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.org/sumo
3// Copyright (C) 2017-2023 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>
33#include "Edge.h"
34
35
36namespace libsumo {
37// ===========================================================================
38// static member initializations
39// ===========================================================================
40SubscriptionResults Edge::mySubscriptionResults;
41ContextSubscriptionResults Edge::myContextSubscriptionResults;
42
43
44// ===========================================================================
45// static member definitions
46// ===========================================================================
47std::vector<std::string>
48Edge::getIDList() {
49 std::vector<std::string> ids;
51 return ids;
52}
53
54
55int
56Edge::getIDCount() {
57 return (int)getIDList().size();
58}
59
60
61double
62Edge::getAdaptedTraveltime(const std::string& edgeID, double time) {
63 const MSEdge* e = getEdge(edgeID);
64 double value;
65 if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingTravelTime(e, time, value)) {
66 return -1.;
67 }
68 return value;
69}
70
71
72double
73Edge::getEffort(const std::string& edgeID, double time) {
74 const MSEdge* e = getEdge(edgeID);
75 double value;
76 if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, time, value)) {
77 return -1.;
78 }
79 return value;
80}
81
82
83double
84Edge::getTraveltime(const std::string& edgeID) {
85 return getEdge(edgeID)->getCurrentTravelTime();
86}
87
88
89MSEdge*
90Edge::getEdge(const std::string& edgeID) {
91 MSEdge* e = MSEdge::dictionary(edgeID);
92 if (e == nullptr) {
93 throw TraCIException("Edge '" + edgeID + "' is not known");
94 }
95 return e;
96}
97
98
99double
100Edge::getWaitingTime(const std::string& edgeID) {
101 return getEdge(edgeID)->getWaitingSeconds();
102}
103
104
105const std::vector<std::string>
106Edge::getLastStepPersonIDs(const std::string& edgeID) {
107 std::vector<std::string> personIDs;
108 std::vector<MSTransportable*> persons = getEdge(edgeID)->getSortedPersons(MSNet::getInstance()->getCurrentTimeStep(), true);
109 personIDs.reserve(persons.size());
110 for (MSTransportable* p : persons) {
111 personIDs.push_back(p->getID());
112 }
113 return personIDs;
114}
115
116
117const std::vector<std::string>
118Edge::getLastStepVehicleIDs(const std::string& edgeID) {
119 std::vector<std::string> vehIDs;
120 for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
121 vehIDs.push_back(veh->getID());
122 }
123 return vehIDs;
124}
125
126
127double
128Edge::getCO2Emission(const std::string& edgeID) {
129 double sum = 0;
130 for (MSLane* lane : getEdge(edgeID)->getLanes()) {
131 sum += lane->getEmissions<PollutantsInterface::CO2>();
132 }
133 return sum;
134}
135
136
137double
138Edge::getCOEmission(const std::string& edgeID) {
139 double sum = 0;
140 for (MSLane* lane : getEdge(edgeID)->getLanes()) {
141 sum += lane->getEmissions<PollutantsInterface::CO>();
142 }
143 return sum;
144}
145
146
147double
148Edge::getHCEmission(const std::string& edgeID) {
149 double sum = 0;
150 for (MSLane* lane : getEdge(edgeID)->getLanes()) {
151 sum += lane->getEmissions<PollutantsInterface::HC>();
152 }
153 return sum;
154}
155
156
157double
158Edge::getPMxEmission(const std::string& edgeID) {
159 double sum = 0;
160 for (MSLane* lane : getEdge(edgeID)->getLanes()) {
161 sum += lane->getEmissions<PollutantsInterface::PM_X>();
162 }
163 return sum;
164}
165
166
167double
168Edge::getNOxEmission(const std::string& edgeID) {
169 double sum = 0;
170 for (MSLane* lane : getEdge(edgeID)->getLanes()) {
171 sum += lane->getEmissions<PollutantsInterface::NO_X>();
172 }
173 return sum;
174}
175
176
177double
178Edge::getFuelConsumption(const std::string& edgeID) {
179 double sum = 0;
180 for (MSLane* lane : getEdge(edgeID)->getLanes()) {
181 sum += lane->getEmissions<PollutantsInterface::FUEL>();
182 }
183 return sum;
184}
185
186
187double
188Edge::getNoiseEmission(const std::string& edgeID) {
189 double sum = 0;
190 for (MSLane* lane : getEdge(edgeID)->getLanes()) {
191 sum += pow(10., (lane->getHarmonoise_NoiseEmissions() / 10.));
192 }
193 if (sum != 0) {
194 return HelpersHarmonoise::sum(sum);
195 }
196 return sum;
197}
198
199
200double
201Edge::getElectricityConsumption(const std::string& edgeID) {
202 double sum = 0;
203 for (MSLane* lane : getEdge(edgeID)->getLanes()) {
204 sum += lane->getEmissions<PollutantsInterface::ELEC>();
205 }
206 return sum;
207}
208
209
210int
211Edge::getLastStepVehicleNumber(const std::string& edgeID) {
212 return getEdge(edgeID)->getVehicleNumber();
213}
214
215
216double
217Edge::getLastStepMeanSpeed(const std::string& edgeID) {
218 return getEdge(edgeID)->getMeanSpeed();
219}
220
221double
222Edge::getMeanFriction(const std::string& edgeID) {
223 return getEdge(edgeID)->getMeanFriction();
224}
225
226
227double
228Edge::getLastStepOccupancy(const std::string& edgeID) {
229 return getEdge(edgeID)->getOccupancy();
230}
231
232
233int
234Edge::getLastStepHaltingNumber(const std::string& edgeID) {
235 int result = 0;
236 for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
237 if (veh->getSpeed() < SUMO_const_haltingSpeed) {
238 result++;
239 }
240 }
241 return result;
242}
243
244
245double
246Edge::getLastStepLength(const std::string& edgeID) {
247 double lengthSum = 0;
248 int numVehicles = 0;
249 for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
250 numVehicles++;
251 lengthSum += dynamic_cast<const MSBaseVehicle*>(veh)->getVehicleType().getLength();
252 }
253 if (numVehicles == 0) {
254 return 0;
255 }
256 return lengthSum / numVehicles;
257}
258
259
260int
261Edge::getLaneNumber(const std::string& edgeID) {
262 return (int)getEdge(edgeID)->getLanes().size();
263}
264
265
266std::string
267Edge::getStreetName(const std::string& edgeID) {
268 return getEdge(edgeID)->getStreetName();
269}
270
271
272const std::vector<std::string>
273Edge::getPendingVehicles(const std::string& edgeID) {
274 getEdge(edgeID); // validate edgeID
275 std::vector<std::string> vehIDs;
276 for (const SUMOVehicle* veh : MSNet::getInstance()->getInsertionControl().getPendingVehicles()) {
277 if (veh->getEdge()->getID() == edgeID) {
278 vehIDs.push_back(veh->getID());
279 }
280 }
281 return vehIDs;
282}
283
284std::string
285Edge::getParameter(const std::string& edgeID, const std::string& param) {
286 return getEdge(edgeID)->getParameter(param, "");
287}
288
289
291
292
293void
294Edge::setAllowed(const std::string& edgeID, std::string allowedClasses) {
295 setAllowedSVCPermissions(edgeID, parseVehicleClasses(allowedClasses));
296}
297
298
299void
300Edge::setAllowed(const std::string& edgeID, std::vector<std::string> allowedClasses) {
301 setAllowedSVCPermissions(edgeID, parseVehicleClasses(allowedClasses));
302}
303
304
305void
306Edge::setDisallowed(const std::string& edgeID, std::string disallowedClasses) {
307 setAllowedSVCPermissions(edgeID, invertPermissions(parseVehicleClasses(disallowedClasses)));
308}
309
310
311void
312Edge::setDisallowed(const std::string& edgeID, std::vector<std::string> disallowedClasses) {
313 setAllowedSVCPermissions(edgeID, invertPermissions(parseVehicleClasses(disallowedClasses)));
314}
315
316
317void
318Edge::setAllowedSVCPermissions(const std::string& edgeID, int permissions) {
319 MSEdge* e = getEdge(edgeID);
320 for (MSLane* lane : e->getLanes()) {
321 lane->setPermissions(permissions, MSLane::CHANGE_PERMISSIONS_PERMANENT);
322 }
324}
325
326
327void
328Edge::adaptTraveltime(const std::string& edgeID, double time, double beginSeconds, double endSeconds) {
329 MSNet::getInstance()->getWeightsStorage().addTravelTime(getEdge(edgeID), beginSeconds, endSeconds, time);
330}
331
332
333void
334Edge::setEffort(const std::string& edgeID, double effort, double beginSeconds, double endSeconds) {
335 MSNet::getInstance()->getWeightsStorage().addEffort(getEdge(edgeID), beginSeconds, endSeconds, effort);
336}
337
338
339void
340Edge::setMaxSpeed(const std::string& edgeID, double speed) {
341 for (MSLane* lane : getEdge(edgeID)->getLanes()) {
342 lane->setMaxSpeed(speed);
343 }
344}
345
346void
347Edge::setFriction(const std::string& edgeID, double value) {
348 for (MSLane* lane : getEdge(edgeID)->getLanes()) {
349 lane->setFrictionCoefficient(value);
350 }
351}
352
353void
354Edge::setParameter(const std::string& edgeID, const std::string& name, const std::string& value) {
355 getEdge(edgeID)->setParameter(name, value);
356}
357
358
360
361
362void
363Edge::storeShape(const std::string& edgeID, PositionVector& shape) {
364 const MSEdge* const e = getEdge(edgeID);
365 const std::vector<MSLane*>& lanes = e->getLanes();
366 shape = lanes.front()->getShape();
367 if (lanes.size() > 1) {
368 copy(lanes.back()->getShape().begin(), lanes.back()->getShape().end(), back_inserter(shape));
369 }
370}
371
372
373std::shared_ptr<VariableWrapper>
374Edge::makeWrapper() {
375 return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
376}
377
378
379bool
380Edge::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
381 switch (variable) {
382 case TRACI_ID_LIST:
383 return wrapper->wrapStringList(objID, variable, getIDList());
384 case ID_COUNT:
385 return wrapper->wrapInt(objID, variable, getIDCount());
387 return wrapper->wrapDouble(objID, variable, getTraveltime(objID));
388 case VAR_WAITING_TIME:
389 return wrapper->wrapDouble(objID, variable, getWaitingTime(objID));
391 return wrapper->wrapStringList(objID, variable, getLastStepPersonIDs(objID));
393 return wrapper->wrapStringList(objID, variable, getLastStepVehicleIDs(objID));
394 case VAR_CO2EMISSION:
395 return wrapper->wrapDouble(objID, variable, getCO2Emission(objID));
396 case VAR_COEMISSION:
397 return wrapper->wrapDouble(objID, variable, getCOEmission(objID));
398 case VAR_HCEMISSION:
399 return wrapper->wrapDouble(objID, variable, getHCEmission(objID));
400 case VAR_PMXEMISSION:
401 return wrapper->wrapDouble(objID, variable, getPMxEmission(objID));
402 case VAR_NOXEMISSION:
403 return wrapper->wrapDouble(objID, variable, getNOxEmission(objID));
405 return wrapper->wrapDouble(objID, variable, getFuelConsumption(objID));
407 return wrapper->wrapDouble(objID, variable, getNoiseEmission(objID));
409 return wrapper->wrapDouble(objID, variable, getElectricityConsumption(objID));
411 return wrapper->wrapInt(objID, variable, getLastStepVehicleNumber(objID));
413 return wrapper->wrapDouble(objID, variable, getLastStepMeanSpeed(objID));
414 case VAR_FRICTION:
415 return wrapper->wrapDouble(objID, variable, getMeanFriction(objID));
417 return wrapper->wrapDouble(objID, variable, getLastStepOccupancy(objID));
419 return wrapper->wrapInt(objID, variable, getLastStepHaltingNumber(objID));
420 case LAST_STEP_LENGTH:
421 return wrapper->wrapDouble(objID, variable, getLastStepLength(objID));
422 case VAR_LANE_INDEX:
423 return wrapper->wrapInt(objID, variable, getLaneNumber(objID));
424 case VAR_NAME:
425 return wrapper->wrapString(objID, variable, getStreetName(objID));
427 return wrapper->wrapStringList(objID, variable, getPendingVehicles(objID));
429 paramData->readUnsignedByte();
430 return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
432 paramData->readUnsignedByte();
433 return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
434 default:
435 return false;
436 }
437}
438
439}
440
441
442/****************************************************************************/
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.
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
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
void rebuildAllowedLanes(const bool onInit=false)
Definition: MSEdge.cpp:300
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:945
static void insertIDs(std::vector< std::string > &into)
Inserts IDs of all known edges into the given vector.
Definition: MSEdge.cpp:1000
double getWaitingSeconds() const
return accumated waiting time for all vehicles on this edges lanes or segments
Definition: MSEdge.cpp:1424
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:1329
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:183
MSEdgeWeightsStorage & getWeightsStorage()
Returns the net's internal edge travel times/efforts container.
Definition: MSNet.cpp:1182
A list of positions.
Representation of a vehicle.
Definition: SUMOVehicle.h:62
virtual std::string readString()
Definition: storage.cpp:180
virtual int readUnsignedByte()
Definition: storage.cpp:155
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_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 VAR_CURRENT_TRAVELTIME
TRACI_CONST int VAR_ELECTRICITYCONSUMPTION