/****************************************************************************/ // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo // Copyright (C) 2017-2019 German Aerospace Center (DLR) and others. // This program and the accompanying materials // are made available under the terms of the Eclipse Public License v2.0 // which accompanies this distribution, and is available at // http://www.eclipse.org/legal/epl-v20.html // SPDX-License-Identifier: EPL-2.0 /****************************************************************************/ /// @file Edge.cpp /// @author Gregor Laemmel /// @date 15.09.2017 /// @version $Id$ /// // C++ TraCI client API implementation /****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "Edge.h" namespace libsumo { // =========================================================================== // static member initializations // =========================================================================== SubscriptionResults Edge::mySubscriptionResults; ContextSubscriptionResults Edge::myContextSubscriptionResults; // =========================================================================== // static member definitions // =========================================================================== std::vector Edge::getIDList() { std::vector ids; MSEdge::insertIDs(ids); return ids; } int Edge::getIDCount() { return (int)getIDList().size(); } double Edge::getAdaptedTraveltime(const std::string& id, double time) { const MSEdge* e = getEdge(id); double value; if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingTravelTime(e, time, value)) { return -1.; } return value; } double Edge::getEffort(const std::string& id, double time) { const MSEdge* e = getEdge(id); double value; if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, time, value)) { return -1.; } return value; } double Edge::getTraveltime(const std::string& id) { return getEdge(id)->getCurrentTravelTime(); } MSEdge* Edge::getEdge(const std::string& id) { MSEdge* e = MSEdge::dictionary(id); if (e == nullptr) { throw TraCIException("Edge '" + id + "' is not known"); } return e; } double Edge::getWaitingTime(const std::string& id) { double wtime = 0; for (MSLane* lane : getEdge(id)->getLanes()) { wtime += lane->getWaitingSeconds(); } return wtime; } const std::vector Edge::getLastStepPersonIDs(const std::string& id) { std::vector personIDs; std::vector persons = getEdge(id)->getSortedPersons(MSNet::getInstance()->getCurrentTimeStep(), true); personIDs.reserve(persons.size()); for (MSTransportable* p : persons) { personIDs.push_back(p->getID()); } return personIDs; } const std::vector Edge::getLastStepVehicleIDs(const std::string& id) { std::vector vehIDs; for (MSLane* lane : getEdge(id)->getLanes()) { const MSLane::VehCont& vehs = lane->getVehiclesSecure(); for (auto veh : vehs) { vehIDs.push_back(veh->getID()); } lane->releaseVehicles(); } return vehIDs; } double Edge::getCO2Emission(const std::string& id) { double sum = 0; for (MSLane* lane : getEdge(id)->getLanes()) { sum += lane->getCO2Emissions(); } return sum; } double Edge::getCOEmission(const std::string& id) { double sum = 0; for (MSLane* lane : getEdge(id)->getLanes()) { sum += lane->getCOEmissions(); } return sum; } double Edge::getHCEmission(const std::string& id) { double sum = 0; for (MSLane* lane : getEdge(id)->getLanes()) { sum += lane->getHCEmissions(); } return sum; } double Edge::getPMxEmission(const std::string& id) { double sum = 0; for (MSLane* lane : getEdge(id)->getLanes()) { sum += lane->getPMxEmissions(); } return sum; } double Edge::getNOxEmission(const std::string& id) { double sum = 0; for (MSLane* lane : getEdge(id)->getLanes()) { sum += lane->getNOxEmissions(); } return sum; } double Edge::getFuelConsumption(const std::string& id) { double sum = 0; for (MSLane* lane : getEdge(id)->getLanes()) { sum += lane->getFuelConsumption(); } return sum; } double Edge::getNoiseEmission(const std::string& id) { double sum = 0; for (MSLane* lane : getEdge(id)->getLanes()) { sum += pow(10., (lane->getHarmonoise_NoiseEmissions() / 10.)); } if (sum != 0) { return HelpersHarmonoise::sum(sum); } return sum; } double Edge::getElectricityConsumption(const std::string& id) { double sum = 0; for (MSLane* lane : getEdge(id)->getLanes()) { sum += lane->getElectricityConsumption(); } return sum; } int Edge::getLastStepVehicleNumber(const std::string& id) { int sum = 0; for (MSLane* lane : getEdge(id)->getLanes()) { sum += lane->getVehicleNumber(); } return sum; } double Edge::getLastStepMeanSpeed(const std::string& id) { return getEdge(id)->getMeanSpeed(); } double Edge::getLastStepOccupancy(const std::string& id) { double sum = 0; const std::vector& lanes = getEdge(id)->getLanes(); for (auto lane : lanes) { sum += lane->getNettoOccupancy(); } return sum / (double)lanes.size(); } int Edge::getLastStepHaltingNumber(const std::string& id) { int halting = 0; for (MSLane* lane : getEdge(id)->getLanes()) { const MSLane::VehCont& vehs = lane->getVehiclesSecure(); for (auto veh : vehs) { if (veh->getSpeed() < SUMO_const_haltingSpeed) { ++halting; } } lane->releaseVehicles(); } return halting; } double Edge::getLastStepLength(const std::string& id) { double lengthSum = 0; int noVehicles = 0; for (MSLane* lane : getEdge(id)->getLanes()) { const MSLane::VehCont& vehs = lane->getVehiclesSecure(); for (auto veh : vehs) { lengthSum += veh->getVehicleType().getLength(); } noVehicles += (int)vehs.size(); lane->releaseVehicles(); } if (noVehicles == 0) { return 0; } return lengthSum / (double)noVehicles; } int Edge::getLaneNumber(const std::string& id) { return (int)getEdge(id)->getLanes().size(); } std::string Edge::getStreetName(const std::string& id) { return getEdge(id)->getStreetName(); } std::string Edge::getParameter(const std::string& id, const std::string& paramName) { return getEdge(id)->getParameter(paramName, ""); } void Edge::setAllowedVehicleClasses(const std::string& id, std::vector classes) { SVCPermissions permissions = parseVehicleClasses(classes); setAllowedSVCPermissions(id, permissions); } void Edge::setDisallowedVehicleClasses(const std::string& id, std::vector classes) { SVCPermissions permissions = invertPermissions(parseVehicleClasses(classes)); setAllowedSVCPermissions(id, permissions); } void Edge::setAllowedSVCPermissions(const std::string& id, int permissions) { MSEdge* e = getEdge(id); for (MSLane* lane : e->getLanes()) { lane->setPermissions(permissions, MSLane::CHANGE_PERMISSIONS_PERMANENT); } e->rebuildAllowedLanes(); for (MSEdge* const pred : e->getPredecessors()) { pred->rebuildAllowedTargets(); } } void Edge::adaptTraveltime(const std::string& id, double value, double begTime, double endTime) { MSNet::getInstance()->getWeightsStorage().addTravelTime(getEdge(id), begTime, endTime, value); } void Edge::setEffort(const std::string& id, double value, double begTime, double endTime) { MSNet::getInstance()->getWeightsStorage().addEffort(getEdge(id), begTime, endTime, value); } void Edge::setMaxSpeed(const std::string& id, double value) { for (MSLane* lane : getEdge(id)->getLanes()) { lane->setMaxSpeed(value); } } void Edge::setParameter(const std::string& id, const std::string& name, const std::string& value) { getEdge(id)->setParameter(name, value); } LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(Edge, EDGE) void Edge::storeShape(const std::string& id, PositionVector& shape) { const MSEdge* const e = getEdge(id); const std::vector& lanes = e->getLanes(); shape = lanes.front()->getShape(); if (lanes.size() > 1) { copy(lanes.back()->getShape().begin(), lanes.back()->getShape().end(), back_inserter(shape)); } } std::shared_ptr Edge::makeWrapper() { return std::make_shared(handleVariable, mySubscriptionResults, myContextSubscriptionResults); } bool Edge::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper) { switch (variable) { case TRACI_ID_LIST: return wrapper->wrapStringList(objID, variable, getIDList()); case ID_COUNT: return wrapper->wrapInt(objID, variable, getIDCount()); case VAR_CURRENT_TRAVELTIME: return wrapper->wrapDouble(objID, variable, getTraveltime(objID)); case VAR_WAITING_TIME: return wrapper->wrapDouble(objID, variable, getWaitingTime(objID)); case LAST_STEP_PERSON_ID_LIST: return wrapper->wrapStringList(objID, variable, getLastStepPersonIDs(objID)); case LAST_STEP_VEHICLE_ID_LIST: return wrapper->wrapStringList(objID, variable, getLastStepVehicleIDs(objID)); case VAR_CO2EMISSION: return wrapper->wrapDouble(objID, variable, getCO2Emission(objID)); case VAR_COEMISSION: return wrapper->wrapDouble(objID, variable, getCOEmission(objID)); case VAR_HCEMISSION: return wrapper->wrapDouble(objID, variable, getHCEmission(objID)); case VAR_PMXEMISSION: return wrapper->wrapDouble(objID, variable, getPMxEmission(objID)); case VAR_NOXEMISSION: return wrapper->wrapDouble(objID, variable, getNOxEmission(objID)); case VAR_FUELCONSUMPTION: return wrapper->wrapDouble(objID, variable, getFuelConsumption(objID)); case VAR_NOISEEMISSION: return wrapper->wrapDouble(objID, variable, getNoiseEmission(objID)); case VAR_ELECTRICITYCONSUMPTION: return wrapper->wrapDouble(objID, variable, getElectricityConsumption(objID)); case LAST_STEP_VEHICLE_NUMBER: return wrapper->wrapInt(objID, variable, getLastStepVehicleNumber(objID)); case LAST_STEP_MEAN_SPEED: return wrapper->wrapDouble(objID, variable, getLastStepMeanSpeed(objID)); case LAST_STEP_OCCUPANCY: return wrapper->wrapDouble(objID, variable, getLastStepOccupancy(objID)); case LAST_STEP_VEHICLE_HALTING_NUMBER: return wrapper->wrapInt(objID, variable, getLastStepHaltingNumber(objID)); case LAST_STEP_LENGTH: return wrapper->wrapDouble(objID, variable, getLastStepLength(objID)); case VAR_LANE_INDEX: return wrapper->wrapInt(objID, variable, getLaneNumber(objID)); case VAR_NAME: return wrapper->wrapString(objID, variable, getStreetName(objID)); default: return false; } } } /****************************************************************************/