SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TraCIServerAPI_Lane.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // APIs for getting/setting lane 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 <microsim/MSEdge.h>
37 #include <microsim/MSEdgeControl.h>
38 #include <microsim/MSLane.h>
39 #include <microsim/MSNet.h>
40 #include "TraCIConstants.h"
41 #include "TraCIServerAPI_Lane.h"
42 
43 #ifdef CHECK_MEMORY_LEAKS
44 #include <foreign/nvwa/debug_new.h>
45 #endif // CHECK_MEMORY_LEAKS
46 
47 
48 // ===========================================================================
49 // used namespaces
50 // ===========================================================================
51 using namespace traci;
52 
53 
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
57 bool
59  tcpip::Storage& outputStorage) {
60  // variable
61  int variable = inputStorage.readUnsignedByte();
62  std::string id = inputStorage.readString();
63  // check variable
64  if (variable != ID_LIST && variable != LANE_LINK_NUMBER && variable != LANE_EDGE_ID && variable != VAR_LENGTH
65  && variable != VAR_MAXSPEED && variable != LANE_LINKS && variable != VAR_SHAPE
66  && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION
67  && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION
68  && variable != LAST_STEP_MEAN_SPEED && variable != LAST_STEP_VEHICLE_NUMBER
69  && variable != LAST_STEP_VEHICLE_ID_LIST && variable != LAST_STEP_OCCUPANCY && variable != LAST_STEP_VEHICLE_HALTING_NUMBER
70  && variable != LAST_STEP_LENGTH && variable != VAR_CURRENT_TRAVELTIME
71  && variable != LANE_ALLOWED && variable != LANE_DISALLOWED && variable != VAR_WIDTH && variable != ID_COUNT) {
72  return server.writeErrorStatusCmd(CMD_GET_LANE_VARIABLE, "Get Lane Variable: unsupported variable specified", outputStorage);
73  }
74  // begin response building
75  tcpip::Storage tempMsg;
76  // response-code, variableID, objectID
78  tempMsg.writeUnsignedByte(variable);
79  tempMsg.writeString(id);
80  if (variable == ID_LIST) {
81  std::vector<std::string> ids;
82  MSLane::insertIDs(ids);
84  tempMsg.writeStringList(ids);
85  } else if (variable == ID_COUNT) {
86  std::vector<std::string> ids;
87  MSLane::insertIDs(ids);
89  tempMsg.writeInt((int) ids.size());
90  } else {
91  MSLane* lane = MSLane::dictionary(id);
92  if (lane == 0) {
93  return server.writeErrorStatusCmd(CMD_GET_LANE_VARIABLE, "Lane '" + id + "' is not known", outputStorage);
94  }
95  switch (variable) {
96  case LANE_LINK_NUMBER:
98  tempMsg.writeUnsignedByte((int) lane->getLinkCont().size());
99  break;
100  case LANE_EDGE_ID:
102  tempMsg.writeString(lane->getEdge().getID());
103  break;
104  case VAR_LENGTH:
106  tempMsg.writeDouble(lane->getLength());
107  break;
108  case VAR_MAXSPEED:
110  tempMsg.writeDouble(lane->getSpeedLimit());
111  break;
112  case LANE_LINKS: {
114  tcpip::Storage tempContent;
115  unsigned int cnt = 0;
116  tempContent.writeUnsignedByte(TYPE_INTEGER);
117  const MSLinkCont& links = lane->getLinkCont();
118  tempContent.writeInt((int) links.size());
119  ++cnt;
120  const SUMOTime currTime = MSNet::getInstance()->getCurrentTimeStep();
121  for (MSLinkCont::const_iterator i = links.begin(); i != links.end(); ++i) {
122  MSLink* link = (*i);
123  // approached non-internal lane (if any)
124  tempContent.writeUnsignedByte(TYPE_STRING);
125  tempContent.writeString(link->getLane() != 0 ? link->getLane()->getID() : "");
126  ++cnt;
127  // approached "via", internal lane (if any)
128  tempContent.writeUnsignedByte(TYPE_STRING);
129 #ifdef HAVE_INTERNAL_LANES
130  tempContent.writeString(link->getViaLane() != 0 ? link->getViaLane()->getID() : "");
131 #else
132  tempContent.writeString("");
133 #endif
134  ++cnt;
135  // priority
136  tempContent.writeUnsignedByte(TYPE_UBYTE);
137  tempContent.writeUnsignedByte(link->havePriority() ? 1 : 0);
138  ++cnt;
139  // opened
140  tempContent.writeUnsignedByte(TYPE_UBYTE);
141  const SUMOReal speed = MIN2(lane->getSpeedLimit(), link->getLane()->getSpeedLimit());
142  tempContent.writeUnsignedByte(link->opened(currTime, speed, speed, DEFAULT_VEH_LENGTH, 0.0, DEFAULT_VEH_DECEL, 0) ? 1 : 0);
143  ++cnt;
144  // approaching foe
145  tempContent.writeUnsignedByte(TYPE_UBYTE);
146  tempContent.writeUnsignedByte(link->hasApproachingFoe(currTime, currTime, 0) ? 1 : 0);
147  ++cnt;
148  // state (not implemented, yet)
149  tempContent.writeUnsignedByte(TYPE_STRING);
150  tempContent.writeString(SUMOXMLDefinitions::LinkStates.getString(link->getState()));
151  ++cnt;
152  // direction
153  tempContent.writeUnsignedByte(TYPE_STRING);
154  tempContent.writeString(SUMOXMLDefinitions::LinkDirections.getString(link->getDirection()));
155  ++cnt;
156  // length
157  tempContent.writeUnsignedByte(TYPE_DOUBLE);
158  tempContent.writeDouble(link->getLength());
159  ++cnt;
160  }
161  tempMsg.writeInt((int) cnt);
162  tempMsg.writeStorage(tempContent);
163  }
164  break;
165  case LANE_ALLOWED: {
167  SVCPermissions permissions = lane->getPermissions();
168  if (permissions == SVCFreeForAll) { // special case: write nothing
169  permissions = 0;
170  }
171  tempMsg.writeStringList(getAllowedVehicleClassNamesList(permissions));
172  }
173  case LANE_DISALLOWED: {
175  tempMsg.writeStringList(getAllowedVehicleClassNamesList(~(lane->getPermissions()))); // negation yields disallowed
176  }
177  break;
178  case VAR_SHAPE:
180  tempMsg.writeUnsignedByte((int)MIN2(static_cast<size_t>(255), lane->getShape().size()));
181  for (unsigned int iPoint = 0; iPoint < MIN2(static_cast<size_t>(255), lane->getShape().size()); ++iPoint) {
182  tempMsg.writeDouble(lane->getShape()[iPoint].x());
183  tempMsg.writeDouble(lane->getShape()[iPoint].y());
184  }
185  break;
186  case VAR_CO2EMISSION:
188  tempMsg.writeDouble(lane->getHBEFA_CO2Emissions());
189  break;
190  case VAR_COEMISSION:
192  tempMsg.writeDouble(lane->getHBEFA_COEmissions());
193  break;
194  case VAR_HCEMISSION:
196  tempMsg.writeDouble(lane->getHBEFA_HCEmissions());
197  break;
198  case VAR_PMXEMISSION:
200  tempMsg.writeDouble(lane->getHBEFA_PMxEmissions());
201  break;
202  case VAR_NOXEMISSION:
204  tempMsg.writeDouble(lane->getHBEFA_NOxEmissions());
205  break;
206  case VAR_FUELCONSUMPTION:
208  tempMsg.writeDouble(lane->getHBEFA_FuelConsumption());
209  break;
210  case VAR_NOISEEMISSION:
212  tempMsg.writeDouble(lane->getHarmonoise_NoiseEmissions());
213  break;
216  tempMsg.writeInt((int) lane->getVehicleNumber());
217  break;
220  tempMsg.writeDouble(lane->getMeanSpeed());
221  break;
223  std::vector<std::string> vehIDs;
224  const MSLane::VehCont& vehs = lane->getVehiclesSecure();
225  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
226  vehIDs.push_back((*j)->getID());
227  }
228  lane->releaseVehicles();
230  tempMsg.writeStringList(vehIDs);
231  }
232  break;
233  case LAST_STEP_OCCUPANCY:
235  tempMsg.writeDouble(lane->getOccupancy());
236  break;
238  int halting = 0;
239  const MSLane::VehCont& vehs = lane->getVehiclesSecure();
240  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
241  if ((*j)->getSpeed() < SUMO_const_haltingSpeed) {
242  ++halting;
243  }
244  }
245  lane->releaseVehicles();
247  tempMsg.writeInt(halting);
248  }
249  break;
250  case LAST_STEP_LENGTH: {
251  SUMOReal lengthSum = 0;
252  const MSLane::VehCont& vehs = lane->getVehiclesSecure();
253  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
254  lengthSum += (*j)->getVehicleType().getLength();
255  }
257  if (vehs.size() == 0) {
258  tempMsg.writeDouble(0);
259  } else {
260  tempMsg.writeDouble(lengthSum / (SUMOReal) vehs.size());
261  }
262  lane->releaseVehicles();
263  }
264  break;
265  case VAR_CURRENT_TRAVELTIME: {
266  SUMOReal meanSpeed = lane->getMeanSpeed();
268  if (meanSpeed != 0) {
269  tempMsg.writeDouble(lane->getLength() / meanSpeed);
270  } else {
271  tempMsg.writeDouble(1000000.);
272  }
273  }
274  break;
275  case VAR_WIDTH:
277  tempMsg.writeDouble(lane->getWidth());
278  break;
279  default:
280  break;
281  }
282  }
283  server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_OK, "", outputStorage);
284  server.writeResponseWithLength(outputStorage, tempMsg);
285  return true;
286 }
287 
288 
289 bool
291  tcpip::Storage& outputStorage) {
292  std::string warning = ""; // additional description for response
293  // variable
294  int variable = inputStorage.readUnsignedByte();
295  if (variable != VAR_MAXSPEED && variable != VAR_LENGTH && variable != LANE_ALLOWED && variable != LANE_DISALLOWED) {
296  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Change Lane State: unsupported variable specified", outputStorage);
297  }
298  // id
299  std::string id = inputStorage.readString();
300  MSLane* l = MSLane::dictionary(id);
301  if (l == 0) {
302  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Lane '" + id + "' is not known", outputStorage);
303  }
304  // process
305  switch (variable) {
306  case VAR_MAXSPEED: {
307  double value = 0;
308  if (!server.readTypeCheckingDouble(inputStorage, value)) {
309  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "The speed must be given as a double.", outputStorage);
310  }
311  l->setMaxSpeed(value);
312  }
313  break;
314  case VAR_LENGTH: {
315  double value = 0;
316  if (!server.readTypeCheckingDouble(inputStorage, value)) {
317  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "The length must be given as a double.", outputStorage);
318  }
319  l->setLength(value);
320  }
321  break;
322  case LANE_ALLOWED: {
323  std::vector<std::string> classes;
324  if (!server.readTypeCheckingStringList(inputStorage, classes)) {
325  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Allowed classes must be given as a list of strings.", outputStorage);
326  }
327  l->setPermissions(parseVehicleClasses(classes));
329  }
330  break;
331  case LANE_DISALLOWED: {
332  std::vector<std::string> classes;
333  if (!server.readTypeCheckingStringList(inputStorage, classes)) {
334  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Not allowed classes must be given as a list of strings.", outputStorage);
335  }
336  l->setPermissions(~parseVehicleClasses(classes)); // negation yields allowed
338  }
339  break;
340  default:
341  break;
342  }
343  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_OK, warning, outputStorage);
344  return true;
345 }
346 
347 
348 bool
349 TraCIServerAPI_Lane::getShape(const std::string& id, PositionVector& shape) {
350  const MSLane* const l = MSLane::dictionary(id);
351  if (l == 0) {
352  return false;
353  }
354  shape.push_back(l->getShape());
355  return true;
356 }
357 
358 
359 TraCIRTree*
361  TraCIRTree* t = new TraCIRTree();
362  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
363  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
364  const std::vector<MSLane*>& lanes = (*i)->getLanes();
365  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
366  Boundary b = (*j)->getShape().getBoxBoundary();
367  b.grow(3.);
368  t->addObject(*j, b);
369  }
370  }
371  return t;
372 }
373 
374 #endif
375 
376 
377 /****************************************************************************/
378