SUMO - Simulation of Urban MObility
TraCIServerAPI_Simulation.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // APIs for getting/setting edge values via TraCI
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
13 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #ifndef NO_TRACI
35 
36 #include <utils/common/StdDefs.h>
38 #include <microsim/MSNet.h>
39 #include <microsim/MSEdgeControl.h>
41 #include <microsim/MSEdge.h>
42 #include <microsim/MSLane.h>
43 #include <microsim/MSVehicle.h>
47 #include <traci-server/lib/TraCI.h>
48 #include "TraCIConstants.h"
50 
51 
52 // ===========================================================================
53 // method definitions
54 // ===========================================================================
55 bool
57  tcpip::Storage& outputStorage) {
58  // variable & id
59  int variable = inputStorage.readUnsignedByte();
60  std::string id = inputStorage.readString();
61  // check variable
62  if (variable != VAR_TIME_STEP
63  && variable != VAR_LOADED_VEHICLES_NUMBER && variable != VAR_LOADED_VEHICLES_IDS
64  && variable != VAR_DEPARTED_VEHICLES_NUMBER && variable != VAR_DEPARTED_VEHICLES_IDS
67  && variable != VAR_ARRIVED_VEHICLES_NUMBER && variable != VAR_ARRIVED_VEHICLES_IDS
68  && variable != VAR_DELTA_T && variable != VAR_NET_BOUNDING_BOX
69  && variable != VAR_MIN_EXPECTED_VEHICLES
70  && variable != POSITION_CONVERSION && variable != DISTANCE_REQUEST
71  && variable != VAR_BUS_STOP_WAITING
76  ) {
77  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Get Simulation Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
78  }
79  // begin response building
80  tcpip::Storage tempMsg;
81  // response-code, variableID, objectID
83  tempMsg.writeUnsignedByte(variable);
84  tempMsg.writeString(id);
85  // process request
86  switch (variable) {
87  case VAR_TIME_STEP:
89  tempMsg.writeInt((int)MSNet::getInstance()->getCurrentTimeStep());
90  break;
93  break;
96  break;
99  break;
102  break;
105  break;
108  break;
111  break;
114  break;
117  break;
120  break;
123  break;
126  break;
129  break;
132  break;
135  break;
138  break;
141  break;
144  break;
145  case VAR_DELTA_T:
147  tempMsg.writeInt((int)DELTA_T);
148  break;
149  case VAR_NET_BOUNDING_BOX: {
152  tempMsg.writeDouble(b.xmin());
153  tempMsg.writeDouble(b.ymin());
154  tempMsg.writeDouble(b.xmax());
155  tempMsg.writeDouble(b.ymax());
156  break;
157  }
158  break;
161  tempMsg.writeInt(MSNet::getInstance()->getVehicleControl().getActiveVehicleCount() + MSNet::getInstance()->getInsertionControl().getPendingFlowCount());
162  break;
163  case POSITION_CONVERSION:
164  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
165  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Position conversion requires a compound object.", outputStorage);
166  }
167  if (inputStorage.readInt() != 2) {
168  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Position conversion requires a source position and a position type as parameter.", outputStorage);
169  }
170  if (!commandPositionConversion(server, inputStorage, tempMsg, CMD_GET_SIM_VARIABLE)) {
171  return false;
172  }
173  break;
174  case DISTANCE_REQUEST:
175  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
176  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Retrieval of distance requires a compound object.", outputStorage);
177  }
178  if (inputStorage.readInt() != 3) {
179  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Retrieval of distance requires two positions and a distance type as parameter.", outputStorage);
180  }
181  if (!commandDistanceRequest(server, inputStorage, tempMsg, CMD_GET_SIM_VARIABLE)) {
182  return false;
183  }
184  break;
185  case VAR_BUS_STOP_WAITING: {
186  std::string id;
187  if (!server.readTypeCheckingString(inputStorage, id)) {
188  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Retrieval of persons at busstop requires a string.", outputStorage);
189  }
191  if (s == 0) {
192  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Unknown bus stop '" + id + "'.", outputStorage);
193  }
195  tempMsg.writeInt(s->getTransportableNumber());
196  break;
197  }
198  default:
199  break;
200  }
201  server.writeStatusCmd(CMD_GET_SIM_VARIABLE, RTYPE_OK, "", outputStorage);
202  server.writeResponseWithLength(outputStorage, tempMsg);
203  return true;
204 }
205 
206 
207 bool
209  tcpip::Storage& outputStorage) {
210  std::string warning = ""; // additional description for response
211  // variable
212  int variable = inputStorage.readUnsignedByte();
213  if (variable != CMD_CLEAR_PENDING_VEHICLES
214  && variable != CMD_SAVE_SIMSTATE) {
215  return server.writeErrorStatusCmd(CMD_SET_SIM_VARIABLE, "Set Simulation Variable: unsupported variable " + toHex(variable, 2) + " specified", outputStorage);
216  }
217  // id
218  std::string id = inputStorage.readString();
219  // process
220  switch (variable) {
222  //clear any pending vehicle insertions
223  std::string route;
224  if (!server.readTypeCheckingString(inputStorage, route)) {
225  return server.writeErrorStatusCmd(CMD_SET_SIM_VARIABLE, "A string is needed for clearing pending vehicles.", outputStorage);
226  }
228  }
229  break;
230  case CMD_SAVE_SIMSTATE: {
231  //save current simulation state
232  std::string file;
233  if (!server.readTypeCheckingString(inputStorage, file)) {
234  return server.writeErrorStatusCmd(CMD_SET_SIM_VARIABLE, "A string is needed for saving simulation state.", outputStorage);
235  }
236  MSStateHandler::saveState(file, MSNet::getInstance()->getCurrentTimeStep());
237  }
238  break;
239  default:
240  break;
241  }
242  server.writeStatusCmd(CMD_SET_SIM_VARIABLE, RTYPE_OK, warning, outputStorage);
243  return true;
244 }
245 
246 
247 void
249  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(state)->second;
250  outputStorage.writeUnsignedByte(TYPE_INTEGER);
251  outputStorage.writeInt((int) ids.size());
252 }
253 
254 
255 void
257  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(state)->second;
258  outputStorage.writeUnsignedByte(TYPE_STRINGLIST);
259  outputStorage.writeStringList(ids);
260 }
261 
262 
263 std::pair<MSLane*, double>
265  std::pair<MSLane*, double> result;
266  std::vector<std::string> allEdgeIds;
267  double minDistance = std::numeric_limits<double>::max();
268 
269  allEdgeIds = MSNet::getInstance()->getEdgeControl().getEdgeNames();
270  for (std::vector<std::string>::iterator itId = allEdgeIds.begin(); itId != allEdgeIds.end(); itId++) {
271  const std::vector<MSLane*>& allLanes = MSEdge::dictionary((*itId))->getLanes();
272  for (std::vector<MSLane*>::const_iterator itLane = allLanes.begin(); itLane != allLanes.end(); itLane++) {
273  const double newDistance = (*itLane)->getShape().distance2D(pos);
274  if (newDistance < minDistance) {
275  minDistance = newDistance;
276  result.first = (*itLane);
277  }
278  }
279  }
280  // @todo this may be a place where 3D is required but 2D is delivered
281  result.second = result.first->getShape().nearest_offset_to_point2D(pos, false);
282  return result;
283 }
284 
285 
286 bool
288  tcpip::Storage& outputStorage, int commandId) {
289  std::pair<MSLane*, double> roadPos;
290  Position cartesianPos;
291  Position geoPos;
292  double z = 0;
293 
294  // actual position type that will be converted
295  int srcPosType = inputStorage.readUnsignedByte();
296 
297  switch (srcPosType) {
298  case POSITION_2D:
299  case POSITION_3D:
300  case POSITION_LON_LAT:
301  case POSITION_LON_LAT_ALT: {
302  double x = inputStorage.readDouble();
303  double y = inputStorage.readDouble();
304  if (srcPosType != POSITION_2D && srcPosType != POSITION_LON_LAT) {
305  z = inputStorage.readDouble();
306  }
307  geoPos.set(x, y);
308  cartesianPos.set(x, y);
309  if (srcPosType == POSITION_LON_LAT || srcPosType == POSITION_LON_LAT_ALT) {
311  } else {
313  }
314  }
315  break;
316  case POSITION_ROADMAP: {
317  std::string roadID = inputStorage.readString();
318  double pos = inputStorage.readDouble();
319  int laneIdx = inputStorage.readUnsignedByte();
320  try {
321  // convert edge,offset,laneIdx to cartesian position
322  cartesianPos = geoPos = TraCI::getLaneChecking(roadID, laneIdx, pos)->getShape().positionAtOffset(pos);
323  z = cartesianPos.z();
325  } catch (TraCIException& e) {
326  server.writeStatusCmd(commandId, RTYPE_ERR, e.what());
327  return false;
328  }
329  }
330  break;
331  default:
332  server.writeStatusCmd(commandId, RTYPE_ERR, "Source position type not supported");
333  return false;
334  }
335 
336  int destPosType = 0;
337  if (!server.readTypeCheckingUnsignedByte(inputStorage, destPosType)) {
338  server.writeStatusCmd(commandId, RTYPE_ERR, "Destination position type must be of type ubyte.");
339  return false;
340  }
341 
342  switch (destPosType) {
343  case POSITION_ROADMAP: {
344  // convert cartesion position to edge,offset,lane_index
345  roadPos = convertCartesianToRoadMap(cartesianPos);
346  // write result that is added to response msg
347  outputStorage.writeUnsignedByte(POSITION_ROADMAP);
348  outputStorage.writeString(roadPos.first->getEdge().getID());
349  outputStorage.writeDouble(roadPos.second);
350  const std::vector<MSLane*> lanes = roadPos.first->getEdge().getLanes();
351  outputStorage.writeUnsignedByte((int)distance(lanes.begin(), find(lanes.begin(), lanes.end(), roadPos.first)));
352  }
353  break;
354  case POSITION_2D:
355  case POSITION_3D:
356  case POSITION_LON_LAT:
358  outputStorage.writeUnsignedByte(destPosType);
359  if (destPosType == POSITION_LON_LAT || destPosType == POSITION_LON_LAT_ALT) {
360  outputStorage.writeDouble(geoPos.x());
361  outputStorage.writeDouble(geoPos.y());
362  } else {
363  outputStorage.writeDouble(cartesianPos.x());
364  outputStorage.writeDouble(cartesianPos.y());
365  }
366  if (destPosType != POSITION_2D && destPosType != POSITION_LON_LAT) {
367  outputStorage.writeDouble(z);
368  }
369  break;
370  default:
371  server.writeStatusCmd(commandId, RTYPE_ERR, "Destination position type not supported");
372  return false;
373  }
374  return true;
375 }
376 
377 /****************************************************************************/
378 
379 bool
381  tcpip::Storage& outputStorage, int commandId) {
382  Position pos1;
383  Position pos2;
384  std::pair<const MSLane*, double> roadPos1;
385  std::pair<const MSLane*, double> roadPos2;
386 
387  // read position 1
388  int posType = inputStorage.readUnsignedByte();
389  switch (posType) {
390  case POSITION_ROADMAP:
391  try {
392  std::string roadID = inputStorage.readString();
393  roadPos1.second = inputStorage.readDouble();
394  roadPos1.first = TraCI::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos1.second);
395  pos1 = roadPos1.first->getShape().positionAtOffset(roadPos1.second);
396  } catch (TraCIException& e) {
397  server.writeStatusCmd(commandId, RTYPE_ERR, e.what());
398  return false;
399  }
400  break;
401  case POSITION_2D:
402  case POSITION_3D: {
403  double p1x = inputStorage.readDouble();
404  double p1y = inputStorage.readDouble();
405  pos1.set(p1x, p1y);
406  }
407  if (posType == POSITION_3D) {
408  inputStorage.readDouble();// z value is ignored
409  }
410  roadPos1 = convertCartesianToRoadMap(pos1);
411  break;
412  default:
413  server.writeStatusCmd(commandId, RTYPE_ERR, "Unknown position format used for distance request");
414  return false;
415  }
416 
417  // read position 2
418  posType = inputStorage.readUnsignedByte();
419  switch (posType) {
420  case POSITION_ROADMAP:
421  try {
422  std::string roadID = inputStorage.readString();
423  roadPos2.second = inputStorage.readDouble();
424  roadPos2.first = TraCI::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos2.second);
425  pos2 = roadPos2.first->getShape().positionAtOffset(roadPos2.second);
426  } catch (TraCIException& e) {
427  server.writeStatusCmd(commandId, RTYPE_ERR, e.what());
428  return false;
429  }
430  break;
431  case POSITION_2D:
432  case POSITION_3D: {
433  double p2x = inputStorage.readDouble();
434  double p2y = inputStorage.readDouble();
435  pos2.set(p2x, p2y);
436  }
437  if (posType == POSITION_3D) {
438  inputStorage.readDouble();// z value is ignored
439  }
440  roadPos2 = convertCartesianToRoadMap(pos2);
441  break;
442  default:
443  server.writeStatusCmd(commandId, RTYPE_ERR, "Unknown position format used for distance request");
444  return false;
445  }
446 
447  // read distance type
448  int distType = inputStorage.readUnsignedByte();
449 
450  double distance = 0.0;
451  if (distType == REQUEST_DRIVINGDIST) {
452  // compute driving distance
453  if ((roadPos1.first == roadPos2.first) && (roadPos1.second <= roadPos2.second)) {
454  // same edge
455  distance = roadPos2.second - roadPos1.second;
456  } else {
457  ConstMSEdgeVector newRoute;
459  &roadPos1.first->getEdge(), &roadPos2.first->getEdge(), 0, MSNet::getInstance()->getCurrentTimeStep(), newRoute);
460  MSRoute route("", newRoute, false, 0, std::vector<SUMOVehicleParameter::Stop>());
461  distance = route.getDistanceBetween(roadPos1.second, roadPos2.second, &roadPos1.first->getEdge(), &roadPos2.first->getEdge());
462  }
463  } else {
464  // compute air distance (default)
465  distance = pos1.distanceTo(pos2);
466  }
467  // write response command
468  outputStorage.writeUnsignedByte(TYPE_DOUBLE);
469  outputStorage.writeDouble(distance);
470  return true;
471 }
472 
473 
474 #endif
475 
476 /****************************************************************************/
The vehicle has departed (was inserted into the network)
Definition: MSNet.h:575
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:132
#define CMD_CLEAR_PENDING_VEHICLES
double z() const
Returns the z-position.
Definition: Position.h:73
#define VAR_TIME_STEP
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
#define REQUEST_DRIVINGDIST
static void writeVehicleStateIDs(TraCIServer &server, tcpip::Storage &outputStorage, MSNet::VehicleState state)
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation. ...
#define TYPE_COMPOUND
#define POSITION_2D
A lane area vehicles can halt at.
#define VAR_PARKING_STARTING_VEHICLES_IDS
std::vector< std::string > getEdgeNames() const
Returns the list of names of all known edges.
#define VAR_STOP_ENDING_VEHICLES_IDS
#define VAR_PARKING_ENDING_VEHICLES_NUMBER
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:144
double x() const
Returns the x-position.
Definition: Position.h:63
#define POSITION_LON_LAT_ALT
#define RTYPE_OK
#define POSITION_ROADMAP
#define DISTANCE_REQUEST
virtual double readDouble()
#define VAR_LOADED_VEHICLES_IDS
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xab: Get Simulation Variable)
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:169
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
#define TYPE_STRINGLIST
#define RESPONSE_GET_SIM_VARIABLE
#define POSITION_3D
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn&#39;t already in the dictionary...
Definition: MSEdge.cpp:745
#define VAR_TELEPORT_STARTING_VEHICLES_IDS
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:79
virtual void writeUnsignedByte(int)
void set(double x, double y)
set positions x and y
Definition: Position.h:93
#define POSITION_LON_LAT
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:252
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
#define VAR_LOADED_VEHICLES_NUMBER
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
#define VAR_STOP_STARTING_VEHICLES_NUMBER
static void writeVehicleStateNumber(TraCIServer &server, tcpip::Storage &outputStorage, MSNet::VehicleState state)
virtual void writeInt(int)
virtual int readUnsignedByte()
The vehicles starts to stop.
Definition: MSNet.h:589
#define POSITION_CONVERSION
#define CMD_SAVE_SIMSTATE
#define VAR_DEPARTED_VEHICLES_NUMBER
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xcb: Set Simulation Variable)
#define max(a, b)
Definition: polyfonts.c:65
#define VAR_MIN_EXPECTED_VEHICLES
The vehicle arrived at his destination (is deleted)
Definition: MSNet.h:581
MSStoppingPlace * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:864
The vehicles starts to park.
Definition: MSNet.h:585
virtual int readInt()
static const MSLane * getLaneChecking(const std::string &edgeID, int laneIndex, double pos)
Definition: TraCI.cpp:169
const std::map< MSNet::VehicleState, std::vector< std::string > > & getVehicleStateChanges() const
Definition: TraCIServer.h:165
#define VAR_STOP_STARTING_VEHICLES_IDS
#define VAR_NET_BOUNDING_BOX
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
#define VAR_TELEPORT_STARTING_VEHICLES_NUMBER
#define TYPE_BOUNDINGBOX
double y() const
Returns the y-position.
Definition: Position.h:68
virtual void writeStringList(const std::vector< std::string > &s)
static bool commandPositionConversion(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage, int commandId)
#define VAR_TELEPORT_ENDING_VEHICLES_IDS
The vehicle started to teleport.
Definition: MSNet.h:577
#define CMD_GET_SIM_VARIABLE
virtual std::string readString()
#define VAR_DEPARTED_VEHICLES_IDS
void clearPendingVehicles(std::string &route)
clears out all pending vehicles from a route, "" for all routes
The vehicle ends to park.
Definition: MSNet.h:587
const Boundary & getConvBoundary() const
Returns the converted boundary.
bool readTypeCheckingUnsignedByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and an unsigned byte, verifying the type.
#define VAR_DELTA_T
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:74
#define CMD_SET_SIM_VARIABLE
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:240
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
VehicleState
Definition of a vehicle state.
Definition: MSNet.h:571
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:962
static bool commandDistanceRequest(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage, int commandId)
The vehicle was built, but has not yet departed.
Definition: MSNet.h:573
#define VAR_ARRIVED_VEHICLES_NUMBER
virtual void writeString(const std::string &s)
#define TYPE_DOUBLE
std::string toHex(const T i, std::streamsize numDigits=0)
Definition: ToString.h:66
int getTransportableNumber() const
Returns the number of transportables waiting on this stop.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
#define VAR_STOP_ENDING_VEHICLES_NUMBER
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:358
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:126
#define VAR_PARKING_ENDING_VEHICLES_IDS
The vehicle ends to stop.
Definition: MSNet.h:591
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:138
static std::pair< MSLane *, double > convertCartesianToRoadMap(Position pos)
virtual void writeDouble(double)
#define VAR_TELEPORT_ENDING_VEHICLES_NUMBER
double getDistanceBetween(double fromPos, double 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:281
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:426
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:348
#define VAR_PARKING_STARTING_VEHICLES_NUMBER
#define RTYPE_ERR
#define TYPE_INTEGER
#define VAR_ARRIVED_VEHICLES_IDS
The vehicle ended being teleported.
Definition: MSNet.h:579
#define VAR_BUS_STOP_WAITING
static void saveState(const std::string &file, SUMOTime step)
Saves the current state.