SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TraCIServerAPI_Vehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
13 // APIs for getting/setting vehicle values via TraCI
14 /****************************************************************************/
15 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
16 // Copyright (C) 2009-2014 DLR (http://www.dlr.de/) and contributors
17 /****************************************************************************/
18 //
19 // This file is part of SUMO.
20 // SUMO is free software: you can redistribute it and/or modify
21 // it under the terms of the GNU General Public License as published by
22 // the Free Software Foundation, either version 3 of the License, or
23 // (at your option) any later version.
24 //
25 /****************************************************************************/
26 
27 
28 // ===========================================================================
29 // included modules
30 // ===========================================================================
31 #ifdef _MSC_VER
32 #include <windows_config.h>
33 #else
34 #include <config.h>
35 #endif
36 
37 #ifndef NO_TRACI
38 
39 #include <microsim/MSNet.h>
41 #include <microsim/MSVehicle.h>
42 #include <microsim/MSLane.h>
43 #include <microsim/MSEdge.h>
52 #include "TraCIConstants.h"
54 #include "TraCIServerAPI_Vehicle.h"
56 
57 #ifdef CHECK_MEMORY_LEAKS
58 #include <foreign/nvwa/debug_new.h>
59 #endif // CHECK_MEMORY_LEAKS
60 
61 
62 // ===========================================================================
63 // static member variables
64 // ===========================================================================
65 std::map<std::string, std::vector<MSLane*> > TraCIServerAPI_Vehicle::gVTDMap;
66 
67 
68 // ===========================================================================
69 // method definitions
70 // ===========================================================================
71 bool
73  tcpip::Storage& outputStorage) {
74  // variable & id
75  int variable = inputStorage.readUnsignedByte();
76  std::string id = inputStorage.readString();
77  // check variable
78  if (variable != ID_LIST && variable != VAR_SPEED && variable != VAR_SPEED_WITHOUT_TRACI
79  && variable != VAR_POSITION && variable != VAR_ANGLE && variable != VAR_POSITION3D
80  && variable != VAR_ROAD_ID && variable != VAR_LANE_ID && variable != VAR_LANE_INDEX
81  && variable != VAR_TYPE && variable != VAR_ROUTE_ID && variable != VAR_COLOR
82  && variable != VAR_LANEPOSITION
83  && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION
84  && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION
85  && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION
86  && variable != VAR_PERSON_NUMBER && variable != VAR_LEADER
87  && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT
88  && variable != VAR_ROUTE_VALID && variable != VAR_EDGES
89  && variable != VAR_SIGNALS && variable != VAR_DISTANCE
90  && variable != VAR_LENGTH && variable != VAR_MAXSPEED && variable != VAR_VEHICLECLASS
91  && variable != VAR_SPEED_FACTOR && variable != VAR_SPEED_DEVIATION
92  && variable != VAR_ALLOWED_SPEED && variable != VAR_EMISSIONCLASS
93  && variable != VAR_WIDTH && variable != VAR_MINGAP && variable != VAR_SHAPECLASS
94  && variable != VAR_ACCEL && variable != VAR_DECEL && variable != VAR_IMPERFECTION
95  && variable != VAR_TAU && variable != VAR_BEST_LANES && variable != DISTANCE_REQUEST
96  && variable != ID_COUNT && variable != VAR_STOPSTATE && variable != VAR_WAITING_TIME
97  ) {
98  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Get Vehicle Variable: unsupported variable specified", outputStorage);
99  }
100  // begin response building
101  tcpip::Storage tempMsg;
102  // response-code, variableID, objectID
104  tempMsg.writeUnsignedByte(variable);
105  tempMsg.writeString(id);
106  // process request
107  if (variable == ID_LIST || variable == ID_COUNT) {
108  std::vector<std::string> ids;
110  for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
111  if ((*i).second->isOnRoad()) {
112  ids.push_back((*i).first);
113  }
114  }
115  if (variable == ID_LIST) {
117  tempMsg.writeStringList(ids);
118  } else {
120  tempMsg.writeInt((int) ids.size());
121  }
122  } else {
124  if (sumoVehicle == 0) {
125  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
126  }
127  MSVehicle* v = dynamic_cast<MSVehicle*>(sumoVehicle);
128  if (v == 0) {
129  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a micro-simulation vehicle", outputStorage);
130  }
131  const bool onRoad = v->isOnRoad();
132  switch (variable) {
133  case VAR_SPEED:
135  tempMsg.writeDouble(onRoad ? v->getSpeed() : INVALID_DOUBLE_VALUE);
136  break;
140  break;
141  case VAR_POSITION:
143  tempMsg.writeDouble(onRoad ? v->getPosition().x() : INVALID_DOUBLE_VALUE);
144  tempMsg.writeDouble(onRoad ? v->getPosition().y() : INVALID_DOUBLE_VALUE);
145  break;
146  case VAR_POSITION3D:
148  tempMsg.writeDouble(onRoad ? v->getPosition().x() : INVALID_DOUBLE_VALUE);
149  tempMsg.writeDouble(onRoad ? v->getPosition().y() : INVALID_DOUBLE_VALUE);
150  tempMsg.writeDouble(onRoad ? v->getPosition().z() : INVALID_DOUBLE_VALUE);
151  break;
152  case VAR_ANGLE:
154  tempMsg.writeDouble(onRoad ? v->getAngle() : INVALID_DOUBLE_VALUE);
155  break;
156  case VAR_ROAD_ID:
158  tempMsg.writeString(onRoad ? v->getLane()->getEdge().getID() : "");
159  break;
160  case VAR_LANE_ID:
162  tempMsg.writeString(onRoad ? v->getLane()->getID() : "");
163  break;
164  case VAR_LANE_INDEX:
166  if (onRoad) {
167  const std::vector<MSLane*>& lanes = v->getLane()->getEdge().getLanes();
168  tempMsg.writeInt((int)std::distance(lanes.begin(), std::find(lanes.begin(), lanes.end(), v->getLane())));
169  } else {
170  tempMsg.writeInt(INVALID_INT_VALUE);
171  }
172  break;
173  case VAR_TYPE:
175  tempMsg.writeString(v->getVehicleType().getID());
176  break;
177  case VAR_ROUTE_ID:
179  tempMsg.writeString(v->getRoute().getID());
180  break;
181  case VAR_COLOR:
182  tempMsg.writeUnsignedByte(TYPE_COLOR);
183  tempMsg.writeUnsignedByte(v->getParameter().color.red());
184  tempMsg.writeUnsignedByte(v->getParameter().color.green());
185  tempMsg.writeUnsignedByte(v->getParameter().color.blue());
186  tempMsg.writeUnsignedByte(v->getParameter().color.alpha());
187  break;
188  case VAR_LANEPOSITION:
190  tempMsg.writeDouble(onRoad ? v->getPositionOnLane() : INVALID_DOUBLE_VALUE);
191  break;
192  case VAR_CO2EMISSION:
194  tempMsg.writeDouble(onRoad ? v->getCO2Emissions() : INVALID_DOUBLE_VALUE);
195  break;
196  case VAR_COEMISSION:
198  tempMsg.writeDouble(onRoad ? v->getCOEmissions() : INVALID_DOUBLE_VALUE);
199  break;
200  case VAR_HCEMISSION:
202  tempMsg.writeDouble(onRoad ? v->getHCEmissions() : INVALID_DOUBLE_VALUE);
203  break;
204  case VAR_PMXEMISSION:
206  tempMsg.writeDouble(onRoad ? v->getPMxEmissions() : INVALID_DOUBLE_VALUE);
207  break;
208  case VAR_NOXEMISSION:
210  tempMsg.writeDouble(onRoad ? v->getNOxEmissions() : INVALID_DOUBLE_VALUE);
211  break;
212  case VAR_FUELCONSUMPTION:
214  tempMsg.writeDouble(onRoad ? v->getFuelConsumption() : INVALID_DOUBLE_VALUE);
215  break;
216  case VAR_NOISEEMISSION:
219  break;
220  case VAR_PERSON_NUMBER:
222  tempMsg.writeInt(v->getPersonNumber());
223  break;
224  case VAR_LEADER: {
225  double dist = 0;
226  if (!server.readTypeCheckingDouble(inputStorage, dist)) {
227  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Leader retrieval requires a double.", outputStorage);
228  }
229  std::pair<const MSVehicle* const, SUMOReal> leaderInfo = v->getLeader(dist);
231  tempMsg.writeInt(2);
233  tempMsg.writeString(leaderInfo.first != 0 ? leaderInfo.first->getID() : "");
235  tempMsg.writeDouble(leaderInfo.second);
236  }
237  break;
238  case VAR_WAITING_TIME:
240  tempMsg.writeDouble(v->getWaitingSeconds());
241  break;
242  case VAR_EDGE_TRAVELTIME: {
243  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
244  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires a compound object.", outputStorage);
245  }
246  if (inputStorage.readInt() != 2) {
247  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires time, and edge as parameter.", outputStorage);
248  }
249  // time
250  SUMOTime time = 0;
251  if (!server.readTypeCheckingInt(inputStorage, time)) {
252  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires the referenced time as first parameter.", outputStorage);
253  }
254  // edge
255  std::string edgeID;
256  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
257  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires the referenced edge as second parameter.", outputStorage);
258  }
259  MSEdge* edge = MSEdge::dictionary(edgeID);
260  if (edge == 0) {
261  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
262  }
263  // retrieve
265  SUMOReal value;
266  if (!v->getWeightsStorage().retrieveExistingTravelTime(edge, time, value)) {
268  } else {
269  tempMsg.writeDouble(value);
270  }
271 
272  }
273  break;
274  case VAR_EDGE_EFFORT: {
275  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
276  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires a compound object.", outputStorage);
277  }
278  if (inputStorage.readInt() != 2) {
279  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of travel time requires time, and edge as parameter.", outputStorage);
280  }
281  // time
282  SUMOTime time = 0;
283  if (!server.readTypeCheckingInt(inputStorage, time)) {
284  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of effort requires the referenced time as first parameter.", outputStorage);
285  }
286  // edge
287  std::string edgeID;
288  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
289  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of effort requires the referenced edge as second parameter.", outputStorage);
290  }
291  MSEdge* edge = MSEdge::dictionary(edgeID);
292  if (edge == 0) {
293  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
294  }
295  // retrieve
297  SUMOReal value;
298  if (!v->getWeightsStorage().retrieveExistingEffort(edge, time, value)) {
300  } else {
301  tempMsg.writeDouble(value);
302  }
303 
304  }
305  break;
306  case VAR_ROUTE_VALID: {
307  std::string msg;
308  tempMsg.writeUnsignedByte(TYPE_UBYTE);
309  tempMsg.writeUnsignedByte(v->hasValidRoute(msg));
310  }
311  break;
312  case VAR_EDGES: {
313  const MSRoute& r = v->getRoute();
315  tempMsg.writeInt(r.size());
316  for (MSRouteIterator i = r.begin(); i != r.end(); ++i) {
317  tempMsg.writeString((*i)->getID());
318  }
319  }
320  break;
321  case VAR_SIGNALS:
323  tempMsg.writeInt(v->getSignals());
324  break;
325  case VAR_BEST_LANES: {
327  tcpip::Storage tempContent;
328  unsigned int cnt = 0;
329  tempContent.writeUnsignedByte(TYPE_INTEGER);
330  const std::vector<MSVehicle::LaneQ>& bestLanes = onRoad ? v->getBestLanes() : std::vector<MSVehicle::LaneQ>();
331  tempContent.writeInt((int) bestLanes.size());
332  ++cnt;
333  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bestLanes.begin(); i != bestLanes.end(); ++i) {
334  const MSVehicle::LaneQ& lq = *i;
335  tempContent.writeUnsignedByte(TYPE_STRING);
336  tempContent.writeString(lq.lane->getID());
337  ++cnt;
338  tempContent.writeUnsignedByte(TYPE_DOUBLE);
339  tempContent.writeDouble(lq.length);
340  ++cnt;
341  tempContent.writeUnsignedByte(TYPE_DOUBLE);
342  tempContent.writeDouble(lq.nextOccupation);
343  ++cnt;
344  tempContent.writeUnsignedByte(TYPE_BYTE);
345  tempContent.writeByte(lq.bestLaneOffset);
346  ++cnt;
347  tempContent.writeUnsignedByte(TYPE_UBYTE);
348  lq.allowsContinuation ? tempContent.writeUnsignedByte(1) : tempContent.writeUnsignedByte(0);
349  ++cnt;
350  std::vector<std::string> bestContIDs;
351  for (std::vector<MSLane*>::const_iterator j = lq.bestContinuations.begin(); j != lq.bestContinuations.end(); ++j) {
352  if ((*j) != 0) {
353  bestContIDs.push_back((*j)->getID());
354  }
355  }
356  tempContent.writeUnsignedByte(TYPE_STRINGLIST);
357  tempContent.writeStringList(bestContIDs);
358  ++cnt;
359  }
360  tempMsg.writeInt((int) cnt);
361  tempMsg.writeStorage(tempContent);
362  }
363  break;
364  case VAR_STOPSTATE: {
365  char b = (
366  1 * (v->isStopped() ? 1 : 0) +
367  2 * (v->isParking() ? 1 : 0) +
368  4 * (v->isStoppedTriggered() ? 1 : 0));
369  tempMsg.writeUnsignedByte(TYPE_UBYTE);
370  tempMsg.writeUnsignedByte(b);
371  }
372  break;
373  case VAR_DISTANCE: {
375  SUMOReal distance = onRoad ? v->getRoute().getDistanceBetween(0, v->getPositionOnLane(), v->getRoute().getEdges()[0], &v->getLane()->getEdge()) : INVALID_DOUBLE_VALUE;
376  if (distance == std::numeric_limits<SUMOReal>::max()) {
377  distance = INVALID_DOUBLE_VALUE;
378  }
379  tempMsg.writeDouble(distance);
380  }
381  break;
382  case DISTANCE_REQUEST:
383  if (!commandDistanceRequest(server, inputStorage, tempMsg, v)) {
384  return false;
385  }
386  break;
387  case VAR_ALLOWED_SPEED:
389  tempMsg.writeDouble(onRoad ? v->getLane()->getVehicleMaxSpeed(v) : INVALID_DOUBLE_VALUE);
390  break;
391  case VAR_SPEED_FACTOR:
393  tempMsg.writeDouble(v->getChosenSpeedFactor());
394  break;
395  default:
397  break;
398  }
399  }
400  server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_OK, "", outputStorage);
401  server.writeResponseWithLength(outputStorage, tempMsg);
402  return true;
403 }
404 
405 
406 bool
408  tcpip::Storage& outputStorage) {
409  std::string warning = ""; // additional description for response
410  // variable
411  int variable = inputStorage.readUnsignedByte();
412  if (variable != CMD_STOP && variable != CMD_CHANGELANE
413  && variable != CMD_SLOWDOWN && variable != CMD_CHANGETARGET && variable != CMD_RESUME
414  && variable != VAR_TYPE && variable != VAR_ROUTE_ID && variable != VAR_ROUTE
415  && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT
416  && variable != CMD_REROUTE_TRAVELTIME && variable != CMD_REROUTE_EFFORT
417  && variable != VAR_SIGNALS && variable != VAR_MOVE_TO
418  && variable != VAR_LENGTH && variable != VAR_MAXSPEED && variable != VAR_VEHICLECLASS
419  && variable != VAR_SPEED_FACTOR && variable != VAR_EMISSIONCLASS
420  && variable != VAR_WIDTH && variable != VAR_MINGAP && variable != VAR_SHAPECLASS
421  && variable != VAR_ACCEL && variable != VAR_DECEL && variable != VAR_IMPERFECTION
422  && variable != VAR_TAU && variable != VAR_LANECHANGE_MODE
423  && variable != VAR_SPEED && variable != VAR_SPEEDSETMODE && variable != VAR_COLOR
424  && variable != ADD && variable != ADD_FULL && variable != REMOVE
425  && variable != VAR_MOVE_TO_VTD
426  ) {
427  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Change Vehicle State: unsupported variable specified", outputStorage);
428  }
429  // id
430  std::string id = inputStorage.readString();
431  const bool shouldExist = variable != ADD && variable != ADD_FULL;
433  if (sumoVehicle == 0) {
434  if (shouldExist) {
435  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not known", outputStorage);
436  }
437  }
438  MSVehicle* v = dynamic_cast<MSVehicle*>(sumoVehicle);
439  if (v == 0 && shouldExist) {
440  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Vehicle '" + id + "' is not a micro-simulation vehicle", outputStorage);
441  }
442  switch (variable) {
443  case CMD_STOP: {
444  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
445  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description.", outputStorage);
446  }
447  int compoundSize = inputStorage.readInt();
448  if (compoundSize != 4 && compoundSize != 5) {
449  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Stop needs a compound object description of four of five items.", outputStorage);
450  }
451  // read road map position
452  std::string roadId;
453  if (!server.readTypeCheckingString(inputStorage, roadId)) {
454  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first stop parameter must be the edge id given as a string.", outputStorage);
455  }
456  double pos = 0;
457  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
458  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second stop parameter must be the position along the edge given as a double.", outputStorage);
459  }
460  int laneIndex = 0;
461  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
462  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The third stop parameter must be the lane index given as a byte.", outputStorage);
463  }
464  // waitTime
465  SUMOTime waitTime = 0;
466  if (!server.readTypeCheckingInt(inputStorage, waitTime)) {
467  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "The fourth stop parameter must be the waiting time given as an integer.", outputStorage);
468  }
469  // optional stop flags
470  bool parking = false;
471  bool triggered = false;
472  if (compoundSize == 5) {
473  int stopFlags;
474  if (!server.readTypeCheckingByte(inputStorage, stopFlags)) {
475  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The fifth stop parameter must be a byte indicating its parking/triggered status.", outputStorage);
476  }
477  parking = ((stopFlags & 1) != 0);
478  triggered = ((stopFlags & 2) != 0);
479  }
480  // check
481  if (pos < 0) {
482  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Position on lane must not be negative.", outputStorage);
483  }
484  // get the actual lane that is referenced by laneIndex
485  MSEdge* road = MSEdge::dictionary(roadId);
486  if (road == 0) {
487  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Unable to retrieve road with given id.", outputStorage);
488  }
489  const std::vector<MSLane*>& allLanes = road->getLanes();
490  if ((laneIndex < 0) || laneIndex >= (int)(allLanes.size())) {
491  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + roadId + "'.", outputStorage);
492  }
493  // Forward command to vehicle
494  std::string error;
495  if (!v->addTraciStop(allLanes[laneIndex], pos, 0, waitTime, parking, triggered, error)) {
496  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
497  }
498  }
499  break;
500  case CMD_RESUME: {
501  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
502  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Resuming requires a compound object.", outputStorage);
503  return false;
504  }
505  if (inputStorage.readInt() != 0) {
506  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Resuming should obtain an empty compound object.", outputStorage);
507  return false;
508  }
509  if (!static_cast<MSVehicle*>(v)->hasStops()) {
510  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Failed to resume vehicle '" + v->getID() + "', it has no stops.", outputStorage);
511  return false;
512  }
513  if (!static_cast<MSVehicle*>(v)->resumeFromStopping()) {
514  MSVehicle::Stop& sto = (static_cast<MSVehicle*>(v))->getNextStop();
515  std::ostringstream strs;
516  strs << "reached: " << sto.reached;
517  strs << ", duration:" << sto.duration;
518  strs << ", edge:" << (*sto.edge)->getID();
519  strs << ", startPos: " << sto.startPos;
520  std::string posStr = strs.str();
521  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Failed to resume a non parking vehicle '" + v->getID() + "', " + posStr, outputStorage);
522  return false;
523  }
524  }
525  break;
526  case CMD_CHANGELANE: {
527  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
528  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description.", outputStorage);
529  }
530  if (inputStorage.readInt() != 2) {
531  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Lane change needs a compound object description of two items.", outputStorage);
532  }
533  // Lane ID
534  int laneIndex = 0;
535  if (!server.readTypeCheckingByte(inputStorage, laneIndex)) {
536  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first lane change parameter must be the lane index given as a byte.", outputStorage);
537  }
538  // stickyTime
539  SUMOTime stickyTime = 0;
540  if (!server.readTypeCheckingInt(inputStorage, stickyTime)) {
541  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second lane change parameter must be the duration given as an integer.", outputStorage);
542  }
543  if ((laneIndex < 0) || (laneIndex >= (int)(v->getEdge()->getLanes().size()))) {
544  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "No lane with index '" + toString(laneIndex) + "' on road '" + v->getEdge()->getID() + "'.", outputStorage);
545  }
546  // Forward command to vehicle
547  std::vector<std::pair<SUMOTime, unsigned int> > laneTimeLine;
548  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), laneIndex));
549  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + stickyTime, laneIndex));
550  v->getInfluencer().setLaneTimeLine(laneTimeLine);
551  }
552  break;
553  case CMD_SLOWDOWN: {
554  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
555  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description.", outputStorage);
556  }
557  if (inputStorage.readInt() != 2) {
558  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Slow down needs a compound object description of two items.", outputStorage);
559  }
560  double newSpeed = 0;
561  if (!server.readTypeCheckingDouble(inputStorage, newSpeed)) {
562  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first slow down parameter must be the speed given as a double.", outputStorage);
563  }
564  if (newSpeed < 0) {
565  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Speed must not be negative", outputStorage);
566  }
567  SUMOTime duration = 0;
568  if (!server.readTypeCheckingInt(inputStorage, duration)) {
569  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second slow down parameter must be the duration given as an integer.", outputStorage);
570  }
571  if (duration < 0 || STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) + STEPS2TIME(duration) > STEPS2TIME(SUMOTime_MAX - DELTA_T)) {
572  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid time interval", outputStorage);
573  }
574  std::vector<std::pair<SUMOTime, SUMOReal> > speedTimeLine;
575  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), v->getSpeed()));
576  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + duration, newSpeed));
577  v->getInfluencer().setSpeedTimeLine(speedTimeLine);
578  }
579  break;
580  case CMD_CHANGETARGET: {
581  std::string edgeID;
582  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
583  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Change target requires a string containing the id of the new destination edge as parameter.", outputStorage);
584  }
585  const MSEdge* destEdge = MSEdge::dictionary(edgeID);
586  if (destEdge == 0) {
587  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Can not retrieve road with ID " + edgeID, outputStorage);
588  }
589  // build a new route between the vehicle's current edge and destination edge
590  MSEdgeVector newRoute;
591  const MSEdge* currentEdge = v->getRerouteOrigin();
593  currentEdge, destEdge, (const MSVehicle * const) v, MSNet::getInstance()->getCurrentTimeStep(), newRoute);
594  // replace the vehicle's route by the new one
595  if (!v->replaceRouteEdges(newRoute, v->getLane() == 0)) {
596  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Route replacement failed for " + v->getID(), outputStorage);
597  }
598  }
599  break;
600  case VAR_TYPE: {
601  std::string vTypeID;
602  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
603  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The vehicle type id must be given as a string.", outputStorage);
604  }
605  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(vTypeID);
606  if (vehicleType == 0) {
607  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The vehicle type '" + vTypeID + "' is not known.", outputStorage);
608  }
609  v->replaceVehicleType(vehicleType);
610  }
611  break;
612  case VAR_ROUTE_ID: {
613  std::string rid;
614  if (!server.readTypeCheckingString(inputStorage, rid)) {
615  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The route id must be given as a string.", outputStorage);
616  }
617  const MSRoute* r = MSRoute::dictionary(rid);
618  if (r == 0) {
619  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The route '" + rid + "' is not known.", outputStorage);
620  }
621  if (!v->replaceRoute(r, v->getLane() == 0)) {
622  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Route replacement failed for " + v->getID(), outputStorage);
623  }
624  }
625  break;
626  case VAR_ROUTE: {
627  std::vector<std::string> edgeIDs;
628  if (!server.readTypeCheckingStringList(inputStorage, edgeIDs)) {
629  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "A route must be defined as a list of edge ids.", outputStorage);
630  }
631  std::vector<const MSEdge*> edges;
632  MSEdge::parseEdgesList(edgeIDs, edges, "<unknown>");
633  if (!v->replaceRouteEdges(edges, v->getLane() == 0)) {
634  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Route replacement failed for " + v->getID(), outputStorage);
635  }
636  }
637  break;
638  case VAR_EDGE_TRAVELTIME: {
639  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
640  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires a compound object.", outputStorage);
641  }
642  int parameterCount = inputStorage.readInt();
643  if (parameterCount == 4) {
644  // begin time
645  SUMOTime begTime = 0, endTime = 0;
646  if (!server.readTypeCheckingInt(inputStorage, begTime)) {
647  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the begin time as first parameter.", outputStorage);
648  }
649  // begin time
650  if (!server.readTypeCheckingInt(inputStorage, endTime)) {
651  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the end time as second parameter.", outputStorage);
652  }
653  // edge
654  std::string edgeID;
655  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
656  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the referenced edge as third parameter.", outputStorage);
657  }
658  MSEdge* edge = MSEdge::dictionary(edgeID);
659  if (edge == 0) {
660  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
661  }
662  // value
663  double value = 0;
664  if (!server.readTypeCheckingDouble(inputStorage, value)) {
665  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 4 parameters requires the travel time as double as fourth parameter.", outputStorage);
666  }
667  // retrieve
668  v->getWeightsStorage().addTravelTime(edge, begTime, endTime, value);
669  } else if (parameterCount == 2) {
670  // edge
671  std::string edgeID;
672  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
673  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the referenced edge as first parameter.", outputStorage);
674  }
675  MSEdge* edge = MSEdge::dictionary(edgeID);
676  if (edge == 0) {
677  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
678  }
679  // value
680  double value = 0;
681  if (!server.readTypeCheckingDouble(inputStorage, value)) {
682  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 2 parameters requires the travel time as second parameter.", outputStorage);
683  }
684  // retrieve
685  while (v->getWeightsStorage().knowsTravelTime(edge)) {
687  }
688  v->getWeightsStorage().addTravelTime(edge, 0, SUMOTime_MAX, value);
689  } else if (parameterCount == 1) {
690  // edge
691  std::string edgeID;
692  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
693  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time using 1 parameter requires the referenced edge as first parameter.", outputStorage);
694  }
695  MSEdge* edge = MSEdge::dictionary(edgeID);
696  if (edge == 0) {
697  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
698  }
699  // retrieve
700  while (v->getWeightsStorage().knowsTravelTime(edge)) {
702  }
703  } else {
704  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage);
705  }
706  }
707  break;
708  case VAR_EDGE_EFFORT: {
709  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
710  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort requires a compound object.", outputStorage);
711  }
712  int parameterCount = inputStorage.readInt();
713  if (parameterCount == 4) {
714  // begin time
715  SUMOTime begTime = 0, endTime = 0;
716  if (!server.readTypeCheckingInt(inputStorage, begTime)) {
717  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the begin time as first parameter.", outputStorage);
718  }
719  // begin time
720  if (!server.readTypeCheckingInt(inputStorage, endTime)) {
721  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the end time as second parameter.", outputStorage);
722  }
723  // edge
724  std::string edgeID;
725  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
726  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the referenced edge as third parameter.", outputStorage);
727  }
728  MSEdge* edge = MSEdge::dictionary(edgeID);
729  if (edge == 0) {
730  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
731  }
732  // value
733  double value = 0;
734  if (!server.readTypeCheckingDouble(inputStorage, value)) {
735  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 4 parameters requires the travel time as fourth parameter.", outputStorage);
736  }
737  // retrieve
738  v->getWeightsStorage().addEffort(edge, begTime, endTime, value);
739  } else if (parameterCount == 2) {
740  // edge
741  std::string edgeID;
742  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
743  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the referenced edge as first parameter.", outputStorage);
744  }
745  MSEdge* edge = MSEdge::dictionary(edgeID);
746  if (edge == 0) {
747  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
748  }
749  // value
750  double value = 0;
751  if (!server.readTypeCheckingDouble(inputStorage, value)) {
752  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 2 parameters requires the travel time as second parameter.", outputStorage);
753  }
754  // retrieve
755  while (v->getWeightsStorage().knowsEffort(edge)) {
756  v->getWeightsStorage().removeEffort(edge);
757  }
758  v->getWeightsStorage().addEffort(edge, 0, SUMOTime_MAX, value);
759  } else if (parameterCount == 1) {
760  // edge
761  std::string edgeID;
762  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
763  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort using 1 parameter requires the referenced edge as first parameter.", outputStorage);
764  }
765  MSEdge* edge = MSEdge::dictionary(edgeID);
766  if (edge == 0) {
767  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Referenced edge '" + edgeID + "' is not known.", outputStorage);
768  }
769  // retrieve
770  while (v->getWeightsStorage().knowsEffort(edge)) {
771  v->getWeightsStorage().removeEffort(edge);
772  }
773  } else {
774  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort requires 1, 2, or 4 parameters.", outputStorage);
775  }
776  }
777  break;
778  case CMD_REROUTE_TRAVELTIME: {
779  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
780  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
781  }
782  if (inputStorage.readInt() != 0) {
783  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
784  }
785  v->reroute(MSNet::getInstance()->getCurrentTimeStep(), MSNet::getInstance()->getRouterTT());
786  }
787  break;
788  case CMD_REROUTE_EFFORT: {
789  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
790  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting requires a compound object.", outputStorage);
791  }
792  if (inputStorage.readInt() != 0) {
793  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Rerouting should obtain an empty compound object.", outputStorage);
794  }
795  v->reroute(MSNet::getInstance()->getCurrentTimeStep(), MSNet::getInstance()->getRouterEffort());
796  }
797  break;
798  case VAR_SIGNALS: {
799  int signals = 0;
800  if (!server.readTypeCheckingInt(inputStorage, signals)) {
801  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting signals requires an integer.", outputStorage);
802  }
803  v->switchOffSignal(0x0fffffff);
804  v->switchOnSignal(signals);
805  }
806  break;
807  case VAR_MOVE_TO: {
808  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
809  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting position requires a compound object.", outputStorage);
810  }
811  if (inputStorage.readInt() != 2) {
812  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting position should obtain the lane id and the position.", outputStorage);
813  }
814  // lane ID
815  std::string laneID;
816  if (!server.readTypeCheckingString(inputStorage, laneID)) {
817  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first parameter for setting a position must be the lane ID given as a string.", outputStorage);
818  }
819  // position on lane
820  double position = 0;
821  if (!server.readTypeCheckingDouble(inputStorage, position)) {
822  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second parameter for setting a position must be the position given as a double.", outputStorage);
823  }
824  // process
825  MSLane* l = MSLane::dictionary(laneID);
826  if (l == 0) {
827  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Unknown lane '" + laneID + "'.", outputStorage);
828  }
829  MSEdge& destinationEdge = l->getEdge();
830  if (!v->willPass(&destinationEdge)) {
831  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Vehicle '" + laneID + "' may be set onto an edge to pass only.", outputStorage);
832  }
835  while (v->getEdge() != &destinationEdge) {
836  const MSEdge* nextEdge = v->succEdge(1);
837  // let the vehicle move to the next edge
838  if (v->enterLaneAtMove(nextEdge->getLanes()[0], true)) {
840  continue;
841  }
842  }
843  l->forceVehicleInsertion(v, position);
844  }
845  break;
846  case VAR_SPEED: {
847  double speed = 0;
848  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
849  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting speed requires a double.", outputStorage);
850  }
851  std::vector<std::pair<SUMOTime, SUMOReal> > speedTimeLine;
852  if (speed >= 0) {
853  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), speed));
854  speedTimeLine.push_back(std::make_pair(SUMOTime_MAX - DELTA_T, speed));
855  }
856  v->getInfluencer().setSpeedTimeLine(speedTimeLine);
857  }
858  break;
859  case VAR_SPEEDSETMODE: {
860  int speedMode = 0;
861  if (!server.readTypeCheckingInt(inputStorage, speedMode)) {
862  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting speed mode requires an integer.", outputStorage);
863  }
864  v->getInfluencer().setConsiderSafeVelocity((speedMode & 1) != 0);
865  v->getInfluencer().setConsiderMaxAcceleration((speedMode & 2) != 0);
866  v->getInfluencer().setConsiderMaxDeceleration((speedMode & 4) != 0);
867  v->getInfluencer().setRespectJunctionPriority((speedMode & 8) != 0);
868  v->getInfluencer().setEmergencyBrakeRedLight((speedMode & 16) != 0);
869  }
870  break;
871  case VAR_LANECHANGE_MODE: {
872  int laneChangeMode = 0;
873  if (!server.readTypeCheckingInt(inputStorage, laneChangeMode)) {
874  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting lane change mode requires an integer.", outputStorage);
875  }
876  v->getInfluencer().setLaneChangeMode(laneChangeMode);
877  }
878  break;
879  case VAR_COLOR: {
880  RGBColor col;
881  if (!server.readTypeCheckingColor(inputStorage, col)) {
882  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The color must be given using the according type.", outputStorage);
883  }
884  v->getParameter().color.set(col.red(), col.green(), col.blue(), col.alpha());
886  }
887  break;
888  case ADD: {
889  if (v != 0) {
890  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The vehicle " + id + " to add already exists.", outputStorage);
891  }
892  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
893  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle requires a compound object.", outputStorage);
894  }
895  if (inputStorage.readInt() != 6) {
896  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle needs six parameters.", outputStorage);
897  }
898  SUMOVehicleParameter vehicleParams;
899  vehicleParams.id = id;
900 
901  std::string vTypeID;
902  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
903  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "First parameter (type) requires a string.", outputStorage);
904  }
905  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(vTypeID);
906  if (!vehicleType) {
907  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid type '" + vTypeID + "' for vehicle '" + id + "'", outputStorage);
908  }
909 
910  std::string routeID;
911  if (!server.readTypeCheckingString(inputStorage, routeID)) {
912  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Second parameter (route) requires a string.", outputStorage);
913  }
914  const MSRoute* route = MSRoute::dictionary(routeID);
915  if (!route) {
916  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid route '" + routeID + "' for vehicle: '" + id + "'", outputStorage);
917  }
918 
919  if (!server.readTypeCheckingInt(inputStorage, vehicleParams.depart)) {
920  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Third parameter (depart) requires an integer.", outputStorage);
921  }
922  if (vehicleParams.depart < 0) {
923  const int proc = static_cast<int>(-vehicleParams.depart);
924  if (proc >= static_cast<int>(DEPART_DEF_MAX)) {
925  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure time.", outputStorage);
926  }
927  vehicleParams.departProcedure = (DepartDefinition)proc;
928  } else if (vehicleParams.depart < MSNet::getInstance()->getCurrentTimeStep()) {
929  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Departure time in the past.", outputStorage);
930  }
931 
932  double pos;
933  if (!server.readTypeCheckingDouble(inputStorage, pos)) {
934  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Fourth parameter (position) requires a double.", outputStorage);
935  }
936  vehicleParams.departPos = pos;
937  if (vehicleParams.departPos < 0) {
938  const int proc = static_cast<int>(-vehicleParams.departPos);
939  if (fabs(proc + vehicleParams.departPos) > NUMERICAL_EPS || proc >= static_cast<int>(DEPART_POS_DEF_MAX) || proc == static_cast<int>(DEPART_POS_GIVEN)) {
940  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure position.", outputStorage);
941  }
942  vehicleParams.departPosProcedure = (DepartPosDefinition)proc;
943  } else {
944  vehicleParams.departPosProcedure = DEPART_POS_GIVEN;
945  }
946 
947  double speed;
948  if (!server.readTypeCheckingDouble(inputStorage, speed)) {
949  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Fifth parameter (speed) requires a double.", outputStorage);
950  }
951  vehicleParams.departSpeed = speed;
952  if (vehicleParams.departSpeed < 0) {
953  const int proc = static_cast<int>(-vehicleParams.departSpeed);
954  if (proc >= static_cast<int>(DEPART_SPEED_DEF_MAX)) {
955  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure speed.", outputStorage);
956  }
957  vehicleParams.departSpeedProcedure = (DepartSpeedDefinition)proc;
958  } else {
960  }
961 
962  if (!server.readTypeCheckingByte(inputStorage, vehicleParams.departLane)) {
963  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Sixth parameter (lane) requires a byte.", outputStorage);
964  }
965 
966  if (vehicleParams.departLane < 0) {
967  const int proc = static_cast<int>(-vehicleParams.departLane);
968  if (proc >= static_cast<int>(DEPART_LANE_DEF_MAX)) {
969  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid departure lane.", outputStorage);
970  }
971  vehicleParams.departLaneProcedure = (DepartLaneDefinition)proc;
972  } else {
973  vehicleParams.departLaneProcedure = DEPART_LANE_GIVEN;
974  }
975 
976  SUMOVehicleParameter* params = new SUMOVehicleParameter(vehicleParams);
977  try {
978  SUMOVehicle* vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(params, route, vehicleType, true, false);
979  MSNet::getInstance()->getVehicleControl().addVehicle(vehicleParams.id, vehicle);
981  } catch (ProcessError& e) {
982  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
983  }
984  }
985  break;
986  case ADD_FULL: {
987  if (v != 0) {
988  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The vehicle " + id + " to add already exists.", outputStorage);
989  }
990  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
991  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Adding a vehicle requires a compound object.", outputStorage);
992  }
993  if (inputStorage.readInt() != 14) {
994  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Adding a fully specified vehicle needs fourteen parameters.", outputStorage);
995  }
996  SUMOVehicleParameter vehicleParams;
997  vehicleParams.id = id;
998 
999  std::string routeID;
1000  if (!server.readTypeCheckingString(inputStorage, routeID)) {
1001  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Second parameter (route) requires a string.", outputStorage);
1002  }
1003  const MSRoute* route = MSRoute::dictionary(routeID);
1004  if (!route) {
1005  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid route '" + routeID + "' for vehicle: '" + id + "'", outputStorage);
1006  }
1007 
1008  std::string vTypeID;
1009  if (!server.readTypeCheckingString(inputStorage, vTypeID)) {
1010  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "First parameter (type) requires a string.", outputStorage);
1011  }
1012  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(vTypeID);
1013  if (!vehicleType) {
1014  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Invalid type '" + vTypeID + "' for vehicle '" + id + "'", outputStorage);
1015  }
1016 
1017  std::string helper;
1018  std::string error;
1019  if (!server.readTypeCheckingString(inputStorage, helper)) {
1020  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Third parameter (depart) requires an string.", outputStorage);
1021  }
1022  if (!SUMOVehicleParameter::parseDepart(helper, "vehicle", id, vehicleParams.depart, vehicleParams.departProcedure, error)) {
1023  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1024  }
1025  if (vehicleParams.departProcedure == DEPART_GIVEN && vehicleParams.depart < MSNet::getInstance()->getCurrentTimeStep()) {
1026  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Departure time in the past.", outputStorage);
1027  }
1028 
1029  if (!server.readTypeCheckingString(inputStorage, helper)) {
1030  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Fourth parameter (depart lane) requires a string.", outputStorage);
1031  }
1032  if (!SUMOVehicleParameter::parseDepartLane(helper, "vehicle", id, vehicleParams.departLane, vehicleParams.departLaneProcedure, error)) {
1033  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1034  }
1035  if (!server.readTypeCheckingString(inputStorage, helper)) {
1036  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Fifth parameter (depart position) requires a string.", outputStorage);
1037  }
1038  if (!SUMOVehicleParameter::parseDepartPos(helper, "vehicle", id, vehicleParams.departPos, vehicleParams.departPosProcedure, error)) {
1039  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1040  }
1041  if (!server.readTypeCheckingString(inputStorage, helper)) {
1042  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Sixth parameter (depart speed) requires a string.", outputStorage);
1043  }
1044  if (!SUMOVehicleParameter::parseDepartSpeed(helper, "vehicle", id, vehicleParams.departSpeed, vehicleParams.departSpeedProcedure, error)) {
1045  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1046  }
1047 
1048  if (!server.readTypeCheckingString(inputStorage, helper)) {
1049  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Seventh parameter (arrival lane) requires a string.", outputStorage);
1050  }
1051  if (!SUMOVehicleParameter::parseArrivalLane(helper, "vehicle", id, vehicleParams.arrivalLane, vehicleParams.arrivalLaneProcedure, error)) {
1052  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1053  }
1054  if (!server.readTypeCheckingString(inputStorage, helper)) {
1055  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Eighth parameter (arrival position) requires a string.", outputStorage);
1056  }
1057  if (!SUMOVehicleParameter::parseArrivalPos(helper, "vehicle", id, vehicleParams.arrivalPos, vehicleParams.arrivalPosProcedure, error)) {
1058  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1059  }
1060  if (!server.readTypeCheckingString(inputStorage, helper)) {
1061  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Ninth parameter (arrival speed) requires a string.", outputStorage);
1062  }
1063  if (!SUMOVehicleParameter::parseArrivalSpeed(helper, "vehicle", id, vehicleParams.arrivalSpeed, vehicleParams.arrivalSpeedProcedure, error)) {
1064  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage);
1065  }
1066 
1067  if (!server.readTypeCheckingString(inputStorage, vehicleParams.fromTaz)) {
1068  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Tenth parameter (from taz) requires a string.", outputStorage);
1069  }
1070  if (!server.readTypeCheckingString(inputStorage, vehicleParams.toTaz)) {
1071  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Eleventh parameter (to taz) requires a string.", outputStorage);
1072  }
1073  if (!server.readTypeCheckingString(inputStorage, vehicleParams.line)) {
1074  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Twelth parameter (line) requires a string.", outputStorage);
1075  }
1076 
1077  int num;
1078  if (!server.readTypeCheckingInt(inputStorage, num)) {
1079  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "13th parameter (person capacity) requires an int.", outputStorage);
1080  }
1081  vehicleParams.personCapacity = num;
1082  if (!server.readTypeCheckingInt(inputStorage, num)) {
1083  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "14th parameter (person number) requires an int.", outputStorage);
1084  }
1085  vehicleParams.personNumber = num;
1086 
1087  SUMOVehicleParameter* params = new SUMOVehicleParameter(vehicleParams);
1088  try {
1089  SUMOVehicle* vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(params, route, vehicleType, true, false);
1090  MSNet::getInstance()->getVehicleControl().addVehicle(vehicleParams.id, vehicle);
1092  } catch (ProcessError& e) {
1093  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1094  }
1095  }
1096  break;
1097  case REMOVE: {
1098  int why = 0;
1099  if (!server.readTypeCheckingByte(inputStorage, why)) {
1100  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Removing a vehicle requires a byte.", outputStorage);
1101  }
1103  switch (why) {
1104  case REMOVE_TELEPORT:
1105  // XXX semantics unclear
1106  // n = MSMoveReminder::NOTIFICATION_TELEPORT;
1108  break;
1109  case REMOVE_PARKING:
1110  // XXX semantics unclear
1111  // n = MSMoveReminder::NOTIFICATION_PARKING;
1113  break;
1114  case REMOVE_ARRIVED:
1116  break;
1117  case REMOVE_VAPORIZED:
1119  break;
1122  break;
1123  default:
1124  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Unknown removal status.", outputStorage);
1125  }
1126  if (v->hasDeparted()) {
1127  v->onRemovalFromNet(n);
1128  if (v->getLane() != 0) {
1129  v->getLane()->removeVehicle(v, n);
1130  }
1132  }
1133  }
1134  break;
1135  case VAR_MOVE_TO_VTD: {
1136  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
1137  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting VTD vehicle requires a compound object.", outputStorage);
1138  }
1139  if (inputStorage.readInt() != 4) {
1140  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting VTD vehicle should obtain: edgeID, lane, x, y.", outputStorage);
1141  }
1142  // edge ID
1143  std::string edgeID;
1144  if (!server.readTypeCheckingString(inputStorage, edgeID)) {
1145  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The first parameter for setting a VTD vehicle must be the edge ID given as a string.", outputStorage);
1146  }
1147  // lane index
1148  int laneNum = 0;
1149  if (!server.readTypeCheckingInt(inputStorage, laneNum)) {
1150  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The second parameter for setting a VTD vehicle must be lane given as an int.", outputStorage);
1151  }
1152  // x
1153  double x = 0, y = 0;
1154  if (!server.readTypeCheckingDouble(inputStorage, x)) {
1155  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The third parameter for setting a VTD vehicle must be the x-position given as a double.", outputStorage);
1156  }
1157  // y
1158  if (!server.readTypeCheckingDouble(inputStorage, y)) {
1159  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "The fourth parameter for setting a VTD vehicle must be the y-position given as a double.", outputStorage);
1160  }
1161  // process
1162  if (!v->isOnRoad()) {
1163  break;
1164  }
1165  std::string origID = edgeID + " " + toString(laneNum);
1166  if (laneNum < 0) {
1167  edgeID = '-' + edgeID;
1168  laneNum = -laneNum;
1169  }
1170  Position pos(x, y);
1171 
1172  Position vehPos = v->getPosition();
1173  v->updateBestLanes();
1174  bool report = server.vtdDebug();
1175  if (report) {
1176  std::cout << std::endl << "begin vehicle " << v->getID() << " vehPos:" << vehPos << " lane:" << v->getLane()->getID() << std::endl;
1177  }
1178  if (report) {
1179  std::cout << " want pos:" << pos << " edge:" << edgeID << " laneNum:" << laneNum << std::endl;
1180  }
1181 
1182  MSEdgeVector edgesA, edgesB, edgesC;
1183  MSLane* laneA, *laneB, *laneC;
1184  laneA = laneB = laneC = 0;
1185  SUMOReal lanePosA, lanePosB, lanePosC;
1186  SUMOReal bestDistanceA, bestDistanceB, bestDistanceC;
1187  bestDistanceA = bestDistanceB = bestDistanceC = 1000.;//pos.distanceSquaredTo2D(vehPos);
1188  int routeOffsetA, routeOffsetB, routeOffsetC;
1189  routeOffsetA = routeOffsetB = routeOffsetC = 0;
1190  // case a): edge/lane is known and matches route
1191  bool aFound = vtdMap_matchingEdgeLane(pos, origID, *v, server.vtdDebug(), bestDistanceA, &laneA, lanePosA, routeOffsetA, edgesA);
1192  // case b): position is at route, should be somewhere near to it
1193  bool bFound = vtdMap_matchingRoutePosition(pos, origID, *v, server.vtdDebug(), bestDistanceB, &laneB, lanePosB, routeOffsetB, edgesB);
1194  // case c) nearest matching lane
1195  bool cFound = vtdMap_matchingNearest(pos, origID, *v, server, server.vtdDebug(), bestDistanceC, &laneC, lanePosC, routeOffsetC, edgesC);
1196  //
1197  SUMOReal maxRouteDistance = 50;
1198  if (cFound && (bestDistanceA > maxRouteDistance && bestDistanceC > maxRouteDistance)) {
1199  // both route-based approach yield in a position too far away from the submitted --> new route!?
1200  server.setVTDControlled(v, laneC, lanePosC, routeOffsetC, edgesC);
1201  } else {
1202  // use the best we have
1203  if (bFound) {
1204  server.setVTDControlled(v, laneB, lanePosB, routeOffsetB, edgesB);
1205  } else if (aFound) {
1206  server.setVTDControlled(v, laneA, lanePosA, routeOffsetA, edgesA);
1207  } else if (cFound) {
1208  server.setVTDControlled(v, laneC, lanePosC, routeOffsetC, edgesC);
1209  } else {
1210  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Could not map vehicle.", outputStorage);
1211  }
1212  }
1213  }
1214  break;
1215  case VAR_SPEED_FACTOR: {
1216  double factor = 0;
1217  if (!server.readTypeCheckingDouble(inputStorage, factor)) {
1218  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting speed factor requires a double.", outputStorage);
1219  }
1220  v->setChosenSpeedFactor(factor);
1221  }
1222  break;
1223  default:
1224  try {
1225  if (!TraCIServerAPI_VehicleType::setVariable(CMD_SET_VEHICLE_VARIABLE, variable, getSingularType(v), server, inputStorage, outputStorage)) {
1226  return false;
1227  }
1228  } catch (ProcessError& e) {
1229  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, e.what(), outputStorage);
1230  }
1231  break;
1232  }
1233  server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_OK, warning, outputStorage);
1234  return true;
1235 }
1236 
1237 
1238 bool
1239 TraCIServerAPI_Vehicle::vtdMap_matchingEdgeLane(const Position& pos, const std::string& origID, MSVehicle& v, bool report,
1240  SUMOReal& bestDistance, MSLane** lane, SUMOReal& lanePos, int& routeOffset, MSEdgeVector& edges) {
1241  UNUSED_PARAMETER(edges);
1242  const std::map<std::string, std::vector<MSLane*> >& vtdMap = getOrBuildVTDMap();
1243  if (vtdMap.find(origID) == vtdMap.end()) {
1244  if (report) {
1245  std::cout << " a failed - lane not in map" << std::endl;
1246  }
1247  return false;
1248  }
1249  const std::vector<MSLane*>& lanes = vtdMap.find(origID)->second;
1250  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end() && bestDistance > POSITION_EPS; ++i) {
1251  MSLane* l = *i;
1252  SUMOReal dist = l->getShape().distance(pos);
1253  if (report) {
1254  std::cout << " a at lane " << l->getID() << " dist:" << dist << " best:" << bestDistance << std::endl;
1255  }
1256  if (dist < bestDistance) {
1257  bestDistance = dist;
1258  *lane = l;
1259  }
1260  }
1261  MSLane* pni = *lane;
1262  while (pni != 0 && pni->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL && pni->getIncomingLanes().size() != 0) {
1263  pni = pni->getIncomingLanes()[0].lane;
1264  }
1265  if (pni == 0 || pni->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1266  // not found
1267  if (report) {
1268  std::cout << " a failed - no incoming lane" << std::endl;
1269  }
1270  return false;
1271  }
1272  const MSEdgeVector& tedges = v.getRoute().getEdges();
1273  MSEdgeVector::const_iterator p = std::find(tedges.begin() + v.getRoutePosition(), tedges.end(), &pni->getEdge());
1274  if (p != tedges.end()) {
1275  lanePos = MAX2(SUMOReal(0), MIN2(SUMOReal((*lane)->getLength() - POSITION_EPS), (*lane)->getShape().nearest_offset_to_point2D(pos, false)));
1276  routeOffset = (int)(std::distance(tedges.begin(), p) - v.getRoutePosition());
1277  if (report) {
1278  std::cout << " a ok lane:" << (*lane)->getID() << " lanePos:" << lanePos << " routeOffset:" << routeOffset << std::endl;
1279  }
1280  return true;
1281  }
1282  if (report) {
1283  std::cout << " a failed - route position beyond route length" << std::endl;
1284  }
1285  return false;
1286 }
1287 
1288 
1289 bool
1290 TraCIServerAPI_Vehicle::vtdMap_matchingRoutePosition(const Position& pos, const std::string& origID, MSVehicle& v, bool report,
1291  SUMOReal& bestDistance, MSLane** lane, SUMOReal& lanePos, int& routeOffset, MSEdgeVector& edges) {
1292  UNUSED_PARAMETER(edges);
1293  UNUSED_PARAMETER(origID);
1294  int lastBestRouteEdge = 0;
1295  int lastRouteEdge = 0;
1296  MSLane* bestRouteLane = 0;
1297  const std::vector<MSLane*>& bestLaneConts = v.getBestLanesContinuation(v.getLane());
1298  for (std::vector<MSLane*>::const_iterator i = bestLaneConts.begin(); i != bestLaneConts.end() && bestDistance > POSITION_EPS; ++i) {
1299  MSEdge& e = (*i)->getEdge();
1300  if (i != bestLaneConts.begin() && e.getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1301  ++lastRouteEdge;
1302  }
1303  const std::vector<MSLane*>& lanes = e.getLanes();
1304  for (std::vector<MSLane*>::const_iterator k = lanes.begin(); k != lanes.end() && bestDistance > POSITION_EPS; ++k) {
1305  MSLane* cl = *k;
1306  SUMOReal dist = cl->getShape().distance(pos);
1307  if (report) {
1308  std::cout << " b at lane " << cl->getID() << " dist:" << dist << " best:" << bestDistance << std::endl;
1309  }
1310  if (dist < bestDistance) {
1311  bestDistance = dist;
1312  *lane = cl;
1313  lastBestRouteEdge = lastRouteEdge;
1315  bestRouteLane = *i;
1316  } else {
1317  bestRouteLane = *lane;
1318  }
1319  }
1320  }
1321  }
1322  if (bestRouteLane == 0) {
1323  if (report) {
1324  std::cout << " b failed - no best route lane" << std::endl;
1325  }
1326  return false;
1327  }
1328  lanePos = MAX2(SUMOReal(0), MIN2(SUMOReal(bestRouteLane->getLength() - POSITION_EPS), bestRouteLane->getShape().nearest_offset_to_point2D(pos, false)));
1329  routeOffset = lastBestRouteEdge;
1330  if (report) {
1331  std::cout << " b ok lane " << bestRouteLane->getID() << " lanePos:" << lanePos << " best:" << lastBestRouteEdge << std::endl;
1332  }
1333  return true;
1334 }
1335 
1336 
1337 bool
1338 TraCIServerAPI_Vehicle::vtdMap_matchingNearest(const Position& pos, const std::string& origID, MSVehicle& v, TraCIServer& server, bool report,
1339  SUMOReal& bestDistance, MSLane** lane, SUMOReal& lanePos, int& routeOffset, MSEdgeVector& edges) {
1340  UNUSED_PARAMETER(bestDistance);
1341  unsigned int r = 0;
1342  SUMOReal minDist = 1 << (11);
1343  MSLane* minDistLane = 0;
1344  MSLane* nameMatchingLane = 0;
1345  SUMOReal minDistNameMatchingLane = 1 << (11);
1346  for (; minDistLane == 0 && r < 10 && nameMatchingLane == 0; ++r) {
1347  std::set<std::string> into;
1348  PositionVector shape;
1349  shape.push_back(pos);
1350  server.collectObjectsInRange(CMD_GET_EDGE_VARIABLE, shape, 1 << r, into);
1351  for (std::set<std::string>::const_iterator j = into.begin(); j != into.end(); ++j) {
1352  MSEdge* e = MSEdge::dictionary(*j);
1353  const std::vector<MSLane*>& lanes = e->getLanes();
1354  for (std::vector<MSLane*>::const_iterator k = lanes.begin(); k != lanes.end(); ++k) {
1355  MSLane* lane = *k;
1356  SUMOReal dist = lane->getShape().distance(pos);
1357  if (lane->knowsParameter("origId")) {
1358  if (lane->getParameter("origId", "") == origID) {
1359  if (dist < minDistNameMatchingLane) {
1360  minDistNameMatchingLane = dist;
1361  nameMatchingLane = lane;
1362  }
1363  }
1364  }
1365  if (dist < minDist) {
1366  minDist = dist;
1367  minDistLane = lane;
1368  }
1369  }
1370  }
1371  }
1372  *lane = nameMatchingLane != 0 ? nameMatchingLane : minDistLane;
1373  if (lane == 0) {
1374  if (report) {
1375  std::cout << " c failed - no matching lane" << std::endl;
1376  }
1377  return false;
1378  }
1379  lanePos = (*lane)->interpolateGeometryPosToLanePos((*lane)->getShape().nearest_offset_to_point2D(pos, false));
1380  if (*lane == v.getLane()) {
1381  routeOffset = 0;
1382  if (report) {
1383  std::cout << " c ok, on same lane" << std::endl;
1384  }
1385  return true;
1386  }
1387  MSEdge& destinationEdge = (*lane)->getEdge();
1388  MSEdge* routePos = &destinationEdge;
1389  while (routePos->getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1390  routePos = &routePos->getLanes()[0]->getLogicalPredecessorLane()->getEdge();
1391  }
1392  r = 0;
1393  const MSRoute& route = v.getRoute();
1394  unsigned int c = v.getRoutePosition();
1395  unsigned int l = (int)route.getEdges().size();
1396  unsigned int rindex = 0;
1397  bool found = false;
1398  while (!found && ((int)(c - r) >= 0 || c + r < l)) {
1399  if ((int)(c - r) >= 0 && route[c - r] == routePos) {
1400  rindex = c - r;
1401  found = true;
1402  }
1403  if (c + r < l && route[c + r] == routePos) {
1404  rindex = c + r;
1405  found = true;
1406  }
1407  ++r;
1408  }
1409  if (found) {
1410  // the matching lane is part of the route
1411  routeOffset = rindex - v.getRoutePosition();
1412  if (report) {
1413  std::cout << " c ok, on a different edge of same route" << std::endl;
1414  }
1415  return true;
1416  }
1417  // build new route
1418  MSLane* firstLane = *lane;
1419  if (destinationEdge.getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1420  edges.push_back(&destinationEdge);
1421  } else {
1422  firstLane = (*lane)->getLogicalPredecessorLane();
1423  edges.push_back(&firstLane->getEdge());
1424  }
1425  const MSLinkCont& lc = firstLane->getLinkCont();
1426  if (lc.size() != 0 && lc[0]->getLane() != 0) {
1427  edges.push_back(&lc[0]->getLane()->getEdge());
1428  }
1429  if (report) {
1430  std::cout << " c ok, on a different route" << std::endl;
1431  }
1432  return true;
1433 }
1434 
1435 
1436 bool
1438  tcpip::Storage& outputStorage, const MSVehicle* v) {
1439  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
1440  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of distance requires a compound object.", outputStorage);
1441  }
1442  if (inputStorage.readInt() != 2) {
1443  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Retrieval of distance requires position and distance type as parameter.", outputStorage);
1444  }
1445 
1446  Position pos;
1447  std::pair<const MSLane*, SUMOReal> roadPos;
1448 
1449  // read position
1450  int posType = inputStorage.readUnsignedByte();
1451  switch (posType) {
1452  case POSITION_ROADMAP:
1453  try {
1454  std::string roadID = inputStorage.readString();
1455  roadPos.second = inputStorage.readDouble();
1456  roadPos.first = TraCIServerAPI_Simulation::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos.second);
1457  pos = roadPos.first->getShape().positionAtOffset(roadPos.second);
1458  } catch (TraCIException& e) {
1459  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, e.what(), outputStorage);
1460  }
1461  break;
1462  case POSITION_2D:
1463  case POSITION_3D: {
1464  const double p1x = inputStorage.readDouble();
1465  const double p1y = inputStorage.readDouble();
1466  pos.set(p1x, p1y);
1467  }
1468  if (posType == POSITION_3D) {
1469  inputStorage.readDouble(); // z value is ignored
1470  }
1472  break;
1473  default:
1474  return server.writeErrorStatusCmd(CMD_GET_VEHICLE_VARIABLE, "Unknown position format used for distance request", outputStorage);
1475  }
1476 
1477  // read distance type
1478  int distType = inputStorage.readUnsignedByte();
1479 
1480  SUMOReal distance = INVALID_DOUBLE_VALUE;
1481  if (v->isOnRoad()) {
1482  if (distType == REQUEST_DRIVINGDIST) {
1483  distance = v->getRoute().getDistanceBetween(v->getPositionOnLane(), roadPos.second,
1484  v->getEdge(), &roadPos.first->getEdge());
1485  if (distance == std::numeric_limits<SUMOReal>::max()) {
1486  distance = INVALID_DOUBLE_VALUE;
1487  }
1488  } else {
1489  // compute air distance (default)
1490  distance = v->getPosition().distanceTo(pos);
1491  }
1492  }
1493  // write response command
1494  outputStorage.writeUnsignedByte(TYPE_DOUBLE);
1495  outputStorage.writeDouble(distance);
1496  return true;
1497 }
1498 
1499 
1500 // ------ helper functions ------
1501 bool
1502 TraCIServerAPI_Vehicle::getPosition(const std::string& id, Position& p) {
1503  MSVehicle* v = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(id));
1504  if (v == 0) {
1505  return false;
1506  }
1507  p = v->getPosition();
1508  return true;
1509 }
1510 
1511 
1514  const MSVehicleType& oType = veh->getVehicleType();
1515  std::string newID = oType.getID().find('@') == std::string::npos ? oType.getID() + "@" + veh->getID() : oType.getID();
1516  MSVehicleType* type = MSVehicleType::build(newID, &oType);
1517  static_cast<MSVehicle*>(veh)->replaceVehicleType(type);
1518  return *type;
1519 }
1520 
1521 
1522 #include <microsim/MSEdgeControl.h>
1523 
1524 const std::map<std::string, std::vector<MSLane*> >&
1526  if (gVTDMap.size() == 0) {
1527  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
1528  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
1529  const std::vector<MSLane*>& lanes = (*i)->getLanes();
1530  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
1531  if ((*j)->knowsParameter("origId")) {
1532  std::string origID = (*j)->getParameter("origId", "");
1533  if (gVTDMap.find(origID) == gVTDMap.end()) {
1534  gVTDMap[origID] = std::vector<MSLane*>();
1535  }
1536  gVTDMap[origID].push_back(*j);
1537  }
1538  }
1539  }
1540  if (gVTDMap.size() == 0) {
1541  gVTDMap["unknown"] = std::vector<MSLane*>();
1542  }
1543  }
1544  return gVTDMap;
1545 }
1546 
1547 
1548 #endif
1549 
1550 
1551 /****************************************************************************/
1552 
#define VAR_ROAD_ID
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:641
static bool setVariable(const int cmd, const int variable, MSVehicleType &v, TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value for the given type.
#define REMOVE_PARKING
void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
Definition: MSVehicle.cpp:2300
bool enterLaneAtMove(MSLane *enteredLane, bool onTeleporting=false)
Update when the vehicle enters a new lane in the move step.
Definition: MSVehicle.cpp:1644
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:455
RGBColor color
The vehicle&#39;s color.
static bool commandDistanceRequest(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage, const MSVehicle *v)
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:78
#define VAR_EMISSIONCLASS
void reroute(SUMOTime t, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, bool withTaz=false)
Performs a rerouting using the given router.
static bool vtdMap_matchingRoutePosition(const Position &pos, const std::string &origID, MSVehicle &v, bool report, SUMOReal &bestDistance, MSLane **lane, SUMOReal &lanePos, int &routeOffset, MSEdgeVector &edges)
#define VAR_CO2EMISSION
#define REQUEST_DRIVINGDIST
#define VAR_LENGTH
void collectObjectsInRange(int domain, const PositionVector &shape, SUMOReal range, std::set< std::string > &into)
The time is given.
static bool parseDepartSpeed(const std::string &val, const std::string &element, const std::string &id, SUMOReal &speed, DepartSpeedDefinition &dsd, std::string &error)
Validates a given departSpeed value.
#define RESPONSE_GET_VEHICLE_VARIABLE
SUMOReal nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
static MSVehicleType & getSingularType(SUMOVehicle *const veh)
#define CMD_GET_VEHICLE_VARIABLE
#define TYPE_COMPOUND
static std::map< std::string, std::vector< MSLane * > > gVTDMap
static bool parseArrivalPos(const std::string &val, const std::string &element, const std::string &id, SUMOReal &pos, ArrivalPosDefinition &apd, std::string &error)
Validates a given arrivalPos value.
constVehIt loadedVehBegin() const
Returns the begin of the internal vehicle map.
#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
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:180
static const MSLane * getLaneChecking(std::string roadID, int laneIndex, SUMOReal pos)
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
Definition: MSVehicle.h:464
#define VAR_ROUTE
#define CMD_CHANGELANE
bool readTypeCheckingColor(tcpip::Storage &inputStorage, RGBColor &into)
Reads the value type and a color, verifying the type.
#define VAR_SPEEDSETMODE
#define VAR_TAU
MSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:60
SUMOReal getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:2400
void setRespectJunctionPriority(bool value)
Sets whether junction priority rules shall be respected.
Definition: MSVehicle.cpp:323
#define CMD_STOP
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:370
Position getPosition(const SUMOReal offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:595
SUMOReal departSpeed
(optional) The initial speed of the vehicle
#define VAR_ALLOWED_SPEED
#define TYPE_UBYTE
The position is given.
#define RTYPE_OK
#define POSITION_ROADMAP
unsigned int personCapacity
The vehicle&#39;s capacity (persons)
#define DISTANCE_REQUEST
Tag for the last element in the enum for safe int casting.
static bool getVariable(const int variable, const MSVehicleType &v, tcpip::Storage &tempMsg)
Processes a value request for the given type.
#define VAR_WAITING_TIME
virtual double readDouble()
SUMOReal arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
#define VAR_SIGNALS
#define VAR_TYPE
#define VAR_ROUTE_ID
Notification
Definition of a vehicle state.
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:1066
#define VAR_VEHICLECLASS
bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:449
const MSEdgeVector & getEdges() const
Definition: MSRoute.h:123
#define VAR_SPEED_FACTOR
#define VAR_COLOR
SUMOReal getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:2209
static bool getPosition(const std::string &id, Position &p)
Returns the named vehicle&#39;s position.
bool reached
Information whether the stop has been reached.
Definition: MSVehicle.h:578
bool readTypeCheckingInt(tcpip::Storage &inputStorage, int &into)
Reads the value type and an int, verifying the type.
SUMOReal arrivalPos
(optional) The position the vehicle shall arrive on
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:156
T MAX2(T a, T b)
Definition: StdDefs.h:74
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:82
unsigned int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:2262
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
#define TYPE_COLOR
#define TYPE_STRINGLIST
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
bool hasDeparted() const
Returns whether this vehicle has already departed.
The vehicle got vaporized.
#define POSITION_3D
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn&#39;t already in the dictionary...
Definition: MSEdge.cpp:523
virtual bool addVehicle(const std::string &id, SUMOVehicle *v)
Tries to insert the vehicle into the internal vehicle container.
static std::pair< MSLane *, SUMOReal > convertCartesianToRoadMap(Position pos)
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:558
#define VAR_BEST_LANES
SUMOReal getCO2Emissions() const
Returns CO2 emission of the current state.
Definition: MSVehicle.cpp:2197
unsigned int personNumber
The number of persons in the vehicle.
std::pair< const MSVehicle *const, SUMOReal > getLeader(SUMOReal dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:2163
SUMOReal distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:229
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
SUMOReal getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:284
virtual void writeUnsignedByte(int)
const std::string & getParameter(const std::string &key, const std::string &defaultValue) const
Returns the value for a given key.
constVehIt loadedVehEnd() const
Returns the end of the internal vehicle map.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:230
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
Tag for the last element in the enum for safe int casting.
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
#define VAR_SPEED_DEVIATION
SUMOReal length
The overall length which may be driven when using this lane without a lane change.
Definition: MSVehicle.h:458
#define VAR_NOISEEMISSION
#define VAR_FUELCONSUMPTION
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
void addEffort(const MSEdge *const e, SUMOReal begin, SUMOReal end, SUMOReal value)
Adds an effort information for an edge and a time span.
static MSVehicleType * build(SUMOVTypeParameter &from)
Builds the microsim vehicle type described by the given parameter.
virtual void writeInt(int)
#define VAR_POSITION3D
The speed is given.
The car-following model and parameter.
Definition: MSVehicleType.h:74
#define TYPE_STRING
virtual int readUnsignedByte()
std::string toTaz
The vehicle&#39;s destination zone (district)
The lane is given.
void addTravelTime(const MSEdge *const e, SUMOReal begin, SUMOReal end, SUMOReal value)
Adds a travel time information for an edge and a time span.
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa4: Get Vehicle Variable)
SUMOReal nextOccupation
As occupation, but without the first lane.
Definition: MSVehicle.h:462
#define VAR_NOXEMISSION
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.h:91
#define VAR_ANGLE
const std::string & getID() const
Returns the id.
Definition: Named.h:60
A road/street connecting two junctions.
Definition: MSEdge.h:75
static void parseEdgesList(const std::string &desc, std::vector< const MSEdge * > &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
Definition: MSEdge.cpp:586
MSLane * lane
The described lane.
Definition: MSVehicle.h:456
#define VAR_PERSON_NUMBER
#define CMD_SLOWDOWN
MSLane * getLogicalPredecessorLane() const
Definition: MSLane.cpp:1351
#define VAR_SHAPECLASS
#define max(a, b)
Definition: polyfonts.c:65
void setEmergencyBrakeRedLight(bool value)
Sets whether red lights shall be a reason to brake.
Definition: MSVehicle.cpp:329
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
void removeEffort(const MSEdge *const e)
Removes the effort information for an edge.
#define REMOVE_ARRIVED
DepartLaneDefinition
Possible ways to choose a lane on depart.
#define VAR_ACCEL
#define CMD_CHANGETARGET
Representation of a vehicle.
Definition: SUMOVehicle.h:64
void setChosenSpeedFactor(const SUMOReal factor)
Returns the precomputed factor by which the driver wants to be faster than the speed limit...
virtual int readInt()
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
SUMOReal getDistanceBetween(SUMOReal fromPos, SUMOReal toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:265
#define REMOVE_TELEPORT_ARRIVED
std::vector< const MSEdge * > MSEdgeVector
Definition: MSPerson.h:57
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, unsigned int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:176
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the subpart of best lanes that describes the vehicle&#39;s current lane and their successors...
Definition: MSVehicle.cpp:2085
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:86
bool willPass(const MSEdge *const edge) const
Returns whether the vehicle wil pass the given edge.
Definition: MSVehicle.cpp:497
#define VAR_LANEPOSITION
A list of positions.
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:1819
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:283
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.h:99
virtual void writeByte(int)
#define REMOVE_TELEPORT
const MSEdge * succEdge(unsigned int nSuccs) const
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
bool readTypeCheckingStringList(tcpip::Storage &inputStorage, std::vector< std::string > &into)
Reads the value type and a string list, verifying the type.
SUMOReal z() const
Returns the z-position.
Definition: Position.h:73
The vehicle arrived at its destination (is deleted)
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:791
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, const MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true)
Builds a vehicle, increases the number of built vehicles.
int arrivalLane
(optional) The lane the vehicle shall arrive on (not used yet)
SUMOReal distance(const Position &p) const
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
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:570
#define CMD_SET_VEHICLE_VARIABLE
T MIN2(T a, T b)
Definition: StdDefs.h:68
#define VAR_IMPERFECTION
#define POSITION_EPS
Definition: config.h:189
std::string fromTaz
The vehicle&#39;s origin zone (district)
virtual std::string readString()
void setVTDControlled(MSVehicle *v, MSLane *l, SUMOReal pos, int edgeOffset, MSEdgeVector route)
#define CMD_GET_EDGE_VARIABLE
Tag for the last element in the enum for safe int casting.
A structure representing the best lanes for continuing the route.
Definition: MSVehicle.h:454
#define VAR_EDGES
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:428
static bool parseArrivalLane(const std::string &val, const std::string &element, const std::string &id, int &lane, ArrivalLaneDefinition &ald, std::string &error)
Validates a given arrivalLane value.
#define VAR_EDGE_EFFORT
#define CMD_REROUTE_EFFORT
#define VAR_STOPSTATE
#define ADD
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
#define REMOVE
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:74
const int VEHPARS_COLOR_SET
virtual void writeStorage(tcpip::Storage &store)
#define VAR_LEADER
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:797
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:1813
static bool parseDepartPos(const std::string &val, const std::string &element, const std::string &id, SUMOReal &pos, DepartPosDefinition &dpd, std::string &error)
Validates a given departPos value.
bool allowsContinuation
Whether this lane allows to continue the drive.
Definition: MSVehicle.h:466
SUMOReal getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
Definition: MSVehicle.cpp:2233
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
std::string line
The vehicle&#39;s line (mainly for public transport)
#define INVALID_DOUBLE_VALUE
#define VAR_SPEED
DepartSpeedDefinition
Possible ways to choose the departure speed.
SUMOReal getNOxEmissions() const
Returns NOx emission of the current state.
Definition: MSVehicle.cpp:2215
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
static bool parseArrivalSpeed(const std::string &val, const std::string &element, const std::string &id, SUMOReal &speed, ArrivalSpeedDefinition &asd, std::string &error)
Validates a given arrivalSpeed value.
SUMOReal getPMxEmissions() const
Returns PMx emission of the current state.
Definition: MSVehicle.cpp:2221
SUMOReal getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:2203
#define VAR_EDGE_TRAVELTIME
void push_back(const PositionVector &p)
Appends all positions from the given vector.
static bool vtdMap_matchingNearest(const Position &pos, const std::string &origID, MSVehicle &v, TraCIServer &server, bool report, SUMOReal &bestDistance, MSLane **lane, SUMOReal &lanePos, int &routeOffset, MSEdgeVector &edges)
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:869
#define VAR_COEMISSION
bool replaceRouteEdges(MSEdgeVector &edges, bool onInit=false)
Replaces the current route by the given edges.
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, SUMOReal > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:169
virtual void writeString(const std::string &s)
void removeTravelTime(const MSEdge *const e)
Removes the travel time information for an edge.
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:222
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2391
void scheduleVehicleRemoval(SUMOVehicle *veh)
Removes a vehicle after it has ended.
Structure representing possible vehicle parameter.
#define INVALID_INT_VALUE
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:81
#define VAR_MOVE_TO
#define SUMOTime_MAX
Definition: SUMOTime.h:44
bool addTraciStop(MSLane *lane, SUMOReal pos, SUMOReal radius, SUMOTime duration, bool parking, bool triggered, std::string &errorMsg)
Definition: MSVehicle.cpp:2324
#define TYPE_DOUBLE
void setConsiderMaxDeceleration(bool value)
Sets whether the maximum deceleration shall be regarded.
Definition: MSVehicle.cpp:317
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:314
int setParameter
Information for the router which parameter were set.
#define CMD_REROUTE_TRAVELTIME
std::vector< MSLane * > bestContinuations
Consecutive lane that can be followed without a lane change (contribute to length and occupation) ...
Definition: MSVehicle.h:468
#define TYPE_BYTE
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
SUMOReal getFuelConsumption() const
Returns fuel consumption of the current state.
Definition: MSVehicle.cpp:2227
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:90
void set(SUMOReal x, SUMOReal y)
Definition: Position.h:78
void setConsiderSafeVelocity(bool value)
Sets whether the safe velocity shall be regarded.
Definition: MSVehicle.cpp:305
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:560
SUMOReal getChosenSpeedFactor() const
Returns the precomputed factor by which the driver wants to be faster than the speed limit...
const std::string & getID() const
Returns the name of the vehicle type.
static bool vtdMap_matchingEdgeLane(const Position &pos, const std::string &origID, MSVehicle &v, bool report, SUMOReal &bestDistance, MSLane **lane, SUMOReal &lanePos, int &routeOffset, MSEdgeVector &edges)
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const std::vector< MSEdge * > &prohibited=std::vector< MSEdge * >()) const
Definition: MSNet.cpp:739
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:292
int SUMOTime
Definition: SUMOTime.h:43
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
std::map< std::string, SUMOVehicle * >::const_iterator constVehIt
Definition of the internal vehicles map iterator.
SUMOReal departPos
(optional) The position the vehicle shall depart from
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:335
SUMOReal getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:368
virtual void writeDouble(double)
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
Definition: MSVehicle.cpp:803
#define REMOVE_VAPORIZED
unsigned size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:87
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:323
#define VAR_MOVE_TO_VTD
const std::vector< MSEdge * > & getEdges() const
Returns loaded edges.
const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
Definition: MSVehicle.cpp:622
bool knowsEffort(const MSEdge *const e) const
Returns the information whether any effort is known for the given edge.
bool hasValidRoute(std::string &msg) const
Validates the current route.
int getSignals() const
Returns the signals.
Definition: MSVehicle.h:798
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.h:83
#define SUMOReal
Definition: config.h:218
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:790
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:782
virtual void compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
#define VAR_SPEED_WITHOUT_TRACI
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:304
#define NUMERICAL_EPS
Definition: config.h:162
#define VAR_LANECHANGE_MODE
#define VAR_MAXSPEED
#define DELTA_T
Definition: SUMOTime.h:50
bool retrieveExistingEffort(const MSEdge *const e, const SUMOReal t, SUMOReal &value) const
Returns an effort for an edge and time if stored.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
The vehicle was teleported out of the net.
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1039
#define VAR_DECEL
#define VAR_ROUTE_VALID
The class responsible for building and deletion of vehicles.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
#define ID_COUNT
#define VAR_LANE_INDEX
bool knowsTravelTime(const MSEdge *const e) const
Returns the information whether any travel time is known for the given edge.
bool vtdDebug() const
#define VAR_LANE_ID
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane&#39;s maximum speed, given a vehicle&#39;s speed limit adaptation.
Definition: MSLane.h:354
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:337
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:329
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:580
The edge is an internal edge.
Definition: MSEdge.h:92
static const std::map< std::string, std::vector< MSLane * > > & getOrBuildVTDMap()
SUMOReal interpolateGeometryPosToLanePos(SUMOReal geometryPos) const
Definition: MSLane.h:346
Tag for the last element in the enum for safe int casting.
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, MTRand *rng=0)
Returns the named vehicle type or a sample from the named distribution.
DepartPosDefinition
Possible ways to choose the departure position.
#define RTYPE_ERR
#define TYPE_INTEGER
#define VAR_MINGAP
#define ID_LIST
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.h:75
#define ADD_FULL
void add(SUMOVehicle *veh)
Adds a single vehicle for departure.
SUMOReal startPos
The stopping position start.
Definition: MSVehicle.h:566
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle&#39;s internal edge travel times/efforts container.
Definition: MSVehicle.cpp:518
bool retrieveExistingTravelTime(const MSEdge *const e, const SUMOReal t, SUMOReal &value) const
Returns a travel time for an edge and time if stored.
unsigned int getRoutePosition() const
Definition: MSVehicle.cpp:503
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
DepartDefinition
Possible ways to depart.
static bool parseDepart(const std::string &val, const std::string &element, const std::string &id, SUMOTime &depart, DepartDefinition &dd, std::string &error)
Validates a given depart value.
#define VAR_DISTANCE
bool readTypeCheckingByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and a byte, verifying the type.
#define VAR_HCEMISSION
void setConsiderMaxAcceleration(bool value)
Sets whether the maximum acceleration shall be regarded.
Definition: MSVehicle.cpp:311
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:75
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
std::string id
The vehicle&#39;s id.
The vehicle is being teleported.
#define VAR_WIDTH
SUMOReal getAngle() const
Returns the vehicle&#39;s direction in degrees.
Definition: MSVehicle.cpp:638
const std::string & getID() const
Returns the name of the vehicle.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:116
static bool parseDepartLane(const std::string &val, const std::string &element, const std::string &id, int &lane, DepartLaneDefinition &dld, std::string &error)
Validates a given departLane value.