Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/libsumo/Edge.cpp
169665 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2017-2025 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
/****************************************************************************/
14
/// @file Edge.cpp
15
/// @author Gregor Laemmel
16
/// @date 15.09.2017
17
///
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>
25
#include <microsim/MSEdgeWeightsStorage.h>
26
#include <microsim/transportables/MSTransportable.h>
27
#include <microsim/MSVehicle.h>
28
#include <microsim/MSInsertionControl.h>
29
#include <libsumo/Helper.h>
30
#include <libsumo/StorageHelper.h>
31
#include <libsumo/TraCIDefs.h>
32
#include <libsumo/TraCIConstants.h>
33
#include <libsumo/Lane.h>
34
#include <utils/emissions/HelpersHarmonoise.h>
35
#include "Edge.h"
36
37
38
namespace libsumo {
39
// ===========================================================================
40
// static member initializations
41
// ===========================================================================
42
SubscriptionResults Edge::mySubscriptionResults;
43
ContextSubscriptionResults Edge::myContextSubscriptionResults;
44
45
46
// ===========================================================================
47
// static member definitions
48
// ===========================================================================
49
std::vector<std::string>
50
Edge::getIDList() {
51
MSNet::getInstance(); // just to check that we actually have a network
52
std::vector<std::string> ids;
53
MSEdge::insertIDs(ids);
54
return ids;
55
}
56
57
58
int
59
Edge::getIDCount() {
60
return (int)getIDList().size();
61
}
62
63
64
double
65
Edge::getAdaptedTraveltime(const std::string& edgeID, double time) {
66
const MSEdge* e = getEdge(edgeID);
67
double value;
68
if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingTravelTime(e, time, value)) {
69
return -1.;
70
}
71
return value;
72
}
73
74
75
double
76
Edge::getEffort(const std::string& edgeID, double time) {
77
const MSEdge* e = getEdge(edgeID);
78
double value;
79
if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, time, value)) {
80
return -1.;
81
}
82
return value;
83
}
84
85
86
double
87
Edge::getTraveltime(const std::string& edgeID) {
88
return getEdge(edgeID)->getCurrentTravelTime();
89
}
90
91
92
MSEdge*
93
Edge::getEdge(const std::string& edgeID) {
94
MSEdge* e = MSEdge::dictionary(edgeID);
95
if (e == nullptr) {
96
throw TraCIException("Edge '" + edgeID + "' is not known");
97
}
98
return e;
99
}
100
101
102
double
103
Edge::getWaitingTime(const std::string& edgeID) {
104
return getEdge(edgeID)->getWaitingSeconds();
105
}
106
107
108
const std::vector<std::string>
109
Edge::getLastStepPersonIDs(const std::string& edgeID) {
110
std::vector<std::string> personIDs;
111
std::vector<MSTransportable*> persons = getEdge(edgeID)->getSortedPersons(MSNet::getInstance()->getCurrentTimeStep(), true);
112
personIDs.reserve(persons.size());
113
for (MSTransportable* p : persons) {
114
personIDs.push_back(p->getID());
115
}
116
return personIDs;
117
}
118
119
120
const std::vector<std::string>
121
Edge::getLastStepVehicleIDs(const std::string& edgeID) {
122
std::vector<std::string> vehIDs;
123
for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
124
vehIDs.push_back(veh->getID());
125
}
126
return vehIDs;
127
}
128
129
130
double
131
Edge::getCO2Emission(const std::string& edgeID) {
132
double sum = 0;
133
for (MSLane* lane : getEdge(edgeID)->getLanes()) {
134
sum += lane->getEmissions<PollutantsInterface::CO2>();
135
}
136
return sum;
137
}
138
139
140
double
141
Edge::getCOEmission(const std::string& edgeID) {
142
double sum = 0;
143
for (MSLane* lane : getEdge(edgeID)->getLanes()) {
144
sum += lane->getEmissions<PollutantsInterface::CO>();
145
}
146
return sum;
147
}
148
149
150
double
151
Edge::getHCEmission(const std::string& edgeID) {
152
double sum = 0;
153
for (MSLane* lane : getEdge(edgeID)->getLanes()) {
154
sum += lane->getEmissions<PollutantsInterface::HC>();
155
}
156
return sum;
157
}
158
159
160
double
161
Edge::getPMxEmission(const std::string& edgeID) {
162
double sum = 0;
163
for (MSLane* lane : getEdge(edgeID)->getLanes()) {
164
sum += lane->getEmissions<PollutantsInterface::PM_X>();
165
}
166
return sum;
167
}
168
169
170
double
171
Edge::getNOxEmission(const std::string& edgeID) {
172
double sum = 0;
173
for (MSLane* lane : getEdge(edgeID)->getLanes()) {
174
sum += lane->getEmissions<PollutantsInterface::NO_X>();
175
}
176
return sum;
177
}
178
179
180
double
181
Edge::getFuelConsumption(const std::string& edgeID) {
182
double sum = 0;
183
for (MSLane* lane : getEdge(edgeID)->getLanes()) {
184
sum += lane->getEmissions<PollutantsInterface::FUEL>();
185
}
186
return sum;
187
}
188
189
190
double
191
Edge::getNoiseEmission(const std::string& edgeID) {
192
double sum = 0;
193
for (MSLane* lane : getEdge(edgeID)->getLanes()) {
194
sum += pow(10., (lane->getHarmonoise_NoiseEmissions() / 10.));
195
}
196
if (sum != 0) {
197
return HelpersHarmonoise::sum(sum);
198
}
199
return sum;
200
}
201
202
203
double
204
Edge::getElectricityConsumption(const std::string& edgeID) {
205
double sum = 0;
206
for (MSLane* lane : getEdge(edgeID)->getLanes()) {
207
sum += lane->getEmissions<PollutantsInterface::ELEC>();
208
}
209
return sum;
210
}
211
212
213
int
214
Edge::getLastStepVehicleNumber(const std::string& edgeID) {
215
return getEdge(edgeID)->getVehicleNumber();
216
}
217
218
219
double
220
Edge::getLastStepMeanSpeed(const std::string& edgeID) {
221
return getEdge(edgeID)->getMeanSpeed();
222
}
223
224
double
225
Edge::getMeanFriction(const std::string& edgeID) {
226
return getEdge(edgeID)->getMeanFriction();
227
}
228
229
230
double
231
Edge::getLastStepOccupancy(const std::string& edgeID) {
232
return getEdge(edgeID)->getOccupancy();
233
}
234
235
236
int
237
Edge::getLastStepHaltingNumber(const std::string& edgeID) {
238
int result = 0;
239
for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
240
if (veh->getSpeed() < SUMO_const_haltingSpeed) {
241
result++;
242
}
243
}
244
return result;
245
}
246
247
248
double
249
Edge::getLastStepLength(const std::string& edgeID) {
250
double lengthSum = 0;
251
int numVehicles = 0;
252
for (const SUMOVehicle* veh : getEdge(edgeID)->getVehicles()) {
253
numVehicles++;
254
lengthSum += dynamic_cast<const MSBaseVehicle*>(veh)->getVehicleType().getLength();
255
}
256
if (numVehicles == 0) {
257
return 0;
258
}
259
return lengthSum / numVehicles;
260
}
261
262
263
int
264
Edge::getLaneNumber(const std::string& edgeID) {
265
return (int)getEdge(edgeID)->getLanes().size();
266
}
267
268
269
std::string
270
Edge::getStreetName(const std::string& edgeID) {
271
return getEdge(edgeID)->getStreetName();
272
}
273
274
275
const std::vector<std::string>
276
Edge::getPendingVehicles(const std::string& edgeID) {
277
getEdge(edgeID); // validate edgeID
278
std::vector<std::string> vehIDs;
279
for (const SUMOVehicle* veh : MSNet::getInstance()->getInsertionControl().getPendingVehicles()) {
280
if (veh->getEdge()->getID() == edgeID) {
281
vehIDs.push_back(veh->getID());
282
}
283
}
284
return vehIDs;
285
}
286
287
288
double
289
Edge::getAngle(const std::string& edgeID, double relativePosition) {
290
const std::vector<MSLane*>& lanes = getEdge(edgeID)->getLanes();
291
return lanes.empty() ? libsumo::INVALID_DOUBLE_VALUE : Lane::getAngle(lanes.front()->getID(), relativePosition);
292
}
293
294
std::string
295
Edge::getFromJunction(const std::string& edgeID) {
296
return getEdge(edgeID)->getFromJunction()->getID();
297
}
298
299
std::string
300
Edge::getToJunction(const std::string& edgeID) {
301
return getEdge(edgeID)->getToJunction()->getID();
302
}
303
304
std::string
305
Edge::getBidiEdge(const std::string& edgeID) {
306
const MSEdge* bidi = getEdge(edgeID)->getBidiEdge();
307
return bidi == nullptr ? "" : bidi->getID();
308
}
309
310
std::string
311
Edge::getParameter(const std::string& edgeID, const std::string& param) {
312
return getEdge(edgeID)->getParameter(param, "");
313
}
314
315
316
LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(Edge)
317
318
319
void
320
Edge::setAllowed(const std::string& edgeID, std::string allowedClasses) {
321
setAllowedSVCPermissions(edgeID, parseVehicleClasses(allowedClasses));
322
}
323
324
325
void
326
Edge::setAllowed(const std::string& edgeID, std::vector<std::string> allowedClasses) {
327
setAllowedSVCPermissions(edgeID, parseVehicleClasses(allowedClasses));
328
}
329
330
331
void
332
Edge::setDisallowed(const std::string& edgeID, std::string disallowedClasses) {
333
setAllowedSVCPermissions(edgeID, invertPermissions(parseVehicleClasses(disallowedClasses)));
334
}
335
336
337
void
338
Edge::setDisallowed(const std::string& edgeID, std::vector<std::string> disallowedClasses) {
339
setAllowedSVCPermissions(edgeID, invertPermissions(parseVehicleClasses(disallowedClasses)));
340
}
341
342
343
void
344
Edge::setAllowedSVCPermissions(const std::string& edgeID, long long int permissions) {
345
MSEdge* e = getEdge(edgeID);
346
for (MSLane* lane : e->getLanes()) {
347
lane->setPermissions(permissions, MSLane::CHANGE_PERMISSIONS_PERMANENT);
348
}
349
e->rebuildAllowedLanes(false, true);
350
}
351
352
353
void
354
Edge::adaptTraveltime(const std::string& edgeID, double time, double beginSeconds, double endSeconds) {
355
MSNet::getInstance()->getWeightsStorage().addTravelTime(getEdge(edgeID), beginSeconds, endSeconds, time);
356
}
357
358
359
void
360
Edge::setEffort(const std::string& edgeID, double effort, double beginSeconds, double endSeconds) {
361
MSNet::getInstance()->getWeightsStorage().addEffort(getEdge(edgeID), beginSeconds, endSeconds, effort);
362
}
363
364
365
void
366
Edge::setMaxSpeed(const std::string& edgeID, double speed) {
367
getEdge(edgeID)->setMaxSpeed(speed);
368
}
369
370
void
371
Edge::setFriction(const std::string& edgeID, double friction) {
372
for (MSLane* lane : getEdge(edgeID)->getLanes()) {
373
lane->setFrictionCoefficient(friction);
374
}
375
}
376
377
void
378
Edge::setParameter(const std::string& edgeID, const std::string& name, const std::string& value) {
379
getEdge(edgeID)->setParameter(name, value);
380
}
381
382
383
LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(Edge, EDGE)
384
385
386
void
387
Edge::storeShape(const std::string& edgeID, PositionVector& shape) {
388
const MSEdge* const e = getEdge(edgeID);
389
for (const MSLane* lane : e->getLanes()) {
390
copy(lane->getShape().begin(), lane->getShape().end(), back_inserter(shape));
391
}
392
}
393
394
395
std::shared_ptr<VariableWrapper>
396
Edge::makeWrapper() {
397
return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
398
}
399
400
401
bool
402
Edge::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
403
switch (variable) {
404
case TRACI_ID_LIST:
405
return wrapper->wrapStringList(objID, variable, getIDList());
406
case ID_COUNT:
407
return wrapper->wrapInt(objID, variable, getIDCount());
408
case VAR_EDGE_TRAVELTIME:
409
return wrapper->wrapDouble(objID, variable, getAdaptedTraveltime(objID, StoHelp::readTypedDouble(*paramData)));
410
case VAR_EDGE_EFFORT:
411
return wrapper->wrapDouble(objID, variable, getEffort(objID, StoHelp::readTypedDouble(*paramData)));
412
case VAR_CURRENT_TRAVELTIME:
413
return wrapper->wrapDouble(objID, variable, getTraveltime(objID));
414
case VAR_WAITING_TIME:
415
return wrapper->wrapDouble(objID, variable, getWaitingTime(objID));
416
case LAST_STEP_PERSON_ID_LIST:
417
return wrapper->wrapStringList(objID, variable, getLastStepPersonIDs(objID));
418
case LAST_STEP_VEHICLE_ID_LIST:
419
return wrapper->wrapStringList(objID, variable, getLastStepVehicleIDs(objID));
420
case VAR_CO2EMISSION:
421
return wrapper->wrapDouble(objID, variable, getCO2Emission(objID));
422
case VAR_COEMISSION:
423
return wrapper->wrapDouble(objID, variable, getCOEmission(objID));
424
case VAR_HCEMISSION:
425
return wrapper->wrapDouble(objID, variable, getHCEmission(objID));
426
case VAR_PMXEMISSION:
427
return wrapper->wrapDouble(objID, variable, getPMxEmission(objID));
428
case VAR_NOXEMISSION:
429
return wrapper->wrapDouble(objID, variable, getNOxEmission(objID));
430
case VAR_FUELCONSUMPTION:
431
return wrapper->wrapDouble(objID, variable, getFuelConsumption(objID));
432
case VAR_NOISEEMISSION:
433
return wrapper->wrapDouble(objID, variable, getNoiseEmission(objID));
434
case VAR_ELECTRICITYCONSUMPTION:
435
return wrapper->wrapDouble(objID, variable, getElectricityConsumption(objID));
436
case LAST_STEP_VEHICLE_NUMBER:
437
return wrapper->wrapInt(objID, variable, getLastStepVehicleNumber(objID));
438
case LAST_STEP_MEAN_SPEED:
439
return wrapper->wrapDouble(objID, variable, getLastStepMeanSpeed(objID));
440
case VAR_FRICTION:
441
return wrapper->wrapDouble(objID, variable, getMeanFriction(objID));
442
case LAST_STEP_OCCUPANCY:
443
return wrapper->wrapDouble(objID, variable, getLastStepOccupancy(objID));
444
case LAST_STEP_VEHICLE_HALTING_NUMBER:
445
return wrapper->wrapInt(objID, variable, getLastStepHaltingNumber(objID));
446
case LAST_STEP_LENGTH:
447
return wrapper->wrapDouble(objID, variable, getLastStepLength(objID));
448
case VAR_LANE_INDEX:
449
return wrapper->wrapInt(objID, variable, getLaneNumber(objID));
450
case VAR_NAME:
451
return wrapper->wrapString(objID, variable, getStreetName(objID));
452
case VAR_PENDING_VEHICLES:
453
return wrapper->wrapStringList(objID, variable, getPendingVehicles(objID));
454
case VAR_ANGLE:
455
return wrapper->wrapDouble(objID, variable, getAngle(objID, StoHelp::readTypedDouble(*paramData)));
456
case FROM_JUNCTION:
457
return wrapper->wrapString(objID, variable, getFromJunction(objID));
458
case TO_JUNCTION:
459
return wrapper->wrapString(objID, variable, getToJunction(objID));
460
case VAR_BIDI:
461
return wrapper->wrapString(objID, variable, getBidiEdge(objID));
462
case VAR_PARAMETER:
463
return wrapper->wrapString(objID, variable, getParameter(objID, StoHelp::readTypedString(*paramData)));
464
case VAR_PARAMETER_WITH_KEY:
465
return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, StoHelp::readTypedString(*paramData)));
466
default:
467
return false;
468
}
469
}
470
471
}
472
473
474
/****************************************************************************/
475
476