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