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 std::string warning = ""; // additional description for response
62 // variable
63 int variable = inputStorage.readUnsignedByte();
64 if (variable != libsumo::CMD_STOP && variable != libsumo::CMD_CHANGELANE
66 && variable != libsumo::CMD_CHANGESUBLANE && variable != libsumo::CMD_OPENGAP
67 && variable != libsumo::CMD_REPLACE_STOP
68 && variable != libsumo::CMD_INSERT_STOP
69 && variable != libsumo::VAR_STOP_PARAMETER
70 && variable != libsumo::CMD_SLOWDOWN && variable != libsumo::CMD_CHANGETARGET && variable != libsumo::CMD_RESUME
71 && variable != libsumo::VAR_TYPE && variable != libsumo::VAR_ROUTE_ID && variable != libsumo::VAR_ROUTE
74 && variable != libsumo::VAR_EDGE_TRAVELTIME && variable != libsumo::VAR_EDGE_EFFORT
76 && variable != libsumo::VAR_SIGNALS && variable != libsumo::VAR_MOVE_TO
77 && variable != libsumo::VAR_LENGTH && variable != libsumo::VAR_MAXSPEED && variable != libsumo::VAR_VEHICLECLASS
78 && variable != libsumo::VAR_SPEED_FACTOR && variable != libsumo::VAR_EMISSIONCLASS
79 && variable != libsumo::VAR_WIDTH && variable != libsumo::VAR_MINGAP && variable != libsumo::VAR_SHAPECLASS
80 && variable != libsumo::VAR_ACCEL && variable != libsumo::VAR_DECEL && variable != libsumo::VAR_IMPERFECTION
83 && variable != libsumo::VAR_TAU && variable != libsumo::VAR_LANECHANGE_MODE
84 && variable != libsumo::VAR_SPEED && variable != libsumo::VAR_ACCELERATION && variable != libsumo::VAR_PREV_SPEED && variable != libsumo::VAR_SPEEDSETMODE && variable != libsumo::VAR_COLOR
85 && variable != libsumo::ADD && variable != libsumo::ADD_FULL && variable != libsumo::REMOVE
86 && variable != libsumo::VAR_HEIGHT
87 && variable != libsumo::VAR_MASS
88 && variable != libsumo::VAR_ROUTING_MODE
89 && variable != libsumo::VAR_LATALIGNMENT
90 && variable != libsumo::VAR_MAXSPEED_LAT
91 && variable != libsumo::VAR_MINGAP_LAT
92 && variable != libsumo::VAR_LINE
93 && variable != libsumo::VAR_VIA
94 && variable != libsumo::VAR_IMPATIENCE
96 && variable != libsumo::VAR_HIGHLIGHT
97 && variable != libsumo::CMD_TAXI_DISPATCH
98 && variable != libsumo::MOVE_TO_XY && variable != libsumo::VAR_PARAMETER/* && variable != libsumo::VAR_SPEED_TIME_LINE && variable != libsumo::VAR_LANE_TIME_LINE*/
99 ) {
100 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Change Vehicle State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
101 }
102 // id
103 std::string id = inputStorage.readString();
104#ifdef DEBUG_MOVEXY
105 std::cout << SIMTIME << " processSet veh=" << id << "\n";
106#endif
107 const bool shouldExist = variable != libsumo::ADD && variable != libsumo::ADD_FULL;
109 if (sumoVehicle == nullptr) {
110 if (shouldExist) {
111 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
112 }
113 }
114 MSBaseVehicle* v = dynamic_cast<MSBaseVehicle*>(sumoVehicle);
115 if (v == nullptr && shouldExist) {
116 return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a proper vehicle", outputStorage);
117 }
118 try {
119 switch (variable) {
120 case libsumo::CMD_STOP: {
121 const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Stop needs a compound object description.");
122 if (compoundSize < 4 || compoundSize > 7) {
123 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description of four to seven items.", outputStorage);
124 }
125 // read road map position
126 const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first stop parameter must be the edge id given as a string.");
127 const double pos = StoHelp::readTypedDouble(inputStorage, "The second stop parameter must be the end position along the edge given as a double.");
128 const int laneIndex = StoHelp::readTypedByte(inputStorage, "The third stop parameter must be the lane index given as a byte.");
129 const double duration = StoHelp::readTypedDouble(inputStorage, "The fourth stop parameter must be the stopping duration given as a double.");
130 int stopFlags = 0;
131 if (compoundSize >= 5) {
132 stopFlags = StoHelp::readTypedByte(inputStorage, "The fifth stop parameter must be a byte indicating its parking/triggered status.");
133 }
134 double startPos = libsumo::INVALID_DOUBLE_VALUE;
135 if (compoundSize >= 6) {
136 startPos = StoHelp::readTypedDouble(inputStorage, "The sixth stop parameter must be the start position along the edge given as a double.");
137 }
138 double until = libsumo::INVALID_DOUBLE_VALUE;
139 if (compoundSize >= 7) {
140 until = StoHelp::readTypedDouble(inputStorage, "The seventh stop parameter must be the minimum departure time given as a double.");
141 }
142 libsumo::Vehicle::setStop(id, edgeID, pos, laneIndex, duration, stopFlags, startPos, until);
143 }
144 break;
146 if (!insertReplaceStop(server, inputStorage, outputStorage, id, true)) {
147 return false;
148 }
149 break;
151 if (!insertReplaceStop(server, inputStorage, outputStorage, id, false)) {
152 return false;
153 }
154 break;
156 const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Setting stop parameter needs a compound object description.");
157 if (compoundSize != 3 && compoundSize != 4) {
158 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting a stop parameter needs a compound object description of 3 or 4 items.", outputStorage);
159 }
160 const int nextStopIndex = StoHelp::readTypedInt(inputStorage, "The first setStopParameter parameter must be the nextStopIndex given as an integer.");
161 const std::string param = StoHelp::readTypedString(inputStorage, "The second setStopParameter parameter must be the param given as a string.");
162 const std::string value = StoHelp::readTypedString(inputStorage, "The third setStopParameter parameter must be the value given as a string.");
163 int customParam = 0;
164 if (compoundSize == 4) {
165 customParam = StoHelp::readTypedByte(inputStorage, "The fourth setStopParameter parameter must be the customParam flag given as a byte.");
166 }
167 libsumo::Vehicle::setStopParameter(id, nextStopIndex, param, value, customParam != 0);
168 }
169 break;
171 StoHelp::readCompound(inputStorage, 1, "Reroute to stop needs a compound object description of 1 item.");
172 libsumo::Vehicle::rerouteParkingArea(id, StoHelp::readTypedString(inputStorage, "The first reroute to stop parameter must be the parking area id given as a string."));
173 }
174 break;
175 case libsumo::CMD_RESUME: {
176 StoHelp::readCompound(inputStorage, 0, "Resuming requires an empty compound object.");
177 libsumo::Vehicle::resume(id);
178 }
179 break;
181 const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Lane change needs a compound object description.");
182 if (compoundSize != 3 && compoundSize != 2) {
183 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two or three items.", outputStorage);
184 }
185 const int laneIndex = StoHelp::readTypedByte(inputStorage, "The first lane change parameter must be the lane index given as a byte.");
186 const double duration = StoHelp::readTypedDouble(inputStorage, "The second lane change parameter must be the duration given as a double.");
187 // relative lane change
188 int relative = 0;
189 if (compoundSize == 3) {
190 relative = StoHelp::readTypedByte(inputStorage, "The third lane change parameter must be a Byte for defining whether a relative lane change should be applied.");
191 }
192
193 if ((laneIndex < 0 || laneIndex >= (int)v->getEdge()->getLanes().size()) && relative < 1) {
194 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + v->getEdge()->getID() + "'.", outputStorage);
195 }
196
197 if (relative < 1) {
198 libsumo::Vehicle::changeLane(id, laneIndex, duration);
199 } else {
200 libsumo::Vehicle::changeLaneRelative(id, laneIndex, duration);
201 }
202 }
203 break;
205 libsumo::Vehicle::changeSublane(id, StoHelp::readTypedDouble(inputStorage, "Sublane-changing requires a double."));
206 }
207 break;
209 StoHelp::readCompound(inputStorage, 2, "Slow down needs a compound object description of two items.");
210 const double newSpeed = StoHelp::readTypedDouble(inputStorage, "The first slow down parameter must be the speed given as a double.");
211 if (newSpeed < 0.) {
212 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Speed must not be negative", outputStorage);
213 }
214 const double duration = StoHelp::readTypedDouble(inputStorage, "The second slow down parameter must be the duration given as a double.");
215 if (duration < 0. || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
216 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval", outputStorage);
217 }
218 libsumo::Vehicle::slowDown(id, newSpeed, duration);
219 }
220 break;
222 libsumo::Vehicle::changeTarget(id, StoHelp::readTypedString(inputStorage, "Change target requires a string containing the id of the new destination edge as parameter."));
223 }
224 break;
226 const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Create gap needs a compound object description.");
227 if (compoundSize != 5 && compoundSize != 6) {
228 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Create gap needs a compound object description of five or six items.", outputStorage);
229 }
230 const double newTimeHeadway = StoHelp::readTypedDouble(inputStorage, "The first create gap parameter must be the new desired time headway (tau) given as a double.");
231 double newSpaceHeadway = StoHelp::readTypedDouble(inputStorage, "The second create gap parameter must be the new desired space headway given as a double.");
232 const double duration = StoHelp::readTypedDouble(inputStorage, "The third create gap parameter must be the duration given as a double.");
233 const double changeRate = StoHelp::readTypedDouble(inputStorage, "The fourth create gap parameter must be the change rate given as a double.");
234 const double maxDecel = StoHelp::readTypedDouble(inputStorage, "The fifth create gap parameter must be the maximal braking rate given as a double.");
235
236 if (newTimeHeadway == -1 && newSpaceHeadway == -1 && duration == -1 && changeRate == -1 && maxDecel == -1) {
237 libsumo::Vehicle::deactivateGapControl(id);
238 } else {
239 if (newTimeHeadway <= 0) {
240 if (newTimeHeadway != -1) {
241 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired time headway (tau) must be positive for create gap", outputStorage);
242 } // else if == -1: keep vehicles current headway, see libsumo::Vehicle::openGap
243 }
244 if (newSpaceHeadway < 0) {
245 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired space headway must be non-negative for create gap", outputStorage);
246 }
247 if ((duration < 0 && duration != -1) || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
248 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval for create gap", outputStorage);
249 }
250 if (changeRate <= 0) {
251 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the change rate must be positive for the openGap command", outputStorage);
252 }
253 if (maxDecel <= 0 && maxDecel != -1 && maxDecel != libsumo::INVALID_DOUBLE_VALUE) {
254 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the maximal braking rate must be positive for the openGap command", outputStorage);
255 } // else if <= 0: don't limit cf model's suggested brake rate, see libsumo::Vehicle::openGap
256 std::string refVehID = "";
257 if (compoundSize == 6) {
258 refVehID = StoHelp::readTypedString(inputStorage, "The sixth create gap parameter must be a reference vehicle's ID given as a string.");
259 }
260 libsumo::Vehicle::openGap(id, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel, refVehID);
261 }
262 }
263 break;
264 case libsumo::VAR_TYPE: {
265 libsumo::Vehicle::setType(id, StoHelp::readTypedString(inputStorage, "The vehicle type id must be given as a string."));
266 }
267 break;
269 libsumo::Vehicle::setRouteID(id, StoHelp::readTypedString(inputStorage, "The route id must be given as a string."));
270 }
271 break;
272 case libsumo::VAR_ROUTE: {
273 libsumo::Vehicle::setRoute(id, StoHelp::readTypedStringList(inputStorage, "A route must be defined as a list of edge ids."));
274 }
275 break;
277 const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting travel time requires a compound object.");
278 std::string edgeID;
279 double begTime = 0.;
280 double endTime = std::numeric_limits<double>::max();
281 double value = libsumo::INVALID_DOUBLE_VALUE;
282 if (parameterCount == 4) {
283 begTime = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the begin time as first parameter.");
284 endTime = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the end time as second parameter.");
285 edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 4 parameters requires the referenced edge as third parameter.");
286 value = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the travel time as double as fourth parameter.");
287 } else if (parameterCount == 2) {
288 edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 2 parameters requires the referenced edge as first parameter.");
289 value = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 2 parameters requires the travel time as double as second parameter.");
290 } else if (parameterCount == 1) {
291 edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 1 parameter requires the referenced edge as first parameter.");
292 } else {
293 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);
294 }
295 libsumo::Vehicle::setAdaptedTraveltime(id, edgeID, value, begTime, endTime);
296 }
297 break;
299 const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting travel time requires a compound object.");
300 std::string edgeID;
301 double begTime = 0.;
302 double endTime = std::numeric_limits<double>::max();
303 double value = libsumo::INVALID_DOUBLE_VALUE;
304 if (parameterCount == 4) {
305 begTime = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the begin time as first parameter.");
306 endTime = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the end time as second parameter.");
307 edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 4 parameters requires the referenced edge as third parameter.");
308 value = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the effort as double as fourth parameter.");
309 } else if (parameterCount == 2) {
310 edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 2 parameters requires the referenced edge as first parameter.");
311 value = StoHelp::readTypedDouble(inputStorage, "Setting effort using 2 parameters requires the effort as double as second parameter.");
312 } else if (parameterCount == 1) {
313 edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 1 parameter requires the referenced edge as first parameter.");
314 } else {
315 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);
316 }
317 libsumo::Vehicle::setEffort(id, edgeID, value, begTime, endTime);
318 }
319 break;
321 StoHelp::readCompound(inputStorage, 0, "Rerouting by travel time requires an empty compound object.");
322 libsumo::Vehicle::rerouteTraveltime(id, false);
323 }
324 break;
326 StoHelp::readCompound(inputStorage, 0, "Rerouting by effort requires an empty compound object.");
327 libsumo::Vehicle::rerouteEffort(id);
328 }
329 break;
331 libsumo::Vehicle::setSignals(id, StoHelp::readTypedInt(inputStorage, "Setting signals requires an integer."));
332 break;
334 const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting position requires a compound object.");
335 if (parameterCount < 2 || parameterCount > 3) {
336 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting position should obtain the lane id and the position and optionally the reason.", outputStorage);
337 }
338 const std::string laneID = StoHelp::readTypedString(inputStorage, "The first parameter for setting a position must be the lane ID given as a string.");
339 const double position = StoHelp::readTypedDouble(inputStorage, "The second parameter for setting a position must be the position given as a double.");
340 int reason = libsumo::MOVE_AUTOMATIC;
341 if (parameterCount == 3) {
342 reason = StoHelp::readTypedInt(inputStorage, "The third parameter for setting a position must be the reason given as an int.");
343 }
344 // process
345 libsumo::Vehicle::moveTo(id, laneID, position, reason);
346 }
347 break;
349 libsumo::Vehicle::setImpatience(id, StoHelp::readTypedDouble(inputStorage, "Setting impatience requires a double."));
350 }
351 break;
352 case libsumo::VAR_SPEED: {
353 libsumo::Vehicle::setSpeed(id, StoHelp::readTypedDouble(inputStorage, "Setting speed requires a double."));
354 }
355 break;
357 StoHelp::readCompound(inputStorage, 2, "Setting acceleration requires 2 parameters.");
358 const double accel = StoHelp::readTypedDouble(inputStorage, "Setting acceleration requires the acceleration as first parameter given as a double.");
359 const double duration = StoHelp::readTypedDouble(inputStorage, "Setting acceleration requires the duration as second parameter given as a double.");
360 if (duration < 0) {
361 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Duration must not be negative.", outputStorage);
362 }
363 libsumo::Vehicle::setAcceleration(id, accel, duration);
364 }
365 break;
367 double prevSpeed = 0;
368 double prevAcceleration = libsumo::INVALID_DOUBLE_VALUE;
369 int inputtype = inputStorage.readUnsignedByte();
370 if (inputtype == libsumo::TYPE_COMPOUND) {
371 // Setting previous speed with 2 parameters, uses a compound object description
372 const int parameterCount = inputStorage.readInt();
373 if (parameterCount == 2) {
374 prevSpeed = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 2 parameters requires the previous speed as first parameter given as a double.");
375 prevAcceleration = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 2 parameters requires the previous acceleration as second parameter given as a double.");
376 } else if (parameterCount == 1) {
377 prevSpeed = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 1 parameter requires the previous speed as first parameter given as a double.");
378 } else {
379 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed requires 1 or 2 parameters.", outputStorage);
380 }
381 } else if (inputtype == libsumo::TYPE_DOUBLE) {
382 // Setting previous speed with 1 parameter (double), no compound object description
383 prevSpeed = inputStorage.readDouble();
384 } else {
385 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);
386 }
387 if (prevSpeed < 0) {
388 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Previous speed must not be negative.", outputStorage);
389 }
390 libsumo::Vehicle::setPreviousSpeed(id, prevSpeed, prevAcceleration);
391 }
392 break;
394 libsumo::Vehicle::setSpeedMode(id, StoHelp::readTypedInt(inputStorage, "Setting speed mode requires an integer."));
395 break;
397 libsumo::Vehicle::setLaneChangeMode(id, StoHelp::readTypedInt(inputStorage, "Setting lane change mode requires an integer."));
398 break;
400 libsumo::Vehicle::setRoutingMode(id, StoHelp::readTypedInt(inputStorage, "Setting routing mode requires an integer."));
401 break;
402 case libsumo::VAR_COLOR: {
403 libsumo::Vehicle::setColor(id, StoHelp::readTypedColor(inputStorage, "The color must be given using the according type."));
404 break;
405 }
406 case libsumo::ADD: {
407 StoHelp::readCompound(inputStorage, 6, "Adding a vehicle needs six parameters.");
408 const std::string vTypeID = StoHelp::readTypedString(inputStorage, "First parameter (type) requires a string.");
409 const std::string routeID = StoHelp::readTypedString(inputStorage, "Second parameter (route) requires a string.");
410 const int departCode = StoHelp::readTypedInt(inputStorage, "Third parameter (depart) requires an integer.");
411 std::string depart = toString(STEPS2TIME(departCode));
412 if (-departCode == static_cast<int>(DepartDefinition::TRIGGERED)) {
413 depart = "triggered";
414 } else if (-departCode == static_cast<int>(DepartDefinition::CONTAINER_TRIGGERED)) {
415 depart = "containerTriggered";
416 } else if (-departCode == static_cast<int>(DepartDefinition::NOW)) {
417 depart = "now";
418 } else if (-departCode == static_cast<int>(DepartDefinition::SPLIT)) {
419 depart = "split";
420 } else if (-departCode == static_cast<int>(DepartDefinition::BEGIN)) {
421 depart = "begin";
422 }
423
424 const double departPosCode = StoHelp::readTypedDouble(inputStorage, "Fourth parameter (position) requires a double.");
425 std::string departPos = toString(departPosCode);
426 if (-departPosCode == (int)DepartPosDefinition::RANDOM) {
427 departPos = "random";
428 } else if (-departPosCode == (int)DepartPosDefinition::RANDOM_FREE) {
429 departPos = "random_free";
430 } else if (-departPosCode == (int)DepartPosDefinition::FREE) {
431 departPos = "free";
432 } else if (-departPosCode == (int)DepartPosDefinition::BASE) {
433 departPos = "base";
434 } else if (-departPosCode == (int)DepartPosDefinition::LAST) {
435 departPos = "last";
436 } else if (-departPosCode == (int)DepartPosDefinition::GIVEN) {
437 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid departure position.", outputStorage);
438 }
439
440 const double departSpeedCode = StoHelp::readTypedDouble(inputStorage, "Fifth parameter (speed) requires a double.");
441 std::string departSpeed = toString(departSpeedCode);
442 if (-departSpeedCode == (int)DepartSpeedDefinition::RANDOM) {
443 departSpeed = "random";
444 } else if (-departSpeedCode == (int)DepartSpeedDefinition::MAX) {
445 departSpeed = "max";
446 } else if (-departSpeedCode == (int)DepartSpeedDefinition::DESIRED) {
447 departSpeed = "desired";
448 } else if (-departSpeedCode == (int)DepartSpeedDefinition::LIMIT) {
449 departSpeed = "speedLimit";
450 } else if (-departSpeedCode == (int)DepartSpeedDefinition::LAST) {
451 departSpeed = "last";
452 } else if (-departSpeedCode == (int)DepartSpeedDefinition::AVG) {
453 departSpeed = "avg";
454 }
455
456 const int departLaneCode = StoHelp::readTypedByte(inputStorage, "Sixth parameter (lane) requires a byte.");
457 std::string departLane = toString(departLaneCode);
458 if (-departLaneCode == (int)DepartLaneDefinition::RANDOM) {
459 departLane = "random";
460 } else if (-departLaneCode == (int)DepartLaneDefinition::FREE) {
461 departLane = "free";
462 } else if (-departLaneCode == (int)DepartLaneDefinition::ALLOWED_FREE) {
463 departLane = "allowed";
464 } else if (-departLaneCode == (int)DepartLaneDefinition::BEST_FREE) {
465 departLane = "best";
466 } else if (-departLaneCode == (int)DepartLaneDefinition::FIRST_ALLOWED) {
467 departLane = "first";
468 }
469 libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed);
470 }
471 break;
472 case libsumo::ADD_FULL: {
473 StoHelp::readCompound(inputStorage, 14, "Adding a fully specified vehicle needs fourteen parameters.");
474 const std::string routeID = StoHelp::readTypedString(inputStorage, "First parameter (route) requires a string.");
475 const std::string vTypeID = StoHelp::readTypedString(inputStorage, "Second parameter (type) requires a string.");
476 const std::string depart = StoHelp::readTypedString(inputStorage, "Third parameter (depart) requires an string.");
477 const std::string departLane = StoHelp::readTypedString(inputStorage, "Fourth parameter (depart lane) requires a string.");
478 const std::string departPos = StoHelp::readTypedString(inputStorage, "Fifth parameter (depart position) requires a string.");
479 const std::string departSpeed = StoHelp::readTypedString(inputStorage, "Sixth parameter (depart speed) requires a string.");
480 const std::string arrivalLane = StoHelp::readTypedString(inputStorage, "Seventh parameter (arrival lane) requires a string.");
481 const std::string arrivalPos = StoHelp::readTypedString(inputStorage, "Eighth parameter (arrival position) requires a string.");
482 const std::string arrivalSpeed = StoHelp::readTypedString(inputStorage, "Ninth parameter (arrival speed) requires a string.");
483 const std::string fromTaz = StoHelp::readTypedString(inputStorage, "Tenth parameter (from taz) requires a string.");
484 const std::string toTaz = StoHelp::readTypedString(inputStorage, "Eleventh parameter (to taz) requires a string.");
485 const std::string line = StoHelp::readTypedString(inputStorage, "Twelth parameter (line) requires a string.");
486 const int personCapacity = StoHelp::readTypedInt(inputStorage, "13th parameter (person capacity) requires an int.");
487 const int personNumber = StoHelp::readTypedInt(inputStorage, "14th parameter (person number) requires an int.");
488 libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed, arrivalLane, arrivalPos, arrivalSpeed,
489 fromTaz, toTaz, line, personCapacity, personNumber);
490 }
491 break;
492 case libsumo::REMOVE: {
493 libsumo::Vehicle::remove(id, (char)StoHelp::readTypedByte(inputStorage, "Removing a vehicle requires a byte."));
494 }
495 break;
496 case libsumo::MOVE_TO_XY: {
497 const int parameterCount = StoHelp::readCompound(inputStorage, -1, "MoveToXY vehicle requires a compound object.");
498 if (parameterCount < 5 || parameterCount > 7) {
499 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "MoveToXY vehicle should obtain: edgeID, lane, x, y, angle and optionally keepRouteFlag and matchThreshold.", outputStorage);
500 }
501 const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first parameter for moveToXY must be the edge ID given as a string.");
502 const int laneIndex = StoHelp::readTypedInt(inputStorage, "The second parameter for moveToXY must be lane given as an int.");
503 const double x = StoHelp::readTypedDouble(inputStorage, "The third parameter for moveToXY must be the x-position given as a double.");
504 const double y = StoHelp::readTypedDouble(inputStorage, "The fourth parameter for moveToXY must be the y-position given as a double.");
505 const double angle = StoHelp::readTypedDouble(inputStorage, "The fifth parameter for moveToXY must be the angle given as a double.");
506 int keepRouteFlag = 1;
507 if (parameterCount >= 6) {
508 keepRouteFlag = StoHelp::readTypedByte(inputStorage, "The sixth parameter for moveToXY must be the keepRouteFlag given as a byte.");
509 }
510 double matchThreshold = 100.;
511 if (parameterCount == 7) {
512 matchThreshold = StoHelp::readTypedDouble(inputStorage, "The seventh parameter for moveToXY must be the matchThreshold given as a double.");
513 }
514 libsumo::Vehicle::moveToXY(id, edgeID, laneIndex, x, y, angle, keepRouteFlag, matchThreshold);
515 }
516 break;
518 libsumo::Vehicle::setSpeedFactor(id, StoHelp::readTypedDouble(inputStorage, "Setting speed factor requires a double."));
519 }
520 break;
521 case libsumo::VAR_LINE: {
522 libsumo::Vehicle::setLine(id, StoHelp::readTypedString(inputStorage, "The line must be given as a string."));
523 }
524 break;
525 case libsumo::VAR_VIA: {
526 libsumo::Vehicle::setVia(id, StoHelp::readTypedStringList(inputStorage, "Vias must be defined as a list of edge ids."));
527 }
528 break;
530 StoHelp::readCompound(inputStorage, 2, "A compound object of size 2 is needed for setting a parameter.");
531 const std::string name = StoHelp::readTypedString(inputStorage, "The name of the parameter must be given as a string.");
532 const std::string value = StoHelp::readTypedString(inputStorage, "The value of the parameter must be given as a string.");
533 libsumo::Vehicle::setParameter(id, name, value);
534 }
535 break;
537 const int parameterCount = StoHelp::readCompound(inputStorage, -1, "A compound object is needed for highlighting an object.");
538 if (parameterCount > 5) {
539 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Highlighting an object needs zero to five parameters.", outputStorage);
540 }
541
543 if (parameterCount > 0) {
544 col = StoHelp::readTypedColor(inputStorage, "The first parameter for highlighting must be the highlight color.");
545 }
546 double size = -1;
547 if (parameterCount > 1) {
548 size = StoHelp::readTypedDouble(inputStorage, "The second parameter for highlighting must be the highlight size.");
549 }
550 int alphaMax = -1;
551 if (parameterCount > 2) {
552 alphaMax = StoHelp::readTypedUnsignedByte(inputStorage, "The third parameter for highlighting must be maximal alpha.");
553 }
554 double duration = -1;
555 if (parameterCount > 3) {
556 duration = StoHelp::readTypedDouble(inputStorage, "The fourth parameter for highlighting must be the highlight duration.");
557 }
558 int type = 0;
559 if (parameterCount > 4) {
560 type = StoHelp::readTypedUnsignedByte(inputStorage, "The fifth parameter for highlighting must be the highlight type id as ubyte.");
561 }
562 libsumo::Vehicle::highlight(id, col, size, alphaMax, duration, type);
563 }
564 break;
566 libsumo::Vehicle::dispatchTaxi(id, StoHelp::readTypedStringList(inputStorage, "A dispatch command must be defined as a list of reservation ids."));
567 }
568 break;
570 const double value = StoHelp::readTypedDouble(inputStorage, "Setting action step length requires a double.");
571 if (fabs(value) == std::numeric_limits<double>::infinity()) {
572 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid action step length.", outputStorage);
573 }
574 bool resetActionOffset = value >= 0.0;
575 libsumo::Vehicle::setActionStepLength(id, fabs(value), resetActionOffset);
576 }
577 break;
579 libsumo::Vehicle::setLateralLanePosition(id, StoHelp::readTypedDouble(inputStorage, "Setting lateral lane position requires a double."));
580 }
581 break;
583 libsumo::Vehicle::updateBestLanes(id);
584 }
585 break;
586 case libsumo::VAR_MINGAP: {
587 const double value = StoHelp::readTypedDouble(inputStorage, "Setting minimum gap requires a double.");
588 if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
589 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum gap.", outputStorage);
590 }
591 libsumo::Vehicle::setMinGap(id, value);
592 }
593 break;
595 const double value = StoHelp::readTypedDouble(inputStorage, "Setting minimum lateral gap requires a double.");
596 if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
597 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum lateral gap.", outputStorage);
598 }
599 libsumo::Vehicle::setMinGapLat(id, value);
600 }
601 break;
602 default: {
603 try {
604 if (!TraCIServerAPI_VehicleType::setVariable(libsumo::CMD_SET_VEHICLE_VARIABLE, variable, v->getSingularType().getID(), server, inputStorage, outputStorage)) {
605 return false;
606 }
607 } catch (ProcessError& e) {
608 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
609 } catch (libsumo::TraCIException& e) {
610 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
611 }
612 }
613 break;
614 }
615 } catch (libsumo::TraCIException& e) {
616 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
617 }
619 return true;
620}
621
622
623bool
624TraCIServerAPI_Vehicle::insertReplaceStop(TraCIServer& server, tcpip::Storage& inputStorage, tcpip::Storage& outputStorage, const std::string& id, bool replace) {
625 const std::string m1 = replace ? "Replacing" : "Inserting";
626 const std::string m2 = replace ? "replacement" : "insertion";
627 const int parameterCount = StoHelp::readCompound(inputStorage, -1, m1 + " stop needs a compound object description.");
628 if (parameterCount != 8 && parameterCount != 9) {
629 return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, m1 + " stop needs a compound object description of eight or nine items.", outputStorage);
630 }
631 // read road map position
632 const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first stop " + m2 + " parameter must be the edge id given as a string.");
633 const double pos = StoHelp::readTypedDouble(inputStorage, "The second stop " + m2 + " parameter must be the end position along the edge given as a double.");
634 const int laneIndex = StoHelp::readTypedByte(inputStorage, "The third stop " + m2 + " parameter must be the lane index given as a byte.");
635 const double duration = StoHelp::readTypedDouble(inputStorage, "The fourth stop " + m2 + " parameter must be the stopping duration given as a double.");
636 const int stopFlags = StoHelp::readTypedInt(inputStorage, "The fifth stop " + m2 + " parameter must be an int indicating its parking/triggered status.");
637 const double startPos = StoHelp::readTypedDouble(inputStorage, "The sixth stop " + m2 + " parameter must be the start position along the edge given as a double.");
638 const double until = StoHelp::readTypedDouble(inputStorage, "The seventh stop " + m2 + " parameter must be the minimum departure time given as a double.");
639 const int nextStopIndex = StoHelp::readTypedInt(inputStorage, "The eighth stop " + m2 + " parameter must be the replacement index given as an int.");
640 int teleport = 0;
641 if (parameterCount == 9) {
642 teleport = StoHelp::readTypedByte(inputStorage, "The ninth stop " + m2 + " parameter must be the teleport flag given as a byte.");
643 }
644 if (replace) {
645 libsumo::Vehicle::replaceStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
646 } else {
647 libsumo::Vehicle::insertStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
648 }
649 return true;
650}
651
652
653/****************************************************************************/
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 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.
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
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 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