Eclipse SUMO - Simulation of Urban MObility
TraCIServerAPI_Vehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2009-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
28 // APIs for getting/setting vehicle values via TraCI
29 /****************************************************************************/
30 #include <config.h>
31 
32 #include <microsim/MSNet.h>
34 #include <microsim/MSVehicle.h>
36 #include <microsim/MSLane.h>
37 #include <microsim/MSEdge.h>
38 #include <microsim/MSGlobals.h>
46 #include <libsumo/TraCIConstants.h>
47 #include <libsumo/Vehicle.h>
48 #include <libsumo/VehicleType.h>
50 #include "TraCIServerAPI_Vehicle.h"
52 
53 
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
57 bool
59  tcpip::Storage& outputStorage) {
60  const int variable = inputStorage.readUnsignedByte();
61  const std::string id = inputStorage.readString();
63  try {
64  if (!libsumo::Vehicle::handleVariable(id, variable, &server, &inputStorage)) {
65  switch (variable) {
67  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
68  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires a compound object.", outputStorage);
69  }
70  if (inputStorage.readInt() != 2) {
71  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires time and edge as parameter.", outputStorage);
72  }
73  double time = 0.;
74  if (!server.readTypeCheckingDouble(inputStorage, time)) {
75  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires the referenced time as first parameter.", outputStorage);
76  }
77  // edge
78  std::string edgeID;
79  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
80  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires the referenced edge as second parameter.", outputStorage);
81  }
82  // retrieve
84  server.getWrapperStorage().writeDouble(libsumo::Vehicle::getAdaptedTraveltime(id, time, edgeID));
85  break;
86  }
88  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
89  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of effort requires a compound object.", outputStorage);
90  }
91  if (inputStorage.readInt() != 2) {
92  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of effort requires time and edge as parameter.", outputStorage);
93  }
94  double time = 0.;
95  if (!server.readTypeCheckingDouble(inputStorage, time)) {
96  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of effort requires the referenced time as first parameter.", outputStorage);
97  }
98  // edge
99  std::string edgeID;
100  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
101  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of effort requires the referenced edge as second parameter.", outputStorage);
102  }
104  server.getWrapperStorage().writeDouble(libsumo::Vehicle::getEffort(id, time, edgeID));
105  break;
106  }
109  tcpip::Storage tempContent;
110  int cnt = 0;
112  std::vector<libsumo::TraCIBestLanesData> bestLanes = libsumo::Vehicle::getBestLanes(id);
113  tempContent.writeInt((int)bestLanes.size());
114  ++cnt;
115  for (std::vector<libsumo::TraCIBestLanesData>::const_iterator i = bestLanes.begin(); i != bestLanes.end(); ++i) {
116  const libsumo::TraCIBestLanesData& bld = *i;
118  tempContent.writeString(bld.laneID);
119  ++cnt;
121  tempContent.writeDouble(bld.length);
122  ++cnt;
124  tempContent.writeDouble(bld.occupation);
125  ++cnt;
127  tempContent.writeByte(bld.bestLaneOffset);
128  ++cnt;
130  bld.allowsContinuation ? tempContent.writeUnsignedByte(1) : tempContent.writeUnsignedByte(0);
131  ++cnt;
133  tempContent.writeStringList(bld.continuationLanes);
134  ++cnt;
135  }
136  server.getWrapperStorage().writeInt((int)cnt);
137  server.getWrapperStorage().writeStorage(tempContent);
138  break;
139  }
140  case libsumo::VAR_NEXT_TLS: {
141  std::vector<libsumo::TraCINextTLSData> nextTLS = libsumo::Vehicle::getNextTLS(id);
143  const int cnt = 1 + (int)nextTLS.size() * 4;
144  server.getWrapperStorage().writeInt(cnt);
146  server.getWrapperStorage().writeInt((int)nextTLS.size());
147  for (std::vector<libsumo::TraCINextTLSData>::iterator it = nextTLS.begin(); it != nextTLS.end(); ++it) {
149  server.getWrapperStorage().writeString(it->id);
151  server.getWrapperStorage().writeInt(it->tlIndex);
153  server.getWrapperStorage().writeDouble(it->dist);
155  server.getWrapperStorage().writeByte(it->state);
156  }
157  break;
158  }
160  // deliberate fallThrough!
161  int limit = 0;
162  if (!server.readTypeCheckingInt(inputStorage, limit)) {
163  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Stop retrieval uses an optional integer.", outputStorage);
164  }
165  writeNextStops(server, id, limit, true);
166  break;
167  }
169  writeNextStops(server, id, 0, false);
170  break;
171  }
173  std::vector<libsumo::TraCIConnection> links = libsumo::Vehicle::getNextLinks(id);
175  tcpip::Storage tempContent;
176  int cnt = 0;
178  tempContent.writeInt((int)links.size());
179  ++cnt;
180  for (std::vector<libsumo::TraCIConnection>::const_iterator i = links.begin(); i != links.end(); ++i) {
181  // approached non-internal lane (if any)
183  tempContent.writeString(i->approachedLane);
184  ++cnt;
185  // approached "via", internal lane (if any)
187  tempContent.writeString(i->approachedInternal);
188  ++cnt;
189  // priority
191  tempContent.writeUnsignedByte(i->hasPrio);
192  ++cnt;
193  // opened
195  tempContent.writeUnsignedByte(i->isOpen);
196  ++cnt;
197  // approaching foe
199  tempContent.writeUnsignedByte(i->hasFoe);
200  ++cnt;
201  // state (not implemented yet)
203  tempContent.writeString(i->state);
204  ++cnt;
205  // direction
207  tempContent.writeString(i->direction);
208  ++cnt;
209  // length
211  tempContent.writeDouble(i->length);
212  ++cnt;
213  }
214  server.getWrapperStorage().writeInt(cnt);
215  server.getWrapperStorage().writeStorage(tempContent);
216  break;
217  }
219  // read variables
220  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
221  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "getting stop parameter needs a compound object description.", outputStorage);
222  }
223  int compoundSize = inputStorage.readInt();
224  if (compoundSize != 2 && compoundSize != 3) {
225  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "getting a stop parameter needs a compound object description of 2 or 3 items.", outputStorage);
226  }
227  int nextStopIndex;
228  if (!server.readTypeCheckingInt(inputStorage, nextStopIndex)) {
229  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first setStopParameter parameter must be the nextStopIndex given as an integer.", outputStorage);
230  }
231  std::string param;
232  if (!server.readTypeCheckingString(inputStorage, param)) {
233  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second setStopParameter parameter must be the param given as a string.", outputStorage);
234  }
235  int customParam = 0;
236  if (compoundSize == 3) {
237  if (!server.readTypeCheckingByte(inputStorage, customParam)) {
238  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third setStopParameter parameter must be the customParam flag given as a byte.", outputStorage);
239  }
240  }
242  server.getWrapperStorage().writeString(libsumo::Vehicle::getStopParameter(id, nextStopIndex, param, customParam != 0));
243  }
244  break;
246  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
247  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of distance requires a compound object.", outputStorage);
248  }
249  if (inputStorage.readInt() != 2) {
250  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of distance requires position and distance type as parameter.", outputStorage);
251  }
252 
253  // read position
254  int posType = inputStorage.readUnsignedByte();
255  switch (posType) {
257  try {
258  const std::string roadID = inputStorage.readString();
259  const double edgePos = inputStorage.readDouble();
260  const int laneIndex = inputStorage.readUnsignedByte();
262  server.getWrapperStorage().writeDouble(libsumo::Vehicle::getDrivingDistance(id, roadID, edgePos, laneIndex));
263  break;
264  } catch (libsumo::TraCIException& e) {
265  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, e.what(), outputStorage);
266  }
268  case libsumo::POSITION_3D: {
269  const double p1x = inputStorage.readDouble();
270  const double p1y = inputStorage.readDouble();
271  if (posType == libsumo::POSITION_3D) {
272  inputStorage.readDouble(); // z value is ignored
273  }
275  server.getWrapperStorage().writeDouble(libsumo::Vehicle::getDrivingDistance2D(id, p1x, p1y));
276  break;
277  }
278  default:
279  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Unknown position format used for distance request", outputStorage);
280  }
281  // read distance type
282  int distType = inputStorage.readUnsignedByte();
283  if (distType != libsumo::REQUEST_DRIVINGDIST) {
284  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Only driving distance is supported for vehicles.", outputStorage);
285  }
286  break;
287  }
289  int direction = 0;
290  if (!server.readTypeCheckingInt(inputStorage, direction)) {
291  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of lane change state requires a direction as int.", outputStorage);
292  }
293  const std::pair<int, int> state = libsumo::Vehicle::getLaneChangeState(id, direction);
295  server.getWrapperStorage().writeInt(2);
297  server.getWrapperStorage().writeInt(state.first);
299  server.getWrapperStorage().writeInt(state.second);
300  break;
301  }
303  int flag = 0;
304  if (!server.readTypeCheckingInt(inputStorage, flag)) {
305  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of taxi fleet requires an integer flag.", outputStorage);
306  }
308  server.getWrapperStorage().writeStringList(libsumo::Vehicle::getTaxiFleet(flag));
309  break;
310  }
311  case libsumo::VAR_NEIGHBORS: {
312  int mode;
313  if (!server.readTypeCheckingUnsignedByte(inputStorage, mode)) {
314  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of neighboring vehicles needs bitset to specify mode.", outputStorage);
315  }
316  const std::vector<std::pair<std::string, double> >& neighVehicles = libsumo::Vehicle::getNeighbors(id, mode);
318  server.getWrapperStorage().writeInt((int)neighVehicles.size());
319  for (auto& p : neighVehicles) {
320  server.getWrapperStorage().writeString(p.first);
321  server.getWrapperStorage().writeDouble(p.second);
322  }
323  break;
324  }
326  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
327  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of followSpeed requires requires a compound object.", outputStorage);
328  }
329  int parameterCount = inputStorage.readInt();
330  double speed;
331  double gap;
332  double leaderSpeed;
333  double leaderMaxDecel;
334  std::string leaderID;
335  if (parameterCount == 5) {
336  // speed
337  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
338  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of followSpeed requires the speed as first parameter.", outputStorage);
339  }
340  // gap
341  if (!server.readTypeCheckingDouble(inputStorage, gap)) {
342  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of followSpeed requires the gap as second parameter.", outputStorage);
343  }
344  // leaderSpeed
345  if (!server.readTypeCheckingDouble(inputStorage, leaderSpeed)) {
346  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of followSpeed requires the leaderSpeed as third parameter.", outputStorage);
347  }
348  // leaderMaxDecel
349  if (!server.readTypeCheckingDouble(inputStorage, leaderMaxDecel)) {
350  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of followSpeed requires the leaderMaxDecel as fourth parameter.", outputStorage);
351  }
352  // leaderID
353  if (!server.readTypeCheckingString(inputStorage, leaderID)) {
354  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of followSpeed requires the leaderID as fifth parameter.", outputStorage);
355  }
356  } else {
357  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of followSpeed requires 5 parameters.", outputStorage);
358  }
359  // retrieve
361  server.getWrapperStorage().writeDouble(libsumo::Vehicle::getFollowSpeed(id, speed, gap, leaderSpeed, leaderMaxDecel, leaderID));
362  }
363  break;
365  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
366  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of secureGap requires requires a compound object.", outputStorage);
367  }
368  int parameterCount = inputStorage.readInt();
369  double speed;
370  double leaderSpeed;
371  double leaderMaxDecel;
372  std::string leaderID;
373  if (parameterCount == 4) {
374  // speed
375  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
376  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of secureGap requires the speed as first parameter.", outputStorage);
377  }
378  // leaderSpeed
379  if (!server.readTypeCheckingDouble(inputStorage, leaderSpeed)) {
380  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of secureGap requires the leaderSpeed as second parameter.", outputStorage);
381  }
382  // leaderMaxDecel
383  if (!server.readTypeCheckingDouble(inputStorage, leaderMaxDecel)) {
384  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of secureGap requires the leaderMaxDecel as third parameter.", outputStorage);
385  }
386  // leaderID
387  if (!server.readTypeCheckingString(inputStorage, leaderID)) {
388  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of secureGap requires the leaderID as fourth parameter.", outputStorage);
389  }
390  } else {
391  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of secureGap requires 4 parameters.", outputStorage);
392  }
393  // retrieve
395  server.getWrapperStorage().writeDouble(libsumo::Vehicle::getSecureGap(id, speed, leaderSpeed, leaderMaxDecel, leaderID));
396  }
397  break;
399  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
400  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of stopSpeed requires requires a compound object.", outputStorage);
401  }
402  int parameterCount = inputStorage.readInt();
403  double speed;
404  double gap;
405  if (parameterCount == 2) {
406  // speed
407  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
408  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of stopSpeed requires the speed as first parameter.", outputStorage);
409  }
410  // gap
411  if (!server.readTypeCheckingDouble(inputStorage, gap)) {
412  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Retrieval of stopSpeed requires the gap as second parameter.", outputStorage);
413  }
414  } else {
415  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of stopSpeed requires 2 parameters.", outputStorage);
416  }
417  // retrieve
419  server.getWrapperStorage().writeDouble(libsumo::Vehicle::getStopSpeed(id, speed, gap));
420  }
421  break;
422  case libsumo::VAR_FOES: {
423  double distance;
424  if (!server.readTypeCheckingDouble(inputStorage, distance)) {
425  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Retrieval of junction foes requires the distance as first parameter.", outputStorage);
426  }
427  std::vector<libsumo::TraCIJunctionFoe> junctionFoes = libsumo::Vehicle::getJunctionFoes(id, distance);
429  const int cnt = 1 + (int)junctionFoes.size() * 9;
430  server.getWrapperStorage().writeInt(cnt);
432  server.getWrapperStorage().writeInt((int)junctionFoes.size());
433  for (std::vector<libsumo::TraCIJunctionFoe>::iterator it = junctionFoes.begin(); it != junctionFoes.end(); ++it) {
435  server.getWrapperStorage().writeString(it->foeId);
437  server.getWrapperStorage().writeDouble(it->egoDist);
439  server.getWrapperStorage().writeDouble(it->foeDist);
441  server.getWrapperStorage().writeDouble(it->egoExitDist);
443  server.getWrapperStorage().writeDouble(it->foeExitDist);
445  server.getWrapperStorage().writeString(it->egoLane);
447  server.getWrapperStorage().writeString(it->foeLane);
449  server.getWrapperStorage().writeChar(it->egoResponse);
451  server.getWrapperStorage().writeChar(it->foeResponse);
452  }
453  break;
454  }
455  default:
456  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Get Vehicle Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
457  }
458  }
459  } catch (libsumo::TraCIException& e) {
460  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, e.what(), outputStorage);
461  }
463  server.writeResponseWithLength(outputStorage, server.getWrapperStorage());
464  return true;
465 }
466 
467 
468 bool
470  tcpip::Storage& outputStorage) {
471  std::string warning = ""; // additional description for response
472  // variable
473  int variable = inputStorage.readUnsignedByte();
474  if (variable != libsumo::CMD_STOP && variable != libsumo::CMD_CHANGELANE
475  && variable != libsumo::CMD_REROUTE_TO_PARKING
476  && variable != libsumo::CMD_CHANGESUBLANE && variable != libsumo::CMD_OPENGAP
477  && variable != libsumo::CMD_REPLACE_STOP
478  && variable != libsumo::CMD_INSERT_STOP
479  && variable != libsumo::VAR_STOP_PARAMETER
480  && variable != libsumo::CMD_SLOWDOWN && variable != libsumo::CMD_CHANGETARGET && variable != libsumo::CMD_RESUME
481  && variable != libsumo::VAR_TYPE && variable != libsumo::VAR_ROUTE_ID && variable != libsumo::VAR_ROUTE
482  && variable != libsumo::VAR_LANEPOSITION_LAT
483  && variable != libsumo::VAR_UPDATE_BESTLANES
484  && variable != libsumo::VAR_EDGE_TRAVELTIME && variable != libsumo::VAR_EDGE_EFFORT
486  && variable != libsumo::VAR_SIGNALS && variable != libsumo::VAR_MOVE_TO
487  && variable != libsumo::VAR_LENGTH && variable != libsumo::VAR_MAXSPEED && variable != libsumo::VAR_VEHICLECLASS
488  && variable != libsumo::VAR_SPEED_FACTOR && variable != libsumo::VAR_EMISSIONCLASS
489  && variable != libsumo::VAR_WIDTH && variable != libsumo::VAR_MINGAP && variable != libsumo::VAR_SHAPECLASS
490  && variable != libsumo::VAR_ACCEL && variable != libsumo::VAR_DECEL && variable != libsumo::VAR_IMPERFECTION
491  && variable != libsumo::VAR_APPARENT_DECEL && variable != libsumo::VAR_EMERGENCY_DECEL
492  && variable != libsumo::VAR_ACTIONSTEPLENGTH
493  && variable != libsumo::VAR_TAU && variable != libsumo::VAR_LANECHANGE_MODE
494  && variable != libsumo::VAR_SPEED && variable != libsumo::VAR_ACCELERATION && variable != libsumo::VAR_PREV_SPEED && variable != libsumo::VAR_SPEEDSETMODE && variable != libsumo::VAR_COLOR
495  && variable != libsumo::ADD && variable != libsumo::ADD_FULL && variable != libsumo::REMOVE
496  && variable != libsumo::VAR_HEIGHT
497  && variable != libsumo::VAR_MASS
498  && variable != libsumo::VAR_ROUTING_MODE
499  && variable != libsumo::VAR_LATALIGNMENT
500  && variable != libsumo::VAR_MAXSPEED_LAT
501  && variable != libsumo::VAR_MINGAP_LAT
502  && variable != libsumo::VAR_LINE
503  && variable != libsumo::VAR_VIA
504  && variable != libsumo::VAR_IMPATIENCE
505  && variable != libsumo::VAR_BOARDING_DURATION
506  && variable != libsumo::VAR_HIGHLIGHT
507  && variable != libsumo::CMD_TAXI_DISPATCH
508  && variable != libsumo::MOVE_TO_XY && variable != libsumo::VAR_PARAMETER/* && variable != libsumo::VAR_SPEED_TIME_LINE && variable != libsumo::VAR_LANE_TIME_LINE*/
509  ) {
510  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Change Vehicle State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
511  }
512  // id
513  std::string id = inputStorage.readString();
514 #ifdef DEBUG_MOVEXY
515  std::cout << SIMTIME << " processSet veh=" << id << "\n";
516 #endif
517  const bool shouldExist = variable != libsumo::ADD && variable != libsumo::ADD_FULL;
519  if (sumoVehicle == nullptr) {
520  if (shouldExist) {
521  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
522  }
523  }
524  MSBaseVehicle* v = dynamic_cast<MSBaseVehicle*>(sumoVehicle);
525  if (v == nullptr && shouldExist) {
526  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a proper vehicle", outputStorage);
527  }
528  try {
529  switch (variable) {
530  case libsumo::CMD_STOP: {
531  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
532  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description.", outputStorage);
533  }
534  int compoundSize = inputStorage.readInt();
535  if (compoundSize < 4 || compoundSize > 7) {
536  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description of four to seven items.", outputStorage);
537  }
538  // read road map position
539  std::string edgeID;
540  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
541  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first stop parameter must be the edge id given as a string.", outputStorage);
542  }
543  double pos = 0;
544  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
545  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);
546  }
547  int laneIndex = 0;
548  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
549  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third stop parameter must be the lane index given as a byte.", outputStorage);
550  }
551  // waitTime
552  double duration = libsumo::INVALID_DOUBLE_VALUE;
553  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
554  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "The fourth stop parameter must be the stopping duration given as a double.", outputStorage);
555  }
556  int stopFlags = 0;
557  if (compoundSize >= 5) {
558  if (!server.readTypeCheckingByte(inputStorage, stopFlags)) {
559  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth stop parameter must be a byte indicating its parking/triggered status.", outputStorage);
560  }
561  }
562  double startPos = libsumo::INVALID_DOUBLE_VALUE;
563  if (compoundSize >= 6) {
564  if (!server.readTypeCheckingDouble(inputStorage, startPos)) {
565  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);
566  }
567  }
568  double until = libsumo::INVALID_DOUBLE_VALUE;
569  if (compoundSize >= 7) {
570  if (!server.readTypeCheckingDouble(inputStorage, until)) {
571  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The seventh stop parameter must be the minimum departure time given as a double.", outputStorage);
572  }
573  }
574  libsumo::Vehicle::setStop(id, edgeID, pos, laneIndex, duration, stopFlags, startPos, until);
575  }
576  break;
578  if (!insertReplaceStop(server, inputStorage, outputStorage, id, true)) {
579  return false;
580  }
581  break;
583  if (!insertReplaceStop(server, inputStorage, outputStorage, id, false)) {
584  return false;
585  }
586  break;
588  // read variables
589  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
590  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting stop parameter needs a compound object description.", outputStorage);
591  }
592  int compoundSize = inputStorage.readInt();
593  if (compoundSize != 3 && compoundSize != 4) {
594  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting a stop parameter needs a compound object description of 3 or 4 items.", outputStorage);
595  }
596  int nextStopIndex;
597  if (!server.readTypeCheckingInt(inputStorage, nextStopIndex)) {
598  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first setStopParameter parameter must be the nextStopIndex given as an integer.", outputStorage);
599  }
600  std::string param;
601  if (!server.readTypeCheckingString(inputStorage, param)) {
602  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second setStopParameter parameter must be the param given as a string.", outputStorage);
603  }
604  std::string value;
605  if (!server.readTypeCheckingString(inputStorage, value)) {
606  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third setStopParameter parameter must be the value given as a string.", outputStorage);
607  }
608  int customParam = 0;
609  if (compoundSize == 4) {
610  if (!server.readTypeCheckingByte(inputStorage, customParam)) {
611  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth setStopParameter parameter must be the customParam flag given as a byte.", outputStorage);
612  }
613  }
614  libsumo::Vehicle::setStopParameter(id, nextStopIndex, param, value, customParam != 0);
615  }
616  break;
618  // read variables
619  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
620  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Reroute to stop needs a compound object description.", outputStorage);
621  }
622  int compoundSize = inputStorage.readInt();
623  if (compoundSize != 1) {
624  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Reroute to stop needs a compound object description of 1 item.", outputStorage);
625  }
626  std::string parkingAreaID;
627  if (!server.readTypeCheckingString(inputStorage, parkingAreaID)) {
628  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);
629  }
630  libsumo::Vehicle::rerouteParkingArea(id, parkingAreaID);
631  }
632  break;
633  case libsumo::CMD_RESUME: {
634  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
635  server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_ERR, "Resuming requires a compound object.", outputStorage);
636  return false;
637  }
638  if (inputStorage.readInt() != 0) {
639  server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_ERR, "Resuming should obtain an empty compound object.", outputStorage);
640  return false;
641  }
642  libsumo::Vehicle::resume(id);
643  }
644  break;
646  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
647  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description.", outputStorage);
648  }
649  int compounds = inputStorage.readInt();
650  if (compounds != 3 && compounds != 2) {
651  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two or three items.", outputStorage);
652  }
653  // Lane ID
654  int laneIndex = 0;
655  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
656  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first lane change parameter must be the lane index given as a byte.", outputStorage);
657  }
658  // duration
659  double duration = 0.;
660  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
661  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second lane change parameter must be the duration given as a double.", outputStorage);
662  }
663  // relativelanechange
664  int relative = 0;
665  if (compounds == 3) {
666  if (!server.readTypeCheckingByte(inputStorage, relative)) {
667  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);
668  }
669  }
670 
671  if ((laneIndex < 0 || laneIndex >= (int)v->getEdge()->getLanes().size()) && relative < 1) {
672  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + v->getEdge()->getID() + "'.", outputStorage);
673  }
674 
675  if (relative < 1) {
676  libsumo::Vehicle::changeLane(id, laneIndex, duration);
677  } else {
678  libsumo::Vehicle::changeLaneRelative(id, laneIndex, duration);
679  }
680  }
681  break;
683  double latDist = 0;
684  if (!server.readTypeCheckingDouble(inputStorage, latDist)) {
685  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Sublane-changing requires a double.", outputStorage);
686  }
687  libsumo::Vehicle::changeSublane(id, latDist);
688  }
689  break;
690  case libsumo::CMD_SLOWDOWN: {
691  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
692  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description.", outputStorage);
693  }
694  if (inputStorage.readInt() != 2) {
695  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description of two items.", outputStorage);
696  }
697  double newSpeed = 0;
698  if (!server.readTypeCheckingDouble(inputStorage, newSpeed)) {
699  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first slow down parameter must be the speed given as a double.", outputStorage);
700  }
701  if (newSpeed < 0) {
702  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Speed must not be negative", outputStorage);
703  }
704  double duration = 0.;
705  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
706  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second slow down parameter must be the duration given as a double.", outputStorage);
707  }
708  if (duration < 0 || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
709  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval", outputStorage);
710  }
711  libsumo::Vehicle::slowDown(id, newSpeed, duration);
712  }
713  break;
715  std::string edgeID;
716  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
717  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Change target requires a string containing the id of the new destination edge as parameter.", outputStorage);
718  }
719  libsumo::Vehicle::changeTarget(id, edgeID);
720  }
721  break;
722  case libsumo::CMD_OPENGAP: {
723  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
724  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Create gap needs a compound object description.", outputStorage);
725  }
726  const int nParameter = inputStorage.readInt();
727  if (nParameter != 5 && nParameter != 6) {
728  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Create gap needs a compound object description of five or six items.", outputStorage);
729  }
730  double newTimeHeadway = 0;
731  if (!server.readTypeCheckingDouble(inputStorage, newTimeHeadway)) {
732  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);
733  }
734  double newSpaceHeadway = 0;
735  if (!server.readTypeCheckingDouble(inputStorage, newSpaceHeadway)) {
736  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);
737  }
738  double duration = 0.;
739  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
740  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third create gap parameter must be the duration given as a double.", outputStorage);
741  }
742  double changeRate = 0;
743  if (!server.readTypeCheckingDouble(inputStorage, changeRate)) {
744  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth create gap parameter must be the change rate given as a double.", outputStorage);
745  }
746  double maxDecel = 0;
747  if (!server.readTypeCheckingDouble(inputStorage, maxDecel)) {
748  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth create gap parameter must be the maximal braking rate given as a double.", outputStorage);
749  }
750 
751  if (newTimeHeadway == -1 && newSpaceHeadway == -1 && duration == -1 && changeRate == -1 && maxDecel == -1) {
752  libsumo::Vehicle::deactivateGapControl(id);
753  } else {
754  if (newTimeHeadway <= 0) {
755  if (newTimeHeadway != -1) {
756  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired time headway (tau) must be positive for create gap", outputStorage);
757  } // else if == -1: keep vehicles current headway, see libsumo::Vehicle::openGap
758  }
759  if (newSpaceHeadway < 0) {
760  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired space headway must be non-negative for create gap", outputStorage);
761  }
762  if ((duration < 0 && duration != -1) || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
763  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval for create gap", outputStorage);
764  }
765  if (changeRate <= 0) {
766  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the change rate must be positive for the openGap command", outputStorage);
767  }
768  if (maxDecel <= 0 && maxDecel != -1 && maxDecel != libsumo::INVALID_DOUBLE_VALUE) {
769  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the maximal braking rate must be positive for the openGap command", outputStorage);
770  } // else if <= 0: don't limit cf model's suggested brake rate, see libsumo::Vehicle::openGap
771  std::string refVehID = "";
772  if (nParameter == 6) {
773  if (!server.readTypeCheckingString(inputStorage, refVehID)) {
774  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);
775  }
776  }
777  libsumo::Vehicle::openGap(id, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel, refVehID);
778  }
779  }
780  break;
781  case libsumo::VAR_TYPE: {
782  std::string vTypeID;
783  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
784  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The vehicle type id must be given as a string.", outputStorage);
785  }
786  libsumo::Vehicle::setType(id, vTypeID);
787  }
788  break;
789  case libsumo::VAR_ROUTE_ID: {
790  std::string rid;
791  if (!server.readTypeCheckingString(inputStorage, rid)) {
792  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The route id must be given as a string.", outputStorage);
793  }
794  libsumo::Vehicle::setRouteID(id, rid);
795  }
796  break;
797  case libsumo::VAR_ROUTE: {
798  std::vector<std::string> edgeIDs;
799  if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {
800  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A route must be defined as a list of edge ids.", outputStorage);
801  }
802  libsumo::Vehicle::setRoute(id, edgeIDs);
803  }
804  break;
806  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
807  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires a compound object.", outputStorage);
808  }
809  int parameterCount = inputStorage.readInt();
810  std::string edgeID;
811  double begTime = 0.;
812  double endTime = std::numeric_limits<double>::max();
813  double value = libsumo::INVALID_DOUBLE_VALUE;
814  if (parameterCount == 4) {
815  // begin time
816  if (!server.readTypeCheckingDouble(inputStorage, begTime)) {
817  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the begin time as first parameter.", outputStorage);
818  }
819  // begin time
820  if (!server.readTypeCheckingDouble(inputStorage, endTime)) {
821  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the end time as second parameter.", outputStorage);
822  }
823  // edge
824  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
825  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the referenced edge as third parameter.", outputStorage);
826  }
827  // value
828  if (!server.readTypeCheckingDouble(inputStorage, value)) {
829  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the travel time as double as fourth parameter.", outputStorage);
830  }
831  } else if (parameterCount == 2) {
832  // edge
833  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
834  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the referenced edge as first parameter.", outputStorage);
835  }
836  // value
837  if (!server.readTypeCheckingDouble(inputStorage, value)) {
838  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the travel time as second parameter.", outputStorage);
839  }
840  } else if (parameterCount == 1) {
841  // edge
842  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
843  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 1 parameter requires the referenced edge as first parameter.", outputStorage);
844  }
845  } else {
846  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);
847  }
848  libsumo::Vehicle::setAdaptedTraveltime(id, edgeID, value, begTime, endTime);
849  }
850  break;
852  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
853  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort requires a compound object.", outputStorage);
854  }
855  int parameterCount = inputStorage.readInt();
856  std::string edgeID;
857  double begTime = 0.;
858  double endTime = std::numeric_limits<double>::max();
859  double value = libsumo::INVALID_DOUBLE_VALUE;
860  if (parameterCount == 4) {
861  // begin time
862  if (!server.readTypeCheckingDouble(inputStorage, begTime)) {
863  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the begin time as first parameter.", outputStorage);
864  }
865  // begin time
866  if (!server.readTypeCheckingDouble(inputStorage, endTime)) {
867  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the end time as second parameter.", outputStorage);
868  }
869  // edge
870  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
871  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the referenced edge as third parameter.", outputStorage);
872  }
873  // value
874  if (!server.readTypeCheckingDouble(inputStorage, value)) {
875  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the travel time as fourth parameter.", outputStorage);
876  }
877  } else if (parameterCount == 2) {
878  // edge
879  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
880  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the referenced edge as first parameter.", outputStorage);
881  }
882  if (!server.readTypeCheckingDouble(inputStorage, value)) {
883  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the travel time as second parameter.", outputStorage);
884  }
885  } else if (parameterCount == 1) {
886  // edge
887  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
888  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 1 parameter requires the referenced edge as first parameter.", outputStorage);
889  }
890  } else {
891  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);
892  }
893  // retrieve
894  libsumo::Vehicle::setEffort(id, edgeID, value, begTime, endTime);
895  }
896  break;
898  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
899  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
900  }
901  if (inputStorage.readInt() != 0) {
902  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
903  }
904  libsumo::Vehicle::rerouteTraveltime(id, false);
905  }
906  break;
908  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
909  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
910  }
911  if (inputStorage.readInt() != 0) {
912  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
913  }
914  libsumo::Vehicle::rerouteEffort(id);
915  }
916  break;
917  case libsumo::VAR_SIGNALS: {
918  int signals = 0;
919  if (!server.readTypeCheckingInt(inputStorage, signals)) {
920  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting signals requires an integer.", outputStorage);
921  }
922  libsumo::Vehicle::setSignals(id, signals);
923  }
924  break;
925  case libsumo::VAR_MOVE_TO: {
926  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
927  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting position requires a compound object.", outputStorage);
928  }
929  const int numArgs = inputStorage.readInt();
930  if (numArgs < 2 || numArgs > 3) {
931  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting position should obtain the lane id and the position and optionally the reason.", outputStorage);
932  }
933  // lane ID
934  std::string laneID;
935  if (!server.readTypeCheckingString(inputStorage, laneID)) {
936  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);
937  }
938  // position on lane
939  double position = 0;
940  if (!server.readTypeCheckingDouble(inputStorage, position)) {
941  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second parameter for setting a position must be the position given as a double.", outputStorage);
942  }
943  int reason = libsumo::MOVE_AUTOMATIC;
944  if (numArgs == 3) {
945  if (!server.readTypeCheckingInt(inputStorage, reason)) {
946  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third parameter for setting a position must be the reason given as an int.", outputStorage);
947  }
948  }
949  // process
950  libsumo::Vehicle::moveTo(id, laneID, position, reason);
951  }
952  break;
954  double impatience = 0;
955  if (!server.readTypeCheckingDouble(inputStorage, impatience)) {
956  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting impatience requires a double.", outputStorage);
957  }
958  libsumo::Vehicle::setImpatience(id, impatience);
959  }
960  break;
961  case libsumo::VAR_SPEED: {
962  double speed = 0;
963  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
964  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting speed requires a double.", outputStorage);
965  }
966  libsumo::Vehicle::setSpeed(id, speed);
967  }
968  break;
970  double accel = 0;
971  double duration = 0;
972  int inputtype = inputStorage.readUnsignedByte();
973  if (inputtype == libsumo::TYPE_COMPOUND) {
974  int parameterCount = inputStorage.readInt();
975  if (parameterCount == 2) {
976  if (!server.readTypeCheckingDouble(inputStorage, accel)) {
977  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires the acceleration as first parameter given as a double.", outputStorage);
978  }
979  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
980  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires the duration as second parameter given as a double.", outputStorage);
981  }
982  } else {
983  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires 2 parameters.", outputStorage);
984  }
985  } else {
986  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires 2 parameters as compound object description.", outputStorage);
987  }
988  if (duration < 0) {
989  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Duration must not be negative.", outputStorage);
990  }
991  libsumo::Vehicle::setAcceleration(id, accel, duration);
992  }
993  break;
995  double prevSpeed = 0;
996  double prevAcceleration = libsumo::INVALID_DOUBLE_VALUE;
997  int inputtype = inputStorage.readUnsignedByte();
998  if (inputtype == libsumo::TYPE_COMPOUND) {
999  // Setting previous speed with 2 parameters, uses a compound object description
1000  int parameterCount = inputStorage.readInt();
1001  if (parameterCount == 2) {
1002  if (!server.readTypeCheckingDouble(inputStorage, prevSpeed)) {
1003  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);
1004  }
1005  if (!server.readTypeCheckingDouble(inputStorage, prevAcceleration)) {
1006  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);
1007  }
1008  } else if (parameterCount == 1) {
1009  if (!server.readTypeCheckingDouble(inputStorage, prevSpeed)) {
1010  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);
1011  }
1012  } else {
1013  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed requires 1 or 2 parameters.", outputStorage);
1014  }
1015  } else if (inputtype == libsumo::TYPE_DOUBLE) {
1016  // Setting previous speed with 1 parameter (double), no compound object description
1017  prevSpeed = inputStorage.readDouble();
1018  } else {
1019  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);
1020  }
1021  if (prevSpeed < 0) {
1022  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Previous speed must not be negative.", outputStorage);
1023  }
1024  libsumo::Vehicle::setPreviousSpeed(id, prevSpeed, prevAcceleration);
1025  }
1026  break;
1028  int speedMode = 0;
1029  if (!server.readTypeCheckingInt(inputStorage, speedMode)) {
1030  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting speed mode requires an integer.", outputStorage);
1031  }
1032  libsumo::Vehicle::setSpeedMode(id, speedMode);
1033  }
1034  break;
1036  int laneChangeMode = 0;
1037  if (!server.readTypeCheckingInt(inputStorage, laneChangeMode)) {
1038  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting lane change mode requires an integer.", outputStorage);
1039  }
1040  libsumo::Vehicle::setLaneChangeMode(id, laneChangeMode);
1041  }
1042  break;
1044  int routingMode = 0;
1045  if (!server.readTypeCheckingInt(inputStorage, routingMode)) {
1046  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting routing mode requires an integer.", outputStorage);
1047  }
1048  libsumo::Vehicle::setRoutingMode(id, routingMode);
1049  }
1050  break;
1051  case libsumo::VAR_COLOR: {
1052  libsumo::TraCIColor col;
1053  if (!server.readTypeCheckingColor(inputStorage, col)) {
1054  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The color must be given using the according type.", outputStorage);
1055  }
1056  libsumo::Vehicle::setColor(id, col);
1057  break;
1058  }
1059  case libsumo::ADD: {
1060  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1061  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle requires a compound object.", outputStorage);
1062  }
1063  if (inputStorage.readInt() != 6) {
1064  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle needs six parameters.", outputStorage);
1065  }
1066  std::string vTypeID;
1067  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
1068  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "First parameter (type) requires a string.", outputStorage);
1069  }
1070  std::string routeID;
1071  if (!server.readTypeCheckingString(inputStorage, routeID)) {
1072  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Second parameter (route) requires a string.", outputStorage);
1073  }
1074  int departCode;
1075  if (!server.readTypeCheckingInt(inputStorage, departCode)) {
1076  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Third parameter (depart) requires an integer.", outputStorage);
1077  }
1078  std::string depart = toString(STEPS2TIME(departCode));
1079  if (-departCode == static_cast<int>(DepartDefinition::TRIGGERED)) {
1080  depart = "triggered";
1081  } else if (-departCode == static_cast<int>(DepartDefinition::CONTAINER_TRIGGERED)) {
1082  depart = "containerTriggered";
1083  } else if (-departCode == static_cast<int>(DepartDefinition::NOW)) {
1084  depart = "now";
1085  } else if (-departCode == static_cast<int>(DepartDefinition::SPLIT)) {
1086  depart = "split";
1087  } else if (-departCode == static_cast<int>(DepartDefinition::BEGIN)) {
1088  depart = "begin";
1089  }
1090 
1091  double departPosCode;
1092  if (!server.readTypeCheckingDouble(inputStorage, departPosCode)) {
1093  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fourth parameter (position) requires a double.", outputStorage);
1094  }
1095  std::string departPos = toString(departPosCode);
1096  if (-departPosCode == (int)DepartPosDefinition::RANDOM) {
1097  departPos = "random";
1098  } else if (-departPosCode == (int)DepartPosDefinition::RANDOM_FREE) {
1099  departPos = "random_free";
1100  } else if (-departPosCode == (int)DepartPosDefinition::FREE) {
1101  departPos = "free";
1102  } else if (-departPosCode == (int)DepartPosDefinition::BASE) {
1103  departPos = "base";
1104  } else if (-departPosCode == (int)DepartPosDefinition::LAST) {
1105  departPos = "last";
1106  } else if (-departPosCode == (int)DepartPosDefinition::GIVEN) {
1107  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid departure position.", outputStorage);
1108  }
1109 
1110  double departSpeedCode;
1111  if (!server.readTypeCheckingDouble(inputStorage, departSpeedCode)) {
1112  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fifth parameter (speed) requires a double.", outputStorage);
1113  }
1114  std::string departSpeed = toString(departSpeedCode);
1115  if (-departSpeedCode == (int)DepartSpeedDefinition::RANDOM) {
1116  departSpeed = "random";
1117  } else if (-departSpeedCode == (int)DepartSpeedDefinition::MAX) {
1118  departSpeed = "max";
1119  } else if (-departSpeedCode == (int)DepartSpeedDefinition::DESIRED) {
1120  departSpeed = "desired";
1121  } else if (-departSpeedCode == (int)DepartSpeedDefinition::LIMIT) {
1122  departSpeed = "speedLimit";
1123  } else if (-departSpeedCode == (int)DepartSpeedDefinition::LAST) {
1124  departSpeed = "last";
1125  } else if (-departSpeedCode == (int)DepartSpeedDefinition::AVG) {
1126  departSpeed = "avg";
1127  }
1128 
1129  int departLaneCode;
1130  if (!server.readTypeCheckingByte(inputStorage, departLaneCode)) {
1131  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Sixth parameter (lane) requires a byte.", outputStorage);
1132  }
1133  std::string departLane = toString(departLaneCode);
1134  if (-departLaneCode == (int)DepartLaneDefinition::RANDOM) {
1135  departLane = "random";
1136  } else if (-departLaneCode == (int)DepartLaneDefinition::FREE) {
1137  departLane = "free";
1138  } else if (-departLaneCode == (int)DepartLaneDefinition::ALLOWED_FREE) {
1139  departLane = "allowed";
1140  } else if (-departLaneCode == (int)DepartLaneDefinition::BEST_FREE) {
1141  departLane = "best";
1142  } else if (-departLaneCode == (int)DepartLaneDefinition::FIRST_ALLOWED) {
1143  departLane = "first";
1144  }
1145  libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed);
1146  }
1147  break;
1148  case libsumo::ADD_FULL: {
1149  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1150  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle requires a compound object.", outputStorage);
1151  }
1152  if (inputStorage.readInt() != 14) {
1153  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a fully specified vehicle needs fourteen parameters.", outputStorage);
1154  }
1155  std::string routeID;
1156  if (!server.readTypeCheckingString(inputStorage, routeID)) {
1157  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Second parameter (route) requires a string.", outputStorage);
1158  }
1159  std::string vTypeID;
1160  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
1161  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "First parameter (type) requires a string.", outputStorage);
1162  }
1163  std::string depart;
1164  if (!server.readTypeCheckingString(inputStorage, depart)) {
1165  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Third parameter (depart) requires an string.", outputStorage);
1166  }
1167  std::string departLane;
1168  if (!server.readTypeCheckingString(inputStorage, departLane)) {
1169  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fourth parameter (depart lane) requires a string.", outputStorage);
1170  }
1171  std::string departPos;
1172  if (!server.readTypeCheckingString(inputStorage, departPos)) {
1173  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fifth parameter (depart position) requires a string.", outputStorage);
1174  }
1175  std::string departSpeed;
1176  if (!server.readTypeCheckingString(inputStorage, departSpeed)) {
1177  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Sixth parameter (depart speed) requires a string.", outputStorage);
1178  }
1179  std::string arrivalLane;
1180  if (!server.readTypeCheckingString(inputStorage, arrivalLane)) {
1181  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Seventh parameter (arrival lane) requires a string.", outputStorage);
1182  }
1183  std::string arrivalPos;
1184  if (!server.readTypeCheckingString(inputStorage, arrivalPos)) {
1185  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Eighth parameter (arrival position) requires a string.", outputStorage);
1186  }
1187  std::string arrivalSpeed;
1188  if (!server.readTypeCheckingString(inputStorage, arrivalSpeed)) {
1189  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Ninth parameter (arrival speed) requires a string.", outputStorage);
1190  }
1191  std::string fromTaz;
1192  if (!server.readTypeCheckingString(inputStorage, fromTaz)) {
1193  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Tenth parameter (from taz) requires a string.", outputStorage);
1194  }
1195  std::string toTaz;
1196  if (!server.readTypeCheckingString(inputStorage, toTaz)) {
1197  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Eleventh parameter (to taz) requires a string.", outputStorage);
1198  }
1199  std::string line;
1200  if (!server.readTypeCheckingString(inputStorage, line)) {
1201  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Twelth parameter (line) requires a string.", outputStorage);
1202  }
1203  int personCapacity;
1204  if (!server.readTypeCheckingInt(inputStorage, personCapacity)) {
1205  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "13th parameter (person capacity) requires an int.", outputStorage);
1206  }
1207  int personNumber;
1208  if (!server.readTypeCheckingInt(inputStorage, personNumber)) {
1209  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "14th parameter (person number) requires an int.", outputStorage);
1210  }
1211  libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed, arrivalLane, arrivalPos, arrivalSpeed,
1212  fromTaz, toTaz, line, personCapacity, personNumber);
1213  }
1214  break;
1215  case libsumo::REMOVE: {
1216  int why = 0;
1217  if (!server.readTypeCheckingByte(inputStorage, why)) {
1218  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Removing a vehicle requires a byte.", outputStorage);
1219  }
1220  libsumo::Vehicle::remove(id, (char)why);
1221  }
1222  break;
1223  case libsumo::MOVE_TO_XY: {
1224  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1225  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "MoveToXY vehicle requires a compound object.", outputStorage);
1226  }
1227  const int numArgs = inputStorage.readInt();
1228  if (numArgs < 5 || numArgs > 7) {
1229  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "MoveToXY vehicle should obtain: edgeID, lane, x, y, angle and optionally keepRouteFlag and matchThreshold.", outputStorage);
1230  }
1231  // edge ID
1232  std::string edgeID;
1233  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
1234  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first parameter for moveToXY must be the edge ID given as a string.", outputStorage);
1235  }
1236  // lane index
1237  int laneNum = 0;
1238  if (!server.readTypeCheckingInt(inputStorage, laneNum)) {
1239  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second parameter for moveToXY must be lane given as an int.", outputStorage);
1240  }
1241  // x
1242  double x = 0;
1243  if (!server.readTypeCheckingDouble(inputStorage, x)) {
1244  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third parameter for moveToXY must be the x-position given as a double.", outputStorage);
1245  }
1246  // y
1247  double y = 0;
1248  if (!server.readTypeCheckingDouble(inputStorage, y)) {
1249  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth parameter for moveToXY must be the y-position given as a double.", outputStorage);
1250  }
1251  // angle
1252  double angle = 0;
1253  if (!server.readTypeCheckingDouble(inputStorage, angle)) {
1254  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth parameter for moveToXY must be the angle given as a double.", outputStorage);
1255  }
1256 
1257  int keepRouteFlag = 1;
1258  if (numArgs >= 6) {
1259  if (!server.readTypeCheckingByte(inputStorage, keepRouteFlag)) {
1260  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The sixth parameter for moveToXY must be the keepRouteFlag given as a byte.", outputStorage);
1261  }
1262  }
1263  double matchThreshold = 100;
1264  if (numArgs == 7) {
1265  if (!server.readTypeCheckingDouble(inputStorage, matchThreshold)) {
1266  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The seventh parameter for moveToXY must be the matchThreshold given as a double.", outputStorage);
1267  }
1268  }
1269  libsumo::Vehicle::moveToXY(id, edgeID, laneNum, x, y, angle, keepRouteFlag, matchThreshold);
1270  }
1271  break;
1273  double factor = 0;
1274  if (!server.readTypeCheckingDouble(inputStorage, factor)) {
1275  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting speed factor requires a double.", outputStorage);
1276  }
1277  libsumo::Vehicle::setSpeedFactor(id, factor);
1278  }
1279  break;
1280  case libsumo::VAR_LINE: {
1281  std::string line;
1282  if (!server.readTypeCheckingString(inputStorage, line)) {
1283  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The line must be given as a string.", outputStorage);
1284  }
1285  libsumo::Vehicle::setLine(id, line);
1286  }
1287  break;
1288  case libsumo::VAR_VIA: {
1289  std::vector<std::string> edgeIDs;
1290  if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {
1291  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Vias must be defined as a list of edge ids.", outputStorage);
1292  }
1293  libsumo::Vehicle::setVia(id, edgeIDs);
1294  }
1295  break;
1296  case libsumo::VAR_PARAMETER: {
1297  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1298  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
1299  }
1300  //readt itemNo
1301  inputStorage.readInt();
1302  std::string name;
1303  if (!server.readTypeCheckingString(inputStorage, name)) {
1304  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);
1305  }
1306  std::string value;
1307  if (!server.readTypeCheckingString(inputStorage, value)) {
1308  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
1309  }
1310  try {
1312  libsumo::Vehicle::setParameter(id, name, value);
1313  } catch (libsumo::TraCIException& e) {
1314  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1315  }
1316  }
1317  break;
1318  case libsumo::VAR_HIGHLIGHT: {
1319  // Highlight the vehicle by adding a tracking polygon. (NOTE: duplicated code exists for POI domain)
1320  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1321  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A compound object is needed for highlighting an object.", outputStorage);
1322  }
1323  const int itemNo = inputStorage.readInt();
1324  if (itemNo > 5) {
1325  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Highlighting an object needs zero to five parameters.", outputStorage);
1326  }
1327  libsumo::TraCIColor col = libsumo::TraCIColor(255, 0, 0);
1328  if (itemNo > 0) {
1329  if (!server.readTypeCheckingColor(inputStorage, col)) {
1330  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first parameter for highlighting must be the highlight color.", outputStorage);
1331  }
1332  }
1333  double size = -1;
1334  if (itemNo > 1) {
1335  if (!server.readTypeCheckingDouble(inputStorage, size)) {
1336  return server.writeErrorStatusCmd(libsumo::CMD_SET_POI_VARIABLE, "The second parameter for highlighting must be the highlight size.", outputStorage);
1337  }
1338  }
1339  int alphaMax = -1;
1340  if (itemNo > 2) {
1341  if (!server.readTypeCheckingUnsignedByte(inputStorage, alphaMax)) {
1342  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third parameter for highlighting must be maximal alpha.", outputStorage);
1343  }
1344  }
1345  double duration = -1;
1346  if (itemNo > 3) {
1347  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
1348  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth parameter for highlighting must be the highlight duration.", outputStorage);
1349  }
1350  }
1351  int type = 0;
1352  if (itemNo > 4) {
1353  if (!server.readTypeCheckingUnsignedByte(inputStorage, type)) {
1354  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth parameter for highlighting must be the highlight type id as ubyte.", outputStorage);
1355  }
1356  }
1357  libsumo::Vehicle::highlight(id, col, size, alphaMax, duration, type);
1358  }
1359  break;
1361  std::vector<std::string> reservations;
1362  if (!server.readTypeCheckingStringList(inputStorage, reservations)) {
1363  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A dispatch command must be defined as a list of reservation ids.", outputStorage);
1364  }
1365  libsumo::Vehicle::dispatchTaxi(id, reservations);
1366  }
1367  break;
1369  double value = 0;
1370  if (!server.readTypeCheckingDouble(inputStorage, value)) {
1371  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting action step length requires a double.", outputStorage);
1372  }
1373  if (fabs(value) == std::numeric_limits<double>::infinity()) {
1374  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid action step length.", outputStorage);
1375  }
1376  bool resetActionOffset = value >= 0.0;
1377  libsumo::Vehicle::setActionStepLength(id, fabs(value), resetActionOffset);
1378  }
1379  break;
1381  double value = 0;
1382  if (!server.readTypeCheckingDouble(inputStorage, value)) {
1383  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting lateral lane position requires a double.", outputStorage);
1384  }
1385  libsumo::Vehicle::setLateralLanePosition(id, value);
1386  }
1387  break;
1389  libsumo::Vehicle::updateBestLanes(id);
1390  }
1391  break;
1392  case libsumo::VAR_MINGAP: {
1393  double value = 0;
1394  if (!server.readTypeCheckingDouble(inputStorage, value)) {
1395  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting minimum gap requires a double.", outputStorage);
1396  }
1397  if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
1398  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum gap.", outputStorage);
1399  }
1400  libsumo::Vehicle::setMinGap(id, value);
1401  }
1402  break;
1403  case libsumo::VAR_MINGAP_LAT: {
1404  double value = 0;
1405  if (!server.readTypeCheckingDouble(inputStorage, value)) {
1406  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting minimum lateral gap requires a double.", outputStorage);
1407  }
1408  if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
1409  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum lateral gap.", outputStorage);
1410  }
1411  libsumo::Vehicle::setMinGapLat(id, value);
1412  }
1413  break;
1414  default: {
1415  try {
1416  if (!TraCIServerAPI_VehicleType::setVariable(libsumo::CMD_SET_VEHICLE_VARIABLE, variable, v->getSingularType().getID(), server, inputStorage, outputStorage)) {
1417  return false;
1418  }
1419  } catch (ProcessError& e) {
1420  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1421  } catch (libsumo::TraCIException& e) {
1422  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1423  }
1424  }
1425  break;
1426  }
1427  } catch (libsumo::TraCIException& e) {
1428  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1429  }
1430  server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);
1431  return true;
1432 }
1433 
1434 
1435 void
1436 TraCIServerAPI_Vehicle::writeNextStops(TraCIServer& server, const std::string& id, int limit, bool full) {
1437  std::vector<libsumo::TraCINextStopData> nextStops = libsumo::Vehicle::getStops(id, limit);
1439  const int cnt = 1 + (int)nextStops.size() * 4;
1440  server.getWrapperStorage().writeInt(cnt);
1442  server.getWrapperStorage().writeInt((int)nextStops.size());
1443  for (std::vector<libsumo::TraCINextStopData>::iterator it = nextStops.begin(); it != nextStops.end(); ++it) {
1444  int legacyStopFlags = (it->stopFlags << 1) + (it->arrival >= 0 ? 1 : 0);
1446  server.getWrapperStorage().writeString(it->lane);
1448  server.getWrapperStorage().writeDouble(it->endPos);
1450  server.getWrapperStorage().writeString(it->stoppingPlaceID);
1452  server.getWrapperStorage().writeInt(full ? it->stopFlags : legacyStopFlags);
1454  server.getWrapperStorage().writeDouble(it->duration);
1456  server.getWrapperStorage().writeDouble(it->until);
1457  if (full) {
1459  server.getWrapperStorage().writeDouble(it->startPos);
1461  server.getWrapperStorage().writeDouble(it->intendedArrival);
1463  server.getWrapperStorage().writeDouble(it->arrival);
1465  server.getWrapperStorage().writeDouble(it->depart);
1467  server.getWrapperStorage().writeString(it->split);
1469  server.getWrapperStorage().writeString(it->join);
1471  server.getWrapperStorage().writeString(it->actType);
1473  server.getWrapperStorage().writeString(it->tripId);
1475  server.getWrapperStorage().writeString(it->line);
1477  server.getWrapperStorage().writeDouble(it->speed);
1478  }
1479  }
1480 }
1481 
1482 bool
1483 TraCIServerAPI_Vehicle::insertReplaceStop(TraCIServer& server, tcpip::Storage& inputStorage, tcpip::Storage& outputStorage, const std::string& id, bool replace) {
1484  const std::string m1 = replace ? "Replacing" : "Inserting";
1485  const std::string m2 = replace ? "replacement" : "insertion";
1486 
1487  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1488  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, m1 + " stop needs a compound object description.", outputStorage);
1489  }
1490  int compoundSize = inputStorage.readInt();
1491  if (compoundSize != 8 && compoundSize != 9) {
1492  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, m1 + " stop needs a compound object description of eight or nine items.", outputStorage);
1493  }
1494  // read road map position
1495  std::string edgeID;
1496  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
1497  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first stop " + m2 + " parameter must be the edge id given as a string.", outputStorage);
1498  }
1499  double pos = 0;
1500  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
1501  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);
1502  }
1503  int laneIndex = 0;
1504  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
1505  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third stop " + m2 + " parameter must be the lane index given as a byte.", outputStorage);
1506  }
1507  // waitTime
1508  double duration = libsumo::INVALID_DOUBLE_VALUE;
1509  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
1510  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "The fourth stop " + m2 + " parameter must be the stopping duration given as a double.", outputStorage);
1511  }
1512  int stopFlags = 0;
1513  if (!server.readTypeCheckingInt(inputStorage, stopFlags)) {
1514  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth stop " + m2 + " parameter must be a int indicating its parking/triggered status.", outputStorage);
1515  }
1516  double startPos = libsumo::INVALID_DOUBLE_VALUE;
1517  if (!server.readTypeCheckingDouble(inputStorage, startPos)) {
1518  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);
1519  }
1520  double until = libsumo::INVALID_DOUBLE_VALUE;
1521  if (!server.readTypeCheckingDouble(inputStorage, until)) {
1522  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The seventh stop " + m2 + " parameter must be the minimum departure time given as a double.", outputStorage);
1523  }
1524  int nextStopIndex = 0;
1525  if (!server.readTypeCheckingInt(inputStorage, nextStopIndex)) {
1526  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The eigth stop " + m2 + " parameter must be the replacement index given as a int.", outputStorage);
1527  }
1528  int teleport = 0;
1529  if (compoundSize == 9) {
1530  if (!server.readTypeCheckingByte(inputStorage, teleport)) {
1531  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The nineth stop " + m2 + " parameter must be the teleport flag given as a byte.", outputStorage);
1532  }
1533  }
1534  if (replace) {
1535  libsumo::Vehicle::replaceStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
1536  } else {
1537  libsumo::Vehicle::insertStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
1538  }
1539  return true;
1540 }
1541 /****************************************************************************/
SUMOTime DELTA_T
Definition: SUMOTime.cpp:38
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
#define SUMOTime_MAX
Definition: SUMOTime.h:34
#define SIMTIME
Definition: SUMOTime.h:62
@ RANDOM
The lane is chosen randomly.
@ BEST_FREE
The least occupied lane from best lanes.
@ ALLOWED_FREE
The least occupied lane from lanes which allow the continuation.
@ FIRST_ALLOWED
The rightmost lane the vehicle may use.
@ FREE
The least occupied lane is used.
@ RANDOM
A random position is chosen.
@ GIVEN
The position is given.
@ FREE
A free position is chosen.
@ BASE
Back-at-zero position.
@ LAST
Insert behind the last vehicle as close as possible to still allow the specified departSpeed....
@ RANDOM_FREE
If a fixed number of random choices fails, a free position is chosen.
@ RANDOM
The speed is chosen randomly.
@ MAX
The maximum safe speed is used.
@ LIMIT
The maximum lane speed is used (speedLimit)
@ DESIRED
The maximum lane speed is used (speedLimit * speedFactor)
@ LAST
The speed of the last vehicle. Fallback to DepartSpeedDefinition::DESIRED if there is no vehicle on t...
@ AVG
The average speed on the lane. Fallback to DepartSpeedDefinition::DESIRED if there is no vehicle on t...
@ BEGIN
The departure is at simulation start.
@ NOW
The vehicle is discarded if emission fails (not fully implemented yet)
@ SPLIT
The departure is triggered by a train split.
@ CONTAINER_TRIGGERED
The departure is container triggered.
@ TRIGGERED
The departure is person triggered.
std::string toHex(const T i, std::streamsize numDigits=0)
Definition: ToString.h:56
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:57
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:184
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:378
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:91
const std::string & getID() const
Returns the id.
Definition: Named.h:74
Representation of a vehicle.
Definition: SUMOVehicle.h:62
static void writeNextStops(TraCIServer &server, const std::string &id, int limit, bool full)
helper function to write the response for VAR_NEXT_STOPS and VAR_NEXT_STOPS2
static bool insertReplaceStop(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage, const std::string &id, bool replace)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc4: Change Vehicle State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa4: Get Vehicle Variable)
static bool setVariable(const int cmd, const int variable, const std::string &id, TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value for the given type.
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:59
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
bool readTypeCheckingByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and a byte, verifying the type.
tcpip::Storage & getWrapperStorage()
bool readTypeCheckingUnsignedByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and an unsigned byte, verifying the type.
void initWrapper(const int domainID, const int variable, const std::string &objID)
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
bool readTypeCheckingInt(tcpip::Storage &inputStorage, int &into)
Reads the value type and an int, verifying the type.
bool readTypeCheckingStringList(tcpip::Storage &inputStorage, std::vector< std::string > &into)
Reads the value type and a string list, verifying the type.
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
bool readTypeCheckingColor(tcpip::Storage &inputStorage, libsumo::TraCIColor &into)
Reads the value type and a color, verifying the type.
An error which allows to continue.
Definition: TraCIDefs.h:144
virtual std::string readString()
Definition: storage.cpp:180
virtual void writeString(const std::string &s)
Definition: storage.cpp:197
virtual void writeInt(int)
Definition: storage.cpp:321
virtual void writeDouble(double)
Definition: storage.cpp:354
virtual int readUnsignedByte()
Definition: storage.cpp:155
virtual void writeStringList(const std::vector< std::string > &s)
Definition: storage.cpp:247
virtual void writeChar(unsigned char)
Definition: storage.cpp:116
virtual void writeUnsignedByte(int)
Definition: storage.cpp:165
virtual void writeByte(int)
Definition: storage.cpp:140
virtual void writeStorage(tcpip::Storage &store)
Definition: storage.cpp:388
virtual double readDouble()
Definition: storage.cpp:362
virtual int readInt()
Definition: storage.cpp:311
TRACI_CONST double INVALID_DOUBLE_VALUE
TRACI_CONST int POSITION_3D
TRACI_CONST int POSITION_ROADMAP
TRACI_CONST int VAR_LANECHANGE_MODE
TRACI_CONST int MOVE_AUTOMATIC
TRACI_CONST int VAR_VEHICLECLASS
TRACI_CONST int VAR_IMPATIENCE
TRACI_CONST int VAR_LATALIGNMENT
TRACI_CONST int VAR_TYPE
TRACI_CONST int CMD_CHANGESUBLANE
TRACI_CONST int VAR_ROUTING_MODE
TRACI_CONST int VAR_MINGAP
TRACI_CONST int CMD_TAXI_DISPATCH
TRACI_CONST int VAR_SECURE_GAP
TRACI_CONST int VAR_SHAPECLASS
TRACI_CONST int CMD_STOP
TRACI_CONST int VAR_LINE
TRACI_CONST int VAR_EDGE_TRAVELTIME
TRACI_CONST int CMD_GET_VEHICLE_VARIABLE
TRACI_CONST int CMD_RESUME
TRACI_CONST int VAR_ACTIONSTEPLENGTH
TRACI_CONST int VAR_SPEED_FACTOR
TRACI_CONST int MOVE_TO_XY
TRACI_CONST int VAR_FOLLOW_SPEED
TRACI_CONST int VAR_TAU
TRACI_CONST int TYPE_COMPOUND
TRACI_CONST int VAR_NEXT_TLS
TRACI_CONST int VAR_EDGE_EFFORT
TRACI_CONST int VAR_ROUTE
TRACI_CONST int VAR_BEST_LANES
TRACI_CONST int VAR_HIGHLIGHT
TRACI_CONST int VAR_BOARDING_DURATION
TRACI_CONST int TYPE_UBYTE
TRACI_CONST int CMD_SET_POI_VARIABLE
TRACI_CONST int VAR_MOVE_TO
TRACI_CONST int VAR_UPDATE_BESTLANES
TRACI_CONST int VAR_COLOR
TRACI_CONST int VAR_WIDTH
TRACI_CONST int VAR_STOP_PARAMETER
TRACI_CONST int POSITION_2D
TRACI_CONST int VAR_MAXSPEED
TRACI_CONST int CMD_CHANGETARGET
TRACI_CONST int ADD_FULL
TRACI_CONST int CMD_REROUTE_TO_PARKING
TRACI_CONST int RESPONSE_GET_VEHICLE_VARIABLE
TRACI_CONST int CMD_REROUTE_TRAVELTIME
TRACI_CONST int TYPE_STRINGLIST
TRACI_CONST int VAR_TAXI_FLEET
TRACI_CONST int TYPE_INTEGER
TRACI_CONST int VAR_PREV_SPEED
TRACI_CONST int VAR_SPEEDSETMODE
TRACI_CONST int CMD_REPLACE_STOP
TRACI_CONST int VAR_MASS
TRACI_CONST int CMD_SET_VEHICLE_VARIABLE
TRACI_CONST int VAR_LENGTH
TRACI_CONST int VAR_MAXSPEED_LAT
TRACI_CONST int CMD_REROUTE_EFFORT
TRACI_CONST int VAR_PARAMETER
TRACI_CONST int REMOVE
TRACI_CONST int CMD_INSERT_STOP
TRACI_CONST int VAR_STOP_SPEED
TRACI_CONST int VAR_IMPERFECTION
TRACI_CONST int VAR_HEIGHT
TRACI_CONST int VAR_APPARENT_DECEL
TRACI_CONST int REQUEST_DRIVINGDIST
TRACI_CONST int VAR_SPEED
TRACI_CONST int VAR_DECEL
TRACI_CONST int VAR_SIGNALS
TRACI_CONST int VAR_MINGAP_LAT
TRACI_CONST int VAR_NEXT_LINKS
TRACI_CONST int VAR_NEXT_STOPS2
TRACI_CONST int CMD_SLOWDOWN
TRACI_CONST int VAR_ACCELERATION
TRACI_CONST int VAR_ROUTE_ID
TRACI_CONST int TYPE_DOUBLE
TRACI_CONST int DISTANCE_REQUEST
TRACI_CONST int TYPE_BYTE
TRACI_CONST int CMD_OPENGAP
TRACI_CONST int VAR_LANEPOSITION_LAT
TRACI_CONST int CMD_CHANGELANE
TRACI_CONST int RTYPE_ERR
TRACI_CONST int VAR_NEIGHBORS
TRACI_CONST int VAR_EMERGENCY_DECEL
TRACI_CONST int RTYPE_OK
TRACI_CONST int VAR_EMISSIONCLASS
TRACI_CONST int VAR_ACCEL
TRACI_CONST int ADD
TRACI_CONST int VAR_FOES
TRACI_CONST int VAR_VIA
TRACI_CONST int TYPE_STRING
TRACI_CONST int VAR_NEXT_STOPS
double length
The length than can be driven from that lane without lane change.
Definition: TraCIDefs.h:544
double occupation
The traffic density along length.
Definition: TraCIDefs.h:546
bool allowsContinuation
Whether this lane allows continuing the route.
Definition: TraCIDefs.h:550
int bestLaneOffset
The offset of this lane from the best lane.
Definition: TraCIDefs.h:548
std::vector< std::string > continuationLanes
The sequence of lanes that best allows continuing the route without lane change.
Definition: TraCIDefs.h:552
std::string laneID
The id of the lane.
Definition: TraCIDefs.h:542