Eclipse SUMO - Simulation of Urban MObility
libsumo/Lane.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/****************************************************************************/
23// C++ TraCI client API implementation
24/****************************************************************************/
25#include <config.h>
26
27#include <microsim/MSNet.h>
28#include <microsim/MSLane.h>
29#include <microsim/MSEdge.h>
30#include <microsim/MSVehicle.h>
31#include <microsim/MSLink.h>
33#include <libsumo/Helper.h>
35#include "Lane.h"
36
37
38namespace libsumo {
39// ===========================================================================
40// static member initializations
41// ===========================================================================
42SubscriptionResults Lane::mySubscriptionResults;
43ContextSubscriptionResults Lane::myContextSubscriptionResults;
44
45
46// ===========================================================================
47// static member definitions
48// ===========================================================================
49std::vector<std::string>
50Lane::getIDList() {
51 std::vector<std::string> ids;
53 return ids;
54}
55
56
57int
58Lane::getIDCount() {
59 return (int)getIDList().size();
60}
61
62
63std::string
64Lane::getEdgeID(const std::string& laneID) {
65 return getLane(laneID)->getEdge().getID();
66}
67
68
69double
70Lane::getLength(const std::string& laneID) {
71 return getLane(laneID)->getLength();
72}
73
74
75double
76Lane::getMaxSpeed(const std::string& laneID) {
77 return getLane(laneID)->getSpeedLimit();
78}
79
80double
81Lane::getFriction(const std::string& laneID) {
82 return getLane(laneID)->getFrictionCoefficient();
83}
84
85int
86Lane::getLinkNumber(const std::string& laneID) {
87 return (int)getLane(laneID)->getLinkCont().size();
88}
89
90
91std::vector<TraCIConnection>
92Lane::getLinks(const std::string& laneID) {
93 std::vector<TraCIConnection> v;
94 const MSLane* const lane = getLane(laneID);
96 for (const MSLink* const link : lane->getLinkCont()) {
97 const std::string approachedLane = link->getLane() != nullptr ? link->getLane()->getID() : "";
98 const bool hasPrio = link->havePriority();
99 const double speed = MIN2(lane->getSpeedLimit(), link->getLane()->getSpeedLimit());
100 const bool isOpen = link->opened(currTime, speed, speed, SUMOVTypeParameter::getDefault().length,
102 const bool hasFoe = link->hasApproachingFoe(currTime, currTime, 0, SUMOVTypeParameter::getDefaultDecel());
103 const std::string approachedInternal = link->getViaLane() != nullptr ? link->getViaLane()->getID() : "";
104 const std::string state = SUMOXMLDefinitions::LinkStates.getString(link->getState());
105 const std::string direction = SUMOXMLDefinitions::LinkDirections.getString(link->getDirection());
106 const double length = link->getLength();
107 v.push_back(TraCIConnection(approachedLane, hasPrio, isOpen, hasFoe, approachedInternal, state, direction, length));
108 }
109 return v;
110}
111
112
113std::vector<std::string>
114Lane::getAllowed(const std::string& laneID) {
115 SVCPermissions permissions = getLane(laneID)->getPermissions();
116 if (permissions == SVCAll) { // special case: write nothing
117 permissions = 0;
118 }
119 return getVehicleClassNamesList(permissions);
120}
121
122
123std::vector<std::string>
124Lane::getDisallowed(const std::string& laneID) {
125 return getVehicleClassNamesList(invertPermissions((getLane(laneID)->getPermissions()))); // negation yields disallowed
126}
127
128
129std::vector<std::string>
130Lane::getChangePermissions(const std::string& laneID, const int direction) {
131 if (direction == libsumo::LANECHANGE_LEFT) {
132 return getVehicleClassNamesList(getLane(laneID)->getChangeLeft());
133 } else if (direction == libsumo::LANECHANGE_RIGHT) {
134 return getVehicleClassNamesList(getLane(laneID)->getChangeRight());
135 } else {
136 throw TraCIException("Invalid direction for change permission (must be " + toString(libsumo::LANECHANGE_LEFT) + " or " + toString(libsumo::LANECHANGE_RIGHT));
137 }
138}
139
140
141TraCIPositionVector
142Lane::getShape(const std::string& laneID) {
143 TraCIPositionVector pv;
144 const PositionVector& shp = getLane(laneID)->getShape();
145 for (PositionVector::const_iterator pi = shp.begin(); pi != shp.end(); ++pi) {
146 TraCIPosition p;
147 p.x = pi->x();
148 p.y = pi->y();
149 p.z = pi->z();
150 pv.value.push_back(p);
151 }
152 return pv;
153}
154
155
156double
157Lane::getWidth(const std::string& laneID) {
158 return getLane(laneID)->getWidth();
159}
160
161
162double
163Lane::getCO2Emission(const std::string& laneID) {
164 return getLane(laneID)->getEmissions<PollutantsInterface::CO2>();
165}
166
167
168double
169Lane::getCOEmission(const std::string& laneID) {
170 return getLane(laneID)->getEmissions<PollutantsInterface::CO>();
171}
172
173
174double
175Lane::getHCEmission(const std::string& laneID) {
176 return getLane(laneID)->getEmissions<PollutantsInterface::HC>();
177}
178
179
180double
181Lane::getPMxEmission(const std::string& laneID) {
182 return getLane(laneID)->getEmissions<PollutantsInterface::PM_X>();
183}
184
185
186double
187Lane::getNOxEmission(const std::string& laneID) {
188 return getLane(laneID)->getEmissions<PollutantsInterface::NO_X>();
189}
190
191double
192Lane::getFuelConsumption(const std::string& laneID) {
193 return getLane(laneID)->getEmissions<PollutantsInterface::FUEL>();
194}
195
196
197double
198Lane::getNoiseEmission(const std::string& laneID) {
199 return getLane(laneID)->getHarmonoise_NoiseEmissions();
200}
201
202
203double
204Lane::getElectricityConsumption(const std::string& laneID) {
205 return getLane(laneID)->getEmissions<PollutantsInterface::ELEC>();
206}
207
208
209double
210Lane::getLastStepMeanSpeed(const std::string& laneID) {
211 return getLane(laneID)->getMeanSpeed();
212}
213
214
215double
216Lane::getLastStepOccupancy(const std::string& laneID) {
217 return getLane(laneID)->getNettoOccupancy();
218}
219
220
221double
222Lane::getLastStepLength(const std::string& laneID) {
223 const MSLane* lane = getLane(laneID);
224 double length = 0;
225 const MSLane::VehCont& vehs = lane->getVehiclesSecure();
226 for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
227 length += (*j)->getVehicleType().getLength();
228 }
229 if (vehs.size() > 0) {
230 length = length / (double)vehs.size();
231 }
232 lane->releaseVehicles();
233 return length;
234}
235
236
237double
238Lane::getWaitingTime(const std::string& laneID) {
239 return getLane(laneID)->getWaitingSeconds();
240}
241
242
243double
244Lane::getTraveltime(const std::string& laneID) {
245 const MSLane* lane = getLane(laneID);
246 double meanSpeed = lane->getMeanSpeed();
247 if (meanSpeed != 0) {
248 return lane->getLength() / meanSpeed;
249 } else {
250 return 1000000.;
251 }
252}
253
254
255int
256Lane::getLastStepVehicleNumber(const std::string& laneID) {
257 return (int)getLane(laneID)->getVehicleNumber();
258}
259
260
261int
262Lane::getLastStepHaltingNumber(const std::string& laneID) {
263 const MSLane* lane = getLane(laneID);
264 int halting = 0;
265 const MSLane::VehCont& vehs = lane->getVehiclesSecure();
266 for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
267 if ((*j)->getSpeed() < SUMO_const_haltingSpeed) {
268 ++halting;
269 }
270 }
271 lane->releaseVehicles();
272 return halting;
273}
274
275
276std::vector<std::string>
277Lane::getLastStepVehicleIDs(const std::string& laneID) {
278 const MSLane* lane = getLane(laneID);
279 std::vector<std::string> vehIDs;
280 const MSLane::VehCont& vehs = lane->getVehiclesSecure();
281 for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
282 vehIDs.push_back((*j)->getID());
283 }
284 lane->releaseVehicles();
285 return vehIDs;
286}
287
288
289std::vector<std::string>
290Lane::getFoes(const std::string& laneID, const std::string& toLaneID) {
291 std::vector<std::string> foeIDs;
292 const MSLink* const link = getLane(laneID)->getLinkTo(getLane(toLaneID));
293 if (link == nullptr) {
294 throw TraCIException("No connection from lane '" + laneID + "' to lane '" + toLaneID + "'");
295 }
296 for (const MSLink* foe : link->getFoeLinks()) {
297 foeIDs.push_back(foe->getLaneBefore()->getID());
298 }
299 return foeIDs;
300}
301
302
303std::vector<std::string>
304Lane::getInternalFoes(const std::string& laneID) {
305 const MSLane* lane = getLane(laneID);
306 const std::vector<const MSLane*>* foeLanes;
307 std::vector<const MSLane*>::const_iterator it;
308 std::vector<std::string> foeIDs;
309
310 if ((lane->isInternal() || lane->isCrossing()) && lane->getLinkCont().size() > 0) {
311 MSLink* link = lane->getLinkCont().front();
312 foeLanes = &link->getFoeLanes();
313
314 for (it = foeLanes->begin(); foeLanes->end() != it; ++it) {
315 foeIDs.push_back((*it)->getID());
316 }
317 }
318 return foeIDs;
319}
320
321
322const std::vector<std::string>
323Lane::getPendingVehicles(const std::string& laneID) {
324 MSLane* const l = getLane(laneID); // validate laneID
325 std::vector<std::string> vehIDs;
326 for (const SUMOVehicle* veh : MSNet::getInstance()->getInsertionControl().getPendingVehicles()) {
327 if (veh->getLane() == l) {
328 vehIDs.push_back(veh->getID());
329 }
330 }
331 return vehIDs;
332}
333
334
335void
336Lane::setAllowed(const std::string& laneID, std::string allowedClass) {
337 setAllowed(laneID, std::vector<std::string>({allowedClass}));
338}
339
340
341void
342Lane::setAllowed(const std::string& laneID, std::vector<std::string> allowedClasses) {
343 MSLane* const l = getLane(laneID);
346}
347
348
349void
350Lane::setDisallowed(const std::string& laneID, std::string disallowedClasses) {
351 setDisallowed(laneID, std::vector<std::string>({disallowedClasses}));
352}
353
354
355void
356Lane::setDisallowed(const std::string& laneID, std::vector<std::string> disallowedClasses) {
357 MSLane* const l = getLane(laneID);
358 l->setPermissions(invertPermissions(parseVehicleClasses(disallowedClasses)), MSLane::CHANGE_PERMISSIONS_PERMANENT); // negation yields allowed
360}
361
362
363void
364Lane::setChangePermissions(const std::string& laneID, std::vector<std::string> allowedClasses, const int direction) {
365 MSLane* const l = getLane(laneID);
366 if (direction == libsumo::LANECHANGE_LEFT) {
367 l->setChangeLeft(parseVehicleClasses(allowedClasses));
368 } else if (direction == libsumo::LANECHANGE_RIGHT) {
369 l->setChangeRight(parseVehicleClasses(allowedClasses));
370 } else {
371 throw TraCIException("Invalid direction for change permission (must be " + toString(libsumo::LANECHANGE_LEFT) + " or " + toString(libsumo::LANECHANGE_RIGHT));
372 }
373}
374
375
376void
377Lane::setMaxSpeed(const std::string& laneID, double speed) {
378 getLane(laneID)->setMaxSpeed(speed);
379}
380
381
382void
383Lane::setLength(const std::string& laneID, double length) {
384 getLane(laneID)->setLength(length);
385}
386
387
388void
389Lane::setFriction(const std::string& laneID, double friction) {
390 getLane(laneID)->setFrictionCoefficient(friction);
391}
392
393
394std::string
395Lane::getParameter(const std::string& laneID, const std::string& param) {
396 return getLane(laneID)->getParameter(param, "");
397}
398
399
401
402
403void
404Lane::setParameter(const std::string& laneID, const std::string& key, const std::string& value) {
405 getLane(laneID)->setParameter(key, value);
406}
407
408
410
411
412MSLane*
413Lane::getLane(const std::string& id) {
414 MSLane* const lane = MSLane::dictionary(id);
415 if (lane == nullptr) {
416 throw TraCIException("Lane '" + id + "' is not known");
417 }
418 return lane;
419}
420
421
422void
423Lane::storeShape(const std::string& id, PositionVector& shape) {
424 shape = getLane(id)->getShape();
425}
426
427
428std::shared_ptr<VariableWrapper>
429Lane::makeWrapper() {
430 return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
431}
432
433
434bool
435Lane::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
436 switch (variable) {
437 case TRACI_ID_LIST:
438 return wrapper->wrapStringList(objID, variable, getIDList());
439 case ID_COUNT:
440 return wrapper->wrapInt(objID, variable, getIDCount());
441 case LANE_LINK_NUMBER:
442 return wrapper->wrapInt(objID, variable, getLinkNumber(objID));
443 case LANE_EDGE_ID:
444 return wrapper->wrapString(objID, variable, getEdgeID(objID));
445 case VAR_LENGTH:
446 return wrapper->wrapDouble(objID, variable, getLength(objID));
447 case VAR_MAXSPEED:
448 return wrapper->wrapDouble(objID, variable, getMaxSpeed(objID));
449 case VAR_FRICTION:
450 return wrapper->wrapDouble(objID, variable, getFriction(objID));
451 case LANE_ALLOWED:
452 return wrapper->wrapStringList(objID, variable, getAllowed(objID));
453 case LANE_DISALLOWED:
454 return wrapper->wrapStringList(objID, variable, getDisallowed(objID));
455 case LANE_CHANGES:
456 paramData->readUnsignedByte();
457 return wrapper->wrapStringList(objID, variable, getChangePermissions(objID, paramData->readByte()));
458 case VAR_CO2EMISSION:
459 return wrapper->wrapDouble(objID, variable, getCO2Emission(objID));
460 case VAR_COEMISSION:
461 return wrapper->wrapDouble(objID, variable, getCOEmission(objID));
462 case VAR_HCEMISSION:
463 return wrapper->wrapDouble(objID, variable, getHCEmission(objID));
464 case VAR_PMXEMISSION:
465 return wrapper->wrapDouble(objID, variable, getPMxEmission(objID));
466 case VAR_NOXEMISSION:
467 return wrapper->wrapDouble(objID, variable, getNOxEmission(objID));
469 return wrapper->wrapDouble(objID, variable, getFuelConsumption(objID));
471 return wrapper->wrapDouble(objID, variable, getNoiseEmission(objID));
473 return wrapper->wrapDouble(objID, variable, getElectricityConsumption(objID));
475 return wrapper->wrapInt(objID, variable, getLastStepVehicleNumber(objID));
477 return wrapper->wrapDouble(objID, variable, getLastStepMeanSpeed(objID));
479 return wrapper->wrapStringList(objID, variable, getLastStepVehicleIDs(objID));
481 return wrapper->wrapDouble(objID, variable, getLastStepOccupancy(objID));
483 return wrapper->wrapInt(objID, variable, getLastStepHaltingNumber(objID));
484 case LAST_STEP_LENGTH:
485 return wrapper->wrapDouble(objID, variable, getLastStepLength(objID));
486 case VAR_WAITING_TIME:
487 return wrapper->wrapDouble(objID, variable, getWaitingTime(objID));
489 return wrapper->wrapDouble(objID, variable, getTraveltime(objID));
490 case VAR_WIDTH:
491 return wrapper->wrapDouble(objID, variable, getWidth(objID));
492 case VAR_SHAPE:
493 return wrapper->wrapPositionVector(objID, variable, getShape(objID));
495 return wrapper->wrapStringList(objID, variable, getPendingVehicles(objID));
497 paramData->readUnsignedByte();
498 return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
500 paramData->readUnsignedByte();
501 return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
502 default:
503 return false;
504 }
505}
506}
507
508
509/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
const SVCPermissions SVCAll
all VClasses are allowed
SVCPermissions invertPermissions(SVCPermissions permissions)
negate the given permissions and ensure that only relevant bits are set
const std::vector< std::string > & getVehicleClassNamesList(SVCPermissions permissions)
Returns the ids of the given classes, divided using a ' '.
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
T MIN2(T a, T b)
Definition: StdDefs.h:76
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:58
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
#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.
void rebuildAllowedLanes(const bool onInit=false)
Definition: MSEdge.cpp:300
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
static void insertIDs(std::vector< std::string > &into)
Adds the ids of all stored lanes into the given vector.
Definition: MSLane.cpp:2266
void setChangeRight(SVCPermissions permissions)
Sets the permissions for changing to the right neighbour lane.
Definition: MSLane.cpp:4234
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:579
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:119
static const long CHANGE_PERMISSIONS_PERMANENT
Definition: MSLane.h:1329
double getLength() const
Returns the lane's length.
Definition: MSLane.h:593
void setChangeLeft(SVCPermissions permissions)
Sets the permissions for changing to the left neighbour lane.
Definition: MSLane.cpp:4228
void setPermissions(SVCPermissions permissions, long long transientID)
Sets the permissions to the given value. If a transientID is given, the permissions are recored as te...
Definition: MSLane.cpp:4195
bool isCrossing() const
Definition: MSLane.cpp:2377
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:2234
bool isInternal() const
Definition: MSLane.cpp:2365
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:474
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:504
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:745
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.h:707
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:3131
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:183
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:320
A list of positions.
static double getDefaultDecel(const SUMOVehicleClass vc=SVC_IGNORING)
Returns the default deceleration for the given vehicle class This needs to be a function because the ...
static const SUMOVTypeParameter & getDefault()
return the default parameters, this is a function due to the http://www.parashift....
Representation of a vehicle.
Definition: SUMOVehicle.h:62
static StringBijection< LinkState > LinkStates
link states
static StringBijection< LinkDirection > LinkDirections
link directions
const std::string & getString(const T key) const
virtual std::string readString()
Definition: storage.cpp:180
virtual int readUnsignedByte()
Definition: storage.cpp:155
virtual int readByte()
Definition: storage.cpp:128
TRACI_CONST int LAST_STEP_VEHICLE_ID_LIST
TRACI_CONST int LAST_STEP_VEHICLE_NUMBER
TRACI_CONST int VAR_NOXEMISSION
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 LANE_LINK_NUMBER
TRACI_CONST int LANE_CHANGES
TRACI_CONST int LAST_STEP_LENGTH
TRACI_CONST int LANE_EDGE_ID
TRACI_CONST int VAR_PMXEMISSION
TRACI_CONST int VAR_COEMISSION
TRACI_CONST int VAR_WIDTH
TRACI_CONST int VAR_MAXSPEED
TRACI_CONST int LAST_STEP_MEAN_SPEED
TRACI_CONST int VAR_CO2EMISSION
TRACI_CONST int LANECHANGE_RIGHT
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 VAR_SHAPE
TRACI_CONST int LAST_STEP_VEHICLE_HALTING_NUMBER
TRACI_CONST int VAR_LENGTH
TRACI_CONST int VAR_HCEMISSION
TRACI_CONST int ID_COUNT
TRACI_CONST int VAR_PARAMETER
TRACI_CONST int LANECHANGE_LEFT
TRACI_CONST int LAST_STEP_OCCUPANCY
TRACI_CONST int VAR_NOISEEMISSION
TRACI_CONST int LANE_DISALLOWED
TRACI_CONST int VAR_PARAMETER_WITH_KEY
TRACI_CONST int VAR_FRICTION
TRACI_CONST int VAR_CURRENT_TRAVELTIME
TRACI_CONST int LANE_ALLOWED
TRACI_CONST int VAR_ELECTRICITYCONSUMPTION