LCOV - code coverage report
Current view: top level - src/traci-server - TraCIServerAPI_Simulation.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 94.0 % 319 300
Test Date: 2025-12-06 15:35:27 Functions: 100.0 % 8 8

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-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    TraCIServerAPI_Simulation.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @author  Laura Bieker
      19              : /// @date    Sept 2002
      20              : ///
      21              : // APIs for getting/setting simulation values via TraCI
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <utils/common/StdDefs.h>
      26              : #include <utils/geom/GeoConvHelper.h>
      27              : #include <microsim/MSNet.h>
      28              : #include <microsim/MSEdgeControl.h>
      29              : #include <microsim/MSInsertionControl.h>
      30              : #include <microsim/MSEdge.h>
      31              : #include <microsim/MSLane.h>
      32              : #include <microsim/MSVehicle.h>
      33              : #include <microsim/MSVehicleControl.h>
      34              : #include <microsim/MSStateHandler.h>
      35              : #include <microsim/MSStoppingPlace.h>
      36              : #include <libsumo/Helper.h>
      37              : #include <libsumo/Simulation.h>
      38              : #include <libsumo/TraCIConstants.h>
      39              : #include <libsumo/StorageHelper.h>
      40              : #include "TraCIServerAPI_Simulation.h"
      41              : 
      42              : 
      43              : // ===========================================================================
      44              : // method definitions
      45              : // ===========================================================================
      46              : bool
      47      7896530 : TraCIServerAPI_Simulation::processGet(TraCIServer& server, tcpip::Storage& inputStorage,
      48              :                                       const std::string& objID, const int variable) {
      49              :     // unlike the other domains we cannot check here first whether libsumo::Simulation can handle it because the implementations for the state variables differ
      50      7896530 :     switch (variable) {
      51           20 :         case libsumo::VAR_LOADED_VEHICLES_NUMBER:
      52           20 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::BUILT);
      53           20 :             break;
      54           80 :         case libsumo::VAR_LOADED_VEHICLES_IDS:
      55           80 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::BUILT);
      56           80 :             break;
      57        32183 :         case libsumo::VAR_DEPARTED_VEHICLES_NUMBER:
      58        32183 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::DEPARTED);
      59        32183 :             break;
      60        26089 :         case libsumo::VAR_DEPARTED_VEHICLES_IDS:
      61        26089 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::DEPARTED);
      62        26089 :             break;
      63           20 :         case libsumo::VAR_TELEPORT_STARTING_VEHICLES_NUMBER:
      64           20 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_TELEPORT);
      65           20 :             break;
      66           20 :         case libsumo::VAR_TELEPORT_STARTING_VEHICLES_IDS:
      67           20 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_TELEPORT);
      68           20 :             break;
      69           20 :         case libsumo::VAR_TELEPORT_ENDING_VEHICLES_NUMBER:
      70           20 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_TELEPORT);
      71           20 :             break;
      72           20 :         case libsumo::VAR_TELEPORT_ENDING_VEHICLES_IDS:
      73           20 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_TELEPORT);
      74           20 :             break;
      75         1032 :         case libsumo::VAR_ARRIVED_VEHICLES_NUMBER:
      76         1032 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ARRIVED);
      77         1032 :             break;
      78         8204 :         case libsumo::VAR_ARRIVED_VEHICLES_IDS:
      79         8204 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ARRIVED);
      80         8204 :             break;
      81           15 :         case libsumo::VAR_DEPARTED_PERSONS_NUMBER:
      82           15 :             writeTransportableStateNumber(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_DEPARTED);
      83           15 :             break;
      84           15 :         case libsumo::VAR_DEPARTED_PERSONS_IDS:
      85           15 :             writeTransportableStateIDs(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_DEPARTED);
      86           15 :             break;
      87           15 :         case libsumo::VAR_ARRIVED_PERSONS_NUMBER:
      88           15 :             writeTransportableStateNumber(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_ARRIVED);
      89           15 :             break;
      90           15 :         case libsumo::VAR_ARRIVED_PERSONS_IDS:
      91           15 :             writeTransportableStateIDs(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_ARRIVED);
      92           15 :             break;
      93           25 :         case libsumo::VAR_PARKING_STARTING_VEHICLES_NUMBER:
      94           25 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_PARKING);
      95           25 :             break;
      96           25 :         case libsumo::VAR_PARKING_STARTING_VEHICLES_IDS:
      97           25 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_PARKING);
      98           25 :             break;
      99            7 :         case libsumo::VAR_PARKING_MANEUVERING_VEHICLES_NUMBER:
     100            7 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::MANEUVERING);
     101            7 :             break;
     102            7 :         case libsumo::VAR_PARKING_MANEUVERING_VEHICLES_IDS:
     103            7 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::MANEUVERING);
     104            7 :             break;
     105           25 :         case libsumo::VAR_PARKING_ENDING_VEHICLES_NUMBER:
     106           25 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_PARKING);
     107           25 :             break;
     108           25 :         case libsumo::VAR_PARKING_ENDING_VEHICLES_IDS:
     109           25 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_PARKING);
     110           25 :             break;
     111           25 :         case libsumo::VAR_STOP_STARTING_VEHICLES_NUMBER:
     112           25 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_STOP);
     113           25 :             break;
     114           25 :         case libsumo::VAR_STOP_STARTING_VEHICLES_IDS:
     115           25 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_STOP);
     116           25 :             break;
     117           25 :         case libsumo::VAR_STOP_ENDING_VEHICLES_NUMBER:
     118           25 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_STOP);
     119           25 :             break;
     120           25 :         case libsumo::VAR_STOP_ENDING_VEHICLES_IDS:
     121           25 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_STOP);
     122           25 :             break;
     123           57 :         case libsumo::VAR_COLLIDING_VEHICLES_NUMBER:
     124           57 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::COLLISION);
     125           57 :             break;
     126           18 :         case libsumo::VAR_COLLIDING_VEHICLES_IDS:
     127           18 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::COLLISION);
     128           18 :             break;
     129           54 :         case libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_NUMBER:
     130           54 :             writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::EMERGENCYSTOP);
     131           54 :             break;
     132           18 :         case libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_IDS:
     133           18 :             writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::EMERGENCYSTOP);
     134           18 :             break;
     135          210 :         case libsumo::VAR_COLLISIONS: {
     136          210 :             std::vector<libsumo::TraCICollision> collisions = libsumo::Simulation::getCollisions();
     137          210 :             server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_COMPOUND);
     138          210 :             const int cnt = 1 + (int)collisions.size() * 4;
     139          210 :             server.getWrapperStorage().writeInt(cnt);
     140          210 :             server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_INTEGER);
     141          210 :             server.getWrapperStorage().writeInt((int)collisions.size());
     142          225 :             for (const auto& c : collisions) {
     143           15 :                 server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
     144           15 :                 server.getWrapperStorage().writeString(c.collider);
     145           15 :                 server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
     146           15 :                 server.getWrapperStorage().writeString(c.victim);
     147           15 :                 server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
     148           15 :                 server.getWrapperStorage().writeString(c.colliderType);
     149           15 :                 server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
     150           15 :                 server.getWrapperStorage().writeString(c.victimType);
     151           15 :                 server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);
     152           15 :                 server.getWrapperStorage().writeDouble(c.colliderSpeed);
     153           15 :                 server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);
     154           15 :                 server.getWrapperStorage().writeDouble(c.victimSpeed);
     155           15 :                 server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
     156           15 :                 server.getWrapperStorage().writeString(c.type);
     157           15 :                 server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);
     158           15 :                 server.getWrapperStorage().writeString(c.lane);
     159           15 :                 server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);
     160           15 :                 server.getWrapperStorage().writeDouble(c.pos);
     161              :             }
     162              :             break;
     163              :         }
     164            9 :         case libsumo::VAR_NET_BOUNDING_BOX: {
     165            9 :             server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_POLYGON);
     166            9 :             libsumo::TraCIPositionVector tb = libsumo::Simulation::getNetBoundary();
     167            9 :             server.getWrapperStorage().writeByte(2);
     168            9 :             server.getWrapperStorage().writeDouble(tb.value[0].x);
     169            9 :             server.getWrapperStorage().writeDouble(tb.value[0].y);
     170            9 :             server.getWrapperStorage().writeDouble(tb.value[1].x);
     171            9 :             server.getWrapperStorage().writeDouble(tb.value[1].y);
     172              :             break;
     173              :         }
     174          270 :         case libsumo::POSITION_CONVERSION: {
     175          270 :             if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
     176            0 :                 throw libsumo::TraCIException("Position conversion requires a compound object.");
     177              :             }
     178          261 :             const int compoundSize = inputStorage.readInt();
     179          261 :             if (compoundSize < 2 || compoundSize > 3) {
     180            0 :                 throw libsumo::TraCIException("Position conversion requires a source position and a position type as parameter.");
     181              :             }
     182          261 :             commandPositionConversion(inputStorage, compoundSize, server.getWrapperStorage());
     183          256 :             break;
     184              :         }
     185          262 :         case libsumo::DISTANCE_REQUEST:
     186          262 :             if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
     187            0 :                 throw libsumo::TraCIException("Retrieval of distance requires a compound object.");
     188              :             }
     189          256 :             if (inputStorage.readInt() != 3) {
     190            0 :                 throw libsumo::TraCIException("Retrieval of distance requires two positions and a distance type as parameter.");
     191              :             }
     192          256 :             commandDistanceRequest(inputStorage, server.getWrapperStorage());
     193          256 :             break;
     194              :         case libsumo::FIND_ROUTE: {
     195         5416 :             const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Retrieval of a route requires a compound object.");
     196         5413 :             if (parameterCount < 5 || parameterCount > 7) {
     197            0 :                 throw libsumo::TraCIException("Retrieval of a route requires between five to seven parameters.");
     198              :             }
     199         5413 :             const std::string from = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as first parameter.");
     200         5419 :             const std::string to = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as second parameter.");
     201         5419 :             const std::string vtype = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as third parameter.");
     202         5413 :             const double depart = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as fourth parameter.");
     203         5413 :             const int routingMode = StoHelp::readTypedInt(inputStorage, "Retrieval of a route requires an integer as fifth parameter.");
     204              :             double departPos = 0.;
     205         5413 :             if (parameterCount > 5) {
     206         5411 :                 departPos = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as sixth parameter.");
     207              :             }
     208              :             double arrivalPos = libsumo::INVALID_DOUBLE_VALUE;
     209         5411 :             if (parameterCount > 6) {
     210        10822 :                 arrivalPos = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as seventh parameter.");
     211              :             }
     212         5413 :             StoHelp::writeStage(server.getWrapperStorage(), libsumo::Simulation::findRoute(from, to, vtype, depart, routingMode, departPos, arrivalPos));
     213              :             break;
     214              :         }
     215              :         case libsumo::FIND_INTERMODAL_ROUTE: {
     216          236 :             StoHelp::readCompound(inputStorage, 13, "Retrieval of an intermodal route requires thirteen parameters.");
     217          236 :             const std::string from = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as first parameter.");
     218          242 :             const std::string to = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as second parameter.");
     219          242 :             const std::string modes = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as third parameter.");
     220          236 :             const double depart = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as fourth parameter.");
     221          236 :             const int routingMode = StoHelp::readTypedInt(inputStorage, "Retrieval of a route requires an integer as fifth parameter.");
     222          236 :             const double speed = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as sixth parameter.");
     223          236 :             const double walkFactor = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as seventh parameter.");
     224          236 :             const double departPos = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as eighth parameter.");
     225          236 :             const double arrivalPos = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as ninth parameter.");
     226          236 :             const double departPosLat = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as tenth parameter.");
     227          242 :             const std::string ptype = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as eleventh parameter.");
     228          242 :             const std::string vtype = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as twelfth parameter.");
     229          242 :             const std::string destStop = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as thirteenth parameter.");
     230          236 :             const std::vector<libsumo::TraCIStage>& result = libsumo::Simulation::findIntermodalRoute(from, to, modes, depart, routingMode, speed, walkFactor, departPos, arrivalPos, departPosLat, ptype, vtype, destStop);
     231          230 :             server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_COMPOUND);
     232          230 :             server.getWrapperStorage().writeInt((int)result.size());
     233          700 :             for (const libsumo::TraCIStage& s : result) {
     234          470 :                 StoHelp::writeStage(server.getWrapperStorage(), s);
     235              :             }
     236              :             break;
     237          230 :         }
     238      7822018 :         default:
     239      7822018 :             if (!libsumo::Simulation::handleVariable(objID, variable, &server, &inputStorage)) {
     240           14 :                 throw libsumo::TraCIException("Get Simulation Variable: unsupported variable " + toHex(variable, 2) + " specified");
     241              :             }
     242              :     }
     243      7896470 :     return true;
     244              : }
     245              : 
     246              : 
     247              : bool
     248          190 : TraCIServerAPI_Simulation::processSet(TraCIServer& server, tcpip::Storage& inputStorage,
     249              :                                       tcpip::Storage& outputStorage) {
     250          190 :     std::string warning = ""; // additional description for response
     251              :     // variable
     252          190 :     int variable = inputStorage.readUnsignedByte();
     253          190 :     if (variable != libsumo::CMD_CLEAR_PENDING_VEHICLES
     254              :             && variable != libsumo::CMD_SAVE_SIMSTATE
     255          190 :             && variable != libsumo::CMD_LOAD_SIMSTATE
     256          190 :             && variable != libsumo::VAR_PARAMETER
     257            7 :             && variable != libsumo::VAR_SCALE
     258            7 :             && variable != libsumo::CMD_MESSAGE
     259              :        ) {
     260            0 :         return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "Set Simulation Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
     261              :     }
     262              :     // id
     263          190 :     std::string id = inputStorage.readString();
     264              :     // process
     265              :     try {
     266          190 :         switch (variable) {
     267              :             case libsumo::VAR_SCALE: {
     268            3 :                 const double value = StoHelp::readTypedDouble(inputStorage, "A double is needed for setting traffic scale.");
     269            3 :                 if (value < 0.0) {
     270            0 :                     return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "Traffic scale may not be negative.", outputStorage);
     271              :                 }
     272            3 :                 libsumo::Simulation::setScale(value);
     273              :             }
     274              :             break;
     275              :             case libsumo::CMD_CLEAR_PENDING_VEHICLES:
     276              :                 //clear any pending vehicle insertions
     277            4 :                 libsumo::Simulation::clearPending(StoHelp::readTypedString(inputStorage, "A string is needed for clearing pending vehicles."));
     278            4 :                 break;
     279              :             case libsumo::CMD_SAVE_SIMSTATE:
     280              :                 //save current simulation state
     281           50 :                 libsumo::Simulation::saveState(StoHelp::readTypedString(inputStorage, "A string is needed for saving simulation state."));
     282           50 :                 break;
     283              :             case libsumo::CMD_LOAD_SIMSTATE: {
     284              :                 //quick-load simulation state
     285          240 :                 const double time = libsumo::Simulation::loadState(StoHelp::readTypedString(inputStorage, "A string is needed for loading simulation state."));
     286          117 :                 TraCIServer::getInstance()->stateLoaded(TIME2STEPS(time));
     287              :             }
     288              :             break;
     289              :             case libsumo::VAR_PARAMETER: {
     290            6 :                 StoHelp::readCompound(inputStorage, 2, "A compound object of size 2 is needed for setting a parameter.");
     291            6 :                 const std::string name = StoHelp::readTypedString(inputStorage, "The name of the parameter must be given as a string.");
     292            9 :                 const std::string value = StoHelp::readTypedString(inputStorage, "The value of the parameter must be given as a string.");
     293            6 :                 libsumo::Simulation::setParameter(id, name, value);
     294              :                 break;
     295              :             }
     296              :             case libsumo::CMD_MESSAGE:
     297            4 :                 libsumo::Simulation::writeMessage(StoHelp::readTypedString(inputStorage, "A string is needed for adding a log message."));
     298            4 :                 break;
     299              :             default:
     300              :                 break;
     301              :         }
     302            9 :     } catch (libsumo::TraCIException& e) {
     303            9 :         return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, e.what(), outputStorage);
     304            9 :     }
     305          181 :     server.writeStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);
     306              :     return true;
     307              : }
     308              : 
     309              : 
     310              : void
     311        33493 : TraCIServerAPI_Simulation::writeVehicleStateNumber(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::VehicleState state) {
     312        33493 :     StoHelp::writeTypedInt(outputStorage, (int)server.getVehicleStateChanges().find(state)->second.size());
     313        33493 : }
     314              : 
     315              : 
     316              : void
     317        34556 : TraCIServerAPI_Simulation::writeVehicleStateIDs(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::VehicleState state) {
     318        34556 :     StoHelp::writeTypedStringList(outputStorage, server.getVehicleStateChanges().find(state)->second);
     319        34556 : }
     320              : 
     321              : 
     322              : void
     323           30 : TraCIServerAPI_Simulation::writeTransportableStateNumber(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::TransportableState state) {
     324           30 :     StoHelp::writeTypedInt(outputStorage, (int)server.getTransportableStateChanges().find(state)->second.size());
     325           30 : }
     326              : 
     327              : 
     328              : void
     329           30 : TraCIServerAPI_Simulation::writeTransportableStateIDs(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::TransportableState state) {
     330           30 :     StoHelp::writeTypedStringList(outputStorage, server.getTransportableStateChanges().find(state)->second);
     331           30 : }
     332              : 
     333              : 
     334              : void
     335          261 : TraCIServerAPI_Simulation::commandPositionConversion(tcpip::Storage& inputStorage,
     336              :         const int compoundSize, tcpip::Storage& outputStorage) {
     337              :     std::pair<MSLane*, double> roadPos;
     338              :     Position cartesianPos;
     339              :     Position geoPos;
     340              :     double z = 0;
     341              : 
     342              :     // actual position type that will be converted
     343          261 :     int srcPosType = inputStorage.readUnsignedByte();
     344              : 
     345          261 :     switch (srcPosType) {
     346          106 :         case libsumo::POSITION_2D:
     347              :         case libsumo::POSITION_3D:
     348              :         case libsumo::POSITION_LON_LAT:
     349              :         case libsumo::POSITION_LON_LAT_ALT: {
     350          106 :             const double x = inputStorage.readDouble();
     351          106 :             const double y = inputStorage.readDouble();
     352          106 :             if (srcPosType != libsumo::POSITION_2D && srcPosType != libsumo::POSITION_LON_LAT) {
     353            6 :                 z = inputStorage.readDouble();
     354              :             }
     355              :             geoPos.set(x, y);
     356              :             cartesianPos.set(x, y);
     357          106 :             if (srcPosType == libsumo::POSITION_LON_LAT || srcPosType == libsumo::POSITION_LON_LAT_ALT) {
     358           13 :                 GeoConvHelper::getFinal().x2cartesian_const(cartesianPos);
     359              :             } else {
     360           93 :                 GeoConvHelper::getFinal().cartesian2geo(geoPos);
     361              :             }
     362              :         }
     363              :         break;
     364          155 :         case libsumo::POSITION_ROADMAP: {
     365          155 :             const std::string roadID = inputStorage.readString();
     366          155 :             const double pos = inputStorage.readDouble();
     367          155 :             const int laneIdx = inputStorage.readUnsignedByte();
     368              :             // convert edge,offset,laneIdx to cartesian position
     369          305 :             cartesianPos = geoPos = libsumo::Helper::getLaneChecking(roadID, laneIdx, pos)->geometryPositionAtOffset(pos);
     370              :             z = cartesianPos.z();
     371          150 :             GeoConvHelper::getFinal().cartesian2geo(geoPos);
     372              :         }
     373          150 :         break;
     374            0 :         default:
     375            0 :             throw libsumo::TraCIException("Source position type not supported");
     376              :     }
     377              : 
     378          256 :     const int destPosType = StoHelp::readTypedUnsignedByte(inputStorage, "Destination position type must be of type ubyte.");
     379              :     SUMOVehicleClass vClass = SVC_IGNORING;
     380          256 :     if (compoundSize == 3) {
     381           79 :         inputStorage.readUnsignedByte();
     382           79 :         const std::string& vClassString = inputStorage.readString();
     383           79 :         if (!SumoVehicleClassStrings.hasString(vClassString)) {
     384            0 :             throw libsumo::TraCIException("Unknown vehicle class '" + vClassString + "'.");
     385              :         }
     386           79 :         vClass = SumoVehicleClassStrings.get(vClassString);
     387              :     }
     388              : 
     389          256 :     switch (destPosType) {
     390           90 :         case libsumo::POSITION_ROADMAP: {
     391              :             // convert cartesion position to edge,offset,lane_index
     392           90 :             roadPos = libsumo::Helper::convertCartesianToRoadMap(cartesianPos, vClass);
     393           90 :             if (roadPos.first == nullptr) {
     394            0 :                 throw libsumo::TraCIException("No matching lane found.");
     395              :             }
     396              :             // write result that is added to response msg
     397           90 :             outputStorage.writeUnsignedByte(libsumo::POSITION_ROADMAP);
     398           90 :             outputStorage.writeString(roadPos.first->getEdge().getID());
     399           90 :             outputStorage.writeDouble(roadPos.second);
     400           90 :             outputStorage.writeUnsignedByte(roadPos.first->getIndex());
     401              :         }
     402              :         break;
     403          166 :         case libsumo::POSITION_2D:
     404              :         case libsumo::POSITION_3D:
     405              :         case libsumo::POSITION_LON_LAT:
     406              :         case libsumo::POSITION_LON_LAT_ALT:
     407          166 :             outputStorage.writeUnsignedByte(destPosType);
     408          166 :             if (destPosType == libsumo::POSITION_LON_LAT || destPosType == libsumo::POSITION_LON_LAT_ALT) {
     409           20 :                 outputStorage.writeDouble(geoPos.x());
     410           20 :                 outputStorage.writeDouble(geoPos.y());
     411              :             } else {
     412          146 :                 outputStorage.writeDouble(cartesianPos.x());
     413          146 :                 outputStorage.writeDouble(cartesianPos.y());
     414              :             }
     415          166 :             if (destPosType != libsumo::POSITION_2D && destPosType != libsumo::POSITION_LON_LAT) {
     416           11 :                 outputStorage.writeDouble(z);
     417              :             }
     418              :             break;
     419            0 :         default:
     420            0 :             throw libsumo::TraCIException("Destination position type not supported");
     421              :     }
     422          256 : }
     423              : 
     424              : 
     425              : void
     426          256 : TraCIServerAPI_Simulation::commandDistanceRequest(tcpip::Storage& inputStorage, tcpip::Storage& outputStorage) {
     427              :     Position pos1;
     428              :     Position pos2;
     429          256 :     std::pair<const MSLane*, double> roadPos1;
     430          256 :     std::pair<const MSLane*, double> roadPos2;
     431              : 
     432              :     // read position 1
     433          256 :     int posType = inputStorage.readUnsignedByte();
     434          256 :     switch (posType) {
     435          139 :         case libsumo::POSITION_ROADMAP: {
     436          139 :             std::string roadID = inputStorage.readString();
     437          139 :             roadPos1.second = inputStorage.readDouble();
     438          139 :             roadPos1.first = libsumo::Helper::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos1.second);
     439          139 :             pos1 = roadPos1.first->geometryPositionAtOffset(roadPos1.second);
     440              :             break;
     441              :         }
     442          114 :         case libsumo::POSITION_2D:
     443              :         case libsumo::POSITION_3D: {
     444          114 :             double p1x = inputStorage.readDouble();
     445          114 :             double p1y = inputStorage.readDouble();
     446              :             pos1.set(p1x, p1y);
     447              :         }
     448          114 :         if (posType == libsumo::POSITION_3D) {
     449            4 :             inputStorage.readDouble();// z value is ignored
     450              :         }
     451          114 :         roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);
     452          114 :         break;
     453            3 :         case libsumo::POSITION_LON_LAT:
     454              :         case libsumo::POSITION_LON_LAT_ALT: {
     455            3 :             double p1x = inputStorage.readDouble();
     456            3 :             double p1y = inputStorage.readDouble();
     457              :             pos1.set(p1x, p1y);
     458            3 :             GeoConvHelper::getFinal().x2cartesian_const(pos1);
     459              :         }
     460            3 :         if (posType == libsumo::POSITION_LON_LAT_ALT) {
     461            0 :             inputStorage.readDouble();// altitude value is ignored
     462              :         }
     463            3 :         roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);
     464            3 :         break;
     465            0 :         default:
     466            0 :             throw libsumo::TraCIException("Unknown position format used for distance request");
     467              :     }
     468              : 
     469              :     // read position 2
     470          256 :     posType = inputStorage.readUnsignedByte();
     471          256 :     switch (posType) {
     472          139 :         case libsumo::POSITION_ROADMAP: {
     473          139 :             std::string roadID = inputStorage.readString();
     474          139 :             roadPos2.second = inputStorage.readDouble();
     475          139 :             roadPos2.first = libsumo::Helper::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos2.second);
     476          139 :             pos2 = roadPos2.first->geometryPositionAtOffset(roadPos2.second);
     477              :             break;
     478              :         }
     479          114 :         case libsumo::POSITION_2D:
     480              :         case libsumo::POSITION_3D: {
     481          114 :             double p2x = inputStorage.readDouble();
     482          114 :             double p2y = inputStorage.readDouble();
     483              :             pos2.set(p2x, p2y);
     484              :         }
     485          114 :         if (posType == libsumo::POSITION_3D) {
     486            4 :             inputStorage.readDouble();// z value is ignored
     487              :         }
     488          114 :         roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);
     489          114 :         break;
     490            3 :         case libsumo::POSITION_LON_LAT:
     491              :         case libsumo::POSITION_LON_LAT_ALT: {
     492            3 :             double p2x = inputStorage.readDouble();
     493            3 :             double p2y = inputStorage.readDouble();
     494              :             pos2.set(p2x, p2y);
     495            3 :             GeoConvHelper::getFinal().x2cartesian_const(pos2);
     496              :         }
     497            3 :         if (posType == libsumo::POSITION_LON_LAT_ALT) {
     498            0 :             inputStorage.readDouble();// altitude value is ignored
     499              :         }
     500            3 :         roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);
     501            3 :         break;
     502            0 :         default:
     503            0 :             throw libsumo::TraCIException("Unknown position format used for distance request");
     504              :     }
     505              : 
     506              :     // read distance type
     507          256 :     const int distType = inputStorage.readUnsignedByte();
     508              : 
     509              :     double distance = 0.0;
     510          256 :     if (distType == libsumo::REQUEST_DRIVINGDIST) {
     511          139 :         distance = libsumo::Helper::getDrivingDistance(roadPos1, roadPos2);
     512              :     } else {
     513              :         // compute air distance (default)
     514          117 :         distance = pos1.distanceTo(pos2);
     515              :     }
     516              :     // write response command
     517              :     StoHelp::writeTypedDouble(outputStorage, distance);
     518          256 : }
     519              : 
     520              : 
     521              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1