SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TraCIServerAPI_Vehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // APIs for getting/setting vehicle values via TraCI
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
14 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #ifndef NO_TRACI
36 
37 #include <microsim/MSNet.h>
39 #include <microsim/MSVehicle.h>
40 #include <microsim/MSLane.h>
41 #include <microsim/MSEdge.h>
50 #include "TraCIConstants.h"
52 #include "TraCIServerAPI_Vehicle.h"
54 
55 #ifdef CHECK_MEMORY_LEAKS
56 #include <foreign/nvwa/debug_new.h>
57 #endif // CHECK_MEMORY_LEAKS
58 
59 
60 // ===========================================================================
61 // used namespaces
62 // ===========================================================================
63 using namespace traci;
64 
65 
66 // ===========================================================================
67 // method definitions
68 // ===========================================================================
69 bool
71  tcpip::Storage& outputStorage) {
72  std::string warning = ""; // additional description for response
73  // variable & id
74  int variable = inputStorage.readUnsignedByte();
75  std::string id = inputStorage.readString();
76  // check variable
77  if (variable != ID_LIST && variable != VAR_SPEED && variable != VAR_SPEED_WITHOUT_TRACI && variable != VAR_POSITION && variable != VAR_ANGLE
78  && variable != VAR_ROAD_ID && variable != VAR_LANE_ID && variable != VAR_LANE_INDEX
79  && variable != VAR_TYPE && variable != VAR_ROUTE_ID && variable != VAR_COLOR
80  && variable != VAR_LANEPOSITION
81  && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION
82  && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION
83  && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT
84  && variable != VAR_ROUTE_VALID && variable != VAR_EDGES
85  && variable != VAR_SIGNALS
86  && variable != VAR_LENGTH && variable != VAR_MAXSPEED && variable != VAR_VEHICLECLASS
87  && variable != VAR_SPEED_FACTOR && variable != VAR_SPEED_DEVIATION && variable != VAR_EMISSIONCLASS
88  && variable != VAR_WIDTH && variable != VAR_MINGAP && variable != VAR_SHAPECLASS
89  && variable != VAR_ACCEL && variable != VAR_DECEL && variable != VAR_IMPERFECTION
90  && variable != VAR_TAU && variable != VAR_BEST_LANES && variable != DISTANCE_REQUEST
91  && variable != ID_COUNT
92  ) {
93  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Get Vehicle Variable: unsupported variable specified", outputStorage);
94  return false;
95  }
96  // begin response building
97  tcpip::Storage tempMsg;
98  // response-code, variableID, objectID
100  tempMsg.writeUnsignedByte(variable);
101  tempMsg.writeString(id);
102  // process request
103  if (variable == ID_LIST || variable == ID_COUNT) {
104  std::vector<std::string> ids;
106  for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
107  if ((*i).second->isOnRoad()) {
108  ids.push_back((*i).first);
109  }
110  }
111  if (variable == ID_LIST) {
113  tempMsg.writeStringList(ids);
114  } else {
116  tempMsg.writeInt((int) ids.size());
117  }
118  } else {
120  if (v == 0) {
121  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Vehicle '" + id + "' is not known", outputStorage);
122  return false;
123  }
124  const bool onRoad = v->isOnRoad();
125  switch (variable) {
126  case VAR_SPEED:
128  tempMsg.writeDouble(onRoad ? v->getSpeed() : INVALID_DOUBLE_VALUE);
129  break;
133  break;
134  case VAR_POSITION:
136  tempMsg.writeDouble(onRoad ? v->getPosition().x() : INVALID_DOUBLE_VALUE);
137  tempMsg.writeDouble(onRoad ? v->getPosition().y() : INVALID_DOUBLE_VALUE);
138  break;
139  case VAR_ANGLE:
141  tempMsg.writeDouble(onRoad ? v->getAngle() : INVALID_DOUBLE_VALUE);
142  break;
143  case VAR_ROAD_ID:
145  tempMsg.writeString(onRoad ? v->getLane()->getEdge().getID() : "");
146  break;
147  case VAR_LANE_ID:
149  tempMsg.writeString(onRoad ? v->getLane()->getID() : "");
150  break;
151  case VAR_LANE_INDEX:
153  if (onRoad) {
154  const std::vector<MSLane*> &lanes = v->getLane()->getEdge().getLanes();
155  tempMsg.writeInt((int)std::distance(lanes.begin(), std::find(lanes.begin(), lanes.end(), v->getLane())));
156  } else {
157  tempMsg.writeInt(INVALID_INT_VALUE);
158  }
159  break;
160  case VAR_TYPE:
162  tempMsg.writeString(v->getVehicleType().getID());
163  break;
164  case VAR_ROUTE_ID:
166  tempMsg.writeString(v->getRoute().getID());
167  break;
168  case VAR_COLOR:
169  tempMsg.writeUnsignedByte(TYPE_COLOR);
170  tempMsg.writeUnsignedByte(static_cast<int>(v->getParameter().color.red() * 255. + 0.5));
171  tempMsg.writeUnsignedByte(static_cast<int>(v->getParameter().color.green() * 255. + 0.5));
172  tempMsg.writeUnsignedByte(static_cast<int>(v->getParameter().color.blue() * 255. + 0.5));
173  tempMsg.writeUnsignedByte(255);
174  break;
175  case VAR_LANEPOSITION:
177  tempMsg.writeDouble(onRoad ? v->getPositionOnLane() : INVALID_DOUBLE_VALUE);
178  break;
179  case VAR_CO2EMISSION:
182  break;
183  case VAR_COEMISSION:
186  break;
187  case VAR_HCEMISSION:
190  break;
191  case VAR_PMXEMISSION:
194  break;
195  case VAR_NOXEMISSION:
198  break;
199  case VAR_FUELCONSUMPTION:
202  break;
203  case VAR_NOISEEMISSION:
206  break;
207  case VAR_EDGE_TRAVELTIME: {
208  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
209  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires a compound object.", outputStorage);
210  return false;
211  }
212  if (inputStorage.readInt() != 2) {
213  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires time, and edge as parameter.", outputStorage);
214  return false;
215  }
216  // time
217  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
218  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires the referenced time as first parameter.", outputStorage);
219  return false;
220  }
221  SUMOTime time = inputStorage.readInt();
222  // edge
223  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
224  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires the referenced edge as second parameter.", outputStorage);
225  return false;
226  }
227  std::string edgeID = inputStorage.readString();
228  MSEdge* edge = MSEdge::dictionary(edgeID);
229  if (edge == 0) {
230  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
231  return false;
232  }
233  // retrieve
235  SUMOReal value;
236  if (!v->getWeightsStorage().retrieveExistingTravelTime(edge, 0, time, value)) {
238  } else {
239  tempMsg.writeDouble(value);
240  }
241 
242  }
243  break;
244  case VAR_EDGE_EFFORT: {
245  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
246  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires a compound object.", outputStorage);
247  return false;
248  }
249  if (inputStorage.readInt() != 2) {
250  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires time, and edge as parameter.", outputStorage);
251  return false;
252  }
253  // time
254  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
255  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of effort requires the referenced time as first parameter.", outputStorage);
256  return false;
257  }
258  SUMOTime time = inputStorage.readInt();
259  // edge
260  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
261  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of effort requires the referenced edge as second parameter.", outputStorage);
262  return false;
263  }
264  std::string edgeID = inputStorage.readString();
265  MSEdge* edge = MSEdge::dictionary(edgeID);
266  if (edge == 0) {
267  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
268  return false;
269  }
270  // retrieve
272  SUMOReal value;
273  if (!v->getWeightsStorage().retrieveExistingEffort(edge, 0, time, value)) {
275  } else {
276  tempMsg.writeDouble(value);
277  }
278 
279  }
280  break;
281  case VAR_ROUTE_VALID: {
282  std::string msg;
283  tempMsg.writeUnsignedByte(TYPE_UBYTE);
284  tempMsg.writeUnsignedByte(v->hasValidRoute(msg));
285  }
286  break;
287  case VAR_EDGES: {
288  const MSRoute& r = v->getRoute();
290  tempMsg.writeInt(r.size());
291  for (MSRouteIterator i = r.begin(); i != r.end(); ++i) {
292  tempMsg.writeString((*i)->getID());
293  }
294  }
295  break;
296  case VAR_SIGNALS:
298  tempMsg.writeInt(v->getSignals());
299  break;
300  case VAR_BEST_LANES: {
302  tcpip::Storage tempContent;
303  unsigned int cnt = 0;
304  tempContent.writeUnsignedByte(TYPE_INTEGER);
305  const std::vector<MSVehicle::LaneQ> &bestLanes = onRoad ? v->getBestLanes() : std::vector<MSVehicle::LaneQ>();
306  tempContent.writeInt((int) bestLanes.size());
307  ++cnt;
308  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bestLanes.begin(); i != bestLanes.end(); ++i) {
309  const MSVehicle::LaneQ& lq = *i;
310  tempContent.writeUnsignedByte(TYPE_STRING);
311  tempContent.writeString(lq.lane->getID());
312  ++cnt;
313  tempContent.writeUnsignedByte(TYPE_DOUBLE);
314  tempContent.writeDouble(lq.length);
315  ++cnt;
316  tempContent.writeUnsignedByte(TYPE_DOUBLE);
317  tempContent.writeDouble(lq.nextOccupation);
318  ++cnt;
319  tempContent.writeUnsignedByte(TYPE_BYTE);
320  tempContent.writeByte(lq.bestLaneOffset);
321  ++cnt;
322  tempContent.writeUnsignedByte(TYPE_UBYTE);
323  lq.allowsContinuation ? tempContent.writeUnsignedByte(1) : tempContent.writeUnsignedByte(0);
324  ++cnt;
325  std::vector<std::string> bestContIDs;
326  for (std::vector<MSLane*>::const_iterator j = lq.bestContinuations.begin(); j != lq.bestContinuations.end(); ++j) {
327  bestContIDs.push_back((*j)->getID());
328  }
329  tempContent.writeUnsignedByte(TYPE_STRINGLIST);
330  tempContent.writeStringList(bestContIDs);
331  ++cnt;
332  }
333  tempMsg.writeInt((int) cnt);
334  tempMsg.writeStorage(tempContent);
335  }
336  break;
337  case DISTANCE_REQUEST:
338  if (!commandDistanceRequest(server, inputStorage, tempMsg, v)) {
339  return false;
340  }
341  break;
342  default:
344  break;
345  }
346  }
347  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_OK, warning, outputStorage);
348  server.writeResponseWithLength(outputStorage, tempMsg);
349  return true;
350 }
351 
352 
353 bool
355  tcpip::Storage& outputStorage) {
356  std::string warning = ""; // additional description for response
357  // variable
358  int variable = inputStorage.readUnsignedByte();
359  if (variable != CMD_STOP && variable != CMD_CHANGELANE
360  && variable != CMD_SLOWDOWN && variable != CMD_CHANGETARGET
361  && variable != VAR_ROUTE_ID && variable != VAR_ROUTE
362  && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT
363  && variable != CMD_REROUTE_TRAVELTIME && variable != CMD_REROUTE_EFFORT
364  && variable != VAR_SIGNALS && variable != VAR_MOVE_TO
365  && variable != VAR_LENGTH && variable != VAR_MAXSPEED && variable != VAR_VEHICLECLASS
366  && variable != VAR_SPEED_FACTOR && variable != VAR_SPEED_DEVIATION && variable != VAR_EMISSIONCLASS
367  && variable != VAR_WIDTH && variable != VAR_MINGAP && variable != VAR_SHAPECLASS
368  && variable != VAR_ACCEL && variable != VAR_DECEL && variable != VAR_IMPERFECTION
369  && variable != VAR_TAU
370  && variable != VAR_SPEED && variable != VAR_SPEEDSETMODE && variable != VAR_COLOR
371  && variable != ADD && variable != REMOVE
372  ) {
373  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Change Vehicle State: unsupported variable specified", outputStorage);
374  return false;
375  }
376  // id
377  std::string id = inputStorage.readString();
379  if (v == 0 && variable != ADD) {
380  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Vehicle '" + id + "' is not known", outputStorage);
381  return false;
382  }
383  // process
384  int valueDataType = inputStorage.readUnsignedByte();
385  switch (variable) {
386  case CMD_STOP: {
387  if (valueDataType != TYPE_COMPOUND) {
388  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Stop needs a compound object description.", outputStorage);
389  return false;
390  }
391  if (inputStorage.readInt() != 4) {
392  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Stop needs a compound object description of four items.", outputStorage);
393  return false;
394  }
395  // read road map position
396  valueDataType = inputStorage.readUnsignedByte();
397  if (valueDataType != TYPE_STRING) {
398  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The first stop parameter must be the edge id given as a string.", outputStorage);
399  return false;
400  }
401  std::string roadId = inputStorage.readString();
402  valueDataType = inputStorage.readUnsignedByte();
403  if (valueDataType != TYPE_DOUBLE) {
404  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The second stop parameter must be the position along the edge given as a double.", outputStorage);
405  return false;
406  }
407  SUMOReal pos = inputStorage.readDouble();
408  valueDataType = inputStorage.readUnsignedByte();
409  if (valueDataType != TYPE_BYTE) {
410  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The third stop parameter must be the lane index given as a byte.", outputStorage);
411  return false;
412  }
413  int laneIndex = inputStorage.readByte();
414  // waitTime
415  valueDataType = inputStorage.readUnsignedByte();
416  if (valueDataType != TYPE_INTEGER) {
417  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The fourth stop parameter must be the waiting time given as an integer.", outputStorage);
418  return false;
419  }
420  SUMOTime waitTime = inputStorage.readInt();
421  // check
422  if (pos < 0) {
423  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Position on lane must not be negative", outputStorage);
424  return false;
425  }
426  // get the actual lane that is referenced by laneIndex
427  MSEdge* road = MSEdge::dictionary(roadId);
428  if (road == 0) {
429  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Unable to retrieve road with given id", outputStorage);
430  return false;
431  }
432  const std::vector<MSLane*> &allLanes = road->getLanes();
433  if ((laneIndex < 0) || laneIndex >= (int)(allLanes.size())) {
434  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "No lane existing with such id on the given road", outputStorage);
435  return false;
436  }
437  // Forward command to vehicle
438  if (!static_cast<MSVehicle*>(v)->addTraciStop(allLanes[laneIndex], pos, 0, waitTime)) {
439  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Vehicle is too close or behind the stop on " + allLanes[laneIndex]->getID(), outputStorage);
440  return false;
441  }
442  }
443  break;
444  case CMD_CHANGELANE: {
445  if (valueDataType != TYPE_COMPOUND) {
446  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Lane change needs a compound object description.", outputStorage);
447  return false;
448  }
449  if (inputStorage.readInt() != 2) {
450  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Lane change needs a compound object description of two items.", outputStorage);
451  return false;
452  }
453  // Lane ID
454  valueDataType = inputStorage.readUnsignedByte();
455  if (valueDataType != TYPE_BYTE) {
456  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The first lane change parameter must be the lane index given as a byte.", outputStorage);
457  return false;
458  }
459  int laneIndex = inputStorage.readByte();
460  // stickyTime
461  valueDataType = inputStorage.readUnsignedByte();
462  if (valueDataType != TYPE_INTEGER) {
463  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The second lane change parameter must be the duration given as an integer.", outputStorage);
464  return false;
465  }
466  SUMOTime stickyTime = inputStorage.readInt();
467  if ((laneIndex < 0) || (laneIndex >= (int)(v->getEdge()->getLanes().size()))) {
468  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "No lane existing with given id on the current road", outputStorage);
469  return false;
470  }
471  // Forward command to vehicle
472  std::vector<std::pair<SUMOTime, unsigned int> > laneTimeLine;
473  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), laneIndex));
474  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + stickyTime, laneIndex));
475  static_cast<MSVehicle*>(v)->getInfluencer().setLaneTimeLine(laneTimeLine);
476  MSVehicle::ChangeRequest req = static_cast<MSVehicle*>(v)->getInfluencer().checkForLaneChanges(MSNet::getInstance()->getCurrentTimeStep(),
477  *static_cast<MSVehicle*>(v)->getEdge(), static_cast<MSVehicle*>(v)->getLaneIndex());
478  static_cast<MSVehicle*>(v)->getLaneChangeModel().requestLaneChange(req);
479  }
480  break;
481  case CMD_SLOWDOWN: {
482  if (valueDataType != TYPE_COMPOUND) {
483  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Slow down needs a compound object description.", outputStorage);
484  return false;
485  }
486  if (inputStorage.readInt() != 2) {
487  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Slow down needs a compound object description of two items.", outputStorage);
488  return false;
489  }
490  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
491  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The first slow down parameter must be the speed given as a double.", outputStorage);
492  return false;
493  }
494  SUMOReal newSpeed = MAX2(inputStorage.readDouble(), 0.0);
495  if (newSpeed < 0) {
496  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Speed must not be negative", outputStorage);
497  return false;
498  }
499  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
500  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The second slow down parameter must be the duration given as an integer.", outputStorage);
501  return false;
502  }
503  SUMOTime duration = inputStorage.readInt();
504  if (duration < 0) {
505  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid time interval", outputStorage);
506  return false;
507  }
508  std::vector<std::pair<SUMOTime, SUMOReal> > speedTimeLine;
509  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), v->getSpeed()));
510  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + duration, newSpeed));
511  static_cast<MSVehicle*>(v)->getInfluencer().setSpeedTimeLine(speedTimeLine);
512  }
513  break;
514  case CMD_CHANGETARGET: {
515  if (valueDataType != TYPE_STRING) {
516  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Change target requires a string containing the id of the new destination edge as parameter.", outputStorage);
517  return false;
518  }
519  std::string edgeID = inputStorage.readString();
520  const MSEdge* destEdge = MSEdge::dictionary(edgeID);
521  if (destEdge == 0) {
522  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Can not retrieve road with ID " + edgeID, outputStorage);
523  return false;
524  }
525  // build a new route between the vehicle's current edge and destination edge
526  MSEdgeVector newRoute;
527  const MSEdge* currentEdge = v->getEdge();
528  MSEdgeWeightsStorage empty;
529  MSNet::EdgeWeightsProxi proxi(empty, MSNet::getInstance()->getWeightsStorage());
531  router.compute(currentEdge, destEdge, (const MSVehicle * const) v, MSNet::getInstance()->getCurrentTimeStep(), newRoute);
532  // replace the vehicle's route by the new one
533  if (!v->replaceRouteEdges(newRoute)) {
534  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Route replacement failed for " + v->getID(), outputStorage);
535  return false;
536  }
537  }
538  break;
539  case VAR_ROUTE_ID: {
540  if (valueDataType != TYPE_STRING) {
541  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The route id must be given as a string.", outputStorage);
542  return false;
543  }
544  std::string rid = inputStorage.readString();
545  const MSRoute* r = MSRoute::dictionary(rid);
546  if (r == 0) {
547  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The route '" + rid + "' is not known.", outputStorage);
548  return false;
549  }
550  if (!v->replaceRoute(r)) {
551  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Route replacement failed for " + v->getID(), outputStorage);
552  return false;
553  }
554  }
555  break;
556  case VAR_ROUTE: {
557  if (valueDataType != TYPE_STRINGLIST) {
558  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "A route must be defined as a list of edge ids.", outputStorage);
559  return false;
560  }
561  std::vector<std::string> edgeIDs = inputStorage.readStringList();
562  std::vector<const MSEdge*> edges;
563  MSEdge::parseEdgesList(edgeIDs, edges, "<unknown>");
564  if (!v->replaceRouteEdges(edges)) {
565  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Route replacement failed for " + v->getID(), outputStorage);
566  return false;
567  }
568  }
569  break;
570  case VAR_EDGE_TRAVELTIME: {
571  if (valueDataType != TYPE_COMPOUND) {
572  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time requires a compound object.", outputStorage);
573  return false;
574  }
575  int parameterCount = inputStorage.readInt();
576  if (parameterCount == 4) {
577  // begin time
578  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
579  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 4 parameters requires the begin time as first parameter.", outputStorage);
580  return false;
581  }
582  SUMOTime begTime = inputStorage.readInt();
583  // begin time
584  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
585  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 4 parameters requires the end time as second parameter.", outputStorage);
586  return false;
587  }
588  SUMOTime endTime = inputStorage.readInt();
589  // edge
590  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
591  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 4 parameters requires the referenced edge as third parameter.", outputStorage);
592  return false;
593  }
594  std::string edgeID = inputStorage.readString();
595  MSEdge* edge = MSEdge::dictionary(edgeID);
596  if (edge == 0) {
597  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
598  return false;
599  }
600  // value
601  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
602  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 4 parameters requires the travel time as fourth parameter.", outputStorage);
603  return false;
604  }
605  SUMOReal value = inputStorage.readDouble();
606  // retrieve
607  static_cast<MSVehicle*>(v)->getWeightsStorage().addTravelTime(edge, begTime, endTime, value);
608  } else if (parameterCount == 2) {
609  // edge
610  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
611  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 2 parameters requires the referenced edge as first parameter.", outputStorage);
612  return false;
613  }
614  std::string edgeID = inputStorage.readString();
615  MSEdge* edge = MSEdge::dictionary(edgeID);
616  if (edge == 0) {
617  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
618  return false;
619  }
620  // value
621  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
622  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 2 parameters requires the travel time as second parameter.", outputStorage);
623  return false;
624  }
625  SUMOReal value = inputStorage.readDouble();
626  // retrieve
627  while (static_cast<MSVehicle*>(v)->getWeightsStorage().knowsTravelTime(edge)) {
628  static_cast<MSVehicle*>(v)->getWeightsStorage().removeTravelTime(edge);
629  }
630  static_cast<MSVehicle*>(v)->getWeightsStorage().addTravelTime(edge, 0, SUMOTime_MAX, value);
631  } else if (parameterCount == 1) {
632  // edge
633  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
634  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 1 parameter requires the referenced edge as first parameter.", outputStorage);
635  return false;
636  }
637  std::string edgeID = inputStorage.readString();
638  MSEdge* edge = MSEdge::dictionary(edgeID);
639  if (edge == 0) {
640  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
641  return false;
642  }
643  // retrieve
644  while (static_cast<MSVehicle*>(v)->getWeightsStorage().knowsTravelTime(edge)) {
645  static_cast<MSVehicle*>(v)->getWeightsStorage().removeTravelTime(edge);
646  }
647  } else {
648  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);
649  return false;
650  }
651  }
652  break;
653  case VAR_EDGE_EFFORT: {
654  if (valueDataType != TYPE_COMPOUND) {
655  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort requires a compound object.", outputStorage);
656  return false;
657  }
658  int parameterCount = inputStorage.readInt();
659  if (parameterCount == 4) {
660  // begin time
661  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
662  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 4 parameters requires the begin time as first parameter.", outputStorage);
663  return false;
664  }
665  SUMOTime begTime = inputStorage.readInt();
666  // begin time
667  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
668  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 4 parameters requires the end time as second parameter.", outputStorage);
669  return false;
670  }
671  SUMOTime endTime = inputStorage.readInt();
672  // edge
673  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
674  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 4 parameters requires the referenced edge as third parameter.", outputStorage);
675  return false;
676  }
677  std::string edgeID = inputStorage.readString();
678  MSEdge* edge = MSEdge::dictionary(edgeID);
679  if (edge == 0) {
680  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
681  return false;
682  }
683  // value
684  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
685  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 4 parameters requires the travel time as fourth parameter.", outputStorage);
686  return false;
687  }
688  SUMOReal value = inputStorage.readDouble();
689  // retrieve
690  static_cast<MSVehicle*>(v)->getWeightsStorage().addEffort(edge, begTime, endTime, value);
691  } else if (parameterCount == 2) {
692  // edge
693  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
694  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 2 parameters requires the referenced edge as first parameter.", outputStorage);
695  return false;
696  }
697  std::string edgeID = inputStorage.readString();
698  MSEdge* edge = MSEdge::dictionary(edgeID);
699  if (edge == 0) {
700  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
701  return false;
702  }
703  // value
704  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
705  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 2 parameters requires the travel time as second parameter.", outputStorage);
706  return false;
707  }
708  SUMOReal value = inputStorage.readDouble();
709  // retrieve
710  while (static_cast<MSVehicle*>(v)->getWeightsStorage().knowsEffort(edge)) {
711  static_cast<MSVehicle*>(v)->getWeightsStorage().removeEffort(edge);
712  }
713  static_cast<MSVehicle*>(v)->getWeightsStorage().addEffort(edge, 0, SUMOTime_MAX, value);
714  } else if (parameterCount == 1) {
715  // edge
716  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
717  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 1 parameter requires the referenced edge as first parameter.", outputStorage);
718  return false;
719  }
720  std::string edgeID = inputStorage.readString();
721  MSEdge* edge = MSEdge::dictionary(edgeID);
722  if (edge == 0) {
723  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
724  return false;
725  }
726  // retrieve
727  while (static_cast<MSVehicle*>(v)->getWeightsStorage().knowsEffort(edge)) {
728  static_cast<MSVehicle*>(v)->getWeightsStorage().removeEffort(edge);
729  }
730  } else {
731  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);
732  return false;
733  }
734  }
735  break;
736  case CMD_REROUTE_TRAVELTIME: {
737  if (valueDataType != TYPE_COMPOUND) {
738  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Rerouting requires a compound object.", outputStorage);
739  return false;
740  }
741  if (inputStorage.readInt() != 0) {
742  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Rerouting should obtain an empty compound object.", outputStorage);
743  return false;
744  }
745  MSNet::EdgeWeightsProxi proxi(static_cast<MSVehicle*>(v)->getWeightsStorage(), MSNet::getInstance()->getWeightsStorage());
747  v->reroute(MSNet::getInstance()->getCurrentTimeStep(), router);
748  }
749  break;
750  case CMD_REROUTE_EFFORT: {
751  if (valueDataType != TYPE_COMPOUND) {
752  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Rerouting requires a compound object.", outputStorage);
753  return false;
754  }
755  if (inputStorage.readInt() != 0) {
756  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Rerouting should obtain an empty compound object.", outputStorage);
757  return false;
758  }
759  MSNet::EdgeWeightsProxi proxi(static_cast<MSVehicle*>(v)->getWeightsStorage(), MSNet::getInstance()->getWeightsStorage());
761  v->reroute(MSNet::getInstance()->getCurrentTimeStep(), router);
762  }
763  break;
764  case VAR_SIGNALS:
765  if (valueDataType != TYPE_INTEGER) {
766  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting signals requires an integer.", outputStorage);
767  return false;
768  }
769  static_cast<MSVehicle*>(v)->switchOffSignal(0x0fffffff);
770  static_cast<MSVehicle*>(v)->switchOnSignal(inputStorage.readInt());
771  break;
772  case VAR_MOVE_TO: {
773  if (valueDataType != TYPE_COMPOUND) {
774  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting position requires a compound object.", outputStorage);
775  return false;
776  }
777  if (inputStorage.readInt() != 2) {
778  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting position should obtain the lane id and the position.", outputStorage);
779  return false;
780  }
781  // lane ID
782  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
783  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The first parameter for setting a position must be the lane ID given as a string.", outputStorage);
784  return false;
785  }
786  std::string laneID = inputStorage.readString();
787  // position on lane
788  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
789  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The second parameter for setting a position must be the position given as a double.", outputStorage);
790  return false;
791  }
792  SUMOReal position = inputStorage.readDouble();
793  // process
794  MSLane* l = MSLane::dictionary(laneID);
795  if (l == 0) {
796  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Unknown lane '" + laneID + "'.", outputStorage);
797  return false;
798  }
799  MSEdge& destinationEdge = l->getEdge();
800  if (!static_cast<MSVehicle*>(v)->willPass(&destinationEdge)) {
801  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Vehicle '" + laneID + "' may be set onto an edge to pass only.", outputStorage);
802  return false;
803  }
804  static_cast<MSVehicle*>(v)->onRemovalFromNet(MSMoveReminder::NOTIFICATION_TELEPORT);
805  static_cast<MSVehicle*>(v)->getLane()->removeVehicle(static_cast<MSVehicle*>(v));
806  while (v->getEdge() != &destinationEdge) {
807  const MSEdge* nextEdge = v->succEdge(1);
808  // let the vehicle move to the next edge
809  if (static_cast<MSVehicle*>(v)->enterLaneAtMove(nextEdge->getLanes()[0], true)) {
811  continue;
812  }
813  }
814  l->forceVehicleInsertion(static_cast<MSVehicle*>(v), position);
815  }
816  break;
817  case VAR_SPEED: {
818  if (valueDataType != TYPE_DOUBLE) {
819  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting speed requires a double.", outputStorage);
820  return false;
821  }
822  SUMOReal speed = inputStorage.readDouble();
823  std::vector<std::pair<SUMOTime, SUMOReal> > speedTimeLine;
824  if (speed >= 0) {
825  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), speed));
826  speedTimeLine.push_back(std::make_pair(SUMOTime_MAX, speed));
827  }
828  static_cast<MSVehicle*>(v)->getInfluencer().setSpeedTimeLine(speedTimeLine);
829  }
830  break;
831  case VAR_SPEEDSETMODE: {
832  if (valueDataType != TYPE_INTEGER) {
833  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting speed requires a double.", outputStorage);
834  return false;
835  }
836  int speedMode = inputStorage.readInt();
837  static_cast<MSVehicle*>(v)->getInfluencer().setConsiderSafeVelocity((speedMode & 1) != 0);
838  static_cast<MSVehicle*>(v)->getInfluencer().setConsiderMaxAcceleration((speedMode & 2) != 0);
839  static_cast<MSVehicle*>(v)->getInfluencer().setConsiderMaxDeceleration((speedMode & 4) != 0);
840  }
841  break;
842  case VAR_COLOR: {
843  if (valueDataType != TYPE_COLOR) {
844  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The color must be given using the according type.", outputStorage);
845  return false;
846  }
847  SUMOReal r = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
848  SUMOReal g = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
849  SUMOReal b = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
850  inputStorage.readUnsignedByte(); // skip alpha level
851  v->getParameter().color.set(r, g, b);
852  }
853  break;
854  case ADD: {
855  if (v != 0) {
856  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The vehicle " + id + " to add already exists.", outputStorage);
857  return false;
858  }
859  if (valueDataType != TYPE_COMPOUND) {
860  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Adding a vehicle requires a compound object.", outputStorage);
861  return false;
862  }
863  if (inputStorage.readInt() != 6) {
864  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Adding a vehicle needs six parameters.", outputStorage);
865  return false;
866  }
867  SUMOVehicleParameter vehicleParams;
868  vehicleParams.id = id;
869 
870  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
871  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "First parameter (type) requires a string.", outputStorage);
872  return false;
873  }
874  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(inputStorage.readString());
875  if (!vehicleType) {
876  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid type for vehicle: '" + id + "'");
877  return false;
878  }
879 
880  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
881  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Second parameter (route) requires a string.", outputStorage);
882  return false;
883  }
884  const std::string routeID = inputStorage.readString();
885  const MSRoute* route = MSRoute::dictionary(routeID);
886  if (!route) {
887  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid route '" + routeID + "' for vehicle: '" + id + "'");
888  return false;
889  }
890 
891  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
892  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Third parameter (depart) requires an integer.", outputStorage);
893  return false;
894  }
895  vehicleParams.depart = inputStorage.readInt();
896  if (vehicleParams.depart < 0) {
897  const int proc = static_cast<int>(-vehicleParams.depart);
898  if (proc >= static_cast<int>(DEPART_DEF_MAX)) {
899  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid departure time.", outputStorage);
900  return false;
901  }
902  vehicleParams.departProcedure = (DepartDefinition)proc;
903  }
904 
905  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
906  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Fourth parameter (position) requires a double.", outputStorage);
907  return false;
908  }
909  vehicleParams.departPos = inputStorage.readDouble();
910  if (vehicleParams.departPos < 0) {
911  const int proc = static_cast<int>(-vehicleParams.departPos);
912  if (proc >= static_cast<int>(DEPART_POS_DEF_MAX)) {
913  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid departure position.", outputStorage);
914  return false;
915  }
916  vehicleParams.departPosProcedure = (DepartPosDefinition)proc;
917  } else {
918  vehicleParams.departPosProcedure = DEPART_POS_GIVEN;
919  }
920 
921  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
922  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Fifth parameter (speed) requires a double.", outputStorage);
923  return false;
924  }
925  vehicleParams.departSpeed = inputStorage.readDouble();
926  if (vehicleParams.departSpeed < 0) {
927  const int proc = static_cast<int>(-vehicleParams.departSpeed);
928  if (proc >= static_cast<int>(DEPART_SPEED_DEF_MAX)) {
929  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid departure speed.", outputStorage);
930  return false;
931  }
932  vehicleParams.departSpeedProcedure = (DepartSpeedDefinition)proc;
933  } else {
935  }
936 
937  if (inputStorage.readUnsignedByte() != TYPE_BYTE) {
938  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Sixth parameter (lane) requires a byte.", outputStorage);
939  return false;
940  }
941  vehicleParams.departLane = inputStorage.readByte();
942  if (vehicleParams.departLane < 0) {
943  const int proc = static_cast<int>(-vehicleParams.departLane);
944  if (proc >= static_cast<int>(DEPART_LANE_DEF_MAX)) {
945  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid departure lane.", outputStorage);
946  return false;
947  }
948  vehicleParams.departLaneProcedure = (DepartLaneDefinition)proc;
949  } else {
950  vehicleParams.departLaneProcedure = DEPART_LANE_GIVEN;
951  }
952 
954  *params = vehicleParams;
955  try {
956  SUMOVehicle* vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(params, route, vehicleType);
957  MSNet::getInstance()->getVehicleControl().addVehicle(vehicleParams.id, vehicle);
959  } catch (ProcessError& e) {
960  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, e.what(), outputStorage);
961  return false;
962  }
963  }
964  break;
965  case REMOVE: {
966  if (valueDataType != TYPE_BYTE) {
967  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Removing a vehicle requires an int.", outputStorage);
968  return false;
969  }
970  int why = (int) inputStorage.readByte();
972  switch (why) {
973  case 0:
975  break;
976  case 1:
978  break;
979  case 2:
981  break;
982  case 3:
984  break;
985  case 4:
986  default:
988  break;
989  }
990  static_cast<MSVehicle*>(v)->onRemovalFromNet(n);
991  static_cast<MSVehicle*>(v)->getLane()->removeVehicle(static_cast<MSVehicle*>(v));
992  MSNet::getInstance()->getVehicleControl().scheduleVehicleRemoval(static_cast<MSVehicle*>(v));
993  }
994  break;
995  default:
996  try {
998  getSingularType(v), server, inputStorage, outputStorage)) {
999  return false;
1000  }
1001  } catch (ProcessError& e) {
1002  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, e.what(), outputStorage);
1003  return false;
1004  }
1005  break;
1006  }
1007  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_OK, warning, outputStorage);
1008  return true;
1009 }
1010 
1011 
1012 bool
1014  tcpip::Storage& outputStorage, const MSVehicle* v) {
1015  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
1016  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of distance requires a compound object.", outputStorage);
1017  return false;
1018  }
1019  if (inputStorage.readInt() != 2) {
1020  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of distance requires position and distance type as parameter.", outputStorage);
1021  return false;
1022  }
1023 
1024  Position pos;
1025  std::pair<const MSLane*, SUMOReal> roadPos;
1026 
1027  // read position
1028  int posType = inputStorage.readUnsignedByte();
1029  switch (posType) {
1030  case POSITION_ROADMAP:
1031  try {
1032  std::string roadID = inputStorage.readString();
1033  roadPos.second = inputStorage.readDouble();
1034  roadPos.first = TraCIServerAPI_Simulation::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos.second);
1035  pos = roadPos.first->getShape().positionAtLengthPosition(roadPos.second);
1036  } catch (TraCIException& e) {
1038  return false;
1039  }
1040  break;
1041  case POSITION_2D:
1042  case POSITION_3D: {
1043  const double p1x = inputStorage.readDouble();
1044  const double p1y = inputStorage.readDouble();
1045  pos.set(p1x, p1y);
1046  }
1047  if (posType == POSITION_3D) {
1048  inputStorage.readDouble(); // z value is ignored
1049  }
1051  break;
1052  default:
1053  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Unknown position format used for distance request");
1054  return false;
1055  }
1056 
1057  // read distance type
1058  int distType = inputStorage.readUnsignedByte();
1059 
1060  SUMOReal distance = INVALID_DOUBLE_VALUE;
1061  if (v->isOnRoad()) {
1062  if (distType == REQUEST_DRIVINGDIST) {
1063  distance = v->getRoute().getDistanceBetween(v->getPositionOnLane(), roadPos.second,
1064  v->getEdge(), &roadPos.first->getEdge());
1065  if (distance == std::numeric_limits<SUMOReal>::max()) {
1066  distance = INVALID_DOUBLE_VALUE;
1067  }
1068  } else {
1069  // compute air distance (default)
1070  distance = v->getPosition().distanceTo(pos);
1071  }
1072  }
1073  // write response command
1074  outputStorage.writeUnsignedByte(TYPE_DOUBLE);
1075  outputStorage.writeDouble(distance);
1076  return true;
1077 }
1078 
1079 // ------ helper functions ------
1082  const MSVehicleType& oType = veh->getVehicleType();
1083  std::string newID = oType.getID().find('@') == std::string::npos ? oType.getID() + "@" + veh->getID() : oType.getID();
1084  MSVehicleType* type = MSVehicleType::build(newID, &oType);
1085  static_cast<MSVehicle*>(veh)->replaceVehicleType(type);
1086  return *type;
1087 }
1088 
1089 #endif
1090 
1091 
1092 /****************************************************************************/
1093