LCOV - code coverage report
Current view: top level - src/libsumo - Lane.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 240 258 93.0 %
Date: 2024-04-27 15:34:54 Functions: 52 57 91.2 %

          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    Lane.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Mario Krumnow
      17             : /// @author  Jakob Erdmann
      18             : /// @author  Michael Behrisch
      19             : /// @author  Robert Hilbrich
      20             : /// @author  Leonhard Luecken
      21             : /// @date    30.05.2012
      22             : ///
      23             : // C++ TraCI client API implementation
      24             : /****************************************************************************/
      25             : #include <config.h>
      26             : 
      27             : #include <microsim/MSNet.h>
      28             : #include <microsim/MSLane.h>
      29             : #include <microsim/MSEdge.h>
      30             : #include <microsim/MSVehicle.h>
      31             : #include <microsim/MSLink.h>
      32             : #include <microsim/MSInsertionControl.h>
      33             : #include <utils/geom/GeomHelper.h>
      34             : #include <libsumo/Helper.h>
      35             : #include <libsumo/TraCIConstants.h>
      36             : #include "Lane.h"
      37             : 
      38             : 
      39             : namespace libsumo {
      40             : // ===========================================================================
      41             : // static member initializations
      42             : // ===========================================================================
      43             : SubscriptionResults Lane::mySubscriptionResults;
      44             : ContextSubscriptionResults Lane::myContextSubscriptionResults;
      45             : 
      46             : 
      47             : // ===========================================================================
      48             : // static member definitions
      49             : // ===========================================================================
      50             : std::vector<std::string>
      51         156 : Lane::getIDList() {
      52         156 :     MSNet::getInstance(); // just to check that we actually have a network
      53             :     std::vector<std::string> ids;
      54         154 :     MSLane::insertIDs(ids);
      55         154 :     return ids;
      56           0 : }
      57             : 
      58             : 
      59             : int
      60          14 : Lane::getIDCount() {
      61          14 :     return (int)getIDList().size();
      62             : }
      63             : 
      64             : 
      65             : std::string
      66          19 : Lane::getEdgeID(const std::string& laneID) {
      67          19 :     return getLane(laneID)->getEdge().getID();
      68             : }
      69             : 
      70             : 
      71             : double
      72       10344 : Lane::getLength(const std::string& laneID) {
      73       10344 :     return getLane(laneID)->getLength();
      74             : }
      75             : 
      76             : 
      77             : double
      78         362 : Lane::getMaxSpeed(const std::string& laneID) {
      79         362 :     return getLane(laneID)->getSpeedLimit();
      80             : }
      81             : 
      82             : double
      83           0 : Lane::getFriction(const std::string& laneID) {
      84           0 :     return getLane(laneID)->getFrictionCoefficient();
      85             : }
      86             : 
      87             : int
      88          22 : Lane::getLinkNumber(const std::string& laneID) {
      89          22 :     return (int)getLane(laneID)->getLinkCont().size();
      90             : }
      91             : 
      92             : 
      93             : std::vector<TraCIConnection>
      94          43 : Lane::getLinks(const std::string& laneID) {
      95             :     std::vector<TraCIConnection> v;
      96          43 :     const MSLane* const lane = getLane(laneID);
      97          43 :     const SUMOTime currTime = MSNet::getInstance()->getCurrentTimeStep();
      98         135 :     for (const MSLink* const link : lane->getLinkCont()) {
      99         184 :         const std::string approachedLane = link->getLane() != nullptr ? link->getLane()->getID() : "";
     100             :         const bool hasPrio = link->havePriority();
     101             :         const double speed = MIN2(lane->getSpeedLimit(), link->getLane()->getSpeedLimit());
     102         184 :         const bool isOpen = link->opened(currTime, speed, speed, SUMOVTypeParameter::getDefault().length,
     103          92 :                                          SUMOVTypeParameter::getDefault().impatience, SUMOVTypeParameter::getDefaultDecel(), 0);
     104          92 :         const bool hasFoe = link->hasApproachingFoe(currTime, currTime, 0, SUMOVTypeParameter::getDefaultDecel());
     105          96 :         const std::string approachedInternal = link->getViaLane() != nullptr ? link->getViaLane()->getID() : "";
     106          92 :         const std::string state = SUMOXMLDefinitions::LinkStates.getString(link->getState());
     107          92 :         const std::string direction = SUMOXMLDefinitions::LinkDirections.getString(link->getDirection());
     108             :         const double length = link->getLength();
     109         184 :         v.push_back(TraCIConnection(approachedLane, hasPrio, isOpen, hasFoe, approachedInternal, state, direction, length));
     110             :     }
     111          43 :     return v;
     112           0 : }
     113             : 
     114             : 
     115             : std::vector<std::string>
     116          88 : Lane::getAllowed(const std::string& laneID) {
     117          88 :     SVCPermissions permissions = getLane(laneID)->getPermissions();
     118          88 :     if (permissions == SVCAll) {  // special case: write nothing
     119             :         permissions = 0;
     120             :     }
     121          88 :     return getVehicleClassNamesList(permissions);
     122             : }
     123             : 
     124             : 
     125             : std::vector<std::string>
     126          70 : Lane::getDisallowed(const std::string& laneID) {
     127          70 :     return getVehicleClassNamesList(invertPermissions((getLane(laneID)->getPermissions()))); // negation yields disallowed
     128             : }
     129             : 
     130             : 
     131             : std::vector<std::string>
     132          44 : Lane::getChangePermissions(const std::string& laneID, const int direction) {
     133          44 :     if (direction == libsumo::LANECHANGE_LEFT) {
     134          22 :         return getVehicleClassNamesList(getLane(laneID)->getChangeLeft());
     135          22 :     } else if (direction == libsumo::LANECHANGE_RIGHT) {
     136          22 :         return getVehicleClassNamesList(getLane(laneID)->getChangeRight());
     137             :     } else {
     138           0 :         throw TraCIException("Invalid direction for change permission (must be " + toString(libsumo::LANECHANGE_LEFT) + " or " + toString(libsumo::LANECHANGE_RIGHT));
     139             :     }
     140             : }
     141             : 
     142             : 
     143             : TraCIPositionVector
     144       20039 : Lane::getShape(const std::string& laneID) {
     145             :     TraCIPositionVector pv;
     146       20039 :     const PositionVector& shp = getLane(laneID)->getShape();
     147       60117 :     for (PositionVector::const_iterator pi = shp.begin(); pi != shp.end(); ++pi) {
     148       40078 :         TraCIPosition p;
     149       40078 :         p.x = pi->x();
     150       40078 :         p.y = pi->y();
     151       40078 :         p.z = pi->z();
     152       40078 :         pv.value.push_back(p);
     153             :     }
     154       20039 :     return pv;
     155             : }
     156             : 
     157             : 
     158             : double
     159          19 : Lane::getWidth(const std::string& laneID) {
     160          19 :     return getLane(laneID)->getWidth();
     161             : }
     162             : 
     163             : 
     164             : double
     165          21 : Lane::getCO2Emission(const std::string& laneID) {
     166          21 :     return getLane(laneID)->getEmissions<PollutantsInterface::CO2>();
     167             : }
     168             : 
     169             : 
     170             : double
     171          21 : Lane::getCOEmission(const std::string& laneID) {
     172          21 :     return getLane(laneID)->getEmissions<PollutantsInterface::CO>();
     173             : }
     174             : 
     175             : 
     176             : double
     177          21 : Lane::getHCEmission(const std::string& laneID) {
     178          21 :     return getLane(laneID)->getEmissions<PollutantsInterface::HC>();
     179             : }
     180             : 
     181             : 
     182             : double
     183          21 : Lane::getPMxEmission(const std::string& laneID) {
     184          21 :     return getLane(laneID)->getEmissions<PollutantsInterface::PM_X>();
     185             : }
     186             : 
     187             : 
     188             : double
     189          21 : Lane::getNOxEmission(const std::string& laneID) {
     190          21 :     return getLane(laneID)->getEmissions<PollutantsInterface::NO_X>();
     191             : }
     192             : 
     193             : double
     194          21 : Lane::getFuelConsumption(const std::string& laneID) {
     195          21 :     return getLane(laneID)->getEmissions<PollutantsInterface::FUEL>();
     196             : }
     197             : 
     198             : 
     199             : double
     200          21 : Lane::getNoiseEmission(const std::string& laneID) {
     201          21 :     return getLane(laneID)->getHarmonoise_NoiseEmissions();
     202             : }
     203             : 
     204             : 
     205             : double
     206          17 : Lane::getElectricityConsumption(const std::string& laneID) {
     207          17 :     return getLane(laneID)->getEmissions<PollutantsInterface::ELEC>();
     208             : }
     209             : 
     210             : 
     211             : double
     212          21 : Lane::getLastStepMeanSpeed(const std::string& laneID) {
     213          21 :     return getLane(laneID)->getMeanSpeed();
     214             : }
     215             : 
     216             : 
     217             : double
     218          21 : Lane::getLastStepOccupancy(const std::string& laneID) {
     219          21 :     return getLane(laneID)->getNettoOccupancy();
     220             : }
     221             : 
     222             : 
     223             : double
     224          21 : Lane::getLastStepLength(const std::string& laneID) {
     225          21 :     const MSLane* lane = getLane(laneID);
     226             :     double length = 0;
     227          21 :     const MSLane::VehCont& vehs = lane->getVehiclesSecure();
     228          33 :     for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
     229          12 :         length += (*j)->getVehicleType().getLength();
     230             :     }
     231          21 :     if (vehs.size() > 0) {
     232          12 :         length = length / (double)vehs.size();
     233             :     }
     234          21 :     lane->releaseVehicles();
     235          21 :     return length;
     236             : }
     237             : 
     238             : 
     239             : double
     240          18 : Lane::getWaitingTime(const std::string& laneID) {
     241          18 :     return getLane(laneID)->getWaitingSeconds();
     242             : }
     243             : 
     244             : 
     245             : double
     246          21 : Lane::getTraveltime(const std::string& laneID) {
     247          21 :     const MSLane* lane = getLane(laneID);
     248          21 :     double meanSpeed = lane->getMeanSpeed();
     249          21 :     if (meanSpeed != 0) {
     250          21 :         return lane->getLength() / meanSpeed;
     251             :     } else {
     252             :         return 1000000.;
     253             :     }
     254             : }
     255             : 
     256             : 
     257             : int
     258          89 : Lane::getLastStepVehicleNumber(const std::string& laneID) {
     259          89 :     return (int)getLane(laneID)->getVehicleNumber();
     260             : }
     261             : 
     262             : 
     263             : int
     264          21 : Lane::getLastStepHaltingNumber(const std::string& laneID) {
     265          21 :     const MSLane* lane = getLane(laneID);
     266             :     int halting = 0;
     267          21 :     const MSLane::VehCont& vehs = lane->getVehiclesSecure();
     268          33 :     for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
     269          12 :         if ((*j)->getSpeed() < SUMO_const_haltingSpeed) {
     270           0 :             ++halting;
     271             :         }
     272             :     }
     273          21 :     lane->releaseVehicles();
     274          21 :     return halting;
     275             : }
     276             : 
     277             : 
     278             : std::vector<std::string>
     279         845 : Lane::getLastStepVehicleIDs(const std::string& laneID) {
     280         845 :     const MSLane* lane = getLane(laneID);
     281             :     std::vector<std::string> vehIDs;
     282         845 :     const MSLane::VehCont& vehs = lane->getVehiclesSecure();
     283        1369 :     for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
     284         524 :         vehIDs.push_back((*j)->getID());
     285             :     }
     286         845 :     lane->releaseVehicles();
     287         845 :     return vehIDs;
     288           0 : }
     289             : 
     290             : 
     291             : std::vector<std::string>
     292          18 : Lane::getFoes(const std::string& laneID, const std::string& toLaneID) {
     293             :     std::vector<std::string> foeIDs;
     294          18 :     const MSLink* const link = getLane(laneID)->getLinkTo(getLane(toLaneID));
     295          18 :     if (link == nullptr) {
     296           2 :         throw TraCIException("No connection from lane '" + laneID + "' to lane '" + toLaneID + "'");
     297             :     }
     298         105 :     for (const MSLink* foe : link->getFoeLinks()) {
     299          88 :         foeIDs.push_back(foe->getLaneBefore()->getID());
     300             :     }
     301          17 :     return foeIDs;
     302           1 : }
     303             : 
     304             : 
     305             : std::vector<std::string>
     306          12 : Lane::getInternalFoes(const std::string& laneID) {
     307          12 :     const MSLane* lane = getLane(laneID);
     308             :     const std::vector<const MSLane*>* foeLanes;
     309             :     std::vector<const MSLane*>::const_iterator it;
     310             :     std::vector<std::string> foeIDs;
     311             : 
     312          10 :     if ((lane->isInternal() || lane->isCrossing()) && lane->getLinkCont().size() > 0) {
     313           9 :         MSLink* link = lane->getLinkCont().front();
     314             :         foeLanes = &link->getFoeLanes();
     315             : 
     316         134 :         for (it = foeLanes->begin(); foeLanes->end() != it; ++it) {
     317         125 :             foeIDs.push_back((*it)->getID());
     318             :         }
     319             :     }
     320          10 :     return foeIDs;
     321           0 : }
     322             : 
     323             : 
     324             : const std::vector<std::string>
     325          51 : Lane::getPendingVehicles(const std::string& laneID) {
     326          51 :     MSLane* const l = getLane(laneID); // validate laneID
     327             :     std::vector<std::string> vehIDs;
     328          61 :     for (const SUMOVehicle* veh : MSNet::getInstance()->getInsertionControl().getPendingVehicles()) {
     329          10 :         if (veh->getLane() == l) {
     330          10 :             vehIDs.push_back(veh->getID());
     331             :         }
     332             :     }
     333          51 :     return vehIDs;
     334           0 : }
     335             : 
     336             : 
     337             : double
     338          35 : Lane::getAngle(const std::string& laneID, double relativePosition) {
     339             :     double angle;
     340          35 :     MSLane* lane = getLane(laneID);
     341          35 :     if (relativePosition == libsumo::INVALID_DOUBLE_VALUE) {
     342          17 :         Position start = lane->getShape().front();
     343          17 :         Position end = lane->getShape().back();
     344             :         angle = start.angleTo2D(end);
     345             :     } else {
     346          18 :         angle = lane->getShape().rotationAtOffset(lane->interpolateLanePosToGeometryPos(relativePosition));
     347             :     }
     348             : 
     349          35 :     return GeomHelper::naviDegree(angle);
     350             : }
     351             : 
     352             : 
     353             : void
     354           8 : Lane::setAllowed(const std::string& laneID, std::string allowedClass) {
     355          16 :     setAllowed(laneID, std::vector<std::string>({allowedClass}));
     356           8 : }
     357             : 
     358             : 
     359             : void
     360          42 : Lane::setAllowed(const std::string& laneID, std::vector<std::string> allowedClasses) {
     361          42 :     MSLane* const l = getLane(laneID);
     362          42 :     l->setPermissions(parseVehicleClasses(allowedClasses), MSLane::CHANGE_PERMISSIONS_PERMANENT);
     363          42 :     l->getEdge().rebuildAllowedLanes();
     364          42 : }
     365             : 
     366             : 
     367             : void
     368           0 : Lane::setDisallowed(const std::string& laneID, std::string disallowedClasses) {
     369           0 :     setDisallowed(laneID, std::vector<std::string>({disallowedClasses}));
     370           0 : }
     371             : 
     372             : 
     373             : void
     374          24 : Lane::setDisallowed(const std::string& laneID, std::vector<std::string> disallowedClasses) {
     375          24 :     MSLane* const l = getLane(laneID);
     376          24 :     l->setPermissions(invertPermissions(parseVehicleClasses(disallowedClasses)), MSLane::CHANGE_PERMISSIONS_PERMANENT); // negation yields allowed
     377          24 :     l->getEdge().rebuildAllowedLanes();
     378          24 : }
     379             : 
     380             : 
     381             : void
     382          22 : Lane::setChangePermissions(const std::string& laneID, std::vector<std::string> allowedClasses, const int direction) {
     383          22 :     MSLane* const l = getLane(laneID);
     384          22 :     if (direction == libsumo::LANECHANGE_LEFT) {
     385          11 :         l->setChangeLeft(parseVehicleClasses(allowedClasses));
     386          11 :     } else if (direction == libsumo::LANECHANGE_RIGHT) {
     387          11 :         l->setChangeRight(parseVehicleClasses(allowedClasses));
     388             :     } else {
     389           0 :         throw TraCIException("Invalid direction for change permission (must be " + toString(libsumo::LANECHANGE_LEFT) + " or " + toString(libsumo::LANECHANGE_RIGHT));
     390             :     }
     391          22 : }
     392             : 
     393             : 
     394             : void
     395          39 : Lane::setMaxSpeed(const std::string& laneID, double speed) {
     396          39 :     getLane(laneID)->setMaxSpeed(speed, false, true);
     397          39 : }
     398             : 
     399             : 
     400             : void
     401          18 : Lane::setLength(const std::string& laneID, double length) {
     402          18 :     getLane(laneID)->setLength(length);
     403          18 : }
     404             : 
     405             : 
     406             : void
     407           0 : Lane::setFriction(const std::string& laneID, double friction) {
     408           0 :     getLane(laneID)->setFrictionCoefficient(friction);
     409           0 : }
     410             : 
     411             : 
     412             : std::string
     413         110 : Lane::getParameter(const std::string& laneID, const std::string& param) {
     414         220 :     return getLane(laneID)->getParameter(param, "");
     415             : }
     416             : 
     417             : 
     418          56 : LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(Lane)
     419             : 
     420             : 
     421             : void
     422          67 : Lane::setParameter(const std::string& laneID, const std::string& key, const std::string& value) {
     423          67 :     getLane(laneID)->setParameter(key, value);
     424          67 : }
     425             : 
     426             : 
     427        8228 : LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(Lane, LANE)
     428             : 
     429             : 
     430             : MSLane*
     431       52983 : Lane::getLane(const std::string& id) {
     432       52983 :     MSLane* const lane = MSLane::dictionary(id);
     433       52983 :     if (lane == nullptr) {
     434           8 :         throw TraCIException("Lane '" + id + "' is not known");
     435             :     }
     436       52979 :     return lane;
     437             : }
     438             : 
     439             : 
     440             : void
     441       20256 : Lane::storeShape(const std::string& id, PositionVector& shape) {
     442       20256 :     shape = getLane(id)->getShape();
     443       20256 : }
     444             : 
     445             : 
     446             : std::shared_ptr<VariableWrapper>
     447         267 : Lane::makeWrapper() {
     448         267 :     return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
     449             : }
     450             : 
     451             : 
     452             : bool
     453       20886 : Lane::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
     454       20886 :     switch (variable) {
     455          86 :         case TRACI_ID_LIST:
     456          86 :             return wrapper->wrapStringList(objID, variable, getIDList());
     457          10 :         case ID_COUNT:
     458          10 :             return wrapper->wrapInt(objID, variable, getIDCount());
     459          16 :         case LANE_LINK_NUMBER:
     460          16 :             return wrapper->wrapInt(objID, variable, getLinkNumber(objID));
     461          13 :         case LANE_EDGE_ID:
     462          26 :             return wrapper->wrapString(objID, variable, getEdgeID(objID));
     463        6926 :         case VAR_LENGTH:
     464        6926 :             return wrapper->wrapDouble(objID, variable, getLength(objID));
     465         348 :         case VAR_MAXSPEED:
     466         348 :             return wrapper->wrapDouble(objID, variable, getMaxSpeed(objID));
     467           0 :         case VAR_FRICTION:
     468           0 :             return wrapper->wrapDouble(objID, variable, getFriction(objID));
     469          60 :         case LANE_ALLOWED:
     470          60 :             return wrapper->wrapStringList(objID, variable, getAllowed(objID));
     471          48 :         case LANE_DISALLOWED:
     472          48 :             return wrapper->wrapStringList(objID, variable, getDisallowed(objID));
     473          28 :         case LANE_CHANGES:
     474          28 :             paramData->readUnsignedByte();
     475          28 :             return wrapper->wrapStringList(objID, variable, getChangePermissions(objID, paramData->readByte()));
     476          15 :         case VAR_CO2EMISSION:
     477          15 :             return wrapper->wrapDouble(objID, variable, getCO2Emission(objID));
     478          15 :         case VAR_COEMISSION:
     479          15 :             return wrapper->wrapDouble(objID, variable, getCOEmission(objID));
     480          15 :         case VAR_HCEMISSION:
     481          15 :             return wrapper->wrapDouble(objID, variable, getHCEmission(objID));
     482          15 :         case VAR_PMXEMISSION:
     483          15 :             return wrapper->wrapDouble(objID, variable, getPMxEmission(objID));
     484          15 :         case VAR_NOXEMISSION:
     485          15 :             return wrapper->wrapDouble(objID, variable, getNOxEmission(objID));
     486          15 :         case VAR_FUELCONSUMPTION:
     487          15 :             return wrapper->wrapDouble(objID, variable, getFuelConsumption(objID));
     488          15 :         case VAR_NOISEEMISSION:
     489          15 :             return wrapper->wrapDouble(objID, variable, getNoiseEmission(objID));
     490          11 :         case VAR_ELECTRICITYCONSUMPTION:
     491          11 :             return wrapper->wrapDouble(objID, variable, getElectricityConsumption(objID));
     492          83 :         case LAST_STEP_VEHICLE_NUMBER:
     493          83 :             return wrapper->wrapInt(objID, variable, getLastStepVehicleNumber(objID));
     494          15 :         case LAST_STEP_MEAN_SPEED:
     495          15 :             return wrapper->wrapDouble(objID, variable, getLastStepMeanSpeed(objID));
     496         839 :         case LAST_STEP_VEHICLE_ID_LIST:
     497         839 :             return wrapper->wrapStringList(objID, variable, getLastStepVehicleIDs(objID));
     498          15 :         case LAST_STEP_OCCUPANCY:
     499          15 :             return wrapper->wrapDouble(objID, variable, getLastStepOccupancy(objID));
     500          15 :         case LAST_STEP_VEHICLE_HALTING_NUMBER:
     501          15 :             return wrapper->wrapInt(objID, variable, getLastStepHaltingNumber(objID));
     502          15 :         case LAST_STEP_LENGTH:
     503          15 :             return wrapper->wrapDouble(objID, variable, getLastStepLength(objID));
     504          12 :         case VAR_WAITING_TIME:
     505          12 :             return wrapper->wrapDouble(objID, variable, getWaitingTime(objID));
     506          15 :         case VAR_CURRENT_TRAVELTIME:
     507          15 :             return wrapper->wrapDouble(objID, variable, getTraveltime(objID));
     508          13 :         case VAR_WIDTH:
     509          13 :             return wrapper->wrapDouble(objID, variable, getWidth(objID));
     510       12025 :         case VAR_SHAPE:
     511       24050 :             return wrapper->wrapPositionVector(objID, variable, getShape(objID));
     512          33 :         case VAR_PENDING_VEHICLES:
     513          33 :             return wrapper->wrapStringList(objID, variable, getPendingVehicles(objID));
     514          15 :         case VAR_ANGLE:
     515          15 :             paramData->readUnsignedByte();
     516          15 :             return wrapper->wrapDouble(objID, variable, getAngle(objID, paramData->readDouble()));
     517          62 :         case libsumo::VAR_PARAMETER:
     518          62 :             paramData->readUnsignedByte();
     519         124 :             return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
     520          24 :         case libsumo::VAR_PARAMETER_WITH_KEY:
     521          24 :             paramData->readUnsignedByte();
     522          24 :             return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
     523             :         default:
     524             :             return false;
     525             :     }
     526             : }
     527             : }
     528             : 
     529             : 
     530             : /****************************************************************************/

Generated by: LCOV version 1.14