Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSInductLoop.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2026 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/****************************************************************************/
24// An unextended detector measuring at a fixed position on a fixed lane.
25/****************************************************************************/
26#include <config.h>
27
28#include "MSInductLoop.h"
29#include <cassert>
30#include <numeric>
31#include <utility>
32#ifdef HAVE_FOX
34#endif
38#include <microsim/MSLane.h>
39#include <microsim/MSEdge.h>
40#include <microsim/MSVehicle.h>
41#include <microsim/MSNet.h>
49
50#define HAS_NOT_LEFT_DETECTOR -1
51
52//#define DEBUG_E1_NOTIFY_MOVE
53
54#define DEBUG_COND (true)
55//#define DEBUG_COND (isSelected())
56//#define DEBUG_COND (getID()=="")
57
58// ===========================================================================
59// method definitions
60// ===========================================================================
61MSInductLoop::MSInductLoop(const std::string& id, MSLane* const lane,
62 double positionInMeters,
63 double length, std::string name,
64 const std::string& vTypes,
65 const std::string& nextEdges,
66 int detectPersons,
67 const bool needLocking) :
68 MSMoveReminder(id, lane),
69 MSDetectorFileOutput(id, vTypes, nextEdges, detectPersons),
70 myName(name),
71 myPosition(positionInMeters),
72 myEndPosition(myPosition + length),
73 myNeedLock(needLocking || MSGlobals::gNumSimThreads > 1),
74 // initialize in a way which doesn't impact actualted traffic lights at simulation start (yet doesn't look ugly in the outputs)
75 myLastLeaveTime(-3600),
76 myOverrideTime(-1),
77 myOverrideEntryTime(-1),
78 myVehicleDataCont(),
79 myVehiclesOnDet(),
80 myLastIntervalEnd(-1) {
81 assert(length >= 0);
82 assert(myPosition >= 0 && myEndPosition <= myLane->getLength());
83 reset();
84}
85
86
89
90
91void
102
103
104bool
105MSInductLoop::notifyEnter(SUMOTrafficObject& veh, Notification reason, const MSLane* /* enteredLane */) {
106 // vehicles must be kept if the "inductionloop" wants to detect passeengers
107 if (!vehicleApplies(veh) && (veh.isPerson() || myDetectPersons <= (int)PersonMode::WALK)) {
108 return false;
109 }
110 if (reason != NOTIFICATION_JUNCTION) { // the junction case is handled in notifyMove
112 return false;
113 }
114 if (veh.getPositionOnLane() >= myPosition) {
115#ifdef HAVE_FOX
116 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
117#endif
118 myVehiclesOnDet[&veh] = SIMTIME;
120 }
121 }
122 return true;
123}
124
125
126bool
128 double newPos, double newSpeed) {
129 if (newPos < myPosition) {
130 // detector not reached yet
131 return true;
132 }
133 if (myDetectPersons > (int)PersonMode::WALK && !veh.isPerson()) {
134 bool keep = false;
135 MSBaseVehicle& v = dynamic_cast<MSBaseVehicle&>(veh);
136 for (MSTransportable* p : v.getPersons()) {
137 keep = notifyMove(*p, oldPos, newPos, newSpeed);
138 }
139 return keep;
140 }
141#ifdef HAVE_FOX
142 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
143#endif
144 const double oldSpeed = veh.getPreviousSpeed();
145 if (newPos >= myPosition && oldPos < myPosition) {
146 // entered the detector by move
147 const double timeBeforeEnter = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
148 myVehiclesOnDet[&veh] = SIMTIME + timeBeforeEnter;
150#ifdef DEBUG_E1_NOTIFY_MOVE
151 if (DEBUG_COND) {
152 std::cout << SIMTIME << " det=" << getID() << " enteredVeh=" << veh.getID() << "\n";
153 }
154#endif
155 }
156 double oldBackPos = oldPos - veh.getVehicleType().getLength();
157 double newBackPos = newPos - veh.getVehicleType().getLength();
158 if (newBackPos > myEndPosition) {
159 // vehicle passed the detector (it may have changed onto this lane somewhere past the detector)
160 // assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed > 0 || myVehiclesOnDet.find(&veh) == myVehiclesOnDet.end());
161 // assertion is invalid in case of teleportation
162 if (oldBackPos <= myEndPosition) {
163 const std::map<SUMOTrafficObject*, double>::iterator it = myVehiclesOnDet.find(&veh);
164 if (it != myVehiclesOnDet.end()) {
165 const double entryTime = it->second;
166 const double leaveTime = SIMTIME + MSCFModel::passingTime(oldBackPos, myEndPosition, newBackPos, oldSpeed, newSpeed);
167 myVehiclesOnDet.erase(it);
168 assert(entryTime <= leaveTime);
169 myVehicleDataCont.push_back(VehicleData(veh, entryTime, leaveTime, false, myEndPosition - myPosition));
170 myLastLeaveTime = leaveTime;
171#ifdef DEBUG_E1_NOTIFY_MOVE
172 if (DEBUG_COND) {
173 std::cout << SIMTIME << " det=" << getID() << " leftVeh=" << veh.getID() << " oldBackPos=" << oldBackPos << " newBackPos=" << newBackPos << "\n";
174 }
175#endif
176 } else {
177#ifdef DEBUG_E1_NOTIFY_MOVE
178 if (DEBUG_COND) {
179 std::cout << SIMTIME << " det=" << getID() << " leftVeh=" << veh.getID() << " oldBackPos=" << oldBackPos << " newBackPos=" << newBackPos << " (notFound)\n";
180 }
181#endif
182 }
183 } else {
184 // vehicle is already beyond the detector...
185 // This can happen even if it is still registered in myVehiclesOnDet, e.g., after teleport.
186 myVehiclesOnDet.erase(&veh);
187#ifdef DEBUG_E1_NOTIFY_MOVE
188 if (DEBUG_COND) {
189 std::cout << SIMTIME << " det=" << getID() << " leftVeh=" << veh.getID() << " oldBackPos=" << oldBackPos << " newBackPos=" << newBackPos << " (unusual)\n";
190 }
191#endif
192 }
193 return false;
194 }
195 // vehicle stays on the detector
196 return true;
197}
198
199
200bool
201MSInductLoop::notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
202 if (veh.isPerson() && myDetectPersons != (int)PersonMode::NONE) {
203 const int lastDir = lastPos < 0 ? MSPModel::BACKWARD : MSPModel::FORWARD;
204 notifyMovePerson(dynamic_cast<MSTransportable*>(&veh), lastDir, lastPos);
205 }
207#ifdef HAVE_FOX
208 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
209#endif
210 const std::map<SUMOTrafficObject*, double>::iterator it = myVehiclesOnDet.find(&veh);
211 if (it != myVehiclesOnDet.end()) {
212 const double entryTime = it->second;
213 const double leaveTime = SIMTIME + TS;
214 myVehiclesOnDet.erase(it);
215 myVehicleDataCont.push_back(VehicleData(veh, entryTime, leaveTime, true));
216 myLastLeaveTime = leaveTime;
217 }
218 return false;
219 }
220 return true;
221}
222
223
224double
225MSInductLoop::getSpeed(const int offset) const {
226 const std::vector<VehicleData>& d = collectVehiclesOnDet(SIMSTEP - offset);
227 return d.empty() ? -1. : std::accumulate(d.begin(), d.end(), 0.0, speedSum) / (double) d.size();
228}
229
230
231double
232MSInductLoop::getVehicleLength(const int offset) const {
233 const std::vector<VehicleData>& d = collectVehiclesOnDet(SIMSTEP - offset);
234 return d.empty() ? -1. : std::accumulate(d.begin(), d.end(), 0.0, lengthSum) / (double)d.size();
235}
236
237
238double
240 if (myOverrideTime >= 0) {
241 return myOverrideTime < TS ? (TS - myOverrideTime) / TS * 100 : 0;
242 }
243 const SUMOTime tbeg = SIMSTEP - DELTA_T;
244 double occupancy = 0;
245 const double csecond = SIMTIME;
246 for (const VehicleData& i : collectVehiclesOnDet(tbeg, false, false, true)) {
247 const double leaveTime = i.leaveTimeM == HAS_NOT_LEFT_DETECTOR ? csecond : MIN2(i.leaveTimeM, csecond);
248 const double entryTime = MAX2(i.entryTimeM, STEPS2TIME(tbeg));
249 occupancy += MIN2(leaveTime - entryTime, TS);
250 }
251 return occupancy / TS * 100.;
252}
253
254
255double
256MSInductLoop::getEnteredNumber(const int offset) const {
257 if (myOverrideTime >= 0) {
258 return myOverrideTime < TS ? 1 : 0;
259 }
260 return (double)collectVehiclesOnDet(SIMSTEP - offset, true, true).size();
261}
262
263
264std::vector<std::string>
265MSInductLoop::getVehicleIDs(const int offset) const {
266 std::vector<std::string> ret;
267 for (const VehicleData& i : collectVehiclesOnDet(SIMSTEP - offset, true, true)) {
268 ret.push_back(i.idM);
269 }
270 return ret;
271}
272
273
274double
276 if (myOverrideTime >= 0) {
277 return myOverrideTime;
278 }
279 if (myVehiclesOnDet.size() != 0) {
280 // detector is occupied
281 return 0;
282 }
283 return SIMTIME - myLastLeaveTime;
284}
285
286
287void
291
292
293double
295#ifdef HAVE_FOX
296 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
297#endif
298 if (myOverrideTime >= 0) {
300 }
301 if (myVehiclesOnDet.size() == 0) {
302 // detector is unoccupied
303 return 0;
304 } else {
305 double minEntry = std::numeric_limits<double>::max();
306 for (const auto& i : myVehiclesOnDet) {
307 minEntry = MIN2(i.second, minEntry);
308 }
309 return SIMTIME - minEntry;
310 }
311}
312
313
314double
316#ifdef HAVE_FOX
317 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
318#endif
320 double result = -INVALID_DOUBLE;
321 for (const auto& item : collectVehiclesOnDet(SIMSTEP - DELTA_T)) {
322 SUMOVehicle* v = vc.getVehicle(item.idM);
323 if (v != nullptr) {
324 MSBaseVehicle* veh = dynamic_cast<MSBaseVehicle*>(v);
325 double ad = veh->getStopArrivalDelay();
326 if (ad != INVALID_DOUBLE) {
327 result = MAX2(result, ad);
328 }
329 }
330 }
331 return result;
332}
333
334
337 if (myOverrideTime >= 0) {
339 }
340 if (myVehiclesOnDet.size() != 0) {
342 }
344}
345
346
347double
348MSInductLoop::getIntervalOccupancy(bool lastInterval) const {
349 double occupancy = 0;
350 const double csecond = lastInterval ? STEPS2TIME(myLastIntervalEnd) : SIMTIME;
351 const double aggTime = csecond - STEPS2TIME(lastInterval ? myLastIntervalBegin : myLastIntervalEnd);
352 if (aggTime == 0) {
353 return 0;
354 }
355 for (const VehicleData& i : collectVehiclesOnDet(myLastIntervalEnd, false, false, true, lastInterval)) {
356 const double leaveTime = i.leaveTimeM == HAS_NOT_LEFT_DETECTOR ? csecond : MIN2(i.leaveTimeM, csecond);
357 const double entryTime = MAX2(i.entryTimeM, STEPS2TIME(lastInterval ? myLastIntervalBegin : myLastIntervalEnd));
358 occupancy += MIN2(leaveTime - entryTime, aggTime);
359 }
360 return occupancy / aggTime * 100.;
361}
362
363
364double
365MSInductLoop::getIntervalMeanSpeed(bool lastInterval) const {
366 const std::vector<VehicleData>& d = collectVehiclesOnDet(myLastIntervalEnd, false, false, false, lastInterval);
367 return d.empty() ? -1. : std::accumulate(d.begin(), d.end(), 0.0, speedSum) / (double) d.size();
368}
369
370
371int
373 return (int)collectVehiclesOnDet(myLastIntervalEnd, false, false, false, lastInterval).size();
374}
375
376
377std::vector<std::string>
378MSInductLoop::getIntervalVehicleIDs(bool lastInterval) const {
379 std::vector<std::string> ret;
380 for (const VehicleData& i : collectVehiclesOnDet(myLastIntervalEnd, false, false, false, lastInterval)) {
381 ret.push_back(i.idM);
382 }
383 return ret;
384}
385
386
387void
389 myOverrideTime = time;
390 if (time < 0) {
392 } else {
393 const double entryTime = MAX2(0.0, SIMTIME - time);
394 if (myOverrideEntryTime >= 0) {
395 // maintain earlier entry time to achive continous detection
397 } else {
398 myOverrideEntryTime = entryTime;
399 }
400 }
401}
402
403void
405 dev.writeXMLHeader("detector", "det_e1_file.xsd");
406}
407
408
409void
411 if (dev.isNull()) {
412 reset();
413 return;
414 }
415 const double t(STEPS2TIME(stopTime - startTime));
416 double occupancy = 0.;
417 double speedSum = 0.;
418 double lengthSum = 0.;
419 int contrib = 0;
420 // to approximate the space mean speed
421 double inverseSpeedSum = 0.;
422 for (const VehicleData& vData : myVehicleDataCont) {
423 const double timeOnDetDuringInterval = vData.leaveTimeM - MAX2(STEPS2TIME(startTime), vData.entryTimeM);
424 occupancy += MIN2(timeOnDetDuringInterval, t);
425 if (!vData.leftEarlyM) {
426 speedSum += vData.speedM;
427 assert(vData.speedM > 0.);
428 inverseSpeedSum += 1. / vData.speedM;
429 lengthSum += vData.lengthM;
430 contrib++;
431 }
432 }
433 const double flow = (double)contrib / t * 3600.;
434 for (std::map< SUMOTrafficObject*, double >::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
435 occupancy += STEPS2TIME(stopTime) - MAX2(STEPS2TIME(startTime), i->second);
436 }
437 occupancy *= 100. / t;
438 const double meanSpeed = contrib != 0 ? speedSum / (double)contrib : -1;
439 const double harmonicMeanSpeed = contrib != 0 ? (double)contrib / inverseSpeedSum : -1;
440 const double meanLength = contrib != 0 ? lengthSum / (double)contrib : -1;
442 dev.writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML(getID())).writeAttr("nVehContrib", contrib);
443 dev.writeAttr("flow", flow).writeAttr("occupancy", occupancy).writeAttr("speed", meanSpeed).writeAttr("harmonicMeanSpeed", harmonicMeanSpeed);
444 dev.writeAttr("length", meanLength).writeAttr("nVehEntered", myEnteredVehicleNumber).closeTag();
445 reset();
446}
447
448
449void
451 if (myDetectPersons == (int)PersonMode::NONE) {
452 return;
453 }
454 if (myLane->hasPedestrians()) {
455 for (MSTransportable* p : myLane->getEdge().getPersons()) {
456 if (p->getLane() != myLane || !vehicleApplies(*p)) {
457 continue;
458 }
459 notifyMovePerson(p, p->getDirection(), p->getPositionOnLane());
460 }
461 }
462}
463
464
465void
467 if (personApplies(*p, dir)) {
468 const double newSpeed = p->getSpeed();
469 const double newPos = (dir == MSPModel::FORWARD
470 ? pos
471 // position relative to detector
472 : myPosition - (pos - myPosition));
473 const double oldPos = newPos - SPEED2DIST(newSpeed);
474 if (oldPos - p->getVehicleType().getLength() <= myPosition) {
475 notifyMove(*p, oldPos, newPos, newSpeed);
476 }
477 }
478}
479
480
481std::vector<MSInductLoop::VehicleData>
482MSInductLoop::collectVehiclesOnDet(SUMOTime tMS, bool includeEarly, bool leaveTime, bool forOccupancy, bool lastInterval) const {
483#ifdef HAVE_FOX
484 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
485#endif
486 const double t = STEPS2TIME(tMS);
487 std::vector<VehicleData> ret;
488 for (const VehicleData& i : myVehicleDataCont) {
489 if ((includeEarly || !i.leftEarlyM) && (!lastInterval || i.entryTimeM < t)) {
490 if (i.entryTimeM >= t || (leaveTime && i.leaveTimeM >= t)) {
491 ret.push_back(i);
492 }
493 }
494 }
495 for (const VehicleData& i : myLastVehicleDataCont) {
496 if (includeEarly || !i.leftEarlyM) {
497 if ((!lastInterval && (i.entryTimeM >= t || (leaveTime && i.leaveTimeM >= t)))
498 || (lastInterval && i.leaveTimeM <= t + STEPS2TIME(myLastIntervalEnd - myLastIntervalBegin))) { // TODO: check duration of last interval
499 ret.push_back(i);
500 }
501 }
502 }
503 for (const auto& i : myVehiclesOnDet) {
504 if ((!lastInterval && (i.second >= t || leaveTime || forOccupancy))
505 || (lastInterval && i.second < t && t - i.second < STEPS2TIME(DELTA_T))) { // no need to check leave time, they are still on the detector
506 SUMOTrafficObject* const v = i.first;
507 VehicleData d(*v, i.second, HAS_NOT_LEFT_DETECTOR, false);
508 d.speedM = v->getSpeed();
509 ret.push_back(d);
510 }
511 }
512 return ret;
513}
514
515
517 double leaveTimestep, const bool leftEarly, const double detLength)
518 : idM(v.getID()), lengthM(v.getVehicleType().getLength()), entryTimeM(entryTimestep), leaveTimeM(leaveTimestep),
519 speedM((v.getVehicleType().getLength() + detLength) / MAX2(leaveTimestep - entryTimestep, NUMERICAL_EPS)), typeIDM(v.getVehicleType().getID()),
520 leftEarlyM(leftEarly) {}
521
522
523void
531
532/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define HAS_NOT_LEFT_DETECTOR
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
#define STEPS2TIME(x)
Definition SUMOTime.h:58
#define SPEED2DIST(x)
Definition SUMOTime.h:48
#define SIMSTEP
Definition SUMOTime.h:64
#define TS
Definition SUMOTime.h:45
#define SIMTIME
Definition SUMOTime.h:65
#define TIME2STEPS(x)
Definition SUMOTime.h:60
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ID
const double INVALID_DOUBLE
invalid double
Definition StdDefs.h:68
T MIN2(T a, T b)
Definition StdDefs.h:80
T MAX2(T a, T b)
Definition StdDefs.h:86
The base class for microscopic and mesoscopic vehicles.
const std::vector< MSTransportable * > & getPersons() const
retrieve riding persons
virtual double getStopArrivalDelay() const
Returns the estimated public transport stop arrival delay in seconds.
static double passingTime(const double lastPos, const double passedPos, const double currentPos, const double lastSpeed, const double currentSpeed)
Calculates the time at which the position passedPosition has been passed In case of a ballistic updat...
Base of value-generating classes (detectors)
bool vehicleApplies(const SUMOTrafficObject &veh) const
Checks whether the detector measures vehicles of the given type.
const int myDetectPersons
Whether pedestrians shall be detected instead of vehicles.
bool personApplies(const MSTransportable &p, int dir) const
const std::set< MSTransportable *, ComparatorNumericalIdLess > & getPersons() const
Returns this edge's persons set.
Definition MSEdge.h:204
double getOccupancyTime() const
Returns the time of continous occupation by the same vehicle in seconds or 0 if there is no vehicle o...
static double lengthSum(double sumSoFar, const MSInductLoop::VehicleData &data)
Adds up VehicleData::lengthM.
double getOccupancy() const
Returns the current occupancy.
double getIntervalOccupancy(bool lastInterval=false) const
std::vector< std::string > getIntervalVehicleIDs(bool lastInterval=false) const
int myEnteredVehicleNumber
The number of entered vehicles.
double getEnteredNumber(const int offset) const
Returns the number of vehicles that have passed the detector.
int getIntervalVehicleNumber(bool lastInterval=false) const
void writeXMLOutput(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime)
Writes collected values into the given stream.
static double speedSum(double sumSoFar, const MSInductLoop::VehicleData &data)
Adds up VehicleData::speedM.
std::vector< VehicleData > collectVehiclesOnDet(SUMOTime t, bool includeEarly=false, bool leaveTime=false, bool forOccupancy=false, bool lastInterval=false) const
Returns vehicle data for vehicles that have been on the detector starting at the given time.
VehicleDataCont myVehicleDataCont
Data of vehicles that have completely passed the detector.
void overrideTimeSinceDetection(double time)
double myOverrideEntryTime
records the time at which overrideTimeSinceDetection was activated
double getSpeed(const int offset) const
Returns the speed of the vehicle on the detector.
SUMOTime myLastIntervalEnd
std::vector< std::string > getVehicleIDs(const int offset) const
Returns the ids of vehicles that have passed the detector.
double getVehicleLength(const int offset) const
Returns the length of the vehicle on the detector.
SUMOTime myLastIntervalBegin
virtual void reset()
Resets all generated values to allow computation of next interval.
const double myPosition
Detector's position on lane [m].
VehicleDataCont myLastVehicleDataCont
Data of vehicles that have completely passed the detector in the last time interval.
const double myEndPosition
Detector's end position (defaults to myPosition)
~MSInductLoop()
Destructor.
void loadTimeSinceLastDetection(double time)
void writeXMLDetectorProlog(OutputDevice &dev) const
Opens the XML-output using "detector" as root element.
void detectorUpdate(const SUMOTime step)
Updates the detector (computes values) only used when detecting persons.
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Checks whether the vehicle shall be counted and/or shall still touch this MSMoveReminder.
void notifyMovePerson(MSTransportable *p, int dir, double pos)
helper function for mapping person movement
double myOverrideTime
overrides the time since last detection
MSInductLoop(const std::string &id, MSLane *const lane, double positionInMeters, double length, std::string name, const std::string &vTypes, const std::string &nextEdges, int detectPersons, const bool needLocking)
Constructor.
double getArrivalDelay() const
Returns the maximum stop arrival delay of public transport vehicles that are on the detector or passe...
double getTimeSinceLastDetection() const
Returns the time since the last vehicle left the detector.
double myLastLeaveTime
Leave-time of the last vehicle detected [s].
const bool myNeedLock
whether internals need to be guarded against concurrent access (GUI or multi threading)
double getIntervalMeanSpeed(bool lastInterval=false) const
bool notifyEnter(SUMOTrafficObject &veh, Notification reason, const MSLane *enteredLane=0)
Checks whether the reminder is activated by a vehicle entering the lane.
virtual void clearState(SUMOTime time)
Remove all vehicles before quick-loading state.
std::map< SUMOTrafficObject *, double > myVehiclesOnDet
Data for vehicles that have entered the detector (vehicle -> enter time)
SUMOTime getLastDetectionTime() const
return last time a vehicle was on the detector
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Dismisses the vehicle if it is on the detector due to a lane change.
Representation of a lane in the micro simulation.
Definition MSLane.h:84
bool hasPedestrians() const
whether the lane has pedestrians on it
Definition MSLane.cpp:4603
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:775
Something on a lane to be noticed about vehicle movement.
Notification
Definition of a vehicle state.
@ NOTIFICATION_JUNCTION
The vehicle arrived at a junction.
MSLane * myLane
Lane on which the reminder works.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:199
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:334
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:402
static const int BACKWARD
Definition MSPModel.h:55
static const int FORWARD
Definition MSPModel.h:54
virtual double getSpeed() const override
the current speed of the transportable
const MSVehicleType & getVehicleType() const override
Returns the object's "vehicle" type.
The class responsible for building and deletion of vehicles.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
double getLength() const
Get vehicle's length [m].
const std::string & getID() const
Returns the id.
Definition Named.h:74
Static storage of an output device and its base (abstract) implementation.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false)
writes a named attribute
virtual bool isNull()
returns the information whether the device will discard all output
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
OutputDevice & writeTime(const SumoXMLAttr attr, const SUMOTime val)
Representation of a vehicle, person, or container.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual double getPreviousSpeed() const =0
Returns the object's previous speed.
virtual double getSpeed() const =0
Returns the object's current speed.
virtual bool isPerson() const
Whether it is a person.
virtual double getBackPositionOnLane(const MSLane *lane) const =0
Get the object's back position along the given lane.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
Definition SUMOVehicle.h:63
A scoped lock which only triggers on condition.
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.
#define DEBUG_COND
Struct to store the data of the counted vehicle internally.
VehicleData(const SUMOTrafficObject &v, double entryTimestep, double leaveTimestep, const bool leftEarly, const double detLength=0)
Constructor.
double speedM
Speed of the vehicle in [m/s].