LCOV - code coverage report
Current view: top level - src/libsumo - Edge.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 195 213 91.5 %
Date: 2024-04-28 15:39:05 Functions: 48 53 90.6 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2017-2024 German Aerospace Center (DLR) and others.
       4             : // This program and the accompanying materials are made available under the
       5             : // terms of the Eclipse Public License 2.0 which is available at
       6             : // https://www.eclipse.org/legal/epl-2.0/
       7             : // This Source Code may also be made available under the following Secondary
       8             : // Licenses when the conditions for such availability set forth in the Eclipse
       9             : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10             : // or later which is available at
      11             : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12             : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13             : /****************************************************************************/
      14             : /// @file    Edge.cpp
      15             : /// @author  Gregor Laemmel
      16             : /// @date    15.09.2017
      17             : ///
      18             : // C++ TraCI client API implementation
      19             : /****************************************************************************/
      20             : #include <config.h>
      21             : 
      22             : #include <iterator>
      23             : #include <microsim/MSEdge.h>
      24             : #include <microsim/MSLane.h>
      25             : #include <microsim/MSEdgeWeightsStorage.h>
      26             : #include <microsim/transportables/MSTransportable.h>
      27             : #include <microsim/MSVehicle.h>
      28             : #include <microsim/MSInsertionControl.h>
      29             : #include <libsumo/Helper.h>
      30             : #include <libsumo/TraCIDefs.h>
      31             : #include <libsumo/TraCIConstants.h>
      32             : #include <libsumo/Lane.h>
      33             : #include <utils/emissions/HelpersHarmonoise.h>
      34             : #include "Edge.h"
      35             : 
      36             : 
      37             : namespace libsumo {
      38             : // ===========================================================================
      39             : // static member initializations
      40             : // ===========================================================================
      41             : SubscriptionResults Edge::mySubscriptionResults;
      42             : ContextSubscriptionResults Edge::myContextSubscriptionResults;
      43             : 
      44             : 
      45             : // ===========================================================================
      46             : // static member definitions
      47             : // ===========================================================================
      48             : std::vector<std::string>
      49         207 : Edge::getIDList() {
      50         207 :     MSNet::getInstance(); // just to check that we actually have a network
      51             :     std::vector<std::string> ids;
      52         205 :     MSEdge::insertIDs(ids);
      53         205 :     return ids;
      54           0 : }
      55             : 
      56             : 
      57             : int
      58           9 : Edge::getIDCount() {
      59           9 :     return (int)getIDList().size();
      60             : }
      61             : 
      62             : 
      63             : double
      64         129 : Edge::getAdaptedTraveltime(const std::string& edgeID, double time) {
      65         129 :     const MSEdge* e = getEdge(edgeID);
      66             :     double value;
      67         129 :     if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingTravelTime(e, time, value)) {
      68             :         return -1.;
      69             :     }
      70          45 :     return value;
      71             : }
      72             : 
      73             : 
      74             : double
      75          57 : Edge::getEffort(const std::string& edgeID, double time) {
      76          57 :     const MSEdge* e = getEdge(edgeID);
      77             :     double value;
      78          57 :     if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, time, value)) {
      79             :         return -1.;
      80             :     }
      81          33 :     return value;
      82             : }
      83             : 
      84             : 
      85             : double
      86         194 : Edge::getTraveltime(const std::string& edgeID) {
      87         194 :     return getEdge(edgeID)->getCurrentTravelTime();
      88             : }
      89             : 
      90             : 
      91             : MSEdge*
      92       48241 : Edge::getEdge(const std::string& edgeID) {
      93       48241 :     MSEdge* e = MSEdge::dictionary(edgeID);
      94       48241 :     if (e == nullptr) {
      95           8 :         throw TraCIException("Edge '" + edgeID + "' is not known");
      96             :     }
      97       48237 :     return e;
      98             : }
      99             : 
     100             : 
     101             : double
     102           7 : Edge::getWaitingTime(const std::string& edgeID) {
     103           7 :     return getEdge(edgeID)->getWaitingSeconds();
     104             : }
     105             : 
     106             : 
     107             : const std::vector<std::string>
     108       26844 : Edge::getLastStepPersonIDs(const std::string& edgeID) {
     109             :     std::vector<std::string> personIDs;
     110       26844 :     std::vector<MSTransportable*> persons = getEdge(edgeID)->getSortedPersons(MSNet::getInstance()->getCurrentTimeStep(), true);
     111       26844 :     personIDs.reserve(persons.size());
     112       28076 :     for (MSTransportable* p : persons) {
     113        1232 :         personIDs.push_back(p->getID());
     114             :     }
     115       26844 :     return personIDs;
     116           0 : }
     117             : 
     118             : 
     119             : const std::vector<std::string>
     120          22 : Edge::getLastStepVehicleIDs(const std::string& edgeID) {
     121             :     std::vector<std::string> vehIDs;
     122         362 :     for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
     123         340 :         vehIDs.push_back(veh->getID());
     124             :     }
     125          20 :     return vehIDs;
     126           2 : }
     127             : 
     128             : 
     129             : double
     130          10 : Edge::getCO2Emission(const std::string& edgeID) {
     131             :     double sum = 0;
     132          20 :     for (MSLane* lane : getEdge(edgeID)->getLanes()) {
     133          10 :         sum += lane->getEmissions<PollutantsInterface::CO2>();
     134             :     }
     135          10 :     return sum;
     136             : }
     137             : 
     138             : 
     139             : double
     140          10 : Edge::getCOEmission(const std::string& edgeID) {
     141             :     double sum = 0;
     142          20 :     for (MSLane* lane : getEdge(edgeID)->getLanes()) {
     143          10 :         sum += lane->getEmissions<PollutantsInterface::CO>();
     144             :     }
     145          10 :     return sum;
     146             : }
     147             : 
     148             : 
     149             : double
     150          10 : Edge::getHCEmission(const std::string& edgeID) {
     151             :     double sum = 0;
     152          20 :     for (MSLane* lane : getEdge(edgeID)->getLanes()) {
     153          10 :         sum += lane->getEmissions<PollutantsInterface::HC>();
     154             :     }
     155          10 :     return sum;
     156             : }
     157             : 
     158             : 
     159             : double
     160          10 : Edge::getPMxEmission(const std::string& edgeID) {
     161             :     double sum = 0;
     162          20 :     for (MSLane* lane : getEdge(edgeID)->getLanes()) {
     163          10 :         sum += lane->getEmissions<PollutantsInterface::PM_X>();
     164             :     }
     165          10 :     return sum;
     166             : }
     167             : 
     168             : 
     169             : double
     170          10 : Edge::getNOxEmission(const std::string& edgeID) {
     171             :     double sum = 0;
     172          20 :     for (MSLane* lane : getEdge(edgeID)->getLanes()) {
     173          10 :         sum += lane->getEmissions<PollutantsInterface::NO_X>();
     174             :     }
     175          10 :     return sum;
     176             : }
     177             : 
     178             : 
     179             : double
     180          10 : Edge::getFuelConsumption(const std::string& edgeID) {
     181             :     double sum = 0;
     182          20 :     for (MSLane* lane : getEdge(edgeID)->getLanes()) {
     183          10 :         sum += lane->getEmissions<PollutantsInterface::FUEL>();
     184             :     }
     185          10 :     return sum;
     186             : }
     187             : 
     188             : 
     189             : double
     190          10 : Edge::getNoiseEmission(const std::string& edgeID) {
     191             :     double sum = 0;
     192          20 :     for (MSLane* lane : getEdge(edgeID)->getLanes()) {
     193          10 :         sum += pow(10., (lane->getHarmonoise_NoiseEmissions() / 10.));
     194             :     }
     195          10 :     if (sum != 0) {
     196          10 :         return HelpersHarmonoise::sum(sum);
     197             :     }
     198             :     return sum;
     199             : }
     200             : 
     201             : 
     202             : double
     203           6 : Edge::getElectricityConsumption(const std::string& edgeID) {
     204             :     double sum = 0;
     205          12 :     for (MSLane* lane : getEdge(edgeID)->getLanes()) {
     206           6 :         sum += lane->getEmissions<PollutantsInterface::ELEC>();
     207             :     }
     208           6 :     return sum;
     209             : }
     210             : 
     211             : 
     212             : int
     213         154 : Edge::getLastStepVehicleNumber(const std::string& edgeID) {
     214         154 :     return getEdge(edgeID)->getVehicleNumber();
     215             : }
     216             : 
     217             : 
     218             : double
     219          70 : Edge::getLastStepMeanSpeed(const std::string& edgeID) {
     220          70 :     return getEdge(edgeID)->getMeanSpeed();
     221             : }
     222             : 
     223             : double
     224           0 : Edge::getMeanFriction(const std::string& edgeID) {
     225           0 :     return getEdge(edgeID)->getMeanFriction();
     226             : }
     227             : 
     228             : 
     229             : double
     230          16 : Edge::getLastStepOccupancy(const std::string& edgeID) {
     231          16 :     return getEdge(edgeID)->getOccupancy();
     232             : }
     233             : 
     234             : 
     235             : int
     236          10 : Edge::getLastStepHaltingNumber(const std::string& edgeID) {
     237             :     int result = 0;
     238          18 :     for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
     239           8 :         if (veh->getSpeed() < SUMO_const_haltingSpeed) {
     240           0 :             result++;
     241             :         }
     242             :     }
     243          10 :     return result;
     244             : }
     245             : 
     246             : 
     247             : double
     248          10 : Edge::getLastStepLength(const std::string& edgeID) {
     249             :     double lengthSum = 0;
     250             :     int numVehicles = 0;
     251          18 :     for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
     252           8 :         numVehicles++;
     253           8 :         lengthSum += dynamic_cast<const MSBaseVehicle*>(veh)->getVehicleType().getLength();
     254             :     }
     255          10 :     if (numVehicles == 0) {
     256             :         return 0;
     257             :     }
     258           8 :     return lengthSum / numVehicles;
     259             : }
     260             : 
     261             : 
     262             : int
     263           7 : Edge::getLaneNumber(const std::string& edgeID) {
     264           7 :     return (int)getEdge(edgeID)->getLanes().size();
     265             : }
     266             : 
     267             : 
     268             : std::string
     269           7 : Edge::getStreetName(const std::string& edgeID) {
     270           7 :     return getEdge(edgeID)->getStreetName();
     271             : }
     272             : 
     273             : 
     274             : const std::vector<std::string>
     275          60 : Edge::getPendingVehicles(const std::string& edgeID) {
     276          60 :     getEdge(edgeID); // validate edgeID
     277             :     std::vector<std::string> vehIDs;
     278          75 :     for (const SUMOVehicle* veh : MSNet::getInstance()->getInsertionControl().getPendingVehicles()) {
     279          15 :         if (veh->getEdge()->getID() == edgeID) {
     280          15 :             vehIDs.push_back(veh->getID());
     281             :         }
     282             :     }
     283          60 :     return vehIDs;
     284           0 : }
     285             : 
     286             : 
     287             : double
     288          12 : Edge::getAngle(const std::string& edgeID, double relativePosition) {
     289          12 :     const std::vector<MSLane*>& lanes = getEdge(edgeID)->getLanes();
     290          12 :     return lanes.empty() ? libsumo::INVALID_DOUBLE_VALUE : Lane::getAngle(lanes.front()->getID(), relativePosition);
     291             : }
     292             : 
     293             : std::string
     294           6 : Edge::getFromJunction(const std::string& edgeID) {
     295           6 :     return getEdge(edgeID)->getFromJunction()->getID();
     296             : }
     297             : 
     298             : std::string
     299           6 : Edge::getToJunction(const std::string& edgeID) {
     300           6 :     return getEdge(edgeID)->getToJunction()->getID();
     301             : }
     302             : 
     303             : std::string
     304         110 : Edge::getParameter(const std::string& edgeID, const std::string& param) {
     305         220 :     return getEdge(edgeID)->getParameter(param, "");
     306             : }
     307             : 
     308             : 
     309          56 : LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(Edge)
     310             : 
     311             : 
     312             : void
     313           2 : Edge::setAllowed(const std::string& edgeID, std::string allowedClasses) {
     314           2 :     setAllowedSVCPermissions(edgeID, parseVehicleClasses(allowedClasses));
     315           2 : }
     316             : 
     317             : 
     318             : void
     319          10 : Edge::setAllowed(const std::string& edgeID, std::vector<std::string> allowedClasses) {
     320          10 :     setAllowedSVCPermissions(edgeID, parseVehicleClasses(allowedClasses));
     321          10 : }
     322             : 
     323             : 
     324             : void
     325           0 : Edge::setDisallowed(const std::string& edgeID, std::string disallowedClasses) {
     326           0 :     setAllowedSVCPermissions(edgeID, invertPermissions(parseVehicleClasses(disallowedClasses)));
     327           0 : }
     328             : 
     329             : 
     330             : void
     331           0 : Edge::setDisallowed(const std::string& edgeID, std::vector<std::string> disallowedClasses) {
     332           0 :     setAllowedSVCPermissions(edgeID, invertPermissions(parseVehicleClasses(disallowedClasses)));
     333           0 : }
     334             : 
     335             : 
     336             : void
     337          12 : Edge::setAllowedSVCPermissions(const std::string& edgeID, long long int permissions) {
     338          12 :     MSEdge* e = getEdge(edgeID);
     339          24 :     for (MSLane* lane : e->getLanes()) {
     340          12 :         lane->setPermissions(permissions, MSLane::CHANGE_PERMISSIONS_PERMANENT);
     341             :     }
     342          12 :     e->rebuildAllowedLanes();
     343          12 : }
     344             : 
     345             : 
     346             : void
     347          93 : Edge::adaptTraveltime(const std::string& edgeID, double time, double beginSeconds, double endSeconds) {
     348          93 :     MSNet::getInstance()->getWeightsStorage().addTravelTime(getEdge(edgeID), beginSeconds, endSeconds, time);
     349          92 : }
     350             : 
     351             : 
     352             : void
     353          22 : Edge::setEffort(const std::string& edgeID, double effort, double beginSeconds, double endSeconds) {
     354          22 :     MSNet::getInstance()->getWeightsStorage().addEffort(getEdge(edgeID), beginSeconds, endSeconds, effort);
     355          21 : }
     356             : 
     357             : 
     358             : void
     359          23 : Edge::setMaxSpeed(const std::string& edgeID, double speed) {
     360          23 :     getEdge(edgeID)->setMaxSpeed(speed);
     361          23 : }
     362             : 
     363             : void
     364           0 : Edge::setFriction(const std::string& edgeID, double friction) {
     365           0 :     for (MSLane* lane : getEdge(edgeID)->getLanes()) {
     366           0 :         lane->setFrictionCoefficient(friction);
     367             :     }
     368           0 : }
     369             : 
     370             : void
     371          67 : Edge::setParameter(const std::string& edgeID, const std::string& name, const std::string& value) {
     372          67 :     getEdge(edgeID)->setParameter(name, value);
     373          67 : }
     374             : 
     375             : 
     376        8210 : LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(Edge, EDGE)
     377             : 
     378             : 
     379             : void
     380       20227 : Edge::storeShape(const std::string& edgeID, PositionVector& shape) {
     381       20227 :     const MSEdge* const e = getEdge(edgeID);
     382             :     const std::vector<MSLane*>& lanes = e->getLanes();
     383       20227 :     shape = lanes.front()->getShape();
     384       20227 :     if (lanes.size() > 1) {
     385          12 :         copy(lanes.back()->getShape().begin(), lanes.back()->getShape().end(), back_inserter(shape));
     386             :     }
     387       20227 : }
     388             : 
     389             : 
     390             : std::shared_ptr<VariableWrapper>
     391         263 : Edge::makeWrapper() {
     392         263 :     return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
     393             : }
     394             : 
     395             : 
     396             : bool
     397       22732 : Edge::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
     398       22732 :     switch (variable) {
     399         124 :         case TRACI_ID_LIST:
     400         124 :             return wrapper->wrapStringList(objID, variable, getIDList());
     401           7 :         case ID_COUNT:
     402           7 :             return wrapper->wrapInt(objID, variable, getIDCount());
     403         146 :         case VAR_CURRENT_TRAVELTIME:
     404         146 :             return wrapper->wrapDouble(objID, variable, getTraveltime(objID));
     405           5 :         case VAR_WAITING_TIME:
     406           5 :             return wrapper->wrapDouble(objID, variable, getWaitingTime(objID));
     407       21880 :         case LAST_STEP_PERSON_ID_LIST:
     408       21880 :             return wrapper->wrapStringList(objID, variable, getLastStepPersonIDs(objID));
     409          18 :         case LAST_STEP_VEHICLE_ID_LIST:
     410          18 :             return wrapper->wrapStringList(objID, variable, getLastStepVehicleIDs(objID));
     411           8 :         case VAR_CO2EMISSION:
     412           8 :             return wrapper->wrapDouble(objID, variable, getCO2Emission(objID));
     413           8 :         case VAR_COEMISSION:
     414           8 :             return wrapper->wrapDouble(objID, variable, getCOEmission(objID));
     415           8 :         case VAR_HCEMISSION:
     416           8 :             return wrapper->wrapDouble(objID, variable, getHCEmission(objID));
     417           8 :         case VAR_PMXEMISSION:
     418           8 :             return wrapper->wrapDouble(objID, variable, getPMxEmission(objID));
     419           8 :         case VAR_NOXEMISSION:
     420           8 :             return wrapper->wrapDouble(objID, variable, getNOxEmission(objID));
     421           8 :         case VAR_FUELCONSUMPTION:
     422           8 :             return wrapper->wrapDouble(objID, variable, getFuelConsumption(objID));
     423           8 :         case VAR_NOISEEMISSION:
     424           8 :             return wrapper->wrapDouble(objID, variable, getNoiseEmission(objID));
     425           4 :         case VAR_ELECTRICITYCONSUMPTION:
     426           4 :             return wrapper->wrapDouble(objID, variable, getElectricityConsumption(objID));
     427         132 :         case LAST_STEP_VEHICLE_NUMBER:
     428         132 :             return wrapper->wrapInt(objID, variable, getLastStepVehicleNumber(objID));
     429          48 :         case LAST_STEP_MEAN_SPEED:
     430          48 :             return wrapper->wrapDouble(objID, variable, getLastStepMeanSpeed(objID));
     431           0 :         case VAR_FRICTION:
     432           0 :             return wrapper->wrapDouble(objID, variable, getMeanFriction(objID));
     433          12 :         case LAST_STEP_OCCUPANCY:
     434          12 :             return wrapper->wrapDouble(objID, variable, getLastStepOccupancy(objID));
     435           8 :         case LAST_STEP_VEHICLE_HALTING_NUMBER:
     436           8 :             return wrapper->wrapInt(objID, variable, getLastStepHaltingNumber(objID));
     437           8 :         case LAST_STEP_LENGTH:
     438           8 :             return wrapper->wrapDouble(objID, variable, getLastStepLength(objID));
     439           5 :         case VAR_LANE_INDEX:
     440           5 :             return wrapper->wrapInt(objID, variable, getLaneNumber(objID));
     441           5 :         case VAR_NAME:
     442          10 :             return wrapper->wrapString(objID, variable, getStreetName(objID));
     443          40 :         case VAR_PENDING_VEHICLES:
     444          40 :             return wrapper->wrapStringList(objID, variable, getPendingVehicles(objID));
     445           8 :         case VAR_ANGLE:
     446           8 :             paramData->readUnsignedByte();
     447           8 :             return wrapper->wrapDouble(objID, variable, getAngle(objID, paramData->readDouble()));
     448           4 :         case FROM_JUNCTION:
     449           8 :             return wrapper->wrapString(objID, variable, getFromJunction(objID));
     450           4 :         case TO_JUNCTION:
     451           8 :             return wrapper->wrapString(objID, variable, getToJunction(objID));
     452          62 :         case libsumo::VAR_PARAMETER:
     453          62 :             paramData->readUnsignedByte();
     454         124 :             return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
     455          24 :         case libsumo::VAR_PARAMETER_WITH_KEY:
     456          24 :             paramData->readUnsignedByte();
     457          24 :             return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
     458             :         default:
     459             :             return false;
     460             :     }
     461             : }
     462             : 
     463             : }
     464             : 
     465             : 
     466             : /****************************************************************************/

Generated by: LCOV version 1.14