SUMO - Simulation of Urban MObility
TraCIServerAPI_Edge.cpp
Go to the documentation of this file.
1 /****************************************************************************/
12 // APIs for getting/setting edge values via TraCI
13 /****************************************************************************/
14 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
15 // Copyright (C) 2002-2015 DLR (http://www.dlr.de/) and contributors
16 /****************************************************************************/
17 //
18 // This file is part of SUMO.
19 // SUMO is free software: you can redistribute it and/or modify
20 // it under the terms of the GNU General Public License as published by
21 // the Free Software Foundation, either version 3 of the License, or
22 // (at your option) any later version.
23 //
24 /****************************************************************************/
25 
26 
27 // ===========================================================================
28 // included modules
29 // ===========================================================================
30 #ifdef _MSC_VER
31 #include <windows_config.h>
32 #else
33 #include <config.h>
34 #endif
35 
36 #ifndef NO_TRACI
37 
38 #include <utils/common/StdDefs.h>
39 #include <microsim/MSNet.h>
40 #include <microsim/MSEdgeControl.h>
41 #include <microsim/MSEdge.h>
42 #include <microsim/MSLane.h>
43 #include <microsim/MSVehicle.h>
44 #include "TraCIConstants.h"
45 #include "TraCIServerAPI_Edge.h"
48 
49 #ifdef CHECK_MEMORY_LEAKS
50 #include <foreign/nvwa/debug_new.h>
51 #endif // CHECK_MEMORY_LEAKS
52 
53 
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
57 bool
59  tcpip::Storage& outputStorage) {
60  // variable & id
61  int variable = inputStorage.readUnsignedByte();
62  std::string id = inputStorage.readString();
63  // check variable
64  if (variable != ID_LIST && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT && variable != VAR_CURRENT_TRAVELTIME
65  && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION
66  && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION && variable != VAR_WAITING_TIME
67  && variable != LAST_STEP_VEHICLE_NUMBER && variable != LAST_STEP_MEAN_SPEED && variable != LAST_STEP_OCCUPANCY
68  && variable != LAST_STEP_VEHICLE_HALTING_NUMBER && variable != LAST_STEP_LENGTH
69  && variable != LAST_STEP_VEHICLE_ID_LIST && variable != ID_COUNT && variable != VAR_PARAMETER) {
70  return server.writeErrorStatusCmd(CMD_GET_EDGE_VARIABLE, "Get Edge Variable: unsupported variable specified", outputStorage);
71  }
72  // begin response building
73  tcpip::Storage tempMsg;
74  // response-code, variableID, objectID
76  tempMsg.writeUnsignedByte(variable);
77  tempMsg.writeString(id);
78  // process request
79  if (variable == ID_LIST) {
80  std::vector<std::string> ids;
81  MSEdge::insertIDs(ids);
83  tempMsg.writeStringList(ids);
84  } else if (variable == ID_COUNT) {
85  std::vector<std::string> ids;
86  MSEdge::insertIDs(ids);
88  tempMsg.writeInt((int) ids.size());
89  } else {
90  MSEdge* e = MSEdge::dictionary(id);
91  if (e == 0) {
92  return server.writeErrorStatusCmd(CMD_GET_EDGE_VARIABLE, "Edge '" + id + "' is not known", outputStorage);
93  }
94  switch (variable) {
95  case VAR_EDGE_TRAVELTIME: {
96  // time
97  SUMOTime time = 0;
98  if (!server.readTypeCheckingInt(inputStorage, time)) {
99  return server.writeErrorStatusCmd(CMD_GET_EDGE_VARIABLE, "The message must contain the time definition.", outputStorage);
100  }
102  SUMOReal value;
103  if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingTravelTime(e, time, value)) {
104  tempMsg.writeDouble(-1);
105  } else {
106  tempMsg.writeDouble(value);
107  }
108  }
109  break;
110  case VAR_EDGE_EFFORT: {
111  // time
112  SUMOTime time = 0;
113  if (!server.readTypeCheckingInt(inputStorage, time)) {
114  return server.writeErrorStatusCmd(CMD_GET_EDGE_VARIABLE, "The message must contain the time definition.", outputStorage);
115  }
117  SUMOReal value;
118  if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, time, value)) {
119  tempMsg.writeDouble(-1);
120  } else {
121  tempMsg.writeDouble(value);
122  }
123  }
124  break;
127  tempMsg.writeDouble(e->getCurrentTravelTime());
128  break;
129  case VAR_WAITING_TIME: {
130  SUMOReal wtime = 0;
131  const std::vector<MSLane*>& lanes = e->getLanes();
132  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
133  wtime += (*i)->getWaitingSeconds();
134  }
136  tempMsg.writeDouble(wtime);
137  }
138  break;
140  std::vector<std::string> vehIDs;
141  const std::vector<MSLane*>& lanes = e->getLanes();
142  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
143  const MSLane::VehCont& vehs = (*i)->getVehiclesSecure();
144  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
145  vehIDs.push_back((*j)->getID());
146  }
147  (*i)->releaseVehicles();
148  }
150  tempMsg.writeStringList(vehIDs);
151  }
152  break;
153  case VAR_CO2EMISSION: {
154  SUMOReal sum = 0;
155  const std::vector<MSLane*>& lanes = e->getLanes();
156  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
157  sum += (*i)->getCO2Emissions();
158  }
160  tempMsg.writeDouble(sum);
161  }
162  break;
163  case VAR_COEMISSION: {
164  SUMOReal sum = 0;
165  const std::vector<MSLane*>& lanes = e->getLanes();
166  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
167  sum += (*i)->getCOEmissions();
168  }
170  tempMsg.writeDouble(sum);
171  }
172  break;
173  case VAR_HCEMISSION: {
174  SUMOReal sum = 0;
175  const std::vector<MSLane*>& lanes = e->getLanes();
176  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
177  sum += (*i)->getHCEmissions();
178  }
180  tempMsg.writeDouble(sum);
181  }
182  break;
183  case VAR_PMXEMISSION: {
184  SUMOReal sum = 0;
185  const std::vector<MSLane*>& lanes = e->getLanes();
186  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
187  sum += (*i)->getPMxEmissions();
188  }
190  tempMsg.writeDouble(sum);
191  }
192  break;
193  case VAR_NOXEMISSION: {
194  SUMOReal sum = 0;
195  const std::vector<MSLane*>& lanes = e->getLanes();
196  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
197  sum += (*i)->getNOxEmissions();
198  }
200  tempMsg.writeDouble(sum);
201  }
202  break;
203  case VAR_FUELCONSUMPTION: {
204  SUMOReal sum = 0;
205  const std::vector<MSLane*>& lanes = e->getLanes();
206  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
207  sum += (*i)->getFuelConsumption();
208  }
210  tempMsg.writeDouble(sum);
211  }
212  break;
213  case VAR_NOISEEMISSION: {
214  SUMOReal sum = 0;
215  const std::vector<MSLane*>& lanes = e->getLanes();
216  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
217  sum += (SUMOReal) pow(10., ((*i)->getHarmonoise_NoiseEmissions() / 10.));
218  }
220  if (sum != 0) {
221  tempMsg.writeDouble(HelpersHarmonoise::sum(sum));
222  } else {
223  tempMsg.writeDouble(0);
224  }
225  }
226  break;
228  int sum = 0;
229  const std::vector<MSLane*>& lanes = e->getLanes();
230  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
231  sum += (*i)->getVehicleNumber();
232  }
234  tempMsg.writeInt(sum);
235  }
236  break;
237  case LAST_STEP_MEAN_SPEED: {
238  SUMOReal sum = 0;
239  const std::vector<MSLane*>& lanes = e->getLanes();
240  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
241  sum += (*i)->getMeanSpeed();
242  }
244  tempMsg.writeDouble(sum / (SUMOReal) lanes.size());
245  }
246  break;
247  case LAST_STEP_OCCUPANCY: {
248  SUMOReal sum = 0;
249  const std::vector<MSLane*>& lanes = e->getLanes();
250  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
251  sum += (*i)->getNettoOccupancy();
252  }
254  tempMsg.writeDouble(sum / (SUMOReal) lanes.size());
255  }
256  break;
258  int halting = 0;
259  const std::vector<MSLane*>& lanes = e->getLanes();
260  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
261  const MSLane::VehCont& vehs = (*i)->getVehiclesSecure();
262  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
263  if ((*j)->getSpeed() < SUMO_const_haltingSpeed) {
264  ++halting;
265  }
266  }
267  (*i)->releaseVehicles();
268  }
270  tempMsg.writeInt(halting);
271  }
272  break;
273  case LAST_STEP_LENGTH: {
274  SUMOReal lengthSum = 0;
275  int noVehicles = 0;
276  const std::vector<MSLane*>& lanes = e->getLanes();
277  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
278  const MSLane::VehCont& vehs = (*i)->getVehiclesSecure();
279  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
280  lengthSum += (*j)->getVehicleType().getLength();
281  }
282  noVehicles += (int) vehs.size();
283  (*i)->releaseVehicles();
284  }
286  if (noVehicles == 0) {
287  tempMsg.writeDouble(0);
288  } else {
289  tempMsg.writeDouble(lengthSum / (SUMOReal) noVehicles);
290  }
291  }
292  break;
293  case VAR_PARAMETER: {
294  std::string paramName = "";
295  if (!server.readTypeCheckingString(inputStorage, paramName)) {
296  return server.writeErrorStatusCmd(CMD_GET_EDGE_VARIABLE, "Retrieval of a parameter requires its name.", outputStorage);
297  }
299  tempMsg.writeString(e->getParameter(paramName, ""));
300  }
301  break;
302  default:
303  break;
304  }
305  }
306  server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_OK, "", outputStorage);
307  server.writeResponseWithLength(outputStorage, tempMsg);
308  return true;
309 }
310 
311 
312 bool
314  tcpip::Storage& outputStorage) {
315  std::string warning = ""; // additional description for response
316  // variable
317  int variable = inputStorage.readUnsignedByte();
318  if (variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT && variable != VAR_MAXSPEED && variable != VAR_PARAMETER) {
319  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "Change Edge State: unsupported variable specified", outputStorage);
320  }
321  // id
322  std::string id = inputStorage.readString();
323  MSEdge* e = MSEdge::dictionary(id);
324  if (e == 0) {
325  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "Edge '" + id + "' is not known", outputStorage);
326  }
327  // process
328  switch (variable) {
329  case LANE_ALLOWED: {
330  // read and set allowed vehicle classes
331  std::vector<std::string> classes;
332  if (!server.readTypeCheckingStringList(inputStorage, classes)) {
333  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "Allowed vehicle classes must be given as a list of strings.", outputStorage);
334  }
335  SVCPermissions permissions = parseVehicleClasses(classes);
336  const std::vector<MSLane*>& lanes = e->getLanes();
337  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
338  (*i)->setPermissions(permissions);
339  }
340  e->rebuildAllowedLanes();
341  }
342  break;
343  case LANE_DISALLOWED: {
344  // read and set disallowed vehicle classes
345  std::vector<std::string> classes;
346  if (!server.readTypeCheckingStringList(inputStorage, classes)) {
347  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "Not allowed vehicle classes must be given as a list of strings.", outputStorage);
348  }
349  SVCPermissions permissions = ~parseVehicleClasses(classes); // negation yields allowed
350  const std::vector<MSLane*>& lanes = e->getLanes();
351  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
352  (*i)->setPermissions(permissions);
353  }
354  e->rebuildAllowedLanes();
355  }
356  break;
357  case VAR_EDGE_TRAVELTIME: {
358  // read and set travel time
359  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
360  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires a compound object.", outputStorage);
361  }
362  int parameterCount = inputStorage.readInt();
363  if (parameterCount == 3) {
364  // bound by time
365  SUMOTime begTime = 0, endTime = 0;
366  double value = 0;
367  if (!server.readTypeCheckingInt(inputStorage, begTime)) {
368  return server.writeErrorStatusCmd(CMD_GET_EDGE_VARIABLE, "The first variable must be the begin time given as int.", outputStorage);
369  }
370  if (!server.readTypeCheckingInt(inputStorage, endTime)) {
371  return server.writeErrorStatusCmd(CMD_GET_EDGE_VARIABLE, "The second variable must be the end time given as int.", outputStorage);
372  }
373  if (!server.readTypeCheckingDouble(inputStorage, value)) {
374  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "The third variable must be the value given as double", outputStorage);
375  }
376  MSNet::getInstance()->getWeightsStorage().addTravelTime(e, begTime, endTime, value);
377  } else if (parameterCount == 1) {
378  // unbound
379  double value = 0;
380  if (!server.readTypeCheckingDouble(inputStorage, value)) {
381  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "The variable must be the value given as double", outputStorage);
382  }
384  } else {
385  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting travel time requires either begin time, end time, and value, or only value as parameter.", outputStorage);
386  }
387  }
388  break;
389  case VAR_EDGE_EFFORT: {
390  // read and set effort
391  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
392  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort requires a compound object.", outputStorage);
393  }
394  int parameterCount = inputStorage.readInt();
395  if (parameterCount == 3) {
396  // bound by time
397  SUMOTime begTime = 0, endTime = 0;
398  double value = 0;
399  if (!server.readTypeCheckingInt(inputStorage, begTime)) {
400  return server.writeErrorStatusCmd(CMD_GET_EDGE_VARIABLE, "The first variable must be the begin time given as int.", outputStorage);
401  }
402  if (!server.readTypeCheckingInt(inputStorage, endTime)) {
403  return server.writeErrorStatusCmd(CMD_GET_EDGE_VARIABLE, "The second variable must be the end time given as int.", outputStorage);
404  }
405  if (!server.readTypeCheckingDouble(inputStorage, value)) {
406  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "The third variable must be the value given as double", outputStorage);
407  }
408  MSNet::getInstance()->getWeightsStorage().addEffort(e, begTime, endTime, value);
409  } else if (parameterCount == 1) {
410  // unbound
411  double value = 0;
412  if (!server.readTypeCheckingDouble(inputStorage, value)) {
413  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "The variable must be the value given as double", outputStorage);
414  }
416  } else {
417  return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Setting effort requires either begin time, end time, and value, or only value as parameter.", outputStorage);
418  }
419  }
420  break;
421  case VAR_MAXSPEED: {
422  // read and set max. speed
423  double value = 0;
424  if (!server.readTypeCheckingDouble(inputStorage, value)) {
425  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "The speed must be given as a double.", outputStorage);
426  }
427  const std::vector<MSLane*>& lanes = e->getLanes();
428  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
429  (*i)->setMaxSpeed(value);
430  }
431  }
432  break;
433  case VAR_PARAMETER: {
434  if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) {
435  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "A compound object is needed for setting a parameter.", outputStorage);
436  }
437  //readt itemNo
438  inputStorage.readInt();
439  std::string name;
440  if (!server.readTypeCheckingString(inputStorage, name)) {
441  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "The name of the parameter must be given as a string.", outputStorage);
442  }
443  std::string value;
444  if (!server.readTypeCheckingString(inputStorage, value)) {
445  return server.writeErrorStatusCmd(CMD_SET_EDGE_VARIABLE, "The value of the parameter must be given as a string.", outputStorage);
446  }
447  e->addParameter(name, value);
448  }
449  break;
450  default:
451  break;
452  }
453  server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_OK, warning, outputStorage);
454  return true;
455 }
456 
457 
458 bool
459 TraCIServerAPI_Edge::getShape(const std::string& id, PositionVector& shape) {
460  MSEdge* e = MSEdge::dictionary(id);
461  if (e == 0) {
462  return false;
463  }
464  const std::vector<MSLane*>& lanes = e->getLanes();
465  shape.push_back(lanes.front()->getShape());
466  if (lanes.size() > 1) {
467  shape.push_back(lanes.back()->getShape().reverse());
468  }
469  return true;
470 }
471 
472 #endif
473 
474 
475 /****************************************************************************/
476 
#define LAST_STEP_MEAN_SPEED
static void insertIDs(std::vector< std::string > &into)
Inserts IDs of all known edges into the given vector.
Definition: MSEdge.cpp:586
#define VAR_CO2EMISSION
#define TYPE_COMPOUND
#define VAR_CURRENT_TRAVELTIME
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:186
int SVCPermissions
#define RTYPE_OK
#define VAR_WAITING_TIME
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:88
bool readTypeCheckingInt(tcpip::Storage &inputStorage, int &into)
Reads the value type and an int, verifying the type.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
#define TYPE_STRINGLIST
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary...
Definition: MSEdge.cpp:531
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xca: Change Edge State)
virtual void writeUnsignedByte(int)
#define CMD_SET_EDGE_VARIABLE
const std::string & getParameter(const std::string &key, const std::string &defaultValue) const
Returns the value for a given key.
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
#define VAR_NOISEEMISSION
#define VAR_FUELCONSUMPTION
void addEffort(const MSEdge *const e, SUMOReal begin, SUMOReal end, SUMOReal value)
Adds an effort information for an edge and a time span.
virtual void writeInt(int)
#define TYPE_STRING
virtual int readUnsignedByte()
#define LAST_STEP_LENGTH
void addTravelTime(const MSEdge *const e, SUMOReal begin, SUMOReal end, SUMOReal value)
Adds a travel time information for an edge and a time span.
#define VAR_NOXEMISSION
A road/street connecting two junctions.
Definition: MSEdge.h:81
#define LANE_ALLOWED
void rebuildAllowedLanes()
Definition: MSEdge.cpp:168
virtual int readInt()
A list of positions.
bool readTypeCheckingStringList(tcpip::Storage &inputStorage, std::vector< std::string > &into)
Reads the value type and a string list, verifying the type.
virtual void writeStringList(const std::vector< std::string > &s)
#define VAR_PMXEMISSION
#define CMD_SET_VEHICLE_VARIABLE
virtual std::string readString()
#define CMD_GET_EDGE_VARIABLE
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
#define VAR_EDGE_EFFORT
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:74
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
#define LAST_STEP_VEHICLE_NUMBER
void addParameter(const std::string &key, const std::string &value)
Adds a parameter.
#define VAR_EDGE_TRAVELTIME
void push_back(const PositionVector &p)
Appends all positions from the given vector.
#define VAR_COEMISSION
static bool getShape(const std::string &id, PositionVector &shape)
Returns the named edge's shape.
virtual void writeString(const std::string &s)
#define LAST_STEP_VEHICLE_ID_LIST
#define LANE_DISALLOWED
#define SUMOTime_MAX
Definition: SUMOTime.h:44
#define TYPE_DOUBLE
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:54
static SUMOReal sum(SUMOReal val)
Computes the resulting noise.
int SUMOTime
Definition: SUMOTime.h:43
virtual void writeDouble(double)
#define SUMOReal
Definition: config.h:218
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
#define LAST_STEP_OCCUPANCY
#define VAR_MAXSPEED
#define VAR_PARAMETER
#define ID_COUNT
#define TYPE_INTEGER
#define ID_LIST
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xaa: Get Edge Variable)
SUMOReal getCurrentTravelTime(const SUMOReal minSpeed=NUMERICAL_EPS) const
Computes and returns the current travel time for this edge.
Definition: MSEdge.cpp:501
#define LAST_STEP_VEHICLE_HALTING_NUMBER
#define VAR_HCEMISSION
#define RESPONSE_GET_EDGE_VARIABLE
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net's internal edge travel times/efforts container.
Definition: MSNet.cpp:675