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
int getRoutePosition() const
Definition: MSVehicle.cpp:678
double x
Definition: TraCIDefs.h:72
#define REMOVE_PARKING
static double gLateralResolution
Definition: MSGlobals.h:92
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1979
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
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
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:582
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.
bool hasValidRoute(std::string &msg, const MSRoute *route=0) const
Validates the current or given route.
#define VAR_VIA
#define VAR_CO2EMISSION
#define REQUEST_DRIVINGDIST
#define VAR_LENGTH
static int getPersonNumber(const std::string &vehicleID)
The time is given.
#define SPEED2DIST(x)
Definition: SUMOTime.h:55
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:128
#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 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) ...
double nextOccupation
The traffic density along length.
Definition: TraCI_Vehicle.h:76
bool hasDeparted() const
Returns whether this vehicle has already departed.
#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)
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:488
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
bool knowsEffort(const MSEdge *const e) const
Returns the information whether any effort is known for the given edge.
static std::string getLaneID(const std::string &vehicleID)
#define VAR_ROUTE
#define CMD_CHANGELANE
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:250
#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
double getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:375
#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
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
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
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
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
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...
#define VAR_SPEED_FACTOR
#define VAR_COLOR
bool knowsTravelTime(const MSEdge *const e) const
Returns the information whether any travel time is known for the given edge.
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.
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:192
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
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
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
double getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:484
#define TYPE_STRINGLIST
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:426
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
const MSRoute & getRoute() const
Returns the current route.
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
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:777
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
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)
const std::string & getID() const
Returns the id.
Definition: Named.h:66
virtual void writeUnsignedByte(int)
static std::pair< int, int > getLaneChangeState(const std::string &vehicleID, int direction)
#define VAR_NEXT_TLS
EdgeBasicFunction
Defines possible edge types.
Definition: MSEdge.h:89
double getLength() const
return the length of the edge
Definition: MSEdge.h:586
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()
#define VAR_SPEED_DEVIATION
#define VAR_NOISEEMISSION
#define VAR_FUELCONSUMPTION
double getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:500
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
A road/street connecting two junctions.
Definition: MSEdge.h:80
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:510
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
#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
#define SUMOTime_MAX
Definition: TraCIDefs.h:53
#define VAR_LANEPOSITION
A list of positions.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
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
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.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:257
#define CMD_SET_VEHICLE_VARIABLE
T MIN2(T a, T b)
Definition: StdDefs.h:64
#define VAR_IMPERFECTION
#define POSITION_EPS
Definition: config.h:175
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
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:249
#define VAR_STOPSTATE
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)
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) ...
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)
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal) const
Definition: MSEdge.cpp:650
#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()
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)
const std::string & getParameter(const std::string &key, const std::string &defaultValue) const
Returns the value for a given key.
#define VAR_EDGE_TRAVELTIME
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
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.
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
void collectObjectsInRange(int domain, const PositionVector &shape, double range, std::set< std::string > &into)
#define VAR_MOVE_TO
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
#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 MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
Definition: MSVehicle.cpp:809
const std::string & getID() const
Returns the name of the vehicle type.
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 MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:339
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.
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)
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:424
virtual void writeDouble(double)
const MSEdge * succEdge(int nSuccs) const
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
#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 MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle&#39;s internal edge travel times/efforts container.
Definition: MSVehicle.cpp:693
static double getLateralLanePosition(const std::string &vehicleID)
unsigned char b
Definition: TraCIDefs.h:79
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)
#define VAR_SPEED_WITHOUT_TRACI
#define NUMERICAL_EPS
Definition: config.h:151
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
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:925
The vehicle was teleported out of the net.
#define VAR_DECEL
#define VAR_ROUTE_VALID
bool willPass(const MSEdge *const edge) const
Returns whether the vehicle wil pass the given edge.
Definition: MSVehicle.cpp:672
#define VAR_PARAMETER
#define ID_COUNT
#define VAR_LANE_INDEX
static void resume(const std::string &vehicleID)
#define VAR_LANE_ID
#define VAR_LINE
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:442
static double getSpeed(const std::string &vehicleID)
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
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
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
#define TYPE_INTEGER
static bool findCloserLane(const MSEdge *edge, const Position &pos, double &bestDistance, MSLane **lane)
#define VAR_MINGAP
#define ID_LIST
const std::string & getID() const
Returns the name of the vehicle.
#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
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
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
#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
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)
void addEffort(const MSEdge *const e, double begin, double end, double value)
Adds an effort information for an edge and a time span.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp: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.