LCOV - code coverage report
Current view: top level - src/libsumo - Edge.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 92.3 % 221 204
Test Date: 2024-12-21 15:45:41 Functions: 90.7 % 54 49

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

Generated by: LCOV version 2.0-1