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_ROUTING_MODE
498  && variable != libsumo::VAR_LATALIGNMENT
499  && variable != libsumo::VAR_MAXSPEED_LAT
500  && variable != libsumo::VAR_MINGAP_LAT
501  && variable != libsumo::VAR_LINE
502  && variable != libsumo::VAR_VIA
503  && variable != libsumo::VAR_IMPATIENCE
504  && variable != libsumo::VAR_BOARDING_DURATION
505  && variable != libsumo::VAR_HIGHLIGHT
506  && variable != libsumo::CMD_TAXI_DISPATCH
507  && variable != libsumo::MOVE_TO_XY && variable != libsumo::VAR_PARAMETER/* && variable != libsumo::VAR_SPEED_TIME_LINE && variable != libsumo::VAR_LANE_TIME_LINE*/
508  ) {
509  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Change Vehicle State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
510  }
511  // id
512  std::string id = inputStorage.readString();
513 #ifdef DEBUG_MOVEXY
514  std::cout << SIMTIME << " processSet veh=" << id << "\n";
515 #endif
516  const bool shouldExist = variable != libsumo::ADD && variable != libsumo::ADD_FULL;
518  if (sumoVehicle == nullptr) {
519  if (shouldExist) {
520  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
521  }
522  }
523  MSBaseVehicle* v = dynamic_cast<MSBaseVehicle*>(sumoVehicle);
524  if (v == nullptr && shouldExist) {
525  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a proper vehicle", outputStorage);
526  }
527  try {
528  switch (variable) {
529  case libsumo::CMD_STOP: {
530  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
531  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description.", outputStorage);
532  }
533  int compoundSize = inputStorage.readInt();
534  if (compoundSize < 4 || compoundSize > 7) {
535  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description of four to seven items.", outputStorage);
536  }
537  // read road map position
538  std::string edgeID;
539  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
540  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first stop parameter must be the edge id given as a string.", outputStorage);
541  }
542  double pos = 0;
543  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
544  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);
545  }
546  int laneIndex = 0;
547  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
548  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third stop parameter must be the lane index given as a byte.", outputStorage);
549  }
550  // waitTime
551  double duration = libsumo::INVALID_DOUBLE_VALUE;
552  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
553  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "The fourth stop parameter must be the stopping duration given as a double.", outputStorage);
554  }
555  int stopFlags = 0;
556  if (compoundSize >= 5) {
557  if (!server.readTypeCheckingByte(inputStorage, stopFlags)) {
558  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth stop parameter must be a byte indicating its parking/triggered status.", outputStorage);
559  }
560  }
561  double startPos = libsumo::INVALID_DOUBLE_VALUE;
562  if (compoundSize >= 6) {
563  if (!server.readTypeCheckingDouble(inputStorage, startPos)) {
564  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);
565  }
566  }
567  double until = libsumo::INVALID_DOUBLE_VALUE;
568  if (compoundSize >= 7) {
569  if (!server.readTypeCheckingDouble(inputStorage, until)) {
570  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The seventh stop parameter must be the minimum departure time given as a double.", outputStorage);
571  }
572  }
573  libsumo::Vehicle::setStop(id, edgeID, pos, laneIndex, duration, stopFlags, startPos, until);
574  }
575  break;
577  if (!insertReplaceStop(server, inputStorage, outputStorage, id, true)) {
578  return false;
579  }
580  break;
582  if (!insertReplaceStop(server, inputStorage, outputStorage, id, false)) {
583  return false;
584  }
585  break;
587  // read variables
588  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
589  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting stop parameter needs a compound object description.", outputStorage);
590  }
591  int compoundSize = inputStorage.readInt();
592  if (compoundSize != 3 && compoundSize != 4) {
593  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting a stop parameter needs a compound object description of 3 or 4 items.", outputStorage);
594  }
595  int nextStopIndex;
596  if (!server.readTypeCheckingInt(inputStorage, nextStopIndex)) {
597  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first setStopParameter parameter must be the nextStopIndex given as an integer.", outputStorage);
598  }
599  std::string param;
600  if (!server.readTypeCheckingString(inputStorage, param)) {
601  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second setStopParameter parameter must be the param given as a string.", outputStorage);
602  }
603  std::string value;
604  if (!server.readTypeCheckingString(inputStorage, value)) {
605  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third setStopParameter parameter must be the value given as a string.", outputStorage);
606  }
607  int customParam = 0;
608  if (compoundSize == 4) {
609  if (!server.readTypeCheckingByte(inputStorage, customParam)) {
610  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth setStopParameter parameter must be the customParam flag given as a byte.", outputStorage);
611  }
612  }
613  libsumo::Vehicle::setStopParameter(id, nextStopIndex, param, value, customParam != 0);
614  }
615  break;
617  // read variables
618  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
619  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Reroute to stop needs a compound object description.", outputStorage);
620  }
621  int compoundSize = inputStorage.readInt();
622  if (compoundSize != 1) {
623  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Reroute to stop needs a compound object description of 1 item.", outputStorage);
624  }
625  std::string parkingAreaID;
626  if (!server.readTypeCheckingString(inputStorage, parkingAreaID)) {
627  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);
628  }
629  libsumo::Vehicle::rerouteParkingArea(id, parkingAreaID);
630  }
631  break;
632  case libsumo::CMD_RESUME: {
633  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
634  server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_ERR, "Resuming requires a compound object.", outputStorage);
635  return false;
636  }
637  if (inputStorage.readInt() != 0) {
638  server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_ERR, "Resuming should obtain an empty compound object.", outputStorage);
639  return false;
640  }
641  libsumo::Vehicle::resume(id);
642  }
643  break;
645  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
646  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description.", outputStorage);
647  }
648  int compounds = inputStorage.readInt();
649  if (compounds != 3 && compounds != 2) {
650  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two or three items.", outputStorage);
651  }
652  // Lane ID
653  int laneIndex = 0;
654  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
655  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first lane change parameter must be the lane index given as a byte.", outputStorage);
656  }
657  // duration
658  double duration = 0.;
659  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
660  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second lane change parameter must be the duration given as a double.", outputStorage);
661  }
662  // relativelanechange
663  int relative = 0;
664  if (compounds == 3) {
665  if (!server.readTypeCheckingByte(inputStorage, relative)) {
666  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);
667  }
668  }
669 
670  if ((laneIndex < 0 || laneIndex >= (int)v->getEdge()->getLanes().size()) && relative < 1) {
671  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + v->getEdge()->getID() + "'.", outputStorage);
672  }
673 
674  if (relative < 1) {
675  libsumo::Vehicle::changeLane(id, laneIndex, duration);
676  } else {
677  libsumo::Vehicle::changeLaneRelative(id, laneIndex, duration);
678  }
679  }
680  break;
682  double latDist = 0;
683  if (!server.readTypeCheckingDouble(inputStorage, latDist)) {
684  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Sublane-changing requires a double.", outputStorage);
685  }
686  libsumo::Vehicle::changeSublane(id, latDist);
687  }
688  break;
689  case libsumo::CMD_SLOWDOWN: {
690  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
691  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description.", outputStorage);
692  }
693  if (inputStorage.readInt() != 2) {
694  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description of two items.", outputStorage);
695  }
696  double newSpeed = 0;
697  if (!server.readTypeCheckingDouble(inputStorage, newSpeed)) {
698  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first slow down parameter must be the speed given as a double.", outputStorage);
699  }
700  if (newSpeed < 0) {
701  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Speed must not be negative", outputStorage);
702  }
703  double duration = 0.;
704  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
705  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second slow down parameter must be the duration given as a double.", outputStorage);
706  }
707  if (duration < 0 || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
708  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval", outputStorage);
709  }
710  libsumo::Vehicle::slowDown(id, newSpeed, duration);
711  }
712  break;
714  std::string edgeID;
715  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
716  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Change target requires a string containing the id of the new destination edge as parameter.", outputStorage);
717  }
718  libsumo::Vehicle::changeTarget(id, edgeID);
719  }
720  break;
721  case libsumo::CMD_OPENGAP: {
722  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
723  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Create gap needs a compound object description.", outputStorage);
724  }
725  const int nParameter = inputStorage.readInt();
726  if (nParameter != 5 && nParameter != 6) {
727  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Create gap needs a compound object description of five or six items.", outputStorage);
728  }
729  double newTimeHeadway = 0;
730  if (!server.readTypeCheckingDouble(inputStorage, newTimeHeadway)) {
731  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);
732  }
733  double newSpaceHeadway = 0;
734  if (!server.readTypeCheckingDouble(inputStorage, newSpaceHeadway)) {
735  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);
736  }
737  double duration = 0.;
738  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
739  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third create gap parameter must be the duration given as a double.", outputStorage);
740  }
741  double changeRate = 0;
742  if (!server.readTypeCheckingDouble(inputStorage, changeRate)) {
743  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth create gap parameter must be the change rate given as a double.", outputStorage);
744  }
745  double maxDecel = 0;
746  if (!server.readTypeCheckingDouble(inputStorage, maxDecel)) {
747  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth create gap parameter must be the maximal braking rate given as a double.", outputStorage);
748  }
749 
750  if (newTimeHeadway == -1 && newSpaceHeadway == -1 && duration == -1 && changeRate == -1 && maxDecel == -1) {
751  libsumo::Vehicle::deactivateGapControl(id);
752  } else {
753  if (newTimeHeadway <= 0) {
754  if (newTimeHeadway != -1) {
755  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired time headway (tau) must be positive for create gap", outputStorage);
756  } // else if == -1: keep vehicles current headway, see libsumo::Vehicle::openGap
757  }
758  if (newSpaceHeadway < 0) {
759  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the new desired space headway must be non-negative for create gap", outputStorage);
760  }
761  if ((duration < 0 && duration != -1) || SIMTIME + duration > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
762  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid time interval for create gap", outputStorage);
763  }
764  if (changeRate <= 0) {
765  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the change rate must be positive for the openGap command", outputStorage);
766  }
767  if (maxDecel <= 0 && maxDecel != -1 && maxDecel != libsumo::INVALID_DOUBLE_VALUE) {
768  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value for the maximal braking rate must be positive for the openGap command", outputStorage);
769  } // else if <= 0: don't limit cf model's suggested brake rate, see libsumo::Vehicle::openGap
770  std::string refVehID = "";
771  if (nParameter == 6) {
772  if (!server.readTypeCheckingString(inputStorage, refVehID)) {
773  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);
774  }
775  }
776  libsumo::Vehicle::openGap(id, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel, refVehID);
777  }
778  }
779  break;
780  case libsumo::VAR_TYPE: {
781  std::string vTypeID;
782  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
783  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The vehicle type id must be given as a string.", outputStorage);
784  }
785  libsumo::Vehicle::setType(id, vTypeID);
786  }
787  break;
788  case libsumo::VAR_ROUTE_ID: {
789  std::string rid;
790  if (!server.readTypeCheckingString(inputStorage, rid)) {
791  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The route id must be given as a string.", outputStorage);
792  }
793  libsumo::Vehicle::setRouteID(id, rid);
794  }
795  break;
796  case libsumo::VAR_ROUTE: {
797  std::vector<std::string> edgeIDs;
798  if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {
799  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A route must be defined as a list of edge ids.", outputStorage);
800  }
801  libsumo::Vehicle::setRoute(id, edgeIDs);
802  }
803  break;
805  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
806  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires a compound object.", outputStorage);
807  }
808  int parameterCount = inputStorage.readInt();
809  std::string edgeID;
810  double begTime = 0.;
811  double endTime = std::numeric_limits<double>::max();
812  double value = libsumo::INVALID_DOUBLE_VALUE;
813  if (parameterCount == 4) {
814  // begin time
815  if (!server.readTypeCheckingDouble(inputStorage, begTime)) {
816  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the begin time as first parameter.", outputStorage);
817  }
818  // begin time
819  if (!server.readTypeCheckingDouble(inputStorage, endTime)) {
820  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the end time as second parameter.", outputStorage);
821  }
822  // edge
823  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
824  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the referenced edge as third parameter.", outputStorage);
825  }
826  // value
827  if (!server.readTypeCheckingDouble(inputStorage, value)) {
828  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the travel time as double as fourth parameter.", outputStorage);
829  }
830  } else if (parameterCount == 2) {
831  // edge
832  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
833  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the referenced edge as first parameter.", outputStorage);
834  }
835  // value
836  if (!server.readTypeCheckingDouble(inputStorage, value)) {
837  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the travel time as second parameter.", outputStorage);
838  }
839  } else if (parameterCount == 1) {
840  // edge
841  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
842  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 1 parameter requires the referenced edge as first parameter.", outputStorage);
843  }
844  } else {
845  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);
846  }
847  libsumo::Vehicle::setAdaptedTraveltime(id, edgeID, value, begTime, endTime);
848  }
849  break;
851  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
852  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort requires a compound object.", outputStorage);
853  }
854  int parameterCount = inputStorage.readInt();
855  std::string edgeID;
856  double begTime = 0.;
857  double endTime = std::numeric_limits<double>::max();
858  double value = libsumo::INVALID_DOUBLE_VALUE;
859  if (parameterCount == 4) {
860  // begin time
861  if (!server.readTypeCheckingDouble(inputStorage, begTime)) {
862  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the begin time as first parameter.", outputStorage);
863  }
864  // begin time
865  if (!server.readTypeCheckingDouble(inputStorage, endTime)) {
866  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the end time as second parameter.", outputStorage);
867  }
868  // edge
869  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
870  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the referenced edge as third parameter.", outputStorage);
871  }
872  // value
873  if (!server.readTypeCheckingDouble(inputStorage, value)) {
874  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the travel time as fourth parameter.", outputStorage);
875  }
876  } else if (parameterCount == 2) {
877  // edge
878  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
879  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the referenced edge as first parameter.", outputStorage);
880  }
881  if (!server.readTypeCheckingDouble(inputStorage, value)) {
882  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the travel time as second parameter.", outputStorage);
883  }
884  } else if (parameterCount == 1) {
885  // edge
886  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
887  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort using 1 parameter requires the referenced edge as first parameter.", outputStorage);
888  }
889  } else {
890  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);
891  }
892  // retrieve
893  libsumo::Vehicle::setEffort(id, edgeID, value, begTime, endTime);
894  }
895  break;
897  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
898  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
899  }
900  if (inputStorage.readInt() != 0) {
901  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
902  }
903  libsumo::Vehicle::rerouteTraveltime(id, false);
904  }
905  break;
907  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
908  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
909  }
910  if (inputStorage.readInt() != 0) {
911  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
912  }
913  libsumo::Vehicle::rerouteEffort(id);
914  }
915  break;
916  case libsumo::VAR_SIGNALS: {
917  int signals = 0;
918  if (!server.readTypeCheckingInt(inputStorage, signals)) {
919  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting signals requires an integer.", outputStorage);
920  }
921  libsumo::Vehicle::setSignals(id, signals);
922  }
923  break;
924  case libsumo::VAR_MOVE_TO: {
925  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
926  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting position requires a compound object.", outputStorage);
927  }
928  const int numArgs = inputStorage.readInt();
929  if (numArgs < 2 || numArgs > 3) {
930  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting position should obtain the lane id and the position and optionally the reason.", outputStorage);
931  }
932  // lane ID
933  std::string laneID;
934  if (!server.readTypeCheckingString(inputStorage, laneID)) {
935  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);
936  }
937  // position on lane
938  double position = 0;
939  if (!server.readTypeCheckingDouble(inputStorage, position)) {
940  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second parameter for setting a position must be the position given as a double.", outputStorage);
941  }
942  int reason = libsumo::MOVE_AUTOMATIC;
943  if (numArgs == 3) {
944  if (!server.readTypeCheckingInt(inputStorage, reason)) {
945  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third parameter for setting a position must be the reason given as an int.", outputStorage);
946  }
947  }
948  // process
949  libsumo::Vehicle::moveTo(id, laneID, position, reason);
950  }
951  break;
953  double impatience = 0;
954  if (!server.readTypeCheckingDouble(inputStorage, impatience)) {
955  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting impatience requires a double.", outputStorage);
956  }
957  libsumo::Vehicle::setImpatience(id, impatience);
958  }
959  break;
960  case libsumo::VAR_SPEED: {
961  double speed = 0;
962  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
963  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting speed requires a double.", outputStorage);
964  }
965  libsumo::Vehicle::setSpeed(id, speed);
966  }
967  break;
969  double accel = 0;
970  double duration = 0;
971  int inputtype = inputStorage.readUnsignedByte();
972  if (inputtype == libsumo::TYPE_COMPOUND) {
973  int parameterCount = inputStorage.readInt();
974  if (parameterCount == 2) {
975  if (!server.readTypeCheckingDouble(inputStorage, accel)) {
976  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires the acceleration as first parameter given as a double.", outputStorage);
977  }
978  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
979  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires the duration as second parameter given as a double.", outputStorage);
980  }
981  } else {
982  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires 2 parameters.", outputStorage);
983  }
984  } else {
985  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting acceleration requires 2 parameters as compound object description.", outputStorage);
986  }
987  if (duration < 0) {
988  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Duration must not be negative.", outputStorage);
989  }
990  libsumo::Vehicle::setAcceleration(id, accel, duration);
991  }
992  break;
994  double prevSpeed = 0;
995  double prevAcceleration = libsumo::INVALID_DOUBLE_VALUE;
996  int inputtype = inputStorage.readUnsignedByte();
997  if (inputtype == libsumo::TYPE_COMPOUND) {
998  // Setting previous speed with 2 parameters, uses a compound object description
999  int parameterCount = inputStorage.readInt();
1000  if (parameterCount == 2) {
1001  if (!server.readTypeCheckingDouble(inputStorage, prevSpeed)) {
1002  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);
1003  }
1004  if (!server.readTypeCheckingDouble(inputStorage, prevAcceleration)) {
1005  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);
1006  }
1007  } else if (parameterCount == 1) {
1008  if (!server.readTypeCheckingDouble(inputStorage, prevSpeed)) {
1009  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);
1010  }
1011  } else {
1012  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting previous speed requires 1 or 2 parameters.", outputStorage);
1013  }
1014  } else if (inputtype == libsumo::TYPE_DOUBLE) {
1015  // Setting previous speed with 1 parameter (double), no compound object description
1016  prevSpeed = inputStorage.readDouble();
1017  } else {
1018  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);
1019  }
1020  if (prevSpeed < 0) {
1021  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Previous speed must not be negative.", outputStorage);
1022  }
1023  libsumo::Vehicle::setPreviousSpeed(id, prevSpeed, prevAcceleration);
1024  }
1025  break;
1027  int speedMode = 0;
1028  if (!server.readTypeCheckingInt(inputStorage, speedMode)) {
1029  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting speed mode requires an integer.", outputStorage);
1030  }
1031  libsumo::Vehicle::setSpeedMode(id, speedMode);
1032  }
1033  break;
1035  int laneChangeMode = 0;
1036  if (!server.readTypeCheckingInt(inputStorage, laneChangeMode)) {
1037  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting lane change mode requires an integer.", outputStorage);
1038  }
1039  libsumo::Vehicle::setLaneChangeMode(id, laneChangeMode);
1040  }
1041  break;
1043  int routingMode = 0;
1044  if (!server.readTypeCheckingInt(inputStorage, routingMode)) {
1045  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting routing mode requires an integer.", outputStorage);
1046  }
1047  libsumo::Vehicle::setRoutingMode(id, routingMode);
1048  }
1049  break;
1050  case libsumo::VAR_COLOR: {
1051  libsumo::TraCIColor col;
1052  if (!server.readTypeCheckingColor(inputStorage, col)) {
1053  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The color must be given using the according type.", outputStorage);
1054  }
1055  libsumo::Vehicle::setColor(id, col);
1056  break;
1057  }
1058  case libsumo::ADD: {
1059  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1060  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle requires a compound object.", outputStorage);
1061  }
1062  if (inputStorage.readInt() != 6) {
1063  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle needs six parameters.", outputStorage);
1064  }
1065  std::string vTypeID;
1066  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
1067  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "First parameter (type) requires a string.", outputStorage);
1068  }
1069  std::string routeID;
1070  if (!server.readTypeCheckingString(inputStorage, routeID)) {
1071  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Second parameter (route) requires a string.", outputStorage);
1072  }
1073  int departCode;
1074  if (!server.readTypeCheckingInt(inputStorage, departCode)) {
1075  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Third parameter (depart) requires an integer.", outputStorage);
1076  }
1077  std::string depart = toString(STEPS2TIME(departCode));
1078  if (-departCode == static_cast<int>(DepartDefinition::TRIGGERED)) {
1079  depart = "triggered";
1080  } else if (-departCode == static_cast<int>(DepartDefinition::CONTAINER_TRIGGERED)) {
1081  depart = "containerTriggered";
1082  } else if (-departCode == static_cast<int>(DepartDefinition::NOW)) {
1083  depart = "now";
1084  } else if (-departCode == static_cast<int>(DepartDefinition::SPLIT)) {
1085  depart = "split";
1086  } else if (-departCode == static_cast<int>(DepartDefinition::BEGIN)) {
1087  depart = "begin";
1088  }
1089 
1090  double departPosCode;
1091  if (!server.readTypeCheckingDouble(inputStorage, departPosCode)) {
1092  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fourth parameter (position) requires a double.", outputStorage);
1093  }
1094  std::string departPos = toString(departPosCode);
1095  if (-departPosCode == (int)DepartPosDefinition::RANDOM) {
1096  departPos = "random";
1097  } else if (-departPosCode == (int)DepartPosDefinition::RANDOM_FREE) {
1098  departPos = "random_free";
1099  } else if (-departPosCode == (int)DepartPosDefinition::FREE) {
1100  departPos = "free";
1101  } else if (-departPosCode == (int)DepartPosDefinition::BASE) {
1102  departPos = "base";
1103  } else if (-departPosCode == (int)DepartPosDefinition::LAST) {
1104  departPos = "last";
1105  } else if (-departPosCode == (int)DepartPosDefinition::GIVEN) {
1106  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid departure position.", outputStorage);
1107  }
1108 
1109  double departSpeedCode;
1110  if (!server.readTypeCheckingDouble(inputStorage, departSpeedCode)) {
1111  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fifth parameter (speed) requires a double.", outputStorage);
1112  }
1113  std::string departSpeed = toString(departSpeedCode);
1114  if (-departSpeedCode == (int)DepartSpeedDefinition::RANDOM) {
1115  departSpeed = "random";
1116  } else if (-departSpeedCode == (int)DepartSpeedDefinition::MAX) {
1117  departSpeed = "max";
1118  } else if (-departSpeedCode == (int)DepartSpeedDefinition::DESIRED) {
1119  departSpeed = "desired";
1120  } else if (-departSpeedCode == (int)DepartSpeedDefinition::LIMIT) {
1121  departSpeed = "speedLimit";
1122  } else if (-departSpeedCode == (int)DepartSpeedDefinition::LAST) {
1123  departSpeed = "last";
1124  } else if (-departSpeedCode == (int)DepartSpeedDefinition::AVG) {
1125  departSpeed = "avg";
1126  }
1127 
1128  int departLaneCode;
1129  if (!server.readTypeCheckingByte(inputStorage, departLaneCode)) {
1130  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Sixth parameter (lane) requires a byte.", outputStorage);
1131  }
1132  std::string departLane = toString(departLaneCode);
1133  if (-departLaneCode == (int)DepartLaneDefinition::RANDOM) {
1134  departLane = "random";
1135  } else if (-departLaneCode == (int)DepartLaneDefinition::FREE) {
1136  departLane = "free";
1137  } else if (-departLaneCode == (int)DepartLaneDefinition::ALLOWED_FREE) {
1138  departLane = "allowed";
1139  } else if (-departLaneCode == (int)DepartLaneDefinition::BEST_FREE) {
1140  departLane = "best";
1141  } else if (-departLaneCode == (int)DepartLaneDefinition::FIRST_ALLOWED) {
1142  departLane = "first";
1143  }
1144  libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed);
1145  }
1146  break;
1147  case libsumo::ADD_FULL: {
1148  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1149  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle requires a compound object.", outputStorage);
1150  }
1151  if (inputStorage.readInt() != 14) {
1152  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Adding a fully specified vehicle needs fourteen parameters.", outputStorage);
1153  }
1154  std::string routeID;
1155  if (!server.readTypeCheckingString(inputStorage, routeID)) {
1156  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Second parameter (route) requires a string.", outputStorage);
1157  }
1158  std::string vTypeID;
1159  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
1160  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "First parameter (type) requires a string.", outputStorage);
1161  }
1162  std::string depart;
1163  if (!server.readTypeCheckingString(inputStorage, depart)) {
1164  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Third parameter (depart) requires an string.", outputStorage);
1165  }
1166  std::string departLane;
1167  if (!server.readTypeCheckingString(inputStorage, departLane)) {
1168  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fourth parameter (depart lane) requires a string.", outputStorage);
1169  }
1170  std::string departPos;
1171  if (!server.readTypeCheckingString(inputStorage, departPos)) {
1172  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Fifth parameter (depart position) requires a string.", outputStorage);
1173  }
1174  std::string departSpeed;
1175  if (!server.readTypeCheckingString(inputStorage, departSpeed)) {
1176  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Sixth parameter (depart speed) requires a string.", outputStorage);
1177  }
1178  std::string arrivalLane;
1179  if (!server.readTypeCheckingString(inputStorage, arrivalLane)) {
1180  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Seventh parameter (arrival lane) requires a string.", outputStorage);
1181  }
1182  std::string arrivalPos;
1183  if (!server.readTypeCheckingString(inputStorage, arrivalPos)) {
1184  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Eighth parameter (arrival position) requires a string.", outputStorage);
1185  }
1186  std::string arrivalSpeed;
1187  if (!server.readTypeCheckingString(inputStorage, arrivalSpeed)) {
1188  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Ninth parameter (arrival speed) requires a string.", outputStorage);
1189  }
1190  std::string fromTaz;
1191  if (!server.readTypeCheckingString(inputStorage, fromTaz)) {
1192  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Tenth parameter (from taz) requires a string.", outputStorage);
1193  }
1194  std::string toTaz;
1195  if (!server.readTypeCheckingString(inputStorage, toTaz)) {
1196  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Eleventh parameter (to taz) requires a string.", outputStorage);
1197  }
1198  std::string line;
1199  if (!server.readTypeCheckingString(inputStorage, line)) {
1200  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Twelth parameter (line) requires a string.", outputStorage);
1201  }
1202  int personCapacity;
1203  if (!server.readTypeCheckingInt(inputStorage, personCapacity)) {
1204  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "13th parameter (person capacity) requires an int.", outputStorage);
1205  }
1206  int personNumber;
1207  if (!server.readTypeCheckingInt(inputStorage, personNumber)) {
1208  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "14th parameter (person number) requires an int.", outputStorage);
1209  }
1210  libsumo::Vehicle::add(id, routeID, vTypeID, depart, departLane, departPos, departSpeed, arrivalLane, arrivalPos, arrivalSpeed,
1211  fromTaz, toTaz, line, personCapacity, personNumber);
1212  }
1213  break;
1214  case libsumo::REMOVE: {
1215  int why = 0;
1216  if (!server.readTypeCheckingByte(inputStorage, why)) {
1217  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Removing a vehicle requires a byte.", outputStorage);
1218  }
1219  libsumo::Vehicle::remove(id, (char)why);
1220  }
1221  break;
1222  case libsumo::MOVE_TO_XY: {
1223  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1224  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "MoveToXY vehicle requires a compound object.", outputStorage);
1225  }
1226  const int numArgs = inputStorage.readInt();
1227  if (numArgs < 5 || numArgs > 7) {
1228  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "MoveToXY vehicle should obtain: edgeID, lane, x, y, angle and optionally keepRouteFlag and matchThreshold.", outputStorage);
1229  }
1230  // edge ID
1231  std::string edgeID;
1232  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
1233  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first parameter for moveToXY must be the edge ID given as a string.", outputStorage);
1234  }
1235  // lane index
1236  int laneNum = 0;
1237  if (!server.readTypeCheckingInt(inputStorage, laneNum)) {
1238  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The second parameter for moveToXY must be lane given as an int.", outputStorage);
1239  }
1240  // x
1241  double x = 0;
1242  if (!server.readTypeCheckingDouble(inputStorage, x)) {
1243  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third parameter for moveToXY must be the x-position given as a double.", outputStorage);
1244  }
1245  // y
1246  double y = 0;
1247  if (!server.readTypeCheckingDouble(inputStorage, y)) {
1248  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth parameter for moveToXY must be the y-position given as a double.", outputStorage);
1249  }
1250  // angle
1251  double angle = 0;
1252  if (!server.readTypeCheckingDouble(inputStorage, angle)) {
1253  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth parameter for moveToXY must be the angle given as a double.", outputStorage);
1254  }
1255 
1256  int keepRouteFlag = 1;
1257  if (numArgs >= 6) {
1258  if (!server.readTypeCheckingByte(inputStorage, keepRouteFlag)) {
1259  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The sixth parameter for moveToXY must be the keepRouteFlag given as a byte.", outputStorage);
1260  }
1261  }
1262  double matchThreshold = 100;
1263  if (numArgs == 7) {
1264  if (!server.readTypeCheckingDouble(inputStorage, matchThreshold)) {
1265  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The seventh parameter for moveToXY must be the matchThreshold given as a double.", outputStorage);
1266  }
1267  }
1268  libsumo::Vehicle::moveToXY(id, edgeID, laneNum, x, y, angle, keepRouteFlag, matchThreshold);
1269  }
1270  break;
1272  double factor = 0;
1273  if (!server.readTypeCheckingDouble(inputStorage, factor)) {
1274  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting speed factor requires a double.", outputStorage);
1275  }
1276  libsumo::Vehicle::setSpeedFactor(id, factor);
1277  }
1278  break;
1279  case libsumo::VAR_LINE: {
1280  std::string line;
1281  if (!server.readTypeCheckingString(inputStorage, line)) {
1282  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The line must be given as a string.", outputStorage);
1283  }
1284  libsumo::Vehicle::setLine(id, line);
1285  }
1286  break;
1287  case libsumo::VAR_VIA: {
1288  std::vector<std::string> edgeIDs;
1289  if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {
1290  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Vias must be defined as a list of edge ids.", outputStorage);
1291  }
1292  libsumo::Vehicle::setVia(id, edgeIDs);
1293  }
1294  break;
1295  case libsumo::VAR_PARAMETER: {
1296  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1297  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
1298  }
1299  //readt itemNo
1300  inputStorage.readInt();
1301  std::string name;
1302  if (!server.readTypeCheckingString(inputStorage, name)) {
1303  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);
1304  }
1305  std::string value;
1306  if (!server.readTypeCheckingString(inputStorage, value)) {
1307  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
1308  }
1309  try {
1311  libsumo::Vehicle::setParameter(id, name, value);
1312  } catch (libsumo::TraCIException& e) {
1313  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1314  }
1315  }
1316  break;
1317  case libsumo::VAR_HIGHLIGHT: {
1318  // Highlight the vehicle by adding a tracking polygon. (NOTE: duplicated code exists for POI domain)
1319  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1320  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A compound object is needed for highlighting an object.", outputStorage);
1321  }
1322  const int itemNo = inputStorage.readInt();
1323  if (itemNo > 5) {
1324  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Highlighting an object needs zero to five parameters.", outputStorage);
1325  }
1326  libsumo::TraCIColor col = libsumo::TraCIColor(255, 0, 0);
1327  if (itemNo > 0) {
1328  if (!server.readTypeCheckingColor(inputStorage, col)) {
1329  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first parameter for highlighting must be the highlight color.", outputStorage);
1330  }
1331  }
1332  double size = -1;
1333  if (itemNo > 1) {
1334  if (!server.readTypeCheckingDouble(inputStorage, size)) {
1335  return server.writeErrorStatusCmd(libsumo::CMD_SET_POI_VARIABLE, "The second parameter for highlighting must be the highlight size.", outputStorage);
1336  }
1337  }
1338  int alphaMax = -1;
1339  if (itemNo > 2) {
1340  if (!server.readTypeCheckingUnsignedByte(inputStorage, alphaMax)) {
1341  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third parameter for highlighting must be maximal alpha.", outputStorage);
1342  }
1343  }
1344  double duration = -1;
1345  if (itemNo > 3) {
1346  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
1347  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fourth parameter for highlighting must be the highlight duration.", outputStorage);
1348  }
1349  }
1350  int type = 0;
1351  if (itemNo > 4) {
1352  if (!server.readTypeCheckingUnsignedByte(inputStorage, type)) {
1353  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth parameter for highlighting must be the highlight type id as ubyte.", outputStorage);
1354  }
1355  }
1356  libsumo::Vehicle::highlight(id, col, size, alphaMax, duration, type);
1357  }
1358  break;
1360  std::vector<std::string> reservations;
1361  if (!server.readTypeCheckingStringList(inputStorage, reservations)) {
1362  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "A dispatch command must be defined as a list of reservation ids.", outputStorage);
1363  }
1364  libsumo::Vehicle::dispatchTaxi(id, reservations);
1365  }
1366  break;
1368  double value = 0;
1369  if (!server.readTypeCheckingDouble(inputStorage, value)) {
1370  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting action step length requires a double.", outputStorage);
1371  }
1372  if (fabs(value) == std::numeric_limits<double>::infinity()) {
1373  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid action step length.", outputStorage);
1374  }
1375  bool resetActionOffset = value >= 0.0;
1376  libsumo::Vehicle::setActionStepLength(id, fabs(value), resetActionOffset);
1377  }
1378  break;
1380  double value = 0;
1381  if (!server.readTypeCheckingDouble(inputStorage, value)) {
1382  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting lateral lane position requires a double.", outputStorage);
1383  }
1384  libsumo::Vehicle::setLateralLanePosition(id, value);
1385  }
1386  break;
1388  libsumo::Vehicle::updateBestLanes(id);
1389  }
1390  break;
1391  case libsumo::VAR_MINGAP_LAT: {
1392  double value = 0;
1393  if (!server.readTypeCheckingDouble(inputStorage, value)) {
1394  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Setting minimum lateral gap requires a double.", outputStorage);
1395  }
1396  if (value < 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
1397  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "Invalid minimum lateral gap.", outputStorage);
1398  }
1399  libsumo::Vehicle::setMinGapLat(id, value);
1400  }
1401  break;
1402  default: {
1403  try {
1404  if (!TraCIServerAPI_VehicleType::setVariable(libsumo::CMD_SET_VEHICLE_VARIABLE, variable, v->getSingularType().getID(), server, inputStorage, outputStorage)) {
1405  return false;
1406  }
1407  } catch (ProcessError& e) {
1408  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1409  } catch (libsumo::TraCIException& e) {
1410  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1411  }
1412  }
1413  break;
1414  }
1415  } catch (libsumo::TraCIException& e) {
1416  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1417  }
1418  server.writeStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, libsumo::RTYPE_OK, warning, outputStorage);
1419  return true;
1420 }
1421 
1422 
1423 void
1424 TraCIServerAPI_Vehicle::writeNextStops(TraCIServer& server, const std::string& id, int limit, bool full) {
1425  std::vector<libsumo::TraCINextStopData> nextStops = libsumo::Vehicle::getStops(id, limit);
1427  const int cnt = 1 + (int)nextStops.size() * 4;
1428  server.getWrapperStorage().writeInt(cnt);
1430  server.getWrapperStorage().writeInt((int)nextStops.size());
1431  for (std::vector<libsumo::TraCINextStopData>::iterator it = nextStops.begin(); it != nextStops.end(); ++it) {
1432  int legacyStopFlags = (it->stopFlags << 1) + (it->arrival >= 0 ? 1 : 0);
1434  server.getWrapperStorage().writeString(it->lane);
1436  server.getWrapperStorage().writeDouble(it->endPos);
1438  server.getWrapperStorage().writeString(it->stoppingPlaceID);
1440  server.getWrapperStorage().writeInt(full ? it->stopFlags : legacyStopFlags);
1442  server.getWrapperStorage().writeDouble(it->duration);
1444  server.getWrapperStorage().writeDouble(it->until);
1445  if (full) {
1447  server.getWrapperStorage().writeDouble(it->startPos);
1449  server.getWrapperStorage().writeDouble(it->intendedArrival);
1451  server.getWrapperStorage().writeDouble(it->arrival);
1453  server.getWrapperStorage().writeDouble(it->depart);
1455  server.getWrapperStorage().writeString(it->split);
1457  server.getWrapperStorage().writeString(it->join);
1459  server.getWrapperStorage().writeString(it->actType);
1461  server.getWrapperStorage().writeString(it->tripId);
1463  server.getWrapperStorage().writeString(it->line);
1465  server.getWrapperStorage().writeDouble(it->speed);
1466  }
1467  }
1468 }
1469 
1470 bool
1471 TraCIServerAPI_Vehicle::insertReplaceStop(TraCIServer& server, tcpip::Storage& inputStorage, tcpip::Storage& outputStorage, const std::string& id, bool replace) {
1472  const std::string m1 = replace ? "Replacing" : "Inserting";
1473  const std::string m2 = replace ? "replacement" : "insertion";
1474 
1475  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COMPOUND) {
1476  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, m1 + " stop needs a compound object description.", outputStorage);
1477  }
1478  int compoundSize = inputStorage.readInt();
1479  if (compoundSize != 8 && compoundSize != 9) {
1480  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, m1 + " stop needs a compound object description of eight or nine items.", outputStorage);
1481  }
1482  // read road map position
1483  std::string edgeID;
1484  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
1485  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The first stop " + m2 + " parameter must be the edge id given as a string.", outputStorage);
1486  }
1487  double pos = 0;
1488  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
1489  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);
1490  }
1491  int laneIndex = 0;
1492  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
1493  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The third stop " + m2 + " parameter must be the lane index given as a byte.", outputStorage);
1494  }
1495  // waitTime
1496  double duration = libsumo::INVALID_DOUBLE_VALUE;
1497  if (!server.readTypeCheckingDouble(inputStorage, duration)) {
1498  return server.writeErrorStatusCmd(libsumo::CMD_GET_VEHICLE_VARIABLE, "The fourth stop " + m2 + " parameter must be the stopping duration given as a double.", outputStorage);
1499  }
1500  int stopFlags = 0;
1501  if (!server.readTypeCheckingInt(inputStorage, stopFlags)) {
1502  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The fifth stop " + m2 + " parameter must be a int indicating its parking/triggered status.", outputStorage);
1503  }
1504  double startPos = libsumo::INVALID_DOUBLE_VALUE;
1505  if (!server.readTypeCheckingDouble(inputStorage, startPos)) {
1506  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);
1507  }
1508  double until = libsumo::INVALID_DOUBLE_VALUE;
1509  if (!server.readTypeCheckingDouble(inputStorage, until)) {
1510  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The seventh stop " + m2 + " parameter must be the minimum departure time given as a double.", outputStorage);
1511  }
1512  int nextStopIndex = 0;
1513  if (!server.readTypeCheckingInt(inputStorage, nextStopIndex)) {
1514  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The eigth stop " + m2 + " parameter must be the replacement index given as a int.", outputStorage);
1515  }
1516  int teleport = 0;
1517  if (compoundSize == 9) {
1518  if (!server.readTypeCheckingByte(inputStorage, teleport)) {
1519  return server.writeErrorStatusCmd(libsumo::CMD_SET_VEHICLE_VARIABLE, "The nineth stop " + m2 + " parameter must be the teleport flag given as a byte.", outputStorage);
1520  }
1521  }
1522  if (replace) {
1523  libsumo::Vehicle::replaceStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
1524  } else {
1525  libsumo::Vehicle::insertStop(id, nextStopIndex, edgeID, pos, laneIndex, duration, stopFlags, startPos, until, teleport);
1526  }
1527  return true;
1528 }
1529 /****************************************************************************/
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:55
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:182
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:60
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 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