Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
TraCIServerAPI_Vehicle.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2009-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/****************************************************************************/
28// APIs for getting/setting vehicle values via TraCI
29/****************************************************************************/
30#include <config.h>
31
32#include <microsim/MSNet.h>
34#include <microsim/MSVehicle.h>
36#include <microsim/MSLane.h>
37#include <microsim/MSEdge.h>
38#include <microsim/MSGlobals.h>
48#include <libsumo/Vehicle.h>
49#include <libsumo/VehicleType.h>
53
54
55// ===========================================================================
56// method definitions
57// ===========================================================================
58bool
60 tcpip::Storage& outputStorage) {
61 const int variable = inputStorage.readUnsignedByte();
62 const std::string id = inputStorage.readString();
64 try {
65 if (!libsumo::Vehicle::handleVariable(id, variable, &server, &inputStorage)) {
66 return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Get Vehicle Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
67 }
68 } catch (libsumo::TraCIException& e) {
69 return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, e.what(), outputStorage);
70 }
72 server.writeResponseWithLength(outputStorage, server.getWrapperStorage());
73 return true;
74}
75
76
77bool
79 tcpip::Storage& outputStorage) {
80 std::string warning = ""; // additional description for response
81 // variable
82 int variable = inputStorage.readUnsignedByte();
83 if (variable != libsumo::CMD_STOP && variable != libsumo::CMD_CHANGELANE
85 && variable != libsumo::CMD_CHANGESUBLANE && variable != libsumo::CMD_OPENGAP
86 && variable != libsumo::CMD_REPLACE_STOP
87 && variable != libsumo::CMD_INSERT_STOP
88 && variable != libsumo::VAR_STOP_PARAMETER
89 && variable != libsumo::CMD_SLOWDOWN && variable != libsumo::CMD_CHANGETARGET && variable != libsumo::CMD_RESUME
90 && variable != libsumo::VAR_TYPE && variable != libsumo::VAR_ROUTE_ID && variable != libsumo::VAR_ROUTE
93 && variable != libsumo::VAR_EDGE_TRAVELTIME && variable != libsumo::VAR_EDGE_EFFORT
95 && variable != libsumo::VAR_SIGNALS && variable != libsumo::VAR_MOVE_TO
96 && variable != libsumo::VAR_LENGTH && variable != libsumo::VAR_MAXSPEED && variable != libsumo::VAR_VEHICLECLASS
97 && variable != libsumo::VAR_SPEED_FACTOR && variable != libsumo::VAR_EMISSIONCLASS
98 && variable != libsumo::VAR_WIDTH && variable != libsumo::VAR_MINGAP && variable != libsumo::VAR_SHAPECLASS
99 && variable != libsumo::VAR_ACCEL && variable != libsumo::VAR_DECEL && variable != libsumo::VAR_IMPERFECTION
101 && variable != libsumo::VAR_ACTIONSTEPLENGTH
102 && variable != libsumo::VAR_TAU && variable != libsumo::VAR_LANECHANGE_MODE
103 && variable != libsumo::VAR_SPEED && variable != libsumo::VAR_ACCELERATION && variable != libsumo::VAR_PREV_SPEED && variable != libsumo::VAR_SPEEDSETMODE && variable != libsumo::VAR_COLOR
104 && variable != libsumo::ADD && variable != libsumo::ADD_FULL && variable != libsumo::REMOVE
105 && variable != libsumo::VAR_HEIGHT
106 && variable != libsumo::VAR_MASS
107 && variable != libsumo::VAR_ROUTING_MODE
108 && variable != libsumo::VAR_LATALIGNMENT
109 && variable != libsumo::VAR_MAXSPEED_LAT
110 && variable != libsumo::VAR_MINGAP_LAT
111 && variable != libsumo::VAR_LINE
112 && variable != libsumo::VAR_VIA
113 && variable != libsumo::VAR_IMPATIENCE
114 && variable != libsumo::VAR_BOARDING_DURATION
115 && variable != libsumo::VAR_HIGHLIGHT
116 && variable != libsumo::CMD_TAXI_DISPATCH
117 && variable != libsumo::MOVE_TO_XY && variable != libsumo::VAR_PARAMETER/* && variable != libsumo::VAR_SPEED_TIME_LINE && variable != libsumo::VAR_LANE_TIME_LINE*/
118 ) {
119 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Change Vehicle State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
120 }
121 // id
122 std::string id = inputStorage.readString();
123#ifdef DEBUG_MOVEXY
124 std::cout << SIMTIME << " processSet veh=" << id << "\n";
125#endif
126 const bool shouldExist = variable != libsumo::ADD && variable != libsumo::ADD_FULL;
128 if (sumoVehicle == nullptr) {
129 if (shouldExist) {
130 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
131 }
132 }
133 MSBaseVehicle* v = dynamic_cast<MSBaseVehicle*>(sumoVehicle);
134 if (v == nullptr && shouldExist) {
135 return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a proper vehicle", outputStorage);
136 }
137 try {
138 switch (variable) {
139 case libsumo::CMD_STOP: {
140 const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Stop needs a compound object description.");
141 if (compoundSize < 4 || compoundSize > 7) {
142 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description of four to seven items.", outputStorage);
143 }
144 // read road map position
145 const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first stop parameter must be the edge id given as a string.");
146 const double pos = StoHelp::readTypedDouble(inputStorage, "The second stop parameter must be the end position along the edge given as a double.");
147 const int laneIndex = StoHelp::readTypedByte(inputStorage, "The third stop parameter must be the lane index given as a byte.");
148 const double duration = StoHelp::readTypedDouble(inputStorage, "The fourth stop parameter must be the stopping duration given as a double.");
149 int stopFlags = 0;
150 if (compoundSize >= 5) {
151 stopFlags = StoHelp::readTypedByte(inputStorage, "The fifth stop parameter must be a byte indicating its parking/triggered status.");
152 }
153 double startPos = libsumo::INVALID_DOUBLE_VALUE;
154 if (compoundSize >= 6) {
155 startPos = StoHelp::readTypedDouble(inputStorage, "The sixth stop parameter must be the start position along the edge given as a double.");
156 }
157 double until = libsumo::INVALID_DOUBLE_VALUE;
158 if (compoundSize >= 7) {
159 until = StoHelp::readTypedDouble(inputStorage, "The seventh stop parameter must be the minimum departure time given as a double.");
160 }
161 libsumo::Vehicle::setStop(id, edgeID, pos, laneIndex, duration, stopFlags, startPos, until);
162 }
163 break;
165 if (!insertReplaceStop(server, inputStorage, outputStorage, id, true)) {
166 return false;
167 }
168 break;
170 if (!insertReplaceStop(server, inputStorage, outputStorage, id, false)) {
171 return false;
172 }
173 break;
175 const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Setting stop parameter needs a compound object description.");
176 if (compoundSize != 3 && compoundSize != 4) {
177 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting a stop parameter needs a compound object description of 3 or 4 items.", outputStorage);
178 }
179 const int nextStopIndex = StoHelp::readTypedInt(inputStorage, "The first setStopParameter parameter must be the nextStopIndex given as an integer.");
180 const std::string param = StoHelp::readTypedString(inputStorage, "The second setStopParameter parameter must be the param given as a string.");
181 const std::string value = StoHelp::readTypedString(inputStorage, "The third setStopParameter parameter must be the value given as a string.");
182 int customParam = 0;
183 if (compoundSize == 4) {
184 customParam = StoHelp::readTypedByte(inputStorage, "The fourth setStopParameter parameter must be the customParam flag given as a byte.");
185 }
186 libsumo::Vehicle::setStopParameter(id, nextStopIndex, param, value, customParam != 0);
187 }
188 break;
190 StoHelp::readCompound(inputStorage, 1, "Reroute to stop needs a compound object description of 1 item.");
191 libsumo::Vehicle::rerouteParkingArea(id, StoHelp::readTypedString(inputStorage, "The first reroute to stop parameter must be the parking area id given as a string."));
192 }
193 break;
194 case libsumo::CMD_RESUME: {
195 StoHelp::readCompound(inputStorage, 0, "Resuming requires an empty compound object.");
196 libsumo::Vehicle::resume(id);
197 }
198 break;
200 const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Lane change needs a compound object description.");
201 if (compoundSize != 3 && compoundSize != 2) {
202 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two or three items.", outputStorage);
203 }
204 const int laneIndex = StoHelp::readTypedByte(inputStorage, "The first lane change parameter must be the lane index given as a byte.");
205 const double duration = StoHelp::readTypedDouble(inputStorage, "The second lane change parameter must be the duration given as a double.");
206 // relative lane change
207 int relative = 0;
208 if (compoundSize == 3) {
209 relative = StoHelp::readTypedByte(inputStorage, "The third lane change parameter must be a Byte for defining whether a relative lane change should be applied.");
210 }
211
212 if ((laneIndex < 0 || laneIndex >= (int)v->getEdge()->getLanes().size()) && relative < 1) {
213 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + v->getEdge()->getID() + "'.", outputStorage);
214 }
215
216 if (relative < 1) {
217 libsumo::Vehicle::changeLane(id, laneIndex, duration);
218 } else {
219 libsumo::Vehicle::changeLaneRelative(id, laneIndex, duration);
220 }
221 }
222 break;
224 libsumo::Vehicle::changeSublane(id, StoHelp::readTypedDouble(inputStorage, "Sublane-changing requires a double."));
225 }
226 break;
228 StoHelp::readCompound(inputStorage, 2, "Slow down needs a compound object description of two items.");
229 const double newSpeed = StoHelp::readTypedDouble(inputStorage, "The first slow down parameter must be the speed given as a double.");
230 if (newSpeed < 0.) {
231 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Speed must not be negative", outputStorage);
232 }
233 const double duration = StoHelp::readTypedDouble(inputStorage, "The second slow down parameter must be the duration given as a double.");
234 if (duration < 0. || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
235 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval", outputStorage);
236 }
237 libsumo::Vehicle::slowDown(id, newSpeed, duration);
238 }
239 break;
241 libsumo::Vehicle::changeTarget(id, StoHelp::readTypedString(inputStorage, "Change target requires a string containing the id of the new destination edge as parameter."));
242 }
243 break;
245 const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Create gap needs a compound object description.");
246 if (compoundSize != 5 && compoundSize != 6) {
247 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Create gap needs a compound object description of five or six items.", outputStorage);
248 }
249 const double newTimeHeadway = StoHelp::readTypedDouble(inputStorage, "The first create gap parameter must be the new desired time headway (tau) given as a double.");
250 double newSpaceHeadway = StoHelp::readTypedDouble(inputStorage, "The second create gap parameter must be the new desired space headway given as a double.");
251 const double duration = StoHelp::readTypedDouble(inputStorage, "The third create gap parameter must be the duration given as a double.");
252 const double changeRate = StoHelp::readTypedDouble(inputStorage, "The fourth create gap parameter must be the change rate given as a double.");
253 const double maxDecel = StoHelp::readTypedDouble(inputStorage, "The fifth create gap parameter must be the maximal braking rate given as a double.");
254
255 if (newTimeHeadway == -1 && newSpaceHeadway == -1 && duration == -1 && changeRate == -1 && maxDecel == -1) {
256 libsumo::Vehicle::deactivateGapControl(id);
257 } else {
258 if (newTimeHeadway <= 0) {
259 if (newTimeHeadway != -1) {
260 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired time headway (tau) must be positive for create gap", outputStorage);
261 } // else if == -1: keep vehicles current headway, see libsumo::Vehicle::openGap
262 }
263 if (newSpaceHeadway < 0) {
264 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired space headway must be non-negative for create gap", outputStorage);
265 }
266 if ((duration < 0 && duration != -1) || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
267 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval for create gap", outputStorage);
268 }
269 if (changeRate <= 0) {
270 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the change rate must be positive for the openGap command", outputStorage);
271 }
272 if (maxDecel <= 0 && maxDecel != -1 && maxDecel != libsumo::INVALID_DOUBLE_VALUE) {
273 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the maximal braking rate must be positive for the openGap command", outputStorage);
274 } // else if <= 0: don't limit cf model's suggested brake rate, see libsumo::Vehicle::openGap
275 std::string refVehID = "";
276 if (compoundSize == 6) {
277 refVehID = StoHelp::readTypedString(inputStorage, "The sixth create gap parameter must be a reference vehicle's ID given as a string.");
278 }
279 libsumo::Vehicle::openGap(id, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel, refVehID);
280 }
281 }
282 break;
283 case libsumo::VAR_TYPE: {
284 libsumo::Vehicle::setType(id, StoHelp::readTypedString(inputStorage, "The vehicle type id must be given as a string."));
285 }
286 break;
288 libsumo::Vehicle::setRouteID(id, StoHelp::readTypedString(inputStorage, "The route id must be given as a string."));
289 }
290 break;
291 case libsumo::VAR_ROUTE: {
292 libsumo::Vehicle::setRoute(id, StoHelp::readTypedStringList(inputStorage, "A route must be defined as a list of edge ids."));
293 }
294 break;
296 const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting travel time requires a compound object.");
297 std::string edgeID;
298 double begTime = 0.;
299 double endTime = std::numeric_limits<double>::max();
300 double value = libsumo::INVALID_DOUBLE_VALUE;
301 if (parameterCount == 4) {
302 begTime = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the begin time as first parameter.");
303 endTime = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the end time as second parameter.");
304 edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 4 parameters requires the referenced edge as third parameter.");
305 value = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the travel time as double as fourth parameter.");
306 } else if (parameterCount == 2) {
307 edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 2 parameters requires the referenced edge as first parameter.");
308 value = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 2 parameters requires the travel time as double as second parameter.");
309 } else if (parameterCount == 1) {
310 edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 1 parameter requires the referenced edge as first parameter.");
311 } else {
312 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);
313 }
314 libsumo::Vehicle::setAdaptedTraveltime(id, edgeID, value, begTime, endTime);
315 }
316 break;
318 const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting travel time requires a compound object.");
319 std::string edgeID;
320 double begTime = 0.;
321 double endTime = std::numeric_limits<double>::max();
322 double value = libsumo::INVALID_DOUBLE_VALUE;
323 if (parameterCount == 4) {
324 begTime = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the begin time as first parameter.");
325 endTime = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the end time as second parameter.");
326 edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 4 parameters requires the referenced edge as third parameter.");
327 value = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the effort as double as fourth parameter.");
328 } else if (parameterCount == 2) {
329 edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 2 parameters requires the referenced edge as first parameter.");
330 value = StoHelp::readTypedDouble(inputStorage, "Setting effort using 2 parameters requires the effort as double as second parameter.");
331 } else if (parameterCount == 1) {
332 edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 1 parameter requires the referenced edge as first parameter.");
333 } else {
334 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);
335 }
336 libsumo::Vehicle::setEffort(id, edgeID, value, begTime, endTime);
337 }
338 break;
340 StoHelp::readCompound(inputStorage, 0, "Rerouting by travel time requires an empty compound object.");
341 libsumo::Vehicle::rerouteTraveltime(id, false);
342 }
343 break;
345 StoHelp::readCompound(inputStorage, 0, "Rerouting by effort requires an empty compound object.");
346 libsumo::Vehicle::rerouteEffort(id);
347 }
348 break;
350 libsumo::Vehicle::setSignals(id, StoHelp::readTypedInt(inputStorage, "Setting signals requires an integer."));
351 break;
353 const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting position requires a compound object.");
354 if (parameterCount < 2 || parameterCount > 3) {
355 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting position should obtain the lane id and the position and optionally the reason.", outputStorage);
356 }
357 const std::string laneID = StoHelp::readTypedString(inputStorage, "The first parameter for setting a position must be the lane ID given as a string.");
358 const double position = StoHelp::readTypedDouble(inputStorage, "The second parameter for setting a position must be the position given as a double.");
359 int reason = libsumo::MOVE_AUTOMATIC;
360 if (parameterCount == 3) {
361 reason = StoHelp::readTypedInt(inputStorage, "The third parameter for setting a position must be the reason given as an int.");
362 }
363 // process
364 libsumo::Vehicle::moveTo(id, laneID, position, reason);
365 }
366 break;
368 libsumo::Vehicle::setImpatience(id, StoHelp::readTypedDouble(inputStorage, "Setting impatience requires a double."));
369 }
370 break;
371 case libsumo::VAR_SPEED: {
372 libsumo::Vehicle::setSpeed(id, StoHelp::readTypedDouble(inputStorage, "Setting speed requires a double."));
373 }
374 break;
376 StoHelp::readCompound(inputStorage, 2, "Setting acceleration requires 2 parameters.");
377 const double accel = StoHelp::readTypedDouble(inputStorage, "Setting acceleration requires the acceleration as first parameter given as a double.");
378 const double duration = StoHelp::readTypedDouble(inputStorage, "Setting acceleration requires the duration as second parameter given as a double.");
379 if (duration < 0) {
380 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Duration must not be negative.", outputStorage);
381 }
382 libsumo::Vehicle::setAcceleration(id, accel, duration);
383 }
384 break;
386 double prevSpeed = 0;
387 double prevAcceleration = libsumo::INVALID_DOUBLE_VALUE;
388 int inputtype = inputStorage.readUnsignedByte();
389 if (inputtype == libsumo::TYPE_COMPOUND) {
390 // Setting previous speed with 2 parameters, uses a compound object description
391 const int parameterCount = inputStorage.readInt();
392 if (parameterCount == 2) {
393 prevSpeed = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 2 parameters requires the previous speed as first parameter given as a double.");
394 prevAcceleration = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 2 parameters requires the previous acceleration as second parameter given as a double.");
395 } else if (parameterCount == 1) {
396 prevSpeed = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 1 parameter requires the previous speed as first parameter given as a double.");
397 } else {
398 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed requires 1 or 2 parameters.", outputStorage);
399 }
400 } else if (inputtype == libsumo::TYPE_DOUBLE) {
401 // Setting previous speed with 1 parameter (double), no compound object description
402 prevSpeed = inputStorage.readDouble();
403 } else {
404 return 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);
405 }
406 if (prevSpeed < 0) {
407 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Previous speed must not be negative.", outputStorage);
408 }
409 libsumo::Vehicle::setPreviousSpeed(id, prevSpeed, prevAcceleration);
410 }
411 break;
413 libsumo::Vehicle::setSpeedMode(id, StoHelp::readTypedInt(inputStorage, "Setting speed mode requires an integer."));
414 break;
416 libsumo::Vehicle::setLaneChangeMode(id, StoHelp::readTypedInt(inputStorage, "Setting lane change mode requires an integer."));
417 break;
419 libsumo::Vehicle::setRoutingMode(id, StoHelp::readTypedInt(inputStorage, "Setting routing mode requires an integer."));
420 break;
421 case libsumo::VAR_COLOR: {
422 libsumo::Vehicle::setColor(id, StoHelp::readTypedColor(inputStorage, "The color must be given using the according type."));
423 break;
424 }
425 case libsumo::ADD: {
426 StoHelp::readCompound(inputStorage, 6, "Adding a vehicle needs six parameters.");
427 const std::string vTypeID = StoHelp::readTypedString(inputStorage, "First parameter (type) requires a string.");
428 const std::string routeID = StoHelp::readTypedString(inputStorage, "Second parameter (route) requires a string.");
429 const int departCode = StoHelp::readTypedInt(inputStorage, "Third parameter (depart) requires an integer.");
430 std::string depart = toString(STEPS2TIME(departCode));
431 if (-departCode == static_cast<int>(DepartDefinition::TRIGGERED)) {
432 depart = "triggered";
433 } else if (-departCode == static_cast<int>(DepartDefinition::CONTAINER_TRIGGERED)) {
434 depart = "containerTriggered";
435 } else if (-departCode == static_cast<int>(DepartDefinition::NOW)) {
436 depart = "now";
437 } else if (-departCode == static_cast<int>(DepartDefinition::SPLIT)) {
438 depart = "split";
439 } else if (-departCode == static_cast<int>(DepartDefinition::BEGIN)) {
440 depart = "begin";
441 }
442
443 const double departPosCode = StoHelp::readTypedDouble(inputStorage, "Fourth parameter (position) requires a double.");
444 std::string departPos = toString(departPosCode);
445 if (-departPosCode == (int)DepartPosDefinition::RANDOM) {
446 departPos = "random";
447 } else if (-departPosCode == (int)DepartPosDefinition::RANDOM_FREE) {
448 departPos = "random_free";
449 } else if (-departPosCode == (int)DepartPosDefinition::FREE) {
450 departPos = "free";
451 } else if (-departPosCode == (int)DepartPosDefinition::BASE) {
452 departPos = "base";
453 } else if (-departPosCode == (int)DepartPosDefinition::LAST) {
454 departPos = "last";
455 } else if (-departPosCode == (int)DepartPosDefinition::GIVEN) {
456 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid departure position.", outputStorage);
457 }
458
459 const double departSpeedCode = StoHelp::readTypedDouble(inputStorage, "Fifth parameter (speed) requires a double.");
460 std::string departSpeed = toString(departSpeedCode);
461 if (-departSpeedCode == (int)DepartSpeedDefinition::RANDOM) {
462 departSpeed = "random";
463 } else if (-departSpeedCode == (int)DepartSpeedDefinition::MAX) {
464 departSpeed = "max";
465 } else if (-departSpeedCode == (int)DepartSpeedDefinition::DESIRED) {
466 departSpeed = "desired";
467 } else if (-departSpeedCode == (int)DepartSpeedDefinition::LIMIT) {
468 departSpeed = "speedLimit";
469 } else if (-departSpeedCode == (int)DepartSpeedDefinition::LAST) {
470 departSpeed = "last";
471 } else if (-departSpeedCode == (int)DepartSpeedDefinition::AVG) {
472 departSpeed = "avg";
473 }
474
475 const int departLaneCode = StoHelp::readTypedByte(inputStorage, "Sixth parameter (lane) requires a byte.");
476 std::string departLane = toString(departLaneCode);
477 if (-departLaneCode == (int)DepartLaneDefinition::RANDOM) {
478 departLane = "random";
479 } else if (-departLaneCode == (int)DepartLaneDefinition::FREE) {
480 departLane = "free";
481 } else if (-departLaneCode == (int)DepartLaneDefinition::ALLOWED_FREE) {
482 departLane = "allowed";
483 } else if (-departLaneCode == (int)DepartLaneDefinition::BEST_FREE) {
484 departLane = "best";
485 } else if (-departLaneCode == (int)DepartLaneDefinition::FIRST_ALLOWED) {
486 departLane = "first";
487 }
488 libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed);
489 }
490 break;
491 case libsumo::ADD_FULL: {
492 StoHelp::readCompound(inputStorage, 14, "Adding a fully specified vehicle needs fourteen parameters.");
493 const std::string routeID = StoHelp::readTypedString(inputStorage, "First parameter (route) requires a string.");
494 const std::string vTypeID = StoHelp::readTypedString(inputStorage, "Second parameter (type) requires a string.");
495 const std::string depart = StoHelp::readTypedString(inputStorage, "Third parameter (depart) requires an string.");
496 const std::string departLane = StoHelp::readTypedString(inputStorage, "Fourth parameter (depart lane) requires a string.");
497 const std::string departPos = StoHelp::readTypedString(inputStorage, "Fifth parameter (depart position) requires a string.");
498 const std::string departSpeed = StoHelp::readTypedString(inputStorage, "Sixth parameter (depart speed) requires a string.");
499 const std::string arrivalLane = StoHelp::readTypedString(inputStorage, "Seventh parameter (arrival lane) requires a string.");
500 const std::string arrivalPos = StoHelp::readTypedString(inputStorage, "Eighth parameter (arrival position) requires a string.");
501 const std::string arrivalSpeed = StoHelp::readTypedString(inputStorage, "Ninth parameter (arrival speed) requires a string.");
502 const std::string fromTaz = StoHelp::readTypedString(inputStorage, "Tenth parameter (from taz) requires a string.");
503 const std::string toTaz = StoHelp::readTypedString(inputStorage, "Eleventh parameter (to taz) requires a string.");
504 const std::string line = StoHelp::readTypedString(inputStorage, "Twelth parameter (line) requires a string.");
505 const int personCapacity = StoHelp::readTypedInt(inputStorage, "13th parameter (person capacity) requires an int.");
506 const int personNumber = StoHelp::readTypedInt(inputStorage, "14th parameter (person number) requires an int.");
507 libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed, arrivalLane, arrivalPos, arrivalSpeed,
508 fromTaz, toTaz, line, personCapacity, personNumber);
509 }
510 break;
511 case libsumo::REMOVE: {
512 libsumo::Vehicle::remove(id, (char)StoHelp::readTypedByte(inputStorage, "Removing a vehicle requires a byte."));
513 }
514 break;
515 case libsumo::MOVE_TO_XY: {
516 const int parameterCount = StoHelp::readCompound(inputStorage, -1, "MoveToXY vehicle requires a compound object.");
517 if (parameterCount < 5 || parameterCount > 7) {
518 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "MoveToXY vehicle should obtain: edgeID, lane, x, y, angle and optionally keepRouteFlag and matchThreshold.", outputStorage);
519 }
520 const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first parameter for moveToXY must be the edge ID given as a string.");
521 const int laneIndex = StoHelp::readTypedInt(inputStorage, "The second parameter for moveToXY must be lane given as an int.");
522 const double x = StoHelp::readTypedDouble(inputStorage, "The third parameter for moveToXY must be the x-position given as a double.");
523 const double y = StoHelp::readTypedDouble(inputStorage, "The fourth parameter for moveToXY must be the y-position given as a double.");
524 const double angle = StoHelp::readTypedDouble(inputStorage, "The fifth parameter for moveToXY must be the angle given as a double.");
525 int keepRouteFlag = 1;
526 if (parameterCount >= 6) {
527 keepRouteFlag = StoHelp::readTypedByte(inputStorage, "The sixth parameter for moveToXY must be the keepRouteFlag given as a byte.");
528 }
529 double matchThreshold = 100.;
530 if (parameterCount == 7) {
531 matchThreshold = StoHelp::readTypedDouble(inputStorage, "The seventh parameter for moveToXY must be the matchThreshold given as a double.");
532 }
533 libsumo::Vehicle::moveToXY(id, edgeID, laneIndex, x, y, angle, keepRouteFlag, matchThreshold);
534 }
535 break;
537 libsumo::Vehicle::setSpeedFactor(id, StoHelp::readTypedDouble(inputStorage, "Setting speed factor requires a double."));
538 }
539 break;
540 case libsumo::VAR_LINE: {
541 libsumo::Vehicle::setLine(id, StoHelp::readTypedString(inputStorage, "The line must be given as a string."));
542 }
543 break;
544 case libsumo::VAR_VIA: {
545 libsumo::Vehicle::setVia(id, StoHelp::readTypedStringList(inputStorage, "Vias must be defined as a list of edge ids."));
546 }
547 break;
549 StoHelp::readCompound(inputStorage, 2, "A compound object of size 2 is needed for setting a parameter.");
550 const std::string name = StoHelp::readTypedString(inputStorage, "The name of the parameter must be given as a string.");
551 const std::string value = StoHelp::readTypedString(inputStorage, "The value of the parameter must be given as a string.");
552 libsumo::Vehicle::setParameter(id, name, value);
553 }
554 break;
556 const int parameterCount = StoHelp::readCompound(inputStorage, -1, "A compound object is needed for highlighting an object.");
557 if (parameterCount > 5) {
558 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Highlighting an object needs zero to five parameters.", outputStorage);
559 }
560
562 if (parameterCount > 0) {
563 col = StoHelp::readTypedColor(inputStorage, "The first parameter for highlighting must be the highlight color.");
564 }
565 double size = -1;
566 if (parameterCount > 1) {
567 size = StoHelp::readTypedDouble(inputStorage, "The second parameter for highlighting must be the highlight size.");
568 }
569 int alphaMax = -1;
570 if (parameterCount > 2) {
571 alphaMax = StoHelp::readTypedUnsignedByte(inputStorage, "The third parameter for highlighting must be maximal alpha.");
572 }
573 double duration = -1;
574 if (parameterCount > 3) {
575 duration = StoHelp::readTypedDouble(inputStorage, "The fourth parameter for highlighting must be the highlight duration.");
576 }
577 int type = 0;
578 if (parameterCount > 4) {
579 type = StoHelp::readTypedUnsignedByte(inputStorage, "The fifth parameter for highlighting must be the highlight type id as ubyte.");
580 }
581 libsumo::Vehicle::highlight(id, col, size, alphaMax, duration, type);
582 }
583 break;
585 libsumo::Vehicle::dispatchTaxi(id, StoHelp::readTypedStringList(inputStorage, "A dispatch command must be defined as a list of reservation ids."));
586 }
587 break;
589 const double value = StoHelp::readTypedDouble(inputStorage, "Setting action step length requires a double.");
590 if (fabs(value) == std::numeric_limits<double>::infinity()) {
591 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid action step length.", outputStorage);
592 }
593 bool resetActionOffset = value >= 0.0;
594 libsumo::Vehicle::setActionStepLength(id, fabs(value), resetActionOffset);
595 }
596 break;
598 libsumo::Vehicle::setLateralLanePosition(id, StoHelp::readTypedDouble(inputStorage, "Setting lateral lane position requires a double."));
599 }
600 break;
602 libsumo::Vehicle::updateBestLanes(id);
603 }
604 break;
605 case libsumo::VAR_MINGAP: {
606 const double value = StoHelp::readTypedDouble(inputStorage, "Setting minimum gap requires a double.");
607 if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
608 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum gap.", outputStorage);
609 }
610 libsumo::Vehicle::setMinGap(id, value);
611 }
612 break;
614 const double value = StoHelp::readTypedDouble(inputStorage, "Setting minimum lateral gap requires a double.");
615 if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
616 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum lateral gap.", outputStorage);
617 }
618 libsumo::Vehicle::setMinGapLat(id, value);
619 }
620 break;
621 default: {
622 try {
623 if (!TraCIServerAPI_VehicleType::setVariable(libsumo::CMD_SET_VEHICLE_VARIABLE, variable, v->getSingularType().getID(), server, inputStorage, outputStorage)) {
624 return false;
625 }
626 } catch (ProcessError& e) {
627 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
628 } catch (libsumo::TraCIException& e) {
629 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
630 }
631 }
632 break;
633 }
634 } catch (libsumo::TraCIException& e) {
635 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
636 }
638 return true;
639}
640
641
642bool
643TraCIServerAPI_Vehicle::insertReplaceStop(TraCIServer& server, tcpip::Storage& inputStorage, tcpip::Storage& outputStorage, const std::string& id, bool replace) {
644 const std::string m1 = replace ? "Replacing" : "Inserting";
645 const std::string m2 = replace ? "replacement" : "insertion";
646 const int parameterCount = StoHelp::readCompound(inputStorage, -1, m1 + " stop needs a compound object description.");
647 if (parameterCount != 8 && parameterCount != 9) {
648 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, m1 + " stop needs a compound object description of eight or nine items.", outputStorage);
649 }
650 // read road map position
651 const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first stop " + m2 + " parameter must be the edge id given as a string.");
652 const double pos = StoHelp::readTypedDouble(inputStorage, "The second stop " + m2 + " parameter must be the end position along the edge given as a double.");
653 const int laneIndex = StoHelp::readTypedByte(inputStorage, "The third stop " + m2 + " parameter must be the lane index given as a byte.");
654 const double duration = StoHelp::readTypedDouble(inputStorage, "The fourth stop " + m2 + " parameter must be the stopping duration given as a double.");
655 const int stopFlags = StoHelp::readTypedInt(inputStorage, "The fifth stop " + m2 + " parameter must be an int indicating its parking/triggered status.");
656 const double startPos = StoHelp::readTypedDouble(inputStorage, "The sixth stop " + m2 + " parameter must be the start position along the edge given as a double.");
657 const double until = StoHelp::readTypedDouble(inputStorage, "The seventh stop " + m2 + " parameter must be the minimum departure time given as a double.");
658 const int nextStopIndex = StoHelp::readTypedInt(inputStorage, "The eighth stop " + m2 + " parameter must be the replacement index given as an int.");
659 int teleport = 0;
660 if (parameterCount == 9) {
661 teleport = StoHelp::readTypedByte(inputStorage, "The ninth stop " + m2 + " parameter must be the teleport flag given as a byte.");
662 }
663 if (replace) {
664 libsumo::Vehicle::replaceStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
665 } else {
666 libsumo::Vehicle::insertStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
667 }
668 return true;
669}
670
671
672/****************************************************************************/
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define SIMTIME
Definition SUMOTime.h:62
@ RANDOM
The lane is chosen randomly.
@ BEST_FREE
The least occupied lane from best lanes.
@ ALLOWED_FREE
The least occupied lane from lanes which allow the continuation.
@ FIRST_ALLOWED
The rightmost lane the vehicle may use.
@ FREE
The least occupied lane is used.
@ RANDOM
A random position is chosen.
@ GIVEN
The position is given.
@ FREE
A free position is chosen.
@ BASE
Back-at-zero position.
@ LAST
Insert behind the last vehicle as close as possible to still allow the specified departSpeed....
@ RANDOM_FREE
If a fixed number of random choices fails, a free position is chosen.
@ RANDOM
The speed is chosen randomly.
@ MAX
The maximum safe speed is used.
@ LIMIT
The maximum lane speed is used (speedLimit)
@ DESIRED
The maximum lane speed is used (speedLimit * speedFactor)
@ LAST
The speed of the last vehicle. Fallback to DepartSpeedDefinition::DESIRED if there is no vehicle on t...
@ AVG
The average speed on the lane. Fallback to DepartSpeedDefinition::DESIRED if there is no vehicle on t...
@ BEGIN
The departure is at simulation start.
@ NOW
The vehicle is discarded if emission fails (not fully implemented yet)
@ SPLIT
The departure is triggered by a train split.
@ CONTAINER_TRIGGERED
The departure is container triggered.
@ TRIGGERED
The departure is person triggered.
std::string toHex(const T i, std::streamsize numDigits=0)
Definition ToString.h:56
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
The base class for microscopic and mesoscopic vehicles.
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:168
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:187
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:392
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
const std::string & getID() const
Returns the name of the vehicle type.
const std::string & getID() const
Returns the id.
Definition Named.h:74
Representation of a vehicle.
Definition SUMOVehicle.h:62
static bool insertReplaceStop(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage, const std::string &id, bool replace)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc4: Change Vehicle State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa4: Get Vehicle Variable)
static bool setVariable(const int cmd, const int variable, const std::string &id, TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value for the given type.
TraCI server used to control sumo by a remote TraCI client.
Definition TraCIServer.h:59
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
tcpip::Storage & getWrapperStorage()
void initWrapper(const int domainID, const int variable, const std::string &objID)
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
static int readTypedUnsignedByte(tcpip::Storage &ret, const std::string &error="")
static int readTypedByte(tcpip::Storage &ret, const std::string &error="")
static int readCompound(tcpip::Storage &ret, int expectedSize=-1, const std::string &error="")
static std::vector< std::string > readTypedStringList(tcpip::Storage &ret, const std::string &error="")
static int readTypedInt(tcpip::Storage &ret, const std::string &error="")
static std::string readTypedString(tcpip::Storage &ret, const std::string &error="")
static const libsumo::TraCIColor readTypedColor(tcpip::Storage &ret, const std::string &error="")
static double readTypedDouble(tcpip::Storage &ret, const std::string &error="")
An error which allows to continue.
Definition TraCIDefs.h:145
virtual std::string readString()
Definition storage.cpp:180
virtual int readUnsignedByte()
Definition storage.cpp:155
virtual double readDouble()
Definition storage.cpp:362
virtual int readInt()
Definition storage.cpp:311
TRACI_CONST double INVALID_DOUBLE_VALUE
TRACI_CONST int VAR_LANECHANGE_MODE
TRACI_CONST int MOVE_AUTOMATIC
TRACI_CONST int VAR_VEHICLECLASS
TRACI_CONST int VAR_IMPATIENCE
TRACI_CONST int VAR_LATALIGNMENT
TRACI_CONST int VAR_TYPE
TRACI_CONST int CMD_CHANGESUBLANE
TRACI_CONST int VAR_ROUTING_MODE
TRACI_CONST int VAR_MINGAP
TRACI_CONST int CMD_TAXI_DISPATCH
TRACI_CONST int VAR_SHAPECLASS
TRACI_CONST int CMD_STOP
TRACI_CONST int VAR_LINE
TRACI_CONST int VAR_EDGE_TRAVELTIME
TRACI_CONST int CMD_GET_VEHICLE_VARIABLE
TRACI_CONST int CMD_RESUME
TRACI_CONST int VAR_ACTIONSTEPLENGTH
TRACI_CONST int VAR_SPEED_FACTOR
TRACI_CONST int MOVE_TO_XY
TRACI_CONST int VAR_TAU
TRACI_CONST int TYPE_COMPOUND
TRACI_CONST int VAR_EDGE_EFFORT
TRACI_CONST int VAR_ROUTE
TRACI_CONST int VAR_HIGHLIGHT
TRACI_CONST int VAR_BOARDING_DURATION
TRACI_CONST int VAR_MOVE_TO
TRACI_CONST int VAR_UPDATE_BESTLANES
TRACI_CONST int VAR_COLOR
TRACI_CONST int VAR_WIDTH
TRACI_CONST int VAR_STOP_PARAMETER
TRACI_CONST int VAR_MAXSPEED
TRACI_CONST int CMD_CHANGETARGET
TRACI_CONST int ADD_FULL
TRACI_CONST int CMD_REROUTE_TO_PARKING
TRACI_CONST int RESPONSE_GET_VEHICLE_VARIABLE
TRACI_CONST int CMD_REROUTE_TRAVELTIME
TRACI_CONST int VAR_PREV_SPEED
TRACI_CONST int VAR_SPEEDSETMODE
TRACI_CONST int CMD_REPLACE_STOP
TRACI_CONST int VAR_MASS
TRACI_CONST int CMD_SET_VEHICLE_VARIABLE
TRACI_CONST int VAR_LENGTH
TRACI_CONST int VAR_MAXSPEED_LAT
TRACI_CONST int CMD_REROUTE_EFFORT
TRACI_CONST int VAR_PARAMETER
TRACI_CONST int REMOVE
TRACI_CONST int CMD_INSERT_STOP
TRACI_CONST int VAR_IMPERFECTION
TRACI_CONST int VAR_HEIGHT
TRACI_CONST int VAR_APPARENT_DECEL
TRACI_CONST int VAR_SPEED
TRACI_CONST int VAR_DECEL
TRACI_CONST int VAR_SIGNALS
TRACI_CONST int VAR_MINGAP_LAT
TRACI_CONST int CMD_SLOWDOWN
TRACI_CONST int VAR_ACCELERATION
TRACI_CONST int VAR_ROUTE_ID
TRACI_CONST int TYPE_DOUBLE
TRACI_CONST int CMD_OPENGAP
TRACI_CONST int VAR_LANEPOSITION_LAT
TRACI_CONST int CMD_CHANGELANE
TRACI_CONST int VAR_EMERGENCY_DECEL
TRACI_CONST int RTYPE_OK
TRACI_CONST int VAR_EMISSIONCLASS
TRACI_CONST int VAR_ACCEL
TRACI_CONST int ADD
TRACI_CONST int VAR_VIA