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/MSLane.h>
38 #include "TraCIConstants.h"
39 #include "TraCIServerAPI_Lane.h"
40 
41 #ifdef CHECK_MEMORY_LEAKS
42 #include <foreign/nvwa/debug_new.h>
43 #endif // CHECK_MEMORY_LEAKS
44 
45 
46 // ===========================================================================
47 // used namespaces
48 // ===========================================================================
49 using namespace traci;
50 
51 
52 // ===========================================================================
53 // method definitions
54 // ===========================================================================
55 bool
57  tcpip::Storage& outputStorage) {
58  std::string warning = ""; // additional description for response
59  // variable
60  int variable = inputStorage.readUnsignedByte();
61  std::string id = inputStorage.readString();
62  // check variable
63  if (variable != ID_LIST && variable != LANE_LINK_NUMBER && variable != LANE_EDGE_ID && variable != VAR_LENGTH
64  && variable != VAR_MAXSPEED && variable != LANE_LINKS && variable != VAR_SHAPE
65  && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION
66  && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION
67  && variable != LAST_STEP_MEAN_SPEED && variable != LAST_STEP_VEHICLE_NUMBER
68  && variable != LAST_STEP_VEHICLE_ID_LIST && variable != LAST_STEP_OCCUPANCY && variable != LAST_STEP_VEHICLE_HALTING_NUMBER
69  && variable != LAST_STEP_LENGTH && variable != VAR_CURRENT_TRAVELTIME
70  && variable != LANE_ALLOWED && variable != LANE_DISALLOWED && variable != VAR_WIDTH && variable != ID_COUNT) {
71  server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_ERR, "Get Lane Variable: unsupported variable specified", outputStorage);
72  return false;
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  server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_ERR, "Lane '" + id + "' is not known", outputStorage);
94  return false;
95  }
96  switch (variable) {
97  case LANE_LINK_NUMBER:
99  tempMsg.writeUnsignedByte((int) lane->getLinkCont().size());
100  break;
101  case LANE_EDGE_ID:
103  tempMsg.writeString(lane->getEdge().getID());
104  break;
105  case VAR_LENGTH:
107  tempMsg.writeDouble(lane->getLength());
108  break;
109  case VAR_MAXSPEED:
111  tempMsg.writeDouble(lane->getMaxSpeed());
112  break;
113  case LANE_LINKS: {
115  tcpip::Storage tempContent;
116  unsigned int cnt = 0;
117  tempContent.writeUnsignedByte(TYPE_INTEGER);
118  const MSLinkCont& links = lane->getLinkCont();
119  tempContent.writeInt((int) links.size());
120  ++cnt;
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);
142  ++cnt;
143  // approaching foe
144  tempContent.writeUnsignedByte(TYPE_UBYTE);
146  ++cnt;
147  // state (not implemented, yet)
148  tempContent.writeUnsignedByte(TYPE_STRING);
149  tempContent.writeString("");
150  ++cnt;
151  // direction (not implemented, yet)
152  tempContent.writeUnsignedByte(TYPE_STRING);
153  tempContent.writeString("");
154  ++cnt;
155  // length
156  tempContent.writeUnsignedByte(TYPE_DOUBLE);
157  tempContent.writeDouble(link->getLength());
158  ++cnt;
159  }
160  tempMsg.writeInt((int) cnt);
161  tempMsg.writeStorage(tempContent);
162  }
163  break;
164  case LANE_ALLOWED: {
166  SVCPermissions permissions = lane->getPermissions();
167  if (permissions == SVCFreeForAll) { // special case: write nothing
168  permissions = 0;
169  }
170  tempMsg.writeStringList(getAllowedVehicleClassNamesList(permissions));
171  }
172  case LANE_DISALLOWED: {
174  tempMsg.writeStringList(getAllowedVehicleClassNamesList(~(lane->getPermissions()))); // negation yields disallowed
175  }
176  break;
177  case VAR_SHAPE:
179  tempMsg.writeUnsignedByte((int)MIN2(static_cast<size_t>(255), lane->getShape().size()));
180  for (unsigned int iPoint = 0; iPoint < MIN2(static_cast<size_t>(255), lane->getShape().size()); ++iPoint) {
181  tempMsg.writeDouble(lane->getShape()[iPoint].x());
182  tempMsg.writeDouble(lane->getShape()[iPoint].y());
183  }
184  break;
185  case VAR_CO2EMISSION:
187  tempMsg.writeDouble(lane->getHBEFA_CO2Emissions());
188  break;
189  case VAR_COEMISSION:
191  tempMsg.writeDouble(lane->getHBEFA_COEmissions());
192  break;
193  case VAR_HCEMISSION:
195  tempMsg.writeDouble(lane->getHBEFA_HCEmissions());
196  break;
197  case VAR_PMXEMISSION:
199  tempMsg.writeDouble(lane->getHBEFA_PMxEmissions());
200  break;
201  case VAR_NOXEMISSION:
203  tempMsg.writeDouble(lane->getHBEFA_NOxEmissions());
204  break;
205  case VAR_FUELCONSUMPTION:
207  tempMsg.writeDouble(lane->getHBEFA_FuelConsumption());
208  break;
209  case VAR_NOISEEMISSION:
211  tempMsg.writeDouble(lane->getHarmonoise_NoiseEmissions());
212  break;
215  tempMsg.writeInt((int) lane->getVehicleNumber());
216  break;
219  tempMsg.writeDouble(lane->getMeanSpeed());
220  break;
222  std::vector<std::string> vehIDs;
223  const std::deque<MSVehicle*> &vehs = lane->getVehiclesSecure();
224  for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
225  vehIDs.push_back((*j)->getID());
226  }
227  lane->releaseVehicles();
229  tempMsg.writeStringList(vehIDs);
230  }
231  break;
232  case LAST_STEP_OCCUPANCY:
234  tempMsg.writeDouble(lane->getOccupancy());
235  break;
237  int halting = 0;
238  const std::deque<MSVehicle*> &vehs = lane->getVehiclesSecure();
239  for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
240  if ((*j)->getSpeed() < 0.1) {
241  ++halting;
242  }
243  }
244  lane->releaseVehicles();
246  tempMsg.writeInt(halting);
247  }
248  break;
249  case LAST_STEP_LENGTH: {
250  SUMOReal lengthSum = 0;
251  const std::deque<MSVehicle*> &vehs = lane->getVehiclesSecure();
252  for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
253  lengthSum += (*j)->getVehicleType().getLength();
254  }
256  if (vehs.size() == 0) {
257  tempMsg.writeDouble(0);
258  } else {
259  tempMsg.writeDouble(lengthSum / (SUMOReal) vehs.size());
260  }
261  lane->releaseVehicles();
262  }
263  break;
264  case VAR_CURRENT_TRAVELTIME: {
265  SUMOReal meanSpeed = lane->getMeanSpeed();
267  if (meanSpeed != 0) {
268  tempMsg.writeDouble(lane->getLength() / meanSpeed);
269  } else {
270  tempMsg.writeDouble(1000000.);
271  }
272  }
273  break;
274  case VAR_WIDTH:
276  tempMsg.writeDouble(lane->getWidth());
277  break;
278  default:
279  break;
280  }
281  }
282  server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_OK, warning, outputStorage);
283  server.writeResponseWithLength(outputStorage, tempMsg);
284  return true;
285 }
286 
287 
288 bool
290  tcpip::Storage& outputStorage) {
291  std::string warning = ""; // additional description for response
292  // variable
293  int variable = inputStorage.readUnsignedByte();
294  if (variable != VAR_MAXSPEED && variable != VAR_LENGTH && variable != LANE_ALLOWED && variable != LANE_DISALLOWED) {
295  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Change Lane State: unsupported variable specified", outputStorage);
296  return false;
297  }
298  // id
299  std::string id = inputStorage.readString();
300  MSLane* l = MSLane::dictionary(id);
301  if (l == 0) {
302  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Lane '" + id + "' is not known", outputStorage);
303  return false;
304  }
305  // process
306  int valueDataType = inputStorage.readUnsignedByte();
307  switch (variable) {
308  case VAR_MAXSPEED: {
309  // speed
310  if (valueDataType != TYPE_DOUBLE) {
311  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "The speed must be given as a double.", outputStorage);
312  return false;
313  }
314  SUMOReal val = inputStorage.readDouble();
315  l->setMaxSpeed(val);
316  }
317  break;
318  case VAR_LENGTH: {
319  // speed
320  if (valueDataType != TYPE_DOUBLE) {
321  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "The length must be given as a double.", outputStorage);
322  return false;
323  }
324  SUMOReal val = inputStorage.readDouble();
325  l->setLength(val);
326  }
327  break;
328  case LANE_ALLOWED: {
329  if (valueDataType != TYPE_STRINGLIST) {
330  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Allowed classes must be given as a list of strings.", outputStorage);
331  return false;
332  }
335  }
336  break;
337  case LANE_DISALLOWED: {
338  if (valueDataType != TYPE_STRINGLIST) {
339  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Not allowed classes must be given as a list of strings.", outputStorage);
340  return false;
341  }
342  l->setPermissions(~parseVehicleClasses(inputStorage.readStringList())); // negation yields allowed
344  }
345  break;
346  default:
347  break;
348  }
349  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_OK, warning, outputStorage);
350  return true;
351 }
352 
353 #endif
354 
355 
356 /****************************************************************************/
357