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 9355615 : TraCIServerAPI_Vehicle::processGet(TraCIServer& server, tcpip::Storage& inputStorage,
60 : tcpip::Storage& outputStorage) {
61 9355615 : const int variable = inputStorage.readUnsignedByte();
62 9355615 : const std::string id = inputStorage.readString();
63 9355615 : server.initWrapper(libsumo::RESPONSE_GET_VEHICLE_VARIABLE, variable, id);
64 : try {
65 9355615 : if (!libsumo::Vehicle::handleVariable(id, variable, &server, &inputStorage)) {
66 18 : return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Get Vehicle Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
67 : }
68 109 : } catch (libsumo::TraCIException& e) {
69 109 : return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, e.what(), outputStorage);
70 109 : }
71 9355500 : server.writeStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, libsumo::RTYPE_OK, "", outputStorage);
72 9355500 : server.writeResponseWithLength(outputStorage, server.getWrapperStorage());
73 : return true;
74 : }
75 :
76 :
77 : bool
78 101129 : TraCIServerAPI_Vehicle::processSet(TraCIServer& server, tcpip::Storage& inputStorage,
79 : tcpip::Storage& outputStorage) {
80 101129 : std::string warning = ""; // additional description for response
81 : // variable
82 101129 : int variable = inputStorage.readUnsignedByte();
83 101129 : if (variable != libsumo::CMD_STOP && variable != libsumo::CMD_CHANGELANE
84 101129 : && variable != libsumo::CMD_REROUTE_TO_PARKING
85 51109 : && variable != libsumo::CMD_CHANGESUBLANE && variable != libsumo::CMD_OPENGAP
86 : && variable != libsumo::CMD_REPLACE_STOP
87 50887 : && variable != libsumo::CMD_INSERT_STOP
88 50688 : && variable != libsumo::VAR_STOP_PARAMETER
89 50688 : && variable != libsumo::CMD_SLOWDOWN && variable != libsumo::CMD_CHANGETARGET && variable != libsumo::CMD_RESUME
90 28497 : && variable != libsumo::VAR_TYPE && variable != libsumo::VAR_ROUTE_ID && variable != libsumo::VAR_ROUTE
91 28324 : && variable != libsumo::VAR_LANEPOSITION_LAT
92 28292 : && variable != libsumo::VAR_UPDATE_BESTLANES
93 28292 : && variable != libsumo::VAR_EDGE_TRAVELTIME && variable != libsumo::VAR_EDGE_EFFORT
94 27997 : && variable != libsumo::CMD_REROUTE_TRAVELTIME && variable != libsumo::CMD_REROUTE_EFFORT
95 27757 : && variable != libsumo::VAR_SIGNALS && variable != libsumo::VAR_MOVE_TO
96 27735 : && variable != libsumo::VAR_LENGTH && variable != libsumo::VAR_MAXSPEED && variable != libsumo::VAR_VEHICLECLASS
97 27327 : && variable != libsumo::VAR_SPEED_FACTOR && variable != libsumo::VAR_EMISSIONCLASS
98 23213 : && variable != libsumo::VAR_WIDTH && variable != libsumo::VAR_MINGAP && variable != libsumo::VAR_SHAPECLASS
99 23195 : && variable != libsumo::VAR_ACCEL && variable != libsumo::VAR_DECEL && variable != libsumo::VAR_IMPERFECTION
100 23149 : && variable != libsumo::VAR_APPARENT_DECEL && variable != libsumo::VAR_EMERGENCY_DECEL
101 23128 : && variable != libsumo::VAR_ACTIONSTEPLENGTH
102 23128 : && variable != libsumo::VAR_TAU && variable != libsumo::VAR_LANECHANGE_MODE
103 23108 : && variable != libsumo::VAR_SPEED && variable != libsumo::VAR_ACCELERATION && variable != libsumo::VAR_PREV_SPEED && variable != libsumo::VAR_SPEEDSETMODE && variable != libsumo::VAR_COLOR
104 19050 : && variable != libsumo::ADD && variable != libsumo::ADD_FULL && variable != libsumo::REMOVE
105 3870 : && variable != libsumo::VAR_HEIGHT
106 3842 : && variable != libsumo::VAR_MASS
107 3842 : && variable != libsumo::VAR_ROUTING_MODE
108 : && variable != libsumo::VAR_LATALIGNMENT
109 3658 : && variable != libsumo::VAR_MAXSPEED_LAT
110 3648 : && variable != libsumo::VAR_MINGAP_LAT
111 3648 : && variable != libsumo::VAR_LINE
112 3634 : && variable != libsumo::VAR_VIA
113 3634 : && variable != libsumo::VAR_IMPATIENCE
114 3608 : && variable != libsumo::VAR_BOARDING_DURATION
115 3608 : && variable != libsumo::VAR_HIGHLIGHT
116 3577 : && variable != libsumo::CMD_TAXI_DISPATCH
117 3577 : && variable != libsumo::MOVE_TO_XY && variable != libsumo::VAR_PARAMETER/* && variable != libsumo::VAR_SPEED_TIME_LINE && variable != libsumo::VAR_LANE_TIME_LINE*/
118 : ) {
119 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Change Vehicle State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
120 : }
121 : // id
122 101129 : std::string id = inputStorage.readString();
123 : #ifdef DEBUG_MOVEXY
124 : std::cout << SIMTIME << " processSet veh=" << id << "\n";
125 : #endif
126 101129 : const bool shouldExist = variable != libsumo::ADD && variable != libsumo::ADD_FULL;
127 101129 : SUMOVehicle* sumoVehicle = MSNet::getInstance()->getVehicleControl().getVehicle(id);
128 101129 : if (sumoVehicle == nullptr) {
129 15190 : if (shouldExist) {
130 33 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
131 : }
132 : }
133 85939 : MSBaseVehicle* v = dynamic_cast<MSBaseVehicle*>(sumoVehicle);
134 101118 : if (v == nullptr && shouldExist) {
135 0 : return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a proper vehicle", outputStorage);
136 : }
137 : try {
138 101118 : switch (variable) {
139 45360 : case libsumo::CMD_STOP: {
140 45360 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
141 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description.", outputStorage);
142 : }
143 45360 : int compoundSize = inputStorage.readInt();
144 45360 : if (compoundSize < 4 || compoundSize > 7) {
145 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description of four to seven items.", outputStorage);
146 : }
147 : // read road map position
148 : std::string edgeID;
149 45360 : if (!server.readTypeCheckingString(inputStorage, edgeID)) {
150 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first stop parameter must be the edge id given as a string.", outputStorage);
151 : }
152 45360 : double pos = 0;
153 45360 : if (!server.readTypeCheckingDouble(inputStorage, pos)) {
154 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second stop parameter must be the end position along the edge given as a double.", outputStorage);
155 : }
156 45360 : int laneIndex = 0;
157 45360 : if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
158 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third stop parameter must be the lane index given as a byte.", outputStorage);
159 : }
160 : // waitTime
161 45360 : double duration = libsumo::INVALID_DOUBLE_VALUE;
162 45360 : if (!server.readTypeCheckingDouble(inputStorage, duration)) {
163 0 : return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "The fourth stop parameter must be the stopping duration given as a double.", outputStorage);
164 : }
165 45360 : int stopFlags = 0;
166 45360 : if (compoundSize >= 5) {
167 45359 : if (!server.readTypeCheckingByte(inputStorage, stopFlags)) {
168 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth stop parameter must be a byte indicating its parking/triggered status.", outputStorage);
169 : }
170 : }
171 1 : double startPos = libsumo::INVALID_DOUBLE_VALUE;
172 45359 : if (compoundSize >= 6) {
173 45358 : if (!server.readTypeCheckingDouble(inputStorage, startPos)) {
174 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The sixth stop parameter must be the start position along the edge given as a double.", outputStorage);
175 : }
176 : }
177 2 : double until = libsumo::INVALID_DOUBLE_VALUE;
178 45358 : if (compoundSize >= 7) {
179 45358 : if (!server.readTypeCheckingDouble(inputStorage, until)) {
180 9 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The seventh stop parameter must be the minimum departure time given as a double.", outputStorage);
181 : }
182 : }
183 45360 : libsumo::Vehicle::setStop(id, edgeID, pos, laneIndex, duration, stopFlags, startPos, until);
184 : }
185 : break;
186 116 : case libsumo::CMD_REPLACE_STOP:
187 116 : if (!insertReplaceStop(server, inputStorage, outputStorage, id, true)) {
188 : return false;
189 : }
190 : break;
191 83 : case libsumo::CMD_INSERT_STOP:
192 83 : if (!insertReplaceStop(server, inputStorage, outputStorage, id, false)) {
193 : return false;
194 : }
195 : break;
196 103 : case libsumo::VAR_STOP_PARAMETER: {
197 : // read variables
198 103 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
199 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting stop parameter needs a compound object description.", outputStorage);
200 : }
201 103 : int compoundSize = inputStorage.readInt();
202 103 : if (compoundSize != 3 && compoundSize != 4) {
203 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting a stop parameter needs a compound object description of 3 or 4 items.", outputStorage);
204 : }
205 206 : const int nextStopIndex = StoHelp::readTypedInt(inputStorage, "The first setStopParameter parameter must be the nextStopIndex given as an integer.");
206 : std::string param;
207 103 : if (!server.readTypeCheckingString(inputStorage, param)) {
208 3 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second setStopParameter parameter must be the param given as a string.", outputStorage);
209 : }
210 : std::string value;
211 103 : if (!server.readTypeCheckingString(inputStorage, value)) {
212 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third setStopParameter parameter must be the value given as a string.", outputStorage);
213 : }
214 103 : int customParam = 0;
215 103 : if (compoundSize == 4) {
216 103 : if (!server.readTypeCheckingByte(inputStorage, customParam)) {
217 3 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth setStopParameter parameter must be the customParam flag given as a byte.", outputStorage);
218 : }
219 : }
220 103 : libsumo::Vehicle::setStopParameter(id, nextStopIndex, param, value, customParam != 0);
221 : }
222 : break;
223 9 : case libsumo::CMD_REROUTE_TO_PARKING: {
224 : // read variables
225 9 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
226 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Reroute to stop needs a compound object description.", outputStorage);
227 : }
228 9 : int compoundSize = inputStorage.readInt();
229 9 : if (compoundSize != 1) {
230 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Reroute to stop needs a compound object description of 1 item.", outputStorage);
231 : }
232 : std::string parkingAreaID;
233 9 : if (!server.readTypeCheckingString(inputStorage, parkingAreaID)) {
234 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first reroute to stop parameter must be the parking area id given as a string.", outputStorage);
235 : }
236 9 : libsumo::Vehicle::rerouteParkingArea(id, parkingAreaID);
237 : }
238 : break;
239 6 : case libsumo::CMD_RESUME: {
240 6 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
241 0 : server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_ERR, "Resuming requires a compound object.", outputStorage);
242 0 : return false;
243 : }
244 6 : if (inputStorage.readInt() != 0) {
245 0 : server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_ERR, "Resuming should obtain an empty compound object.", outputStorage);
246 0 : return false;
247 : }
248 6 : libsumo::Vehicle::resume(id);
249 : }
250 : break;
251 4649 : case libsumo::CMD_CHANGELANE: {
252 4649 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
253 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description.", outputStorage);
254 : }
255 4649 : int compounds = inputStorage.readInt();
256 4649 : if (compounds != 3 && compounds != 2) {
257 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two or three items.", outputStorage);
258 : }
259 : // Lane ID
260 4649 : int laneIndex = 0;
261 4649 : if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
262 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first lane change parameter must be the lane index given as a byte.", outputStorage);
263 : }
264 : // duration
265 4649 : double duration = 0.;
266 4649 : if (!server.readTypeCheckingDouble(inputStorage, duration)) {
267 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second lane change parameter must be the duration given as a double.", outputStorage);
268 : }
269 : // relativelanechange
270 4649 : int relative = 0;
271 4649 : if (compounds == 3) {
272 169 : if (!server.readTypeCheckingByte(inputStorage, relative)) {
273 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third lane change parameter must be a Byte for defining whether a relative lane change should be applied.", outputStorage);
274 : }
275 : }
276 :
277 4649 : if ((laneIndex < 0 || laneIndex >= (int)v->getEdge()->getLanes().size()) && relative < 1) {
278 3 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + v->getEdge()->getID() + "'.", outputStorage);
279 : }
280 :
281 4648 : if (relative < 1) {
282 4485 : libsumo::Vehicle::changeLane(id, laneIndex, duration);
283 : } else {
284 163 : libsumo::Vehicle::changeLaneRelative(id, laneIndex, duration);
285 : }
286 : }
287 4648 : break;
288 187 : case libsumo::CMD_CHANGESUBLANE: {
289 187 : double latDist = 0;
290 187 : if (!server.readTypeCheckingDouble(inputStorage, latDist)) {
291 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Sublane-changing requires a double.", outputStorage);
292 : }
293 187 : libsumo::Vehicle::changeSublane(id, latDist);
294 : }
295 187 : break;
296 41 : case libsumo::CMD_SLOWDOWN: {
297 41 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
298 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description.", outputStorage);
299 : }
300 41 : if (inputStorage.readInt() != 2) {
301 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description of two items.", outputStorage);
302 : }
303 41 : double newSpeed = 0;
304 41 : if (!server.readTypeCheckingDouble(inputStorage, newSpeed)) {
305 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first slow down parameter must be the speed given as a double.", outputStorage);
306 : }
307 41 : if (newSpeed < 0) {
308 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Speed must not be negative", outputStorage);
309 : }
310 41 : double duration = 0.;
311 41 : if (!server.readTypeCheckingDouble(inputStorage, duration)) {
312 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second slow down parameter must be the duration given as a double.", outputStorage);
313 : }
314 41 : if (duration < 0 || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
315 2 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval", outputStorage);
316 : }
317 40 : libsumo::Vehicle::slowDown(id, newSpeed, duration);
318 : }
319 40 : break;
320 : case libsumo::CMD_CHANGETARGET: {
321 : std::string edgeID;
322 22039 : if (!server.readTypeCheckingString(inputStorage, edgeID)) {
323 7 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Change target requires a string containing the id of the new destination edge as parameter.", outputStorage);
324 : }
325 22039 : libsumo::Vehicle::changeTarget(id, edgeID);
326 : }
327 : break;
328 35 : case libsumo::CMD_OPENGAP: {
329 35 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
330 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Create gap needs a compound object description.", outputStorage);
331 : }
332 35 : const int nParameter = inputStorage.readInt();
333 35 : if (nParameter != 5 && nParameter != 6) {
334 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Create gap needs a compound object description of five or six items.", outputStorage);
335 : }
336 35 : double newTimeHeadway = 0;
337 35 : if (!server.readTypeCheckingDouble(inputStorage, newTimeHeadway)) {
338 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first create gap parameter must be the new desired time headway (tau) given as a double.", outputStorage);
339 : }
340 35 : double newSpaceHeadway = 0;
341 35 : if (!server.readTypeCheckingDouble(inputStorage, newSpaceHeadway)) {
342 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second create gap parameter must be the new desired space headway given as a double.", outputStorage);
343 : }
344 35 : double duration = 0.;
345 35 : if (!server.readTypeCheckingDouble(inputStorage, duration)) {
346 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third create gap parameter must be the duration given as a double.", outputStorage);
347 : }
348 35 : double changeRate = 0;
349 35 : if (!server.readTypeCheckingDouble(inputStorage, changeRate)) {
350 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth create gap parameter must be the change rate given as a double.", outputStorage);
351 : }
352 35 : double maxDecel = 0;
353 35 : if (!server.readTypeCheckingDouble(inputStorage, maxDecel)) {
354 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth create gap parameter must be the maximal braking rate given as a double.", outputStorage);
355 : }
356 :
357 35 : if (newTimeHeadway == -1 && newSpaceHeadway == -1 && duration == -1 && changeRate == -1 && maxDecel == -1) {
358 4 : libsumo::Vehicle::deactivateGapControl(id);
359 : } else {
360 31 : if (newTimeHeadway <= 0) {
361 4 : if (newTimeHeadway != -1) {
362 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);
363 : } // else if == -1: keep vehicles current headway, see libsumo::Vehicle::openGap
364 : }
365 31 : if (newSpaceHeadway < 0) {
366 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);
367 : }
368 31 : if ((duration < 0 && duration != -1) || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
369 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval for create gap", outputStorage);
370 : }
371 31 : if (changeRate <= 0) {
372 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the change rate must be positive for the openGap command", outputStorage);
373 : }
374 31 : if (maxDecel <= 0 && maxDecel != -1 && maxDecel != libsumo::INVALID_DOUBLE_VALUE) {
375 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the maximal braking rate must be positive for the openGap command", outputStorage);
376 : } // else if <= 0: don't limit cf model's suggested brake rate, see libsumo::Vehicle::openGap
377 31 : std::string refVehID = "";
378 31 : if (nParameter == 6) {
379 7 : if (!server.readTypeCheckingString(inputStorage, refVehID)) {
380 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The sixth create gap parameter must be a reference vehicle's ID given as a string.", outputStorage);
381 : }
382 : }
383 31 : libsumo::Vehicle::openGap(id, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel, refVehID);
384 : }
385 : }
386 35 : break;
387 : case libsumo::VAR_TYPE: {
388 : std::string vTypeID;
389 154 : if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
390 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The vehicle type id must be given as a string.", outputStorage);
391 : }
392 154 : libsumo::Vehicle::setType(id, vTypeID);
393 : }
394 : break;
395 : case libsumo::VAR_ROUTE_ID: {
396 : std::string rid;
397 18 : if (!server.readTypeCheckingString(inputStorage, rid)) {
398 3 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The route id must be given as a string.", outputStorage);
399 : }
400 18 : libsumo::Vehicle::setRouteID(id, rid);
401 : }
402 : break;
403 : case libsumo::VAR_ROUTE: {
404 : std::vector<std::string> edgeIDs;
405 26 : if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {
406 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A route must be defined as a list of edge ids.", outputStorage);
407 : }
408 26 : libsumo::Vehicle::setRoute(id, edgeIDs);
409 26 : }
410 : break;
411 118 : case libsumo::VAR_EDGE_TRAVELTIME: {
412 118 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
413 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires a compound object.", outputStorage);
414 : }
415 118 : int parameterCount = inputStorage.readInt();
416 : std::string edgeID;
417 118 : double begTime = 0.;
418 118 : double endTime = std::numeric_limits<double>::max();
419 118 : double value = libsumo::INVALID_DOUBLE_VALUE;
420 118 : if (parameterCount == 4) {
421 : // begin time
422 50 : if (!server.readTypeCheckingDouble(inputStorage, begTime)) {
423 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the begin time as first parameter.", outputStorage);
424 : }
425 : // begin time
426 50 : if (!server.readTypeCheckingDouble(inputStorage, endTime)) {
427 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the end time as second parameter.", outputStorage);
428 : }
429 : // edge
430 50 : if (!server.readTypeCheckingString(inputStorage, edgeID)) {
431 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the referenced edge as third parameter.", outputStorage);
432 : }
433 : // value
434 50 : if (!server.readTypeCheckingDouble(inputStorage, value)) {
435 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the travel time as double as fourth parameter.", outputStorage);
436 : }
437 68 : } else if (parameterCount == 2) {
438 : // edge
439 63 : if (!server.readTypeCheckingString(inputStorage, edgeID)) {
440 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the referenced edge as first parameter.", outputStorage);
441 : }
442 : // value
443 63 : if (!server.readTypeCheckingDouble(inputStorage, value)) {
444 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the travel time as second parameter.", outputStorage);
445 : }
446 5 : } else if (parameterCount == 1) {
447 : // edge
448 5 : if (!server.readTypeCheckingString(inputStorage, edgeID)) {
449 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 1 parameter requires the referenced edge as first parameter.", outputStorage);
450 : }
451 : } else {
452 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);
453 : }
454 118 : libsumo::Vehicle::setAdaptedTraveltime(id, edgeID, value, begTime, endTime);
455 : }
456 : break;
457 20 : case libsumo::VAR_EDGE_EFFORT: {
458 20 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
459 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort requires a compound object.", outputStorage);
460 : }
461 20 : int parameterCount = inputStorage.readInt();
462 : std::string edgeID;
463 20 : double begTime = 0.;
464 20 : double endTime = std::numeric_limits<double>::max();
465 20 : double value = libsumo::INVALID_DOUBLE_VALUE;
466 20 : if (parameterCount == 4) {
467 : // begin time
468 12 : if (!server.readTypeCheckingDouble(inputStorage, begTime)) {
469 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the begin time as first parameter.", outputStorage);
470 : }
471 : // begin time
472 12 : if (!server.readTypeCheckingDouble(inputStorage, endTime)) {
473 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the end time as second parameter.", outputStorage);
474 : }
475 : // edge
476 12 : if (!server.readTypeCheckingString(inputStorage, edgeID)) {
477 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the referenced edge as third parameter.", outputStorage);
478 : }
479 : // value
480 12 : if (!server.readTypeCheckingDouble(inputStorage, value)) {
481 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the travel time as fourth parameter.", outputStorage);
482 : }
483 8 : } else if (parameterCount == 2) {
484 : // edge
485 3 : if (!server.readTypeCheckingString(inputStorage, edgeID)) {
486 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the referenced edge as first parameter.", outputStorage);
487 : }
488 3 : if (!server.readTypeCheckingDouble(inputStorage, value)) {
489 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the travel time as second parameter.", outputStorage);
490 : }
491 5 : } else if (parameterCount == 1) {
492 : // edge
493 5 : if (!server.readTypeCheckingString(inputStorage, edgeID)) {
494 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 1 parameter requires the referenced edge as first parameter.", outputStorage);
495 : }
496 : } else {
497 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);
498 : }
499 : // retrieve
500 20 : libsumo::Vehicle::setEffort(id, edgeID, value, begTime, endTime);
501 : }
502 : break;
503 219 : case libsumo::CMD_REROUTE_TRAVELTIME: {
504 219 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
505 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
506 : }
507 219 : if (inputStorage.readInt() != 0) {
508 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
509 : }
510 219 : libsumo::Vehicle::rerouteTraveltime(id, false);
511 : }
512 : break;
513 7 : case libsumo::CMD_REROUTE_EFFORT: {
514 7 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
515 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
516 : }
517 7 : if (inputStorage.readInt() != 0) {
518 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
519 : }
520 7 : libsumo::Vehicle::rerouteEffort(id);
521 : }
522 : break;
523 : case libsumo::VAR_SIGNALS:
524 14 : libsumo::Vehicle::setSignals(id, StoHelp::readTypedInt(inputStorage, "Setting signals requires an integer."));
525 14 : break;
526 304 : case libsumo::VAR_MOVE_TO: {
527 304 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
528 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting position requires a compound object.", outputStorage);
529 : }
530 304 : const int numArgs = inputStorage.readInt();
531 304 : if (numArgs < 2 || numArgs > 3) {
532 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting position should obtain the lane id and the position and optionally the reason.", outputStorage);
533 : }
534 : // lane ID
535 : std::string laneID;
536 304 : if (!server.readTypeCheckingString(inputStorage, laneID)) {
537 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first parameter for setting a position must be the lane ID given as a string.", outputStorage);
538 : }
539 : // position on lane
540 304 : double position = 0;
541 304 : if (!server.readTypeCheckingDouble(inputStorage, position)) {
542 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second parameter for setting a position must be the position given as a double.", outputStorage);
543 : }
544 : int reason = libsumo::MOVE_AUTOMATIC;
545 304 : if (numArgs == 3) {
546 609 : reason = StoHelp::readTypedInt(inputStorage, "The third parameter for setting a position must be the reason given as an int.");
547 : }
548 : // process
549 304 : libsumo::Vehicle::moveTo(id, laneID, position, reason);
550 : }
551 : break;
552 15 : case libsumo::VAR_IMPATIENCE: {
553 15 : double impatience = 0;
554 15 : if (!server.readTypeCheckingDouble(inputStorage, impatience)) {
555 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting impatience requires a double.", outputStorage);
556 : }
557 15 : libsumo::Vehicle::setImpatience(id, impatience);
558 : }
559 15 : break;
560 1990 : case libsumo::VAR_SPEED: {
561 1990 : double speed = 0;
562 1990 : if (!server.readTypeCheckingDouble(inputStorage, speed)) {
563 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting speed requires a double.", outputStorage);
564 : }
565 1990 : libsumo::Vehicle::setSpeed(id, speed);
566 : }
567 1990 : break;
568 9 : case libsumo::VAR_ACCELERATION: {
569 9 : double accel = 0;
570 9 : double duration = 0;
571 9 : int inputtype = inputStorage.readUnsignedByte();
572 9 : if (inputtype == libsumo::TYPE_COMPOUND) {
573 9 : int parameterCount = inputStorage.readInt();
574 9 : if (parameterCount == 2) {
575 9 : if (!server.readTypeCheckingDouble(inputStorage, accel)) {
576 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires the acceleration as first parameter given as a double.", outputStorage);
577 : }
578 9 : if (!server.readTypeCheckingDouble(inputStorage, duration)) {
579 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires the duration as second parameter given as a double.", outputStorage);
580 : }
581 : } else {
582 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires 2 parameters.", outputStorage);
583 : }
584 : } else {
585 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires 2 parameters as compound object description.", outputStorage);
586 : }
587 9 : if (duration < 0) {
588 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Duration must not be negative.", outputStorage);
589 : }
590 9 : libsumo::Vehicle::setAcceleration(id, accel, duration);
591 : }
592 9 : break;
593 145 : case libsumo::VAR_PREV_SPEED: {
594 145 : double prevSpeed = 0;
595 145 : double prevAcceleration = libsumo::INVALID_DOUBLE_VALUE;
596 145 : int inputtype = inputStorage.readUnsignedByte();
597 145 : if (inputtype == libsumo::TYPE_COMPOUND) {
598 : // Setting previous speed with 2 parameters, uses a compound object description
599 145 : int parameterCount = inputStorage.readInt();
600 145 : if (parameterCount == 2) {
601 145 : if (!server.readTypeCheckingDouble(inputStorage, prevSpeed)) {
602 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed using 2 parameters requires the previous speed as first parameter given as a double.", outputStorage);
603 : }
604 145 : if (!server.readTypeCheckingDouble(inputStorage, prevAcceleration)) {
605 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed using 2 parameters requires the previous acceleration as second parameter given as a double.", outputStorage);
606 : }
607 0 : } else if (parameterCount == 1) {
608 0 : if (!server.readTypeCheckingDouble(inputStorage, prevSpeed)) {
609 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed using 1 parameter requires the previous speed as first parameter given as a double.", outputStorage);
610 : }
611 : } else {
612 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed requires 1 or 2 parameters.", outputStorage);
613 : }
614 0 : } else if (inputtype == libsumo::TYPE_DOUBLE) {
615 : // Setting previous speed with 1 parameter (double), no compound object description
616 0 : prevSpeed = inputStorage.readDouble();
617 : } else {
618 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);
619 : }
620 145 : if (prevSpeed < 0) {
621 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Previous speed must not be negative.", outputStorage);
622 : }
623 145 : libsumo::Vehicle::setPreviousSpeed(id, prevSpeed, prevAcceleration);
624 : }
625 145 : break;
626 : case libsumo::VAR_SPEEDSETMODE:
627 1545 : libsumo::Vehicle::setSpeedMode(id, StoHelp::readTypedInt(inputStorage, "Setting speed mode requires an integer."));
628 1545 : break;
629 : case libsumo::VAR_LANECHANGE_MODE:
630 277 : libsumo::Vehicle::setLaneChangeMode(id, StoHelp::readTypedInt(inputStorage, "Setting lane change mode requires an integer."));
631 277 : break;
632 : case libsumo::VAR_ROUTING_MODE:
633 179 : libsumo::Vehicle::setRoutingMode(id, StoHelp::readTypedInt(inputStorage, "Setting routing mode requires an integer."));
634 179 : break;
635 : case libsumo::VAR_COLOR: {
636 : libsumo::TraCIColor col;
637 91 : if (!server.readTypeCheckingColor(inputStorage, col)) {
638 104 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The color must be given using the according type.", outputStorage);
639 : }
640 91 : libsumo::Vehicle::setColor(id, col);
641 : break;
642 : }
643 9 : case libsumo::ADD: {
644 9 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
645 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle requires a compound object.", outputStorage);
646 : }
647 9 : if (inputStorage.readInt() != 6) {
648 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle needs six parameters.", outputStorage);
649 : }
650 : std::string vTypeID;
651 9 : if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
652 5 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "First parameter (type) requires a string.", outputStorage);
653 : }
654 : std::string routeID;
655 9 : if (!server.readTypeCheckingString(inputStorage, routeID)) {
656 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Second parameter (route) requires a string.", outputStorage);
657 : }
658 9 : const int departCode = StoHelp::readTypedInt(inputStorage, "Third parameter (depart) requires an integer.");
659 14 : std::string depart = toString(STEPS2TIME(departCode));
660 : if (-departCode == static_cast<int>(DepartDefinition::TRIGGERED)) {
661 : depart = "triggered";
662 : } else if (-departCode == static_cast<int>(DepartDefinition::CONTAINER_TRIGGERED)) {
663 : depart = "containerTriggered";
664 : } else if (-departCode == static_cast<int>(DepartDefinition::NOW)) {
665 : depart = "now";
666 : } else if (-departCode == static_cast<int>(DepartDefinition::SPLIT)) {
667 : depart = "split";
668 : } else if (-departCode == static_cast<int>(DepartDefinition::BEGIN)) {
669 : depart = "begin";
670 : }
671 :
672 : double departPosCode;
673 9 : if (!server.readTypeCheckingDouble(inputStorage, departPosCode)) {
674 5 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fourth parameter (position) requires a double.", outputStorage);
675 : }
676 9 : std::string departPos = toString(departPosCode);
677 9 : if (-departPosCode == (int)DepartPosDefinition::RANDOM) {
678 : departPos = "random";
679 9 : } else if (-departPosCode == (int)DepartPosDefinition::RANDOM_FREE) {
680 : departPos = "random_free";
681 9 : } else if (-departPosCode == (int)DepartPosDefinition::FREE) {
682 : departPos = "free";
683 9 : } else if (-departPosCode == (int)DepartPosDefinition::BASE) {
684 : departPos = "base";
685 9 : } else if (-departPosCode == (int)DepartPosDefinition::LAST) {
686 : departPos = "last";
687 9 : } else if (-departPosCode == (int)DepartPosDefinition::GIVEN) {
688 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid departure position.", outputStorage);
689 : }
690 :
691 : double departSpeedCode;
692 9 : if (!server.readTypeCheckingDouble(inputStorage, departSpeedCode)) {
693 5 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fifth parameter (speed) requires a double.", outputStorage);
694 : }
695 9 : std::string departSpeed = toString(departSpeedCode);
696 9 : if (-departSpeedCode == (int)DepartSpeedDefinition::RANDOM) {
697 : departSpeed = "random";
698 9 : } else if (-departSpeedCode == (int)DepartSpeedDefinition::MAX) {
699 : departSpeed = "max";
700 9 : } else if (-departSpeedCode == (int)DepartSpeedDefinition::DESIRED) {
701 : departSpeed = "desired";
702 9 : } else if (-departSpeedCode == (int)DepartSpeedDefinition::LIMIT) {
703 : departSpeed = "speedLimit";
704 9 : } else if (-departSpeedCode == (int)DepartSpeedDefinition::LAST) {
705 : departSpeed = "last";
706 9 : } else if (-departSpeedCode == (int)DepartSpeedDefinition::AVG) {
707 : departSpeed = "avg";
708 : }
709 :
710 : int departLaneCode;
711 9 : if (!server.readTypeCheckingByte(inputStorage, departLaneCode)) {
712 5 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Sixth parameter (lane) requires a byte.", outputStorage);
713 : }
714 9 : std::string departLane = toString(departLaneCode);
715 9 : if (-departLaneCode == (int)DepartLaneDefinition::RANDOM) {
716 : departLane = "random";
717 : } else if (-departLaneCode == (int)DepartLaneDefinition::FREE) {
718 : departLane = "free";
719 : } else if (-departLaneCode == (int)DepartLaneDefinition::ALLOWED_FREE) {
720 : departLane = "allowed";
721 : } else if (-departLaneCode == (int)DepartLaneDefinition::BEST_FREE) {
722 : departLane = "best";
723 : } else if (-departLaneCode == (int)DepartLaneDefinition::FIRST_ALLOWED) {
724 : departLane = "first";
725 : }
726 43 : libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed);
727 : }
728 : break;
729 15171 : case libsumo::ADD_FULL: {
730 15171 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
731 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle requires a compound object.", outputStorage);
732 : }
733 15171 : if (inputStorage.readInt() != 14) {
734 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a fully specified vehicle needs fourteen parameters.", outputStorage);
735 : }
736 : std::string routeID;
737 15171 : if (!server.readTypeCheckingString(inputStorage, routeID)) {
738 14 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Second parameter (route) requires a string.", outputStorage);
739 : }
740 : std::string vTypeID;
741 15171 : if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
742 14 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "First parameter (type) requires a string.", outputStorage);
743 : }
744 : std::string depart;
745 15171 : if (!server.readTypeCheckingString(inputStorage, depart)) {
746 14 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Third parameter (depart) requires an string.", outputStorage);
747 : }
748 : std::string departLane;
749 15171 : if (!server.readTypeCheckingString(inputStorage, departLane)) {
750 14 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fourth parameter (depart lane) requires a string.", outputStorage);
751 : }
752 : std::string departPos;
753 15171 : if (!server.readTypeCheckingString(inputStorage, departPos)) {
754 14 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fifth parameter (depart position) requires a string.", outputStorage);
755 : }
756 : std::string departSpeed;
757 15171 : if (!server.readTypeCheckingString(inputStorage, departSpeed)) {
758 14 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Sixth parameter (depart speed) requires a string.", outputStorage);
759 : }
760 : std::string arrivalLane;
761 15171 : if (!server.readTypeCheckingString(inputStorage, arrivalLane)) {
762 14 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Seventh parameter (arrival lane) requires a string.", outputStorage);
763 : }
764 : std::string arrivalPos;
765 15171 : if (!server.readTypeCheckingString(inputStorage, arrivalPos)) {
766 14 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Eighth parameter (arrival position) requires a string.", outputStorage);
767 : }
768 : std::string arrivalSpeed;
769 15171 : if (!server.readTypeCheckingString(inputStorage, arrivalSpeed)) {
770 14 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Ninth parameter (arrival speed) requires a string.", outputStorage);
771 : }
772 : std::string fromTaz;
773 15171 : if (!server.readTypeCheckingString(inputStorage, fromTaz)) {
774 14 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Tenth parameter (from taz) requires a string.", outputStorage);
775 : }
776 : std::string toTaz;
777 15171 : if (!server.readTypeCheckingString(inputStorage, toTaz)) {
778 14 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Eleventh parameter (to taz) requires a string.", outputStorage);
779 : }
780 : std::string line;
781 15171 : if (!server.readTypeCheckingString(inputStorage, line)) {
782 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Twelth parameter (line) requires a string.", outputStorage);
783 : }
784 15171 : const int personCapacity = StoHelp::readTypedInt(inputStorage, "13th parameter (person capacity) requires an int.");
785 15185 : const int personNumber = StoHelp::readTypedInt(inputStorage, "14th parameter (person number) requires an int.");
786 15171 : libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed, arrivalLane, arrivalPos, arrivalSpeed,
787 : fromTaz, toTaz, line, personCapacity, personNumber);
788 : }
789 : break;
790 23 : case libsumo::REMOVE: {
791 23 : int why = 0;
792 23 : if (!server.readTypeCheckingByte(inputStorage, why)) {
793 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Removing a vehicle requires a byte.", outputStorage);
794 : }
795 23 : libsumo::Vehicle::remove(id, (char)why);
796 : }
797 23 : break;
798 3086 : case libsumo::MOVE_TO_XY: {
799 3086 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
800 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "MoveToXY vehicle requires a compound object.", outputStorage);
801 : }
802 3086 : const int numArgs = inputStorage.readInt();
803 3086 : if (numArgs < 5 || numArgs > 7) {
804 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "MoveToXY vehicle should obtain: edgeID, lane, x, y, angle and optionally keepRouteFlag and matchThreshold.", outputStorage);
805 : }
806 : std::string edgeID;
807 3086 : if (!server.readTypeCheckingString(inputStorage, edgeID)) {
808 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first parameter for moveToXY must be the edge ID given as a string.", outputStorage);
809 : }
810 3086 : const int laneIndex = StoHelp::readTypedInt(inputStorage, "The second parameter for moveToXY must be lane given as an int.");
811 3086 : double x = 0;
812 3086 : if (!server.readTypeCheckingDouble(inputStorage, x)) {
813 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third parameter for moveToXY must be the x-position given as a double.", outputStorage);
814 : }
815 3086 : double y = 0;
816 3086 : if (!server.readTypeCheckingDouble(inputStorage, y)) {
817 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth parameter for moveToXY must be the y-position given as a double.", outputStorage);
818 : }
819 3086 : double angle = 0;
820 3086 : if (!server.readTypeCheckingDouble(inputStorage, angle)) {
821 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth parameter for moveToXY must be the angle given as a double.", outputStorage);
822 : }
823 :
824 3086 : int keepRouteFlag = 1;
825 3086 : if (numArgs >= 6) {
826 3050 : if (!server.readTypeCheckingByte(inputStorage, keepRouteFlag)) {
827 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The sixth parameter for moveToXY must be the keepRouteFlag given as a byte.", outputStorage);
828 : }
829 : }
830 36 : double matchThreshold = 100;
831 3050 : if (numArgs == 7) {
832 3042 : if (!server.readTypeCheckingDouble(inputStorage, matchThreshold)) {
833 5 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The seventh parameter for moveToXY must be the matchThreshold given as a double.", outputStorage);
834 : }
835 : }
836 3086 : libsumo::Vehicle::moveToXY(id, edgeID, laneIndex, x, y, angle, keepRouteFlag, matchThreshold);
837 : }
838 : break;
839 4098 : case libsumo::VAR_SPEED_FACTOR: {
840 4098 : double factor = 0;
841 4098 : if (!server.readTypeCheckingDouble(inputStorage, factor)) {
842 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting speed factor requires a double.", outputStorage);
843 : }
844 4098 : libsumo::Vehicle::setSpeedFactor(id, factor);
845 : }
846 4098 : break;
847 : case libsumo::VAR_LINE: {
848 : std::string line;
849 9 : if (!server.readTypeCheckingString(inputStorage, line)) {
850 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The line must be given as a string.", outputStorage);
851 : }
852 9 : libsumo::Vehicle::setLine(id, line);
853 : }
854 : break;
855 : case libsumo::VAR_VIA: {
856 : std::vector<std::string> edgeIDs;
857 11 : if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {
858 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Vias must be defined as a list of edge ids.", outputStorage);
859 : }
860 11 : libsumo::Vehicle::setVia(id, edgeIDs);
861 11 : }
862 : break;
863 337 : case libsumo::VAR_PARAMETER: {
864 337 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
865 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
866 : }
867 : //readt itemNo
868 337 : inputStorage.readInt();
869 : std::string name;
870 337 : if (!server.readTypeCheckingString(inputStorage, name)) {
871 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);
872 : }
873 : std::string value;
874 337 : if (!server.readTypeCheckingString(inputStorage, value)) {
875 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
876 : }
877 : try {
878 : /// XXX but a big try/catch around all retrieval cases
879 337 : libsumo::Vehicle::setParameter(id, name, value);
880 8 : } catch (libsumo::TraCIException& e) {
881 8 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
882 8 : }
883 : }
884 : break;
885 26 : case libsumo::VAR_HIGHLIGHT: {
886 : // Highlight the vehicle by adding a tracking polygon. (NOTE: duplicated code exists for POI domain)
887 26 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
888 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A compound object is needed for highlighting an object.", outputStorage);
889 : }
890 26 : const int itemNo = inputStorage.readInt();
891 26 : if (itemNo > 5) {
892 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Highlighting an object needs zero to five parameters.", outputStorage);
893 : }
894 : libsumo::TraCIColor col = libsumo::TraCIColor(255, 0, 0);
895 26 : if (itemNo > 0) {
896 26 : if (!server.readTypeCheckingColor(inputStorage, col)) {
897 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first parameter for highlighting must be the highlight color.", outputStorage);
898 : }
899 : }
900 0 : double size = -1;
901 26 : if (itemNo > 1) {
902 26 : if (!server.readTypeCheckingDouble(inputStorage, size)) {
903 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_POI_VARIABLE, "The second parameter for highlighting must be the highlight size.", outputStorage);
904 : }
905 : }
906 0 : int alphaMax = -1;
907 26 : if (itemNo > 2) {
908 14 : if (!server.readTypeCheckingUnsignedByte(inputStorage, alphaMax)) {
909 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third parameter for highlighting must be maximal alpha.", outputStorage);
910 : }
911 : }
912 12 : double duration = -1;
913 14 : if (itemNo > 3) {
914 14 : if (!server.readTypeCheckingDouble(inputStorage, duration)) {
915 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth parameter for highlighting must be the highlight duration.", outputStorage);
916 : }
917 : }
918 12 : int type = 0;
919 14 : if (itemNo > 4) {
920 14 : if (!server.readTypeCheckingUnsignedByte(inputStorage, type)) {
921 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth parameter for highlighting must be the highlight type id as ubyte.", outputStorage);
922 : }
923 : }
924 26 : libsumo::Vehicle::highlight(id, col, size, alphaMax, duration, type);
925 : }
926 : break;
927 : case libsumo::CMD_TAXI_DISPATCH: {
928 : std::vector<std::string> reservations;
929 154 : if (!server.readTypeCheckingStringList(inputStorage, reservations)) {
930 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A dispatch command must be defined as a list of reservation ids.", outputStorage);
931 : }
932 154 : libsumo::Vehicle::dispatchTaxi(id, reservations);
933 154 : }
934 : break;
935 11 : case libsumo::VAR_ACTIONSTEPLENGTH: {
936 11 : double value = 0;
937 11 : if (!server.readTypeCheckingDouble(inputStorage, value)) {
938 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting action step length requires a double.", outputStorage);
939 : }
940 11 : if (fabs(value) == std::numeric_limits<double>::infinity()) {
941 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid action step length.", outputStorage);
942 : }
943 11 : bool resetActionOffset = value >= 0.0;
944 11 : libsumo::Vehicle::setActionStepLength(id, fabs(value), resetActionOffset);
945 : }
946 11 : break;
947 5 : case libsumo::VAR_LANEPOSITION_LAT: {
948 5 : double value = 0;
949 5 : if (!server.readTypeCheckingDouble(inputStorage, value)) {
950 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting lateral lane position requires a double.", outputStorage);
951 : }
952 5 : libsumo::Vehicle::setLateralLanePosition(id, value);
953 : }
954 5 : break;
955 176 : case libsumo::VAR_UPDATE_BESTLANES: {
956 176 : libsumo::Vehicle::updateBestLanes(id);
957 : }
958 : break;
959 9 : case libsumo::VAR_MINGAP: {
960 9 : double value = 0;
961 9 : if (!server.readTypeCheckingDouble(inputStorage, value)) {
962 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting minimum gap requires a double.", outputStorage);
963 : }
964 9 : if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
965 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum gap.", outputStorage);
966 : }
967 9 : libsumo::Vehicle::setMinGap(id, value);
968 : }
969 9 : break;
970 5 : case libsumo::VAR_MINGAP_LAT: {
971 5 : double value = 0;
972 5 : if (!server.readTypeCheckingDouble(inputStorage, value)) {
973 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting minimum lateral gap requires a double.", outputStorage);
974 : }
975 5 : if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
976 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum lateral gap.", outputStorage);
977 : }
978 5 : libsumo::Vehicle::setMinGapLat(id, value);
979 : }
980 5 : break;
981 229 : default: {
982 : try {
983 229 : if (!TraCIServerAPI_VehicleType::setVariable(libsumo::CMD_SET_VEHICLE_VARIABLE, variable, v->getSingularType().getID(), server, inputStorage, outputStorage)) {
984 : return false;
985 : }
986 0 : } catch (ProcessError& e) {
987 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
988 0 : } catch (libsumo::TraCIException& e) {
989 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
990 0 : }
991 : }
992 : break;
993 : }
994 104 : } catch (libsumo::TraCIException& e) {
995 104 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
996 104 : }
997 101003 : server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);
998 : return true;
999 : }
1000 :
1001 :
1002 : bool
1003 199 : TraCIServerAPI_Vehicle::insertReplaceStop(TraCIServer& server, tcpip::Storage& inputStorage, tcpip::Storage& outputStorage, const std::string& id, bool replace) {
1004 282 : const std::string m1 = replace ? "Replacing" : "Inserting";
1005 307 : const std::string m2 = replace ? "replacement" : "insertion";
1006 :
1007 199 : if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1008 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, m1 + " stop needs a compound object description.", outputStorage);
1009 : }
1010 199 : int compoundSize = inputStorage.readInt();
1011 199 : if (compoundSize != 8 && compoundSize != 9) {
1012 25 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, m1 + " stop needs a compound object description of eight or nine items.", outputStorage);
1013 : }
1014 : // read road map position
1015 : std::string edgeID;
1016 199 : if (!server.readTypeCheckingString(inputStorage, edgeID)) {
1017 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first stop " + m2 + " parameter must be the edge id given as a string.", outputStorage);
1018 : }
1019 199 : double pos = 0;
1020 199 : if (!server.readTypeCheckingDouble(inputStorage, pos)) {
1021 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second stop " + m2 + " parameter must be the end position along the edge given as a double.", outputStorage);
1022 : }
1023 199 : int laneIndex = 0;
1024 199 : if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
1025 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third stop " + m2 + " parameter must be the lane index given as a byte.", outputStorage);
1026 : }
1027 : // waitTime
1028 199 : double duration = libsumo::INVALID_DOUBLE_VALUE;
1029 199 : if (!server.readTypeCheckingDouble(inputStorage, duration)) {
1030 0 : return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "The fourth stop " + m2 + " parameter must be the stopping duration given as a double.", outputStorage);
1031 : }
1032 398 : const int stopFlags = StoHelp::readTypedInt(inputStorage, "The fifth stop " + m2 + " parameter must be a int indicating its parking/triggered status.");
1033 199 : double startPos = libsumo::INVALID_DOUBLE_VALUE;
1034 199 : if (!server.readTypeCheckingDouble(inputStorage, startPos)) {
1035 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The sixth stop " + m2 + " parameter must be the start position along the edge given as a double.", outputStorage);
1036 : }
1037 199 : double until = libsumo::INVALID_DOUBLE_VALUE;
1038 199 : if (!server.readTypeCheckingDouble(inputStorage, until)) {
1039 0 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The seventh stop " + m2 + " parameter must be the minimum departure time given as a double.", outputStorage);
1040 : }
1041 398 : const int nextStopIndex = StoHelp::readTypedInt(inputStorage, "The eigth stop " + m2 + " parameter must be the replacement index given as a int.");
1042 199 : int teleport = 0;
1043 199 : if (compoundSize == 9) {
1044 199 : if (!server.readTypeCheckingByte(inputStorage, teleport)) {
1045 25 : return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The nineth stop " + m2 + " parameter must be the teleport flag given as a byte.", outputStorage);
1046 : }
1047 : }
1048 199 : if (replace) {
1049 116 : libsumo::Vehicle::replaceStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
1050 : } else {
1051 83 : libsumo::Vehicle::insertStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
1052 : }
1053 : return true;
1054 : }
1055 : /****************************************************************************/
|