Path: blob/main/src/traci-server/TraCIServerAPI_Vehicle.cpp
193870 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2009-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_Vehicle.cpp14/// @author Daniel Krajzewicz15/// @author Laura Bieker16/// @author Christoph Sommer17/// @author Michael Behrisch18/// @author Bjoern Hendriks19/// @author Mario Krumnow20/// @author Jakob Erdmann21/// @author Leonhard Luecken22/// @author Robert Hilbrich23/// @author Lara Codeca24/// @author Mirko Barthauer25/// @date 07.05.200926///27// APIs for getting/setting vehicle values via TraCI28/****************************************************************************/29#include <config.h>3031#include <microsim/MSNet.h>32#include <microsim/MSInsertionControl.h>33#include <microsim/MSVehicle.h>34#include <microsim/MSVehicleControl.h>35#include <microsim/MSLane.h>36#include <microsim/MSEdge.h>37#include <microsim/MSGlobals.h>38#include <microsim/lcmodels/MSAbstractLaneChangeModel.h>39#include <utils/geom/PositionVector.h>40#include <utils/router/DijkstraRouter.h>41#include <utils/router/DijkstraRouter.h>42#include <utils/emissions/PollutantsInterface.h>43#include <utils/emissions/HelpersHarmonoise.h>44#include <utils/vehicle/SUMOVehicleParameter.h>45#include <libsumo/StorageHelper.h>46#include <libsumo/TraCIConstants.h>47#include <libsumo/Vehicle.h>48#include <libsumo/VehicleType.h>49#include "TraCIServerAPI_Simulation.h"50#include "TraCIServerAPI_Vehicle.h"51#include "TraCIServerAPI_VehicleType.h"525354// ===========================================================================55// method definitions56// ===========================================================================57bool58TraCIServerAPI_Vehicle::processSet(TraCIServer& server, tcpip::Storage& inputStorage,59tcpip::Storage& outputStorage) {60std::string warning = ""; // additional description for response61// variable62int variable = inputStorage.readUnsignedByte();63if (variable != libsumo::CMD_STOP && variable != libsumo::CMD_CHANGELANE64&& variable != libsumo::CMD_REROUTE_TO_PARKING65&& variable != libsumo::CMD_CHANGESUBLANE && variable != libsumo::CMD_OPENGAP66&& variable != libsumo::CMD_REPLACE_STOP67&& variable != libsumo::CMD_INSERT_STOP68&& variable != libsumo::VAR_STOP_PARAMETER69&& variable != libsumo::CMD_SLOWDOWN && variable != libsumo::CMD_CHANGETARGET && variable != libsumo::CMD_RESUME70&& variable != libsumo::VAR_TYPE && variable != libsumo::VAR_ROUTE_ID && variable != libsumo::VAR_ROUTE71&& variable != libsumo::VAR_LANEPOSITION_LAT72&& variable != libsumo::VAR_UPDATE_BESTLANES73&& variable != libsumo::VAR_EDGE_TRAVELTIME && variable != libsumo::VAR_EDGE_EFFORT74&& variable != libsumo::CMD_REROUTE_TRAVELTIME && variable != libsumo::CMD_REROUTE_EFFORT75&& variable != libsumo::VAR_SIGNALS && variable != libsumo::VAR_MOVE_TO76&& variable != libsumo::VAR_LENGTH && variable != libsumo::VAR_MAXSPEED && variable != libsumo::VAR_VEHICLECLASS77&& variable != libsumo::VAR_SPEED_FACTOR && variable != libsumo::VAR_EMISSIONCLASS78&& variable != libsumo::VAR_WIDTH && variable != libsumo::VAR_MINGAP && variable != libsumo::VAR_SHAPECLASS79&& variable != libsumo::VAR_ACCEL && variable != libsumo::VAR_DECEL && variable != libsumo::VAR_IMPERFECTION80&& variable != libsumo::VAR_APPARENT_DECEL && variable != libsumo::VAR_EMERGENCY_DECEL81&& variable != libsumo::VAR_ACTIONSTEPLENGTH82&& variable != libsumo::VAR_TAU && variable != libsumo::VAR_LANECHANGE_MODE83&& variable != libsumo::VAR_SPEED && variable != libsumo::VAR_ACCELERATION && variable != libsumo::VAR_PREV_SPEED && variable != libsumo::VAR_SPEEDSETMODE && variable != libsumo::VAR_COLOR84&& variable != libsumo::ADD && variable != libsumo::ADD_FULL && variable != libsumo::REMOVE85&& variable != libsumo::VAR_HEIGHT86&& variable != libsumo::VAR_MASS87&& variable != libsumo::VAR_ROUTING_MODE88&& variable != libsumo::VAR_LATALIGNMENT89&& variable != libsumo::VAR_MAXSPEED_LAT90&& variable != libsumo::VAR_MINGAP_LAT91&& variable != libsumo::VAR_LINE92&& variable != libsumo::VAR_VIA93&& variable != libsumo::VAR_IMPATIENCE94&& variable != libsumo::VAR_BOARDING_DURATION95&& variable != libsumo::VAR_HIGHLIGHT96&& variable != libsumo::CMD_TAXI_DISPATCH97&& variable != libsumo::MOVE_TO_XY && variable != libsumo::VAR_PARAMETER/* && variable != libsumo::VAR_SPEED_TIME_LINE && variable != libsumo::VAR_LANE_TIME_LINE*/98) {99return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Change Vehicle State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);100}101// id102std::string id = inputStorage.readString();103#ifdef DEBUG_MOVEXY104std::cout << SIMTIME << " processSet veh=" << id << "\n";105#endif106const bool shouldExist = variable != libsumo::ADD && variable != libsumo::ADD_FULL;107SUMOVehicle* sumoVehicle = MSNet::getInstance()->getVehicleControl().getVehicle(id);108if (sumoVehicle == nullptr) {109if (shouldExist) {110return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);111}112}113MSBaseVehicle* v = dynamic_cast<MSBaseVehicle*>(sumoVehicle);114if (v == nullptr && shouldExist) {115return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a proper vehicle", outputStorage);116}117try {118switch (variable) {119case libsumo::CMD_STOP: {120const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Stop needs a compound object description.");121if (compoundSize < 4 || compoundSize > 7) {122return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description of four to seven items.", outputStorage);123}124// read road map position125const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first stop parameter must be the edge id given as a string.");126const double pos = StoHelp::readTypedDouble(inputStorage, "The second stop parameter must be the end position along the edge given as a double.");127const int laneIndex = StoHelp::readTypedByte(inputStorage, "The third stop parameter must be the lane index given as a byte.");128const double duration = StoHelp::readTypedDouble(inputStorage, "The fourth stop parameter must be the stopping duration given as a double.");129int stopFlags = 0;130if (compoundSize >= 5) {131stopFlags = StoHelp::readTypedByte(inputStorage, "The fifth stop parameter must be a byte indicating its parking/triggered status.");132}133double startPos = libsumo::INVALID_DOUBLE_VALUE;134if (compoundSize >= 6) {135startPos = StoHelp::readTypedDouble(inputStorage, "The sixth stop parameter must be the start position along the edge given as a double.");136}137double until = libsumo::INVALID_DOUBLE_VALUE;138if (compoundSize >= 7) {139until = StoHelp::readTypedDouble(inputStorage, "The seventh stop parameter must be the minimum departure time given as a double.");140}141libsumo::Vehicle::setStop(id, edgeID, pos, laneIndex, duration, stopFlags, startPos, until);142}143break;144case libsumo::CMD_REPLACE_STOP:145if (!insertReplaceStop(server, inputStorage, outputStorage, id, true)) {146return false;147}148break;149case libsumo::CMD_INSERT_STOP:150if (!insertReplaceStop(server, inputStorage, outputStorage, id, false)) {151return false;152}153break;154case libsumo::VAR_STOP_PARAMETER: {155const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Setting stop parameter needs a compound object description.");156if (compoundSize != 3 && compoundSize != 4) {157return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting a stop parameter needs a compound object description of 3 or 4 items.", outputStorage);158}159const int nextStopIndex = StoHelp::readTypedInt(inputStorage, "The first setStopParameter parameter must be the nextStopIndex given as an integer.");160const std::string param = StoHelp::readTypedString(inputStorage, "The second setStopParameter parameter must be the param given as a string.");161const std::string value = StoHelp::readTypedString(inputStorage, "The third setStopParameter parameter must be the value given as a string.");162int customParam = 0;163if (compoundSize == 4) {164customParam = StoHelp::readTypedByte(inputStorage, "The fourth setStopParameter parameter must be the customParam flag given as a byte.");165}166libsumo::Vehicle::setStopParameter(id, nextStopIndex, param, value, customParam != 0);167}168break;169case libsumo::CMD_REROUTE_TO_PARKING: {170StoHelp::readCompound(inputStorage, 1, "Reroute to stop needs a compound object description of 1 item.");171libsumo::Vehicle::rerouteParkingArea(id, StoHelp::readTypedString(inputStorage, "The first reroute to stop parameter must be the parking area id given as a string."));172}173break;174case libsumo::CMD_RESUME: {175StoHelp::readCompound(inputStorage, 0, "Resuming requires an empty compound object.");176libsumo::Vehicle::resume(id);177}178break;179case libsumo::CMD_CHANGELANE: {180const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Lane change needs a compound object description.");181if (compoundSize != 3 && compoundSize != 2) {182return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two or three items.", outputStorage);183}184const int laneIndex = StoHelp::readTypedByte(inputStorage, "The first lane change parameter must be the lane index given as a byte.");185const double duration = StoHelp::readTypedDouble(inputStorage, "The second lane change parameter must be the duration given as a double.");186// relative lane change187int relative = 0;188if (compoundSize == 3) {189relative = StoHelp::readTypedByte(inputStorage, "The third lane change parameter must be a Byte for defining whether a relative lane change should be applied.");190}191192if ((laneIndex < 0 || laneIndex >= (int)v->getEdge()->getLanes().size()) && relative < 1) {193return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + v->getEdge()->getID() + "'.", outputStorage);194}195196if (relative < 1) {197libsumo::Vehicle::changeLane(id, laneIndex, duration);198} else {199libsumo::Vehicle::changeLaneRelative(id, laneIndex, duration);200}201}202break;203case libsumo::CMD_CHANGESUBLANE: {204libsumo::Vehicle::changeSublane(id, StoHelp::readTypedDouble(inputStorage, "Sublane-changing requires a double."));205}206break;207case libsumo::CMD_SLOWDOWN: {208StoHelp::readCompound(inputStorage, 2, "Slow down needs a compound object description of two items.");209const double newSpeed = StoHelp::readTypedDouble(inputStorage, "The first slow down parameter must be the speed given as a double.");210if (newSpeed < 0.) {211return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Speed must not be negative", outputStorage);212}213const double duration = StoHelp::readTypedDouble(inputStorage, "The second slow down parameter must be the duration given as a double.");214if (duration < 0. || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {215return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval", outputStorage);216}217libsumo::Vehicle::slowDown(id, newSpeed, duration);218}219break;220case libsumo::CMD_CHANGETARGET: {221libsumo::Vehicle::changeTarget(id, StoHelp::readTypedString(inputStorage, "Change target requires a string containing the id of the new destination edge as parameter."));222}223break;224case libsumo::CMD_OPENGAP: {225const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Create gap needs a compound object description.");226if (compoundSize != 5 && compoundSize != 6) {227return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Create gap needs a compound object description of five or six items.", outputStorage);228}229const double newTimeHeadway = StoHelp::readTypedDouble(inputStorage, "The first create gap parameter must be the new desired time headway (tau) given as a double.");230double newSpaceHeadway = StoHelp::readTypedDouble(inputStorage, "The second create gap parameter must be the new desired space headway given as a double.");231const double duration = StoHelp::readTypedDouble(inputStorage, "The third create gap parameter must be the duration given as a double.");232const double changeRate = StoHelp::readTypedDouble(inputStorage, "The fourth create gap parameter must be the change rate given as a double.");233const double maxDecel = StoHelp::readTypedDouble(inputStorage, "The fifth create gap parameter must be the maximal braking rate given as a double.");234235if (newTimeHeadway == -1 && newSpaceHeadway == -1 && duration == -1 && changeRate == -1 && maxDecel == -1) {236libsumo::Vehicle::deactivateGapControl(id);237} else {238if (newTimeHeadway <= 0) {239if (newTimeHeadway != -1) {240return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired time headway (tau) must be positive for create gap", outputStorage);241} // else if == -1: keep vehicles current headway, see libsumo::Vehicle::openGap242}243if (newSpaceHeadway < 0) {244return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired space headway must be non-negative for create gap", outputStorage);245}246if ((duration < 0 && duration != -1) || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {247return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval for create gap", outputStorage);248}249if (changeRate <= 0) {250return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the change rate must be positive for the openGap command", outputStorage);251}252if (maxDecel <= 0 && maxDecel != -1 && maxDecel != libsumo::INVALID_DOUBLE_VALUE) {253return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the maximal braking rate must be positive for the openGap command", outputStorage);254} // else if <= 0: don't limit cf model's suggested brake rate, see libsumo::Vehicle::openGap255std::string refVehID = "";256if (compoundSize == 6) {257refVehID = StoHelp::readTypedString(inputStorage, "The sixth create gap parameter must be a reference vehicle's ID given as a string.");258}259libsumo::Vehicle::openGap(id, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel, refVehID);260}261}262break;263case libsumo::VAR_TYPE: {264libsumo::Vehicle::setType(id, StoHelp::readTypedString(inputStorage, "The vehicle type id must be given as a string."));265}266break;267case libsumo::VAR_ROUTE_ID: {268libsumo::Vehicle::setRouteID(id, StoHelp::readTypedString(inputStorage, "The route id must be given as a string."));269}270break;271case libsumo::VAR_ROUTE: {272libsumo::Vehicle::setRoute(id, StoHelp::readTypedStringList(inputStorage, "A route must be defined as a list of edge ids."));273}274break;275case libsumo::VAR_EDGE_TRAVELTIME: {276const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting travel time requires a compound object.");277std::string edgeID;278double begTime = 0.;279double endTime = std::numeric_limits<double>::max();280double value = libsumo::INVALID_DOUBLE_VALUE;281if (parameterCount == 4) {282begTime = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the begin time as first parameter.");283endTime = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the end time as second parameter.");284edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 4 parameters requires the referenced edge as third parameter.");285value = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the travel time as double as fourth parameter.");286} else if (parameterCount == 2) {287edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 2 parameters requires the referenced edge as first parameter.");288value = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 2 parameters requires the travel time as double as second parameter.");289} else if (parameterCount == 1) {290edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 1 parameter requires the referenced edge as first parameter.");291} else {292return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);293}294libsumo::Vehicle::setAdaptedTraveltime(id, edgeID, value, begTime, endTime);295}296break;297case libsumo::VAR_EDGE_EFFORT: {298const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting travel time requires a compound object.");299std::string edgeID;300double begTime = 0.;301double endTime = std::numeric_limits<double>::max();302double value = libsumo::INVALID_DOUBLE_VALUE;303if (parameterCount == 4) {304begTime = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the begin time as first parameter.");305endTime = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the end time as second parameter.");306edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 4 parameters requires the referenced edge as third parameter.");307value = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the effort as double as fourth parameter.");308} else if (parameterCount == 2) {309edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 2 parameters requires the referenced edge as first parameter.");310value = StoHelp::readTypedDouble(inputStorage, "Setting effort using 2 parameters requires the effort as double as second parameter.");311} else if (parameterCount == 1) {312edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 1 parameter requires the referenced edge as first parameter.");313} else {314return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);315}316libsumo::Vehicle::setEffort(id, edgeID, value, begTime, endTime);317}318break;319case libsumo::CMD_REROUTE_TRAVELTIME: {320StoHelp::readCompound(inputStorage, 0, "Rerouting by travel time requires an empty compound object.");321libsumo::Vehicle::rerouteTraveltime(id, false);322}323break;324case libsumo::CMD_REROUTE_EFFORT: {325StoHelp::readCompound(inputStorage, 0, "Rerouting by effort requires an empty compound object.");326libsumo::Vehicle::rerouteEffort(id);327}328break;329case libsumo::VAR_SIGNALS:330libsumo::Vehicle::setSignals(id, StoHelp::readTypedInt(inputStorage, "Setting signals requires an integer."));331break;332case libsumo::VAR_MOVE_TO: {333const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting position requires a compound object.");334if (parameterCount < 2 || parameterCount > 3) {335return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting position should obtain the lane id and the position and optionally the reason.", outputStorage);336}337const std::string laneID = StoHelp::readTypedString(inputStorage, "The first parameter for setting a position must be the lane ID given as a string.");338const double position = StoHelp::readTypedDouble(inputStorage, "The second parameter for setting a position must be the position given as a double.");339int reason = libsumo::MOVE_AUTOMATIC;340if (parameterCount == 3) {341reason = StoHelp::readTypedInt(inputStorage, "The third parameter for setting a position must be the reason given as an int.");342}343// process344libsumo::Vehicle::moveTo(id, laneID, position, reason);345}346break;347case libsumo::VAR_IMPATIENCE: {348libsumo::Vehicle::setImpatience(id, StoHelp::readTypedDouble(inputStorage, "Setting impatience requires a double."));349}350break;351case libsumo::VAR_SPEED: {352libsumo::Vehicle::setSpeed(id, StoHelp::readTypedDouble(inputStorage, "Setting speed requires a double."));353}354break;355case libsumo::VAR_ACCELERATION: {356StoHelp::readCompound(inputStorage, 2, "Setting acceleration requires 2 parameters.");357const double accel = StoHelp::readTypedDouble(inputStorage, "Setting acceleration requires the acceleration as first parameter given as a double.");358const double duration = StoHelp::readTypedDouble(inputStorage, "Setting acceleration requires the duration as second parameter given as a double.");359if (duration < 0) {360return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Duration must not be negative.", outputStorage);361}362libsumo::Vehicle::setAcceleration(id, accel, duration);363}364break;365case libsumo::VAR_PREV_SPEED: {366double prevSpeed = 0;367double prevAcceleration = libsumo::INVALID_DOUBLE_VALUE;368int inputtype = inputStorage.readUnsignedByte();369if (inputtype == libsumo::TYPE_COMPOUND) {370// Setting previous speed with 2 parameters, uses a compound object description371const int parameterCount = inputStorage.readInt();372if (parameterCount == 2) {373prevSpeed = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 2 parameters requires the previous speed as first parameter given as a double.");374prevAcceleration = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 2 parameters requires the previous acceleration as second parameter given as a double.");375} else if (parameterCount == 1) {376prevSpeed = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 1 parameter requires the previous speed as first parameter given as a double.");377} else {378return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed requires 1 or 2 parameters.", outputStorage);379}380} else if (inputtype == libsumo::TYPE_DOUBLE) {381// Setting previous speed with 1 parameter (double), no compound object description382prevSpeed = inputStorage.readDouble();383} else {384return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed requires 1 parameter given as a double or 2 parameters as compound object description.", outputStorage);385}386if (prevSpeed < 0) {387return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Previous speed must not be negative.", outputStorage);388}389libsumo::Vehicle::setPreviousSpeed(id, prevSpeed, prevAcceleration);390}391break;392case libsumo::VAR_SPEEDSETMODE:393libsumo::Vehicle::setSpeedMode(id, StoHelp::readTypedInt(inputStorage, "Setting speed mode requires an integer."));394break;395case libsumo::VAR_LANECHANGE_MODE:396libsumo::Vehicle::setLaneChangeMode(id, StoHelp::readTypedInt(inputStorage, "Setting lane change mode requires an integer."));397break;398case libsumo::VAR_ROUTING_MODE:399libsumo::Vehicle::setRoutingMode(id, StoHelp::readTypedInt(inputStorage, "Setting routing mode requires an integer."));400break;401case libsumo::VAR_COLOR: {402libsumo::Vehicle::setColor(id, StoHelp::readTypedColor(inputStorage, "The color must be given using the according type."));403break;404}405case libsumo::ADD: {406StoHelp::readCompound(inputStorage, 6, "Adding a vehicle needs six parameters.");407const std::string vTypeID = StoHelp::readTypedString(inputStorage, "First parameter (type) requires a string.");408const std::string routeID = StoHelp::readTypedString(inputStorage, "Second parameter (route) requires a string.");409const int departCode = StoHelp::readTypedInt(inputStorage, "Third parameter (depart) requires an integer.");410std::string depart = toString(STEPS2TIME(departCode));411if (-departCode == static_cast<int>(DepartDefinition::TRIGGERED)) {412depart = "triggered";413} else if (-departCode == static_cast<int>(DepartDefinition::CONTAINER_TRIGGERED)) {414depart = "containerTriggered";415} else if (-departCode == static_cast<int>(DepartDefinition::NOW)) {416depart = "now";417} else if (-departCode == static_cast<int>(DepartDefinition::SPLIT)) {418depart = "split";419} else if (-departCode == static_cast<int>(DepartDefinition::BEGIN)) {420depart = "begin";421}422423const double departPosCode = StoHelp::readTypedDouble(inputStorage, "Fourth parameter (position) requires a double.");424std::string departPos = toString(departPosCode);425if (-departPosCode == (int)DepartPosDefinition::RANDOM) {426departPos = "random";427} else if (-departPosCode == (int)DepartPosDefinition::RANDOM_FREE) {428departPos = "random_free";429} else if (-departPosCode == (int)DepartPosDefinition::FREE) {430departPos = "free";431} else if (-departPosCode == (int)DepartPosDefinition::BASE) {432departPos = "base";433} else if (-departPosCode == (int)DepartPosDefinition::LAST) {434departPos = "last";435} else if (-departPosCode == (int)DepartPosDefinition::GIVEN) {436return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid departure position.", outputStorage);437}438439const double departSpeedCode = StoHelp::readTypedDouble(inputStorage, "Fifth parameter (speed) requires a double.");440std::string departSpeed = toString(departSpeedCode);441if (-departSpeedCode == (int)DepartSpeedDefinition::RANDOM) {442departSpeed = "random";443} else if (-departSpeedCode == (int)DepartSpeedDefinition::MAX) {444departSpeed = "max";445} else if (-departSpeedCode == (int)DepartSpeedDefinition::DESIRED) {446departSpeed = "desired";447} else if (-departSpeedCode == (int)DepartSpeedDefinition::LIMIT) {448departSpeed = "speedLimit";449} else if (-departSpeedCode == (int)DepartSpeedDefinition::LAST) {450departSpeed = "last";451} else if (-departSpeedCode == (int)DepartSpeedDefinition::AVG) {452departSpeed = "avg";453}454455const int departLaneCode = StoHelp::readTypedByte(inputStorage, "Sixth parameter (lane) requires a byte.");456std::string departLane = toString(departLaneCode);457if (-departLaneCode == (int)DepartLaneDefinition::RANDOM) {458departLane = "random";459} else if (-departLaneCode == (int)DepartLaneDefinition::FREE) {460departLane = "free";461} else if (-departLaneCode == (int)DepartLaneDefinition::ALLOWED_FREE) {462departLane = "allowed";463} else if (-departLaneCode == (int)DepartLaneDefinition::BEST_FREE) {464departLane = "best";465} else if (-departLaneCode == (int)DepartLaneDefinition::FIRST_ALLOWED) {466departLane = "first";467}468libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed);469}470break;471case libsumo::ADD_FULL: {472StoHelp::readCompound(inputStorage, 14, "Adding a fully specified vehicle needs fourteen parameters.");473const std::string routeID = StoHelp::readTypedString(inputStorage, "First parameter (route) requires a string.");474const std::string vTypeID = StoHelp::readTypedString(inputStorage, "Second parameter (type) requires a string.");475const std::string depart = StoHelp::readTypedString(inputStorage, "Third parameter (depart) requires an string.");476const std::string departLane = StoHelp::readTypedString(inputStorage, "Fourth parameter (depart lane) requires a string.");477const std::string departPos = StoHelp::readTypedString(inputStorage, "Fifth parameter (depart position) requires a string.");478const std::string departSpeed = StoHelp::readTypedString(inputStorage, "Sixth parameter (depart speed) requires a string.");479const std::string arrivalLane = StoHelp::readTypedString(inputStorage, "Seventh parameter (arrival lane) requires a string.");480const std::string arrivalPos = StoHelp::readTypedString(inputStorage, "Eighth parameter (arrival position) requires a string.");481const std::string arrivalSpeed = StoHelp::readTypedString(inputStorage, "Ninth parameter (arrival speed) requires a string.");482const std::string fromTaz = StoHelp::readTypedString(inputStorage, "Tenth parameter (from taz) requires a string.");483const std::string toTaz = StoHelp::readTypedString(inputStorage, "Eleventh parameter (to taz) requires a string.");484const std::string line = StoHelp::readTypedString(inputStorage, "Twelth parameter (line) requires a string.");485const int personCapacity = StoHelp::readTypedInt(inputStorage, "13th parameter (person capacity) requires an int.");486const int personNumber = StoHelp::readTypedInt(inputStorage, "14th parameter (person number) requires an int.");487libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed, arrivalLane, arrivalPos, arrivalSpeed,488fromTaz, toTaz, line, personCapacity, personNumber);489}490break;491case libsumo::REMOVE: {492libsumo::Vehicle::remove(id, (char)StoHelp::readTypedByte(inputStorage, "Removing a vehicle requires a byte."));493}494break;495case libsumo::MOVE_TO_XY: {496const int parameterCount = StoHelp::readCompound(inputStorage, -1, "MoveToXY vehicle requires a compound object.");497if (parameterCount < 5 || parameterCount > 7) {498return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "MoveToXY vehicle should obtain: edgeID, lane, x, y, angle and optionally keepRouteFlag and matchThreshold.", outputStorage);499}500const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first parameter for moveToXY must be the edge ID given as a string.");501const int laneIndex = StoHelp::readTypedInt(inputStorage, "The second parameter for moveToXY must be lane given as an int.");502const double x = StoHelp::readTypedDouble(inputStorage, "The third parameter for moveToXY must be the x-position given as a double.");503const double y = StoHelp::readTypedDouble(inputStorage, "The fourth parameter for moveToXY must be the y-position given as a double.");504const double angle = StoHelp::readTypedDouble(inputStorage, "The fifth parameter for moveToXY must be the angle given as a double.");505int keepRouteFlag = 1;506if (parameterCount >= 6) {507keepRouteFlag = StoHelp::readTypedByte(inputStorage, "The sixth parameter for moveToXY must be the keepRouteFlag given as a byte.");508}509double matchThreshold = 100.;510if (parameterCount == 7) {511matchThreshold = StoHelp::readTypedDouble(inputStorage, "The seventh parameter for moveToXY must be the matchThreshold given as a double.");512}513libsumo::Vehicle::moveToXY(id, edgeID, laneIndex, x, y, angle, keepRouteFlag, matchThreshold);514}515break;516case libsumo::VAR_SPEED_FACTOR: {517libsumo::Vehicle::setSpeedFactor(id, StoHelp::readTypedDouble(inputStorage, "Setting speed factor requires a double."));518}519break;520case libsumo::VAR_LINE: {521libsumo::Vehicle::setLine(id, StoHelp::readTypedString(inputStorage, "The line must be given as a string."));522}523break;524case libsumo::VAR_VIA: {525libsumo::Vehicle::setVia(id, StoHelp::readTypedStringList(inputStorage, "Vias must be defined as a list of edge ids."));526}527break;528case libsumo::VAR_PARAMETER: {529StoHelp::readCompound(inputStorage, 2, "A compound object of size 2 is needed for setting a parameter.");530const std::string name = StoHelp::readTypedString(inputStorage, "The name of the parameter must be given as a string.");531const std::string value = StoHelp::readTypedString(inputStorage, "The value of the parameter must be given as a string.");532libsumo::Vehicle::setParameter(id, name, value);533}534break;535case libsumo::VAR_HIGHLIGHT: {536const int parameterCount = StoHelp::readCompound(inputStorage, -1, "A compound object is needed for highlighting an object.");537if (parameterCount > 5) {538return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Highlighting an object needs zero to five parameters.", outputStorage);539}540541libsumo::TraCIColor col = libsumo::TraCIColor(255, 0, 0);542if (parameterCount > 0) {543col = StoHelp::readTypedColor(inputStorage, "The first parameter for highlighting must be the highlight color.");544}545double size = -1;546if (parameterCount > 1) {547size = StoHelp::readTypedDouble(inputStorage, "The second parameter for highlighting must be the highlight size.");548}549int alphaMax = -1;550if (parameterCount > 2) {551alphaMax = StoHelp::readTypedUnsignedByte(inputStorage, "The third parameter for highlighting must be maximal alpha.");552}553double duration = -1;554if (parameterCount > 3) {555duration = StoHelp::readTypedDouble(inputStorage, "The fourth parameter for highlighting must be the highlight duration.");556}557int type = 0;558if (parameterCount > 4) {559type = StoHelp::readTypedUnsignedByte(inputStorage, "The fifth parameter for highlighting must be the highlight type id as ubyte.");560}561libsumo::Vehicle::highlight(id, col, size, alphaMax, duration, type);562}563break;564case libsumo::CMD_TAXI_DISPATCH: {565libsumo::Vehicle::dispatchTaxi(id, StoHelp::readTypedStringList(inputStorage, "A dispatch command must be defined as a list of reservation ids."));566}567break;568case libsumo::VAR_ACTIONSTEPLENGTH: {569const double value = StoHelp::readTypedDouble(inputStorage, "Setting action step length requires a double.");570if (fabs(value) == std::numeric_limits<double>::infinity()) {571return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid action step length.", outputStorage);572}573bool resetActionOffset = value >= 0.0;574libsumo::Vehicle::setActionStepLength(id, fabs(value), resetActionOffset);575}576break;577case libsumo::VAR_LANEPOSITION_LAT: {578libsumo::Vehicle::setLateralLanePosition(id, StoHelp::readTypedDouble(inputStorage, "Setting lateral lane position requires a double."));579}580break;581case libsumo::VAR_UPDATE_BESTLANES: {582libsumo::Vehicle::updateBestLanes(id);583}584break;585case libsumo::VAR_MINGAP: {586const double value = StoHelp::readTypedDouble(inputStorage, "Setting minimum gap requires a double.");587if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {588return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum gap.", outputStorage);589}590libsumo::Vehicle::setMinGap(id, value);591}592break;593case libsumo::VAR_MINGAP_LAT: {594const double value = StoHelp::readTypedDouble(inputStorage, "Setting minimum lateral gap requires a double.");595if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {596return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum lateral gap.", outputStorage);597}598libsumo::Vehicle::setMinGapLat(id, value);599}600break;601default: {602try {603if (!TraCIServerAPI_VehicleType::setVariable(libsumo::CMD_SET_VEHICLE_VARIABLE, variable, v->getSingularType().getID(), server, inputStorage, outputStorage)) {604return false;605}606} catch (ProcessError& e) {607return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);608} catch (libsumo::TraCIException& e) {609return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);610}611}612break;613}614} catch (libsumo::TraCIException& e) {615return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);616}617server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);618return true;619}620621622bool623TraCIServerAPI_Vehicle::insertReplaceStop(TraCIServer& server, tcpip::Storage& inputStorage, tcpip::Storage& outputStorage, const std::string& id, bool replace) {624const std::string m1 = replace ? "Replacing" : "Inserting";625const std::string m2 = replace ? "replacement" : "insertion";626const int parameterCount = StoHelp::readCompound(inputStorage, -1, m1 + " stop needs a compound object description.");627if (parameterCount != 8 && parameterCount != 9) {628return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, m1 + " stop needs a compound object description of eight or nine items.", outputStorage);629}630// read road map position631const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first stop " + m2 + " parameter must be the edge id given as a string.");632const double pos = StoHelp::readTypedDouble(inputStorage, "The second stop " + m2 + " parameter must be the end position along the edge given as a double.");633const int laneIndex = StoHelp::readTypedByte(inputStorage, "The third stop " + m2 + " parameter must be the lane index given as a byte.");634const double duration = StoHelp::readTypedDouble(inputStorage, "The fourth stop " + m2 + " parameter must be the stopping duration given as a double.");635const int stopFlags = StoHelp::readTypedInt(inputStorage, "The fifth stop " + m2 + " parameter must be an int indicating its parking/triggered status.");636const double startPos = StoHelp::readTypedDouble(inputStorage, "The sixth stop " + m2 + " parameter must be the start position along the edge given as a double.");637const double until = StoHelp::readTypedDouble(inputStorage, "The seventh stop " + m2 + " parameter must be the minimum departure time given as a double.");638const int nextStopIndex = StoHelp::readTypedInt(inputStorage, "The eighth stop " + m2 + " parameter must be the replacement index given as an int.");639int teleport = 0;640if (parameterCount == 9) {641teleport = StoHelp::readTypedByte(inputStorage, "The ninth stop " + m2 + " parameter must be the teleport flag given as a byte.");642}643if (replace) {644libsumo::Vehicle::replaceStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);645} else {646libsumo::Vehicle::insertStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);647}648return true;649}650651652/****************************************************************************/653654655