Path: blob/main/src/traci-server/TraCIServerAPI_Simulation.cpp
193678 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file TraCIServerAPI_Simulation.cpp14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @author Laura Bieker18/// @date Sept 200219///20// APIs for getting/setting simulation values via TraCI21/****************************************************************************/22#include <config.h>2324#include <utils/common/StdDefs.h>25#include <utils/geom/GeoConvHelper.h>26#include <microsim/MSNet.h>27#include <microsim/MSEdgeControl.h>28#include <microsim/MSInsertionControl.h>29#include <microsim/MSEdge.h>30#include <microsim/MSLane.h>31#include <microsim/MSVehicle.h>32#include <microsim/MSVehicleControl.h>33#include <microsim/MSStateHandler.h>34#include <microsim/MSStoppingPlace.h>35#include <libsumo/Helper.h>36#include <libsumo/Simulation.h>37#include <libsumo/TraCIConstants.h>38#include <libsumo/StorageHelper.h>39#include "TraCIServerAPI_Simulation.h"404142// ===========================================================================43// method definitions44// ===========================================================================45bool46TraCIServerAPI_Simulation::processGet(TraCIServer& server, tcpip::Storage& inputStorage,47const std::string& objID, const int variable) {48// unlike the other domains we cannot check here first whether libsumo::Simulation can handle it because the implementations for the state variables differ49switch (variable) {50case libsumo::VAR_LOADED_VEHICLES_NUMBER:51writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::BUILT);52break;53case libsumo::VAR_LOADED_VEHICLES_IDS:54writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::BUILT);55break;56case libsumo::VAR_DEPARTED_VEHICLES_NUMBER:57writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::DEPARTED);58break;59case libsumo::VAR_DEPARTED_VEHICLES_IDS:60writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::DEPARTED);61break;62case libsumo::VAR_TELEPORT_STARTING_VEHICLES_NUMBER:63writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_TELEPORT);64break;65case libsumo::VAR_TELEPORT_STARTING_VEHICLES_IDS:66writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_TELEPORT);67break;68case libsumo::VAR_TELEPORT_ENDING_VEHICLES_NUMBER:69writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_TELEPORT);70break;71case libsumo::VAR_TELEPORT_ENDING_VEHICLES_IDS:72writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_TELEPORT);73break;74case libsumo::VAR_ARRIVED_VEHICLES_NUMBER:75writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ARRIVED);76break;77case libsumo::VAR_ARRIVED_VEHICLES_IDS:78writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ARRIVED);79break;80case libsumo::VAR_DEPARTED_PERSONS_NUMBER:81writeTransportableStateNumber(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_DEPARTED);82break;83case libsumo::VAR_DEPARTED_PERSONS_IDS:84writeTransportableStateIDs(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_DEPARTED);85break;86case libsumo::VAR_ARRIVED_PERSONS_NUMBER:87writeTransportableStateNumber(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_ARRIVED);88break;89case libsumo::VAR_ARRIVED_PERSONS_IDS:90writeTransportableStateIDs(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_ARRIVED);91break;92case libsumo::VAR_PARKING_STARTING_VEHICLES_NUMBER:93writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_PARKING);94break;95case libsumo::VAR_PARKING_STARTING_VEHICLES_IDS:96writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_PARKING);97break;98case libsumo::VAR_PARKING_MANEUVERING_VEHICLES_NUMBER:99writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::MANEUVERING);100break;101case libsumo::VAR_PARKING_MANEUVERING_VEHICLES_IDS:102writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::MANEUVERING);103break;104case libsumo::VAR_PARKING_ENDING_VEHICLES_NUMBER:105writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_PARKING);106break;107case libsumo::VAR_PARKING_ENDING_VEHICLES_IDS:108writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_PARKING);109break;110case libsumo::VAR_STOP_STARTING_VEHICLES_NUMBER:111writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_STOP);112break;113case libsumo::VAR_STOP_STARTING_VEHICLES_IDS:114writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_STOP);115break;116case libsumo::VAR_STOP_ENDING_VEHICLES_NUMBER:117writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_STOP);118break;119case libsumo::VAR_STOP_ENDING_VEHICLES_IDS:120writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_STOP);121break;122case libsumo::VAR_COLLIDING_VEHICLES_NUMBER:123writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::COLLISION);124break;125case libsumo::VAR_COLLIDING_VEHICLES_IDS:126writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::COLLISION);127break;128case libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_NUMBER:129writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::EMERGENCYSTOP);130break;131case libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_IDS:132writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::EMERGENCYSTOP);133break;134case libsumo::VAR_COLLISIONS: {135std::vector<libsumo::TraCICollision> collisions = libsumo::Simulation::getCollisions();136server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_COMPOUND);137const int cnt = 1 + (int)collisions.size() * 4;138server.getWrapperStorage().writeInt(cnt);139server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_INTEGER);140server.getWrapperStorage().writeInt((int)collisions.size());141for (const auto& c : collisions) {142server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);143server.getWrapperStorage().writeString(c.collider);144server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);145server.getWrapperStorage().writeString(c.victim);146server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);147server.getWrapperStorage().writeString(c.colliderType);148server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);149server.getWrapperStorage().writeString(c.victimType);150server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);151server.getWrapperStorage().writeDouble(c.colliderSpeed);152server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);153server.getWrapperStorage().writeDouble(c.victimSpeed);154server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);155server.getWrapperStorage().writeString(c.type);156server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);157server.getWrapperStorage().writeString(c.lane);158server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);159server.getWrapperStorage().writeDouble(c.pos);160}161break;162}163case libsumo::VAR_NET_BOUNDING_BOX: {164server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_POLYGON);165libsumo::TraCIPositionVector tb = libsumo::Simulation::getNetBoundary();166server.getWrapperStorage().writeByte(2);167server.getWrapperStorage().writeDouble(tb.value[0].x);168server.getWrapperStorage().writeDouble(tb.value[0].y);169server.getWrapperStorage().writeDouble(tb.value[1].x);170server.getWrapperStorage().writeDouble(tb.value[1].y);171break;172}173case libsumo::POSITION_CONVERSION: {174if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {175throw libsumo::TraCIException("Position conversion requires a compound object.");176}177const int compoundSize = inputStorage.readInt();178if (compoundSize < 2 || compoundSize > 3) {179throw libsumo::TraCIException("Position conversion requires a source position and a position type as parameter.");180}181commandPositionConversion(inputStorage, compoundSize, server.getWrapperStorage());182break;183}184case libsumo::DISTANCE_REQUEST:185if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {186throw libsumo::TraCIException("Retrieval of distance requires a compound object.");187}188if (inputStorage.readInt() != 3) {189throw libsumo::TraCIException("Retrieval of distance requires two positions and a distance type as parameter.");190}191commandDistanceRequest(inputStorage, server.getWrapperStorage());192break;193case libsumo::FIND_ROUTE: {194const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Retrieval of a route requires a compound object.");195if (parameterCount < 5 || parameterCount > 7) {196throw libsumo::TraCIException("Retrieval of a route requires between five to seven parameters.");197}198const std::string from = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as first parameter.");199const std::string to = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as second parameter.");200const std::string vtype = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as third parameter.");201const double depart = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as fourth parameter.");202const int routingMode = StoHelp::readTypedInt(inputStorage, "Retrieval of a route requires an integer as fifth parameter.");203double departPos = 0.;204if (parameterCount > 5) {205departPos = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as sixth parameter.");206}207double arrivalPos = libsumo::INVALID_DOUBLE_VALUE;208if (parameterCount > 6) {209arrivalPos = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as seventh parameter.");210}211StoHelp::writeStage(server.getWrapperStorage(), libsumo::Simulation::findRoute(from, to, vtype, depart, routingMode, departPos, arrivalPos));212break;213}214case libsumo::FIND_INTERMODAL_ROUTE: {215StoHelp::readCompound(inputStorage, 13, "Retrieval of an intermodal route requires thirteen parameters.");216const std::string from = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as first parameter.");217const std::string to = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as second parameter.");218const std::string modes = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as third parameter.");219const double depart = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as fourth parameter.");220const int routingMode = StoHelp::readTypedInt(inputStorage, "Retrieval of a route requires an integer as fifth parameter.");221const double speed = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as sixth parameter.");222const double walkFactor = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as seventh parameter.");223const double departPos = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as eighth parameter.");224const double arrivalPos = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as ninth parameter.");225const double departPosLat = StoHelp::readTypedDouble(inputStorage, "Retrieval of a route requires a double as tenth parameter.");226const std::string ptype = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as eleventh parameter.");227const std::string vtype = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as twelfth parameter.");228const std::string destStop = StoHelp::readTypedString(inputStorage, "Retrieval of a route requires a string as thirteenth parameter.");229const std::vector<libsumo::TraCIStage>& result = libsumo::Simulation::findIntermodalRoute(from, to, modes, depart, routingMode, speed, walkFactor, departPos, arrivalPos, departPosLat, ptype, vtype, destStop);230server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_COMPOUND);231server.getWrapperStorage().writeInt((int)result.size());232for (const libsumo::TraCIStage& s : result) {233StoHelp::writeStage(server.getWrapperStorage(), s);234}235break;236}237default:238if (!libsumo::Simulation::handleVariable(objID, variable, &server, &inputStorage)) {239throw libsumo::TraCIException("Get Simulation Variable: unsupported variable " + toHex(variable, 2) + " specified");240}241}242return true;243}244245246bool247TraCIServerAPI_Simulation::processSet(TraCIServer& server, tcpip::Storage& inputStorage,248tcpip::Storage& outputStorage) {249std::string warning = ""; // additional description for response250// variable251int variable = inputStorage.readUnsignedByte();252if (variable != libsumo::CMD_CLEAR_PENDING_VEHICLES253&& variable != libsumo::CMD_SAVE_SIMSTATE254&& variable != libsumo::CMD_LOAD_SIMSTATE255&& variable != libsumo::VAR_PARAMETER256&& variable != libsumo::VAR_SCALE257&& variable != libsumo::CMD_MESSAGE258) {259return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "Set Simulation Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);260}261// id262std::string id = inputStorage.readString();263// process264try {265switch (variable) {266case libsumo::VAR_SCALE: {267const double value = StoHelp::readTypedDouble(inputStorage, "A double is needed for setting traffic scale.");268if (value < 0.0) {269return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "Traffic scale may not be negative.", outputStorage);270}271libsumo::Simulation::setScale(value);272}273break;274case libsumo::CMD_CLEAR_PENDING_VEHICLES:275//clear any pending vehicle insertions276libsumo::Simulation::clearPending(StoHelp::readTypedString(inputStorage, "A string is needed for clearing pending vehicles."));277break;278case libsumo::CMD_SAVE_SIMSTATE:279//save current simulation state280libsumo::Simulation::saveState(StoHelp::readTypedString(inputStorage, "A string is needed for saving simulation state."));281break;282case libsumo::CMD_LOAD_SIMSTATE: {283//quick-load simulation state284const double time = libsumo::Simulation::loadState(StoHelp::readTypedString(inputStorage, "A string is needed for loading simulation state."));285TraCIServer::getInstance()->stateLoaded(TIME2STEPS(time));286}287break;288case libsumo::VAR_PARAMETER: {289StoHelp::readCompound(inputStorage, 2, "A compound object of size 2 is needed for setting a parameter.");290const std::string name = StoHelp::readTypedString(inputStorage, "The name of the parameter must be given as a string.");291const std::string value = StoHelp::readTypedString(inputStorage, "The value of the parameter must be given as a string.");292libsumo::Simulation::setParameter(id, name, value);293break;294}295case libsumo::CMD_MESSAGE:296libsumo::Simulation::writeMessage(StoHelp::readTypedString(inputStorage, "A string is needed for adding a log message."));297break;298default:299break;300}301} catch (libsumo::TraCIException& e) {302return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, e.what(), outputStorage);303}304server.writeStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);305return true;306}307308309void310TraCIServerAPI_Simulation::writeVehicleStateNumber(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::VehicleState state) {311StoHelp::writeTypedInt(outputStorage, (int)server.getVehicleStateChanges().find(state)->second.size());312}313314315void316TraCIServerAPI_Simulation::writeVehicleStateIDs(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::VehicleState state) {317StoHelp::writeTypedStringList(outputStorage, server.getVehicleStateChanges().find(state)->second);318}319320321void322TraCIServerAPI_Simulation::writeTransportableStateNumber(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::TransportableState state) {323StoHelp::writeTypedInt(outputStorage, (int)server.getTransportableStateChanges().find(state)->second.size());324}325326327void328TraCIServerAPI_Simulation::writeTransportableStateIDs(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::TransportableState state) {329StoHelp::writeTypedStringList(outputStorage, server.getTransportableStateChanges().find(state)->second);330}331332333void334TraCIServerAPI_Simulation::commandPositionConversion(tcpip::Storage& inputStorage,335const int compoundSize, tcpip::Storage& outputStorage) {336std::pair<MSLane*, double> roadPos;337Position cartesianPos;338Position geoPos;339double z = 0;340341// actual position type that will be converted342int srcPosType = inputStorage.readUnsignedByte();343344switch (srcPosType) {345case libsumo::POSITION_2D:346case libsumo::POSITION_3D:347case libsumo::POSITION_LON_LAT:348case libsumo::POSITION_LON_LAT_ALT: {349const double x = inputStorage.readDouble();350const double y = inputStorage.readDouble();351if (srcPosType != libsumo::POSITION_2D && srcPosType != libsumo::POSITION_LON_LAT) {352z = inputStorage.readDouble();353}354geoPos.set(x, y);355cartesianPos.set(x, y);356if (srcPosType == libsumo::POSITION_LON_LAT || srcPosType == libsumo::POSITION_LON_LAT_ALT) {357GeoConvHelper::getFinal().x2cartesian_const(cartesianPos);358} else {359GeoConvHelper::getFinal().cartesian2geo(geoPos);360}361}362break;363case libsumo::POSITION_ROADMAP: {364const std::string roadID = inputStorage.readString();365const double pos = inputStorage.readDouble();366const int laneIdx = inputStorage.readUnsignedByte();367// convert edge,offset,laneIdx to cartesian position368cartesianPos = geoPos = libsumo::Helper::getLaneChecking(roadID, laneIdx, pos)->geometryPositionAtOffset(pos);369z = cartesianPos.z();370GeoConvHelper::getFinal().cartesian2geo(geoPos);371}372break;373default:374throw libsumo::TraCIException("Source position type not supported");375}376377const int destPosType = StoHelp::readTypedUnsignedByte(inputStorage, "Destination position type must be of type ubyte.");378SUMOVehicleClass vClass = SVC_IGNORING;379if (compoundSize == 3) {380inputStorage.readUnsignedByte();381const std::string& vClassString = inputStorage.readString();382if (!SumoVehicleClassStrings.hasString(vClassString)) {383throw libsumo::TraCIException("Unknown vehicle class '" + vClassString + "'.");384}385vClass = SumoVehicleClassStrings.get(vClassString);386}387388switch (destPosType) {389case libsumo::POSITION_ROADMAP: {390// convert cartesion position to edge,offset,lane_index391roadPos = libsumo::Helper::convertCartesianToRoadMap(cartesianPos, vClass);392if (roadPos.first == nullptr) {393throw libsumo::TraCIException("No matching lane found.");394}395// write result that is added to response msg396outputStorage.writeUnsignedByte(libsumo::POSITION_ROADMAP);397outputStorage.writeString(roadPos.first->getEdge().getID());398outputStorage.writeDouble(roadPos.second);399outputStorage.writeUnsignedByte(roadPos.first->getIndex());400}401break;402case libsumo::POSITION_2D:403case libsumo::POSITION_3D:404case libsumo::POSITION_LON_LAT:405case libsumo::POSITION_LON_LAT_ALT:406outputStorage.writeUnsignedByte(destPosType);407if (destPosType == libsumo::POSITION_LON_LAT || destPosType == libsumo::POSITION_LON_LAT_ALT) {408outputStorage.writeDouble(geoPos.x());409outputStorage.writeDouble(geoPos.y());410} else {411outputStorage.writeDouble(cartesianPos.x());412outputStorage.writeDouble(cartesianPos.y());413}414if (destPosType != libsumo::POSITION_2D && destPosType != libsumo::POSITION_LON_LAT) {415outputStorage.writeDouble(z);416}417break;418default:419throw libsumo::TraCIException("Destination position type not supported");420}421}422423424void425TraCIServerAPI_Simulation::commandDistanceRequest(tcpip::Storage& inputStorage, tcpip::Storage& outputStorage) {426Position pos1;427Position pos2;428std::pair<const MSLane*, double> roadPos1;429std::pair<const MSLane*, double> roadPos2;430431// read position 1432int posType = inputStorage.readUnsignedByte();433switch (posType) {434case libsumo::POSITION_ROADMAP: {435std::string roadID = inputStorage.readString();436roadPos1.second = inputStorage.readDouble();437roadPos1.first = libsumo::Helper::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos1.second);438pos1 = roadPos1.first->geometryPositionAtOffset(roadPos1.second);439break;440}441case libsumo::POSITION_2D:442case libsumo::POSITION_3D: {443double p1x = inputStorage.readDouble();444double p1y = inputStorage.readDouble();445pos1.set(p1x, p1y);446}447if (posType == libsumo::POSITION_3D) {448inputStorage.readDouble();// z value is ignored449}450roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);451break;452case libsumo::POSITION_LON_LAT:453case libsumo::POSITION_LON_LAT_ALT: {454double p1x = inputStorage.readDouble();455double p1y = inputStorage.readDouble();456pos1.set(p1x, p1y);457GeoConvHelper::getFinal().x2cartesian_const(pos1);458}459if (posType == libsumo::POSITION_LON_LAT_ALT) {460inputStorage.readDouble();// altitude value is ignored461}462roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);463break;464default:465throw libsumo::TraCIException("Unknown position format used for distance request");466}467468// read position 2469posType = inputStorage.readUnsignedByte();470switch (posType) {471case libsumo::POSITION_ROADMAP: {472std::string roadID = inputStorage.readString();473roadPos2.second = inputStorage.readDouble();474roadPos2.first = libsumo::Helper::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos2.second);475pos2 = roadPos2.first->geometryPositionAtOffset(roadPos2.second);476break;477}478case libsumo::POSITION_2D:479case libsumo::POSITION_3D: {480double p2x = inputStorage.readDouble();481double p2y = inputStorage.readDouble();482pos2.set(p2x, p2y);483}484if (posType == libsumo::POSITION_3D) {485inputStorage.readDouble();// z value is ignored486}487roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);488break;489case libsumo::POSITION_LON_LAT:490case libsumo::POSITION_LON_LAT_ALT: {491double p2x = inputStorage.readDouble();492double p2y = inputStorage.readDouble();493pos2.set(p2x, p2y);494GeoConvHelper::getFinal().x2cartesian_const(pos2);495}496if (posType == libsumo::POSITION_LON_LAT_ALT) {497inputStorage.readDouble();// altitude value is ignored498}499roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);500break;501default:502throw libsumo::TraCIException("Unknown position format used for distance request");503}504505// read distance type506const int distType = inputStorage.readUnsignedByte();507508double distance = 0.0;509if (distType == libsumo::REQUEST_DRIVINGDIST) {510distance = libsumo::Helper::getDrivingDistance(roadPos1, roadPos2);511} else {512// compute air distance (default)513distance = pos1.distanceTo(pos2);514}515// write response command516StoHelp::writeTypedDouble(outputStorage, distance);517}518519520/****************************************************************************/521522523