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-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  for (MSLinkCont::const_iterator i = links.begin(); i != links.end(); ++i) {
121  MSLink* link = (*i);
122  // approached non-internal lane (if any)
123  tempContent.writeUnsignedByte(TYPE_STRING);
124  tempContent.writeString(link->getLane() != 0 ? link->getLane()->getID() : "");
125  ++cnt;
126  // approached "via", internal lane (if any)
127  tempContent.writeUnsignedByte(TYPE_STRING);
128 #ifdef HAVE_INTERNAL_LANES
129  tempContent.writeString(link->getViaLane() != 0 ? link->getViaLane()->getID() : "");
130 #else
131  tempContent.writeString("");
132 #endif
133  ++cnt;
134  // priority
135  tempContent.writeUnsignedByte(TYPE_UBYTE);
136  tempContent.writeUnsignedByte(link->havePriority() ? 1 : 0);
137  ++cnt;
138  // opened
139  tempContent.writeUnsignedByte(TYPE_UBYTE);
140  tempContent.writeUnsignedByte(link->opened(MSNet::getInstance()->getCurrentTimeStep(), 0, 0, 0.) ? 1 : 0);
141  ++cnt;
142  // approaching foe
143  tempContent.writeUnsignedByte(TYPE_UBYTE);
145  ++cnt;
146  // state (not implemented, yet)
147  tempContent.writeUnsignedByte(TYPE_STRING);
148  tempContent.writeString("");
149  ++cnt;
150  // direction (not implemented, yet)
151  tempContent.writeUnsignedByte(TYPE_STRING);
152  tempContent.writeString("");
153  ++cnt;
154  // length
155  tempContent.writeUnsignedByte(TYPE_DOUBLE);
156  tempContent.writeDouble(link->getLength());
157  ++cnt;
158  }
159  tempMsg.writeInt((int) cnt);
160  tempMsg.writeStorage(tempContent);
161  }
162  break;
163  case LANE_ALLOWED: {
165  SVCPermissions permissions = lane->getPermissions();
166  if (permissions == SVCFreeForAll) { // special case: write nothing
167  permissions = 0;
168  }
169  tempMsg.writeStringList(getAllowedVehicleClassNamesList(permissions));
170  }
171  case LANE_DISALLOWED: {
173  tempMsg.writeStringList(getAllowedVehicleClassNamesList(~(lane->getPermissions()))); // negation yields disallowed
174  }
175  break;
176  case VAR_SHAPE:
178  tempMsg.writeUnsignedByte((int)MIN2(static_cast<size_t>(255), lane->getShape().size()));
179  for (unsigned int iPoint = 0; iPoint < MIN2(static_cast<size_t>(255), lane->getShape().size()); ++iPoint) {
180  tempMsg.writeDouble(lane->getShape()[iPoint].x());
181  tempMsg.writeDouble(lane->getShape()[iPoint].y());
182  }
183  break;
184  case VAR_CO2EMISSION:
186  tempMsg.writeDouble(lane->getHBEFA_CO2Emissions());
187  break;
188  case VAR_COEMISSION:
190  tempMsg.writeDouble(lane->getHBEFA_COEmissions());
191  break;
192  case VAR_HCEMISSION:
194  tempMsg.writeDouble(lane->getHBEFA_HCEmissions());
195  break;
196  case VAR_PMXEMISSION:
198  tempMsg.writeDouble(lane->getHBEFA_PMxEmissions());
199  break;
200  case VAR_NOXEMISSION:
202  tempMsg.writeDouble(lane->getHBEFA_NOxEmissions());
203  break;
204  case VAR_FUELCONSUMPTION:
206  tempMsg.writeDouble(lane->getHBEFA_FuelConsumption());
207  break;
208  case VAR_NOISEEMISSION:
210  tempMsg.writeDouble(lane->getHarmonoise_NoiseEmissions());
211  break;
214  tempMsg.writeInt((int) lane->getVehicleNumber());
215  break;
218  tempMsg.writeDouble(lane->getMeanSpeed());
219  break;
221  std::vector<std::string> vehIDs;
222  const std::deque<MSVehicle*>& vehs = lane->getVehiclesSecure();
223  for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
224  vehIDs.push_back((*j)->getID());
225  }
226  lane->releaseVehicles();
228  tempMsg.writeStringList(vehIDs);
229  }
230  break;
231  case LAST_STEP_OCCUPANCY:
233  tempMsg.writeDouble(lane->getOccupancy());
234  break;
236  int halting = 0;
237  const std::deque<MSVehicle*>& vehs = lane->getVehiclesSecure();
238  for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
239  if ((*j)->getSpeed() < 0.1) {
240  ++halting;
241  }
242  }
243  lane->releaseVehicles();
245  tempMsg.writeInt(halting);
246  }
247  break;
248  case LAST_STEP_LENGTH: {
249  SUMOReal lengthSum = 0;
250  const std::deque<MSVehicle*>& vehs = lane->getVehiclesSecure();
251  for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
252  lengthSum += (*j)->getVehicleType().getLength();
253  }
255  if (vehs.size() == 0) {
256  tempMsg.writeDouble(0);
257  } else {
258  tempMsg.writeDouble(lengthSum / (SUMOReal) vehs.size());
259  }
260  lane->releaseVehicles();
261  }
262  break;
263  case VAR_CURRENT_TRAVELTIME: {
264  SUMOReal meanSpeed = lane->getMeanSpeed();
266  if (meanSpeed != 0) {
267  tempMsg.writeDouble(lane->getLength() / meanSpeed);
268  } else {
269  tempMsg.writeDouble(1000000.);
270  }
271  }
272  break;
273  case VAR_WIDTH:
275  tempMsg.writeDouble(lane->getWidth());
276  break;
277  default:
278  break;
279  }
280  }
281  server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_OK, "", outputStorage);
282  server.writeResponseWithLength(outputStorage, tempMsg);
283  return true;
284 }
285 
286 
287 bool
289  tcpip::Storage& outputStorage) {
290  std::string warning = ""; // additional description for response
291  // variable
292  int variable = inputStorage.readUnsignedByte();
293  if (variable != VAR_MAXSPEED && variable != VAR_LENGTH && variable != LANE_ALLOWED && variable != LANE_DISALLOWED) {
294  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Change Lane State: unsupported variable specified", outputStorage);
295  }
296  // id
297  std::string id = inputStorage.readString();
298  MSLane* l = MSLane::dictionary(id);
299  if (l == 0) {
300  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Lane '" + id + "' is not known", outputStorage);
301  }
302  // process
303  switch (variable) {
304  case VAR_MAXSPEED: {
305  double value = 0;
306  if (!server.readTypeCheckingDouble(inputStorage, value)) {
307  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "The speed must be given as a double.", outputStorage);
308  }
309  l->setMaxSpeed(value);
310  }
311  break;
312  case VAR_LENGTH: {
313  double value = 0;
314  if (!server.readTypeCheckingDouble(inputStorage, value)) {
315  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "The length must be given as a double.", outputStorage);
316  }
317  l->setLength(value);
318  }
319  break;
320  case LANE_ALLOWED: {
321  std::vector<std::string> classes;
322  if (!server.readTypeCheckingStringList(inputStorage, classes)) {
323  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Allowed classes must be given as a list of strings.", outputStorage);
324  }
325  l->setPermissions(parseVehicleClasses(classes));
327  }
328  break;
329  case LANE_DISALLOWED: {
330  std::vector<std::string> classes;
331  if (!server.readTypeCheckingStringList(inputStorage, classes)) {
332  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Not allowed classes must be given as a list of strings.", outputStorage);
333  }
334  l->setPermissions(~parseVehicleClasses(classes)); // negation yields allowed
336  }
337  break;
338  default:
339  break;
340  }
341  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_OK, warning, outputStorage);
342  return true;
343 }
344 
345 
346 bool
347 TraCIServerAPI_Lane::getShape(const std::string& id, PositionVector& shape) {
348  const MSLane* const l = MSLane::dictionary(id);
349  if (l == 0) {
350  return false;
351  }
352  shape.push_back(l->getShape());
353  return true;
354 }
355 
356 
357 TraCIRTree*
359  TraCIRTree* t = new TraCIRTree();
360  const std::vector<MSEdge*>& edges = MSNet::getInstance()->getEdgeControl().getEdges();
361  for (std::vector<MSEdge*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
362  const std::vector<MSLane*>& lanes = (*i)->getLanes();
363  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
364  Boundary b = (*j)->getShape().getBoxBoundary();
365  b.grow(3.);
366  t->addObject(*j, b);
367  }
368  }
369  return t;
370 }
371 
372 #endif
373 
374 
375 /****************************************************************************/
376