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.sourceforge.net/
13 // Copyright (C) 2001-2012 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  server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_ERR, "Get Lane Variable: unsupported variable specified", outputStorage);
73  return false;
74  }
75  // begin response building
76  tcpip::Storage tempMsg;
77  // response-code, variableID, objectID
79  tempMsg.writeUnsignedByte(variable);
80  tempMsg.writeString(id);
81  if (variable == ID_LIST) {
82  std::vector<std::string> ids;
83  MSLane::insertIDs(ids);
85  tempMsg.writeStringList(ids);
86  } else if (variable == ID_COUNT) {
87  std::vector<std::string> ids;
88  MSLane::insertIDs(ids);
90  tempMsg.writeInt((int) ids.size());
91  } else {
92  MSLane* lane = MSLane::dictionary(id);
93  if (lane == 0) {
94  server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_ERR, "Lane '" + id + "' is not known", outputStorage);
95  return false;
96  }
97  switch (variable) {
98  case LANE_LINK_NUMBER:
100  tempMsg.writeUnsignedByte((int) lane->getLinkCont().size());
101  break;
102  case LANE_EDGE_ID:
104  tempMsg.writeString(lane->getEdge().getID());
105  break;
106  case VAR_LENGTH:
108  tempMsg.writeDouble(lane->getLength());
109  break;
110  case VAR_MAXSPEED:
112  tempMsg.writeDouble(lane->getSpeedLimit());
113  break;
114  case LANE_LINKS: {
116  tcpip::Storage tempContent;
117  unsigned int cnt = 0;
118  tempContent.writeUnsignedByte(TYPE_INTEGER);
119  const MSLinkCont& links = lane->getLinkCont();
120  tempContent.writeInt((int) links.size());
121  ++cnt;
122  for (MSLinkCont::const_iterator i = links.begin(); i != links.end(); ++i) {
123  MSLink* link = (*i);
124  // approached non-internal lane (if any)
125  tempContent.writeUnsignedByte(TYPE_STRING);
126  tempContent.writeString(link->getLane() != 0 ? link->getLane()->getID() : "");
127  ++cnt;
128  // approached "via", internal lane (if any)
129  tempContent.writeUnsignedByte(TYPE_STRING);
130 #ifdef HAVE_INTERNAL_LANES
131  tempContent.writeString(link->getViaLane() != 0 ? link->getViaLane()->getID() : "");
132 #else
133  tempContent.writeString("");
134 #endif
135  ++cnt;
136  // priority
137  tempContent.writeUnsignedByte(TYPE_UBYTE);
138  tempContent.writeUnsignedByte(link->havePriority() ? 1 : 0);
139  ++cnt;
140  // opened
141  tempContent.writeUnsignedByte(TYPE_UBYTE);
142  tempContent.writeUnsignedByte(link->opened(MSNet::getInstance()->getCurrentTimeStep(), 0, 0, 0.) ? 1 : 0);
143  ++cnt;
144  // approaching foe
145  tempContent.writeUnsignedByte(TYPE_UBYTE);
147  ++cnt;
148  // state (not implemented, yet)
149  tempContent.writeUnsignedByte(TYPE_STRING);
150  tempContent.writeString("");
151  ++cnt;
152  // direction (not implemented, yet)
153  tempContent.writeUnsignedByte(TYPE_STRING);
154  tempContent.writeString("");
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 std::deque<MSVehicle*>& vehs = lane->getVehiclesSecure();
225  for (std::deque<MSVehicle*>::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 std::deque<MSVehicle*>& vehs = lane->getVehiclesSecure();
240  for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
241  if ((*j)->getSpeed() < 0.1) {
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 std::deque<MSVehicle*>& vehs = lane->getVehiclesSecure();
253  for (std::deque<MSVehicle*>::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  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Change Lane State: unsupported variable specified", outputStorage);
297  return false;
298  }
299  // id
300  std::string id = inputStorage.readString();
301  MSLane* l = MSLane::dictionary(id);
302  if (l == 0) {
303  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Lane '" + id + "' is not known", outputStorage);
304  return false;
305  }
306  // process
307  int valueDataType = inputStorage.readUnsignedByte();
308  switch (variable) {
309  case VAR_MAXSPEED: {
310  // speed
311  if (valueDataType != TYPE_DOUBLE) {
312  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "The speed must be given as a double.", outputStorage);
313  return false;
314  }
315  SUMOReal val = inputStorage.readDouble();
316  l->setMaxSpeed(val);
317  }
318  break;
319  case VAR_LENGTH: {
320  // speed
321  if (valueDataType != TYPE_DOUBLE) {
322  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "The length must be given as a double.", outputStorage);
323  return false;
324  }
325  SUMOReal val = inputStorage.readDouble();
326  l->setLength(val);
327  }
328  break;
329  case LANE_ALLOWED: {
330  if (valueDataType != TYPE_STRINGLIST) {
331  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Allowed classes must be given as a list of strings.", outputStorage);
332  return false;
333  }
336  }
337  break;
338  case LANE_DISALLOWED: {
339  if (valueDataType != TYPE_STRINGLIST) {
340  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Not allowed classes must be given as a list of strings.", outputStorage);
341  return false;
342  }
343  l->setPermissions(~parseVehicleClasses(inputStorage.readStringList())); // negation yields allowed
345  }
346  break;
347  default:
348  break;
349  }
350  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_OK, warning, outputStorage);
351  return true;
352 }
353 
354 
355 bool
356 TraCIServerAPI_Lane::getShape(const std::string& id, PositionVector& shape) {
357  const MSLane* const l = MSLane::dictionary(id);
358  if (l == 0) {
359  return false;
360  }
361  shape.push_back(l->getShape());
362  return true;
363 }
364 
365 
366 TraCIRTree*
368  TraCIRTree* t = new TraCIRTree();
369  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
370  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
371  const std::vector<MSLane*>& lanes = (*i)->getLanes();
372  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
373  Boundary b = (*j)->getShape().getBoxBoundary();
374  t->addObject(*j, b);
375  }
376  }
377  return t;
378 }
379 
380 #endif
381 
382 
383 /****************************************************************************/
384