Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSInstantInductLoop.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2011-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/****************************************************************************/
20// An instantaneous induction loop
21/****************************************************************************/
22#include <config.h>
23
24#include "MSInstantInductLoop.h"
25#include <cassert>
26#include <numeric>
27#include <utility>
28#ifdef HAVE_FOX
30#endif
34#include <microsim/MSLane.h>
35#include <microsim/MSVehicle.h>
36#include <microsim/MSNet.h>
41
42
43// ===========================================================================
44// method definitions
45// ===========================================================================
47 OutputDevice& od, MSLane* const lane, double positionInMeters,
48 const std::string name, const std::string& vTypes,
49 const std::string& nextEdges,
50 int detectPersons) :
51 MSMoveReminder(id, lane),
52 MSDetectorFileOutput(id, vTypes, nextEdges, detectPersons),
53 myName(name),
54 myOutputDevice(od),
55 myPosition(positionInMeters), myLastExitTime(-1) {
56 assert(myPosition >= 0 && myPosition <= myLane->getLength());
58}
59
60
63
64bool
66 // vehicles must be kept if the "inductionloop" wants to detect passeengers
67 if (!vehicleApplies(veh)) {
68 return false;
69 }
70 if (reason != NOTIFICATION_JUNCTION) { // the junction case is handled in notifyMove
72 return false;
73 }
74 if (veh.getPositionOnLane() >= myPosition) {
75 double entryTime = SIMTIME;
76 if (myLastExitTime >= 0) {
77 write("enter", entryTime, veh, veh.getSpeed(), "gap", entryTime - myLastExitTime);
78 } else {
79 write("enter", entryTime, veh, veh.getSpeed());
80 }
81 myEntryTimes[&veh] = entryTime;
82 }
83 }
84 return true;
85}
86
87
88bool
90 double newPos, double newSpeed) {
91 if (!vehicleApplies(veh)) {
92 return false;
93 }
94 if (newPos < myPosition) {
95 // detector not reached yet
96 return true;
97 }
98#ifdef HAVE_FOX
99 ScopedLocker<> lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
100#endif
101
102 const double oldSpeed = veh.getPreviousSpeed();
103 double enterSpeed = MSGlobals::gSemiImplicitEulerUpdate ? newSpeed : oldSpeed; // NOTE: For the euler update, the vehicle is assumed to travel at constant speed for the whole time step
104
105 if (newPos >= myPosition && oldPos < myPosition/* && static_cast<MSVehicle&>(veh).getLane() == myLane*/) {
106 const double timeBeforeEnter = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
107 const double entryTime = SIMTIME - TS + timeBeforeEnter;
108 enterSpeed = MSCFModel::speedAfterTime(timeBeforeEnter, oldSpeed, newPos - oldPos);
109 if (myLastExitTime >= 0) {
110 write("enter", entryTime, veh, enterSpeed, "gap", entryTime - myLastExitTime);
111 } else {
112 write("enter", entryTime, veh, enterSpeed);
113 }
114 myEntryTimes[&veh] = entryTime;
115 }
116 const double newBackPos = newPos - veh.getVehicleType().getLength();
117 const double oldBackPos = oldPos - veh.getVehicleType().getLength();
118 if (newBackPos > myPosition) {
119 std::map<SUMOTrafficObject*, double>::iterator i = myEntryTimes.find(&veh);
120 if (i != myEntryTimes.end()) {
121 // vehicle passed the detector
122 const double timeBeforeLeave = MSCFModel::passingTime(oldBackPos, myPosition, newBackPos, oldSpeed, newSpeed);
123 const double leaveTime = SIMTIME - TS + timeBeforeLeave;
124 write("leave", leaveTime, veh, newSpeed, "occupancy", leaveTime - (*i).second);
125 myEntryTimes.erase(i);
126 myLastExitTime = leaveTime;
127 }
128 return false;
129 }
130 // vehicle stays on the detector
131 write("stay", SIMTIME, veh, newSpeed);
132 return true;
133}
134
135
136void
137MSInstantInductLoop::write(const char* state, double t, SUMOTrafficObject& veh, double speed, const char* add, double addValue) {
138 if (!myOutputDevice.isNull()) {
139 myOutputDevice.openTag("instantOut").writeAttr(
140 "id", getID()).writeAttr("time", toString(t)).writeAttr("state", state).writeAttr(
141 "vehID", veh.getID()).writeAttr("speed", toString(speed)).writeAttr(
142 "length", toString(veh.getVehicleType().getLength())).writeAttr(
143 "type", veh.getVehicleType().getID());
144 if (add != nullptr) {
145 myOutputDevice.writeAttr(add, toString(addValue));
146 }
148 }
149}
150
151
152bool
153MSInstantInductLoop::notifyLeave(SUMOTrafficObject& veh, double /* lastPos */, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
155 // vehicle might have jumped over detector at the end of the lane. we need
156 // one more notifyMove to register it
157 return true;
158 }
159 std::map<SUMOTrafficObject*, double>::iterator i = myEntryTimes.find(&veh);
160 if (i != myEntryTimes.end()) {
161 write("leave", SIMTIME, veh, veh.getSpeed());
162 myEntryTimes.erase(i);
163 }
164 return false;
165}
166
167
168void
170 dev.writeXMLHeader("instantE1", "instant_e1_file.xsd");
171}
172
173
174/****************************************************************************/
#define TS
Definition SUMOTime.h:42
#define SIMTIME
Definition SUMOTime.h:62
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
static double speedAfterTime(const double t, const double oldSpeed, const double dist)
Calculates the speed after a time t \in [0,TS] given the initial speed and the distance traveled in a...
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.
static bool gSemiImplicitEulerUpdate
Definition MSGlobals.h:53
static int gNumSimThreads
how many threads to use for simulation
Definition MSGlobals.h:146
std::map< SUMOTrafficObject *, double > myEntryTimes
The last exit time.
MSInstantInductLoop(const std::string &id, OutputDevice &od, MSLane *const lane, double positionInMeters, const std::string name, const std::string &vTypes, const std::string &nextEdges, int detectPersons)
Constructor.
bool notifyEnter(SUMOTrafficObject &veh, Notification reason, const MSLane *enteredLane=0)
Checks whether the reminder is activated by a vehicle entering the lane.
OutputDevice & myOutputDevice
The output device to use.
void writeXMLDetectorProlog(OutputDevice &dev) const
Open the XML-output.
void write(const char *state, double t, SUMOTrafficObject &veh, double speed, const char *add=0, double addValue=-1)
Writes an event line.
const double myPosition
Detector's position on lane [m].
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.
double myLastExitTime
The last exit time.
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Checks whether the vehicle shall be counted and/or shall still touch this MSMoveReminder.
Representation of a lane in the micro simulation.
Definition MSLane.h:84
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.
const std::string & getID() const
Returns the name of the 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.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
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.
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 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.