Eclipse SUMO - Simulation of Urban MObility
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-2024 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
36 #include <utils/common/ToString.h>
38 #include <microsim/MSLane.h>
39 #include <microsim/MSEdge.h>
40 #include <microsim/MSVehicle.h>
41 #include <microsim/MSNet.h>
48 
49 #define HAS_NOT_LEFT_DETECTOR -1
50 
51 //#define DEBUG_E1_NOTIFY_MOVE
52 
53 #define DEBUG_COND (true)
54 //#define DEBUG_COND (isSelected())
55 //#define DEBUG_COND (getID()=="")
56 
57 // ===========================================================================
58 // method definitions
59 // ===========================================================================
60 MSInductLoop::MSInductLoop(const std::string& id, MSLane* const lane,
61  double positionInMeters,
62  double length, std::string name,
63  const std::string& vTypes,
64  const std::string& nextEdges,
65  int detectPersons,
66  const bool needLocking) :
67  MSMoveReminder(id, lane),
68  MSDetectorFileOutput(id, vTypes, nextEdges, detectPersons),
69  myName(name),
70  myPosition(positionInMeters),
71  myEndPosition(myPosition + length),
72  myNeedLock(needLocking || MSGlobals::gNumSimThreads > 1),
73  // initialize in a way which doesn't impact actualted traffic lights at simulation start (yet doesn't look ugly in the outputs)
74  myLastLeaveTime(-3600),
75  myOverrideTime(-1),
76  myOverrideEntryTime(-1),
77  myVehicleDataCont(),
78  myVehiclesOnDet(),
79  myLastIntervalEnd(-1) {
80  assert(length >= 0);
81  assert(myPosition >= 0 && myEndPosition <= myLane->getLength());
82  reset();
83 }
84 
85 
87 }
88 
89 
90 void
92 #ifdef HAVE_FOX
93  ScopedLocker<> lock(myNotificationMutex, myNeedLock);
94 #endif
97  myVehicleDataCont.clear();
100 }
101 
102 
103 bool
104 MSInductLoop::notifyEnter(SUMOTrafficObject& veh, Notification reason, const MSLane* /* enteredLane */) {
105  // vehicles must be kept if the "inductionloop" wants to detect passeengers
106  if (!vehicleApplies(veh) && (veh.isPerson() || myDetectPersons <= (int)PersonMode::WALK)) {
107  return false;
108  }
109  if (reason != NOTIFICATION_JUNCTION) { // the junction case is handled in notifyMove
111  return false;
112  }
113  if (veh.getPositionOnLane() >= myPosition) {
114 #ifdef HAVE_FOX
115  ScopedLocker<> lock(myNotificationMutex, myNeedLock);
116 #endif
117  myVehiclesOnDet[&veh] = SIMTIME;
119  }
120  }
121  return true;
122 }
123 
124 
125 bool
127  double newPos, double newSpeed) {
128  if (newPos < myPosition) {
129  // detector not reached yet
130  return true;
131  }
132  if (myDetectPersons > (int)PersonMode::WALK && !veh.isPerson()) {
133  bool keep = false;
134  MSBaseVehicle& v = dynamic_cast<MSBaseVehicle&>(veh);
135  for (MSTransportable* p : v.getPersons()) {
136  keep = notifyMove(*p, oldPos, newPos, newSpeed);
137  }
138  return keep;
139  }
140 #ifdef HAVE_FOX
141  ScopedLocker<> lock(myNotificationMutex, myNeedLock);
142 #endif
143  const double oldSpeed = veh.getPreviousSpeed();
144  if (newPos >= myPosition && oldPos < myPosition) {
145  // entered the detector by move
146  const double timeBeforeEnter = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
147  myVehiclesOnDet[&veh] = SIMTIME + timeBeforeEnter;
149 #ifdef DEBUG_E1_NOTIFY_MOVE
150  if (DEBUG_COND) {
151  std::cout << SIMTIME << " det=" << getID() << " enteredVeh=" << veh.getID() << "\n";
152  }
153 #endif
154  }
155  double oldBackPos = oldPos - veh.getVehicleType().getLength();
156  double newBackPos = newPos - veh.getVehicleType().getLength();
157  if (newBackPos > myEndPosition) {
158  // vehicle passed the detector (it may have changed onto this lane somewhere past the detector)
159  // assert(!MSGlobals::gSemiImplicitEulerUpdate || newSpeed > 0 || myVehiclesOnDet.find(&veh) == myVehiclesOnDet.end());
160  // assertion is invalid in case of teleportation
161  if (oldBackPos <= myEndPosition) {
162  const std::map<SUMOTrafficObject*, double>::iterator it = myVehiclesOnDet.find(&veh);
163  if (it != myVehiclesOnDet.end()) {
164  const double entryTime = it->second;
165  const double leaveTime = SIMTIME + MSCFModel::passingTime(oldBackPos, myEndPosition, newBackPos, oldSpeed, newSpeed);
166  myVehiclesOnDet.erase(it);
167  assert(entryTime <= leaveTime);
168  myVehicleDataCont.push_back(VehicleData(veh, entryTime, leaveTime, false, myEndPosition - myPosition));
169  myLastLeaveTime = leaveTime;
170 #ifdef DEBUG_E1_NOTIFY_MOVE
171  if (DEBUG_COND) {
172  std::cout << SIMTIME << " det=" << getID() << " leftVeh=" << veh.getID() << " oldBackPos=" << oldBackPos << " newBackPos=" << newBackPos << "\n";
173  }
174 #endif
175  } else {
176 #ifdef DEBUG_E1_NOTIFY_MOVE
177  if (DEBUG_COND) {
178  std::cout << SIMTIME << " det=" << getID() << " leftVeh=" << veh.getID() << " oldBackPos=" << oldBackPos << " newBackPos=" << newBackPos << " (notFound)\n";
179  }
180 #endif
181  }
182  } else {
183  // vehicle is already beyond the detector...
184  // This can happen even if it is still registered in myVehiclesOnDet, e.g., after teleport.
185  myVehiclesOnDet.erase(&veh);
186 #ifdef DEBUG_E1_NOTIFY_MOVE
187  if (DEBUG_COND) {
188  std::cout << SIMTIME << " det=" << getID() << " leftVeh=" << veh.getID() << " oldBackPos=" << oldBackPos << " newBackPos=" << newBackPos << " (unusual)\n";
189  }
190 #endif
191  }
192  return false;
193  }
194  // vehicle stays on the detector
195  return true;
196 }
197 
198 
199 bool
200 MSInductLoop::notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
201  if (veh.isPerson() && myDetectPersons != (int)PersonMode::NONE) {
202  const int lastDir = lastPos < 0 ? MSPModel::BACKWARD : MSPModel::FORWARD;
203  notifyMovePerson(dynamic_cast<MSTransportable*>(&veh), lastDir, lastPos);
204  }
206 #ifdef HAVE_FOX
207  ScopedLocker<> lock(myNotificationMutex, myNeedLock);
208 #endif
209  const std::map<SUMOTrafficObject*, double>::iterator it = myVehiclesOnDet.find(&veh);
210  if (it != myVehiclesOnDet.end()) {
211  const double entryTime = it->second;
212  const double leaveTime = SIMTIME + TS;
213  myVehiclesOnDet.erase(it);
214  myVehicleDataCont.push_back(VehicleData(veh, entryTime, leaveTime, true));
215  myLastLeaveTime = leaveTime;
216  }
217  return false;
218  }
219  return true;
220 }
221 
222 
223 double
224 MSInductLoop::getSpeed(const int offset) const {
225  const std::vector<VehicleData>& d = collectVehiclesOnDet(SIMSTEP - offset);
226  return d.empty() ? -1. : std::accumulate(d.begin(), d.end(), 0.0, speedSum) / (double) d.size();
227 }
228 
229 
230 double
231 MSInductLoop::getVehicleLength(const int offset) const {
232  const std::vector<VehicleData>& d = collectVehiclesOnDet(SIMSTEP - offset);
233  return d.empty() ? -1. : std::accumulate(d.begin(), d.end(), 0.0, lengthSum) / (double)d.size();
234 }
235 
236 
237 double
239  if (myOverrideTime >= 0) {
240  return myOverrideTime < TS ? (TS - myOverrideTime) / TS * 100 : 0;
241  }
242  const SUMOTime tbeg = SIMSTEP - DELTA_T;
243  double occupancy = 0;
244  const double csecond = SIMTIME;
245  for (const VehicleData& i : collectVehiclesOnDet(tbeg, false, false, true)) {
246  const double leaveTime = i.leaveTimeM == HAS_NOT_LEFT_DETECTOR ? csecond : MIN2(i.leaveTimeM, csecond);
247  const double entryTime = MAX2(i.entryTimeM, STEPS2TIME(tbeg));
248  occupancy += MIN2(leaveTime - entryTime, TS);
249  }
250  return occupancy / TS * 100.;
251 }
252 
253 
254 double
255 MSInductLoop::getEnteredNumber(const int offset) const {
256  if (myOverrideTime >= 0) {
257  return myOverrideTime < TS ? 1 : 0;
258  }
259  return (double)collectVehiclesOnDet(SIMSTEP - offset, true, true).size();
260 }
261 
262 
263 std::vector<std::string>
264 MSInductLoop::getVehicleIDs(const int offset) const {
265  std::vector<std::string> ret;
266  for (const VehicleData& i : collectVehiclesOnDet(SIMSTEP - offset, true, true)) {
267  ret.push_back(i.idM);
268  }
269  return ret;
270 }
271 
272 
273 double
275  if (myOverrideTime >= 0) {
276  return myOverrideTime;
277  }
278  if (myVehiclesOnDet.size() != 0) {
279  // detector is occupied
280  return 0;
281  }
282  return SIMTIME - myLastLeaveTime;
283 }
284 
285 
286 double
288 #ifdef HAVE_FOX
289  ScopedLocker<> lock(myNotificationMutex, myNeedLock);
290 #endif
291  if (myOverrideTime >= 0) {
292  return SIMTIME - myOverrideEntryTime;
293  }
294  if (myVehiclesOnDet.size() == 0) {
295  // detector is unoccupied
296  return 0;
297  } else {
298  double minEntry = std::numeric_limits<double>::max();
299  for (const auto& i : myVehiclesOnDet) {
300  minEntry = MIN2(i.second, minEntry);
301  }
302  return SIMTIME - minEntry;
303  }
304 }
305 
306 
307 
308 SUMOTime
310  if (myOverrideTime >= 0) {
312  }
313  if (myVehiclesOnDet.size() != 0) {
315  }
316  return TIME2STEPS(myLastLeaveTime);
317 }
318 
319 
320 double
321 MSInductLoop::getIntervalOccupancy(bool lastInterval) const {
322  double occupancy = 0;
323  const double csecond = lastInterval ? STEPS2TIME(myLastIntervalEnd) : SIMTIME;
324  const double aggTime = csecond - STEPS2TIME(lastInterval ? myLastIntervalBegin : myLastIntervalEnd);
325  if (aggTime == 0) {
326  return 0;
327  }
328  for (const VehicleData& i : collectVehiclesOnDet(myLastIntervalEnd, false, false, true, lastInterval)) {
329  const double leaveTime = i.leaveTimeM == HAS_NOT_LEFT_DETECTOR ? csecond : MIN2(i.leaveTimeM, csecond);
330  const double entryTime = MAX2(i.entryTimeM, STEPS2TIME(lastInterval ? myLastIntervalBegin : myLastIntervalEnd));
331  occupancy += MIN2(leaveTime - entryTime, aggTime);
332  }
333  return occupancy / aggTime * 100.;
334 }
335 
336 
337 double
338 MSInductLoop::getIntervalMeanSpeed(bool lastInterval) const {
339  const std::vector<VehicleData>& d = collectVehiclesOnDet(myLastIntervalEnd, false, false, false, lastInterval);
340  return d.empty() ? -1. : std::accumulate(d.begin(), d.end(), 0.0, speedSum) / (double) d.size();
341 }
342 
343 
344 int
345 MSInductLoop::getIntervalVehicleNumber(bool lastInterval) const {
346  return (int)collectVehiclesOnDet(myLastIntervalEnd, false, false, false, lastInterval).size();
347 }
348 
349 
350 std::vector<std::string>
351 MSInductLoop::getIntervalVehicleIDs(bool lastInterval) const {
352  std::vector<std::string> ret;
353  for (const VehicleData& i : collectVehiclesOnDet(myLastIntervalEnd, false, false, false, lastInterval)) {
354  ret.push_back(i.idM);
355  }
356  return ret;
357 }
358 
359 
360 void
362  myOverrideTime = time;
363  if (time < 0) {
364  myOverrideEntryTime = -1;
365  } else {
366  const double entryTime = MAX2(0.0, SIMTIME - time);
367  if (myOverrideEntryTime >= 0) {
368  // maintain earlier entry time to achive continous detection
370  } else {
371  myOverrideEntryTime = entryTime;
372  }
373  }
374 }
375 
376 void
378  dev.writeXMLHeader("detector", "det_e1_file.xsd");
379 }
380 
381 
382 void
384  if (dev.isNull()) {
385  reset();
386  return;
387  }
388  const double t(STEPS2TIME(stopTime - startTime));
389  double occupancy = 0.;
390  double speedSum = 0.;
391  double lengthSum = 0.;
392  int contrib = 0;
393  // to approximate the space mean speed
394  double inverseSpeedSum = 0.;
395  for (const VehicleData& vData : myVehicleDataCont) {
396  const double timeOnDetDuringInterval = vData.leaveTimeM - MAX2(STEPS2TIME(startTime), vData.entryTimeM);
397  occupancy += MIN2(timeOnDetDuringInterval, t);
398  if (!vData.leftEarlyM) {
399  speedSum += vData.speedM;
400  assert(vData.speedM > 0.);
401  inverseSpeedSum += 1. / vData.speedM;
402  lengthSum += vData.lengthM;
403  contrib++;
404  }
405  }
406  const double flow = (double)contrib / t * 3600.;
407  for (std::map< SUMOTrafficObject*, double >::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
408  occupancy += STEPS2TIME(stopTime) - MAX2(STEPS2TIME(startTime), i->second);
409  }
410  occupancy *= 100. / t;
411  const double meanSpeed = contrib != 0 ? speedSum / (double)contrib : -1;
412  const double harmonicMeanSpeed = contrib != 0 ? (double)contrib / inverseSpeedSum : -1;
413  const double meanLength = contrib != 0 ? lengthSum / (double)contrib : -1;
414  dev.openTag(SUMO_TAG_INTERVAL).writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(startTime)).writeAttr(SUMO_ATTR_END, STEPS2TIME(stopTime));
415  dev.writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML(getID())).writeAttr("nVehContrib", contrib);
416  dev.writeAttr("flow", flow).writeAttr("occupancy", occupancy).writeAttr("speed", meanSpeed).writeAttr("harmonicMeanSpeed", harmonicMeanSpeed);
417  dev.writeAttr("length", meanLength).writeAttr("nVehEntered", myEnteredVehicleNumber).closeTag();
418  reset();
419 }
420 
421 
422 void
424  if (myDetectPersons == (int)PersonMode::NONE) {
425  return;
426  }
427  if (myLane->hasPedestrians()) {
428  for (MSTransportable* p : myLane->getEdge().getPersons()) {
429  if (p->getLane() != myLane || !vehicleApplies(*p)) {
430  continue;
431  }
432  notifyMovePerson(p, p->getDirection(), p->getPositionOnLane());
433  }
434  }
435 }
436 
437 
438 void
440  if (personApplies(*p, dir)) {
441  const double newSpeed = p->getSpeed();
442  const double newPos = (dir == MSPModel::FORWARD
443  ? pos
444  // position relative to detector
445  : myPosition - (pos - myPosition));
446  const double oldPos = newPos - SPEED2DIST(newSpeed);
447  if (oldPos - p->getVehicleType().getLength() <= myPosition) {
448  notifyMove(*p, oldPos, newPos, newSpeed);
449  }
450  }
451 }
452 
453 
454 std::vector<MSInductLoop::VehicleData>
455 MSInductLoop::collectVehiclesOnDet(SUMOTime tMS, bool includeEarly, bool leaveTime, bool forOccupancy, bool lastInterval) const {
456 #ifdef HAVE_FOX
457  ScopedLocker<> lock(myNotificationMutex, myNeedLock);
458 #endif
459  const double t = STEPS2TIME(tMS);
460  std::vector<VehicleData> ret;
461  for (const VehicleData& i : myVehicleDataCont) {
462  if ((includeEarly || !i.leftEarlyM) && (!lastInterval || i.entryTimeM < t)) {
463  if (i.entryTimeM >= t || (leaveTime && i.leaveTimeM >= t)) {
464  ret.push_back(i);
465  }
466  }
467  }
468  for (const VehicleData& i : myLastVehicleDataCont) {
469  if (includeEarly || !i.leftEarlyM) {
470  if ((!lastInterval && (i.entryTimeM >= t || (leaveTime && i.leaveTimeM >= t)))
471  || (lastInterval && i.leaveTimeM <= t)) {
472  ret.push_back(i);
473  }
474  }
475  }
476  for (const auto& i : myVehiclesOnDet) {
477  if ((!lastInterval && (i.second >= t || leaveTime || forOccupancy))
478  || (lastInterval && i.second < t)) { // no need to check leave time, they are still on the detector
479  SUMOTrafficObject* const v = i.first;
480  VehicleData d(*v, i.second, HAS_NOT_LEFT_DETECTOR, false);
481  d.speedM = v->getSpeed();
482  ret.push_back(d);
483  }
484  }
485  return ret;
486 }
487 
488 
490  double leaveTimestep, const bool leftEarly, const double detLength)
491  : idM(v.getID()), lengthM(v.getVehicleType().getLength()), entryTimeM(entryTimestep), leaveTimeM(leaveTimestep),
492  speedM((v.getVehicleType().getLength() + detLength) / MAX2(leaveTimestep - entryTimestep, NUMERICAL_EPS)), typeIDM(v.getVehicleType().getID()),
493  leftEarlyM(leftEarly) {}
494 
495 
496 void
498  myLastLeaveTime = STEPS2TIME(time);
500  myLastVehicleDataCont.clear();
501  myVehicleDataCont.clear();
502  myVehiclesOnDet.clear();
503 }
504 
505 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define HAS_NOT_LEFT_DETECTOR
#define DEBUG_COND
SUMOTime DELTA_T
Definition: SUMOTime.cpp:38
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
#define SPEED2DIST(x)
Definition: SUMOTime.h:45
#define SIMSTEP
Definition: SUMOTime.h:61
#define TS
Definition: SUMOTime.h:42
#define SIMTIME
Definition: SUMOTime.h:62
#define TIME2STEPS(x)
Definition: SUMOTime.h:57
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ID
T MIN2(T a, T b)
Definition: StdDefs.h:76
T MAX2(T a, T b)
Definition: StdDefs.h:82
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:55
const std::vector< MSTransportable * > & getPersons() const
retrieve riding persons
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...
Definition: MSCFModel.cpp:658
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:201
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.
Definition: MSInductLoop.h:344
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.
Definition: MSInductLoop.h:375
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.
Definition: MSInductLoop.h:339
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.
Definition: MSInductLoop.h:381
void overrideTimeSinceDetection(double time)
double myOverrideEntryTime
records the time at which overrideTimeSinceDetection was activated
Definition: MSInductLoop.h:372
double getSpeed(const int offset) const
Returns the speed of the vehicle on the detector.
SUMOTime myLastIntervalEnd
Definition: MSInductLoop.h:389
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
Definition: MSInductLoop.h:390
virtual void reset()
Resets all generated values to allow computation of next interval.
const double myPosition
Detector's position on lane [m].
Definition: MSInductLoop.h:357
VehicleDataCont myLastVehicleDataCont
Data of vehicles that have completely passed the detector in the last time interval.
Definition: MSInductLoop.h:384
const double myEndPosition
Detector's end position (defaults to myPosition)
Definition: MSInductLoop.h:360
~MSInductLoop()
Destructor.
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
Definition: MSInductLoop.h:369
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 getTimeSinceLastDetection() const
Returns the time since the last vehicle left the detector.
double myLastLeaveTime
Leave-time of the last vehicle detected [s].
Definition: MSInductLoop.h:366
const bool myNeedLock
whether internals need to be guarded against concurrent access (GUI or multi threading)
Definition: MSInductLoop.h:363
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)
Definition: MSInductLoop.h:387
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:4413
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:752
Something on a lane to be noticed about vehicle movement.
MSLane *const myLane
Lane on which the reminder works.
Notification
Definition of a vehicle state.
@ NOTIFICATION_JUNCTION
The vehicle arrived at a junction.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:182
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:320
static const int BACKWARD
Definition: MSPModel.h:120
static const int FORWARD
Definition: MSPModel.h:119
virtual double getSpeed() const
the current speed of the transportable
const MSVehicleType & getVehicleType() const
Returns the object's "vehicle" type.
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.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
virtual bool isNull()
returns the information whether the device will discard all output
Definition: OutputDevice.h:155
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
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.
Representation of a vehicle, person, or container.
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 const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
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.
A scoped lock which only triggers on condition.
Definition: ScopedLocker.h:40
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.
Struct to store the data of the counted vehicle internally.
Definition: MSInductLoop.h:286
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].
Definition: MSInductLoop.h:309