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 /****************************************************************************/
11 // APIs for getting/setting lane values via TraCI
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
14 // Copyright (C) 2009-2014 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #ifndef NO_TRACI
36 
37 #include <microsim/MSEdge.h>
38 #include <microsim/MSEdgeControl.h>
39 #include <microsim/MSLane.h>
40 #include <microsim/MSNet.h>
41 #include "TraCIConstants.h"
42 #include "TraCIServer.h"
43 #include "TraCIServerAPI_Lane.h"
44 
45 #ifdef CHECK_MEMORY_LEAKS
46 #include <foreign/nvwa/debug_new.h>
47 #endif // CHECK_MEMORY_LEAKS
48 
49 
50 // ===========================================================================
51 // method definitions
52 // ===========================================================================
53 bool
55  tcpip::Storage& outputStorage) {
56  // variable
57  int variable = inputStorage.readUnsignedByte();
58  std::string id = inputStorage.readString();
59  // check variable
60  if (variable != ID_LIST && variable != LANE_LINK_NUMBER && variable != LANE_EDGE_ID && variable != VAR_LENGTH
61  && variable != VAR_MAXSPEED && variable != LANE_LINKS && variable != VAR_SHAPE
62  && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION
63  && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION && variable != VAR_WAITING_TIME
64  && variable != LAST_STEP_MEAN_SPEED && variable != LAST_STEP_VEHICLE_NUMBER
65  && variable != LAST_STEP_VEHICLE_ID_LIST && variable != LAST_STEP_OCCUPANCY && variable != LAST_STEP_VEHICLE_HALTING_NUMBER
66  && variable != LAST_STEP_LENGTH && variable != VAR_CURRENT_TRAVELTIME
67  && variable != LANE_ALLOWED && variable != LANE_DISALLOWED && variable != VAR_WIDTH && variable != ID_COUNT
68  ) {
69  return server.writeErrorStatusCmd(CMD_GET_LANE_VARIABLE, "Get Lane Variable: unsupported variable specified", outputStorage);
70  }
71  // begin response building
72  tcpip::Storage tempMsg;
73  // response-code, variableID, objectID
75  tempMsg.writeUnsignedByte(variable);
76  tempMsg.writeString(id);
77  if (variable == ID_LIST) {
78  std::vector<std::string> ids;
79  MSLane::insertIDs(ids);
81  tempMsg.writeStringList(ids);
82  } else if (variable == ID_COUNT) {
83  std::vector<std::string> ids;
84  MSLane::insertIDs(ids);
86  tempMsg.writeInt((int) ids.size());
87  } else {
88  MSLane* lane = MSLane::dictionary(id);
89  if (lane == 0) {
90  return server.writeErrorStatusCmd(CMD_GET_LANE_VARIABLE, "Lane '" + id + "' is not known", outputStorage);
91  }
92  switch (variable) {
93  case LANE_LINK_NUMBER:
95  tempMsg.writeUnsignedByte((int) lane->getLinkCont().size());
96  break;
97  case LANE_EDGE_ID:
99  tempMsg.writeString(lane->getEdge().getID());
100  break;
101  case VAR_LENGTH:
103  tempMsg.writeDouble(lane->getLength());
104  break;
105  case VAR_MAXSPEED:
107  tempMsg.writeDouble(lane->getSpeedLimit());
108  break;
109  case LANE_LINKS: {
111  tcpip::Storage tempContent;
112  unsigned int cnt = 0;
113  tempContent.writeUnsignedByte(TYPE_INTEGER);
114  const MSLinkCont& links = lane->getLinkCont();
115  tempContent.writeInt((int) links.size());
116  ++cnt;
117  const SUMOTime currTime = MSNet::getInstance()->getCurrentTimeStep();
118  for (MSLinkCont::const_iterator i = links.begin(); i != links.end(); ++i) {
119  MSLink* link = (*i);
120  // approached non-internal lane (if any)
121  tempContent.writeUnsignedByte(TYPE_STRING);
122  tempContent.writeString(link->getLane() != 0 ? link->getLane()->getID() : "");
123  ++cnt;
124  // approached "via", internal lane (if any)
125  tempContent.writeUnsignedByte(TYPE_STRING);
126 #ifdef HAVE_INTERNAL_LANES
127  tempContent.writeString(link->getViaLane() != 0 ? link->getViaLane()->getID() : "");
128 #else
129  tempContent.writeString("");
130 #endif
131  ++cnt;
132  // priority
133  tempContent.writeUnsignedByte(TYPE_UBYTE);
134  tempContent.writeUnsignedByte(link->havePriority() ? 1 : 0);
135  ++cnt;
136  // opened
137  tempContent.writeUnsignedByte(TYPE_UBYTE);
138  const SUMOReal speed = MIN2(lane->getSpeedLimit(), link->getLane()->getSpeedLimit());
139  tempContent.writeUnsignedByte(link->opened(currTime, speed, speed, SUMOVTypeParameter::getDefault().length,
141  ++cnt;
142  // approaching foe
143  tempContent.writeUnsignedByte(TYPE_UBYTE);
144  tempContent.writeUnsignedByte(link->hasApproachingFoe(currTime, currTime, 0, SUMOVTypeParameter::getDefaultDecel()) ? 1 : 0);
145  ++cnt;
146  // state (not implemented, yet)
147  tempContent.writeUnsignedByte(TYPE_STRING);
148  tempContent.writeString(SUMOXMLDefinitions::LinkStates.getString(link->getState()));
149  ++cnt;
150  // direction
151  tempContent.writeUnsignedByte(TYPE_STRING);
152  tempContent.writeString(SUMOXMLDefinitions::LinkDirections.getString(link->getDirection()));
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 == SVCAll) { // special case: write nothing
167  permissions = 0;
168  }
169  tempMsg.writeStringList(getVehicleClassNamesList(permissions));
170  }
171  case LANE_DISALLOWED: {
173  tempMsg.writeStringList(getVehicleClassNamesList(~(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->getCO2Emissions());
187  break;
188  case VAR_COEMISSION:
190  tempMsg.writeDouble(lane->getCOEmissions());
191  break;
192  case VAR_HCEMISSION:
194  tempMsg.writeDouble(lane->getHCEmissions());
195  break;
196  case VAR_PMXEMISSION:
198  tempMsg.writeDouble(lane->getPMxEmissions());
199  break;
200  case VAR_NOXEMISSION:
202  tempMsg.writeDouble(lane->getNOxEmissions());
203  break;
204  case VAR_FUELCONSUMPTION:
206  tempMsg.writeDouble(lane->getFuelConsumption());
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 MSLane::VehCont& vehs = lane->getVehiclesSecure();
223  for (MSLane::VehCont::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->getNettoOccupancy());
234  break;
236  int halting = 0;
237  const MSLane::VehCont& vehs = lane->getVehiclesSecure();
238  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
239  if ((*j)->getSpeed() < SUMO_const_haltingSpeed) {
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 MSLane::VehCont& vehs = lane->getVehiclesSecure();
251  for (MSLane::VehCont::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_WAITING_TIME: {
265  tempMsg.writeDouble(lane->getWaitingSeconds());
266  }
267  break;
268  case VAR_CURRENT_TRAVELTIME: {
269  SUMOReal meanSpeed = lane->getMeanSpeed();
271  if (meanSpeed != 0) {
272  tempMsg.writeDouble(lane->getLength() / meanSpeed);
273  } else {
274  tempMsg.writeDouble(1000000.);
275  }
276  }
277  break;
278  case VAR_WIDTH:
280  tempMsg.writeDouble(lane->getWidth());
281  break;
282  default:
283  break;
284  }
285  }
286  server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_OK, "", outputStorage);
287  server.writeResponseWithLength(outputStorage, tempMsg);
288  return true;
289 }
290 
291 
292 bool
294  tcpip::Storage& outputStorage) {
295  std::string warning = ""; // additional description for response
296  // variable
297  int variable = inputStorage.readUnsignedByte();
298  if (variable != VAR_MAXSPEED && variable != VAR_LENGTH && variable != LANE_ALLOWED && variable != LANE_DISALLOWED) {
299  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Change Lane State: unsupported variable specified", outputStorage);
300  }
301  // id
302  std::string id = inputStorage.readString();
303  MSLane* l = MSLane::dictionary(id);
304  if (l == 0) {
305  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Lane '" + id + "' is not known", outputStorage);
306  }
307  // process
308  switch (variable) {
309  case VAR_MAXSPEED: {
310  double value = 0;
311  if (!server.readTypeCheckingDouble(inputStorage, value)) {
312  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "The speed must be given as a double.", outputStorage);
313  }
314  l->setMaxSpeed(value);
315  }
316  break;
317  case VAR_LENGTH: {
318  double value = 0;
319  if (!server.readTypeCheckingDouble(inputStorage, value)) {
320  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "The length must be given as a double.", outputStorage);
321  }
322  l->setLength(value);
323  }
324  break;
325  case LANE_ALLOWED: {
326  std::vector<std::string> classes;
327  if (!server.readTypeCheckingStringList(inputStorage, classes)) {
328  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Allowed classes must be given as a list of strings.", outputStorage);
329  }
330  l->setPermissions(parseVehicleClasses(classes));
332  }
333  break;
334  case LANE_DISALLOWED: {
335  std::vector<std::string> classes;
336  if (!server.readTypeCheckingStringList(inputStorage, classes)) {
337  return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Not allowed classes must be given as a list of strings.", outputStorage);
338  }
339  l->setPermissions(~parseVehicleClasses(classes)); // negation yields allowed
341  }
342  break;
343  default:
344  break;
345  }
346  server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_OK, warning, outputStorage);
347  return true;
348 }
349 
350 
351 bool
352 TraCIServerAPI_Lane::getShape(const std::string& id, PositionVector& shape) {
353  const MSLane* const l = MSLane::dictionary(id);
354  if (l == 0) {
355  return false;
356  }
357  shape.push_back(l->getShape());
358  return true;
359 }
360 
361 
362 void
364  switch (myDomain) {
366  const MSLane::VehCont& vehs = l->getVehiclesSecure();
367  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
368  if (myShape.distance((*j)->getPosition()) <= myRange) {
369  myIDs.insert((*j)->getID());
370  }
371  }
372  l->releaseVehicles();
373  }
374  break;
375  case CMD_GET_EDGE_VARIABLE: {
376  if (myShape.size() != 1 || l->getShape().distance(myShape[0]) <= myRange) {
377  myIDs.insert(l->getEdge().getID());
378  }
379  }
380  break;
381  case CMD_GET_LANE_VARIABLE: {
382  if (myShape.size() != 1 || l->getShape().distance(myShape[0]) <= myRange) {
383  myIDs.insert(l->getID());
384  }
385  }
386  break;
387  default:
388  break;
389 
390  }
391 }
392 
393 
394 #endif
395 
396 
397 /****************************************************************************/
398