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>
45#include <mesosim/MELoop.h>
46#include <mesosim/MESegment.h>
47#include <mesosim/MEVehicle.h>
52
53#define HAS_NOT_LEFT_DETECTOR -1
54
55//#define DEBUG_E1_NOTIFY_MOVE
56
57#define DEBUG_COND (true)
58//#define DEBUG_COND (isSelected())
59//#define DEBUG_COND (getID()=="")
60
61// ===========================================================================
62// method definitions
63// ===========================================================================
64MSInductLoop::MSInductLoop(const std::string& id, MSLane* const lane,
65 double positionInMeters,
66 double length, std::string name,
67 const std::string& vTypes,
68 const std::string& nextEdges,
69 int detectPersons,
70 const bool needLocking) :
71 MSMoveReminder(id, lane),
72 MSDetectorFileOutput(id, vTypes, nextEdges, detectPersons),
73 myName(name),
74 myPosition(positionInMeters),
75 myEndPosition(myPosition + length),
76 myNeedLock(needLocking || MSGlobals::gNumSimThreads > 1),
77 // initialize in a way which doesn't impact actualted traffic lights at simulation start (yet doesn't look ugly in the outputs)
78 myLastLeaveTime(-3600),
79 myOverrideTime(-1),
80 myOverrideEntryTime(-1),
81 myVehicleDataCont(),
82 myVehiclesOnDet(),
83 myLastIntervalEnd(-1),
84 mySegment(nullptr) {
85 assert(length >= 0);
86 assert(myPosition >= 0 && myEndPosition <= myLane->getLength());
87 reset();
89 // used by actuated tls
93 }
94}
95
96
99
100
101void
103#ifdef HAVE_FOX
104 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
105#endif
108 myVehicleDataCont.clear();
111}
112
113
114bool
115MSInductLoop::notifyEnter(SUMOTrafficObject& veh, Notification reason, const MSLane* /* enteredLane */) {
116 // vehicles must be kept if the "inductionloop" wants to detect passeengers
117 if (!vehicleApplies(veh) && (veh.isPerson() || myDetectPersons <= (int)PersonMode::WALK)) {
118 return false;
119 }
121 MEVehicle* mesoveh = dynamic_cast<MEVehicle*>(&veh);
122 assert(mesoveh != nullptr);
123 const MESegment* seg = mesoveh->getSegment();
124 if (seg != nullptr && (seg->numQueues() == 1 || mesoveh->getQueIndex() == myLane->getIndex())) {
125 const SUMOTime onSegTime = mesoveh->getEventTime() - mesoveh->getLastEntryTime();
126 // extrapolate movement
127 const SUMOTime exLeaveTime = mesoveh->getLastEntryTime() + (SUMOTime)((double)onSegTime * mySegmentPos / seg->getLength());
128 //std::cout << SIMTIME << " det=" << getID() << " veh=" << veh.getID() << " entry=" << STEPS2TIME(mesoveh->getLastEntryTime()) << " et=" << STEPS2TIME(mesoveh->getEventTime()) << " exLeaveTime=" << STEPS2TIME(exLeaveTime) << "\n";
129 myNextMesoLeaveTimes.push(exLeaveTime);
130 }
131 return false;
132 }
133 if (reason != NOTIFICATION_JUNCTION) { // the junction case is handled in notifyMove
135 return false;
136 }
137 if (veh.getPositionOnLane() >= myPosition) {
138#ifdef HAVE_FOX
139 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
140#endif
141 myVehiclesOnDet[&veh] = SIMTIME;
143 }
144 }
145 return true;
146}
147
148
149bool
151 double newPos, double newSpeed) {
152 if (newPos < myPosition) {
153 // detector not reached yet
154 return true;
155 }
156 if (myDetectPersons > (int)PersonMode::WALK && !veh.isPerson()) {
157 bool keep = false;
158 MSBaseVehicle& v = dynamic_cast<MSBaseVehicle&>(veh);
159 for (MSTransportable* p : v.getPersons()) {
160 keep = notifyMove(*p, oldPos, newPos, newSpeed);
161 }
162 return keep;
163 }
164#ifdef HAVE_FOX
165 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
166#endif
167 const double oldSpeed = veh.getPreviousSpeed();
168 if (newPos >= myPosition && oldPos < myPosition) {
169 // entered the detector by move
170 const double timeBeforeEnter = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
171 myVehiclesOnDet[&veh] = SIMTIME + timeBeforeEnter;
173#ifdef DEBUG_E1_NOTIFY_MOVE
174 if (DEBUG_COND) {
175 std::cout << SIMTIME << " det=" << getID() << " enteredVeh=" << veh.getID() << "\n";
176 }
177#endif
178 }
179 double oldBackPos = oldPos - veh.getVehicleType().getLength();
180 double newBackPos = newPos - veh.getVehicleType().getLength();
181 if (newBackPos > myEndPosition) {
182 // vehicle passed the detector (it may have changed onto this lane somewhere past the detector)
183 // assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed > 0 || myVehiclesOnDet.find(&veh) == myVehiclesOnDet.end());
184 // assertion is invalid in case of teleportation
185 if (oldBackPos <= myEndPosition) {
186 const std::map<SUMOTrafficObject*, double>::iterator it = myVehiclesOnDet.find(&veh);
187 if (it != myVehiclesOnDet.end()) {
188 const double entryTime = it->second;
189 const double leaveTime = SIMTIME + MSCFModel::passingTime(oldBackPos, myEndPosition, newBackPos, oldSpeed, newSpeed);
190 myVehiclesOnDet.erase(it);
191 assert(entryTime <= leaveTime);
192 myVehicleDataCont.push_back(VehicleData(veh, entryTime, leaveTime, false, myEndPosition - myPosition));
193 myLastLeaveTime = leaveTime;
194#ifdef DEBUG_E1_NOTIFY_MOVE
195 if (DEBUG_COND) {
196 std::cout << SIMTIME << " det=" << getID() << " leftVeh=" << veh.getID() << " oldBackPos=" << oldBackPos << " newBackPos=" << newBackPos << "\n";
197 }
198#endif
199 } else {
200#ifdef DEBUG_E1_NOTIFY_MOVE
201 if (DEBUG_COND) {
202 std::cout << SIMTIME << " det=" << getID() << " leftVeh=" << veh.getID() << " oldBackPos=" << oldBackPos << " newBackPos=" << newBackPos << " (notFound)\n";
203 }
204#endif
205 }
206 } else {
207 // vehicle is already beyond the detector...
208 // This can happen even if it is still registered in myVehiclesOnDet, e.g., after teleport.
209 myVehiclesOnDet.erase(&veh);
210#ifdef DEBUG_E1_NOTIFY_MOVE
211 if (DEBUG_COND) {
212 std::cout << SIMTIME << " det=" << getID() << " leftVeh=" << veh.getID() << " oldBackPos=" << oldBackPos << " newBackPos=" << newBackPos << " (unusual)\n";
213 }
214#endif
215 }
216 return false;
217 }
218 // vehicle stays on the detector
219 return true;
220}
221
222
223bool
224MSInductLoop::notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
225 if (veh.isPerson() && myDetectPersons != (int)PersonMode::NONE) {
226 const int lastDir = lastPos < 0 ? MSPModel::BACKWARD : MSPModel::FORWARD;
227 notifyMovePerson(dynamic_cast<MSTransportable*>(&veh), lastDir, lastPos);
228 }
230#ifdef HAVE_FOX
231 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
232#endif
233 const std::map<SUMOTrafficObject*, double>::iterator it = myVehiclesOnDet.find(&veh);
234 if (it != myVehiclesOnDet.end()) {
235 const double entryTime = it->second;
236 const double leaveTime = SIMTIME + TS;
237 myVehiclesOnDet.erase(it);
238 myVehicleDataCont.push_back(VehicleData(veh, entryTime, leaveTime, true));
239 myLastLeaveTime = leaveTime;
240 }
241 return false;
242 }
243 return true;
244}
245
246
247double
248MSInductLoop::getSpeed(const int offset) const {
249 const std::vector<VehicleData>& d = collectVehiclesOnDet(SIMSTEP - offset);
250 return d.empty() ? -1. : std::accumulate(d.begin(), d.end(), 0.0, speedSum) / (double) d.size();
251}
252
253
254double
255MSInductLoop::getVehicleLength(const int offset) const {
256 const std::vector<VehicleData>& d = collectVehiclesOnDet(SIMSTEP - offset);
257 return d.empty() ? -1. : std::accumulate(d.begin(), d.end(), 0.0, lengthSum) / (double)d.size();
258}
259
260
261double
263 if (myOverrideTime >= 0) {
264 return myOverrideTime < TS ? (TS - myOverrideTime) / TS * 100 : 0;
265 }
266 const SUMOTime tbeg = SIMSTEP - DELTA_T;
267 double occupancy = 0;
268 const double csecond = SIMTIME;
269 for (const VehicleData& i : collectVehiclesOnDet(tbeg, false, false, true)) {
270 const double leaveTime = i.leaveTimeM == HAS_NOT_LEFT_DETECTOR ? csecond : MIN2(i.leaveTimeM, csecond);
271 const double entryTime = MAX2(i.entryTimeM, STEPS2TIME(tbeg));
272 occupancy += MIN2(leaveTime - entryTime, TS);
273 }
274 return occupancy / TS * 100.;
275}
276
277
278double
279MSInductLoop::getEnteredNumber(const int offset) const {
280 if (myOverrideTime >= 0) {
281 return myOverrideTime < TS ? 1 : 0;
282 }
283 return (double)collectVehiclesOnDet(SIMSTEP - offset, true, true).size();
284}
285
286
287std::vector<std::string>
288MSInductLoop::getVehicleIDs(const int offset) const {
289 std::vector<std::string> ret;
290 for (const VehicleData& i : collectVehiclesOnDet(SIMSTEP - offset, true, true)) {
291 ret.push_back(i.idM);
292 }
293 return ret;
294}
295
296
297double
299 if (myOverrideTime >= 0) {
300 return myOverrideTime;
301 }
302 if (myVehiclesOnDet.size() != 0) {
303 // detector is occupied
304 return 0;
305 }
307 //std::cout << SIMTIME << " det=" << getID() << " qBefore=" << myNextMesoLeaveTimes.size() << " last=" << STEPS2TIME(getLastDetectionTime()) << " qAfter=" << myNextMesoLeaveTimes.size() << " top=" << (myNextMesoLeaveTimes.empty() ? -1 : myNextMesoLeaveTimes.top()) << "\n";
309 }
310 return SIMTIME - myLastLeaveTime;
311}
312
313
314void
318
319
320double
322#ifdef HAVE_FOX
323 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
324#endif
325 if (myOverrideTime >= 0) {
327 }
328 if (myVehiclesOnDet.size() == 0) {
329 // detector is unoccupied
330 return 0;
331 } else {
332 double minEntry = std::numeric_limits<double>::max();
333 for (const auto& i : myVehiclesOnDet) {
334 minEntry = MIN2(i.second, minEntry);
335 }
336 return SIMTIME - minEntry;
337 }
338}
339
340
341double
343#ifdef HAVE_FOX
344 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
345#endif
347 double result = -INVALID_DOUBLE;
348 for (const auto& item : collectVehiclesOnDet(SIMSTEP - DELTA_T)) {
349 SUMOVehicle* v = vc.getVehicle(item.idM);
350 if (v != nullptr) {
351 MSBaseVehicle* veh = dynamic_cast<MSBaseVehicle*>(v);
352 double ad = veh->getStopArrivalDelay();
353 if (ad != INVALID_DOUBLE) {
354 result = MAX2(result, ad);
355 }
356 }
357 }
358 return result;
359}
360
361
364 if (myOverrideTime >= 0) {
366 }
367 if (myVehiclesOnDet.size() != 0) {
369 }
371 && !myNextMesoLeaveTimes.empty()
372 && myNextMesoLeaveTimes.top() < SIMSTEP) {
373 // find the latest time that is already in the past
374 SUMOTime last = myNextMesoLeaveTimes.top();
375 if (myNextMesoLeaveTimes.size() > 1) {
377 while (myNextMesoLeaveTimes.size() > 0 && myNextMesoLeaveTimes.top() < SIMSTEP) {
378 last = myNextMesoLeaveTimes.top();
380 }
381 myNextMesoLeaveTimes.push(last);
382 }
384 const SUMOTime last2 = blockTime - TIME2STEPS((mySegment->getLength() - mySegmentPos) / myLane->getSpeedLimit());
385 //std::cout << SIMTIME << " det=" << getID() << " last=" << last << " last2=" << last2 << " block=" << blockTime << " times=" << myNextMesoLeaveTimes.size() << "\n";
386 return MAX2(last, last2);
387 }
389}
390
391
392double
393MSInductLoop::getIntervalOccupancy(bool lastInterval) const {
394 double occupancy = 0;
395 const double csecond = lastInterval ? STEPS2TIME(myLastIntervalEnd) : SIMTIME;
396 const double aggTime = csecond - STEPS2TIME(lastInterval ? myLastIntervalBegin : myLastIntervalEnd);
397 if (aggTime == 0) {
398 return 0;
399 }
400 for (const VehicleData& i : collectVehiclesOnDet(myLastIntervalEnd, false, false, true, lastInterval)) {
401 const double leaveTime = i.leaveTimeM == HAS_NOT_LEFT_DETECTOR ? csecond : MIN2(i.leaveTimeM, csecond);
402 const double entryTime = MAX2(i.entryTimeM, STEPS2TIME(lastInterval ? myLastIntervalBegin : myLastIntervalEnd));
403 occupancy += MIN2(leaveTime - entryTime, aggTime);
404 }
405 return occupancy / aggTime * 100.;
406}
407
408
409double
410MSInductLoop::getIntervalMeanSpeed(bool lastInterval) const {
411 const std::vector<VehicleData>& d = collectVehiclesOnDet(myLastIntervalEnd, false, false, false, lastInterval);
412 return d.empty() ? -1. : std::accumulate(d.begin(), d.end(), 0.0, speedSum) / (double) d.size();
413}
414
415
416int
418 return (int)collectVehiclesOnDet(myLastIntervalEnd, false, false, false, lastInterval).size();
419}
420
421
422std::vector<std::string>
423MSInductLoop::getIntervalVehicleIDs(bool lastInterval) const {
424 std::vector<std::string> ret;
425 for (const VehicleData& i : collectVehiclesOnDet(myLastIntervalEnd, false, false, false, lastInterval)) {
426 ret.push_back(i.idM);
427 }
428 return ret;
429}
430
431
432void
434 myOverrideTime = time;
435 if (time < 0) {
437 } else {
438 const double entryTime = MAX2(0.0, SIMTIME - time);
439 if (myOverrideEntryTime >= 0) {
440 // maintain earlier entry time to achive continous detection
442 } else {
443 myOverrideEntryTime = entryTime;
444 }
445 }
446}
447
448void
450 dev.writeXMLHeader("detector", "det_e1_file.xsd");
451}
452
453
454void
456 if (dev.isNull()) {
457 reset();
458 return;
459 }
460 const double t(STEPS2TIME(stopTime - startTime));
461 double occupancy = 0.;
462 double speedSum = 0.;
463 double lengthSum = 0.;
464 int contrib = 0;
465 // to approximate the space mean speed
466 double inverseSpeedSum = 0.;
467 for (const VehicleData& vData : myVehicleDataCont) {
468 const double timeOnDetDuringInterval = vData.leaveTimeM - MAX2(STEPS2TIME(startTime), vData.entryTimeM);
469 occupancy += MIN2(timeOnDetDuringInterval, t);
470 if (!vData.leftEarlyM) {
471 speedSum += vData.speedM;
472 assert(vData.speedM > 0.);
473 inverseSpeedSum += 1. / vData.speedM;
474 lengthSum += vData.lengthM;
475 contrib++;
476 }
477 }
478 const double flow = (double)contrib / t * 3600.;
479 for (std::map< SUMOTrafficObject*, double >::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
480 occupancy += STEPS2TIME(stopTime) - MAX2(STEPS2TIME(startTime), i->second);
481 }
482 occupancy *= 100. / t;
483 const double meanSpeed = contrib != 0 ? speedSum / (double)contrib : -1;
484 const double harmonicMeanSpeed = contrib != 0 ? (double)contrib / inverseSpeedSum : -1;
485 const double meanLength = contrib != 0 ? lengthSum / (double)contrib : -1;
487 dev.writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML(getID())).writeAttr("nVehContrib", contrib);
488 dev.writeAttr("flow", flow).writeAttr("occupancy", occupancy).writeAttr("speed", meanSpeed).writeAttr("harmonicMeanSpeed", harmonicMeanSpeed);
489 dev.writeAttr("length", meanLength).writeAttr("nVehEntered", myEnteredVehicleNumber).closeTag();
490 reset();
491}
492
493
494void
496 if (myDetectPersons == (int)PersonMode::NONE) {
497 return;
498 }
499 if (myLane->hasPedestrians()) {
500 for (MSTransportable* p : myLane->getEdge().getPersons()) {
501 if (p->getLane() != myLane || !vehicleApplies(*p)) {
502 continue;
503 }
504 notifyMovePerson(p, p->getDirection(), p->getPositionOnLane());
505 }
506 }
507}
508
509
510void
512 if (personApplies(*p, dir)) {
513 const double newSpeed = p->getSpeed();
514 const double newPos = (dir == MSPModel::FORWARD
515 ? pos
516 // position relative to detector
517 : myPosition - (pos - myPosition));
518 const double oldPos = newPos - SPEED2DIST(newSpeed);
519 if (oldPos - p->getVehicleType().getLength() <= myPosition) {
520 notifyMove(*p, oldPos, newPos, newSpeed);
521 }
522 }
523}
524
525
526std::vector<MSInductLoop::VehicleData>
527MSInductLoop::collectVehiclesOnDet(SUMOTime tMS, bool includeEarly, bool leaveTime, bool forOccupancy, bool lastInterval) const {
528#ifdef HAVE_FOX
529 ScopedLocker<> lock(myNotificationMutex, myNeedLock);
530#endif
531 const double t = STEPS2TIME(tMS);
532 std::vector<VehicleData> ret;
533 for (const VehicleData& i : myVehicleDataCont) {
534 if ((includeEarly || !i.leftEarlyM) && (!lastInterval || i.entryTimeM < t)) {
535 if (i.entryTimeM >= t || (leaveTime && i.leaveTimeM >= t)) {
536 ret.push_back(i);
537 }
538 }
539 }
540 for (const VehicleData& i : myLastVehicleDataCont) {
541 if (includeEarly || !i.leftEarlyM) {
542 if ((!lastInterval && (i.entryTimeM >= t || (leaveTime && i.leaveTimeM >= t)))
543 || (lastInterval && i.leaveTimeM <= t + STEPS2TIME(myLastIntervalEnd - myLastIntervalBegin))) { // TODO: check duration of last interval
544 ret.push_back(i);
545 }
546 }
547 }
548 for (const auto& i : myVehiclesOnDet) {
549 if ((!lastInterval && (i.second >= t || leaveTime || forOccupancy))
550 || (lastInterval && i.second < t && t - i.second < STEPS2TIME(DELTA_T))) { // no need to check leave time, they are still on the detector
551 SUMOTrafficObject* const v = i.first;
552 VehicleData d(*v, i.second, HAS_NOT_LEFT_DETECTOR, false);
553 d.speedM = v->getSpeed();
554 ret.push_back(d);
555 }
556 }
557 return ret;
558}
559
560
562 double leaveTimestep, const bool leftEarly, const double detLength)
563 : idM(v.getID()), lengthM(v.getVehicleType().getLength()), entryTimeM(entryTimestep), leaveTimeM(leaveTimestep),
564 speedM((v.getVehicleType().getLength() + detLength) / MAX2(leaveTimestep - entryTimestep, NUMERICAL_EPS)), typeIDM(v.getVehicleType().getID()),
565 leftEarlyM(leftEarly) {}
566
567
568void
576
577/****************************************************************************/
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
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition MELoop.cpp:339
A single mesoscopic segment (cell)
Definition MESegment.h:50
void addDetector(MSMoveReminder *data, int queueIndex=-1)
Adds a data collector for a detector to this segment.
double getLength() const
Returns the length of the segment in meters.
Definition MESegment.h:251
int numQueues() const
return the number of queues
Definition MESegment.h:215
int getIndex() const
Returns the running index of the segment in the edge (0 is the most upstream).
Definition MESegment.h:235
SUMOTime getQueueBlockTime(int index) const
Definition MESegment.h:226
A vehicle from the mesoscopic point of view.
Definition MEVehicle.h:42
SUMOTime getLastEntryTime() const
Returns the time the vehicle entered the current segment.
Definition MEVehicle.h:264
MESegment * getSegment() const
Returns the current segment the vehicle is on.
Definition MEVehicle.h:233
int getQueIndex() const
Returns the index of the que the vehicle is in.
Definition MEVehicle.h:242
SUMOTime getEventTime() const
Returns the (planned) time at which the vehicle leaves its current segment.
Definition MEVehicle.h:215
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
static bool gUseMesoSim
Definition MSGlobals.h:106
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition MSGlobals.h:115
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.
MESegment * mySegment
current segment (for actuated tls in meso)
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::priority_queue< SUMOTime, std::vector< SUMOTime >, std::greater< SUMOTime > > myNextMesoLeaveTimes
extrapolated leave times for meso vehicle
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 mySegmentPos
position relative to the current segment
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
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition MSLane.h:602
bool hasPedestrians() const
whether the lane has pedestrians on it
Definition MSLane.cpp:4607
int getIndex() const
Returns the lane's index.
Definition MSLane.h:668
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:790
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:73
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, const bool escape=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].