SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-sim.org/
13 // Copyright (C) 2001-2013 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>
44 #include "TraCIConstants.h"
46 
47 #ifdef CHECK_MEMORY_LEAKS
48 #include <foreign/nvwa/debug_new.h>
49 #endif // CHECK_MEMORY_LEAKS
50 
51 
52 // ===========================================================================
53 // used namespaces
54 // ===========================================================================
55 using namespace traci;
56 
57 
58 // ===========================================================================
59 // method definitions
60 // ===========================================================================
61 bool
63  tcpip::Storage& outputStorage) {
64  // variable & id
65  int variable = inputStorage.readUnsignedByte();
66  std::string id = inputStorage.readString();
67  // check variable
68  if (variable != VAR_TIME_STEP
69  && variable != VAR_LOADED_VEHICLES_NUMBER && variable != VAR_LOADED_VEHICLES_IDS
70  && variable != VAR_DEPARTED_VEHICLES_NUMBER && variable != VAR_DEPARTED_VEHICLES_IDS
73  && variable != VAR_ARRIVED_VEHICLES_NUMBER && variable != VAR_ARRIVED_VEHICLES_IDS
74  && variable != VAR_DELTA_T && variable != VAR_NET_BOUNDING_BOX
75  && variable != VAR_MIN_EXPECTED_VEHICLES
76  && variable != POSITION_CONVERSION && variable != DISTANCE_REQUEST
77  && variable != VAR_BUS_STOP_WAITING
78  ) {
79  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Get Simulation Variable: unsupported variable specified", outputStorage);
80  }
81  // begin response building
82  tcpip::Storage tempMsg;
83  // response-code, variableID, objectID
85  tempMsg.writeUnsignedByte(variable);
86  tempMsg.writeString(id);
87  // process request
88  switch (variable) {
89  case VAR_TIME_STEP:
91  tempMsg.writeInt(MSNet::getInstance()->getCurrentTimeStep());
92  break;
94  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(MSNet::VEHICLE_STATE_BUILT)->second;
96  tempMsg.writeInt((int) ids.size());
97  }
98  break;
100  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(MSNet::VEHICLE_STATE_BUILT)->second;
102  tempMsg.writeStringList(ids);
103  }
104  break;
106  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(MSNet::VEHICLE_STATE_DEPARTED)->second;
108  tempMsg.writeInt((int) ids.size());
109  }
110  break;
112  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(MSNet::VEHICLE_STATE_DEPARTED)->second;
114  tempMsg.writeStringList(ids);
115  }
116  break;
118  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(MSNet::VEHICLE_STATE_STARTING_TELEPORT)->second;
120  tempMsg.writeInt((int) ids.size());
121  }
122  break;
124  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(MSNet::VEHICLE_STATE_STARTING_TELEPORT)->second;
126  tempMsg.writeStringList(ids);
127  }
128  break;
130  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(MSNet::VEHICLE_STATE_ENDING_TELEPORT)->second;
132  tempMsg.writeInt((int) ids.size());
133  }
134  break;
136  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(MSNet::VEHICLE_STATE_ENDING_TELEPORT)->second;
138  tempMsg.writeStringList(ids);
139  }
140  break;
142  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(MSNet::VEHICLE_STATE_ARRIVED)->second;
144  tempMsg.writeInt((int) ids.size());
145  }
146  break;
148  const std::vector<std::string>& ids = server.getVehicleStateChanges().find(MSNet::VEHICLE_STATE_ARRIVED)->second;
150  tempMsg.writeStringList(ids);
151  }
152  break;
153  case VAR_DELTA_T:
155  tempMsg.writeInt(DELTA_T);
156  break;
157  case VAR_NET_BOUNDING_BOX: {
160  tempMsg.writeDouble(b.xmin());
161  tempMsg.writeDouble(b.ymin());
162  tempMsg.writeDouble(b.xmax());
163  tempMsg.writeDouble(b.ymax());
164  break;
165  }
166  break;
169  tempMsg.writeInt(MSNet::getInstance()->getVehicleControl().getActiveVehicleCount() + MSNet::getInstance()->getInsertionControl().getPendingFlowCount());
170  break;
171  case POSITION_CONVERSION:
172  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
173  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Position conversion requires a compound object.", outputStorage);
174  }
175  if (inputStorage.readInt() != 2) {
176  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Position conversion requires a source position and a position type as parameter.", outputStorage);
177  }
178  if (!commandPositionConversion(server, inputStorage, tempMsg, CMD_GET_SIM_VARIABLE)) {
179  return false;
180  }
181  break;
182  case DISTANCE_REQUEST:
183  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
184  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Retrieval of distance requires a compound object.", outputStorage);
185  }
186  if (inputStorage.readInt() != 3) {
187  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Retrieval of distance requires two positions and a distance type as parameter.", outputStorage);
188  }
189  if (!commandDistanceRequest(server, inputStorage, tempMsg, CMD_GET_SIM_VARIABLE)) {
190  return false;
191  }
192  break;
193  case VAR_BUS_STOP_WAITING: {
194  std::string id;
195  if (!server.readTypeCheckingString(inputStorage, id)) {
196  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Retrieval of persons at busstop requires a string.", outputStorage);
197  }
199  if (s == 0) {
200  return server.writeErrorStatusCmd(CMD_GET_SIM_VARIABLE, "Unknown bus stop '" + id + "'.", outputStorage);
201  }
203  tempMsg.writeInt(s->getPersonNumber());
204  break;
205  }
206  default:
207  break;
208  }
209  server.writeStatusCmd(CMD_GET_SIM_VARIABLE, RTYPE_OK, "", outputStorage);
210  server.writeResponseWithLength(outputStorage, tempMsg);
211  return true;
212 }
213 
214 
215 std::pair<MSLane*, SUMOReal>
217  std::pair<MSLane*, SUMOReal> result;
218  std::vector<std::string> allEdgeIds;
220 
221  allEdgeIds = MSNet::getInstance()->getEdgeControl().getEdgeNames();
222  for (std::vector<std::string>::iterator itId = allEdgeIds.begin(); itId != allEdgeIds.end(); itId++) {
223  const std::vector<MSLane*>& allLanes = MSEdge::dictionary((*itId))->getLanes();
224  for (std::vector<MSLane*>::const_iterator itLane = allLanes.begin(); itLane != allLanes.end(); itLane++) {
225  const SUMOReal newDistance = (*itLane)->getShape().distance(pos);
226  if (newDistance < minDistance) {
227  minDistance = newDistance;
228  result.first = (*itLane);
229  }
230  }
231  }
232  // @todo this may be a place where 3D is required but 2D is delivered
233  result.second = result.first->getShape().nearest_offset_to_point2D(pos, false);
234  return result;
235 }
236 
237 
238 const MSLane*
239 TraCIServerAPI_Simulation::getLaneChecking(std::string roadID, int laneIndex, SUMOReal pos) {
240  const MSEdge* edge = MSEdge::dictionary(roadID);
241  if (edge == 0) {
242  throw TraCIException("Unknown edge " + roadID);
243  }
244  if (laneIndex < 0 || laneIndex >= (int)edge->getLanes().size()) {
245  throw TraCIException("Invalid lane index for " + roadID);
246  }
247  const MSLane* lane = edge->getLanes()[laneIndex];
248  if (pos < 0 || pos > lane->getLength()) {
249  throw TraCIException("Position on lane invalid");
250  }
251  return lane;
252 }
253 
254 
255 bool
257  tcpip::Storage& outputStorage, int commandId) {
258  std::pair<MSLane*, SUMOReal> roadPos;
259  Position cartesianPos;
260  Position geoPos;
261  SUMOReal z = 0;
262 
263  // actual position type that will be converted
264  int srcPosType = inputStorage.readUnsignedByte();
265 
266  switch (srcPosType) {
267  case POSITION_2D:
268  case POSITION_3D:
269  case POSITION_LON_LAT:
270  case POSITION_LON_LAT_ALT: {
271  SUMOReal x = inputStorage.readDouble();
272  SUMOReal y = inputStorage.readDouble();
273  if (srcPosType != POSITION_2D && srcPosType != POSITION_LON_LAT) {
274  z = inputStorage.readDouble();
275  }
276  geoPos.set(x, y);
277  cartesianPos.set(x, y);
278  if (srcPosType == POSITION_LON_LAT || srcPosType == POSITION_LON_LAT_ALT) {
280  } else {
282  }
283  }
284  break;
285  case POSITION_ROADMAP: {
286  std::string roadID = inputStorage.readString();
287  SUMOReal pos = inputStorage.readDouble();
288  int laneIdx = inputStorage.readUnsignedByte();
289  try {
290  cartesianPos = geoPos = getLaneChecking(roadID, laneIdx, pos)->getShape().positionAtOffset(pos);
292  } catch (TraCIException& e) {
293  server.writeStatusCmd(commandId, RTYPE_ERR, e.what());
294  return false;
295  }
296  }
297  break;
298  default:
299  server.writeStatusCmd(commandId, RTYPE_ERR, "Source position type not supported");
300  return false;
301  }
302 
303  int destPosType = 0;
304  if (!server.readTypeCheckingUnsignedByte(inputStorage, destPosType)) {
305  server.writeStatusCmd(commandId, RTYPE_ERR, "Destination position type must be of type ubyte.");
306  return false;
307  }
308 
309  switch (destPosType) {
310  case POSITION_ROADMAP: {
311  // convert road map to 3D position
312  roadPos = convertCartesianToRoadMap(cartesianPos);
313  // write result that is added to response msg
314  outputStorage.writeUnsignedByte(POSITION_ROADMAP);
315  outputStorage.writeString(roadPos.first->getEdge().getID());
316  outputStorage.writeDouble(roadPos.second);
317  const std::vector<MSLane*> lanes = roadPos.first->getEdge().getLanes();
318  outputStorage.writeUnsignedByte((int)distance(lanes.begin(), find(lanes.begin(), lanes.end(), roadPos.first)));
319  }
320  break;
321  case POSITION_2D:
322  case POSITION_3D:
323  case POSITION_LON_LAT:
325  outputStorage.writeUnsignedByte(destPosType);
326  if (destPosType == POSITION_LON_LAT || destPosType == POSITION_LON_LAT_ALT) {
327  outputStorage.writeDouble(geoPos.x());
328  outputStorage.writeDouble(geoPos.y());
329  } else {
330  outputStorage.writeDouble(cartesianPos.x());
331  outputStorage.writeDouble(cartesianPos.y());
332  }
333  if (destPosType != POSITION_2D && destPosType != POSITION_LON_LAT) {
334  outputStorage.writeDouble(z);
335  }
336  break;
337  default:
338  server.writeStatusCmd(commandId, RTYPE_ERR, "Destination position type not supported");
339  return false;
340  }
341  return true;
342 }
343 
344 /****************************************************************************/
345 
346 bool
348  tcpip::Storage& outputStorage, int commandId) {
349  Position pos1;
350  Position pos2;
351  std::pair<const MSLane*, SUMOReal> roadPos1;
352  std::pair<const MSLane*, SUMOReal> roadPos2;
353 
354  // read position 1
355  int posType = inputStorage.readUnsignedByte();
356  switch (posType) {
357  case POSITION_ROADMAP:
358  try {
359  std::string roadID = inputStorage.readString();
360  roadPos1.second = inputStorage.readDouble();
361  roadPos1.first = getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos1.second);
362  pos1 = roadPos1.first->getShape().positionAtOffset(roadPos1.second);
363  } catch (TraCIException& e) {
364  server.writeStatusCmd(commandId, RTYPE_ERR, e.what());
365  return false;
366  }
367  break;
368  case POSITION_2D:
369  case POSITION_3D: {
370  SUMOReal p1x = inputStorage.readDouble();
371  SUMOReal p1y = inputStorage.readDouble();
372  pos1.set(p1x, p1y);
373  }
374  if (posType == POSITION_3D) {
375  inputStorage.readDouble(); // z value is ignored
376  }
377  roadPos1 = convertCartesianToRoadMap(pos1);
378  break;
379  default:
380  server.writeStatusCmd(commandId, RTYPE_ERR, "Unknown position format used for distance request");
381  return false;
382  }
383 
384  // read position 2
385  posType = inputStorage.readUnsignedByte();
386  switch (posType) {
387  case POSITION_ROADMAP:
388  try {
389  std::string roadID = inputStorage.readString();
390  roadPos2.second = inputStorage.readDouble();
391  roadPos2.first = getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos2.second);
392  pos2 = roadPos2.first->getShape().positionAtOffset(roadPos2.second);
393  } catch (TraCIException& e) {
394  server.writeStatusCmd(commandId, RTYPE_ERR, e.what());
395  return false;
396  }
397  break;
398  case POSITION_2D:
399  case POSITION_3D: {
400  SUMOReal p2x = inputStorage.readDouble();
401  SUMOReal p2y = inputStorage.readDouble();
402  pos2.set(p2x, p2y);
403  }
404  if (posType == POSITION_3D) {
405  inputStorage.readDouble(); // z value is ignored
406  }
407  roadPos2 = convertCartesianToRoadMap(pos2);
408  break;
409  default:
410  server.writeStatusCmd(commandId, RTYPE_ERR, "Unknown position format used for distance request");
411  return false;
412  }
413 
414  // read distance type
415  int distType = inputStorage.readUnsignedByte();
416 
417  SUMOReal distance = 0.0;
418  if (distType == REQUEST_DRIVINGDIST) {
419  // compute driving distance
420  if ((roadPos1.first == roadPos2.first) && (roadPos1.second <= roadPos2.second)) {
421  // same edge
422  distance = roadPos2.second - roadPos1.second;
423  } else {
424  MSEdgeVector newRoute;
426  &roadPos1.first->getEdge(), &roadPos2.first->getEdge(), 0, MSNet::getInstance()->getCurrentTimeStep(), newRoute);
427  MSRoute route("", newRoute, false, 0, std::vector<SUMOVehicleParameter::Stop>());
428  distance = route.getDistanceBetween(roadPos1.second, roadPos2.second, &roadPos1.first->getEdge(), &roadPos2.first->getEdge());
429  }
430  } else {
431  // compute air distance (default)
432  distance = pos1.distanceTo(pos2);
433  }
434  // write response command
435  outputStorage.writeUnsignedByte(TYPE_DOUBLE);
436  outputStorage.writeDouble(distance);
437  return true;
438 }
439 
440 #endif
441 
442 /****************************************************************************/
The vehicle has departed (was inserted into the network)
Definition: MSNet.h:409
#define VAR_TIME_STEP
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
#define REQUEST_DRIVINGDIST
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation. ...
#define TYPE_COMPOUND
#define POSITION_2D
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:167
static const MSLane * getLaneChecking(std::string roadID, int laneIndex, SUMOReal pos)
std::vector< std::string > getEdgeNames() const
Returns the list of names of all known edges.
SUMOReal ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:124
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:360
#define POSITION_LON_LAT_ALT
#define RTYPE_OK
#define POSITION_ROADMAP
#define DISTANCE_REQUEST
virtual double readDouble()
SUMOReal xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:112
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
#define VAR_LOADED_VEHICLES_IDS
static bool processGet(traci::TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xaa: Get Edge Variable)
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:150
#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:461
#define VAR_TELEPORT_STARTING_VEHICLES_IDS
static std::pair< MSLane *, SUMOReal > convertCartesianToRoadMap(Position pos)
SUMOReal distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:208
virtual void writeUnsignedByte(int)
SUMOReal getDistanceBetween(SUMOReal fromPos, SUMOReal toPos, const MSEdge *fromEdge, const MSEdge *toEdge) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:250
#define POSITION_LON_LAT
SUMOTime getCurrentTimeStep() const
Returns the current simulation step (in s)
Definition: MSNet.cpp:500
#define VAR_LOADED_VEHICLES_NUMBER
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
SUMOReal xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:118
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
virtual void writeInt(int)
virtual int readUnsignedByte()
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:76
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
#define POSITION_CONVERSION
A road/street connecting two junctions.
Definition: MSEdge.h:73
#define VAR_DEPARTED_VEHICLES_NUMBER
#define max(a, b)
Definition: polyfonts.c:61
#define VAR_MIN_EXPECTED_VEHICLES
The vehicle arrived at his destination (is deleted)
Definition: MSNet.h:415
virtual int readInt()
std::vector< const MSEdge * > MSEdgeVector
Definition: MSPerson.h:53
#define VAR_NET_BOUNDING_BOX
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
A lane area vehicles can halt at.
Definition: MSBusStop.h:63
#define VAR_TELEPORT_STARTING_VEHICLES_NUMBER
#define TYPE_BOUNDINGBOX
virtual void writeStringList(const std::vector< std::string > &s)
#define VAR_TELEPORT_ENDING_VEHICLES_IDS
The vehicle started to teleport.
Definition: MSNet.h:411
#define CMD_GET_SIM_VARIABLE
virtual std::string readString()
#define VAR_DEPARTED_VEHICLES_IDS
MSBusStop * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:684
const Boundary & getConvBoundary() const
Returns the converted boundary.
#define VAR_DELTA_T
The vehicle was built, but has not yet departed.
Definition: MSNet.h:407
#define VAR_ARRIVED_VEHICLES_NUMBER
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
virtual void writeString(const std::string &s)
#define TYPE_DOUBLE
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
void set(SUMOReal x, SUMOReal y)
Definition: Position.h:78
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const std::vector< MSEdge * > &prohibited=std::vector< MSEdge * >()) const
Definition: MSNet.cpp:703
virtual void writeDouble(double)
#define VAR_TELEPORT_ENDING_VEHICLES_NUMBER
#define SUMOReal
Definition: config.h:221
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...
static bool commandPositionConversion(traci::TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage, int commandId)
SUMOReal ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:130
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:269
static bool commandDistanceRequest(traci::TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage, int commandId)
#define DELTA_T
Definition: SUMOTime.h:50
const std::map< MSNet::VehicleState, std::vector< std::string > > & getVehicleStateChanges() const
Definition: TraCIServer.h:162
bool readTypeCheckingUnsignedByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and an unsigned byte, verifying the type.
#define RTYPE_ERR
unsigned int getPersonNumber() const
Returns the number of persons waiting on this stop.
Definition: MSBusStop.h:139
#define TYPE_INTEGER
Representation of a lane in the micro simulation.
Definition: MSLane.h:73
#define VAR_ARRIVED_VEHICLES_IDS
The vehicle ended being teleported.
Definition: MSNet.h:413
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
#define VAR_BUS_STOP_WAITING