Line data Source code
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 : /****************************************************************************/
14 : /// @file TraCIServerAPI_Vehicle.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Laura Bieker
17 : /// @author Christoph Sommer
18 : /// @author Michael Behrisch
19 : /// @author Bjoern Hendriks
20 : /// @author Mario Krumnow
21 : /// @author Jakob Erdmann
22 : /// @author Leonhard Luecken
23 : /// @author Robert Hilbrich
24 : /// @author Lara Codeca
25 : /// @author Mirko Barthauer
26 : /// @date 07.05.2009
27 : ///
28 : // APIs for getting/setting vehicle values via TraCI
29 : /****************************************************************************/
30 : #include <config.h>
31 :
32 : #include <microsim/MSNet.h>
33 : #include <microsim/MSInsertionControl.h>
34 : #include <microsim/MSVehicle.h>
35 : #include <microsim/MSVehicleControl.h>
36 : #include <microsim/MSLane.h>
37 : #include <microsim/MSEdge.h>
38 : #include <microsim/MSGlobals.h>
39 : #include <microsim/lcmodels/MSAbstractLaneChangeModel.h>
40 : #include <utils/geom/PositionVector.h>
41 : #include <utils/router/DijkstraRouter.h>
42 : #include <utils/router/DijkstraRouter.h>
43 : #include <utils/emissions/PollutantsInterface.h>
44 : #include <utils/emissions/HelpersHarmonoise.h>
45 : #include <utils/vehicle/SUMOVehicleParameter.h>
46 : #include <libsumo/StorageHelper.h>
47 : #include <libsumo/TraCIConstants.h>
48 : #include <libsumo/Vehicle.h>
49 : #include <libsumo/VehicleType.h>
50 : #include "TraCIServerAPI_Simulation.h"
51 : #include "TraCIServerAPI_Vehicle.h"
52 : #include "TraCIServerAPI_VehicleType.h"
53 :
54 :
55 : // ===========================================================================
56 : // method definitions
57 : // ===========================================================================
58 : bool
59 100320 : TraCIServerAPI_Vehicle::processSet(TraCIServer& server, tcpip::Storage& inputStorage,
60 : tcpip::Storage& outputStorage) {
61 100320 : std::string warning = ""; // additional description for response
62 : // variable
63 100320 : int variable = inputStorage.readUnsignedByte();
64 100320 : if (variable != libsumo::CMD_STOP && variable != libsumo::CMD_CHANGELANE
65 100320 : && variable != libsumo::CMD_REROUTE_TO_PARKING
66 50824 : && variable != libsumo::CMD_CHANGESUBLANE && variable != libsumo::CMD_OPENGAP
67 : && variable != libsumo::CMD_REPLACE_STOP
68 50602 : && variable != libsumo::CMD_INSERT_STOP
69 50403 : && variable != libsumo::VAR_STOP_PARAMETER
70 50403 : && variable != libsumo::CMD_SLOWDOWN && variable != libsumo::CMD_CHANGETARGET && variable != libsumo::CMD_RESUME
71 28496 : && variable != libsumo::VAR_TYPE && variable != libsumo::VAR_ROUTE_ID && variable != libsumo::VAR_ROUTE
72 28323 : && variable != libsumo::VAR_LANEPOSITION_LAT
73 28291 : && variable != libsumo::VAR_UPDATE_BESTLANES
74 28291 : && variable != libsumo::VAR_EDGE_TRAVELTIME && variable != libsumo::VAR_EDGE_EFFORT
75 28005 : && variable != libsumo::CMD_REROUTE_TRAVELTIME && variable != libsumo::CMD_REROUTE_EFFORT
76 27765 : && variable != libsumo::VAR_SIGNALS && variable != libsumo::VAR_MOVE_TO
77 27743 : && variable != libsumo::VAR_LENGTH && variable != libsumo::VAR_MAXSPEED && variable != libsumo::VAR_VEHICLECLASS
78 27335 : && variable != libsumo::VAR_SPEED_FACTOR && variable != libsumo::VAR_EMISSIONCLASS
79 23221 : && variable != libsumo::VAR_WIDTH && variable != libsumo::VAR_MINGAP && variable != libsumo::VAR_SHAPECLASS
80 23203 : && variable != libsumo::VAR_ACCEL && variable != libsumo::VAR_DECEL && variable != libsumo::VAR_IMPERFECTION
81 23157 : && variable != libsumo::VAR_APPARENT_DECEL && variable != libsumo::VAR_EMERGENCY_DECEL
82 23136 : && variable != libsumo::VAR_ACTIONSTEPLENGTH
83 23136 : && variable != libsumo::VAR_TAU && variable != libsumo::VAR_LANECHANGE_MODE
84 23116 : && variable != libsumo::VAR_SPEED && variable != libsumo::VAR_ACCELERATION && variable != libsumo::VAR_PREV_SPEED && variable != libsumo::VAR_SPEEDSETMODE && variable != libsumo::VAR_COLOR
85 19058 : && variable != libsumo::ADD && variable != libsumo::ADD_FULL && variable != libsumo::REMOVE
86 3879 : && variable != libsumo::VAR_HEIGHT
87 3851 : && variable != libsumo::VAR_MASS
88 3851 : && variable != libsumo::VAR_ROUTING_MODE
89 : && variable != libsumo::VAR_LATALIGNMENT
90 3667 : && variable != libsumo::VAR_MAXSPEED_LAT
91 3657 : && variable != libsumo::VAR_MINGAP_LAT
92 3657 : && variable != libsumo::VAR_LINE
93 3643 : && variable != libsumo::VAR_VIA
94 3643 : && variable != libsumo::VAR_IMPATIENCE
95 3617 : && variable != libsumo::VAR_BOARDING_DURATION
96 3617 : && variable != libsumo::VAR_HIGHLIGHT
97 3586 : && variable != libsumo::CMD_TAXI_DISPATCH
98 3586 : && variable != libsumo::MOVE_TO_XY && variable != libsumo::VAR_PARAMETER/* && variable != libsumo::VAR_SPEED_TIME_LINE && variable != libsumo::VAR_LANE_TIME_LINE*/
99 : ) {
100 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Change Vehicle State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
101 : }
102 : // id
103 100320 : std::string id = inputStorage.readString();
104 : #ifdef DEBUG_MOVEXY
105 : std::cout << SIMTIME << " processSet veh=" << id << "\n";
106 : #endif
107 100320 : const bool shouldExist = variable != libsumo::ADD && variable != libsumo::ADD_FULL;
108 100320 : SUMOVehicle* sumoVehicle = MSNet::getInstance()->getVehicleControl().getVehicle(id);
109 100320 : if (sumoVehicle == nullptr) {
110 15189 : if (shouldExist) {
111 33 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
112 : }
113 : }
114 85131 : MSBaseVehicle* v = dynamic_cast<MSBaseVehicle*>(sumoVehicle);
115 100309 : if (v == nullptr && shouldExist) {
116 0 : return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a proper vehicle", outputStorage);
117 : }
118 : try {
119 100309 : switch (variable) {
120 : case libsumo::CMD_STOP: {
121 44833 : const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Stop needs a compound object description.");
122 44833 : if (compoundSize < 4 || compoundSize > 7) {
123 0 : 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 44833 : const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first stop parameter must be the edge id given as a string.");
127 44833 : const double pos = StoHelp::readTypedDouble(inputStorage, "The second stop parameter must be the end position along the edge given as a double.");
128 44833 : const int laneIndex = StoHelp::readTypedByte(inputStorage, "The third stop parameter must be the lane index given as a byte.");
129 44833 : const double duration = StoHelp::readTypedDouble(inputStorage, "The fourth stop parameter must be the stopping duration given as a double.");
130 : int stopFlags = 0;
131 44833 : if (compoundSize >= 5) {
132 44832 : 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 44832 : if (compoundSize >= 6) {
136 44831 : 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 44831 : if (compoundSize >= 7) {
140 89671 : until = StoHelp::readTypedDouble(inputStorage, "The seventh stop parameter must be the minimum departure time given as a double.");
141 : }
142 44833 : libsumo::Vehicle::setStop(id, edgeID, pos, laneIndex, duration, stopFlags, startPos, until);
143 : }
144 44824 : break;
145 116 : case libsumo::CMD_REPLACE_STOP:
146 116 : if (!insertReplaceStop(server, inputStorage, outputStorage, id, true)) {
147 : return false;
148 : }
149 : break;
150 83 : case libsumo::CMD_INSERT_STOP:
151 83 : if (!insertReplaceStop(server, inputStorage, outputStorage, id, false)) {
152 : return false;
153 : }
154 : break;
155 : case libsumo::VAR_STOP_PARAMETER: {
156 102 : const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Setting stop parameter needs a compound object description.");
157 102 : if (compoundSize != 3 && compoundSize != 4) {
158 0 : 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 102 : const int nextStopIndex = StoHelp::readTypedInt(inputStorage, "The first setStopParameter parameter must be the nextStopIndex given as an integer.");
161 102 : const std::string param = StoHelp::readTypedString(inputStorage, "The second setStopParameter parameter must be the param given as a string.");
162 105 : const std::string value = StoHelp::readTypedString(inputStorage, "The third setStopParameter parameter must be the value given as a string.");
163 : int customParam = 0;
164 102 : if (compoundSize == 4) {
165 207 : customParam = StoHelp::readTypedByte(inputStorage, "The fourth setStopParameter parameter must be the customParam flag given as a byte.");
166 : }
167 102 : libsumo::Vehicle::setStopParameter(id, nextStopIndex, param, value, customParam != 0);
168 : }
169 99 : break;
170 : case libsumo::CMD_REROUTE_TO_PARKING: {
171 12 : StoHelp::readCompound(inputStorage, 1, "Reroute to stop needs a compound object description of 1 item.");
172 12 : 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 12 : break;
175 : case libsumo::CMD_RESUME: {
176 8 : StoHelp::readCompound(inputStorage, 0, "Resuming requires an empty compound object.");
177 8 : libsumo::Vehicle::resume(id);
178 : }
179 : break;
180 : case libsumo::CMD_CHANGELANE: {
181 4649 : const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Lane change needs a compound object description.");
182 4649 : if (compoundSize != 3 && compoundSize != 2) {
183 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two or three items.", outputStorage);
184 : }
185 4649 : const int laneIndex = StoHelp::readTypedByte(inputStorage, "The first lane change parameter must be the lane index given as a byte.");
186 4649 : 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 4649 : if (compoundSize == 3) {
190 338 : 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 4649 : if ((laneIndex < 0 || laneIndex >= (int)v->getEdge()->getLanes().size()) && relative < 1) {
194 3 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + v->getEdge()->getID() + "'.", outputStorage);
195 : }
196 :
197 4648 : if (relative < 1) {
198 4485 : libsumo::Vehicle::changeLane(id, laneIndex, duration);
199 : } else {
200 163 : libsumo::Vehicle::changeLaneRelative(id, laneIndex, duration);
201 : }
202 : }
203 4648 : break;
204 : case libsumo::CMD_CHANGESUBLANE: {
205 187 : libsumo::Vehicle::changeSublane(id, StoHelp::readTypedDouble(inputStorage, "Sublane-changing requires a double."));
206 : }
207 187 : break;
208 : case libsumo::CMD_SLOWDOWN: {
209 41 : StoHelp::readCompound(inputStorage, 2, "Slow down needs a compound object description of two items.");
210 41 : const double newSpeed = StoHelp::readTypedDouble(inputStorage, "The first slow down parameter must be the speed given as a double.");
211 41 : if (newSpeed < 0.) {
212 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Speed must not be negative", outputStorage);
213 : }
214 41 : const double duration = StoHelp::readTypedDouble(inputStorage, "The second slow down parameter must be the duration given as a double.");
215 41 : if (duration < 0. || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
216 2 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval", outputStorage);
217 : }
218 40 : libsumo::Vehicle::slowDown(id, newSpeed, duration);
219 : }
220 : break;
221 : case libsumo::CMD_CHANGETARGET: {
222 21754 : libsumo::Vehicle::changeTarget(id, StoHelp::readTypedString(inputStorage, "Change target requires a string containing the id of the new destination edge as parameter."));
223 : }
224 21746 : break;
225 : case libsumo::CMD_OPENGAP: {
226 35 : const int compoundSize = StoHelp::readCompound(inputStorage, -1, "Create gap needs a compound object description.");
227 35 : if (compoundSize != 5 && compoundSize != 6) {
228 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Create gap needs a compound object description of five or six items.", outputStorage);
229 : }
230 35 : const double newTimeHeadway = StoHelp::readTypedDouble(inputStorage, "The first create gap parameter must be the new desired time headway (tau) given as a double.");
231 35 : double newSpaceHeadway = StoHelp::readTypedDouble(inputStorage, "The second create gap parameter must be the new desired space headway given as a double.");
232 35 : const double duration = StoHelp::readTypedDouble(inputStorage, "The third create gap parameter must be the duration given as a double.");
233 35 : const double changeRate = StoHelp::readTypedDouble(inputStorage, "The fourth create gap parameter must be the change rate given as a double.");
234 35 : const double maxDecel = StoHelp::readTypedDouble(inputStorage, "The fifth create gap parameter must be the maximal braking rate given as a double.");
235 :
236 35 : if (newTimeHeadway == -1 && newSpaceHeadway == -1 && duration == -1 && changeRate == -1 && maxDecel == -1) {
237 4 : libsumo::Vehicle::deactivateGapControl(id);
238 : } else {
239 31 : if (newTimeHeadway <= 0) {
240 4 : if (newTimeHeadway != -1) {
241 0 : 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 31 : if (newSpaceHeadway < 0) {
245 0 : 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 31 : if ((duration < 0 && duration != -1) || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
248 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval for create gap", outputStorage);
249 : }
250 31 : if (changeRate <= 0) {
251 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the change rate must be positive for the openGap command", outputStorage);
252 : }
253 31 : if (maxDecel <= 0 && maxDecel != -1 && maxDecel != libsumo::INVALID_DOUBLE_VALUE) {
254 0 : 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 31 : std::string refVehID = "";
257 31 : if (compoundSize == 6) {
258 14 : refVehID = StoHelp::readTypedString(inputStorage, "The sixth create gap parameter must be a reference vehicle's ID given as a string.");
259 : }
260 31 : libsumo::Vehicle::openGap(id, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel, refVehID);
261 : }
262 : }
263 : break;
264 : case libsumo::VAR_TYPE: {
265 154 : libsumo::Vehicle::setType(id, StoHelp::readTypedString(inputStorage, "The vehicle type id must be given as a string."));
266 : }
267 154 : break;
268 : case libsumo::VAR_ROUTE_ID: {
269 18 : libsumo::Vehicle::setRouteID(id, StoHelp::readTypedString(inputStorage, "The route id must be given as a string."));
270 : }
271 15 : break;
272 : case libsumo::VAR_ROUTE: {
273 26 : libsumo::Vehicle::setRoute(id, StoHelp::readTypedStringList(inputStorage, "A route must be defined as a list of edge ids."));
274 : }
275 19 : break;
276 : case libsumo::VAR_EDGE_TRAVELTIME: {
277 236 : 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 118 : if (parameterCount == 4) {
283 50 : begTime = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the begin time as first parameter.");
284 50 : endTime = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the end time as second parameter.");
285 50 : edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 4 parameters requires the referenced edge as third parameter.");
286 100 : value = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 4 parameters requires the travel time as double as fourth parameter.");
287 68 : } else if (parameterCount == 2) {
288 63 : edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 2 parameters requires the referenced edge as first parameter.");
289 126 : value = StoHelp::readTypedDouble(inputStorage, "Setting travel time using 2 parameters requires the travel time as double as second parameter.");
290 5 : } else if (parameterCount == 1) {
291 10 : edgeID = StoHelp::readTypedString(inputStorage, "Setting travel time using 1 parameter requires the referenced edge as first parameter.");
292 : } else {
293 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);
294 : }
295 118 : libsumo::Vehicle::setAdaptedTraveltime(id, edgeID, value, begTime, endTime);
296 : }
297 : break;
298 : case libsumo::VAR_EDGE_EFFORT: {
299 40 : 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 20 : if (parameterCount == 4) {
305 12 : begTime = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the begin time as first parameter.");
306 12 : endTime = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the end time as second parameter.");
307 12 : edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 4 parameters requires the referenced edge as third parameter.");
308 24 : value = StoHelp::readTypedDouble(inputStorage, "Setting effort using 4 parameters requires the effort as double as fourth parameter.");
309 8 : } else if (parameterCount == 2) {
310 3 : edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 2 parameters requires the referenced edge as first parameter.");
311 6 : value = StoHelp::readTypedDouble(inputStorage, "Setting effort using 2 parameters requires the effort as double as second parameter.");
312 5 : } else if (parameterCount == 1) {
313 10 : edgeID = StoHelp::readTypedString(inputStorage, "Setting effort using 1 parameter requires the referenced edge as first parameter.");
314 : } else {
315 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);
316 : }
317 20 : libsumo::Vehicle::setEffort(id, edgeID, value, begTime, endTime);
318 : }
319 : break;
320 : case libsumo::CMD_REROUTE_TRAVELTIME: {
321 219 : StoHelp::readCompound(inputStorage, 0, "Rerouting by travel time requires an empty compound object.");
322 219 : libsumo::Vehicle::rerouteTraveltime(id, false);
323 : }
324 : break;
325 : case libsumo::CMD_REROUTE_EFFORT: {
326 7 : StoHelp::readCompound(inputStorage, 0, "Rerouting by effort requires an empty compound object.");
327 7 : libsumo::Vehicle::rerouteEffort(id);
328 : }
329 : break;
330 : case libsumo::VAR_SIGNALS:
331 14 : libsumo::Vehicle::setSignals(id, StoHelp::readTypedInt(inputStorage, "Setting signals requires an integer."));
332 14 : break;
333 : case libsumo::VAR_MOVE_TO: {
334 304 : const int parameterCount = StoHelp::readCompound(inputStorage, -1, "Setting position requires a compound object.");
335 304 : if (parameterCount < 2 || parameterCount > 3) {
336 0 : 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 304 : const std::string laneID = StoHelp::readTypedString(inputStorage, "The first parameter for setting a position must be the lane ID given as a string.");
339 304 : 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 304 : if (parameterCount == 3) {
342 609 : reason = StoHelp::readTypedInt(inputStorage, "The third parameter for setting a position must be the reason given as an int.");
343 : }
344 : // process
345 304 : libsumo::Vehicle::moveTo(id, laneID, position, reason);
346 : }
347 293 : break;
348 : case libsumo::VAR_IMPATIENCE: {
349 15 : libsumo::Vehicle::setImpatience(id, StoHelp::readTypedDouble(inputStorage, "Setting impatience requires a double."));
350 : }
351 15 : break;
352 : case libsumo::VAR_SPEED: {
353 1990 : libsumo::Vehicle::setSpeed(id, StoHelp::readTypedDouble(inputStorage, "Setting speed requires a double."));
354 : }
355 1990 : break;
356 : case libsumo::VAR_ACCELERATION: {
357 9 : StoHelp::readCompound(inputStorage, 2, "Setting acceleration requires 2 parameters.");
358 9 : const double accel = StoHelp::readTypedDouble(inputStorage, "Setting acceleration requires the acceleration as first parameter given as a double.");
359 9 : const double duration = StoHelp::readTypedDouble(inputStorage, "Setting acceleration requires the duration as second parameter given as a double.");
360 9 : if (duration < 0) {
361 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Duration must not be negative.", outputStorage);
362 : }
363 9 : libsumo::Vehicle::setAcceleration(id, accel, duration);
364 : }
365 : break;
366 145 : case libsumo::VAR_PREV_SPEED: {
367 : double prevSpeed = 0;
368 : double prevAcceleration = libsumo::INVALID_DOUBLE_VALUE;
369 145 : int inputtype = inputStorage.readUnsignedByte();
370 145 : if (inputtype == libsumo::TYPE_COMPOUND) {
371 : // Setting previous speed with 2 parameters, uses a compound object description
372 145 : const int parameterCount = inputStorage.readInt();
373 145 : if (parameterCount == 2) {
374 145 : prevSpeed = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 2 parameters requires the previous speed as first parameter given as a double.");
375 290 : prevAcceleration = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 2 parameters requires the previous acceleration as second parameter given as a double.");
376 0 : } else if (parameterCount == 1) {
377 0 : prevSpeed = StoHelp::readTypedDouble(inputStorage, "Setting previous speed using 1 parameter requires the previous speed as first parameter given as a double.");
378 : } else {
379 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed requires 1 or 2 parameters.", outputStorage);
380 : }
381 0 : } else if (inputtype == libsumo::TYPE_DOUBLE) {
382 : // Setting previous speed with 1 parameter (double), no compound object description
383 0 : prevSpeed = inputStorage.readDouble();
384 : } else {
385 0 : 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 145 : if (prevSpeed < 0) {
388 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Previous speed must not be negative.", outputStorage);
389 : }
390 145 : libsumo::Vehicle::setPreviousSpeed(id, prevSpeed, prevAcceleration);
391 : }
392 : break;
393 : case libsumo::VAR_SPEEDSETMODE:
394 1545 : libsumo::Vehicle::setSpeedMode(id, StoHelp::readTypedInt(inputStorage, "Setting speed mode requires an integer."));
395 1545 : break;
396 : case libsumo::VAR_LANECHANGE_MODE:
397 277 : libsumo::Vehicle::setLaneChangeMode(id, StoHelp::readTypedInt(inputStorage, "Setting lane change mode requires an integer."));
398 277 : break;
399 : case libsumo::VAR_ROUTING_MODE:
400 179 : libsumo::Vehicle::setRoutingMode(id, StoHelp::readTypedInt(inputStorage, "Setting routing mode requires an integer."));
401 179 : break;
402 : case libsumo::VAR_COLOR: {
403 91 : libsumo::Vehicle::setColor(id, StoHelp::readTypedColor(inputStorage, "The color must be given using the according type."));
404 91 : break;
405 : }
406 : case libsumo::ADD: {
407 9 : StoHelp::readCompound(inputStorage, 6, "Adding a vehicle needs six parameters.");
408 9 : const std::string vTypeID = StoHelp::readTypedString(inputStorage, "First parameter (type) requires a string.");
409 14 : const std::string routeID = StoHelp::readTypedString(inputStorage, "Second parameter (route) requires a string.");
410 9 : const int departCode = StoHelp::readTypedInt(inputStorage, "Third parameter (depart) requires an integer.");
411 14 : 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 14 : const double departPosCode = StoHelp::readTypedDouble(inputStorage, "Fourth parameter (position) requires a double.");
425 9 : std::string departPos = toString(departPosCode);
426 9 : if (-departPosCode == (int)DepartPosDefinition::RANDOM) {
427 : departPos = "random";
428 9 : } else if (-departPosCode == (int)DepartPosDefinition::RANDOM_FREE) {
429 : departPos = "random_free";
430 9 : } else if (-departPosCode == (int)DepartPosDefinition::FREE) {
431 : departPos = "free";
432 9 : } else if (-departPosCode == (int)DepartPosDefinition::BASE) {
433 : departPos = "base";
434 9 : } else if (-departPosCode == (int)DepartPosDefinition::LAST) {
435 : departPos = "last";
436 9 : } else if (-departPosCode == (int)DepartPosDefinition::GIVEN) {
437 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid departure position.", outputStorage);
438 : }
439 :
440 14 : const double departSpeedCode = StoHelp::readTypedDouble(inputStorage, "Fifth parameter (speed) requires a double.");
441 9 : std::string departSpeed = toString(departSpeedCode);
442 9 : if (-departSpeedCode == (int)DepartSpeedDefinition::RANDOM) {
443 : departSpeed = "random";
444 9 : } else if (-departSpeedCode == (int)DepartSpeedDefinition::MAX) {
445 : departSpeed = "max";
446 9 : } else if (-departSpeedCode == (int)DepartSpeedDefinition::DESIRED) {
447 : departSpeed = "desired";
448 9 : } else if (-departSpeedCode == (int)DepartSpeedDefinition::LIMIT) {
449 : departSpeed = "speedLimit";
450 9 : } else if (-departSpeedCode == (int)DepartSpeedDefinition::LAST) {
451 : departSpeed = "last";
452 9 : } else if (-departSpeedCode == (int)DepartSpeedDefinition::AVG) {
453 : departSpeed = "avg";
454 : }
455 :
456 14 : const int departLaneCode = StoHelp::readTypedByte(inputStorage, "Sixth parameter (lane) requires a byte.");
457 9 : 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 43 : libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed);
470 : }
471 : break;
472 : case libsumo::ADD_FULL: {
473 15170 : StoHelp::readCompound(inputStorage, 14, "Adding a fully specified vehicle needs fourteen parameters.");
474 15170 : const std::string routeID = StoHelp::readTypedString(inputStorage, "First parameter (route) requires a string.");
475 15184 : const std::string vTypeID = StoHelp::readTypedString(inputStorage, "Second parameter (type) requires a string.");
476 15184 : const std::string depart = StoHelp::readTypedString(inputStorage, "Third parameter (depart) requires an string.");
477 15184 : const std::string departLane = StoHelp::readTypedString(inputStorage, "Fourth parameter (depart lane) requires a string.");
478 15184 : const std::string departPos = StoHelp::readTypedString(inputStorage, "Fifth parameter (depart position) requires a string.");
479 15184 : const std::string departSpeed = StoHelp::readTypedString(inputStorage, "Sixth parameter (depart speed) requires a string.");
480 15184 : const std::string arrivalLane = StoHelp::readTypedString(inputStorage, "Seventh parameter (arrival lane) requires a string.");
481 15184 : const std::string arrivalPos = StoHelp::readTypedString(inputStorage, "Eighth parameter (arrival position) requires a string.");
482 15184 : const std::string arrivalSpeed = StoHelp::readTypedString(inputStorage, "Ninth parameter (arrival speed) requires a string.");
483 15184 : const std::string fromTaz = StoHelp::readTypedString(inputStorage, "Tenth parameter (from taz) requires a string.");
484 15184 : const std::string toTaz = StoHelp::readTypedString(inputStorage, "Eleventh parameter (to taz) requires a string.");
485 15184 : const std::string line = StoHelp::readTypedString(inputStorage, "Twelth parameter (line) requires a string.");
486 15170 : const int personCapacity = StoHelp::readTypedInt(inputStorage, "13th parameter (person capacity) requires an int.");
487 15184 : const int personNumber = StoHelp::readTypedInt(inputStorage, "14th parameter (person number) requires an int.");
488 15170 : libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed, arrivalLane, arrivalPos, arrivalSpeed,
489 : fromTaz, toTaz, line, personCapacity, personNumber);
490 : }
491 15156 : break;
492 : case libsumo::REMOVE: {
493 23 : libsumo::Vehicle::remove(id, (char)StoHelp::readTypedByte(inputStorage, "Removing a vehicle requires a byte."));
494 : }
495 23 : break;
496 : case libsumo::MOVE_TO_XY: {
497 3086 : const int parameterCount = StoHelp::readCompound(inputStorage, -1, "MoveToXY vehicle requires a compound object.");
498 3086 : if (parameterCount < 5 || parameterCount > 7) {
499 0 : 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 3086 : const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first parameter for moveToXY must be the edge ID given as a string.");
502 3086 : const int laneIndex = StoHelp::readTypedInt(inputStorage, "The second parameter for moveToXY must be lane given as an int.");
503 3086 : const double x = StoHelp::readTypedDouble(inputStorage, "The third parameter for moveToXY must be the x-position given as a double.");
504 3086 : const double y = StoHelp::readTypedDouble(inputStorage, "The fourth parameter for moveToXY must be the y-position given as a double.");
505 3086 : const double angle = StoHelp::readTypedDouble(inputStorage, "The fifth parameter for moveToXY must be the angle given as a double.");
506 : int keepRouteFlag = 1;
507 3086 : if (parameterCount >= 6) {
508 3050 : keepRouteFlag = StoHelp::readTypedByte(inputStorage, "The sixth parameter for moveToXY must be the keepRouteFlag given as a byte.");
509 : }
510 : double matchThreshold = 100.;
511 3050 : if (parameterCount == 7) {
512 6089 : matchThreshold = StoHelp::readTypedDouble(inputStorage, "The seventh parameter for moveToXY must be the matchThreshold given as a double.");
513 : }
514 3086 : libsumo::Vehicle::moveToXY(id, edgeID, laneIndex, x, y, angle, keepRouteFlag, matchThreshold);
515 : }
516 3081 : break;
517 : case libsumo::VAR_SPEED_FACTOR: {
518 4098 : libsumo::Vehicle::setSpeedFactor(id, StoHelp::readTypedDouble(inputStorage, "Setting speed factor requires a double."));
519 : }
520 4098 : break;
521 : case libsumo::VAR_LINE: {
522 9 : libsumo::Vehicle::setLine(id, StoHelp::readTypedString(inputStorage, "The line must be given as a string."));
523 : }
524 9 : break;
525 : case libsumo::VAR_VIA: {
526 11 : libsumo::Vehicle::setVia(id, StoHelp::readTypedStringList(inputStorage, "Vias must be defined as a list of edge ids."));
527 : }
528 11 : break;
529 : case libsumo::VAR_PARAMETER: {
530 343 : StoHelp::readCompound(inputStorage, 2, "A compound object of size 2 is needed for setting a parameter.");
531 343 : const std::string name = StoHelp::readTypedString(inputStorage, "The name of the parameter must be given as a string.");
532 351 : const std::string value = StoHelp::readTypedString(inputStorage, "The value of the parameter must be given as a string.");
533 343 : libsumo::Vehicle::setParameter(id, name, value);
534 : }
535 335 : break;
536 : case libsumo::VAR_HIGHLIGHT: {
537 26 : const int parameterCount = StoHelp::readCompound(inputStorage, -1, "A compound object is needed for highlighting an object.");
538 26 : if (parameterCount > 5) {
539 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Highlighting an object needs zero to five parameters.", outputStorage);
540 : }
541 :
542 : libsumo::TraCIColor col = libsumo::TraCIColor(255, 0, 0);
543 26 : if (parameterCount > 0) {
544 26 : col = StoHelp::readTypedColor(inputStorage, "The first parameter for highlighting must be the highlight color.");
545 : }
546 : double size = -1;
547 26 : if (parameterCount > 1) {
548 26 : size = StoHelp::readTypedDouble(inputStorage, "The second parameter for highlighting must be the highlight size.");
549 : }
550 : int alphaMax = -1;
551 26 : if (parameterCount > 2) {
552 14 : alphaMax = StoHelp::readTypedUnsignedByte(inputStorage, "The third parameter for highlighting must be maximal alpha.");
553 : }
554 : double duration = -1;
555 14 : if (parameterCount > 3) {
556 14 : duration = StoHelp::readTypedDouble(inputStorage, "The fourth parameter for highlighting must be the highlight duration.");
557 : }
558 : int type = 0;
559 14 : if (parameterCount > 4) {
560 141 : type = StoHelp::readTypedUnsignedByte(inputStorage, "The fifth parameter for highlighting must be the highlight type id as ubyte.");
561 : }
562 26 : libsumo::Vehicle::highlight(id, col, size, alphaMax, duration, type);
563 : }
564 26 : break;
565 : case libsumo::CMD_TAXI_DISPATCH: {
566 157 : libsumo::Vehicle::dispatchTaxi(id, StoHelp::readTypedStringList(inputStorage, "A dispatch command must be defined as a list of reservation ids."));
567 : }
568 142 : break;
569 : case libsumo::VAR_ACTIONSTEPLENGTH: {
570 11 : const double value = StoHelp::readTypedDouble(inputStorage, "Setting action step length requires a double.");
571 11 : if (fabs(value) == std::numeric_limits<double>::infinity()) {
572 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid action step length.", outputStorage);
573 : }
574 11 : bool resetActionOffset = value >= 0.0;
575 11 : libsumo::Vehicle::setActionStepLength(id, fabs(value), resetActionOffset);
576 : }
577 : break;
578 : case libsumo::VAR_LANEPOSITION_LAT: {
579 5 : libsumo::Vehicle::setLateralLanePosition(id, StoHelp::readTypedDouble(inputStorage, "Setting lateral lane position requires a double."));
580 : }
581 5 : break;
582 167 : case libsumo::VAR_UPDATE_BESTLANES: {
583 167 : libsumo::Vehicle::updateBestLanes(id);
584 : }
585 : break;
586 : case libsumo::VAR_MINGAP: {
587 9 : const double value = StoHelp::readTypedDouble(inputStorage, "Setting minimum gap requires a double.");
588 9 : if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
589 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum gap.", outputStorage);
590 : }
591 9 : libsumo::Vehicle::setMinGap(id, value);
592 : }
593 : break;
594 : case libsumo::VAR_MINGAP_LAT: {
595 5 : const double value = StoHelp::readTypedDouble(inputStorage, "Setting minimum lateral gap requires a double.");
596 5 : if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
597 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum lateral gap.", outputStorage);
598 : }
599 5 : libsumo::Vehicle::setMinGapLat(id, value);
600 : }
601 : break;
602 229 : default: {
603 : try {
604 229 : if (!TraCIServerAPI_VehicleType::setVariable(libsumo::CMD_SET_VEHICLE_VARIABLE, variable, v->getSingularType().getID(), server, inputStorage, outputStorage)) {
605 : return false;
606 : }
607 0 : } catch (ProcessError& e) {
608 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
609 0 : } catch (libsumo::TraCIException& e) {
610 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
611 0 : }
612 : }
613 : break;
614 : }
615 113 : } catch (libsumo::TraCIException& e) {
616 113 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
617 113 : }
618 100193 : server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);
619 : return true;
620 : }
621 :
622 :
623 : bool
624 199 : TraCIServerAPI_Vehicle::insertReplaceStop(TraCIServer& server, tcpip::Storage& inputStorage, tcpip::Storage& outputStorage, const std::string& id, bool replace) {
625 282 : const std::string m1 = replace ? "Replacing" : "Inserting";
626 307 : const std::string m2 = replace ? "replacement" : "insertion";
627 199 : const int parameterCount = StoHelp::readCompound(inputStorage, -1, m1 + " stop needs a compound object description.");
628 199 : if (parameterCount != 8 && parameterCount != 9) {
629 0 : 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 423 : const std::string edgeID = StoHelp::readTypedString(inputStorage, "The first stop " + m2 + " parameter must be the edge id given as a string.");
633 398 : const double pos = StoHelp::readTypedDouble(inputStorage, "The second stop " + m2 + " parameter must be the end position along the edge given as a double.");
634 398 : const int laneIndex = StoHelp::readTypedByte(inputStorage, "The third stop " + m2 + " parameter must be the lane index given as a byte.");
635 398 : const double duration = StoHelp::readTypedDouble(inputStorage, "The fourth stop " + m2 + " parameter must be the stopping duration given as a double.");
636 398 : const int stopFlags = StoHelp::readTypedInt(inputStorage, "The fifth stop " + m2 + " parameter must be an int indicating its parking/triggered status.");
637 398 : const double startPos = StoHelp::readTypedDouble(inputStorage, "The sixth stop " + m2 + " parameter must be the start position along the edge given as a double.");
638 398 : const double until = StoHelp::readTypedDouble(inputStorage, "The seventh stop " + m2 + " parameter must be the minimum departure time given as a double.");
639 398 : 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 199 : if (parameterCount == 9) {
642 622 : teleport = StoHelp::readTypedByte(inputStorage, "The ninth stop " + m2 + " parameter must be the teleport flag given as a byte.");
643 : }
644 199 : if (replace) {
645 116 : libsumo::Vehicle::replaceStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
646 : } else {
647 83 : libsumo::Vehicle::insertStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
648 : }
649 : return true;
650 : }
651 :
652 :
653 : /****************************************************************************/
|