Path: blob/main/src/traci-server/TraCIServerAPI_Simulation.cpp
169665 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 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,47tcpip::Storage& outputStorage) {48const int variable = inputStorage.readUnsignedByte();49const std::string id = inputStorage.readString();50server.initWrapper(libsumo::RESPONSE_GET_SIM_VARIABLE, variable, id);51try {52// unlike the other domains we cannot check here first whether libsumo::Simulation can handle it because the implementations for the state variables differ53switch (variable) {54case libsumo::VAR_LOADED_VEHICLES_NUMBER:55writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::BUILT);56break;57case libsumo::VAR_LOADED_VEHICLES_IDS:58writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::BUILT);59break;60case libsumo::VAR_DEPARTED_VEHICLES_NUMBER:61writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::DEPARTED);62break;63case libsumo::VAR_DEPARTED_VEHICLES_IDS:64writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::DEPARTED);65break;66case libsumo::VAR_TELEPORT_STARTING_VEHICLES_NUMBER:67writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_TELEPORT);68break;69case libsumo::VAR_TELEPORT_STARTING_VEHICLES_IDS:70writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_TELEPORT);71break;72case libsumo::VAR_TELEPORT_ENDING_VEHICLES_NUMBER:73writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_TELEPORT);74break;75case libsumo::VAR_TELEPORT_ENDING_VEHICLES_IDS:76writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_TELEPORT);77break;78case libsumo::VAR_ARRIVED_VEHICLES_NUMBER:79writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ARRIVED);80break;81case libsumo::VAR_ARRIVED_VEHICLES_IDS:82writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ARRIVED);83break;84case libsumo::VAR_DEPARTED_PERSONS_NUMBER:85writeTransportableStateNumber(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_DEPARTED);86break;87case libsumo::VAR_DEPARTED_PERSONS_IDS:88writeTransportableStateIDs(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_DEPARTED);89break;90case libsumo::VAR_ARRIVED_PERSONS_NUMBER:91writeTransportableStateNumber(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_ARRIVED);92break;93case libsumo::VAR_ARRIVED_PERSONS_IDS:94writeTransportableStateIDs(server, server.getWrapperStorage(), MSNet::TransportableState::PERSON_ARRIVED);95break;96case libsumo::VAR_PARKING_STARTING_VEHICLES_NUMBER:97writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_PARKING);98break;99case libsumo::VAR_PARKING_STARTING_VEHICLES_IDS:100writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_PARKING);101break;102case libsumo::VAR_PARKING_MANEUVERING_VEHICLES_NUMBER:103writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::MANEUVERING);104break;105case libsumo::VAR_PARKING_MANEUVERING_VEHICLES_IDS:106writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::MANEUVERING);107break;108case libsumo::VAR_PARKING_ENDING_VEHICLES_NUMBER:109writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_PARKING);110break;111case libsumo::VAR_PARKING_ENDING_VEHICLES_IDS:112writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_PARKING);113break;114case libsumo::VAR_STOP_STARTING_VEHICLES_NUMBER:115writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_STOP);116break;117case libsumo::VAR_STOP_STARTING_VEHICLES_IDS:118writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::STARTING_STOP);119break;120case libsumo::VAR_STOP_ENDING_VEHICLES_NUMBER:121writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_STOP);122break;123case libsumo::VAR_STOP_ENDING_VEHICLES_IDS:124writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::ENDING_STOP);125break;126case libsumo::VAR_COLLIDING_VEHICLES_NUMBER:127writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::COLLISION);128break;129case libsumo::VAR_COLLIDING_VEHICLES_IDS:130writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::COLLISION);131break;132case libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_NUMBER:133writeVehicleStateNumber(server, server.getWrapperStorage(), MSNet::VehicleState::EMERGENCYSTOP);134break;135case libsumo::VAR_EMERGENCYSTOPPING_VEHICLES_IDS:136writeVehicleStateIDs(server, server.getWrapperStorage(), MSNet::VehicleState::EMERGENCYSTOP);137break;138case libsumo::VAR_COLLISIONS: {139std::vector<libsumo::TraCICollision> collisions = libsumo::Simulation::getCollisions();140server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_COMPOUND);141const int cnt = 1 + (int)collisions.size() * 4;142server.getWrapperStorage().writeInt(cnt);143server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_INTEGER);144server.getWrapperStorage().writeInt((int)collisions.size());145for (const auto& c : collisions) {146server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);147server.getWrapperStorage().writeString(c.collider);148server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);149server.getWrapperStorage().writeString(c.victim);150server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);151server.getWrapperStorage().writeString(c.colliderType);152server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);153server.getWrapperStorage().writeString(c.victimType);154server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);155server.getWrapperStorage().writeDouble(c.colliderSpeed);156server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);157server.getWrapperStorage().writeDouble(c.victimSpeed);158server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);159server.getWrapperStorage().writeString(c.type);160server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_STRING);161server.getWrapperStorage().writeString(c.lane);162server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_DOUBLE);163server.getWrapperStorage().writeDouble(c.pos);164}165break;166}167case libsumo::VAR_NET_BOUNDING_BOX: {168server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_POLYGON);169libsumo::TraCIPositionVector tb = libsumo::Simulation::getNetBoundary();170server.getWrapperStorage().writeByte(2);171server.getWrapperStorage().writeDouble(tb.value[0].x);172server.getWrapperStorage().writeDouble(tb.value[0].y);173server.getWrapperStorage().writeDouble(tb.value[1].x);174server.getWrapperStorage().writeDouble(tb.value[1].y);175break;176}177case libsumo::POSITION_CONVERSION: {178if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {179return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Position conversion requires a compound object.", outputStorage);180}181const int compoundSize = inputStorage.readInt();182if (compoundSize < 2 || compoundSize > 3) {183return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Position conversion requires a source position and a position type as parameter.", outputStorage);184}185if (!commandPositionConversion(server, inputStorage, compoundSize, server.getWrapperStorage(), libsumo::CMD_GET_SIM_VARIABLE)) {186return false;187}188break;189}190case libsumo::DISTANCE_REQUEST:191if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {192return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of distance requires a compound object.", outputStorage);193}194if (inputStorage.readInt() != 3) {195return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of distance requires two positions and a distance type as parameter.", outputStorage);196}197if (!commandDistanceRequest(server, inputStorage, server.getWrapperStorage(), libsumo::CMD_GET_SIM_VARIABLE)) {198return false;199}200break;201case libsumo::FIND_ROUTE: {202if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {203return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a compound object.", outputStorage);204}205if (inputStorage.readInt() != 5) {206return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires five parameter.", outputStorage);207}208std::string from, to, vtype;209double depart;210if (!server.readTypeCheckingString(inputStorage, from)) {211return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as first parameter.", outputStorage);212}213if (!server.readTypeCheckingString(inputStorage, to)) {214return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as second parameter.", outputStorage);215}216if (!server.readTypeCheckingString(inputStorage, vtype)) {217return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as third parameter.", outputStorage);218}219if (!server.readTypeCheckingDouble(inputStorage, depart)) {220return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as fourth parameter.", outputStorage);221}222const int routingMode = StoHelp::readTypedInt(inputStorage, "Retrieval of a route requires an integer as fifth parameter.");223libsumo::StorageHelper::writeStage(server.getWrapperStorage(), libsumo::Simulation::findRoute(from, to, vtype, depart, routingMode));224break;225}226case libsumo::FIND_INTERMODAL_ROUTE: {227if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {228return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of an intermodal route requires a compound object.", outputStorage);229}230if (inputStorage.readInt() != 13) {231return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of an intermodal route requires thirteen parameters.", outputStorage);232}233std::string from, to, modes, ptype, vtype, destStop;234double depart, speed, walkFactor, departPos, arrivalPos, departPosLat;235if (!server.readTypeCheckingString(inputStorage, from)) {236return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as first parameter.", outputStorage);237}238if (!server.readTypeCheckingString(inputStorage, to)) {239return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as second parameter.", outputStorage);240}241if (!server.readTypeCheckingString(inputStorage, modes)) {242return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as third parameter.", outputStorage);243}244if (!server.readTypeCheckingDouble(inputStorage, depart)) {245return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as fourth parameter.", outputStorage);246}247const int routingMode = StoHelp::readTypedInt(inputStorage, "Retrieval of a route requires an integer as fifth parameter.");248if (!server.readTypeCheckingDouble(inputStorage, speed)) {249return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as sixth parameter.", outputStorage);250}251if (!server.readTypeCheckingDouble(inputStorage, walkFactor)) {252return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as seventh parameter.", outputStorage);253}254if (!server.readTypeCheckingDouble(inputStorage, departPos)) {255return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as eigth parameter.", outputStorage);256}257if (!server.readTypeCheckingDouble(inputStorage, arrivalPos)) {258return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as nineth parameter.", outputStorage);259}260if (!server.readTypeCheckingDouble(inputStorage, departPosLat)) {261return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a double as tenth parameter.", outputStorage);262}263if (!server.readTypeCheckingString(inputStorage, ptype)) {264return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as eleventh parameter.", outputStorage);265}266if (!server.readTypeCheckingString(inputStorage, vtype)) {267return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as twelvth parameter.", outputStorage);268}269if (!server.readTypeCheckingString(inputStorage, destStop)) {270return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Retrieval of a route requires a string as thirteenth parameter.", outputStorage);271}272const std::vector<libsumo::TraCIStage>& result = libsumo::Simulation::findIntermodalRoute(from, to, modes, depart, routingMode, speed, walkFactor, departPos, arrivalPos, departPosLat, ptype, vtype, destStop);273server.getWrapperStorage().writeUnsignedByte(libsumo::TYPE_COMPOUND);274server.getWrapperStorage().writeInt((int)result.size());275for (const libsumo::TraCIStage& s : result) {276libsumo::StorageHelper::writeStage(server.getWrapperStorage(), s);277}278break;279}280default:281if (!libsumo::Simulation::handleVariable(id, variable, &server, &inputStorage)) {282return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, "Get Simulation Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);283}284}285} catch (libsumo::TraCIException& e) {286return server.writeErrorStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, e.what(), outputStorage);287}288server.writeStatusCmd(libsumo::CMD_GET_SIM_VARIABLE, libsumo::RTYPE_OK, "", outputStorage);289server.writeResponseWithLength(outputStorage, server.getWrapperStorage());290return true;291}292293294bool295TraCIServerAPI_Simulation::processSet(TraCIServer& server, tcpip::Storage& inputStorage,296tcpip::Storage& outputStorage) {297std::string warning = ""; // additional description for response298// variable299int variable = inputStorage.readUnsignedByte();300if (variable != libsumo::CMD_CLEAR_PENDING_VEHICLES301&& variable != libsumo::CMD_SAVE_SIMSTATE302&& variable != libsumo::CMD_LOAD_SIMSTATE303&& variable != libsumo::VAR_PARAMETER304&& variable != libsumo::VAR_SCALE305&& variable != libsumo::CMD_MESSAGE306) {307return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "Set Simulation Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);308}309// id310std::string id = inputStorage.readString();311// process312try {313switch (variable) {314case libsumo::VAR_SCALE: {315double value;316if (!server.readTypeCheckingDouble(inputStorage, value)) {317return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "A double is needed for setting traffic scale.", outputStorage);318}319if (value < 0.0) {320return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "Traffic scale may not be negative.", outputStorage);321}322libsumo::Simulation::setScale(value);323}324break;325case libsumo::CMD_CLEAR_PENDING_VEHICLES: {326//clear any pending vehicle insertions327std::string route;328if (!server.readTypeCheckingString(inputStorage, route)) {329return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "A string is needed for clearing pending vehicles.", outputStorage);330}331libsumo::Simulation::clearPending(route);332}333break;334case libsumo::CMD_SAVE_SIMSTATE: {335//save current simulation state336std::string file;337if (!server.readTypeCheckingString(inputStorage, file)) {338return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "A string is needed for saving simulation state.", outputStorage);339}340libsumo::Simulation::saveState(file);341}342break;343case libsumo::CMD_LOAD_SIMSTATE: {344//quick-load simulation state345std::string file;346if (!server.readTypeCheckingString(inputStorage, file)) {347return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "A string is needed for loading simulation state.", outputStorage);348}349double time = libsumo::Simulation::loadState(file);350TraCIServer::getInstance()->stateLoaded(TIME2STEPS(time));351}352break;353case libsumo::VAR_PARAMETER: {354StoHelp::readCompound(inputStorage, 2, "A compound object of size 2 is needed for setting a parameter.");355const std::string name = StoHelp::readTypedString(inputStorage, "The name of the parameter must be given as a string.");356const std::string value = StoHelp::readTypedString(inputStorage, "The value of the parameter must be given as a string.");357libsumo::Simulation::setParameter(id, name, value);358break;359}360case libsumo::CMD_MESSAGE: {361std::string msg;362if (!server.readTypeCheckingString(inputStorage, msg)) {363return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, "A string is needed for adding a log message.", outputStorage);364}365libsumo::Simulation::writeMessage(msg);366}367break;368default:369break;370}371} catch (libsumo::TraCIException& e) {372return server.writeErrorStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, e.what(), outputStorage);373}374server.writeStatusCmd(libsumo::CMD_SET_SIM_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);375return true;376}377378379void380TraCIServerAPI_Simulation::writeVehicleStateNumber(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::VehicleState state) {381const std::vector<std::string>& ids = server.getVehicleStateChanges().find(state)->second;382outputStorage.writeUnsignedByte(libsumo::TYPE_INTEGER);383outputStorage.writeInt((int) ids.size());384}385386387void388TraCIServerAPI_Simulation::writeVehicleStateIDs(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::VehicleState state) {389const std::vector<std::string>& ids = server.getVehicleStateChanges().find(state)->second;390outputStorage.writeUnsignedByte(libsumo::TYPE_STRINGLIST);391outputStorage.writeStringList(ids);392}393394395void396TraCIServerAPI_Simulation::writeTransportableStateNumber(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::TransportableState state) {397const std::vector<std::string>& ids = server.getTransportableStateChanges().find(state)->second;398outputStorage.writeUnsignedByte(libsumo::TYPE_INTEGER);399outputStorage.writeInt((int)ids.size());400}401402403void404TraCIServerAPI_Simulation::writeTransportableStateIDs(TraCIServer& server, tcpip::Storage& outputStorage, MSNet::TransportableState state) {405const std::vector<std::string>& ids = server.getTransportableStateChanges().find(state)->second;406outputStorage.writeUnsignedByte(libsumo::TYPE_STRINGLIST);407outputStorage.writeStringList(ids);408}409410411bool412TraCIServerAPI_Simulation::commandPositionConversion(TraCIServer& server, tcpip::Storage& inputStorage,413const int compoundSize, tcpip::Storage& outputStorage,414const int commandId) {415std::pair<MSLane*, double> roadPos;416Position cartesianPos;417Position geoPos;418double z = 0;419420// actual position type that will be converted421int srcPosType = inputStorage.readUnsignedByte();422423switch (srcPosType) {424case libsumo::POSITION_2D:425case libsumo::POSITION_3D:426case libsumo::POSITION_LON_LAT:427case libsumo::POSITION_LON_LAT_ALT: {428const double x = inputStorage.readDouble();429const double y = inputStorage.readDouble();430if (srcPosType != libsumo::POSITION_2D && srcPosType != libsumo::POSITION_LON_LAT) {431z = inputStorage.readDouble();432}433geoPos.set(x, y);434cartesianPos.set(x, y);435if (srcPosType == libsumo::POSITION_LON_LAT || srcPosType == libsumo::POSITION_LON_LAT_ALT) {436GeoConvHelper::getFinal().x2cartesian_const(cartesianPos);437} else {438GeoConvHelper::getFinal().cartesian2geo(geoPos);439}440}441break;442case libsumo::POSITION_ROADMAP: {443const std::string roadID = inputStorage.readString();444const double pos = inputStorage.readDouble();445const int laneIdx = inputStorage.readUnsignedByte();446try {447// convert edge,offset,laneIdx to cartesian position448cartesianPos = geoPos = libsumo::Helper::getLaneChecking(roadID, laneIdx, pos)->geometryPositionAtOffset(pos);449z = cartesianPos.z();450GeoConvHelper::getFinal().cartesian2geo(geoPos);451} catch (libsumo::TraCIException& e) {452server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, e.what());453return false;454}455}456break;457default:458server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Source position type not supported");459return false;460}461462int destPosType = 0;463if (!server.readTypeCheckingUnsignedByte(inputStorage, destPosType)) {464server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Destination position type must be of type ubyte.");465return false;466}467468SUMOVehicleClass vClass = SVC_IGNORING;469if (compoundSize == 3) {470inputStorage.readUnsignedByte();471const std::string& vClassString = inputStorage.readString();472if (!SumoVehicleClassStrings.hasString(vClassString)) {473server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Unknown vehicle class '" + vClassString + "'.");474return false;475}476vClass = SumoVehicleClassStrings.get(vClassString);477}478479switch (destPosType) {480case libsumo::POSITION_ROADMAP: {481// convert cartesion position to edge,offset,lane_index482roadPos = libsumo::Helper::convertCartesianToRoadMap(cartesianPos, vClass);483if (roadPos.first == nullptr) {484server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "No matching lane found.");485return false;486}487// write result that is added to response msg488outputStorage.writeUnsignedByte(libsumo::POSITION_ROADMAP);489outputStorage.writeString(roadPos.first->getEdge().getID());490outputStorage.writeDouble(roadPos.second);491outputStorage.writeUnsignedByte(roadPos.first->getIndex());492}493break;494case libsumo::POSITION_2D:495case libsumo::POSITION_3D:496case libsumo::POSITION_LON_LAT:497case libsumo::POSITION_LON_LAT_ALT:498outputStorage.writeUnsignedByte(destPosType);499if (destPosType == libsumo::POSITION_LON_LAT || destPosType == libsumo::POSITION_LON_LAT_ALT) {500outputStorage.writeDouble(geoPos.x());501outputStorage.writeDouble(geoPos.y());502} else {503outputStorage.writeDouble(cartesianPos.x());504outputStorage.writeDouble(cartesianPos.y());505}506if (destPosType != libsumo::POSITION_2D && destPosType != libsumo::POSITION_LON_LAT) {507outputStorage.writeDouble(z);508}509break;510default:511server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Destination position type not supported");512return false;513}514return true;515}516517518bool519TraCIServerAPI_Simulation::commandDistanceRequest(TraCIServer& server, tcpip::Storage& inputStorage,520tcpip::Storage& outputStorage, int commandId) {521Position pos1;522Position pos2;523std::pair<const MSLane*, double> roadPos1;524std::pair<const MSLane*, double> roadPos2;525526// read position 1527int posType = inputStorage.readUnsignedByte();528switch (posType) {529case libsumo::POSITION_ROADMAP:530try {531std::string roadID = inputStorage.readString();532roadPos1.second = inputStorage.readDouble();533roadPos1.first = libsumo::Helper::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos1.second);534pos1 = roadPos1.first->geometryPositionAtOffset(roadPos1.second);535} catch (libsumo::TraCIException& e) {536server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, e.what());537return false;538}539break;540case libsumo::POSITION_2D:541case libsumo::POSITION_3D: {542double p1x = inputStorage.readDouble();543double p1y = inputStorage.readDouble();544pos1.set(p1x, p1y);545}546if (posType == libsumo::POSITION_3D) {547inputStorage.readDouble();// z value is ignored548}549roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);550break;551case libsumo::POSITION_LON_LAT:552case libsumo::POSITION_LON_LAT_ALT: {553double p1x = inputStorage.readDouble();554double p1y = inputStorage.readDouble();555pos1.set(p1x, p1y);556GeoConvHelper::getFinal().x2cartesian_const(pos1);557}558if (posType == libsumo::POSITION_LON_LAT_ALT) {559inputStorage.readDouble();// altitude value is ignored560}561roadPos1 = libsumo::Helper::convertCartesianToRoadMap(pos1, SVC_IGNORING);562break;563default:564server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Unknown position format used for distance request");565return false;566}567568// read position 2569posType = inputStorage.readUnsignedByte();570switch (posType) {571case libsumo::POSITION_ROADMAP:572try {573std::string roadID = inputStorage.readString();574roadPos2.second = inputStorage.readDouble();575roadPos2.first = libsumo::Helper::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos2.second);576pos2 = roadPos2.first->geometryPositionAtOffset(roadPos2.second);577} catch (libsumo::TraCIException& e) {578server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, e.what());579return false;580}581break;582case libsumo::POSITION_2D:583case libsumo::POSITION_3D: {584double p2x = inputStorage.readDouble();585double p2y = inputStorage.readDouble();586pos2.set(p2x, p2y);587}588if (posType == libsumo::POSITION_3D) {589inputStorage.readDouble();// z value is ignored590}591roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);592break;593case libsumo::POSITION_LON_LAT:594case libsumo::POSITION_LON_LAT_ALT: {595double p2x = inputStorage.readDouble();596double p2y = inputStorage.readDouble();597pos2.set(p2x, p2y);598GeoConvHelper::getFinal().x2cartesian_const(pos2);599}600if (posType == libsumo::POSITION_LON_LAT_ALT) {601inputStorage.readDouble();// altitude value is ignored602}603roadPos2 = libsumo::Helper::convertCartesianToRoadMap(pos2, SVC_IGNORING);604break;605default:606server.writeStatusCmd(commandId, libsumo::RTYPE_ERR, "Unknown position format used for distance request");607return false;608}609610// read distance type611const int distType = inputStorage.readUnsignedByte();612613double distance = 0.0;614if (distType == libsumo::REQUEST_DRIVINGDIST) {615distance = libsumo::Helper::getDrivingDistance(roadPos1, roadPos2);616} else {617// compute air distance (default)618distance = pos1.distanceTo(pos2);619}620// write response command621outputStorage.writeUnsignedByte(libsumo::TYPE_DOUBLE);622outputStorage.writeDouble(distance);623return true;624}625626627/****************************************************************************/628629630