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-sim.org/
14 // Copyright (C) 2001-2013 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 std::map<std::string, std::vector<MSLane*> > TraCIServerAPI_Vehicle::gVTDMap;
68 
69 // ===========================================================================
70 // method definitions
71 // ===========================================================================
72 bool
74  tcpip::Storage& outputStorage) {
75  // variable & id
76  int variable = inputStorage.readUnsignedByte();
77  std::string id = inputStorage.readString();
78  // check variable
79  if (variable != ID_LIST && variable != VAR_SPEED && variable != VAR_SPEED_WITHOUT_TRACI && variable != VAR_POSITION && variable != VAR_ANGLE
80  && variable != VAR_ROAD_ID && variable != VAR_LANE_ID && variable != VAR_LANE_INDEX
81  && variable != VAR_TYPE && variable != VAR_ROUTE_ID && variable != VAR_COLOR
82  && variable != VAR_LANEPOSITION
83  && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION
84  && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION
85  && variable != VAR_PERSON_NUMBER
86  && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT
87  && variable != VAR_ROUTE_VALID && variable != VAR_EDGES
88  && variable != VAR_SIGNALS
89  && variable != VAR_LENGTH && variable != VAR_MAXSPEED && variable != VAR_VEHICLECLASS
90  && variable != VAR_SPEED_FACTOR && variable != VAR_SPEED_DEVIATION && variable != VAR_EMISSIONCLASS
91  && variable != VAR_WIDTH && variable != VAR_MINGAP && variable != VAR_SHAPECLASS
92  && variable != VAR_ACCEL && variable != VAR_DECEL && variable != VAR_IMPERFECTION
93  && variable != VAR_TAU && variable != VAR_BEST_LANES && variable != DISTANCE_REQUEST
94  && variable != ID_COUNT && variable != VAR_STOPSTATE
95  ) {
96  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Get Vehicle Variable: unsupported variable specified", outputStorage);
97  }
98  // begin response building
99  tcpip::Storage tempMsg;
100  // response-code, variableID, objectID
102  tempMsg.writeUnsignedByte(variable);
103  tempMsg.writeString(id);
104  // process request
105  if (variable == ID_LIST || variable == ID_COUNT) {
106  std::vector<std::string> ids;
108  for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
109  if ((*i).second->isOnRoad()) {
110  ids.push_back((*i).first);
111  }
112  }
113  if (variable == ID_LIST) {
115  tempMsg.writeStringList(ids);
116  } else {
118  tempMsg.writeInt((int) ids.size());
119  }
120  } else {
122  if (sumoVehicle == 0) {
123  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
124  }
125  MSVehicle* v = dynamic_cast<MSVehicle*>(sumoVehicle);
126  if (v == 0) {
127  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a micro-simulation vehicle", outputStorage);
128  }
129  const bool onRoad = v->isOnRoad();
130  switch (variable) {
131  case VAR_SPEED:
133  tempMsg.writeDouble(onRoad ? v->getSpeed() : INVALID_DOUBLE_VALUE);
134  break;
138  break;
139  case VAR_POSITION:
141  tempMsg.writeDouble(onRoad ? v->getPosition().x() : INVALID_DOUBLE_VALUE);
142  tempMsg.writeDouble(onRoad ? v->getPosition().y() : INVALID_DOUBLE_VALUE);
143  break;
144  case VAR_ANGLE:
146  tempMsg.writeDouble(onRoad ? v->getAngle() : INVALID_DOUBLE_VALUE);
147  break;
148  case VAR_ROAD_ID:
150  tempMsg.writeString(onRoad ? v->getLane()->getEdge().getID() : "");
151  break;
152  case VAR_LANE_ID:
154  tempMsg.writeString(onRoad ? v->getLane()->getID() : "");
155  break;
156  case VAR_LANE_INDEX:
158  if (onRoad) {
159  const std::vector<MSLane*>& lanes = v->getLane()->getEdge().getLanes();
160  tempMsg.writeInt((int)std::distance(lanes.begin(), std::find(lanes.begin(), lanes.end(), v->getLane())));
161  } else {
162  tempMsg.writeInt(INVALID_INT_VALUE);
163  }
164  break;
165  case VAR_TYPE:
167  tempMsg.writeString(v->getVehicleType().getID());
168  break;
169  case VAR_ROUTE_ID:
171  tempMsg.writeString(v->getRoute().getID());
172  break;
173  case VAR_COLOR:
174  tempMsg.writeUnsignedByte(TYPE_COLOR);
175  tempMsg.writeUnsignedByte(v->getParameter().color.red());
176  tempMsg.writeUnsignedByte(v->getParameter().color.green());
177  tempMsg.writeUnsignedByte(v->getParameter().color.blue());
178  tempMsg.writeUnsignedByte(v->getParameter().color.alpha());
179  break;
180  case VAR_LANEPOSITION:
182  tempMsg.writeDouble(onRoad ? v->getPositionOnLane() : INVALID_DOUBLE_VALUE);
183  break;
184  case VAR_CO2EMISSION:
187  break;
188  case VAR_COEMISSION:
191  break;
192  case VAR_HCEMISSION:
195  break;
196  case VAR_PMXEMISSION:
199  break;
200  case VAR_NOXEMISSION:
203  break;
204  case VAR_FUELCONSUMPTION:
207  break;
208  case VAR_NOISEEMISSION:
211  break;
212  case VAR_PERSON_NUMBER:
214  tempMsg.writeInt(v->getPersonNumber());
215  break;
216  case VAR_EDGE_TRAVELTIME: {
217  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
218  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Retrieval of travel time requires a compound object.", outputStorage);
219  }
220  if (inputStorage.readInt() != 2) {
221  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Retrieval of travel time requires time, and edge as parameter.", outputStorage);
222  }
223  // time
224  SUMOTime time = 0;
225  if (!server.readTypeCheckingInt(inputStorage, time)) {
226  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires the referenced time as first parameter.", outputStorage);
227  }
228  // edge
229  std::string edgeID;
230  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
231  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires the referenced edge as second parameter.", outputStorage);
232  }
233  MSEdge* edge = MSEdge::dictionary(edgeID);
234  if (edge == 0) {
235  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
236  }
237  // retrieve
239  SUMOReal value;
240  if (!v->getWeightsStorage().retrieveExistingTravelTime(edge, 0, time, value)) {
242  } else {
243  tempMsg.writeDouble(value);
244  }
245 
246  }
247  break;
248  case VAR_EDGE_EFFORT: {
249  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
250  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Retrieval of travel time requires a compound object.", outputStorage);
251  }
252  if (inputStorage.readInt() != 2) {
253  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Retrieval of travel time requires time, and edge as parameter.", outputStorage);
254  }
255  // time
256  SUMOTime time = 0;
257  if (!server.readTypeCheckingInt(inputStorage, time)) {
258  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of effort requires the referenced time as first parameter.", outputStorage);
259  }
260  // edge
261  std::string edgeID;
262  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
263  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of effort requires the referenced edge as second parameter.", outputStorage);
264  }
265  MSEdge* edge = MSEdge::dictionary(edgeID);
266  if (edge == 0) {
267  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
268  }
269  // retrieve
271  SUMOReal value;
272  if (!v->getWeightsStorage().retrieveExistingEffort(edge, 0, time, value)) {
274  } else {
275  tempMsg.writeDouble(value);
276  }
277 
278  }
279  break;
280  case VAR_ROUTE_VALID: {
281  std::string msg;
282  tempMsg.writeUnsignedByte(TYPE_UBYTE);
283  tempMsg.writeUnsignedByte(v->hasValidRoute(msg));
284  }
285  break;
286  case VAR_EDGES: {
287  const MSRoute& r = v->getRoute();
289  tempMsg.writeInt(r.size());
290  for (MSRouteIterator i = r.begin(); i != r.end(); ++i) {
291  tempMsg.writeString((*i)->getID());
292  }
293  }
294  break;
295  case VAR_SIGNALS:
297  tempMsg.writeInt(v->getSignals());
298  break;
299  case VAR_BEST_LANES: {
301  tcpip::Storage tempContent;
302  unsigned int cnt = 0;
303  tempContent.writeUnsignedByte(TYPE_INTEGER);
304  const std::vector<MSVehicle::LaneQ>& bestLanes = onRoad ? v->getBestLanes() : std::vector<MSVehicle::LaneQ>();
305  tempContent.writeInt((int) bestLanes.size());
306  ++cnt;
307  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bestLanes.begin(); i != bestLanes.end(); ++i) {
308  const MSVehicle::LaneQ& lq = *i;
309  tempContent.writeUnsignedByte(TYPE_STRING);
310  tempContent.writeString(lq.lane->getID());
311  ++cnt;
312  tempContent.writeUnsignedByte(TYPE_DOUBLE);
313  tempContent.writeDouble(lq.length);
314  ++cnt;
315  tempContent.writeUnsignedByte(TYPE_DOUBLE);
316  tempContent.writeDouble(lq.nextOccupation);
317  ++cnt;
318  tempContent.writeUnsignedByte(TYPE_BYTE);
319  tempContent.writeByte(lq.bestLaneOffset);
320  ++cnt;
321  tempContent.writeUnsignedByte(TYPE_UBYTE);
322  lq.allowsContinuation ? tempContent.writeUnsignedByte(1) : tempContent.writeUnsignedByte(0);
323  ++cnt;
324  std::vector<std::string> bestContIDs;
325  for (std::vector<MSLane*>::const_iterator j = lq.bestContinuations.begin(); j != lq.bestContinuations.end(); ++j) {
326  bestContIDs.push_back((*j)->getID());
327  }
328  tempContent.writeUnsignedByte(TYPE_STRINGLIST);
329  tempContent.writeStringList(bestContIDs);
330  ++cnt;
331  }
332  tempMsg.writeInt((int) cnt);
333  tempMsg.writeStorage(tempContent);
334  }
335  break;
336  case VAR_STOPSTATE: {
337  char b = (
338  1 * (v->isStopped() ? 1 : 0) +
339  2 * (v->isParking() ? 1 : 0) +
340  4 * (v->isStoppedTriggered() ? 1 : 0));
341  tempMsg.writeUnsignedByte(TYPE_UBYTE);
342  tempMsg.writeUnsignedByte(b);
343  }
344  break;
345  case DISTANCE_REQUEST:
346  if (!commandDistanceRequest(server, inputStorage, tempMsg, v)) {
347  return false;
348  }
349  break;
350  default:
352  break;
353  }
354  }
355  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_OK, "", outputStorage);
356  server.writeResponseWithLength(outputStorage, tempMsg);
357  return true;
358 }
359 
360 
361 bool
363  tcpip::Storage& outputStorage) {
364  std::string warning = ""; // additional description for response
365  // variable
366  int variable = inputStorage.readUnsignedByte();
367  if (variable != CMD_STOP && variable != CMD_CHANGELANE
368  && variable != CMD_SLOWDOWN && variable != CMD_CHANGETARGET && variable != CMD_RESUME
369  && variable != VAR_ROUTE_ID && variable != VAR_ROUTE
370  && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT
371  && variable != CMD_REROUTE_TRAVELTIME && variable != CMD_REROUTE_EFFORT
372  && variable != VAR_SIGNALS && variable != VAR_MOVE_TO
373  && variable != VAR_LENGTH && variable != VAR_MAXSPEED && variable != VAR_VEHICLECLASS
374  && variable != VAR_SPEED_FACTOR && variable != VAR_SPEED_DEVIATION && variable != VAR_EMISSIONCLASS
375  && variable != VAR_WIDTH && variable != VAR_MINGAP && variable != VAR_SHAPECLASS
376  && variable != VAR_ACCEL && variable != VAR_DECEL && variable != VAR_IMPERFECTION
377  && variable != VAR_TAU
378  && variable != VAR_SPEED && variable != VAR_SPEEDSETMODE && variable != VAR_COLOR
379  && variable != ADD && variable != REMOVE
380  && variable != VAR_MOVE_TO_VTD
381  ) {
382  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Change Vehicle State: unsupported variable specified", outputStorage);
383  }
384  // id
385  std::string id = inputStorage.readString();
386  const bool shouldExist = variable != ADD;
388  if (sumoVehicle == 0) {
389  if (shouldExist) {
390  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
391  }
392  }
393  MSVehicle* v = dynamic_cast<MSVehicle*>(sumoVehicle);
394  if (v == 0 && shouldExist) {
395  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a micro-simulation vehicle", outputStorage);
396  }
397  switch (variable) {
398  case CMD_STOP: {
399  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
400  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description.", outputStorage);
401  }
402  int compoundSize = inputStorage.readInt();
403  if (compoundSize != 4 && compoundSize != 5) {
404  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description of four of five items.", outputStorage);
405  }
406  // read road map position
407  std::string roadId;
408  if (!server.readTypeCheckingString(inputStorage, roadId)) {
409  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first stop parameter must be the edge id given as a string.", outputStorage);
410  }
411  double pos = 0;
412  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
413  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second stop parameter must be the position along the edge given as a double.", outputStorage);
414  }
415  int laneIndex = 0;
416  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
417  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The third stop parameter must be the lane index given as a byte.", outputStorage);
418  }
419  // waitTime
420  SUMOTime waitTime = 0;
421  if (!server.readTypeCheckingInt(inputStorage, waitTime)) {
422  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "The fourth stop parameter must be the waiting time given as an integer.", outputStorage);
423  }
424  // optional stop flags
425  bool parking = false;
426  bool triggered = false;
427  if (compoundSize == 5) {
428  int stopFlags;
429  if (!server.readTypeCheckingByte(inputStorage, stopFlags)) {
430  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The fifth stop parameter must be a byte indicating its parking/triggered status.", outputStorage);
431  }
432  parking = ((stopFlags & 1) != 0);
433  triggered = ((stopFlags & 2) != 0);
434  }
435  // check
436  if (pos < 0) {
437  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Position on lane must not be negative", outputStorage);
438  }
439  // get the actual lane that is referenced by laneIndex
440  MSEdge* road = MSEdge::dictionary(roadId);
441  if (road == 0) {
442  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Unable to retrieve road with given id", outputStorage);
443  }
444  const std::vector<MSLane*>& allLanes = road->getLanes();
445  if ((laneIndex < 0) || laneIndex >= (int)(allLanes.size())) {
446  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "No lane existing with such id on the given road", outputStorage);
447  }
448  // Forward command to vehicle
449  if (!v->addTraciStop(allLanes[laneIndex], pos, 0, waitTime, parking, triggered)) {
450  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Vehicle is too close or behind the stop on " + allLanes[laneIndex]->getID(), outputStorage);
451  }
452  }
453  break;
454  case CMD_RESUME: {
455  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
456  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Resuming requires a compound object.", outputStorage);
457  return false;
458  }
459  if (inputStorage.readInt() != 0) {
460  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Resuming should obtain an empty compound object.", outputStorage);
461  return false;
462  }
463  if (!static_cast<MSVehicle*>(v)->resumeFromStopping()) {
464  MSVehicle::Stop& sto = (static_cast<MSVehicle*>(v))->getNextStop();
465  std::ostringstream strs;
466  strs << "reached: " << sto.reached;
467  strs << ", duration:" << sto.duration;
468  strs << ", edge:" << (*sto.edge)->getID();
469  strs << ", startPos: " << sto.startPos;
470  std::string posStr = strs.str();
471  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Failed to resume a non parking vehicle: " + v->getID() + ", " + posStr, outputStorage);
472  return false;
473  }
474  }
475  break;
476  case CMD_CHANGELANE: {
477  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
478  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description.", outputStorage);
479  }
480  if (inputStorage.readInt() != 2) {
481  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two items.", outputStorage);
482  }
483  // Lane ID
484  int laneIndex = 0;
485  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
486  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first lane change parameter must be the lane index given as a byte.", outputStorage);
487  }
488  // stickyTime
489  SUMOTime stickyTime = 0;
490  if (!server.readTypeCheckingInt(inputStorage, stickyTime)) {
491  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second lane change parameter must be the duration given as an integer.", outputStorage);
492  }
493  if ((laneIndex < 0) || (laneIndex >= (int)(v->getEdge()->getLanes().size()))) {
494  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "No lane existing with given id on the current road", outputStorage);
495  }
496  // Forward command to vehicle
497  std::vector<std::pair<SUMOTime, unsigned int> > laneTimeLine;
498  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), laneIndex));
499  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + stickyTime, laneIndex));
500  v->getInfluencer().setLaneTimeLine(laneTimeLine);
502  *v->getEdge(), v->getLaneIndex());
504  }
505  break;
506  case CMD_SLOWDOWN: {
507  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
508  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description.", outputStorage);
509  }
510  if (inputStorage.readInt() != 2) {
511  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description of two items.", outputStorage);
512  }
513  double newSpeed = 0;
514  if (!server.readTypeCheckingDouble(inputStorage, newSpeed)) {
515  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first slow down parameter must be the speed given as a double.", outputStorage);
516  }
517  if (newSpeed < 0) {
518  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Speed must not be negative", outputStorage);
519  }
520  SUMOTime duration = 0;
521  if (!server.readTypeCheckingInt(inputStorage, duration)) {
522  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second slow down parameter must be the duration given as an integer.", outputStorage);
523  }
524  if (duration < 0) {
525  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid time interval", outputStorage);
526  }
527  std::vector<std::pair<SUMOTime, SUMOReal> > speedTimeLine;
528  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), v->getSpeed()));
529  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + duration, newSpeed));
530  v->getInfluencer().setSpeedTimeLine(speedTimeLine);
531  }
532  break;
533  case CMD_CHANGETARGET: {
534  std::string edgeID;
535  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
536  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Change target requires a string containing the id of the new destination edge as parameter.", outputStorage);
537  }
538  const MSEdge* destEdge = MSEdge::dictionary(edgeID);
539  if (destEdge == 0) {
540  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Can not retrieve road with ID " + edgeID, outputStorage);
541  }
542  // build a new route between the vehicle's current edge and destination edge
543  MSEdgeVector newRoute;
544  const MSEdge* currentEdge = v->getEdge();
546  currentEdge, destEdge, (const MSVehicle * const) v, MSNet::getInstance()->getCurrentTimeStep(), newRoute);
547  // replace the vehicle's route by the new one
548  if (!v->replaceRouteEdges(newRoute, v->getLane() == 0)) {
549  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Route replacement failed for " + v->getID(), outputStorage);
550  }
551  }
552  break;
553  case VAR_ROUTE_ID: {
554  std::string rid;
555  if (!server.readTypeCheckingString(inputStorage, rid)) {
556  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The route id must be given as a string.", outputStorage);
557  }
558  const MSRoute* r = MSRoute::dictionary(rid);
559  if (r == 0) {
560  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The route '" + rid + "' is not known.", outputStorage);
561  }
562  if (!v->replaceRoute(r, v->getLane() == 0)) {
563  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Route replacement failed for " + v->getID(), outputStorage);
564  }
565  }
566  break;
567  case VAR_ROUTE: {
568  std::vector<std::string> edgeIDs;
569  if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {
570  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "A route must be defined as a list of edge ids.", outputStorage);
571  }
572  std::vector<const MSEdge*> edges;
573  MSEdge::parseEdgesList(edgeIDs, edges, "<unknown>");
574  if (!v->replaceRouteEdges(edges, v->getLane() == 0)) {
575  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Route replacement failed for " + v->getID(), outputStorage);
576  }
577  }
578  break;
579  case VAR_EDGE_TRAVELTIME: {
580  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
581  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires a compound object.", outputStorage);
582  }
583  int parameterCount = inputStorage.readInt();
584  if (parameterCount == 4) {
585  // begin time
586  SUMOTime begTime = 0, endTime = 0;
587  if (!server.readTypeCheckingInt(inputStorage, begTime)) {
588  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the begin time as first parameter.", outputStorage);
589  }
590  // begin time
591  if (!server.readTypeCheckingInt(inputStorage, endTime)) {
592  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the end time as second parameter.", outputStorage);
593  }
594  // edge
595  std::string edgeID;
596  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
597  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the referenced edge as third parameter.", outputStorage);
598  }
599  MSEdge* edge = MSEdge::dictionary(edgeID);
600  if (edge == 0) {
601  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
602  }
603  // value
604  double value = 0;
605  if (!server.readTypeCheckingDouble(inputStorage, value)) {
606  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the travel time as double as fourth parameter.", outputStorage);
607  }
608  // retrieve
609  v->getWeightsStorage().addTravelTime(edge, begTime, endTime, value);
610  } else if (parameterCount == 2) {
611  // edge
612  std::string edgeID;
613  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
614  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the referenced edge as first parameter.", outputStorage);
615  }
616  MSEdge* edge = MSEdge::dictionary(edgeID);
617  if (edge == 0) {
618  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
619  }
620  // value
621  double value = 0;
622  if (!server.readTypeCheckingDouble(inputStorage, value)) {
623  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the travel time as second parameter.", outputStorage);
624  }
625  // retrieve
626  while (v->getWeightsStorage().knowsTravelTime(edge)) {
628  }
629  v->getWeightsStorage().addTravelTime(edge, 0, SUMOTime_MAX, value);
630  } else if (parameterCount == 1) {
631  // edge
632  std::string edgeID;
633  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
634  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 1 parameter requires the referenced edge as first parameter.", outputStorage);
635  }
636  MSEdge* edge = MSEdge::dictionary(edgeID);
637  if (edge == 0) {
638  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
639  }
640  // retrieve
641  while (v->getWeightsStorage().knowsTravelTime(edge)) {
643  }
644  } else {
645  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);
646  }
647  }
648  break;
649  case VAR_EDGE_EFFORT: {
650  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
651  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort requires a compound object.", outputStorage);
652  }
653  int parameterCount = inputStorage.readInt();
654  if (parameterCount == 4) {
655  // begin time
656  SUMOTime begTime = 0, endTime = 0;
657  if (!server.readTypeCheckingInt(inputStorage, begTime)) {
658  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the begin time as first parameter.", outputStorage);
659  }
660  // begin time
661  if (!server.readTypeCheckingInt(inputStorage, endTime)) {
662  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the end time as second parameter.", outputStorage);
663  }
664  // edge
665  std::string edgeID;
666  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
667  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the referenced edge as third parameter.", outputStorage);
668  }
669  MSEdge* edge = MSEdge::dictionary(edgeID);
670  if (edge == 0) {
671  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
672  }
673  // value
674  double value = 0;
675  if (!server.readTypeCheckingDouble(inputStorage, value)) {
676  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the travel time as fourth parameter.", outputStorage);
677  }
678  // retrieve
679  v->getWeightsStorage().addEffort(edge, begTime, endTime, value);
680  } else if (parameterCount == 2) {
681  // edge
682  std::string edgeID;
683  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
684  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the referenced edge as first parameter.", outputStorage);
685  }
686  MSEdge* edge = MSEdge::dictionary(edgeID);
687  if (edge == 0) {
688  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
689  }
690  // value
691  double value = 0;
692  if (!server.readTypeCheckingDouble(inputStorage, value)) {
693  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the travel time as second parameter.", outputStorage);
694  }
695  // retrieve
696  while (v->getWeightsStorage().knowsEffort(edge)) {
697  v->getWeightsStorage().removeEffort(edge);
698  }
699  v->getWeightsStorage().addEffort(edge, 0, SUMOTime_MAX, value);
700  } else if (parameterCount == 1) {
701  // edge
702  std::string edgeID;
703  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
704  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 1 parameter requires the referenced edge as first parameter.", outputStorage);
705  }
706  MSEdge* edge = MSEdge::dictionary(edgeID);
707  if (edge == 0) {
708  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
709  }
710  // retrieve
711  while (v->getWeightsStorage().knowsEffort(edge)) {
712  v->getWeightsStorage().removeEffort(edge);
713  }
714  } else {
715  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);
716  }
717  }
718  break;
719  case CMD_REROUTE_TRAVELTIME: {
720  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
721  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
722  }
723  if (inputStorage.readInt() != 0) {
724  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
725  }
726  v->reroute(MSNet::getInstance()->getCurrentTimeStep(), MSNet::getInstance()->getRouterTT());
727  }
728  break;
729  case CMD_REROUTE_EFFORT: {
730  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
731  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
732  }
733  if (inputStorage.readInt() != 0) {
734  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
735  }
736  v->reroute(MSNet::getInstance()->getCurrentTimeStep(), MSNet::getInstance()->getRouterEffort());
737  }
738  break;
739  case VAR_SIGNALS: {
740  int signals = 0;
741  if (!server.readTypeCheckingInt(inputStorage, signals)) {
742  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting signals requires an integer.", outputStorage);
743  }
744  v->switchOffSignal(0x0fffffff);
745  v->switchOnSignal(signals);
746  }
747  break;
748  case VAR_MOVE_TO: {
749  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
750  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting position requires a compound object.", outputStorage);
751  }
752  if (inputStorage.readInt() != 2) {
753  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting position should obtain the lane id and the position.", outputStorage);
754  }
755  // lane ID
756  std::string laneID;
757  if (!server.readTypeCheckingString(inputStorage, laneID)) {
758  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first parameter for setting a position must be the lane ID given as a string.", outputStorage);
759  }
760  // position on lane
761  double position = 0;
762  if (!server.readTypeCheckingDouble(inputStorage, position)) {
763  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second parameter for setting a position must be the position given as a double.", outputStorage);
764  }
765  // process
766  MSLane* l = MSLane::dictionary(laneID);
767  if (l == 0) {
768  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Unknown lane '" + laneID + "'.", outputStorage);
769  }
770  MSEdge& destinationEdge = l->getEdge();
771  if (!v->willPass(&destinationEdge)) {
772  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + laneID + "' may be set onto an edge to pass only.", outputStorage);
773  }
776  while (v->getEdge() != &destinationEdge) {
777  const MSEdge* nextEdge = v->succEdge(1);
778  // let the vehicle move to the next edge
779  if (v->enterLaneAtMove(nextEdge->getLanes()[0], true)) {
781  continue;
782  }
783  }
784  l->forceVehicleInsertion(v, position);
785  }
786  break;
787  case VAR_SPEED: {
788  double speed = 0;
789  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
790  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting speed requires a double.", outputStorage);
791  }
792  std::vector<std::pair<SUMOTime, SUMOReal> > speedTimeLine;
793  if (speed >= 0) {
794  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), speed));
795  speedTimeLine.push_back(std::make_pair(SUMOTime_MAX, speed));
796  }
797  v->getInfluencer().setSpeedTimeLine(speedTimeLine);
798  }
799  break;
800  case VAR_SPEEDSETMODE: {
801  int speedMode = 0;
802  if (!server.readTypeCheckingInt(inputStorage, speedMode)) {
803  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting speed mode requires an integer.", outputStorage);
804  }
805  v->getInfluencer().setConsiderSafeVelocity((speedMode & 1) != 0);
806  v->getInfluencer().setConsiderMaxAcceleration((speedMode & 2) != 0);
807  v->getInfluencer().setConsiderMaxDeceleration((speedMode & 4) != 0);
808  }
809  break;
810  case VAR_COLOR: {
811  RGBColor col;
812  if (!server.readTypeCheckingColor(inputStorage, col)) {
813  return server.writeErrorStatusCmd(CMD_SET_POLYGON_VARIABLE, "The color must be given using the according type.", outputStorage);
814  }
815  v->getParameter().color.set(col.red(), col.green(), col.blue(), col.alpha());
817  }
818  break;
819  case ADD: {
820  if (v != 0) {
821  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The vehicle " + id + " to add already exists.", outputStorage);
822  }
823  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
824  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle requires a compound object.", outputStorage);
825  }
826  if (inputStorage.readInt() != 6) {
827  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle needs six parameters.", outputStorage);
828  }
829  SUMOVehicleParameter vehicleParams;
830  vehicleParams.id = id;
831 
832  std::string vTypeID;
833  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
834  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "First parameter (type) requires a string.", outputStorage);
835  }
836  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(vTypeID);
837  if (!vehicleType) {
838  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid type '" + vTypeID + "' for vehicle '" + id + "'", outputStorage);
839  }
840 
841  std::string routeID;
842  if (!server.readTypeCheckingString(inputStorage, routeID)) {
843  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Second parameter (route) requires a string.", outputStorage);
844  }
845  const MSRoute* route = MSRoute::dictionary(routeID);
846  if (!route) {
847  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid route '" + routeID + "' for vehicle: '" + id + "'", outputStorage);
848  }
849 
850  if (!server.readTypeCheckingInt(inputStorage, vehicleParams.depart)) {
851  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Third parameter (depart) requires an integer.", outputStorage);
852  }
853  if (vehicleParams.depart < 0) {
854  const int proc = static_cast<int>(-vehicleParams.depart);
855  if (proc >= static_cast<int>(DEPART_DEF_MAX)) {
856  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure time.", outputStorage);
857  }
858  vehicleParams.departProcedure = (DepartDefinition)proc;
859  }
860 
861  double pos;
862  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
863  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Fourth parameter (position) requires a double.", outputStorage);
864  }
865  vehicleParams.departPos = pos;
866  if (vehicleParams.departPos < 0) {
867  const int proc = static_cast<int>(-vehicleParams.departPos);
868  if (proc >= static_cast<int>(DEPART_POS_DEF_MAX)) {
869  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure position.", outputStorage);
870  }
871  vehicleParams.departPosProcedure = (DepartPosDefinition)proc;
872  } else {
873  vehicleParams.departPosProcedure = DEPART_POS_GIVEN;
874  }
875 
876  double speed;
877  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
878  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Fifth parameter (speed) requires a double.", outputStorage);
879  }
880  vehicleParams.departSpeed = speed;
881  if (vehicleParams.departSpeed < 0) {
882  const int proc = static_cast<int>(-vehicleParams.departSpeed);
883  if (proc >= static_cast<int>(DEPART_SPEED_DEF_MAX)) {
884  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure speed.", outputStorage);
885  }
886  vehicleParams.departSpeedProcedure = (DepartSpeedDefinition)proc;
887  } else {
889  }
890 
891  if (!server.readTypeCheckingByte(inputStorage, vehicleParams.departLane)) {
892  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Sixth parameter (lane) requires a byte.", outputStorage);
893  }
894 
895  if (vehicleParams.departLane < 0) {
896  const int proc = static_cast<int>(-vehicleParams.departLane);
897  if (proc >= static_cast<int>(DEPART_LANE_DEF_MAX)) {
898  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure lane.", outputStorage);
899  }
900  vehicleParams.departLaneProcedure = (DepartLaneDefinition)proc;
901  } else {
902  vehicleParams.departLaneProcedure = DEPART_LANE_GIVEN;
903  }
904 
906  *params = vehicleParams;
907  try {
908  SUMOVehicle* vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(params, route, vehicleType);
909  MSNet::getInstance()->getVehicleControl().addVehicle(vehicleParams.id, vehicle);
911  } catch (ProcessError& e) {
912  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
913  }
914  }
915  break;
916  case REMOVE: {
917  int why = 0;
918  if (!server.readTypeCheckingByte(inputStorage, why)) {
919  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Removing a vehicle requires a byte.", outputStorage);
920  }
922  switch (why) {
923  case REMOVE_TELEPORT:
924  // XXX semantics unclear
925  // n = MSMoveReminder::NOTIFICATION_TELEPORT;
927  break;
928  case REMOVE_PARKING:
929  // XXX semantics unclear
930  // n = MSMoveReminder::NOTIFICATION_PARKING;
932  break;
933  case REMOVE_ARRIVED:
935  break;
936  case REMOVE_VAPORIZED:
938  break;
941  break;
942  default:
943  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Unknown removal status.", outputStorage);
944  }
945  if (v->hasDeparted()) {
946  v->onRemovalFromNet(n);
947  if (v->getLane() != 0) {
948  v->getLane()->removeVehicle(v, n);
949  }
951  }
952  }
953  break;
954  case VAR_MOVE_TO_VTD: {
955  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
956  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting VTD vehicle requires a compound object.", outputStorage);
957  }
958  if (inputStorage.readInt() != 4) {
959  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting VTD vehicle should obtain: edgeID, lane, x, y.", outputStorage);
960  }
961  // edge ID
962  std::string edgeID;
963  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
964  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first parameter for setting a VTD vehicle must be the edge ID given as a string.", outputStorage);
965  }
966  // lane index
967  int laneNum = 0;
968  if (!server.readTypeCheckingInt(inputStorage, laneNum)) {
969  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second parameter for setting a VTD vehicle must be lane given as an int.", outputStorage);
970  }
971  // x
972  double x = 0, y = 0;
973  if (!server.readTypeCheckingDouble(inputStorage, x)) {
974  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The third parameter for setting a VTD vehicle must be the x-position given as a double.", outputStorage);
975  }
976  // y
977  if (!server.readTypeCheckingDouble(inputStorage, y)) {
978  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The fourth parameter for setting a VTD vehicle must be the y-position given as a double.", outputStorage);
979  }
980  // process
981  if (!v->isOnRoad()) {
982  break;
983  }
984  std::string origID = edgeID + " " + toString(laneNum);
985  if (laneNum < 0) {
986  edgeID = '-' + edgeID;
987  laneNum = -laneNum;
988  }
989  Position pos(x, y);
990 
991  Position vehPos = v->getPosition();
992  v->getBestLanes();
993  bool report = server.vtdDebug();
994  if (report) {
995  std::cout << std::endl << "begin vehicle " << v->getID() << " vehPos:" << vehPos << " lane:" << v->getLane()->getID() << std::endl;
996  }
997  if (report) {
998  std::cout << " want pos:" << pos << " edge:" << edgeID << " laneNum:" << laneNum << std::endl;
999  }
1000 
1001  MSEdgeVector edgesA, edgesB, edgesC;
1002  MSLane* laneA, *laneB, *laneC;
1003  laneA = laneB = laneC = 0;
1004  SUMOReal lanePosA, lanePosB, lanePosC;
1005  SUMOReal bestDistanceA, bestDistanceB, bestDistanceC;
1006  bestDistanceA = bestDistanceB = bestDistanceC = 1000.;//pos.distanceSquaredTo2D(vehPos);
1007  int routeOffsetA, routeOffsetB, routeOffsetC;
1008  routeOffsetA = routeOffsetB = routeOffsetC = 0;
1009  // case a): edge/lane is known and matches route
1010  bool aFound = vtdMap_matchingEdgeLane(pos, origID, *v, server.vtdDebug(), bestDistanceA, &laneA, lanePosA, routeOffsetA, edgesA);
1011  // case b): position is at route, should be somewhere near to it
1012  bool bFound = vtdMap_matchingRoutePosition(pos, origID, *v, server.vtdDebug(), bestDistanceB, &laneB, lanePosB, routeOffsetB, edgesB);
1013  // case c) nearest matching lane
1014  bool cFound = vtdMap_matchingNearest(pos, origID, *v, server, server.vtdDebug(), bestDistanceC, &laneC, lanePosC, routeOffsetC, edgesC);
1015  //
1016  SUMOReal maxRouteDistance = 50;
1017  if (cFound && (bestDistanceA > maxRouteDistance && bestDistanceC > maxRouteDistance)) {
1018  // both route-based approach yield in a position too far away from the submitted --> new route!?
1019  server.setVTDControlled(v, laneC, lanePosC, routeOffsetC, edgesC);
1020  } else {
1021  // use the best we have
1022  if (bFound) {
1023  server.setVTDControlled(v, laneB, lanePosB, routeOffsetB, edgesB);
1024  } else if (aFound) {
1025  server.setVTDControlled(v, laneA, lanePosA, routeOffsetA, edgesA);
1026  } else if (cFound) {
1027  server.setVTDControlled(v, laneC, lanePosC, routeOffsetC, edgesC);
1028  } else {
1029  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Could not map vehicle.", outputStorage);
1030  }
1031  }
1032  }
1033  break;
1034  default:
1035  try {
1036  if (!TraCIServerAPI_VehicleType::setVariable(CMD_SET_VEHICLE_VARIABLE, variable, getSingularType(v), server, inputStorage, outputStorage)) {
1037  return false;
1038  }
1039  } catch (ProcessError& e) {
1040  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1041  }
1042  break;
1043  }
1044  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_OK, warning, outputStorage);
1045  return true;
1046 }
1047 
1048 
1049 bool
1050 TraCIServerAPI_Vehicle::vtdMap_matchingEdgeLane(const Position& pos, const std::string& origID, MSVehicle& v, bool report,
1051  SUMOReal& bestDistance, MSLane** lane, SUMOReal& lanePos, int& routeOffset, MSEdgeVector& edges) {
1052  const std::map<std::string, std::vector<MSLane*> >& vtdMap = getOrBuildVTDMap();
1053  if (vtdMap.find(origID) == vtdMap.end()) {
1054  if (report) {
1055  std::cout << " a failed - lane not in map" << std::endl;
1056  }
1057  return false;
1058  }
1059  const std::vector<MSLane*>& lanes = vtdMap.find(origID)->second;
1060  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end() && bestDistance > POSITION_EPS; ++i) {
1061  MSLane* l = *i;
1062  SUMOReal dist = l->getShape().distance(pos);
1063  if (report) {
1064  std::cout << " a at lane " << l->getID() << " dist:" << dist << " best:" << bestDistance << std::endl;
1065  }
1066  if (dist < bestDistance) {
1067  bestDistance = dist;
1068  *lane = l;
1069  }
1070  }
1071  MSLane* pni = *lane;
1072  while (pni != 0 && pni->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL && pni->getIncomingLanes().size() != 0) {
1073  pni = pni->getIncomingLanes()[0].lane;
1074  }
1075  if (pni == 0 || pni->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1076  // not found
1077  if (report) {
1078  std::cout << " a failed - no incoming lane" << std::endl;
1079  }
1080  return false;
1081  }
1082  const MSEdgeVector& tedges = v.getRoute().getEdges();
1083  MSEdgeVector::const_iterator p = std::find(tedges.begin() + v.getRoutePosition(), tedges.end(), &pni->getEdge());
1084  if (p != tedges.end()) {
1085  lanePos = MAX2(SUMOReal(0), MIN2(SUMOReal((*lane)->getLength() - POSITION_EPS), (*lane)->getShape().nearest_offset_to_point2D(pos, false)));
1086  routeOffset = (int)(std::distance(tedges.begin(), p) - v.getRoutePosition());
1087  if (report) {
1088  std::cout << " a ok lane:" << (*lane)->getID() << " lanePos:" << lanePos << " routeOffset:" << routeOffset << std::endl;
1089  }
1090  return true;
1091  }
1092  if (report) {
1093  std::cout << " a failed - route position beyond route length" << std::endl;
1094  }
1095  return false;
1096 }
1097 
1098 
1099 bool
1100 TraCIServerAPI_Vehicle::vtdMap_matchingRoutePosition(const Position& pos, const std::string& origID, MSVehicle& v, bool report,
1101  SUMOReal& bestDistance, MSLane** lane, SUMOReal& lanePos, int& routeOffset, MSEdgeVector& edges) {
1102 
1103  int lastBestRouteEdge = 0;
1104  int lastRouteEdge = 0;
1105  MSLane* bestRouteLane = 0;
1106  const std::vector<MSLane*>& bestLaneConts = v.getBestLanesContinuation(v.getLane());
1107  for (std::vector<MSLane*>::const_iterator i = bestLaneConts.begin(); i != bestLaneConts.end() && bestDistance > POSITION_EPS; ++i) {
1108  MSEdge& e = (*i)->getEdge();
1109  if (i != bestLaneConts.begin() && e.getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1110  ++lastRouteEdge;
1111  }
1112  const std::vector<MSLane*>& lanes = e.getLanes();
1113  for (std::vector<MSLane*>::const_iterator k = lanes.begin(); k != lanes.end() && bestDistance > POSITION_EPS; ++k) {
1114  MSLane* cl = *k;
1115  SUMOReal dist = cl->getShape().distance(pos);
1116  if (report) {
1117  std::cout << " b at lane " << cl->getID() << " dist:" << dist << " best:" << bestDistance << std::endl;
1118  }
1119  if (dist < bestDistance) {
1120  bestDistance = dist;
1121  *lane = cl;
1122  lastBestRouteEdge = lastRouteEdge;
1124  bestRouteLane = *i;
1125  } else {
1126  bestRouteLane = *lane;
1127  }
1128  }
1129  }
1130  }
1131  if (bestRouteLane == 0) {
1132  if (report) {
1133  std::cout << " b failed - no best route lane" << std::endl;
1134  }
1135  return false;
1136  }
1137  lanePos = MAX2(SUMOReal(0), MIN2(SUMOReal(bestRouteLane->getLength() - POSITION_EPS), bestRouteLane->getShape().nearest_offset_to_point2D(pos, false)));
1138  routeOffset = lastBestRouteEdge;
1139  if (report) {
1140  std::cout << " b ok lane " << bestRouteLane->getID() << " lanePos:" << lanePos << " best:" << lastBestRouteEdge << std::endl;
1141  }
1142  return true;
1143 }
1144 
1145 
1146 bool
1147 TraCIServerAPI_Vehicle::vtdMap_matchingNearest(const Position& pos, const std::string& origID, MSVehicle& v, traci::TraCIServer& server, bool report,
1148  SUMOReal& bestDistance, MSLane** lane, SUMOReal& lanePos, int& routeOffset, MSEdgeVector& edges) {
1149  unsigned int r = 0;
1150  SUMOReal minDist = 1 << (11);
1151  MSLane* minDistLane = 0;
1152  MSLane* nameMatchingLane = 0;
1153  SUMOReal minDistNameMatchingLane = 1 << (11);
1154  for (; minDistLane == 0 && r < 10 && nameMatchingLane == 0; ++r) {
1155  std::set<std::string> into;
1156  PositionVector shape;
1157  shape.push_back(pos);
1158  server.collectObjectsInRange(CMD_GET_EDGE_VARIABLE, shape, 1 << r, into);
1159  for (std::set<std::string>::const_iterator j = into.begin(); j != into.end(); ++j) {
1160  MSEdge* e = MSEdge::dictionary(*j);
1161  const std::vector<MSLane*>& lanes = e->getLanes();
1162  for (std::vector<MSLane*>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
1163  MSLane* lane = *k;
1164  SUMOReal dist = lane->getShape().distance(pos);
1165  if (lane->knowsParameter("origId")) {
1166  if (lane->getParameter("origId", "") == origID) {
1167  if (dist < minDistNameMatchingLane) {
1168  minDistNameMatchingLane = dist;
1169  nameMatchingLane = lane;
1170  }
1171  }
1172  }
1173  if (dist < minDist) {
1174  minDist = dist;
1175  minDistLane = lane;
1176  }
1177  }
1178  }
1179  }
1180  *lane = nameMatchingLane != 0 ? nameMatchingLane : minDistLane;
1181  if (lane == 0) {
1182  if (report) {
1183  std::cout << " c failed - no matching lane" << std::endl;
1184  }
1185  return false;
1186  }
1187  lanePos = (*lane)->interpolateGeometryPosToLanePos((*lane)->getShape().nearest_offset_to_point2D(pos, false));
1188  if (*lane == v.getLane()) {
1189  routeOffset = 0;
1190  if (report) {
1191  std::cout << " c ok, on same lane" << std::endl;
1192  }
1193  return true;
1194  }
1195  MSEdge& destinationEdge = (*lane)->getEdge();
1196  MSEdge* routePos = &destinationEdge;
1197  while (routePos->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1198  routePos = &routePos->getLanes()[0]->getLogicalPredecessorLane()->getEdge();
1199  }
1200  r = 0;
1201  const MSRoute& route = v.getRoute();
1202  unsigned int c = v.getRoutePosition();
1203  unsigned int l = (int)route.getEdges().size();
1204  unsigned int rindex = 0;
1205  bool found = false;
1206  while (!found && ((int)(c - r) >= 0 || c + r < l)) {
1207  if ((int)(c - r) >= 0 && route[c - r] == routePos) {
1208  rindex = c - r;
1209  found = true;
1210  }
1211  if (c + r < l && route[c + r] == routePos) {
1212  rindex = c + r;
1213  found = true;
1214  }
1215  ++r;
1216  }
1217  if (found) {
1218  // the matching lane is part of the route
1219  routeOffset = rindex - v.getRoutePosition();
1220  if (report) {
1221  std::cout << " c ok, on a different edge of same route" << std::endl;
1222  }
1223  return true;
1224  }
1225  // build new route
1226  MSLane* firstLane = *lane;
1227  if (destinationEdge.getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1228  edges.push_back(&destinationEdge);
1229  } else {
1230  firstLane = (*lane)->getLogicalPredecessorLane();
1231  edges.push_back(&firstLane->getEdge());
1232  }
1233  const MSLinkCont& lc = firstLane->getLinkCont();
1234  if (lc.size() != 0 && lc[0]->getLane() != 0) {
1235  edges.push_back(&lc[0]->getLane()->getEdge());
1236  }
1237  if (report) {
1238  std::cout << " c ok, on a different route" << std::endl;
1239  }
1240  return true;
1241 }
1242 
1243 
1244 bool
1246  tcpip::Storage& outputStorage, const MSVehicle* v) {
1247  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
1248  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of distance requires a compound object.", outputStorage);
1249  }
1250  if (inputStorage.readInt() != 2) {
1251  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of distance requires position and distance type as parameter.", outputStorage);
1252  }
1253 
1254  Position pos;
1255  std::pair<const MSLane*, SUMOReal> roadPos;
1256 
1257  // read position
1258  int posType = inputStorage.readUnsignedByte();
1259  switch (posType) {
1260  case POSITION_ROADMAP:
1261  try {
1262  std::string roadID = inputStorage.readString();
1263  roadPos.second = inputStorage.readDouble();
1264  roadPos.first = TraCIServerAPI_Simulation::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos.second);
1265  pos = roadPos.first->getShape().positionAtOffset(roadPos.second);
1266  } catch (TraCIException& e) {
1267  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, e.what(), outputStorage);
1268  }
1269  break;
1270  case POSITION_2D:
1271  case POSITION_3D: {
1272  const double p1x = inputStorage.readDouble();
1273  const double p1y = inputStorage.readDouble();
1274  pos.set(p1x, p1y);
1275  }
1276  if (posType == POSITION_3D) {
1277  inputStorage.readDouble(); // z value is ignored
1278  }
1280  break;
1281  default:
1282  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Unknown position format used for distance request", outputStorage);
1283  }
1284 
1285  // read distance type
1286  int distType = inputStorage.readUnsignedByte();
1287 
1288  SUMOReal distance = INVALID_DOUBLE_VALUE;
1289  if (v->isOnRoad()) {
1290  if (distType == REQUEST_DRIVINGDIST) {
1291  distance = v->getRoute().getDistanceBetween(v->getPositionOnLane(), roadPos.second,
1292  v->getEdge(), &roadPos.first->getEdge());
1293  if (distance == std::numeric_limits<SUMOReal>::max()) {
1294  distance = INVALID_DOUBLE_VALUE;
1295  }
1296  } else {
1297  // compute air distance (default)
1298  distance = v->getPosition().distanceTo(pos);
1299  }
1300  }
1301  // write response command
1302  outputStorage.writeUnsignedByte(TYPE_DOUBLE);
1303  outputStorage.writeDouble(distance);
1304  return true;
1305 }
1306 
1307 
1308 // ------ helper functions ------
1309 bool
1310 TraCIServerAPI_Vehicle::getPosition(const std::string& id, Position& p) {
1311  MSVehicle* v = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(id));
1312  if (v == 0) {
1313  return false;
1314  }
1315  p = v->getPosition();
1316  return true;
1317 }
1318 
1319 
1322  const MSVehicleType& oType = veh->getVehicleType();
1323  std::string newID = oType.getID().find('@') == std::string::npos ? oType.getID() + "@" + veh->getID() : oType.getID();
1324  MSVehicleType* type = MSVehicleType::build(newID, &oType);
1325  static_cast<MSVehicle*>(veh)->replaceVehicleType(type);
1326  return *type;
1327 }
1328 
1329 
1330 #include <microsim/MSEdgeControl.h>
1331 
1332 const std::map<std::string, std::vector<MSLane*> >&
1334  if (gVTDMap.size() == 0) {
1335  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
1336  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
1337  const std::vector<MSLane*>& lanes = (*i)->getLanes();
1338  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
1339  if ((*j)->knowsParameter("origId")) {
1340  std::string origID = (*j)->getParameter("origId", "");
1341  if (gVTDMap.find(origID) == gVTDMap.end()) {
1342  gVTDMap[origID] = std::vector<MSLane*>();
1343  }
1344  gVTDMap[origID].push_back(*j);
1345  }
1346  }
1347  }
1348  if (gVTDMap.size() == 0) {
1349  gVTDMap["unknown"] = std::vector<MSLane*>();
1350  }
1351  }
1352  return gVTDMap;
1353 }
1354 
1355 
1356 #endif
1357 
1358 
1359 /****************************************************************************/
1360 
#define VAR_ROAD_ID
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:617
static SUMOReal computeCO(SUMOEmissionClass c, double v, double a)
Returns the amount of emitted CO given the vehicle type and state (in mg/s)
#define REMOVE_PARKING
virtual const std::vector< LaneQ > & getBestLanes(bool forceRebuild=false, MSLane *startLane=0) const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:1539
bool enterLaneAtMove(MSLane *enteredLane, bool onTeleporting=false)
Update when the vehicle enters a new lane in the move step.
Definition: MSVehicle.cpp:1369
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:442
RGBColor color
The vehicle&#39;s color.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
#define VAR_EMISSIONCLASS
void reroute(SUMOTime t, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, bool withTaz=false)
Performs a rerouting using the given router.
static bool vtdMap_matchingRoutePosition(const Position &pos, const std::string &origID, MSVehicle &v, bool report, SUMOReal &bestDistance, MSLane **lane, SUMOReal &lanePos, int &routeOffset, MSEdgeVector &edges)
#define VAR_CO2EMISSION
#define REQUEST_DRIVINGDIST
#define VAR_LENGTH
static SUMOReal computeHC(SUMOEmissionClass c, double v, double a)
Returns the amount of emitted HC given the vehicle type and state (in mg/s)
#define RESPONSE_GET_VEHICLE_VARIABLE
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
static MSVehicleType & getSingularType(SUMOVehicle *const veh)
#define CMD_GET_VEHICLE_VARIABLE
#define TYPE_COMPOUND
static std::map< std::string, std::vector< MSLane * > > gVTDMap
constVehIt loadedVehBegin() const
Returns the begin of the internal vehicle map.
#define CMD_RESUME
#define POSITION_2D
#define VAR_POSITION
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:167
static const MSLane * getLaneChecking(std::string roadID, int laneIndex, SUMOReal pos)
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
Definition: MSVehicle.h:446
#define VAR_ROUTE
#define CMD_CHANGELANE
#define VAR_SPEEDSETMODE
#define VAR_TAU
static bool dictionary(std::string id, MSLane *lane)
Inserts a MSLane into the static dictionary Returns true if the key id isn&#39;t already in the dictionar...
Definition: MSLane.cpp:807
MSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:59
SUMOReal getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:2012
bool retrieveExistingTravelTime(const MSEdge *const e, const SUMOVehicle *const v, SUMOReal t, SUMOReal &value) const
Returns a travel time for an edge and time if stored.
#define CMD_STOP
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:360
SUMOReal departSpeed
(optional) The initial speed of the vehicle
static bool processGet(traci::TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa4: Get Vehicle Variable)
#define TYPE_UBYTE
The position is given.
#define RTYPE_OK
#define POSITION_ROADMAP
#define DISTANCE_REQUEST
Tag for the last element in the enum for safe int casting.
static bool getVariable(const int variable, const MSVehicleType &v, tcpip::Storage &tempMsg)
Processes a value request for the given type.
virtual double readDouble()
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID)
Returns the named vehicle type or a sample from the named distribution.
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
#define VAR_SIGNALS
#define VAR_TYPE
#define VAR_ROUTE_ID
Notification
Definition of a vehicle state.
#define VAR_VEHICLECLASS
const MSEdgeVector & getEdges() const
Definition: MSRoute.h:122
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
#define VAR_SPEED_FACTOR
#define VAR_COLOR
static bool getPosition(const std::string &id, Position &p)
Returns the named vehicle&#39;s position.
bool reached
Information whether the stop has been reached.
Definition: MSVehicle.h:553
bool readTypeCheckingStringList(tcpip::Storage &inputStorage, std::vector< std::string > &into)
Reads the value type and a string list, verifying the type.
bool replaceRouteEdges(const MSEdgeVector &edges, bool onInit=false)
Replaces the current route by the given edges.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:150
T MAX2(T a, T b)
Definition: StdDefs.h:63
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:86
unsigned int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:1897
#define TYPE_COLOR
#define TYPE_STRINGLIST
bool hasDeparted() const
Returns whether this vehicle has already departed.
The vehicle got vaporized.
#define POSITION_3D
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn&#39;t already in the dictionary...
Definition: MSEdge.cpp:461
virtual bool addVehicle(const std::string &id, SUMOVehicle *v)
Tries to insert the vehicle into the internal vehicle container.
static std::pair< MSLane *, SUMOReal > convertCartesianToRoadMap(Position pos)
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:533
#define VAR_BEST_LANES
SUMOReal distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:208
Position getPosition(SUMOReal offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:484
SUMOReal getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:284
virtual void writeUnsignedByte(int)
SUMOReal getDistanceBetween(SUMOReal fromPos, SUMOReal toPos, const MSEdge *fromEdge, const MSEdge *toEdge) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:250
bool retrieveExistingEffort(const MSEdge *const e, const SUMOVehicle *const v, SUMOReal t, SUMOReal &value) const
Returns an effort for an edge and time if stored.
const std::string & getParameter(const std::string &key, const std::string &defaultValue) const
Returns the value for a given key.
constVehIt loadedVehEnd() const
Returns the end of the internal vehicle map.
Tag for the last element in the enum for safe int casting.
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
#define VAR_SPEED_DEVIATION
SUMOReal length
The overall length which may be driven when using this lane without a lane change.
Definition: MSVehicle.h:440
#define VAR_NOISEEMISSION
#define VAR_FUELCONSUMPTION
void addEffort(const MSEdge *const e, SUMOReal begin, SUMOReal end, SUMOReal value)
Adds an effort information for an edge and a time span.
static MSVehicleType * build(SUMOVTypeParameter &from)
Builds the microsim vehicle type described by the given parameter.
virtual void writeInt(int)
The speed is given.
The car-following model and parameter.
Definition: MSVehicleType.h:74
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:1527
#define TYPE_STRING
virtual int readUnsignedByte()
The lane is given.
void addTravelTime(const MSEdge *const e, SUMOReal begin, SUMOReal end, SUMOReal value)
Adds a travel time information for an edge and a time span.
SUMOReal nextOccupation
As occupation, but without the first lane.
Definition: MSVehicle.h:444
#define VAR_NOXEMISSION
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:91
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, const MSVehicleType *type)
Builds a vehicle, increases the number of built vehicles.
static SUMOReal computeNoise(SUMOEmissionClass c, double v, double a)
Returns the noise produced by the a vehicle of the given type at the given speed. ...
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:76
#define VAR_ANGLE
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
static bool vtdMap_matchingNearest(const Position &pos, const std::string &origID, MSVehicle &v, traci::TraCIServer &server, bool report, SUMOReal &bestDistance, MSLane **lane, SUMOReal &lanePos, int &routeOffset, MSEdgeVector &edges)
const std::string & getID() const
Returns the id.
Definition: Named.h:60
A road/street connecting two junctions.
Definition: MSEdge.h:73
static void parseEdgesList(const std::string &desc, std::vector< const MSEdge * > &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
Definition: MSEdge.cpp:524
MSLane * lane
The described lane.
Definition: MSVehicle.h:438
#define VAR_PERSON_NUMBER
static bool commandDistanceRequest(traci::TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage, const MSVehicle *v)
#define CMD_SLOWDOWN
MSLane * getLogicalPredecessorLane() const
Definition: MSLane.cpp:1175
#define VAR_SHAPECLASS
#define max(a, b)
Definition: polyfonts.c:61
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
void removeEffort(const MSEdge *const e)
Removes the effort information for an edge.
static bool setVariable(const int cmd, const int variable, MSVehicleType &v, traci::TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value for the given type.
#define REMOVE_ARRIVED
DepartLaneDefinition
Possible ways to choose a lane on depart.
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification)
remove the vehicle from this lane
Definition: MSLane.cpp:958
#define VAR_ACCEL
bool addTraciStop(MSLane *lane, SUMOReal pos, SUMOReal radius, SUMOTime duration, bool parking, bool triggered)
Definition: MSVehicle.cpp:1958
#define CMD_CHANGETARGET
Representation of a vehicle.
Definition: SUMOVehicle.h:63
virtual int readInt()
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
#define REMOVE_TELEPORT_ARRIVED
std::vector< const MSEdge * > MSEdgeVector
Definition: MSPerson.h:53
bool replaceRoute(const MSRoute *route, bool onInit=false)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:356
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, unsigned int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:161
static bool processSet(traci::TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc4: Change Vehicle State)
ChangeRequest
Requests set via TraCI.
Definition: MSVehicle.h:125
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the subpart of best lanes that describes the vehicle&#39;s current lane and their successors...
Definition: MSVehicle.cpp:1767
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
void set(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
assigns new values
Definition: RGBColor.cpp:85
bool willPass(const MSEdge *const edge) const
Returns whether the vehicle wil pass the given edge.
Definition: MSVehicle.cpp:397
#define VAR_LANEPOSITION
A list of positions.
static SUMOReal computeCO2(SUMOEmissionClass c, double v, double a)
Returns the amount of emitted CO2 given the vehicle type and state (in mg/s)
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:248
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.h:99
virtual void writeByte(int)
#define REMOVE_TELEPORT
const MSEdge * succEdge(unsigned int nSuccs) const
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
void setVTDControlled(MSVehicle *v, MSLane *l, SUMOReal pos, int edgeOffset, MSEdgeVector route)
The vehicle arrived at its destination (is deleted)
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:586
SUMOReal distance(const Position &p) const
virtual void writeStringList(const std::vector< std::string > &s)
SUMOTime depart
The vehicle&#39;s departure time.
#define VAR_PMXEMISSION
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:545
#define CMD_SET_VEHICLE_VARIABLE
T MIN2(T a, T b)
Definition: StdDefs.h:57
#define VAR_IMPERFECTION
#define POSITION_EPS
Definition: config.h:192
ChangeRequest checkForLaneChanges(SUMOTime currentTime, const MSEdge &currentEdge, unsigned int currentLaneIndex)
Definition: MSVehicle.cpp:200
virtual std::string readString()
#define CMD_GET_EDGE_VARIABLE
Tag for the last element in the enum for safe int casting.
A structure representing the best lanes for continuing the route.
Definition: MSVehicle.h:436
#define VAR_EDGES
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:337
#define VAR_EDGE_EFFORT
#define CMD_REROUTE_EFFORT
#define VAR_STOPSTATE
#define ADD
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:51
#define REMOVE
const int VEHPARS_COLOR_SET
virtual void writeStorage(tcpip::Storage &store)
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:592
bool allowsContinuation
Whether this lane allows to continue the drive.
Definition: MSVehicle.h:448
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
#define INVALID_DOUBLE_VALUE
#define VAR_SPEED
DepartSpeedDefinition
Possible ways to choose the departure speed.
virtual void requestLaneChange(MSVehicle::ChangeRequest request)
#define VAR_EDGE_TRAVELTIME
bool vtdDebug() const
void push_back(const PositionVector &p)
Appends all positions from the given vector.
#define CMD_SET_POLYGON_VARIABLE
#define VAR_COEMISSION
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, SUMOReal > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:154
virtual void writeString(const std::string &s)
void removeTravelTime(const MSEdge *const e)
Removes the travel time information for an edge.
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:203
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2003
void scheduleVehicleRemoval(SUMOVehicle *veh)
Removes a vehicle after it has ended.
Structure representing possible vehicle parameter.
#define INVALID_INT_VALUE
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:81
#define VAR_MOVE_TO
#define SUMOTime_MAX
Definition: SUMOTime.h:44
#define TYPE_DOUBLE
void setConsiderMaxDeceleration(bool value)
Sets whether the maximum deceleration shall be regarded.
Definition: MSVehicle.cpp:236
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:279
int setParameter
Information for the router which parameter were set.
SUMOReal getAcceleration() const
Returns the vehicle&#39;s acceleration.
Definition: MSVehicle.h:300
#define CMD_REROUTE_TRAVELTIME
bool readTypeCheckingByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and a byte, verifying the type.
std::vector< MSLane * > bestContinuations
Consecutive lane that can be followed without a lane change (contribute to length and occupation) ...
Definition: MSVehicle.h:450
#define TYPE_BYTE
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:94
void set(SUMOReal x, SUMOReal y)
Definition: Position.h:78
void setConsiderSafeVelocity(bool value)
Sets whether the safe velocity shall be regarded.
Definition: MSVehicle.cpp:224
static SUMOReal computeNOx(SUMOEmissionClass c, double v, double a)
Returns the amount of emitted NOx given the vehicle type and state (in mg/s)
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:535
const std::string & getID() const
Returns the name of the vehicle type.
static bool vtdMap_matchingEdgeLane(const Position &pos, const std::string &origID, MSVehicle &v, bool report, SUMOReal &bestDistance, MSLane **lane, SUMOReal &lanePos, int &routeOffset, MSEdgeVector &edges)
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const std::vector< MSEdge * > &prohibited=std::vector< MSEdge * >()) const
Definition: MSNet.cpp:703
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:292
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
std::map< std::string, SUMOVehicle * >::const_iterator constVehIt
Definition of the internal vehicles map iterator.
SUMOReal departPos
(optional) The position the vehicle shall depart from
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
virtual void writeDouble(double)
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
Definition: MSVehicle.cpp:598
#define REMOVE_VAPORIZED
unsigned size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:87
static SUMOReal computeFuel(SUMOEmissionClass c, double v, double a)
Returns the amount of consumed fuel given the vehicle type and state (in ml/s)
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:318
#define VAR_MOVE_TO_VTD
const std::vector< MSEdge * > & getEdges() const
Returns loaded edges.
bool knowsEffort(const MSEdge *const e) const
Returns the information whether any effort is known for the given edge.
bool hasValidRoute(std::string &msg) const
Validates the current route.
static SUMOReal computePMx(SUMOEmissionClass c, double v, double a)
Returns the amount of emitted PMx given the vehicle type and state (in mg/s)
int getSignals() const
Returns the signals.
Definition: MSVehicle.h:739
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:83
#define SUMOReal
Definition: config.h:221
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:731
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:723
virtual void compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
#define VAR_SPEED_WITHOUT_TRACI
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:269
#define VAR_MAXSPEED
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
The vehicle was teleported out of the net.
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:945
#define VAR_DECEL
#define VAR_ROUTE_VALID
The class responsible for building and deletion of vehicles.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
#define ID_COUNT
#define VAR_LANE_INDEX
bool knowsTravelTime(const MSEdge *const e) const
Returns the information whether any travel time is known for the given edge.
#define VAR_LANE_ID
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:331
void collectObjectsInRange(int domain, const PositionVector &shape, SUMOReal range, std::set< std::string > &into)
SUMOEmissionClass getEmissionClass() const
Get this vehicle type&#39;s emission class.
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:323
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:525
The edge is an internal edge.
Definition: MSEdge.h:90
static const std::map< std::string, std::vector< MSLane * > > & getOrBuildVTDMap()
SUMOReal interpolateGeometryPosToLanePos(SUMOReal geometryPos) const
Definition: MSLane.h:336
Tag for the last element in the enum for safe int casting.
bool readTypeCheckingColor(tcpip::Storage &inputStorage, RGBColor &into)
Reads the value type and a color, verifying the type.
DepartPosDefinition
Possible ways to choose the departure position.
#define RTYPE_ERR
#define TYPE_INTEGER
#define VAR_MINGAP
#define ID_LIST
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:75
void add(SUMOVehicle *veh)
Adds a single vehicle for departure.
SUMOReal startPos
The stopping position start.
Definition: MSVehicle.h:541
Representation of a lane in the micro simulation.
Definition: MSLane.h:73
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle&#39;s internal edge travel times/efforts container.
Definition: MSVehicle.cpp:418
bool readTypeCheckingInt(tcpip::Storage &inputStorage, int &into)
Reads the value type and an int, verifying the type.
unsigned int getRoutePosition() const
Definition: MSVehicle.cpp:403
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
DepartDefinition
Possible ways to depart.
#define VAR_HCEMISSION
void setConsiderMaxAcceleration(bool value)
Sets whether the maximum acceleration shall be regarded.
Definition: MSVehicle.cpp:230
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:75
std::string id
The vehicle&#39;s id.
The vehicle is being teleported.
#define VAR_WIDTH
SUMOReal getAngle() const
Returns the vehicle&#39;s direction in degrees.
Definition: MSVehicle.cpp:504
const std::string & getID() const
Returns the name of the vehicle.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:116
unsigned int getLaneIndex() const
Definition: MSVehicle.cpp:1943