Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2003-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 : /****************************************************************************/
14 : /// @file MSE3Collector.h
15 : /// @author Christian Roessel
16 : /// @author Daniel Krajzewicz
17 : /// @author Michael Behrisch
18 : /// @author Jakob Erdmann
19 : /// @date Tue Dec 02 2003 22:17 CET
20 : ///
21 : // A detector of vehicles passing an area between entry/exit points
22 : /****************************************************************************/
23 : #pragma once
24 : #include <config.h>
25 :
26 : #include <string>
27 : #include <vector>
28 : #include <limits>
29 : #include <microsim/MSMoveReminder.h>
30 : #include <microsim/output/MSDetectorFileOutput.h>
31 : #include <utils/common/Named.h>
32 : #include <microsim/output/MSCrossSection.h>
33 : #include <utils/common/UtilExceptions.h>
34 : #ifdef HAVE_FOX
35 : #include <utils/foxtools/fxheader.h>
36 : #endif
37 :
38 :
39 : // ===========================================================================
40 : // class declarations
41 : // ===========================================================================
42 : class SUMOTrafficObject;
43 : class OutputDevice;
44 : class MSTransportable;
45 :
46 :
47 : // ===========================================================================
48 : // class definitions
49 : // ===========================================================================
50 : /**
51 : * @class MSE3Collector
52 : * @brief A detector of vehicles passing an area between entry/exit points
53 : *
54 : * E3 detectors are defined by a set of in-cross-sections and out-cross-sections.
55 : * Vehicles, that pass an in- and out-cross-section are detected when they pass the
56 : * out-cross-section. Vehicles passing the out-cross-section without having
57 : * passed the in-cross-section are not detected.
58 : */
59 : class MSE3Collector : public MSDetectorFileOutput {
60 : public:
61 : /**
62 : * @class MSE3EntryReminder
63 : * @brief A place on the road net (at a certain lane and position on it) where the E3 area begins
64 : */
65 : class MSE3EntryReminder : public MSMoveReminder {
66 : public:
67 : /** @brief Constructor
68 : *
69 : * @param[in] crossSection The position at which the entry lies
70 : * @param[in] collector The detector the entry belongs to
71 : */
72 : MSE3EntryReminder(const MSCrossSection& crossSection, MSE3Collector& collector);
73 :
74 :
75 : /// @name Methods inherited from MSMoveReminder.
76 : /// @{
77 : /** @brief Checks whether the reminder is activated by a vehicle entering the lane
78 : *
79 : * Lane change means in this case that the vehicle changes to the lane
80 : * the reminder is placed at.
81 : *
82 : * @param[in] veh The entering vehicle.
83 : * @param[in] reason how the vehicle enters the lane
84 : * @return True if vehicle enters the reminder.
85 : * @see Notification
86 : */
87 : bool notifyEnter(SUMOTrafficObject& veh, Notification reason, const MSLane* enteredLane);
88 :
89 : /** @brief Checks whether the vehicle enters
90 : *
91 : * As soon as the reported vehicle enters the detector area (position>myPosition)
92 : * the entering time is computed and both are added to the parent detector using
93 : * "enter".
94 : *
95 : * @param[in] veh The vehicle in question.
96 : * @param[in] oldPos Position before the move-micro-timestep.
97 : * @param[in] newPos Position after the move-micro-timestep.
98 : * @param[in] newSpeed Unused here.
99 : * @return False, if vehicle passed the detector entierly, else true.
100 : * @see MSMoveReminder
101 : * @see MSMoveReminder::notifyMove
102 : * @see MSE3Collector::enter
103 : */
104 : bool notifyMove(SUMOTrafficObject& veh, double, double newPos, double);
105 :
106 :
107 : /** @brief Processes state changes of a vehicle
108 : *
109 : * If the reported vehicle is known, and the reason indicates a removal from the network
110 : * (permanent or temporary), the vehicle is removed from the list of vehicles to regard.
111 : *
112 : * @param[in] veh The leaving vehicle.
113 : * @param[in] lastPos Position on the lane when leaving.
114 : * @param[in] reason The reason for the state change
115 : * @see MSMoveReminder::notifyLeave
116 : */
117 : bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
118 : /// @}
119 :
120 :
121 : double getPosition() const {
122 62736 : return myPosition;
123 : }
124 :
125 : private:
126 : /// @brief The parent collector
127 : MSE3Collector& myCollector;
128 :
129 : /// @brief The position on the lane
130 : double myPosition;
131 :
132 : private:
133 : /// @brief Invalidated copy constructor.
134 : MSE3EntryReminder(const MSE3EntryReminder&);
135 :
136 : /// @brief Invalidated assignment operator.
137 : MSE3EntryReminder& operator=(const MSE3EntryReminder&);
138 :
139 : };
140 :
141 :
142 :
143 : /**
144 : * @class MSE3LeaveReminder
145 : * @brief A place on the road net (at a certain lane and position on it) where the E3 area ends
146 : */
147 : class MSE3LeaveReminder : public MSMoveReminder {
148 : public:
149 : /** @brief Constructor
150 : *
151 : * @param[in] crossSection The position at which the exit lies
152 : * @param[in] collector The detector the exit belongs to
153 : */
154 : MSE3LeaveReminder(const MSCrossSection& crossSection, MSE3Collector& collector);
155 :
156 :
157 : /// @name methods from MSMoveReminder
158 : //@{
159 : /** @brief Checks whether the reminder is activated by a vehicle entering the lane
160 : *
161 : * Lane change means in this case that the vehicle changes to the lane
162 : * the reminder is placed at.
163 : *
164 : * @param[in] veh The entering vehicle.
165 : * @param[in] reason how the vehicle enters the lane
166 : * @return True if vehicle enters the reminder.
167 : * @see Notification
168 : */
169 : bool notifyEnter(SUMOTrafficObject& veh, Notification reason, const MSLane* enteredLane);
170 :
171 : /** @brief Checks whether the vehicle leaves
172 : *
173 : * As soon as the reported vehicle leaves the detector area (position-length>myPosition)
174 : * the leaving time is computed and both are made known to the parent detector using
175 : * "leave".
176 : *
177 : * @param[in] veh The vehicle in question.
178 : * @param[in] oldPos Position before the move-micro-timestep.
179 : * @param[in] newPos Position after the move-micro-timestep.
180 : * @param[in] newSpeed Unused here.
181 : * @return False, if vehicle passed the detector entirely, else true.
182 : * @see MSMoveReminder
183 : * @see MSMoveReminder::notifyMove
184 : * @see MSE3Collector::leave
185 : */
186 : bool notifyMove(SUMOTrafficObject& veh, double oldPos, double newPos, double);
187 :
188 : /** @brief Processes state changes of a vehicle
189 : *
190 : * Checks whether the vehicle has changed lanes and this reminder needs to be removed
191 : *
192 : * @param[in] veh The leaving vehicle (unused).
193 : * @param[in] lastPos Position on the lane when leaving (unused).
194 : * @param[in] reason The reason for the state change
195 : * @see MSMoveReminder::notifyLeave
196 : */
197 : bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
198 : //@}
199 :
200 : double getPosition() const {
201 62736 : return myPosition;
202 : }
203 :
204 :
205 : private:
206 : /// @brief The parent collector
207 : MSE3Collector& myCollector;
208 :
209 : /// @brief The position on the lane
210 : double myPosition;
211 :
212 : private:
213 : /// @brief Invalidated copy constructor.
214 : MSE3LeaveReminder(const MSE3LeaveReminder&);
215 :
216 : /// @brief Invalidated assignment operator.
217 : MSE3LeaveReminder& operator=(const MSE3LeaveReminder&);
218 :
219 : };
220 :
221 :
222 : /** @brief Constructor
223 : *
224 : * Sets reminder objects on entry- and leave-lanes
225 : *
226 : * @param[in] id The detector's unique id.
227 : * @param[in] entries Entry-cross-sections.
228 : * @param[in] exits Leavey-cross-sections.
229 : * @param[in] haltingSpeedThreshold A vehicle must not drive a greater speed than haltingSpeedThreshold to be a "halting" vehicle.
230 : * @param[in] haltingTimeThreshold A vehicle must not drive a greater speed for more than haltingTimeThreshold to be a "halting" vehicle.
231 : */
232 : MSE3Collector(const std::string& id,
233 : const CrossSectionVector& entries, const CrossSectionVector& exits,
234 : double haltingSpeedThreshold,
235 : SUMOTime haltingTimeThreshold,
236 : const std::string name, const std::string& vTypes,
237 : const std::string& nextEdges,
238 : int detectPersons, bool openEntry, bool expectArrival);
239 :
240 :
241 : /// @brief Destructor
242 : virtual ~MSE3Collector();
243 :
244 :
245 : /** @brief Resets all generated values to allow computation of next interval
246 : */
247 : void reset();
248 :
249 :
250 : /** @brief Called if a vehicle touches an entry-cross-section.
251 : *
252 : * Inserts vehicle into internal containers.
253 : *
254 : * @param[in] veh The vehicle that entered the area
255 : * @param[in] entryTimestep The time in seconds the vehicle entered the area
256 : * @param[in] fractionTimeOnDet The interpolated time in seconds the vehicle already spent on the detector
257 : */
258 : void enter(const SUMOTrafficObject& veh, const double entryTimestep, const double fractionTimeOnDet, MSE3EntryReminder* entryReminder, bool isBackward = false);
259 :
260 :
261 : /** @brief Called if a vehicle front passes a leave-cross-section.
262 : *
263 : * @param[in] veh The vehicle that left the area
264 : * @param[in] leaveTimestep The time in seconds the vehicle started crossing the line
265 : */
266 : void leaveFront(const SUMOTrafficObject& veh, const double leaveTimestep);
267 :
268 :
269 : /** @brief Called if a vehicle back passes a leave-cross-section.
270 : *
271 : * Removes vehicle from internal containers.
272 : *
273 : * @param[in] veh The vehicle that left the area
274 : * @param[in] leaveTimestep The time in seconds the vehicle left the area
275 : * @param[in] fractionTimeOnDet The interpolated time in seconds the vehicle still spent on the detector
276 : */
277 : void leave(const SUMOTrafficObject& veh, const double leaveTimestep, const double fractionTimeOnDet, bool isBackward = false);
278 :
279 : /// @brief Returns the entry cross sections
280 : const CrossSectionVector& getEntries() const;
281 :
282 : /// @brief Returns the exit cross sections
283 : const CrossSectionVector& getExits() const;
284 :
285 : /// @name Methods returning current values
286 : /// @{
287 :
288 : /** @brief Returns the mean speed within the area
289 : *
290 : * If no vehicle is within the area, -1 is returned.
291 : *
292 : * @return The mean speed [m/s] of all vehicles within the area, -1 if there is none
293 : */
294 : double getCurrentMeanSpeed() const;
295 :
296 :
297 : /** @brief Returns the number of current haltings within the area
298 : *
299 : * If no vehicle is within the area, 0 is returned.
300 : *
301 : * @return The mean number of haltings within the area
302 : */
303 : int getCurrentHaltingNumber() const;
304 :
305 :
306 : /** @brief Returns the number of vehicles within the area
307 : * @return The number of vehicles that passed the entry collector
308 : */
309 : int getVehiclesWithin() const;
310 :
311 :
312 : /** @brief Returns the number of vehicles within the area
313 : *
314 : * @return The number of vehicles that have passed the entry, but not yet an exit point
315 : */
316 : std::vector<std::string> getCurrentVehicleIDs() const;
317 : /// @}
318 :
319 : /// @name Methods returning values from the previous interval
320 : /// @{
321 :
322 0 : double getLastIntervalMeanTravelTime() const {
323 10 : return myLastMeanTravelTime;
324 : }
325 :
326 0 : double getLastIntervalMeanHaltsPerVehicle() const {
327 10 : return myLastMeanHaltsPerVehicle;
328 : }
329 :
330 0 : double getLastIntervalMeanTimeLoss() const {
331 10 : return myLastMeanTimeLoss;
332 : }
333 :
334 0 : int getLastIntervalVehicleSum() const {
335 10 : return myLastVehicleSum;
336 : }
337 : /// @}
338 :
339 : /// @name Methods inherited from MSDetectorFileOutput.
340 : /// @{
341 :
342 : /** @brief Writes collected values into the given stream
343 : *
344 : * @param[in] dev The output device to write the data into
345 : * @param[in] startTime First time step the data were gathered
346 : * @param[in] stopTime Last time step the data were gathered
347 : * @see MSDetectorFileOutput::writeXMLOutput
348 : * @exception IOError If an error on writing occurs (!!! not yet implemented)
349 : */
350 : void writeXMLOutput(OutputDevice& dev, SUMOTime startTime, SUMOTime stopTime);
351 :
352 :
353 : /** @brief Opens the XML-output using "e3Detector" as root element
354 : *
355 : * The lists of entries/exists are written, too.
356 : *
357 : * @param[in] dev The output device to write the root into
358 : * @see MSDetectorFileOutput::writeXMLDetectorProlog
359 : * @exception IOError If an error on writing occurs (!!! not yet implemented)
360 : */
361 : void writeXMLDetectorProlog(OutputDevice& dev) const;
362 : /// @}
363 :
364 :
365 :
366 : /** @brief Computes the detector values in each time step
367 : *
368 : * This method should be called at the end of a simulation step, when
369 : * all vehicles have moved. The current values are computed and
370 : * summed up with the previous.
371 : *
372 : * @param[in] currentTime The current simulation time (unused)
373 : */
374 : void detectorUpdate(const SUMOTime step);
375 :
376 : /** @brief Remove all vehicles before quick-loading state */
377 : virtual void clearState(SUMOTime step);
378 :
379 : protected:
380 : void notifyMovePerson(MSTransportable* p, MSMoveReminder* rem, double detPos, int dir, double pos);
381 :
382 : protected:
383 : /// @brief name
384 : std::string myName;
385 :
386 : /// @brief The detector's entrys
387 : CrossSectionVector myEntries;
388 :
389 : /// @brief The detector's exits
390 : CrossSectionVector myExits;
391 :
392 : /// @brief The detector's built entry reminder
393 : std::vector<MSE3EntryReminder*> myEntryReminders;
394 :
395 : /// @brief The detector's built exit reminder
396 : std::vector<MSE3LeaveReminder*> myLeaveReminders;
397 :
398 :
399 : // @brief Time-threshold to determine if a vehicle is halting.
400 : SUMOTime myHaltingTimeThreshold;
401 :
402 : /// @brief Speed-threshold to determine if a vehicle is halting.
403 : double myHaltingSpeedThreshold;
404 :
405 : /**
406 : * @struct E3Values
407 : * @brief Internal storage for values from a vehicle
408 : *
409 : * For each vehicle within the area (that entered through an entry point),
410 : * this structure is allocated. All values gathered from the vehicle are aggregated
411 : * within this structure.
412 : */
413 : struct E3Values {
414 : /// @brief The vehicle's entry time
415 : double entryTime;
416 : /// @brief The time the vehicle's front was crossing the leave line
417 : double frontLeaveTime;
418 : /// @brief The time the vehicle's back was crossing the leave line
419 : double backLeaveTime;
420 : /// @brief The sum of registered speeds the vehicle has/had inside the area
421 : double speedSum;
422 : /// @brief The sum of haltings the vehicle has/had within the area
423 : int haltings;
424 : /// @brief Begin time of last halt begin
425 : SUMOTime haltingBegin;
426 : /// @brief The sum of registered speeds the vehicle has/had inside the area during the current interval
427 : double intervalSpeedSum;
428 : /// @brief The sum of haltings the vehicle has/had within the area during the current interval
429 : int intervalHaltings;
430 : /// @brief The timeLoss of the vehicle when entering. Updated to the actual time loss within the area when leaving
431 : SUMOTime timeLoss;
432 : /// @brief The timeLoss of the vehicle when entering. Updated to the current timeLoss at interval write
433 : SUMOTime intervalTimeLoss;
434 : /// @brief An internal information whether the update step was performed
435 : bool hadUpdate;
436 : /// @brief the reminder on which the vehicle entered the detector
437 : MSE3EntryReminder* entryReminder;
438 : };
439 :
440 : /// @brief Container for vehicles that have entered the area
441 : std::map<const SUMOTrafficObject*, E3Values> myEnteredContainer;
442 :
443 : /// @brief Container for vehicles that have left the area
444 : std::vector<E3Values> myLeftContainer;
445 :
446 : #ifdef HAVE_FOX
447 : /// @brief the mutex for access to the containers
448 : FXMutex myContainerMutex;
449 : #endif
450 :
451 : /// @name Storages for current values
452 : /// @{
453 :
454 : /// @brief The current mean speed of known vehicles (inside)
455 : double myCurrentMeanSpeed;
456 :
457 : /// @brief The current number of haltings (inside)
458 : int myCurrentHaltingsNumber;
459 : /// @}
460 :
461 : /// @name Storages for last written values
462 : /// @{
463 : double myLastMeanTravelTime;
464 : double myLastMeanHaltsPerVehicle;
465 : double myLastMeanTimeLoss;
466 : int myLastVehicleSum;
467 : /// @}
468 :
469 : /// @brief Information when the last reset has been done
470 : SUMOTime myLastResetTime;
471 :
472 : /// @brief whether this dector is declared as having incomplete entry detectors
473 : const bool myOpenEntry;
474 : /// @brief Whether the detector expects vehicles to arrive inside (and doesn't issue a warning in this case)
475 : const bool myExpectArrival;
476 :
477 : private:
478 : /// @brief Invalidated copy constructor.
479 : MSE3Collector(const MSE3Collector&);
480 :
481 : /// @brief Invalidated assignment operator.
482 : MSE3Collector& operator=(const MSE3Collector&);
483 :
484 :
485 : };
|