Eclipse SUMO - Simulation of Urban MObility
libsumo/Edge.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2017-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // C++ TraCI client API implementation
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <iterator>
23 #include <microsim/MSEdge.h>
24 #include <microsim/MSLane.h>
27 #include <microsim/MSVehicle.h>
29 #include <libsumo/Helper.h>
30 #include <libsumo/TraCIDefs.h>
31 #include <libsumo/TraCIConstants.h>
32 #include <libsumo/Lane.h>
34 #include "Edge.h"
35 
36 
37 namespace libsumo {
38 // ===========================================================================
39 // static member initializations
40 // ===========================================================================
41 SubscriptionResults Edge::mySubscriptionResults;
42 ContextSubscriptionResults Edge::myContextSubscriptionResults;
43 
44 
45 // ===========================================================================
46 // static member definitions
47 // ===========================================================================
48 std::vector<std::string>
49 Edge::getIDList() {
50  MSNet::getInstance(); // just to check that we actually have a network
51  std::vector<std::string> ids;
52  MSEdge::insertIDs(ids);
53  return ids;
54 }
55 
56 
57 int
58 Edge::getIDCount() {
59  return (int)getIDList().size();
60 }
61 
62 
63 double
64 Edge::getAdaptedTraveltime(const std::string& edgeID, double time) {
65  const MSEdge* e = getEdge(edgeID);
66  double value;
67  if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingTravelTime(e, time, value)) {
68  return -1.;
69  }
70  return value;
71 }
72 
73 
74 double
75 Edge::getEffort(const std::string& edgeID, double time) {
76  const MSEdge* e = getEdge(edgeID);
77  double value;
78  if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, time, value)) {
79  return -1.;
80  }
81  return value;
82 }
83 
84 
85 double
86 Edge::getTraveltime(const std::string& edgeID) {
87  return getEdge(edgeID)->getCurrentTravelTime();
88 }
89 
90 
91 MSEdge*
92 Edge::getEdge(const std::string& edgeID) {
93  MSEdge* e = MSEdge::dictionary(edgeID);
94  if (e == nullptr) {
95  throw TraCIException("Edge '" + edgeID + "' is not known");
96  }
97  return e;
98 }
99 
100 
101 double
102 Edge::getWaitingTime(const std::string& edgeID) {
103  return getEdge(edgeID)->getWaitingSeconds();
104 }
105 
106 
107 const std::vector<std::string>
108 Edge::getLastStepPersonIDs(const std::string& edgeID) {
109  std::vector<std::string> personIDs;
110  std::vector<MSTransportable*> persons = getEdge(edgeID)->getSortedPersons(MSNet::getInstance()->getCurrentTimeStep(), true);
111  personIDs.reserve(persons.size());
112  for (MSTransportable* p : persons) {
113  personIDs.push_back(p->getID());
114  }
115  return personIDs;
116 }
117 
118 
119 const std::vector<std::string>
120 Edge::getLastStepVehicleIDs(const std::string& edgeID) {
121  std::vector<std::string> vehIDs;
122  for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
123  vehIDs.push_back(veh->getID());
124  }
125  return vehIDs;
126 }
127 
128 
129 double
130 Edge::getCO2Emission(const std::string& edgeID) {
131  double sum = 0;
132  for (MSLane* lane : getEdge(edgeID)->getLanes()) {
133  sum += lane->getEmissions<PollutantsInterface::CO2>();
134  }
135  return sum;
136 }
137 
138 
139 double
140 Edge::getCOEmission(const std::string& edgeID) {
141  double sum = 0;
142  for (MSLane* lane : getEdge(edgeID)->getLanes()) {
143  sum += lane->getEmissions<PollutantsInterface::CO>();
144  }
145  return sum;
146 }
147 
148 
149 double
150 Edge::getHCEmission(const std::string& edgeID) {
151  double sum = 0;
152  for (MSLane* lane : getEdge(edgeID)->getLanes()) {
153  sum += lane->getEmissions<PollutantsInterface::HC>();
154  }
155  return sum;
156 }
157 
158 
159 double
160 Edge::getPMxEmission(const std::string& edgeID) {
161  double sum = 0;
162  for (MSLane* lane : getEdge(edgeID)->getLanes()) {
163  sum += lane->getEmissions<PollutantsInterface::PM_X>();
164  }
165  return sum;
166 }
167 
168 
169 double
170 Edge::getNOxEmission(const std::string& edgeID) {
171  double sum = 0;
172  for (MSLane* lane : getEdge(edgeID)->getLanes()) {
173  sum += lane->getEmissions<PollutantsInterface::NO_X>();
174  }
175  return sum;
176 }
177 
178 
179 double
180 Edge::getFuelConsumption(const std::string& edgeID) {
181  double sum = 0;
182  for (MSLane* lane : getEdge(edgeID)->getLanes()) {
183  sum += lane->getEmissions<PollutantsInterface::FUEL>();
184  }
185  return sum;
186 }
187 
188 
189 double
190 Edge::getNoiseEmission(const std::string& edgeID) {
191  double sum = 0;
192  for (MSLane* lane : getEdge(edgeID)->getLanes()) {
193  sum += pow(10., (lane->getHarmonoise_NoiseEmissions() / 10.));
194  }
195  if (sum != 0) {
196  return HelpersHarmonoise::sum(sum);
197  }
198  return sum;
199 }
200 
201 
202 double
203 Edge::getElectricityConsumption(const std::string& edgeID) {
204  double sum = 0;
205  for (MSLane* lane : getEdge(edgeID)->getLanes()) {
206  sum += lane->getEmissions<PollutantsInterface::ELEC>();
207  }
208  return sum;
209 }
210 
211 
212 int
213 Edge::getLastStepVehicleNumber(const std::string& edgeID) {
214  return getEdge(edgeID)->getVehicleNumber();
215 }
216 
217 
218 double
219 Edge::getLastStepMeanSpeed(const std::string& edgeID) {
220  return getEdge(edgeID)->getMeanSpeed();
221 }
222 
223 double
224 Edge::getMeanFriction(const std::string& edgeID) {
225  return getEdge(edgeID)->getMeanFriction();
226 }
227 
228 
229 double
230 Edge::getLastStepOccupancy(const std::string& edgeID) {
231  return getEdge(edgeID)->getOccupancy();
232 }
233 
234 
235 int
236 Edge::getLastStepHaltingNumber(const std::string& edgeID) {
237  int result = 0;
238  for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
239  if (veh->getSpeed() < SUMO_const_haltingSpeed) {
240  result++;
241  }
242  }
243  return result;
244 }
245 
246 
247 double
248 Edge::getLastStepLength(const std::string& edgeID) {
249  double lengthSum = 0;
250  int numVehicles = 0;
251  for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
252  numVehicles++;
253  lengthSum += dynamic_cast<const MSBaseVehicle*>(veh)->getVehicleType().getLength();
254  }
255  if (numVehicles == 0) {
256  return 0;
257  }
258  return lengthSum / numVehicles;
259 }
260 
261 
262 int
263 Edge::getLaneNumber(const std::string& edgeID) {
264  return (int)getEdge(edgeID)->getLanes().size();
265 }
266 
267 
268 std::string
269 Edge::getStreetName(const std::string& edgeID) {
270  return getEdge(edgeID)->getStreetName();
271 }
272 
273 
274 const std::vector<std::string>
275 Edge::getPendingVehicles(const std::string& edgeID) {
276  getEdge(edgeID); // validate edgeID
277  std::vector<std::string> vehIDs;
278  for (const SUMOVehicle* veh : MSNet::getInstance()->getInsertionControl().getPendingVehicles()) {
279  if (veh->getEdge()->getID() == edgeID) {
280  vehIDs.push_back(veh->getID());
281  }
282  }
283  return vehIDs;
284 }
285 
286 
287 double
288 Edge::getAngle(const std::string& edgeID, double relativePosition) {
289  const std::vector<MSLane*>& lanes = getEdge(edgeID)->getLanes();
290  return lanes.empty() ? libsumo::INVALID_DOUBLE_VALUE : Lane::getAngle(lanes.front()->getID(), relativePosition);
291 }
292 
293 std::string
294 Edge::getFromJunction(const std::string& edgeID) {
295  return getEdge(edgeID)->getFromJunction()->getID();
296 }
297 
298 std::string
299 Edge::getToJunction(const std::string& edgeID) {
300  return getEdge(edgeID)->getToJunction()->getID();
301 }
302 
303 std::string
304 Edge::getParameter(const std::string& edgeID, const std::string& param) {
305  return getEdge(edgeID)->getParameter(param, "");
306 }
307 
308 
310 
311 
312 void
313 Edge::setAllowed(const std::string& edgeID, std::string allowedClasses) {
314  setAllowedSVCPermissions(edgeID, parseVehicleClasses(allowedClasses));
315 }
316 
317 
318 void
319 Edge::setAllowed(const std::string& edgeID, std::vector<std::string> allowedClasses) {
320  setAllowedSVCPermissions(edgeID, parseVehicleClasses(allowedClasses));
321 }
322 
323 
324 void
325 Edge::setDisallowed(const std::string& edgeID, std::string disallowedClasses) {
326  setAllowedSVCPermissions(edgeID, invertPermissions(parseVehicleClasses(disallowedClasses)));
327 }
328 
329 
330 void
331 Edge::setDisallowed(const std::string& edgeID, std::vector<std::string> disallowedClasses) {
332  setAllowedSVCPermissions(edgeID, invertPermissions(parseVehicleClasses(disallowedClasses)));
333 }
334 
335 
336 void
337 Edge::setAllowedSVCPermissions(const std::string& edgeID, long long int permissions) {
338  MSEdge* e = getEdge(edgeID);
339  for (MSLane* lane : e->getLanes()) {
340  lane->setPermissions(permissions, MSLane::CHANGE_PERMISSIONS_PERMANENT);
341  }
342  e->rebuildAllowedLanes();
343 }
344 
345 
346 void
347 Edge::adaptTraveltime(const std::string& edgeID, double time, double beginSeconds, double endSeconds) {
348  MSNet::getInstance()->getWeightsStorage().addTravelTime(getEdge(edgeID), beginSeconds, endSeconds, time);
349 }
350 
351 
352 void
353 Edge::setEffort(const std::string& edgeID, double effort, double beginSeconds, double endSeconds) {
354  MSNet::getInstance()->getWeightsStorage().addEffort(getEdge(edgeID), beginSeconds, endSeconds, effort);
355 }
356 
357 
358 void
359 Edge::setMaxSpeed(const std::string& edgeID, double speed) {
360  getEdge(edgeID)->setMaxSpeed(speed);
361 }
362 
363 void
364 Edge::setFriction(const std::string& edgeID, double friction) {
365  for (MSLane* lane : getEdge(edgeID)->getLanes()) {
366  lane->setFrictionCoefficient(friction);
367  }
368 }
369 
370 void
371 Edge::setParameter(const std::string& edgeID, const std::string& name, const std::string& value) {
372  getEdge(edgeID)->setParameter(name, value);
373 }
374 
375 
377 
378 
379 void
380 Edge::storeShape(const std::string& edgeID, PositionVector& shape) {
381  const MSEdge* const e = getEdge(edgeID);
382  const std::vector<MSLane*>& lanes = e->getLanes();
383  shape = lanes.front()->getShape();
384  if (lanes.size() > 1) {
385  copy(lanes.back()->getShape().begin(), lanes.back()->getShape().end(), back_inserter(shape));
386  }
387 }
388 
389 
390 std::shared_ptr<VariableWrapper>
391 Edge::makeWrapper() {
392  return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
393 }
394 
395 
396 bool
397 Edge::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
398  switch (variable) {
399  case TRACI_ID_LIST:
400  return wrapper->wrapStringList(objID, variable, getIDList());
401  case ID_COUNT:
402  return wrapper->wrapInt(objID, variable, getIDCount());
404  return wrapper->wrapDouble(objID, variable, getTraveltime(objID));
405  case VAR_WAITING_TIME:
406  return wrapper->wrapDouble(objID, variable, getWaitingTime(objID));
408  return wrapper->wrapStringList(objID, variable, getLastStepPersonIDs(objID));
410  return wrapper->wrapStringList(objID, variable, getLastStepVehicleIDs(objID));
411  case VAR_CO2EMISSION:
412  return wrapper->wrapDouble(objID, variable, getCO2Emission(objID));
413  case VAR_COEMISSION:
414  return wrapper->wrapDouble(objID, variable, getCOEmission(objID));
415  case VAR_HCEMISSION:
416  return wrapper->wrapDouble(objID, variable, getHCEmission(objID));
417  case VAR_PMXEMISSION:
418  return wrapper->wrapDouble(objID, variable, getPMxEmission(objID));
419  case VAR_NOXEMISSION:
420  return wrapper->wrapDouble(objID, variable, getNOxEmission(objID));
421  case VAR_FUELCONSUMPTION:
422  return wrapper->wrapDouble(objID, variable, getFuelConsumption(objID));
423  case VAR_NOISEEMISSION:
424  return wrapper->wrapDouble(objID, variable, getNoiseEmission(objID));
426  return wrapper->wrapDouble(objID, variable, getElectricityConsumption(objID));
428  return wrapper->wrapInt(objID, variable, getLastStepVehicleNumber(objID));
430  return wrapper->wrapDouble(objID, variable, getLastStepMeanSpeed(objID));
431  case VAR_FRICTION:
432  return wrapper->wrapDouble(objID, variable, getMeanFriction(objID));
433  case LAST_STEP_OCCUPANCY:
434  return wrapper->wrapDouble(objID, variable, getLastStepOccupancy(objID));
436  return wrapper->wrapInt(objID, variable, getLastStepHaltingNumber(objID));
437  case LAST_STEP_LENGTH:
438  return wrapper->wrapDouble(objID, variable, getLastStepLength(objID));
439  case VAR_LANE_INDEX:
440  return wrapper->wrapInt(objID, variable, getLaneNumber(objID));
441  case VAR_NAME:
442  return wrapper->wrapString(objID, variable, getStreetName(objID));
444  return wrapper->wrapStringList(objID, variable, getPendingVehicles(objID));
445  case VAR_ANGLE:
446  paramData->readUnsignedByte();
447  return wrapper->wrapDouble(objID, variable, getAngle(objID, paramData->readDouble()));
448  case FROM_JUNCTION:
449  return wrapper->wrapString(objID, variable, getFromJunction(objID));
450  case TO_JUNCTION:
451  return wrapper->wrapString(objID, variable, getToJunction(objID));
453  paramData->readUnsignedByte();
454  return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
456  paramData->readUnsignedByte();
457  return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
458  default:
459  return false;
460  }
461 }
462 
463 }
464 
465 
466 /****************************************************************************/
SVCPermissions invertPermissions(SVCPermissions permissions)
negate the given permissions and ensure that only relevant bits are set
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:58
#define LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(CLASS, DOM)
Definition: TraCIDefs.h:76
#define LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(CLASS)
Definition: TraCIDefs.h:123
C++ TraCI client API implementation.
Definition: Edge.h:34
static double sum(double val)
Computes the resulting noise.
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:55
double getLength() const
Returns the vehicle's length.
A road/street connecting two junctions.
Definition: MSEdge.h:77
void rebuildAllowedLanes(const bool onInit=false)
Definition: MSEdge.cpp:317
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
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:983
static void insertIDs(std::vector< std::string > &into)
Inserts IDs of all known edges into the given vector.
Definition: MSEdge.cpp:1038
double getWaitingSeconds() const
return accumated waiting time for all vehicles on this edges lanes or segments
Definition: MSEdge.cpp:1463
void addTravelTime(const MSEdge *const e, double begin, double end, double value)
Adds a travel time information for an edge and a time span.
void addEffort(const MSEdge *const e, double begin, double end, double value)
Adds an effort information for an edge and a time span.
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
static const long CHANGE_PERMISSIONS_PERMANENT
Definition: MSLane.h:1351
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:182
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net's internal edge travel times/efforts container.
Definition: MSNet.cpp:1196
A list of positions.
Representation of a vehicle.
Definition: SUMOVehicle.h:60
virtual std::string readString()
Definition: storage.cpp:180
virtual int readUnsignedByte()
Definition: storage.cpp:155
virtual double readDouble()
Definition: storage.cpp:362
TRACI_CONST double INVALID_DOUBLE_VALUE
TRACI_CONST int LAST_STEP_VEHICLE_ID_LIST
TRACI_CONST int LAST_STEP_VEHICLE_NUMBER
TRACI_CONST int VAR_NOXEMISSION
TRACI_CONST int VAR_NAME
TRACI_CONST int LAST_STEP_PERSON_ID_LIST
TRACI_CONST int TRACI_ID_LIST
TRACI_CONST int VAR_WAITING_TIME
std::map< std::string, libsumo::SubscriptionResults > ContextSubscriptionResults
Definition: TraCIDefs.h:338
TRACI_CONST int LAST_STEP_LENGTH
TRACI_CONST int VAR_ANGLE
TRACI_CONST int VAR_LANE_INDEX
TRACI_CONST int VAR_PMXEMISSION
TRACI_CONST int VAR_COEMISSION
TRACI_CONST int LAST_STEP_MEAN_SPEED
TRACI_CONST int VAR_CO2EMISSION
TRACI_CONST int VAR_PENDING_VEHICLES
TRACI_CONST int VAR_FUELCONSUMPTION
std::map< std::string, libsumo::TraCIResults > SubscriptionResults
{object->{variable->value}}
Definition: TraCIDefs.h:337
TRACI_CONST int LAST_STEP_VEHICLE_HALTING_NUMBER
TRACI_CONST int VAR_HCEMISSION
TRACI_CONST int ID_COUNT
TRACI_CONST int VAR_PARAMETER
TRACI_CONST int LAST_STEP_OCCUPANCY
TRACI_CONST int VAR_NOISEEMISSION
TRACI_CONST int VAR_PARAMETER_WITH_KEY
TRACI_CONST int VAR_FRICTION
TRACI_CONST int FROM_JUNCTION
TRACI_CONST int VAR_CURRENT_TRAVELTIME
TRACI_CONST int VAR_ELECTRICITYCONSUMPTION
TRACI_CONST int TO_JUNCTION