LCOV - code coverage report
Current view: top level - src/libsumo - Edge.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 94.5 % 220 208
Test Date: 2025-11-13 15:38:19 Functions: 92.6 % 54 50

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

Generated by: LCOV version 2.0-1