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-2015 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 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(0, 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 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 angle = 0;
1257  double origAngle = 0;
1258  if (!server.readTypeCheckingDouble(inputStorage, x)) {
1259  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);
1260  }
1261  // y
1262  if (!server.readTypeCheckingDouble(inputStorage, y)) {
1263  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);
1264  }
1265  // angle
1266  if (!server.readTypeCheckingDouble(inputStorage, origAngle)) {
1267  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The fifth parameter for setting a VTD vehicle must be the angle given as a double.", outputStorage);
1268  }
1269  // process
1270  if (!v->isOnRoad()) {
1271  break;
1272  }
1273  std::string origID = edgeID + " " + toString(laneNum);
1274  if (laneNum < 0) {
1275  edgeID = '-' + edgeID;
1276  laneNum = -laneNum;
1277  }
1278  Position pos(x, y);
1279  angle *= -1.;
1280  if (angle >= 180.) {
1281  angle = -360. + angle;
1282  } else if (angle <= -180.) {
1283  angle = 360. + angle;
1284  }
1285 
1286  Position vehPos = v->getPosition();
1287  v->getBestLanes();
1288 #ifdef DEBUG_VTD
1289  std::cout << std::endl << "begin vehicle " << v->getID() << " vehPos:" << vehPos << " lane:" << v->getLane()->getID() << std::endl;
1290  std::cout << " want pos:" << pos << " edge:" << edgeID << " laneNum:" << laneNum << " origAngle:" << origAngle << " angle:" << angle << std::endl;
1291 #endif
1292 
1293  ConstMSEdgeVector edges;
1294  MSLane* lane = 0;
1295  SUMOReal lanePos;
1297  int routeOffset = 0;
1298  /* EGO vehicle is known to have a fixed route. @todo make this into a parameter of the TraCI call */
1299  if (v->getID() != "VTD_EGO") {
1300  // case a): vehicle is on its earlier route
1301  // we additionally assume it is moving forward (SUMO-limit);
1302  // note that the route ("edges") is not changed in this case
1303  bool found = vtdMap_matchingRoutePosition(pos, origID, *v, bestDistance, &lane, lanePos, routeOffset, edges);
1304  SUMOReal maxRouteDistance = 100;
1305  // use the best we have
1306  if (found && maxRouteDistance > bestDistance) {
1307  server.setVTDControlled(v, lane, lanePos, routeOffset, edges, MSNet::getInstance()->getCurrentTimeStep());
1308  }
1309  } else {
1310  // case b): vehicle does not follow a pre-fixed route (regard the limiting factor in maxRouteDistance)
1311  bool found = vtdMap(pos, origID, angle, *v, server, bestDistance, &lane, lanePos, routeOffset, edges);
1312  SUMOReal maxRouteDistance = 100;
1313  // use the best we have
1314  if (found && maxRouteDistance > bestDistance) {
1315  server.setVTDControlled(v, lane, lanePos, routeOffset, edges, MSNet::getInstance()->getCurrentTimeStep());
1316  } else {
1317  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Could not map vehicle '" + id + "'.", outputStorage);
1318  }
1319  }
1320  }
1321  break;
1322  case VAR_SPEED_FACTOR: {
1323  double factor = 0;
1324  if (!server.readTypeCheckingDouble(inputStorage, factor)) {
1325  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting speed factor requires a double.", outputStorage);
1326  }
1327  v->setChosenSpeedFactor(factor);
1328  }
1329  break;
1330  case VAR_PARAMETER: {
1331  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
1332  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
1333  }
1334  //readt itemNo
1335  inputStorage.readInt();
1336  std::string name;
1337  if (!server.readTypeCheckingString(inputStorage, name)) {
1338  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);
1339  }
1340  std::string value;
1341  if (!server.readTypeCheckingString(inputStorage, value)) {
1342  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
1343  }
1344  ((SUMOVehicleParameter&) v->getParameter()).addParameter(name, value);
1345  }
1346  break;
1347  default:
1348  try {
1349  if (!TraCIServerAPI_VehicleType::setVariable(CMD_SET_VEHICLE_VARIABLE, variable, getSingularType(v), server, inputStorage, outputStorage)) {
1350  return false;
1351  }
1352  } catch (ProcessError& e) {
1353  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1354  }
1355  break;
1356  }
1357  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_OK, warning, outputStorage);
1358  return true;
1359 }
1360 
1361 
1362 bool
1363 TraCIServerAPI_Vehicle::vtdMap(const Position& pos, const std::string& origID, const SUMOReal angle, MSVehicle& v, TraCIServer& server,
1364  SUMOReal& bestDistance, MSLane** lane, SUMOReal& lanePos, int& routeOffset, ConstMSEdgeVector& edges) {
1365  // collect edges around the vehicle
1366  SUMOReal speed = pos.distanceTo2D(v.getPosition()); // !!!v.getSpeed();
1367  std::set<std::string> into;
1368  PositionVector shape;
1369  shape.push_back(pos);
1370  server.collectObjectsInRange(CMD_GET_EDGE_VARIABLE, shape, speed * 2, into);
1371  SUMOReal maxDist = 0;
1372  std::map<MSLane*, LaneUtility> lane2utility;
1373  // compute utility for all candidate edges
1374  for (std::set<std::string>::const_iterator j = into.begin(); j != into.end(); ++j) {
1375  MSEdge* e = MSEdge::dictionary(*j);
1376  const MSEdge* prevEdge = 0;
1377  const MSEdge* nextEdge = 0;
1379  bool onRoute = false;
1380  // the next if/the clause sets "onRoute", "prevEdge", and "nextEdge", depending on
1381  // whether the currently seen edge is an internal one or a normal one
1382  if (ef != MSEdge::EDGEFUNCTION_INTERNAL) {
1383 #ifdef DEBUG_VTD_ANGLE
1384  std::cout << "Ego on normal" << std::endl;
1385 #endif
1386  // a normal edge
1387  //
1388  // check whether the currently seen edge is in the vehicle's route
1389  // - either the one it's on or one of the next edges
1390  const ConstMSEdgeVector& ev = v.getRoute().getEdges();
1391  unsigned int routePosition = v.getRoutePosition();
1393  ++routePosition;
1394  }
1395  ConstMSEdgeVector::const_iterator edgePos = std::find(ev.begin() + routePosition, ev.end(), e);
1396  onRoute = edgePos != ev.end(); // no? -> onRoute is false
1397  if (edgePos == ev.end() - 1 && v.getEdge() == e) {
1398  // onRoute is false as well if the vehicle is beyond the edge
1399  onRoute &= v.getEdge()->getLanes()[0]->getLength() > v.getPositionOnLane() + SPEED2DIST(speed);
1400  }
1401  // save prior and next edges
1402  prevEdge = e;
1403  nextEdge = !onRoute || edgePos == ev.end() - 1 ? 0 : *(edgePos + 1);
1404 #ifdef DEBUG_VTD_ANGLE
1405  std::cout << "normal:" << e->getID() << " prev:" << prevEdge->getID() << " next:";
1406  if (nextEdge != 0) {
1407  std::cout << nextEdge->getID();
1408  }
1409  std::cout << std::endl;
1410 #endif
1411  } else {
1412 #ifdef DEBUG_VTD_ANGLE
1413  std::cout << "Ego on internal" << std::endl;
1414 #endif
1415  // an internal edge
1416  // get the previous edge
1417  prevEdge = e;
1418  while (prevEdge != 0 && prevEdge->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1419  MSLane* l = prevEdge->getLanes()[0];
1420  l = l->getLogicalPredecessorLane();
1421  prevEdge = l == 0 ? 0 : &l->getEdge();
1422  }
1423  // check whether the previous edge is on the route (was on the route)
1424  const ConstMSEdgeVector& ev = v.getRoute().getEdges();
1425  ConstMSEdgeVector::const_iterator prevEdgePos = std::find(ev.begin() + v.getRoutePosition(), ev.end(), prevEdge);
1426  nextEdge = e;
1427  while (nextEdge != 0 && nextEdge->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1428  nextEdge = nextEdge->getSuccessors()[0]; // should be only one for an internal edge
1429  }
1430  if (prevEdgePos != ev.end()) {
1431  onRoute = *(prevEdgePos + 1) == nextEdge;
1432  }
1433 #ifdef DEBUG_VTD_ANGLE
1434  std::cout << "internal:" << e->getID() << " prev:" << prevEdge->getID() << " next:" << nextEdge->getID() << std::endl;
1435 #endif
1436  }
1437 
1438 
1439  // weight the lanes...
1440  const std::vector<MSLane*>& lanes = e->getLanes();
1441  for (std::vector<MSLane*>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
1442  MSLane* lane = *k;
1443  SUMOReal off = lane->getShape().nearest_offset_to_point2D(pos);
1444  SUMOReal langle = 180.;
1445  SUMOReal dist = 1000.;
1446  if (off >= 0) {
1447  dist = lane->getShape().distance(pos);
1448  if (dist > lane->getLength()) { // this is a workaround
1449  // a SmartDB, running at :49_2 delivers off=~9.24 while dist>24.?
1450  dist = 1000.;
1451  } else {
1452  langle = lane->getShape().rotationDegreeAtOffset(off);
1453  }
1454  }
1455  bool sameEdge = &lane->getEdge() == &v.getLane()->getEdge() && v.getEdge()->getLanes()[0]->getLength() > v.getPositionOnLane() + SPEED2DIST(speed);
1456  /*
1457  const MSEdge* rNextEdge = nextEdge;
1458  while(rNextEdge==0&&lane->getEdge().getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL) {
1459  MSLane* next = lane->getLinkCont()[0]->getLane();
1460  rNextEdge = next == 0 ? 0 : &next->getEdge();
1461  }
1462  */
1463 #ifdef DEBUG_VTD_ANGLE
1464  std::cout << lane->getID() << ": " << langle << " " << off << std::endl;
1465 #endif
1466  lane2utility[lane] = LaneUtility(
1467  dist, GeomHelper::getMinAngleDiff(angle, langle),
1468  lane->getParameter("origId", "") == origID,
1469  onRoute, sameEdge, prevEdge, nextEdge);
1470  // update scaling value
1471  maxDist = MAX2(maxDist, dist);
1472 
1473  }
1474  }
1475 
1476  // get the best lane given the previously computed values
1477  SUMOReal bestValue = 0;
1478  MSLane* bestLane = 0;
1479  for (std::map<MSLane*, LaneUtility>::iterator i = lane2utility.begin(); i != lane2utility.end(); ++i) {
1480  MSLane* l = (*i).first;
1481  const LaneUtility& u = (*i).second;
1482  SUMOReal distN = u.dist > 999 ? -10 : 1. - (u.dist / maxDist);
1483  SUMOReal angleDiffN = 1. - (u.angleDiff / 180.);
1484  SUMOReal idN = u.ID ? 1 : 0;
1485  SUMOReal onRouteN = u.onRoute ? 1 : 0;
1486  SUMOReal sameEdgeN = u.sameEdge ? MIN2(v.getEdge()->getLength() / speed, (SUMOReal)1.) : 0;
1487  SUMOReal value = (distN * .35
1488  + angleDiffN * 0.35 /*.5 */
1489  + idN * .1
1490  + onRouteN * 0.1
1491  + sameEdgeN * 0.1);
1492 #ifdef DEBUG_VTD
1493  std::cout << " x; l:" << l->getID() << " d:" << u.dist << " dN:" << distN << " aD:" << angleDiffN <<
1494  " ID:" << idN << " oRN:" << onRouteN << " sEN:" << sameEdgeN << " value:" << value << std::endl;
1495 #endif
1496  if (value > bestValue || bestLane == 0) {
1497  bestValue = value;
1498  bestLane = l;
1499  }
1500  }
1501  // no best lane found, return
1502  if (bestLane == 0) {
1503  return false;
1504  }
1505  const LaneUtility& u = lane2utility.find(bestLane)->second;
1506  bestDistance = u.dist;
1507  *lane = bestLane;
1508  lanePos = bestLane->getShape().nearest_offset_to_point2D(pos);
1509  const MSEdge* prevEdge = u.prevEdge;
1510  if (u.onRoute) {
1511  const ConstMSEdgeVector& ev = v.getRoute().getEdges();
1512  ConstMSEdgeVector::const_iterator prevEdgePos = std::find(ev.begin() + v.getRoutePosition(), ev.end(), prevEdge);
1513  routeOffset = (int)std::distance(ev.begin(), prevEdgePos) - v.getRoutePosition();
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
1543  SUMOReal& bestDistance, MSLane** lane, SUMOReal& lanePos, int& routeOffset, ConstMSEdgeVector& /*edges*/) {
1544 
1545  int lastBestRouteEdge = 0; // index of the best edge found when going down the route's list of edges
1546  int lastRouteEdge = 0; // last non-internal edge on the route (seen so far)
1547  // get the lanes the vehicle may use
1548  const std::vector<MSLane*>& bestLaneConts = v.getBestLanesContinuation(v.getLane());
1549  for (std::vector<MSLane*>::const_iterator i = bestLaneConts.begin(); i != bestLaneConts.end() && bestDistance > POSITION_EPS; ++i) { // yes, we quit if the distance is < 0.1m or so
1550  if (*i == 0) { // why is that possible???
1551  continue;
1552  }
1553  MSEdge& e = (*i)->getEdge();
1554  if (i != bestLaneConts.begin() && e.getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1555  ++lastRouteEdge; // increment index, if not internal and not the current one
1556  }
1557  const std::vector<MSLane*>& lanes = e.getLanes(); // go over the edge's lanes
1558  for (std::vector<MSLane*>::const_iterator k = lanes.begin(); k != lanes.end() && bestDistance > POSITION_EPS; ++k) {
1559  MSLane* cl = *k;
1560  SUMOReal dist = cl->getShape().distance(pos); // get distance
1561 #ifdef DEBUG_VTD
1562  std::cout << " b at lane " << cl->getID() << " dist:" << dist << " best:" << bestDistance << std::endl;
1563 #endif
1564  if (dist < bestDistance) {
1565  // is the new distance the best one? keep then...
1566  bestDistance = dist;
1567  *lane = cl;
1568  lastBestRouteEdge = lastRouteEdge;
1569  }
1570  }
1571  }
1572  // quit if no solution was found, reporting a failure
1573  if (lane == 0) {
1574 #ifdef DEBUG_VTD
1575  std::cout << " b failed - no best route lane" << std::endl;
1576 #endif
1577  return false;
1578  }
1579  // position may be inaccurate; let's checkt the given index, too
1580  // a) is enabled for non-internal lanes only, as otherwise the position information may ambiguous
1581  // b) it's something one has to enable when building the nework - keepin the OSM IDs - is probably not always done
1582  if ((*lane)->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1583  const std::vector<MSLane*>& lanes = (*lane)->getEdge().getLanes();
1584  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
1585  if ((*i)->getParameter("origId", "") == origID) {
1586  *lane = *i;
1587  break;
1588  }
1589  }
1590  }
1591  // check position, stuff, we should have the best lane along the route
1592  lanePos = MAX2(SUMOReal(0), MIN2(SUMOReal((*lane)->getLength() - POSITION_EPS), (*lane)->getShape().nearest_offset_to_point2D(pos, false)));
1593  routeOffset = lastBestRouteEdge;
1594 #ifdef DEBUG_VTD
1595  std::cout << " b ok lane " << (*lane)->getID() << " lanePos:" << lanePos << " best:" << lastBestRouteEdge << std::endl;
1596 #endif
1597  return true;
1598 }
1599 
1600 
1601 bool
1603  tcpip::Storage& outputStorage, const MSVehicle* v) {
1604  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
1605  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of distance requires a compound object.", outputStorage);
1606  }
1607  if (inputStorage.readInt() != 2) {
1608  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of distance requires position and distance type as parameter.", outputStorage);
1609  }
1610 
1611  Position pos;
1612  std::pair<const MSLane*, SUMOReal> roadPos;
1613 
1614  // read position
1615  int posType = inputStorage.readUnsignedByte();
1616  switch (posType) {
1617  case POSITION_ROADMAP:
1618  try {
1619  std::string roadID = inputStorage.readString();
1620  roadPos.second = inputStorage.readDouble();
1621  roadPos.first = TraCIServerAPI_Simulation::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos.second);
1622  pos = roadPos.first->getShape().positionAtOffset(roadPos.second);
1623  } catch (TraCIException& e) {
1624  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, e.what(), outputStorage);
1625  }
1626  break;
1627  case POSITION_2D:
1628  case POSITION_3D: {
1629  const double p1x = inputStorage.readDouble();
1630  const double p1y = inputStorage.readDouble();
1631  pos.set(p1x, p1y);
1632  }
1633  if (posType == POSITION_3D) {
1634  inputStorage.readDouble(); // z value is ignored
1635  }
1637  break;
1638  default:
1639  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Unknown position format used for distance request", outputStorage);
1640  }
1641 
1642  // read distance type
1643  int distType = inputStorage.readUnsignedByte();
1644 
1645  SUMOReal distance = INVALID_DOUBLE_VALUE;
1646  if (v->isOnRoad()) {
1647  if (distType == REQUEST_DRIVINGDIST) {
1648  distance = v->getRoute().getDistanceBetween(v->getPositionOnLane(), roadPos.second,
1649  v->getEdge(), &roadPos.first->getEdge());
1650  if (distance == std::numeric_limits<SUMOReal>::max()) {
1651  distance = INVALID_DOUBLE_VALUE;
1652  }
1653  } else {
1654  // compute air distance (default)
1655  distance = v->getPosition().distanceTo(pos);
1656  }
1657  }
1658  // write response command
1659  outputStorage.writeUnsignedByte(TYPE_DOUBLE);
1660  outputStorage.writeDouble(distance);
1661  return true;
1662 }
1663 
1664 
1665 // ------ helper functions ------
1666 bool
1667 TraCIServerAPI_Vehicle::getPosition(const std::string& id, Position& p) {
1668  MSVehicle* v = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(id));
1669  if (v == 0) {
1670  return false;
1671  }
1672  p = v->getPosition();
1673  return true;
1674 }
1675 
1676 
1679  const MSVehicleType& oType = veh->getVehicleType();
1680  std::string newID = oType.getID().find('@') == std::string::npos ? oType.getID() + "@" + veh->getID() : oType.getID();
1681  MSVehicleType* type = MSVehicleType::build(newID, &oType);
1682  static_cast<MSVehicle*>(veh)->replaceVehicleType(type);
1683  return *type;
1684 }
1685 
1686 
1687 #include <microsim/MSEdgeControl.h>
1688 
1689 const std::map<std::string, std::vector<MSLane*> >&
1691  if (gVTDMap.size() == 0) {
1693  for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
1694  const std::vector<MSLane*>& lanes = (*i)->getLanes();
1695  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
1696  if ((*j)->knowsParameter("origId")) {
1697  std::string origID = (*j)->getParameter("origId", "");
1698  if (gVTDMap.find(origID) == gVTDMap.end()) {
1699  gVTDMap[origID] = std::vector<MSLane*>();
1700  }
1701  gVTDMap[origID].push_back(*j);
1702  }
1703  }
1704  }
1705  if (gVTDMap.size() == 0) {
1706  gVTDMap["unknown"] = std::vector<MSLane*>();
1707  }
1708  }
1709  return gVTDMap;
1710 }
1711 
1712 
1713 #endif
1714 
1715 
1716 /****************************************************************************/
1717 
#define VAR_ROAD_ID
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:633
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:2441
bool enterLaneAtMove(MSLane *enteredLane, bool onTeleporting=false)
Update when the vehicle enters a new lane in the move step.
Definition: MSVehicle.cpp:1768
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:461
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:2585
#define POSITION_2D
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc4: Change Vehicle State)
#define VAR_POSITION
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:186
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:470
#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:2600
void setRespectJunctionPriority(bool value)
Sets whether junction priority rules shall be respected.
Definition: MSVehicle.cpp:322
#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:376
Position getPosition(const SUMOReal offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:617
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:1086
#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:471
#define VAR_SPEED_FACTOR
#define VAR_COLOR
SUMOReal getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:2308
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:590
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:162
T MAX2(T a, T b)
Definition: StdDefs.h:79
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:85
unsigned int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:2380
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:579
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:564
#define VAR_BEST_LANES
SUMOReal getCO2Emissions() const
Returns CO2 emission of the current state.
Definition: MSVehicle.cpp:2296
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:79
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:2262
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:286
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:90
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:464
#define VAR_NOISEEMISSION
#define VAR_FUELCONSUMPTION
void addEffort(const MSEdge *const e, SUMOReal begin, SUMOReal end, SUMOReal value)
Adds an effort information for an edge and a time span.
static MSVehicleType * build(SUMOVTypeParameter &from)
Builds the microsim vehicle type described by the given parameter.
virtual void writeInt(int)
#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:584
#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:468
#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:81
MSLane * lane
The described lane.
Definition: MSVehicle.h:462
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:535
#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:1420
#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:328
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:572
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:255
#define REMOVE_TELEPORT_ARRIVED
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, unsigned int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:175
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the subpart of best lanes that describes the vehicle&#39;s current lane and their successors...
Definition: MSVehicle.cpp:2188
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:519
#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:61
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:827
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:124
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:580
#define CMD_SET_VEHICLE_VARIABLE
T MIN2(T a, T b)
Definition: StdDefs.h:73
#define VAR_IMPERFECTION
#define POSITION_EPS
Definition: config.h:188
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:460
#define VAR_EDGES
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:450
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:53
#define REMOVE
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:74
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:833
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:1916
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:472
SUMOReal getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
Definition: MSVehicle.cpp:2332
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:2314
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:853
bool replaceRouteEdges(ConstMSEdgeVector &edges, bool onInit=false)
Replaces the current route by the given edges.
void setVTDControlled(MSVehicle *v, MSLane *l, SUMOReal pos, int edgeOffset, ConstMSEdgeVector route, SUMOTime t)
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:2320
SUMOReal getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:2302
#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:884
#define VAR_COEMISSION
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, SUMOReal > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:168
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:235
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2591
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:2456
Structure representing possible vehicle parameter.
#define INVALID_INT_VALUE
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:81
#define VAR_MOVE_TO
#define SUMOTime_MAX
Definition: SUMOTime.h:44
#define TYPE_DOUBLE
bool containerTriggered
whether an arriving container lets the vehicle continue
Definition: MSVehicle.h:586
void setConsiderMaxDeceleration(bool value)
Sets whether the maximum deceleration shall be regarded.
Definition: MSVehicle.cpp:316
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:474
#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:2326
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:304
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:566
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:2498
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:294
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:334
SUMOReal getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:370
virtual void writeDouble(double)
#define REMOVE_VAPORIZED
unsigned size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:87
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:323
#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:647
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:835
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:83
#define SUMOReal
Definition: config.h:214
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:827
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:819
virtual void compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
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:315
#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:161
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
#define DELTA_T
Definition: SUMOTime.h:50
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:78
#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:354
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:339
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:331
The edge is an internal edge.
Definition: MSEdge.h:98
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:2465
SUMOReal startPos
The stopping position start.
Definition: MSVehicle.h:576
MSStoppingPlace * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSVehicle.h:570
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:540
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:525
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:642
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:310
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:75
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:588
The vehicle is being teleported.
#define VAR_WIDTH
SUMOReal getAngle() const
Returns the vehicle&#39;s direction in degrees.
Definition: MSVehicle.cpp:663
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:116
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.