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