SUMO - Simulation of Urban MObility
TraCIServerAPI_Vehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
13 // APIs for getting/setting vehicle values via TraCI
14 /****************************************************************************/
15 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
16 // Copyright (C) 2009-2016 DLR (http://www.dlr.de/) and contributors
17 /****************************************************************************/
18 //
19 // This file is part of SUMO.
20 // SUMO is free software: you can redistribute it and/or modify
21 // it under the terms of the GNU General Public License as published by
22 // the Free Software Foundation, either version 3 of the License, or
23 // (at your option) any later version.
24 //
25 /****************************************************************************/
26 
27 
28 // ===========================================================================
29 // included modules
30 // ===========================================================================
31 #ifdef _MSC_VER
32 #include <windows_config.h>
33 #else
34 #include <config.h>
35 #endif
36 
37 #ifndef NO_TRACI
38 
39 #include <microsim/MSNet.h>
41 #include <microsim/MSVehicle.h>
42 #include <microsim/MSLane.h>
43 #include <microsim/MSEdge.h>
52 #include "TraCIConstants.h"
54 #include "TraCIServerAPI_Vehicle.h"
56 
57 #ifdef CHECK_MEMORY_LEAKS
58 #include <foreign/nvwa/debug_new.h>
59 #endif // CHECK_MEMORY_LEAKS
60 
61 //#define DEBUG_VTD 1
62 //#define DEBUG_VTD_ANGLE 1
63 
64 
65 // ===========================================================================
66 // static member variables
67 // ===========================================================================
68 std::map<std::string, std::vector<MSLane*> > TraCIServerAPI_Vehicle::gVTDMap;
69 
70 
71 // ===========================================================================
72 // method definitions
73 // ===========================================================================
74 bool
76  tcpip::Storage& outputStorage) {
77  // variable & id
78  int variable = inputStorage.readUnsignedByte();
79  std::string id = inputStorage.readString();
80  // check variable
81  if (variable != ID_LIST && variable != VAR_SPEED && variable != VAR_SPEED_WITHOUT_TRACI
82  && variable != VAR_POSITION && variable != VAR_ANGLE && variable != VAR_POSITION3D
83  && variable != VAR_ROAD_ID && variable != VAR_LANE_ID && variable != VAR_LANE_INDEX
84  && variable != VAR_TYPE && variable != VAR_ROUTE_ID && variable != VAR_COLOR
85  && variable != VAR_LANEPOSITION
86  && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION
87  && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION
88  && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION
89  && variable != VAR_PERSON_NUMBER && variable != VAR_LEADER
90  && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT
91  && variable != VAR_ROUTE_VALID && variable != VAR_EDGES
92  && variable != VAR_SIGNALS && variable != VAR_DISTANCE
93  && variable != VAR_LENGTH && variable != VAR_MAXSPEED && variable != VAR_VEHICLECLASS
94  && variable != VAR_SPEED_FACTOR && variable != VAR_SPEED_DEVIATION
95  && variable != VAR_ALLOWED_SPEED && variable != VAR_EMISSIONCLASS
96  && variable != VAR_WIDTH && variable != VAR_MINGAP && variable != VAR_SHAPECLASS
97  && variable != VAR_ACCEL && variable != VAR_DECEL && variable != VAR_IMPERFECTION
98  && variable != VAR_TAU && variable != VAR_BEST_LANES && variable != DISTANCE_REQUEST
99  && variable != ID_COUNT && variable != VAR_STOPSTATE && variable != VAR_WAITING_TIME
100  && variable != VAR_ROUTE_INDEX
101  && variable != VAR_PARAMETER
102  ) {
103  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Get Vehicle Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
104  }
105  // begin response building
106  tcpip::Storage tempMsg;
107  // response-code, variableID, objectID
109  tempMsg.writeUnsignedByte(variable);
110  tempMsg.writeString(id);
111  // process request
112  if (variable == ID_LIST || variable == ID_COUNT) {
113  std::vector<std::string> ids;
115  for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
116  if ((*i).second->isOnRoad() || (*i).second->isParking()) {
117  ids.push_back((*i).first);
118  }
119  }
120  if (variable == ID_LIST) {
122  tempMsg.writeStringList(ids);
123  } else {
125  tempMsg.writeInt((int) ids.size());
126  }
127  } else {
129  if (sumoVehicle == 0) {
130  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
131  }
132  MSVehicle* v = dynamic_cast<MSVehicle*>(sumoVehicle);
133  if (v == 0) {
134  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a micro-simulation vehicle", outputStorage);
135  }
136  const bool onRoad = v->isOnRoad();
137  const bool visible = onRoad || v->isParking();
138  switch (variable) {
139  case VAR_SPEED:
141  tempMsg.writeDouble(visible ? v->getSpeed() : INVALID_DOUBLE_VALUE);
142  break;
146  break;
147  case VAR_POSITION:
149  tempMsg.writeDouble(visible ? v->getPosition().x() : INVALID_DOUBLE_VALUE);
150  tempMsg.writeDouble(visible ? v->getPosition().y() : INVALID_DOUBLE_VALUE);
151  break;
152  case VAR_POSITION3D:
154  tempMsg.writeDouble(visible ? v->getPosition().x() : INVALID_DOUBLE_VALUE);
155  tempMsg.writeDouble(visible ? v->getPosition().y() : INVALID_DOUBLE_VALUE);
156  tempMsg.writeDouble(visible ? v->getPosition().z() : INVALID_DOUBLE_VALUE);
157  break;
158  case VAR_ANGLE:
161  break;
162  case VAR_ROAD_ID:
164  tempMsg.writeString(visible ? v->getLane()->getEdge().getID() : "");
165  break;
166  case VAR_LANE_ID:
168  tempMsg.writeString(onRoad ? v->getLane()->getID() : "");
169  break;
170  case VAR_LANE_INDEX:
172  if (onRoad) {
173  const std::vector<MSLane*>& lanes = v->getLane()->getEdge().getLanes();
174  tempMsg.writeInt((int)std::distance(lanes.begin(), std::find(lanes.begin(), lanes.end(), v->getLane())));
175  } else {
176  tempMsg.writeInt(INVALID_INT_VALUE);
177  }
178  break;
179  case VAR_TYPE:
181  tempMsg.writeString(v->getVehicleType().getID());
182  break;
183  case VAR_ROUTE_ID:
185  tempMsg.writeString(v->getRoute().getID());
186  break;
187  case VAR_ROUTE_INDEX:
189  if (v->hasDeparted()) {
190  tempMsg.writeInt((int)v->getRoutePosition());
191  } else {
192  tempMsg.writeInt(INVALID_INT_VALUE);
193  }
194  break;
195  case VAR_COLOR:
196  tempMsg.writeUnsignedByte(TYPE_COLOR);
197  tempMsg.writeUnsignedByte(v->getParameter().color.red());
198  tempMsg.writeUnsignedByte(v->getParameter().color.green());
199  tempMsg.writeUnsignedByte(v->getParameter().color.blue());
200  tempMsg.writeUnsignedByte(v->getParameter().color.alpha());
201  break;
202  case VAR_LANEPOSITION:
204  tempMsg.writeDouble(onRoad ? v->getPositionOnLane() : INVALID_DOUBLE_VALUE);
205  break;
206  case VAR_CO2EMISSION:
208  tempMsg.writeDouble(visible ? v->getCO2Emissions() : INVALID_DOUBLE_VALUE);
209  break;
210  case VAR_COEMISSION:
212  tempMsg.writeDouble(visible ? v->getCOEmissions() : INVALID_DOUBLE_VALUE);
213  break;
214  case VAR_HCEMISSION:
216  tempMsg.writeDouble(visible ? v->getHCEmissions() : INVALID_DOUBLE_VALUE);
217  break;
218  case VAR_PMXEMISSION:
220  tempMsg.writeDouble(visible ? v->getPMxEmissions() : INVALID_DOUBLE_VALUE);
221  break;
222  case VAR_NOXEMISSION:
224  tempMsg.writeDouble(visible ? v->getNOxEmissions() : INVALID_DOUBLE_VALUE);
225  break;
226  case VAR_FUELCONSUMPTION:
228  tempMsg.writeDouble(visible ? v->getFuelConsumption() : INVALID_DOUBLE_VALUE);
229  break;
230  case VAR_NOISEEMISSION:
233  break;
234  case VAR_PERSON_NUMBER:
236  tempMsg.writeInt(v->getPersonNumber());
237  break;
238  case VAR_LEADER: {
239  double dist = 0;
240  if (!server.readTypeCheckingDouble(inputStorage, dist)) {
241  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Leader retrieval requires a double.", outputStorage);
242  }
243  std::pair<const MSVehicle* const, SUMOReal> leaderInfo = v->getLeader(dist);
245  tempMsg.writeInt(2);
247  tempMsg.writeString(leaderInfo.first != 0 ? leaderInfo.first->getID() : "");
249  tempMsg.writeDouble(leaderInfo.second);
250  }
251  break;
252  case VAR_WAITING_TIME:
254  tempMsg.writeDouble(v->getWaitingSeconds());
255  break;
256  case VAR_EDGE_TRAVELTIME: {
257  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
258  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires a compound object.", outputStorage);
259  }
260  if (inputStorage.readInt() != 2) {
261  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires time, and edge as parameter.", outputStorage);
262  }
263  // time
264  int time = 0;
265  if (!server.readTypeCheckingInt(inputStorage, time)) {
266  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires the referenced time as first parameter.", outputStorage);
267  }
268  // edge
269  std::string edgeID;
270  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
271  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires the referenced edge as second parameter.", outputStorage);
272  }
273  MSEdge* edge = MSEdge::dictionary(edgeID);
274  if (edge == 0) {
275  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
276  }
277  // retrieve
279  SUMOReal value;
280  if (!v->getWeightsStorage().retrieveExistingTravelTime(edge, time, value)) {
282  } else {
283  tempMsg.writeDouble(value);
284  }
285 
286  }
287  break;
288  case VAR_EDGE_EFFORT: {
289  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
290  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires a compound object.", outputStorage);
291  }
292  if (inputStorage.readInt() != 2) {
293  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires time, and edge as parameter.", outputStorage);
294  }
295  // time
296  int time = 0;
297  if (!server.readTypeCheckingInt(inputStorage, time)) {
298  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of effort requires the referenced time as first parameter.", outputStorage);
299  }
300  // edge
301  std::string edgeID;
302  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
303  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of effort requires the referenced edge as second parameter.", outputStorage);
304  }
305  MSEdge* edge = MSEdge::dictionary(edgeID);
306  if (edge == 0) {
307  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
308  }
309  // retrieve
311  SUMOReal value;
312  if (!v->getWeightsStorage().retrieveExistingEffort(edge, time, value)) {
314  } else {
315  tempMsg.writeDouble(value);
316  }
317 
318  }
319  break;
320  case VAR_ROUTE_VALID: {
321  std::string msg;
322  tempMsg.writeUnsignedByte(TYPE_UBYTE);
323  tempMsg.writeUnsignedByte(v->hasValidRoute(msg));
324  }
325  break;
326  case VAR_EDGES: {
327  const MSRoute& r = v->getRoute();
329  tempMsg.writeInt(r.size());
330  for (MSRouteIterator i = r.begin(); i != r.end(); ++i) {
331  tempMsg.writeString((*i)->getID());
332  }
333  }
334  break;
335  case VAR_SIGNALS:
337  tempMsg.writeInt(v->getSignals());
338  break;
339  case VAR_BEST_LANES: {
341  tcpip::Storage tempContent;
342  unsigned int cnt = 0;
343  tempContent.writeUnsignedByte(TYPE_INTEGER);
344  const std::vector<MSVehicle::LaneQ>& bestLanes = onRoad ? v->getBestLanes() : std::vector<MSVehicle::LaneQ>();
345  tempContent.writeInt((int) bestLanes.size());
346  ++cnt;
347  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bestLanes.begin(); i != bestLanes.end(); ++i) {
348  const MSVehicle::LaneQ& lq = *i;
349  tempContent.writeUnsignedByte(TYPE_STRING);
350  tempContent.writeString(lq.lane->getID());
351  ++cnt;
352  tempContent.writeUnsignedByte(TYPE_DOUBLE);
353  tempContent.writeDouble(lq.length);
354  ++cnt;
355  tempContent.writeUnsignedByte(TYPE_DOUBLE);
356  tempContent.writeDouble(lq.nextOccupation);
357  ++cnt;
358  tempContent.writeUnsignedByte(TYPE_BYTE);
359  tempContent.writeByte(lq.bestLaneOffset);
360  ++cnt;
361  tempContent.writeUnsignedByte(TYPE_UBYTE);
362  lq.allowsContinuation ? tempContent.writeUnsignedByte(1) : tempContent.writeUnsignedByte(0);
363  ++cnt;
364  std::vector<std::string> bestContIDs;
365  for (std::vector<MSLane*>::const_iterator j = lq.bestContinuations.begin(); j != lq.bestContinuations.end(); ++j) {
366  if ((*j) != 0) {
367  bestContIDs.push_back((*j)->getID());
368  }
369  }
370  tempContent.writeUnsignedByte(TYPE_STRINGLIST);
371  tempContent.writeStringList(bestContIDs);
372  ++cnt;
373  }
374  tempMsg.writeInt((int) cnt);
375  tempMsg.writeStorage(tempContent);
376  }
377  break;
378  case VAR_STOPSTATE: {
379  char b = 0;
380  if (v->isStopped()) {
381  const MSVehicle::Stop& stop = v->getNextStop();
382  b = 1 + (stop.parking ? 2 : 0) +
383  (stop.triggered ? 4 : 0) +
384  (stop.containerTriggered ? 8 : 0) +
385  (stop.busstop != 0 ? 16 : 0) +
386  (stop.containerstop != 0 ? 32 : 0);
387  }
388  tempMsg.writeUnsignedByte(TYPE_UBYTE);
389  tempMsg.writeUnsignedByte(b);
390  }
391  break;
392  case VAR_DISTANCE: {
394  SUMOReal distance = onRoad ? v->getRoute().getDistanceBetween(v->getDepartPos(), v->getPositionOnLane(), v->getRoute().getEdges()[0], &v->getLane()->getEdge()) : INVALID_DOUBLE_VALUE;
395  if (distance == std::numeric_limits<SUMOReal>::max()) {
396  distance = INVALID_DOUBLE_VALUE;
397  }
398  tempMsg.writeDouble(distance);
399  }
400  break;
401  case DISTANCE_REQUEST:
402  if (!commandDistanceRequest(server, inputStorage, tempMsg, v)) {
403  return false;
404  }
405  break;
406  case VAR_ALLOWED_SPEED:
408  tempMsg.writeDouble(onRoad ? v->getLane()->getVehicleMaxSpeed(v) : INVALID_DOUBLE_VALUE);
409  break;
410  case VAR_SPEED_FACTOR:
412  tempMsg.writeDouble(v->getChosenSpeedFactor());
413  break;
414  case VAR_PARAMETER: {
415  std::string paramName = "";
416  if (!server.readTypeCheckingString(inputStorage, paramName)) {
417  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of a parameter requires its name.", outputStorage);
418  }
420  tempMsg.writeString(v->getParameter().getParameter(paramName, ""));
421  }
422  break;
423  default:
425  break;
426  }
427  }
428  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_OK, "", outputStorage);
429  server.writeResponseWithLength(outputStorage, tempMsg);
430  return true;
431 }
432 
433 
434 bool
436  tcpip::Storage& outputStorage) {
437  std::string warning = ""; // additional description for response
438  // variable
439  int variable = inputStorage.readUnsignedByte();
440  if (variable != CMD_STOP && variable != CMD_CHANGELANE
441  && variable != CMD_SLOWDOWN && variable != CMD_CHANGETARGET && variable != CMD_RESUME
442  && variable != VAR_TYPE && variable != VAR_ROUTE_ID && variable != VAR_ROUTE
443  && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT
444  && variable != CMD_REROUTE_TRAVELTIME && variable != CMD_REROUTE_EFFORT
445  && variable != VAR_SIGNALS && variable != VAR_MOVE_TO
446  && variable != VAR_LENGTH && variable != VAR_MAXSPEED && variable != VAR_VEHICLECLASS
447  && variable != VAR_SPEED_FACTOR && variable != VAR_EMISSIONCLASS
448  && variable != VAR_WIDTH && variable != VAR_MINGAP && variable != VAR_SHAPECLASS
449  && variable != VAR_ACCEL && variable != VAR_DECEL && variable != VAR_IMPERFECTION
450  && variable != VAR_TAU && variable != VAR_LANECHANGE_MODE
451  && variable != VAR_SPEED && variable != VAR_SPEEDSETMODE && variable != VAR_COLOR
452  && variable != ADD && variable != ADD_FULL && variable != REMOVE
453  && variable != VAR_MOVE_TO_VTD && variable != VAR_PARAMETER/* && variable != VAR_SPEED_TIME_LINE && variable != VAR_LANE_TIME_LINE*/
454  ) {
455  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Change Vehicle State: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
456  }
457  // id
458  std::string id = inputStorage.readString();
459 #ifdef DEBUG_VTD
460  WRITE_MESSAGE("Processing " + id);
461 #endif
462  const bool shouldExist = variable != ADD && variable != ADD_FULL;
464  if (sumoVehicle == 0) {
465  if (shouldExist) {
466  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
467  }
468  }
469  MSVehicle* v = dynamic_cast<MSVehicle*>(sumoVehicle);
470  if (v == 0 && shouldExist) {
471  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a micro-simulation vehicle", outputStorage);
472  }
473  switch (variable) {
474  case CMD_STOP: {
475  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
476  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description.", outputStorage);
477  }
478  int compoundSize = inputStorage.readInt();
479  if (compoundSize < 4 || compoundSize > 7) {
480  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description of four to seven items.", outputStorage);
481  }
482  // read road map position
483  std::string roadId;
484  if (!server.readTypeCheckingString(inputStorage, roadId)) {
485  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first stop parameter must be the edge id given as a string.", outputStorage);
486  }
487  double pos = 0;
488  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
489  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second stop parameter must be the end position along the edge given as a double.", outputStorage);
490  }
491  int laneIndex = 0;
492  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
493  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The third stop parameter must be the lane index given as a byte.", outputStorage);
494  }
495  // waitTime
496  int waitTime = -1;
497  if (!server.readTypeCheckingInt(inputStorage, waitTime)) {
498  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "The fourth stop parameter must be the waiting time given as an integer.", outputStorage);
499  }
500  // optional stop flags
501  bool parking = false;
502  bool triggered = false;
503  bool containerTriggered = false;
504  bool isBusStop = false;
505  bool isContainerStop = false;
506  if (compoundSize >= 5) {
507  int stopFlags;
508  if (!server.readTypeCheckingByte(inputStorage, stopFlags)) {
509  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The fifth stop parameter must be a byte indicating its parking/triggered status.", outputStorage);
510  }
511  parking = ((stopFlags & 1) != 0);
512  triggered = ((stopFlags & 2) != 0);
513  containerTriggered = ((stopFlags & 4) != 0);
514  isBusStop = ((stopFlags & 8) != 0);
515  isContainerStop = ((stopFlags & 16) != 0);
516  }
517  double startPos = pos - POSITION_EPS;
518  if (compoundSize >= 6) {
519  double tmp;
520  if (!server.readTypeCheckingDouble(inputStorage, tmp)) {
521  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The sixth stop parameter must be the start position along the edge given as a double.", outputStorage);
522  }
523  if (tmp != INVALID_DOUBLE_VALUE) {
524  startPos = tmp;
525  }
526  }
527  int until = -1;
528  if (compoundSize >= 7) {
529  if (!server.readTypeCheckingInt(inputStorage, until)) {
530  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The seventh stop parameter must be the waiting end time given as integer.", outputStorage);
531  }
532  }
533  std::string error;
534  if (isBusStop || isContainerStop) {
535  // Forward command to vehicle
536  if (!v->addTraciBusOrContainerStop(roadId, waitTime, until, parking, triggered, containerTriggered, isContainerStop, error)) {
537  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
538  }
539  } else {
540  // check
541  if (startPos < 0) {
542  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Position on lane must not be negative.", outputStorage);
543  }
544  if (pos < startPos) {
545  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "End position on lane must be after start position.", outputStorage);
546  }
547  // get the actual lane that is referenced by laneIndex
548  MSEdge* road = MSEdge::dictionary(roadId);
549  if (road == 0) {
550  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Unable to retrieve road with given id.", outputStorage);
551  }
552  const std::vector<MSLane*>& allLanes = road->getLanes();
553  if ((laneIndex < 0) || laneIndex >= (int)(allLanes.size())) {
554  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + roadId + "'.", outputStorage);
555  }
556  // Forward command to vehicle
557  if (!v->addTraciStop(allLanes[laneIndex], startPos, pos, waitTime, until, parking, triggered, containerTriggered, error)) {
558  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
559  }
560  }
561  }
562  break;
563  case CMD_RESUME: {
564  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
565  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Resuming requires a compound object.", outputStorage);
566  return false;
567  }
568  if (inputStorage.readInt() != 0) {
569  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Resuming should obtain an empty compound object.", outputStorage);
570  return false;
571  }
572  if (!static_cast<MSVehicle*>(v)->hasStops()) {
573  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Failed to resume vehicle '" + v->getID() + "', it has no stops.", outputStorage);
574  return false;
575  }
576  if (!static_cast<MSVehicle*>(v)->resumeFromStopping()) {
577  MSVehicle::Stop& sto = (static_cast<MSVehicle*>(v))->getNextStop();
578  std::ostringstream strs;
579  strs << "reached: " << sto.reached;
580  strs << ", duration:" << sto.duration;
581  strs << ", edge:" << (*sto.edge)->getID();
582  strs << ", startPos: " << sto.startPos;
583  std::string posStr = strs.str();
584  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Failed to resume a non parking vehicle '" + v->getID() + "', " + posStr, outputStorage);
585  return false;
586  }
587  }
588  break;
589  case CMD_CHANGELANE: {
590  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
591  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description.", outputStorage);
592  }
593  if (inputStorage.readInt() != 2) {
594  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two items.", outputStorage);
595  }
596  // Lane ID
597  int laneIndex = 0;
598  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
599  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first lane change parameter must be the lane index given as a byte.", outputStorage);
600  }
601  // stickyTime
602  int stickyTime = 0;
603  if (!server.readTypeCheckingInt(inputStorage, stickyTime)) {
604  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second lane change parameter must be the duration given as an integer.", outputStorage);
605  }
606  if ((laneIndex < 0) || (laneIndex >= (int)(v->getEdge()->getLanes().size()))) {
607  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + v->getEdge()->getID() + "'.", outputStorage);
608  }
609  // Forward command to vehicle
610  std::vector<std::pair<SUMOTime, unsigned int> > laneTimeLine;
611  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), laneIndex));
612  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + stickyTime, laneIndex));
613  v->getInfluencer().setLaneTimeLine(laneTimeLine);
614  }
615  break;
616  /*
617  case VAR_LANE_TIME_LINE: {
618  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
619  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description.", outputStorage);
620  }
621  if (inputStorage.readInt() != 2) {
622  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two items.", outputStorage);
623  }
624  // Lane ID
625  int laneIndex = 0;
626  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
627  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first lane change parameter must be the lane index given as a byte.", outputStorage);
628  }
629  // stickyTime
630  SUMOTime stickyTime = 0;
631  if (!server.readTypeCheckingInt(inputStorage, stickyTime)) {
632  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second lane change parameter must be the duration given as an integer.", outputStorage);
633  }
634  if ((laneIndex < 0) || (laneIndex >= (int)(v->getEdge()->getLanes().size()))) {
635  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "No lane existing with given id on the current road", outputStorage);
636  }
637  // Forward command to vehicle
638  std::vector<std::pair<SUMOTime, unsigned int> > laneTimeLine;
639  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), laneIndex));
640  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + stickyTime, laneIndex));
641  v->getInfluencer().setLaneTimeLine(laneTimeLine);
642  MSVehicle::ChangeRequest req = v->getInfluencer().checkForLaneChanges(MSNet::getInstance()->getCurrentTimeStep(),
643  *v->getEdge(), v->getLaneIndex());
644  v->getLaneChangeModel().requestLaneChange(req);
645  }
646  break;
647  */
648  case CMD_SLOWDOWN: {
649  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
650  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description.", outputStorage);
651  }
652  if (inputStorage.readInt() != 2) {
653  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description of two items.", outputStorage);
654  }
655  double newSpeed = 0;
656  if (!server.readTypeCheckingDouble(inputStorage, newSpeed)) {
657  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first slow down parameter must be the speed given as a double.", outputStorage);
658  }
659  if (newSpeed < 0) {
660  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Speed must not be negative", outputStorage);
661  }
662  int duration = 0;
663  if (!server.readTypeCheckingInt(inputStorage, duration)) {
664  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second slow down parameter must be the duration given as an integer.", outputStorage);
665  }
666  if (duration < 0 || STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) + STEPS2TIME(duration) > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
667  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid time interval", outputStorage);
668  }
669  std::vector<std::pair<SUMOTime, SUMOReal> > speedTimeLine;
670  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), v->getSpeed()));
671  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + duration, newSpeed));
672  v->getInfluencer().setSpeedTimeLine(speedTimeLine);
673  }
674  break;
675  case CMD_CHANGETARGET: {
676  std::string edgeID;
677  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
678  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Change target requires a string containing the id of the new destination edge as parameter.", outputStorage);
679  }
680  const MSEdge* destEdge = MSEdge::dictionary(edgeID);
681  if (destEdge == 0) {
682  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Can not retrieve road with ID " + edgeID, outputStorage);
683  }
684  // build a new route between the vehicle's current edge and destination edge
685  ConstMSEdgeVector newRoute;
686  const MSEdge* currentEdge = v->getRerouteOrigin();
688  currentEdge, destEdge, (const MSVehicle * const) v, MSNet::getInstance()->getCurrentTimeStep(), newRoute);
689  // replace the vehicle's route by the new one
690  if (!v->replaceRouteEdges(newRoute, v->getLane() == 0)) {
691  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Route replacement failed for " + v->getID(), outputStorage);
692  }
693  }
694  break;
695  case VAR_TYPE: {
696  std::string vTypeID;
697  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
698  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The vehicle type id must be given as a string.", outputStorage);
699  }
700  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(vTypeID);
701  if (vehicleType == 0) {
702  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The vehicle type '" + vTypeID + "' is not known.", outputStorage);
703  }
704  v->replaceVehicleType(vehicleType);
705  }
706  break;
707  case VAR_ROUTE_ID: {
708  std::string rid;
709  if (!server.readTypeCheckingString(inputStorage, rid)) {
710  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The route id must be given as a string.", outputStorage);
711  }
712  const MSRoute* r = MSRoute::dictionary(rid);
713  if (r == 0) {
714  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The route '" + rid + "' is not known.", outputStorage);
715  }
716  if (!v->replaceRoute(r, v->getLane() == 0)) {
717  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Route replacement failed for " + v->getID(), outputStorage);
718  }
719  }
720  break;
721  case VAR_ROUTE: {
722  std::vector<std::string> edgeIDs;
723  if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {
724  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "A route must be defined as a list of edge ids.", outputStorage);
725  }
726  ConstMSEdgeVector edges;
727  MSEdge::parseEdgesList(edgeIDs, edges, "<unknown>");
728  if (!v->replaceRouteEdges(edges, v->getLane() == 0)) {
729  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Route replacement failed for " + v->getID(), outputStorage);
730  }
731  }
732  break;
733  case VAR_EDGE_TRAVELTIME: {
734  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
735  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires a compound object.", outputStorage);
736  }
737  int parameterCount = inputStorage.readInt();
738  if (parameterCount == 4) {
739  // begin time
740  int begTime = 0, endTime = 0;
741  if (!server.readTypeCheckingInt(inputStorage, begTime)) {
742  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the begin time as first parameter.", outputStorage);
743  }
744  // begin time
745  if (!server.readTypeCheckingInt(inputStorage, endTime)) {
746  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the end time as second parameter.", outputStorage);
747  }
748  // edge
749  std::string edgeID;
750  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
751  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the referenced edge as third parameter.", outputStorage);
752  }
753  MSEdge* edge = MSEdge::dictionary(edgeID);
754  if (edge == 0) {
755  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
756  }
757  // value
758  double value = 0;
759  if (!server.readTypeCheckingDouble(inputStorage, value)) {
760  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the travel time as double as fourth parameter.", outputStorage);
761  }
762  // retrieve
763  v->getWeightsStorage().addTravelTime(edge, begTime, endTime, value);
764  } else if (parameterCount == 2) {
765  // edge
766  std::string edgeID;
767  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
768  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the referenced edge as first parameter.", outputStorage);
769  }
770  MSEdge* edge = MSEdge::dictionary(edgeID);
771  if (edge == 0) {
772  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
773  }
774  // value
775  double value = 0;
776  if (!server.readTypeCheckingDouble(inputStorage, value)) {
777  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the travel time as second parameter.", outputStorage);
778  }
779  // retrieve
780  while (v->getWeightsStorage().knowsTravelTime(edge)) {
782  }
784  } else if (parameterCount == 1) {
785  // edge
786  std::string edgeID;
787  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
788  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 1 parameter requires the referenced edge as first parameter.", outputStorage);
789  }
790  MSEdge* edge = MSEdge::dictionary(edgeID);
791  if (edge == 0) {
792  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
793  }
794  // retrieve
795  while (v->getWeightsStorage().knowsTravelTime(edge)) {
797  }
798  } else {
799  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);
800  }
801  }
802  break;
803  case VAR_EDGE_EFFORT: {
804  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
805  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort requires a compound object.", outputStorage);
806  }
807  int parameterCount = inputStorage.readInt();
808  if (parameterCount == 4) {
809  // begin time
810  int begTime = 0, endTime = 0;
811  if (!server.readTypeCheckingInt(inputStorage, begTime)) {
812  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the begin time as first parameter.", outputStorage);
813  }
814  // begin time
815  if (!server.readTypeCheckingInt(inputStorage, endTime)) {
816  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the end time as second parameter.", outputStorage);
817  }
818  // edge
819  std::string edgeID;
820  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
821  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the referenced edge as third parameter.", outputStorage);
822  }
823  MSEdge* edge = MSEdge::dictionary(edgeID);
824  if (edge == 0) {
825  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
826  }
827  // value
828  double value = 0;
829  if (!server.readTypeCheckingDouble(inputStorage, value)) {
830  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the travel time as fourth parameter.", outputStorage);
831  }
832  // retrieve
833  v->getWeightsStorage().addEffort(edge, begTime, endTime, value);
834  } else if (parameterCount == 2) {
835  // edge
836  std::string edgeID;
837  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
838  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the referenced edge as first parameter.", outputStorage);
839  }
840  MSEdge* edge = MSEdge::dictionary(edgeID);
841  if (edge == 0) {
842  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
843  }
844  // value
845  double value = 0;
846  if (!server.readTypeCheckingDouble(inputStorage, value)) {
847  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the travel time as second parameter.", outputStorage);
848  }
849  // retrieve
850  while (v->getWeightsStorage().knowsEffort(edge)) {
851  v->getWeightsStorage().removeEffort(edge);
852  }
853  v->getWeightsStorage().addEffort(edge, SUMOReal(0), SUMOReal(SUMOTime_MAX), value);
854  } else if (parameterCount == 1) {
855  // edge
856  std::string edgeID;
857  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
858  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 1 parameter requires the referenced edge as first parameter.", outputStorage);
859  }
860  MSEdge* edge = MSEdge::dictionary(edgeID);
861  if (edge == 0) {
862  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
863  }
864  // retrieve
865  while (v->getWeightsStorage().knowsEffort(edge)) {
866  v->getWeightsStorage().removeEffort(edge);
867  }
868  } else {
869  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);
870  }
871  }
872  break;
873  case CMD_REROUTE_TRAVELTIME: {
874  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
875  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
876  }
877  if (inputStorage.readInt() != 0) {
878  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
879  }
880  v->reroute(MSNet::getInstance()->getCurrentTimeStep(), MSNet::getInstance()->getRouterTT());
881  }
882  break;
883  case CMD_REROUTE_EFFORT: {
884  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
885  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
886  }
887  if (inputStorage.readInt() != 0) {
888  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
889  }
890  v->reroute(MSNet::getInstance()->getCurrentTimeStep(), MSNet::getInstance()->getRouterEffort());
891  }
892  break;
893  case VAR_SIGNALS: {
894  int signals = 0;
895  if (!server.readTypeCheckingInt(inputStorage, signals)) {
896  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting signals requires an integer.", outputStorage);
897  }
898  v->switchOffSignal(0x0fffffff);
899  v->switchOnSignal(signals);
900  }
901  break;
902  case VAR_MOVE_TO: {
903  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
904  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting position requires a compound object.", outputStorage);
905  }
906  if (inputStorage.readInt() != 2) {
907  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting position should obtain the lane id and the position.", outputStorage);
908  }
909  // lane ID
910  std::string laneID;
911  if (!server.readTypeCheckingString(inputStorage, laneID)) {
912  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first parameter for setting a position must be the lane ID given as a string.", outputStorage);
913  }
914  // position on lane
915  double position = 0;
916  if (!server.readTypeCheckingDouble(inputStorage, position)) {
917  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second parameter for setting a position must be the position given as a double.", outputStorage);
918  }
919  // process
920  MSLane* l = MSLane::dictionary(laneID);
921  if (l == 0) {
922  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Unknown lane '" + laneID + "'.", outputStorage);
923  }
924  MSEdge& destinationEdge = l->getEdge();
925  if (!v->willPass(&destinationEdge)) {
926  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + laneID + "' may be set onto an edge to pass only.", outputStorage);
927  }
929  if (v->getLane() != 0) {
931  } else {
932  v->setTentativeLaneAndPosition(l, position);
933  }
934  while (v->getEdge() != &destinationEdge) {
935  const MSEdge* nextEdge = v->succEdge(1);
936  // let the vehicle move to the next edge
937  if (v->enterLaneAtMove(nextEdge->getLanes()[0], true)) {
939  continue;
940  }
941  }
942  l->forceVehicleInsertion(v, position);
943  }
944  break;
945  case VAR_SPEED: {
946  double speed = 0;
947  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
948  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting speed requires a double.", outputStorage);
949  }
950  std::vector<std::pair<SUMOTime, SUMOReal> > speedTimeLine;
951  if (speed >= 0) {
952  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), speed));
953  speedTimeLine.push_back(std::make_pair(SUMOTime_MAX - DELTA_T, speed));
954  }
955  v->getInfluencer().setSpeedTimeLine(speedTimeLine);
956  }
957  break;
958  case VAR_SPEEDSETMODE: {
959  int speedMode = 0;
960  if (!server.readTypeCheckingInt(inputStorage, speedMode)) {
961  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting speed mode requires an integer.", outputStorage);
962  }
963  v->getInfluencer().setConsiderSafeVelocity((speedMode & 1) != 0);
964  v->getInfluencer().setConsiderMaxAcceleration((speedMode & 2) != 0);
965  v->getInfluencer().setConsiderMaxDeceleration((speedMode & 4) != 0);
966  v->getInfluencer().setRespectJunctionPriority((speedMode & 8) != 0);
967  v->getInfluencer().setEmergencyBrakeRedLight((speedMode & 16) != 0);
968  }
969  break;
970  case VAR_LANECHANGE_MODE: {
971  int laneChangeMode = 0;
972  if (!server.readTypeCheckingInt(inputStorage, laneChangeMode)) {
973  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting lane change mode requires an integer.", outputStorage);
974  }
975  v->getInfluencer().setLaneChangeMode(laneChangeMode);
976  }
977  break;
978  case VAR_COLOR: {
979  RGBColor col;
980  if (!server.readTypeCheckingColor(inputStorage, col)) {
981  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The color must be given using the according type.", outputStorage);
982  }
983  v->getParameter().color.set(col.red(), col.green(), col.blue(), col.alpha());
985  }
986  break;
987  case ADD: {
988  if (v != 0) {
989  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The vehicle " + id + " to add already exists.", outputStorage);
990  }
991  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
992  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle requires a compound object.", outputStorage);
993  }
994  if (inputStorage.readInt() != 6) {
995  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle needs six parameters.", outputStorage);
996  }
997  SUMOVehicleParameter vehicleParams;
998  vehicleParams.id = id;
999 
1000  std::string vTypeID;
1001  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
1002  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "First parameter (type) requires a string.", outputStorage);
1003  }
1004  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(vTypeID);
1005  if (!vehicleType) {
1006  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid type '" + vTypeID + "' for vehicle '" + id + "'", outputStorage);
1007  }
1008 
1009  std::string routeID;
1010  if (!server.readTypeCheckingString(inputStorage, routeID)) {
1011  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Second parameter (route) requires a string.", outputStorage);
1012  }
1013  const MSRoute* route = MSRoute::dictionary(routeID);
1014  if (!route) {
1015  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid route '" + routeID + "' for vehicle: '" + id + "'", outputStorage);
1016  }
1017  int depart;
1018  if (!server.readTypeCheckingInt(inputStorage, depart)) {
1019  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Third parameter (depart) requires an integer.", outputStorage);
1020  }
1021  if (depart < 0) {
1022  const int proc = -depart;
1023  if (proc >= static_cast<int>(DEPART_DEF_MAX)) {
1024  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure time.", outputStorage);
1025  }
1026  vehicleParams.departProcedure = (DepartDefinition)proc;
1027  } else if (depart < MSNet::getInstance()->getCurrentTimeStep()) {
1028  vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();
1029  WRITE_WARNING("Departure time for vehicle '" + id + "' is in the past; using current time instead.");
1030  } else {
1031  vehicleParams.depart = depart;
1032  }
1033 
1034  double pos;
1035  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
1036  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Fourth parameter (position) requires a double.", outputStorage);
1037  }
1038  vehicleParams.departPos = pos;
1039  if (vehicleParams.departPos < 0) {
1040  const int proc = static_cast<int>(-vehicleParams.departPos);
1041  if (fabs(proc + vehicleParams.departPos) > NUMERICAL_EPS || proc >= static_cast<int>(DEPART_POS_DEF_MAX) || proc == static_cast<int>(DEPART_POS_GIVEN)) {
1042  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure position.", outputStorage);
1043  }
1044  vehicleParams.departPosProcedure = (DepartPosDefinition)proc;
1045  } else {
1046  vehicleParams.departPosProcedure = DEPART_POS_GIVEN;
1047  }
1048 
1049  double speed;
1050  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
1051  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Fifth parameter (speed) requires a double.", outputStorage);
1052  }
1053  vehicleParams.departSpeed = speed;
1054  if (vehicleParams.departSpeed < 0) {
1055  const int proc = static_cast<int>(-vehicleParams.departSpeed);
1056  if (proc >= static_cast<int>(DEPART_SPEED_DEF_MAX)) {
1057  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure speed.", outputStorage);
1058  }
1059  vehicleParams.departSpeedProcedure = (DepartSpeedDefinition)proc;
1060  } else {
1061  vehicleParams.departSpeedProcedure = DEPART_SPEED_GIVEN;
1062  }
1063 
1064  if (!server.readTypeCheckingByte(inputStorage, vehicleParams.departLane)) {
1065  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Sixth parameter (lane) requires a byte.", outputStorage);
1066  }
1067 
1068  if (vehicleParams.departLane < 0) {
1069  const int proc = static_cast<int>(-vehicleParams.departLane);
1070  if (proc >= static_cast<int>(DEPART_LANE_DEF_MAX)) {
1071  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure lane.", outputStorage);
1072  }
1073  vehicleParams.departLaneProcedure = (DepartLaneDefinition)proc;
1074  } else {
1075  vehicleParams.departLaneProcedure = DEPART_LANE_GIVEN;
1076  }
1077 
1078  SUMOVehicleParameter* params = new SUMOVehicleParameter(vehicleParams);
1079  try {
1080  SUMOVehicle* vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(params, route, vehicleType, true, false);
1081  MSNet::getInstance()->getVehicleControl().addVehicle(vehicleParams.id, vehicle);
1083  } catch (ProcessError& e) {
1084  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1085  }
1086  }
1087  break;
1088  case ADD_FULL: {
1089  if (v != 0) {
1090  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The vehicle " + id + " to add already exists.", outputStorage);
1091  }
1092  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
1093  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle requires a compound object.", outputStorage);
1094  }
1095  if (inputStorage.readInt() != 14) {
1096  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Adding a fully specified vehicle needs fourteen parameters.", outputStorage);
1097  }
1098  SUMOVehicleParameter vehicleParams;
1099  vehicleParams.id = id;
1100 
1101  std::string routeID;
1102  if (!server.readTypeCheckingString(inputStorage, routeID)) {
1103  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Second parameter (route) requires a string.", outputStorage);
1104  }
1105  const MSRoute* route = MSRoute::dictionary(routeID);
1106  if (!route) {
1107  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid route '" + routeID + "' for vehicle: '" + id + "'", outputStorage);
1108  }
1109 
1110  std::string vTypeID;
1111  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
1112  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "First parameter (type) requires a string.", outputStorage);
1113  }
1114  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(vTypeID);
1115  if (!vehicleType) {
1116  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid type '" + vTypeID + "' for vehicle '" + id + "'", outputStorage);
1117  }
1118 
1119  std::string helper;
1120  std::string error;
1121  if (!server.readTypeCheckingString(inputStorage, helper)) {
1122  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Third parameter (depart) requires an string.", outputStorage);
1123  }
1124  if (!SUMOVehicleParameter::parseDepart(helper, "vehicle", id, vehicleParams.depart, vehicleParams.departProcedure, error)) {
1125  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1126  }
1127  if (vehicleParams.departProcedure == DEPART_GIVEN && vehicleParams.depart < MSNet::getInstance()->getCurrentTimeStep()) {
1128  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Departure time in the past.", outputStorage);
1129  }
1130 
1131  if (!server.readTypeCheckingString(inputStorage, helper)) {
1132  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Fourth parameter (depart lane) requires a string.", outputStorage);
1133  }
1134  if (!SUMOVehicleParameter::parseDepartLane(helper, "vehicle", id, vehicleParams.departLane, vehicleParams.departLaneProcedure, error)) {
1135  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1136  }
1137  if (!server.readTypeCheckingString(inputStorage, helper)) {
1138  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Fifth parameter (depart position) requires a string.", outputStorage);
1139  }
1140  if (!SUMOVehicleParameter::parseDepartPos(helper, "vehicle", id, vehicleParams.departPos, vehicleParams.departPosProcedure, error)) {
1141  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1142  }
1143  if (!server.readTypeCheckingString(inputStorage, helper)) {
1144  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Sixth parameter (depart speed) requires a string.", outputStorage);
1145  }
1146  if (!SUMOVehicleParameter::parseDepartSpeed(helper, "vehicle", id, vehicleParams.departSpeed, vehicleParams.departSpeedProcedure, error)) {
1147  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1148  }
1149 
1150  if (!server.readTypeCheckingString(inputStorage, helper)) {
1151  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Seventh parameter (arrival lane) requires a string.", outputStorage);
1152  }
1153  if (!SUMOVehicleParameter::parseArrivalLane(helper, "vehicle", id, vehicleParams.arrivalLane, vehicleParams.arrivalLaneProcedure, error)) {
1154  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1155  }
1156  if (!server.readTypeCheckingString(inputStorage, helper)) {
1157  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Eighth parameter (arrival position) requires a string.", outputStorage);
1158  }
1159  if (!SUMOVehicleParameter::parseArrivalPos(helper, "vehicle", id, vehicleParams.arrivalPos, vehicleParams.arrivalPosProcedure, error)) {
1160  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1161  }
1162  if (!server.readTypeCheckingString(inputStorage, helper)) {
1163  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Ninth parameter (arrival speed) requires a string.", outputStorage);
1164  }
1165  if (!SUMOVehicleParameter::parseArrivalSpeed(helper, "vehicle", id, vehicleParams.arrivalSpeed, vehicleParams.arrivalSpeedProcedure, error)) {
1166  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1167  }
1168 
1169  if (!server.readTypeCheckingString(inputStorage, vehicleParams.fromTaz)) {
1170  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Tenth parameter (from taz) requires a string.", outputStorage);
1171  }
1172  if (!server.readTypeCheckingString(inputStorage, vehicleParams.toTaz)) {
1173  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Eleventh parameter (to taz) requires a string.", outputStorage);
1174  }
1175  if (!server.readTypeCheckingString(inputStorage, vehicleParams.line)) {
1176  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Twelth parameter (line) requires a string.", outputStorage);
1177  }
1178 
1179  int num;
1180  if (!server.readTypeCheckingInt(inputStorage, num)) {
1181  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "13th parameter (person capacity) requires an int.", outputStorage);
1182  }
1183  if (!server.readTypeCheckingInt(inputStorage, num)) {
1184  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "14th parameter (person number) requires an int.", outputStorage);
1185  }
1186  vehicleParams.personNumber = num;
1187 
1188  SUMOVehicleParameter* params = new SUMOVehicleParameter(vehicleParams);
1189  try {
1190  SUMOVehicle* vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(params, route, vehicleType, true, false);
1191  MSNet::getInstance()->getVehicleControl().addVehicle(vehicleParams.id, vehicle);
1193  } catch (ProcessError& e) {
1194  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1195  }
1196  }
1197  break;
1198  case REMOVE: {
1199  int why = 0;
1200  if (!server.readTypeCheckingByte(inputStorage, why)) {
1201  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Removing a vehicle requires a byte.", outputStorage);
1202  }
1204  switch (why) {
1205  case REMOVE_TELEPORT:
1206  // XXX semantics unclear
1207  // n = MSMoveReminder::NOTIFICATION_TELEPORT;
1209  break;
1210  case REMOVE_PARKING:
1211  // XXX semantics unclear
1212  // n = MSMoveReminder::NOTIFICATION_PARKING;
1214  break;
1215  case REMOVE_ARRIVED:
1217  break;
1218  case REMOVE_VAPORIZED:
1220  break;
1223  break;
1224  default:
1225  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Unknown removal status.", outputStorage);
1226  }
1227  if (v->hasDeparted()) {
1228  v->onRemovalFromNet(n);
1229  if (v->getLane() != 0) {
1230  v->getLane()->removeVehicle(v, n);
1231  }
1233  }
1234  }
1235  break;
1236  case VAR_MOVE_TO_VTD: {
1237  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
1238  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting VTD vehicle requires a compound object.", outputStorage);
1239  }
1240  if (inputStorage.readInt() != 5) {
1241  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting VTD vehicle should obtain: edgeID, lane, x, y, angle.", outputStorage);
1242  }
1243  // edge ID
1244  std::string edgeID;
1245  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
1246  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);
1247  }
1248  // lane index
1249  int laneNum = 0;
1250  if (!server.readTypeCheckingInt(inputStorage, laneNum)) {
1251  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second parameter for setting a VTD vehicle must be lane given as an int.", outputStorage);
1252  }
1253  // x
1254  double x = 0;
1255  double y = 0;
1256  double origAngle = 0;
1257  if (!server.readTypeCheckingDouble(inputStorage, x)) {
1258  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);
1259  }
1260  // y
1261  if (!server.readTypeCheckingDouble(inputStorage, y)) {
1262  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);
1263  }
1264  // angle
1265  if (!server.readTypeCheckingDouble(inputStorage, origAngle)) {
1266  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The fifth parameter for setting a VTD vehicle must be the angle given as a double.", outputStorage);
1267  }
1268  // process
1269  if (!v->isOnRoad()) {
1270  break;
1271  }
1272  std::string origID = edgeID + " " + toString(laneNum);
1273  if (laneNum < 0) {
1274  edgeID = '-' + edgeID;
1275  laneNum = -laneNum;
1276  }
1277  Position pos(x, y);
1278  SUMOReal angle = origAngle;
1279  if (angle >= 180.) {
1280  angle = -360. + angle;
1281  } else if (angle <= -180.) {
1282  angle = 360. + angle;
1283  }
1284 
1285  Position vehPos = v->getPosition();
1286  v->getBestLanes();
1287 #ifdef DEBUG_VTD
1288  std::cout << std::endl << "begin vehicle " << v->getID() << " vehPos:" << vehPos << " lane:" << v->getLane()->getID() << std::endl;
1289  std::cout << " want pos:" << pos << " edge:" << edgeID << " laneNum:" << laneNum << " origAngle:" << origAngle << " angle:" << angle << std::endl;
1290 #endif
1291 
1292  ConstMSEdgeVector edges;
1293  MSLane* lane = 0;
1294  SUMOReal lanePos;
1296  int routeOffset = 0;
1297  /* EGO vehicle is known to have a fixed route. @todo make this into a parameter of the TraCI call */
1298  if (v->getID() != "VTD_EGO") {
1299  // case a): vehicle is on its earlier route
1300  // we additionally assume it is moving forward (SUMO-limit);
1301  // note that the route ("edges") is not changed in this case
1302  bool found = vtdMap_matchingRoutePosition(pos, origID, *v, bestDistance, &lane, lanePos, routeOffset, edges);
1303  SUMOReal maxRouteDistance = 100;
1304  // use the best we have
1305  if (found && maxRouteDistance > bestDistance) {
1306  server.setVTDControlled(v, lane, lanePos, angle, routeOffset, edges, MSNet::getInstance()->getCurrentTimeStep());
1307  }
1308  } else {
1309  // case b): vehicle does not follow a pre-fixed route (regard the limiting factor in maxRouteDistance)
1310  bool found = vtdMap(pos, origID, angle, *v, server, bestDistance, &lane, lanePos, routeOffset, edges);
1311  SUMOReal maxRouteDistance = 100;
1312  // use the best we have
1313  if (found && maxRouteDistance > bestDistance) {
1314  server.setVTDControlled(v, lane, lanePos, angle, routeOffset, edges, MSNet::getInstance()->getCurrentTimeStep());
1315  } else {
1316  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Could not map vehicle '" + id + "'.", outputStorage);
1317  }
1318  }
1319  }
1320  break;
1321  case VAR_SPEED_FACTOR: {
1322  double factor = 0;
1323  if (!server.readTypeCheckingDouble(inputStorage, factor)) {
1324  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting speed factor requires a double.", outputStorage);
1325  }
1326  v->setChosenSpeedFactor(factor);
1327  }
1328  break;
1329  case VAR_PARAMETER: {
1330  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
1331  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
1332  }
1333  //readt itemNo
1334  inputStorage.readInt();
1335  std::string name;
1336  if (!server.readTypeCheckingString(inputStorage, name)) {
1337  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);
1338  }
1339  std::string value;
1340  if (!server.readTypeCheckingString(inputStorage, value)) {
1341  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
1342  }
1343  ((SUMOVehicleParameter&) v->getParameter()).addParameter(name, value);
1344  }
1345  break;
1346  default:
1347  try {
1348  if (!TraCIServerAPI_VehicleType::setVariable(CMD_SET_VEHICLE_VARIABLE, variable, getSingularType(v), server, inputStorage, outputStorage)) {
1349  return false;
1350  }
1351  } catch (ProcessError& e) {
1352  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1353  }
1354  break;
1355  }
1356  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_OK, warning, outputStorage);
1357  return true;
1358 }
1359 
1360 
1361 bool
1362 TraCIServerAPI_Vehicle::vtdMap(const Position& pos, const std::string& origID, const SUMOReal angle, MSVehicle& v, TraCIServer& server,
1363  SUMOReal& bestDistance, MSLane** lane, SUMOReal& lanePos, int& routeOffset, ConstMSEdgeVector& edges) {
1364  // collect edges around the vehicle
1365  SUMOReal speed = pos.distanceTo2D(v.getPosition()); // !!!v.getSpeed();
1366  std::set<std::string> into;
1367  PositionVector shape;
1368  shape.push_back(pos);
1369  server.collectObjectsInRange(CMD_GET_EDGE_VARIABLE, shape, speed * 2, into);
1370  SUMOReal maxDist = 0;
1371  std::map<MSLane*, LaneUtility> lane2utility;
1372  // compute utility for all candidate edges
1373  for (std::set<std::string>::const_iterator j = into.begin(); j != into.end(); ++j) {
1374  MSEdge* e = MSEdge::dictionary(*j);
1375  const MSEdge* prevEdge = 0;
1376  const MSEdge* nextEdge = 0;
1378  bool onRoute = false;
1379  // the next if/the clause sets "onRoute", "prevEdge", and "nextEdge", depending on
1380  // whether the currently seen edge is an internal one or a normal one
1381  if (ef != MSEdge::EDGEFUNCTION_INTERNAL) {
1382 #ifdef DEBUG_VTD_ANGLE
1383  std::cout << "Ego on normal" << std::endl;
1384 #endif
1385  // a normal edge
1386  //
1387  // check whether the currently seen edge is in the vehicle's route
1388  // - either the one it's on or one of the next edges
1389  const ConstMSEdgeVector& ev = v.getRoute().getEdges();
1390  unsigned int routePosition = v.getRoutePosition();
1392  ++routePosition;
1393  }
1394  ConstMSEdgeVector::const_iterator edgePos = std::find(ev.begin() + routePosition, ev.end(), e);
1395  onRoute = edgePos != ev.end(); // no? -> onRoute is false
1396  if (edgePos == ev.end() - 1 && v.getEdge() == e) {
1397  // onRoute is false as well if the vehicle is beyond the edge
1398  onRoute &= v.getEdge()->getLanes()[0]->getLength() > v.getPositionOnLane() + SPEED2DIST(speed);
1399  }
1400  // save prior and next edges
1401  prevEdge = e;
1402  nextEdge = !onRoute || edgePos == ev.end() - 1 ? 0 : *(edgePos + 1);
1403 #ifdef DEBUG_VTD_ANGLE
1404  std::cout << "normal:" << e->getID() << " prev:" << prevEdge->getID() << " next:";
1405  if (nextEdge != 0) {
1406  std::cout << nextEdge->getID();
1407  }
1408  std::cout << std::endl;
1409 #endif
1410  } else {
1411 #ifdef DEBUG_VTD_ANGLE
1412  std::cout << "Ego on internal" << std::endl;
1413 #endif
1414  // an internal edge
1415  // get the previous edge
1416  prevEdge = e;
1417  while (prevEdge != 0 && prevEdge->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1418  MSLane* l = prevEdge->getLanes()[0];
1419  l = l->getLogicalPredecessorLane();
1420  prevEdge = l == 0 ? 0 : &l->getEdge();
1421  }
1422  // check whether the previous edge is on the route (was on the route)
1423  const ConstMSEdgeVector& ev = v.getRoute().getEdges();
1424  ConstMSEdgeVector::const_iterator prevEdgePos = std::find(ev.begin() + v.getRoutePosition(), ev.end(), prevEdge);
1425  nextEdge = e;
1426  while (nextEdge != 0 && nextEdge->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1427  nextEdge = nextEdge->getSuccessors()[0]; // should be only one for an internal edge
1428  }
1429  if (prevEdgePos != ev.end()) {
1430  onRoute = *(prevEdgePos + 1) == nextEdge;
1431  }
1432 #ifdef DEBUG_VTD_ANGLE
1433  std::cout << "internal:" << e->getID() << " prev:" << prevEdge->getID() << " next:" << nextEdge->getID() << std::endl;
1434 #endif
1435  }
1436 
1437 
1438  // weight the lanes...
1439  const std::vector<MSLane*>& lanes = e->getLanes();
1440  for (std::vector<MSLane*>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
1441  MSLane* lane = *k;
1442  SUMOReal off = lane->getShape().nearest_offset_to_point2D(pos);
1443  SUMOReal langle = 180.;
1444  SUMOReal dist = 1000.;
1445  if (off >= 0) {
1446  dist = lane->getShape().distance(pos);
1447  if (dist > lane->getLength()) { // this is a workaround
1448  // a SmartDB, running at :49_2 delivers off=~9.24 while dist>24.?
1449  dist = 1000.;
1450  } else {
1451  langle = lane->getShape().rotationDegreeAtOffset(off);
1452  }
1453  }
1454  bool sameEdge = &lane->getEdge() == &v.getLane()->getEdge() && v.getEdge()->getLanes()[0]->getLength() > v.getPositionOnLane() + SPEED2DIST(speed);
1455  /*
1456  const MSEdge* rNextEdge = nextEdge;
1457  while(rNextEdge==0&&lane->getEdge().getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL) {
1458  MSLane* next = lane->getLinkCont()[0]->getLane();
1459  rNextEdge = next == 0 ? 0 : &next->getEdge();
1460  }
1461  */
1462 #ifdef DEBUG_VTD_ANGLE
1463  std::cout << lane->getID() << ": " << langle << " " << off << std::endl;
1464 #endif
1465  lane2utility[lane] = LaneUtility(
1466  dist, GeomHelper::getMinAngleDiff(angle, langle),
1467  lane->getParameter("origId", "") == origID,
1468  onRoute, sameEdge, prevEdge, nextEdge);
1469  // update scaling value
1470  maxDist = MAX2(maxDist, dist);
1471 
1472  }
1473  }
1474 
1475  // get the best lane given the previously computed values
1476  SUMOReal bestValue = 0;
1477  MSLane* bestLane = 0;
1478  for (std::map<MSLane*, LaneUtility>::iterator i = lane2utility.begin(); i != lane2utility.end(); ++i) {
1479  MSLane* l = (*i).first;
1480  const LaneUtility& u = (*i).second;
1481  SUMOReal distN = u.dist > 999 ? -10 : 1. - (u.dist / maxDist);
1482  SUMOReal angleDiffN = 1. - (u.angleDiff / 180.);
1483  SUMOReal idN = u.ID ? 1 : 0;
1484  SUMOReal onRouteN = u.onRoute ? 1 : 0;
1485  SUMOReal sameEdgeN = u.sameEdge ? MIN2(v.getEdge()->getLength() / speed, (SUMOReal)1.) : 0;
1486  SUMOReal value = (distN * .35
1487  + angleDiffN * 0.35 /*.5 */
1488  + idN * .1
1489  + onRouteN * 0.1
1490  + sameEdgeN * 0.1);
1491 #ifdef DEBUG_VTD
1492  std::cout << " x; l:" << l->getID() << " d:" << u.dist << " dN:" << distN << " aD:" << angleDiffN <<
1493  " ID:" << idN << " oRN:" << onRouteN << " sEN:" << sameEdgeN << " value:" << value << std::endl;
1494 #endif
1495  if (value > bestValue || bestLane == 0) {
1496  bestValue = value;
1497  bestLane = l;
1498  }
1499  }
1500  // no best lane found, return
1501  if (bestLane == 0) {
1502  return false;
1503  }
1504  const LaneUtility& u = lane2utility.find(bestLane)->second;
1505  bestDistance = u.dist;
1506  *lane = bestLane;
1507  lanePos = bestLane->getShape().nearest_offset_to_point2D(pos);
1508  const MSEdge* prevEdge = u.prevEdge;
1509  if (u.onRoute) {
1510  const ConstMSEdgeVector& ev = v.getRoute().getEdges();
1511  ConstMSEdgeVector::const_iterator prevEdgePos = std::find(ev.begin(), ev.end(), prevEdge);
1512  routeOffset = (int)std::distance(ev.begin(), prevEdgePos);
1513  //std::cout << SIMTIME << "vtdMap vehicle=" << v.getID() << " currLane=" << v.getLane()->getID() << " routeOffset=" << routeOffset << " edges=" << toString(ev) << " bestLane=" << bestLane->getID() << " prevEdge=" << prevEdge->getID() << "\n";
1514  } else {
1515  edges.push_back(u.prevEdge);
1516  /*
1517  if(bestLane->getEdge().getPurpose()!=MSEdge::EDGEFUNCTION_INTERNAL) {
1518  edges.push_back(&bestLane->getEdge());
1519  }
1520  */
1521  if (u.nextEdge != 0) {
1522  edges.push_back(u.nextEdge);
1523  }
1524  routeOffset = 0;
1525 #ifdef DEBUG_VTD_ANGLE
1526  std::cout << "internal2:" << " prev:";
1527  if (u.prevEdge != 0) {
1528  std::cout << u.prevEdge->getID();
1529  }
1530  std::cout << " next:";
1531  if (u.nextEdge != 0) {
1532  std::cout << u.nextEdge->getID();
1533  }
1534  std::cout << std::endl;
1535 #endif
1536  }
1537  return true;
1538 }
1539 
1540 
1541 bool
1542 TraCIServerAPI_Vehicle::findCloserLane(const MSEdge* edge, const Position& pos, SUMOReal& bestDistance, MSLane** lane) {
1543  if (edge == 0) {
1544  return false;
1545  }
1546  const std::vector<MSLane*>& lanes = edge->getLanes();
1547  bool newBest = false;
1548  for (std::vector<MSLane*>::const_iterator k = lanes.begin(); k != lanes.end() && bestDistance > POSITION_EPS; ++k) {
1549  MSLane* candidateLane = *k;
1550  const SUMOReal dist = candidateLane->getShape().distance(pos); // get distance
1551 #ifdef DEBUG_VTD
1552  std::cout << " b at lane " << candidateLane->getID() << " dist:" << dist << " best:" << bestDistance << std::endl;
1553 #endif
1554  if (dist < bestDistance) {
1555  // is the new distance the best one? keep then...
1556  bestDistance = dist;
1557  *lane = candidateLane;
1558  newBest = true;
1559  }
1560  }
1561  return newBest;
1562 }
1563 
1564 bool
1566  SUMOReal& bestDistance, MSLane** lane, SUMOReal& lanePos, int& routeOffset, ConstMSEdgeVector& /*edges*/) {
1567 
1568  const ConstMSEdgeVector& edges = v.getRoute().getEdges();
1569  routeOffset = 0;
1570  // routes may be looped which makes routeOffset ambiguous. We first try to
1571  // find the closest upcoming edge on the route and then look for closer passed edges
1572 
1573  // look forward along the route
1574  const MSEdge* prev = 0;
1575  UNUSED_PARAMETER(prev); // silence 'unused variable' warning when built without INTERNAL_LANES
1576  for (ConstMSEdgeVector::const_iterator i = v.getCurrentRouteEdge(); i != edges.end(); ++i) {
1577 #ifdef HAVE_INTERNAL_LANES
1578  while (prev != 0) {
1579  // check internal edge(s)
1580  const MSEdge* internalCand = prev->getInternalFollowingEdge(*i);
1581  findCloserLane(internalCand, pos, bestDistance, lane);
1582  prev = internalCand;
1583  }
1584 #endif
1585  if (findCloserLane(*i, pos, bestDistance, lane)) {
1586  routeOffset = (int)std::distance(edges.begin(), i);
1587  }
1588  prev = *i;
1589  }
1590  // look backward along the route
1591  const MSEdge* next = *v.getCurrentRouteEdge();
1592  UNUSED_PARAMETER(next); // silence 'unused variable' warning when built without INTERNAL_LANES
1593  for (ConstMSEdgeVector::const_iterator i = v.getCurrentRouteEdge(); i != edges.begin(); --i) {
1594  prev = *i;
1595 #ifdef HAVE_INTERNAL_LANES
1596  while (prev != 0) {
1597  // check internal edge(s)
1598  const MSEdge* internalCand = prev->getInternalFollowingEdge(next);
1599  findCloserLane(internalCand, pos, bestDistance, lane);
1600  prev = internalCand;
1601  }
1602 #endif
1603  if (findCloserLane(*i, pos, bestDistance, lane)) {
1604  routeOffset = (int)std::distance(edges.begin(), i);
1605  }
1606  next = *i;
1607  }
1608 
1609  assert(lane != 0);
1610  // quit if no solution was found, reporting a failure
1611  if (lane == 0) {
1612 #ifdef DEBUG_VTD
1613  std::cout << " b failed - no best route lane" << std::endl;
1614 #endif
1615  return false;
1616  }
1617 
1618 
1619  // position may be inaccurate; let's checkt the given index, too
1620  // a) is enabled for non-internal lanes only, as otherwise the position information may ambiguous
1621  // b) it's something one has to enable when building the nework - keepin the OSM IDs - is probably not always done
1622  if ((*lane)->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1623  const std::vector<MSLane*>& lanes = (*lane)->getEdge().getLanes();
1624  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
1625  if ((*i)->getParameter("origId", "") == origID) {
1626  *lane = *i;
1627  break;
1628  }
1629  }
1630  }
1631  // check position, stuff, we should have the best lane along the route
1632  lanePos = MAX2(SUMOReal(0), MIN2(SUMOReal((*lane)->getLength() - POSITION_EPS), (*lane)->getShape().nearest_offset_to_point2D(pos, false)));
1633  //std::cout << SIMTIME << " vtdMap_matchingRoutePosition vehicle=" << v.getID() << " currLane=" << v.getLane()->getID() << " routeOffset=" << routeOffset << " edges=" << toString(edges) << " lane=" << (*lane)->getID() << "\n";
1634 #ifdef DEBUG_VTD
1635  std::cout << " b ok lane " << (*lane)->getID() << " lanePos:" << lanePos << std::endl;
1636 #endif
1637  return true;
1638 }
1639 
1640 
1641 bool
1643  tcpip::Storage& outputStorage, const MSVehicle* v) {
1644  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
1645  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of distance requires a compound object.", outputStorage);
1646  }
1647  if (inputStorage.readInt() != 2) {
1648  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of distance requires position and distance type as parameter.", outputStorage);
1649  }
1650 
1651  Position pos;
1652  std::pair<const MSLane*, SUMOReal> roadPos;
1653 
1654  // read position
1655  int posType = inputStorage.readUnsignedByte();
1656  switch (posType) {
1657  case POSITION_ROADMAP:
1658  try {
1659  std::string roadID = inputStorage.readString();
1660  roadPos.second = inputStorage.readDouble();
1661  roadPos.first = TraCIServerAPI_Simulation::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos.second);
1662  pos = roadPos.first->getShape().positionAtOffset(roadPos.second);
1663  } catch (TraCIException& e) {
1664  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, e.what(), outputStorage);
1665  }
1666  break;
1667  case POSITION_2D:
1668  case POSITION_3D: {
1669  const double p1x = inputStorage.readDouble();
1670  const double p1y = inputStorage.readDouble();
1671  pos.set(p1x, p1y);
1672  }
1673  if (posType == POSITION_3D) {
1674  inputStorage.readDouble(); // z value is ignored
1675  }
1677  break;
1678  default:
1679  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Unknown position format used for distance request", outputStorage);
1680  }
1681 
1682  // read distance type
1683  int distType = inputStorage.readUnsignedByte();
1684 
1685  SUMOReal distance = INVALID_DOUBLE_VALUE;
1686  if (v->isOnRoad()) {
1687  if (distType == REQUEST_DRIVINGDIST) {
1688  distance = v->getRoute().getDistanceBetween(v->getPositionOnLane(), roadPos.second,
1689  v->getEdge(), &roadPos.first->getEdge());
1690  if (distance == std::numeric_limits<SUMOReal>::max()) {
1691  distance = INVALID_DOUBLE_VALUE;
1692  }
1693  } else {
1694  // compute air distance (default)
1695  distance = v->getPosition().distanceTo(pos);
1696  }
1697  }
1698  // write response command
1699  outputStorage.writeUnsignedByte(TYPE_DOUBLE);
1700  outputStorage.writeDouble(distance);
1701  return true;
1702 }
1703 
1704 
1705 // ------ helper functions ------
1706 bool
1707 TraCIServerAPI_Vehicle::getPosition(const std::string& id, Position& p) {
1708  MSVehicle* v = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(id));
1709  if (v == 0) {
1710  return false;
1711  }
1712  p = v->getPosition();
1713  return true;
1714 }
1715 
1716 
1719  const MSVehicleType& oType = veh->getVehicleType();
1720  std::string newID = oType.getID().find('@') == std::string::npos ? oType.getID() + "@" + veh->getID() : oType.getID();
1721  MSVehicleType* type = MSVehicleType::build(newID, &oType);
1722  static_cast<MSVehicle*>(veh)->replaceVehicleType(type);
1723  return *type;
1724 }
1725 
1726 
1727 #include <microsim/MSEdgeControl.h>
1728 
1729 const std::map<std::string, std::vector<MSLane*> >&
1731  if (gVTDMap.size() == 0) {
1733  for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
1734  const std::vector<MSLane*>& lanes = (*i)->getLanes();
1735  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
1736  if ((*j)->knowsParameter("origId")) {
1737  std::string origID = (*j)->getParameter("origId", "");
1738  if (gVTDMap.find(origID) == gVTDMap.end()) {
1739  gVTDMap[origID] = std::vector<MSLane*>();
1740  }
1741  gVTDMap[origID].push_back(*j);
1742  }
1743  }
1744  }
1745  if (gVTDMap.size() == 0) {
1746  gVTDMap["unknown"] = std::vector<MSLane*>();
1747  }
1748  }
1749  return gVTDMap;
1750 }
1751 
1752 
1753 #endif
1754 
1755 
1756 /****************************************************************************/
1757 
#define VAR_ROAD_ID
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:521
static bool setVariable(const int cmd, const int variable, MSVehicleType &v, TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value for the given type.
#define REMOVE_PARKING
void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
Definition: MSVehicle.cpp:2623
bool enterLaneAtMove(MSLane *enteredLane, bool onTeleporting=false)
Update when the vehicle enters a new lane in the move step.
Definition: MSVehicle.cpp:1882
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:467
RGBColor color
The vehicle&#39;s color.
static bool commandDistanceRequest(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage, const MSVehicle *v)
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80
#define VAR_EMISSIONCLASS
#define VAR_CO2EMISSION
#define REQUEST_DRIVINGDIST
SUMOReal distance(const Position &p, bool perpendicular=false) const
#define VAR_LENGTH
void collectObjectsInRange(int domain, const PositionVector &shape, SUMOReal range, std::set< std::string > &into)
The time is given.
static bool parseDepartSpeed(const std::string &val, const std::string &element, const std::string &id, SUMOReal &speed, DepartSpeedDefinition &dsd, std::string &error)
Validates a given departSpeed value.
#define SPEED2DIST(x)
Definition: SUMOTime.h:55
#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
static bool parseArrivalPos(const std::string &val, const std::string &element, const std::string &id, SUMOReal &pos, ArrivalPosDefinition &apd, std::string &error)
Validates a given arrivalPos value.
#define CMD_RESUME
Stop & getNextStop()
Definition: MSVehicle.cpp:2820
#define POSITION_2D
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc4: Change Vehicle State)
SUMOReal getDepartPos() const
Returns this vehicle&#39;s real departure position.
#define VAR_POSITION
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:185
static const MSLane * getLaneChecking(std::string roadID, int laneIndex, SUMOReal pos)
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
Definition: MSVehicle.h:553
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
#define VAR_ROUTE
#define CMD_CHANGELANE
bool readTypeCheckingColor(tcpip::Storage &inputStorage, RGBColor &into)
Reads the value type and a color, verifying the type.
constVehIt loadedVehBegin() const
Returns the begin of the internal vehicle map.
#define VAR_SPEEDSETMODE
#define VAR_TAU
SUMOReal getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:2835
void setRespectJunctionPriority(bool value)
Sets whether junction priority rules shall be respected.
Definition: MSVehicle.cpp:394
#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:375
Position getPosition(const SUMOReal offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:718
SUMOReal departSpeed
(optional) The initial speed of the vehicle
#define VAR_ALLOWED_SPEED
#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.
#define VAR_WAITING_TIME
virtual double readDouble()
SUMOReal arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
#define VAR_SIGNALS
#define VAR_TYPE
#define VAR_ROUTE_ID
Notification
Definition of a vehicle state.
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:974
#define VAR_VEHICLECLASS
bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:572
#define VAR_SPEED_FACTOR
#define VAR_COLOR
SUMOReal getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:2464
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:673
bool readTypeCheckingInt(tcpip::Storage &inputStorage, int &into)
Reads the value type and an int, verifying the type.
SUMOReal arrivalPos
(optional) The position the vehicle shall arrive on
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:160
T MAX2(T a, T b)
Definition: StdDefs.h:75
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:85
virtual bool 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...
unsigned int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:2562
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
#define TYPE_COLOR
#define TYPE_STRINGLIST
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
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:578
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:647
#define VAR_BEST_LANES
SUMOReal getCO2Emissions() const
Returns CO2 emission of the current state.
Definition: MSVehicle.cpp:2452
unsigned int personNumber
The static number of persons in the vehicle when it departs (not including boarding persons) ...
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
std::pair< const MSVehicle *const, SUMOReal > getLeader(SUMOReal dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:2414
SUMOReal distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:221
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
SUMOReal getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:340
virtual void writeUnsignedByte(int)
const std::string & getParameter(const std::string &key, const std::string &defaultValue) const
Returns the value for a given key.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:255
EdgeBasicFunction
Defines possible edge types.
Definition: MSEdge.h:89
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
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:545
#define VAR_NOISEEMISSION
#define VAR_FUELCONSUMPTION
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
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)
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
#define VAR_POSITION3D
The speed is given.
The car-following model and parameter.
Definition: MSVehicleType.h:74
bool triggered
whether an arriving person lets the vehicle continue
Definition: MSVehicle.h:667
#define TYPE_STRING
virtual int readUnsignedByte()
std::string toTaz
The vehicle&#39;s destination zone (district)
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.
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa4: Get Vehicle Variable)
SUMOReal nextOccupation
As occupation, but without the first lane.
Definition: MSVehicle.h:551
#define VAR_NOXEMISSION
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:91
#define VAR_ANGLE
const std::string & getID() const
Returns the id.
Definition: Named.h:65
A road/street connecting two junctions.
Definition: MSEdge.h:80
MSLane * lane
The described lane.
Definition: MSVehicle.h:543
static bool vtdMap(const Position &pos, const std::string &origID, const SUMOReal angle, MSVehicle &v, TraCIServer &server, SUMOReal &bestDistance, MSLane **lane, SUMOReal &lanePos, int &routeOffset, ConstMSEdgeVector &edges)
#define VAR_PERSON_NUMBER
SUMOReal getLength() const
return the length of the edge
Definition: MSEdge.h:562
void setVTDControlled(MSVehicle *v, MSLane *l, SUMOReal pos, SUMOReal angle, int edgeOffset, ConstMSEdgeVector route, SUMOTime t)
#define CMD_SLOWDOWN
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1308
#define VAR_SHAPECLASS
#define max(a, b)
Definition: polyfonts.c:65
void setEmergencyBrakeRedLight(bool value)
Sets whether red lights shall be a reason to brake.
Definition: MSVehicle.cpp:400
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.
#define REMOVE_ARRIVED
DepartLaneDefinition
Possible ways to choose a lane on depart.
#define VAR_ACCEL
#define CMD_CHANGETARGET
Representation of a vehicle.
Definition: SUMOVehicle.h:65
MSStoppingPlace * containerstop
(Optional) container stop if one is assigned to the stop
Definition: MSVehicle.h:655
void setChosenSpeedFactor(const SUMOReal factor)
Returns the precomputed factor by which the driver wants to be faster than the speed limit...
virtual int readInt()
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
SUMOReal getDistanceBetween(SUMOReal fromPos, SUMOReal toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:285
#define REMOVE_TELEPORT_ARRIVED
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, unsigned int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:247
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:87
bool willPass(const MSEdge *const edge) const
Returns whether the vehicle wil pass the given edge.
Definition: MSVehicle.cpp:620
#define VAR_LANEPOSITION
A list of positions.
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:308
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.
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:65
bool readTypeCheckingStringList(tcpip::Storage &inputStorage, std::vector< std::string > &into)
Reads the value type and a string list, verifying the type.
SUMOReal z() const
Returns the z-position.
Definition: Position.h:73
The vehicle arrived at its destination (is deleted)
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:933
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, const MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true)
Builds a vehicle, increases the number of built vehicles.
int arrivalLane
(optional) The lane the vehicle shall arrive on (not used yet)
virtual void writeStringList(const std::vector< std::string > &s)
SUMOTime depart
The vehicle&#39;s departure time.
#define VAR_PMXEMISSION
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:128
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:663
#define CMD_SET_VEHICLE_VARIABLE
T MIN2(T a, T b)
Definition: StdDefs.h:69
#define VAR_IMPERFECTION
#define POSITION_EPS
Definition: config.h:187
std::string fromTaz
The vehicle&#39;s origin zone (district)
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:541
#define VAR_EDGES
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:551
static bool parseArrivalLane(const std::string &val, const std::string &element, const std::string &id, int &lane, ArrivalLaneDefinition &ald, std::string &error)
Validates a given arrivalLane value.
#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:54
#define REMOVE
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:73
const int VEHPARS_COLOR_SET
virtual void writeStorage(tcpip::Storage &store)
#define VAR_LEADER
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:939
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:2037
static bool parseDepartPos(const std::string &val, const std::string &element, const std::string &id, SUMOReal &pos, DepartPosDefinition &dpd, std::string &error)
Validates a given departPos value.
bool allowsContinuation
Whether this lane allows to continue the drive.
Definition: MSVehicle.h:555
SUMOReal getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
Definition: MSVehicle.cpp:2494
static SUMOReal naviDegree(const SUMOReal angle)
Definition: GeomHelper.cpp:191
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
std::string line
The vehicle&#39;s line (mainly for public transport)
#define INVALID_DOUBLE_VALUE
#define VAR_SPEED
DepartSpeedDefinition
Possible ways to choose the departure speed.
SUMOReal getNOxEmissions() const
Returns NOx emission of the current state.
Definition: MSVehicle.cpp:2470
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
static bool findCloserLane(const MSEdge *edge, const Position &pos, SUMOReal &bestDistance, MSLane **lane)
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:847
bool replaceRouteEdges(ConstMSEdgeVector &edges, bool onInit=false)
Replaces the current route by the given edges.
static bool parseArrivalSpeed(const std::string &val, const std::string &element, const std::string &id, SUMOReal &speed, ArrivalSpeedDefinition &asd, std::string &error)
Validates a given arrivalSpeed value.
SUMOReal getPMxEmissions() const
Returns PMx emission of the current state.
Definition: MSVehicle.cpp:2476
SUMOReal getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:2458
#define VAR_EDGE_TRAVELTIME
SUMOReal rotationDegreeAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:772
#define VAR_COEMISSION
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, SUMOReal > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:240
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:242
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2826
void scheduleVehicleRemoval(SUMOVehicle *veh)
Removes a vehicle after it has ended.
void setTentativeLaneAndPosition(MSLane *lane, const SUMOReal pos)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:2638
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:84
#define VAR_MOVE_TO
#define SUMOTime_MAX
Definition: SUMOTime.h:44
#define TYPE_DOUBLE
std::string toHex(const T i, std::streamsize numDigits=0)
Definition: ToString.h:64
bool containerTriggered
whether an arriving container lets the vehicle continue
Definition: MSVehicle.h:669
void setConsiderMaxDeceleration(bool value)
Sets whether the maximum deceleration shall be regarded.
Definition: MSVehicle.cpp:388
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:349
int setParameter
Information for the router which parameter were set.
#define CMD_REROUTE_TRAVELTIME
std::vector< MSLane * > bestContinuations
Consecutive lane that can be followed without a lane change (contribute to length and occupation) ...
Definition: MSVehicle.h:557
#define TYPE_BYTE
#define VAR_ROUTE_INDEX
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
SUMOReal getFuelConsumption() const
Returns fuel consumption of the current state.
Definition: MSVehicle.cpp:2482
static SUMOReal getMinAngleDiff(SUMOReal angle1, SUMOReal angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
Definition: GeomHelper.cpp:172
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:93
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:376
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:649
SUMOReal getChosenSpeedFactor() const
Returns the precomputed factor by which the driver wants to be faster than the speed limit...
bool addTraciBusOrContainerStop(const std::string &stopId, const SUMOTime duration, const SUMOTime until, const bool parking, const bool triggered, const bool containerTriggered, const bool isContainerStop, std::string &errorMsg)
Definition: MSVehicle.cpp:2733
const std::string & getID() const
Returns the name of the vehicle type.
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:348
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.
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:406
SUMOReal getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:434
virtual void writeDouble(double)
#define REMOVE_VAPORIZED
unsigned size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:90
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:322
#define VAR_MOVE_TO_VTD
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:232
const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
Definition: MSVehicle.cpp:748
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.
int getSignals() const
Returns the signals.
Definition: MSVehicle.h:929
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:83
#define SUMOReal
Definition: config.h:213
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:921
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:913
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
const MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:342
#define VAR_SPEED_WITHOUT_TRACI
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:339
constVehIt loadedVehEnd() const
Returns the end of the internal vehicle map.
#define NUMERICAL_EPS
Definition: config.h:160
void reroute(SUMOTime t, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, const bool onInit=false, const bool withTaz=false)
Performs a rerouting using the given router.
#define VAR_LANECHANGE_MODE
#define VAR_MAXSPEED
bool retrieveExistingEffort(const MSEdge *const e, const SUMOReal t, SUMOReal &value) const
Returns an effort for an edge and time if stored.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
The vehicle was teleported out of the net.
#define VAR_DECEL
#define VAR_ROUTE_VALID
The class responsible for building and deletion of vehicles.
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:77
#define VAR_PARAMETER
#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
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane&#39;s maximum speed, given a vehicle&#39;s speed limit adaptation.
Definition: MSLane.h:353
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:393
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:385
The edge is an internal edge.
Definition: MSEdge.h:97
static const std::map< std::string, std::vector< MSLane * > > & getOrBuildVTDMap()
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:201
Tag for the last element in the enum for safe int casting.
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, MTRand *rng=0)
Returns the named vehicle type or a sample from the named distribution.
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
#define ADD_FULL
void add(SUMOVehicle *veh)
Adds a single vehicle for departure.
bool addTraciStop(MSLane *const lane, const SUMOReal startPos, const SUMOReal endPos, const SUMOTime duration, const SUMOTime until, const bool parking, const bool triggered, const bool containerTriggered, std::string &errorMsg)
Definition: MSVehicle.cpp:2700
SUMOReal startPos
The stopping position start.
Definition: MSVehicle.h:659
MSStoppingPlace * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSVehicle.h:653
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle&#39;s internal edge travel times/efforts container.
Definition: MSVehicle.cpp:641
bool retrieveExistingTravelTime(const MSEdge *const e, const SUMOReal t, SUMOReal &value) const
Returns a travel time for an edge and time if stored.
unsigned int getRoutePosition() const
Definition: MSVehicle.cpp:626
static void parseEdgesList(const std::string &desc, ConstMSEdgeVector &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
Definition: MSEdge.cpp:634
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
DepartDefinition
Possible ways to depart.
static bool parseDepart(const std::string &val, const std::string &element, const std::string &id, SUMOTime &depart, DepartDefinition &dd, std::string &error)
Validates a given depart value.
#define VAR_DISTANCE
bool readTypeCheckingByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and a byte, verifying the type.
#define VAR_HCEMISSION
void setConsiderMaxAcceleration(bool value)
Sets whether the maximum acceleration shall be regarded.
Definition: MSVehicle.cpp:382
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:78
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
std::string id
The vehicle&#39;s id.
bool parking
whether the vehicle is removed from the net while stopping
Definition: MSVehicle.h:671
The vehicle is being teleported.
#define VAR_WIDTH
SUMOReal getAngle() const
Returns the vehicle&#39;s direction in degrees.
Definition: MSVehicle.h:452
const MSEdgeVector & getEdges() const
Returns loaded edges.
const std::string & getID() const
Returns the name of the vehicle.
static bool vtdMap_matchingRoutePosition(const Position &pos, const std::string &origID, MSVehicle &v, SUMOReal &bestDistance, MSLane **lane, SUMOReal &lanePos, int &routeOffset, ConstMSEdgeVector &edges)
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:122
static bool parseDepartLane(const std::string &val, const std::string &element, const std::string &id, int &lane, DepartLaneDefinition &dld, std::string &error)
Validates a given departLane value.