1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    MSMeanData.h
11 /// @author  Daniel Krajzewicz
12 /// @author  Michael Behrisch
13 /// @date    Tue, 17.11.2009
14 /// @version $Id$
15 ///
16 // Data collector for edges/lanes
17 /****************************************************************************/
18 #ifndef MSMeanData_h
19 #define MSMeanData_h
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <vector>
28 #include <set>
29 #include <list>
30 #include <limits>
31 #include <microsim/output/MSDetectorFileOutput.h>
32 #include <microsim/MSMoveReminder.h>
33 #include <utils/common/SUMOTime.h>
34 
35 
36 // ===========================================================================
37 // class declarations
38 // ===========================================================================
39 class OutputDevice;
40 class MSEdge;
41 class MSLane;
42 class SUMOTrafficObject;
43 
44 typedef std::vector<MSEdge*> MSEdgeVector;
45 
46 // ===========================================================================
47 // class definitions
48 // ===========================================================================
49 /**
50  * @class MSMeanData
51  * @brief Data collector for edges/lanes
52  *
53  * This structure does not contain the data itself, it is stored within
54  *  MeanDataValues-MoveReminder objects.
55  * This class is used to build the output, optionally, in the case
56  *  of edge-based dump, aggregated over the edge's lanes.
57  *
58  * @todo consider error-handling on write (using IOError)
59  */
60 class MSMeanData : public MSDetectorFileOutput {
61 public:
62     /**
63      * @class MeanDataValues
64      * @brief Data structure for mean (aggregated) edge/lane values
65      *
66      * Structure holding values that describe the emissions (XXX: emissions?) aggregated, refs. #2579
67      *  over some seconds.
68      */
69     class MeanDataValues : public MSMoveReminder {
70     public:
71         /** @brief Constructor */
72         MeanDataValues(MSLane* const lane, const double length, const bool doAdd, const MSMeanData* const parent);
73 
74         /** @brief Destructor */
75         virtual ~MeanDataValues();
76 
77 
78         /** @brief Resets values so they may be used for the next interval
79          */
80         virtual void reset(bool afterWrite = false) = 0;
81 
82         /** @brief Add the values of this to the given one and store them there
83          *
84          * @param[in] val The meandata to add to
85          */
86         virtual void addTo(MeanDataValues& val) const = 0;
87 
88 
89         /** @brief Called if the vehicle enters the reminder's lane
90          *
91          * @param[in] veh The entering vehicle.
92          * @param[in] reason how the vehicle enters the lane
93          * @see MSMoveReminder
94          * @see MSMoveReminder::notifyEnter
95          * @see MSMoveReminder::Notification
96          */
97         virtual bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
98 
99 
100         /** @brief Checks whether the reminder still has to be notified about the vehicle moves
101          *
102          * Indicator if the reminders is still active for the passed
103          * vehicle/parameters. If false, the vehicle will erase this reminder
104          * from it's reminder-container.
105          *
106          * @param[in] veh Vehicle that asks this reminder.
107          * @param[in] oldPos Position before move.
108          * @param[in] newPos Position after move with newSpeed.
109          * @param[in] newSpeed Moving speed.
110          *
111          * @return True if vehicle hasn't passed the reminder completely.
112          */
113         bool notifyMove(SUMOTrafficObject& veh, double oldPos,
114                         double newPos, double newSpeed);
115 
116 
117         /** @brief Called if the vehicle leaves the reminder's lane
118          *
119          * @param veh The leaving vehicle.
120          * @param[in] lastPos Position on the lane when leaving.
121          * @param[in] reason how the vehicle leaves the lane
122          * @see MSMoveReminder
123          * @see MSMoveReminder::notifyLeave
124          */
125         virtual bool notifyLeave(SUMOTrafficObject& veh, double lastPos,
126                                  MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
127 
128 
129         /** @brief Returns whether any data was collected.
130          *
131          * @return whether no data was collected
132          */
133         virtual bool isEmpty() const;
134 
135 
136         /** @brief Called if a per timestep update is needed. Default does nothing.
137          */
138         virtual void update();
139 
140         /** @brief Writes output values into the given stream
141          *
142          * @param[in] dev The output device to write the data into
143          * @param[in] period Length of the period the data were gathered
144          * @param[in] numLanes The total number of lanes for which the data was collected
145          * @exception IOError If an error on writing occurs (!!! not yet implemented)
146          */
147         virtual void write(OutputDevice& dev, const SUMOTime period,
148                            const double numLanes, const double defaultTravelTime,
149                            const int numVehicles = -1) const = 0;
150 
151         /** @brief Returns the number of collected sample seconds.
152         * @return the number of collected sample seconds
153         */
154         virtual double getSamples() const;
155 
156         /** @brief Returns the total travelled distance.
157         * @return the total travelled distance
158         */
getTravelledDistance()159         double getTravelledDistance() const {
160             return travelledDistance;
161         }
162 
163     protected:
164         /// @brief The meandata parent
165         const MSMeanData* const myParent;
166 
167         /// @brief The length of the lane / edge the data collector is on
168         const double myLaneLength;
169 
170         /// @name Collected values
171         /// @{
172         /// @brief The number of sampled vehicle movements (in s)
173         double sampleSeconds;
174 
175         /// @brief The sum of the distances the vehicles travelled
176         double travelledDistance;
177         //@}
178 
179     };
180 
181 
182     /**
183      * @class MeanDataValueTracker
184      * @brief Data structure for mean (aggregated) edge/lane values for tracked vehicles
185      */
186     class MeanDataValueTracker : public MeanDataValues {
187     public:
188         /** @brief Constructor */
189         MeanDataValueTracker(MSLane* const lane, const double length,
190                              const MSMeanData* const parent);
191 
192         /** @brief Destructor */
193         virtual ~MeanDataValueTracker();
194 
195         /** @brief Resets values so they may be used for the next interval
196          */
197         void reset(bool afterWrite);
198 
199         /** @brief Add the values of this to the given one and store them there
200          *
201          * @param[in] val The meandata to add to
202          */
203         void addTo(MSMeanData::MeanDataValues& val) const;
204 
205         /// @name Methods inherited from MSMoveReminder
206         /// @{
207 
208         /** @brief Internal notification about the vehicle moves
209          *  @see MSMoveReminder::notifyMoveInternal().
210          */
211         void notifyMoveInternal(const SUMOTrafficObject& veh, const double frontOnLane, const double timeOnLane, const double meanSpeedFrontOnLane, const double meanSpeedVehicleOnLane, const double travelledDistanceFrontOnLane, const double travelledDistanceVehicleOnLane, const double meanLengthOnLane);
212 
213 
214         /** @brief Called if the vehicle leaves the reminder's lane
215          *
216          * @param veh The leaving vehicle.
217          * @param[in] lastPos Position on the lane when leaving.
218          * @param[in] isArrival whether the vehicle arrived at its destination
219          * @param[in] isLaneChange whether the vehicle changed from the lane
220          * @see MSMoveReminder
221          * @see MSMoveReminder::notifyLeave
222          */
223         bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
224 
225 
226         /** @brief Computes current values and adds them to their sums
227          *
228          * The fraction of time the vehicle is on the lane is computed and
229          *  used as a weight for the vehicle's current values.
230          *  The "emitted" field is incremented, additionally.
231          *
232          * @param[in] veh The entering vehicle.
233          * @param[in] reason how the vehicle enters the lane
234          * @see MSMoveReminder::notifyEnter
235          * @return Always true
236          */
237         bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0);
238         //@}
239 
240         bool isEmpty() const;
241 
242         /** @brief Writes output values into the given stream
243          *
244          * @param[in] dev The output device to write the data into
245          * @param[in] period Length of the period the data were gathered
246          * @param[in] numLanes The total number of lanes for which the data was collected
247          * @exception IOError If an error on writing occurs (!!! not yet implemented)
248          */
249         void write(OutputDevice& dev, const SUMOTime period,
250                    const double numLanes, const double defaultTravelTime,
251                    const int numVehicles = -1) const;
252 
253         int getNumReady() const;
254 
255         void clearFirst();
256 
257         double getSamples() const;
258 
259     private:
260         class TrackerEntry {
261         public:
262             /** @brief Constructor */
TrackerEntry(MeanDataValues * const values)263             TrackerEntry(MeanDataValues* const values)
264                 : myNumVehicleEntered(0), myNumVehicleLeft(0), myValues(values) {}
265 
266             /** @brief Constructor */
~TrackerEntry()267             virtual ~TrackerEntry() {
268                 delete myValues;
269             }
270 
271             /// @brief The number of vehicles which entered in the current interval
272             int myNumVehicleEntered;
273 
274             /// @brief The number of vehicles which left in the current interval
275             int myNumVehicleLeft;
276 
277             /// @brief The number of vehicles which left in the current interval
278             MeanDataValues* myValues;
279         };
280 
281         /// @brief The map of vehicles to data entries
282         std::map<const SUMOTrafficObject*, TrackerEntry*> myTrackedData;
283 
284         /// @brief The currently active meandata "intervals"
285         std::list<TrackerEntry*> myCurrentData;
286 
287     };
288 
289 
290 public:
291     /** @brief Constructor
292      *
293      * @param[in] id The id of the detector
294      * @param[in] dumpBegin Begin time of dump
295      * @param[in] dumpEnd End time of dump
296      * @param[in] useLanes Information whether lane-based or edge-based dump shall be generated
297      * @param[in] withEmpty Information whether empty lanes/edges shall be written
298      * @param[in] withInternal Information whether internal lanes/edges shall be written
299      * @param[in] trackVehicles Information whether vehicles shall be tracked
300      * @param[in] detectPersons Whether pedestrians shall be detected instead of vehicles
301      * @param[in] maxTravelTime the maximum travel time to use when calculating per vehicle output
302      * @param[in] defaultEffort the value to use when calculating defaults
303      * @param[in] minSamples the minimum number of sample seconds before the values are valid
304      * @param[in] vTypes the set of vehicle types to consider
305      */
306     MSMeanData(const std::string& id,
307                const SUMOTime dumpBegin, const SUMOTime dumpEnd,
308                const bool useLanes, const bool withEmpty,
309                const bool printDefaults, const bool withInternal,
310                const bool trackVehicles, const int detectPersons,
311                const double minSamples,
312                const double maxTravelTime,
313                const std::string& vTypes);
314 
315 
316     /// @brief Destructor
317     virtual ~MSMeanData();
318 
319     /** @brief Adds the value collectors to all relevant edges.
320      */
321     void init();
322 
323     /// @name Methods inherited from MSDetectorFileOutput.
324     /// @{
325 
326     /** @brief Writes collected values into the given stream
327      *
328      * At first, it is checked whether the values for the current interval shall be written.
329      *  If not, a reset is performed, only, using "resetOnly". Otherwise,
330      *  both the list of single-lane edges and the list of multi-lane edges
331      *  are gone through and each edge is written using "writeEdge".
332      *
333      * @param[in] dev The output device to write the data into
334      * @param[in] startTime First time step the data were gathered
335      * @param[in] stopTime Last time step the data were gathered
336      * @see MSDetectorFileOutput::writeXMLOutput
337      * @see write
338      * @exception IOError If an error on writing occurs (!!! not yet implemented)
339      */
340     void writeXMLOutput(OutputDevice& dev, SUMOTime startTime, SUMOTime stopTime);
341 
342     /** @brief Opens the XML-output using "netstats" as root element
343      *
344      * @param[in] dev The output device to write the root into
345      * @see MSDetectorFileOutput::writeXMLDetectorProlog
346      * @exception IOError If an error on writing occurs (!!! not yet implemented)
347      */
348     virtual void writeXMLDetectorProlog(OutputDevice& dev) const;
349     /// @}
350 
351     /** @brief Updates the detector
352      */
353     virtual void detectorUpdate(const SUMOTime step);
354 
getMinSamples()355     double getMinSamples() const {
356         return myMinSamples;
357     }
358 
getMaxTravelTime()359     double getMaxTravelTime() const {
360         return myMaxTravelTime;
361     }
362 
363 
364 protected:
365     /** @brief Create an instance of MeanDataValues
366      *
367      * @param[in] lane The lane to create for
368      * @param[in] doAdd whether to add the values as reminder to the lane
369      */
370     virtual MSMeanData::MeanDataValues* createValues(MSLane* const lane, const double length, const bool doAdd) const = 0;
371 
372     /** @brief Resets network value in order to allow processing of the next interval
373      *
374      * Goes through the lists of edges and starts "resetOnly" for each edge.
375      * @param[in] edge The last time step that is reported
376      */
377     void resetOnly(SUMOTime stopTime);
378 
379     /** @brief Return the relevant edge id
380      *
381      * @param[in] edge The edge to retrieve the id for
382      */
383     virtual std::string getEdgeID(const MSEdge* const edge);
384 
385     /** @brief Writes edge values into the given stream
386      *
387      * microsim: It is checked whether the dump shall be generated edge-
388      *  or lane-wise. In the first case, the lane-data are collected
389      *  and aggregated and written directly. In the second case, "writeLane"
390      *  is used to write each lane's state.
391      *
392      * @param[in] dev The output device to write the data into
393      * @param[in] edgeValues List of this edge's value collectors
394      * @param[in] edge The edge to write the dump of
395      * @param[in] startTime First time step the data were gathered
396      * @param[in] stopTime Last time step the data were gathered
397      * @exception IOError If an error on writing occurs (!!! not yet implemented)
398      */
399     void writeEdge(OutputDevice& dev, const std::vector<MeanDataValues*>& edgeValues,
400                    MSEdge* edge, SUMOTime startTime, SUMOTime stopTime);
401 
402     /** @brief Writes the interval opener
403      *
404      * @param[in] dev The output device to write the data into
405      * @param[in] startTime First time step the data were gathered
406      * @param[in] stopTime Last time step the data were gathered
407      */
408     virtual void openInterval(OutputDevice& dev, const SUMOTime startTime, const SUMOTime stopTime);
409 
410     /** @brief Checks for emptiness and writes prefix into the given stream
411      *
412      * @param[in] dev The output device to write the data into
413      * @param[in] values The values to check for emptiness
414      * @param[in] tag The xml tag to write (lane / edge)
415      * @param[in] id The id for the lane / edge to write
416      * @return whether further output should be generated
417      * @exception IOError If an error on writing occurs (!!! not yet implemented)
418      */
419     virtual bool writePrefix(OutputDevice& dev, const MeanDataValues& values,
420                              const SumoXMLTag tag, const std::string id) const;
421 
422 protected:
423     /// @brief the minimum sample seconds
424     const double myMinSamples;
425 
426     /// @brief the maximum travel time to write
427     const double myMaxTravelTime;
428 
429     /// @brief Value collectors; sorted by edge, then by lane
430     std::vector<std::vector<MeanDataValues*> > myMeasures;
431 
432     /// @brief Whether empty lanes/edges shall be written
433     const bool myDumpEmpty;
434 
435 private:
436     /// @brief Information whether the output shall be edge-based (not lane-based)
437     const bool myAmEdgeBased;
438 
439     /// @brief The first and the last time step to write information (-1 indicates always)
440     const SUMOTime myDumpBegin, myDumpEnd;
441 
442     /// @brief The corresponding first edges
443     MSEdgeVector myEdges;
444 
445     /// @brief Whether empty lanes/edges shall be written
446     const bool myPrintDefaults;
447 
448     /// @brief Whether internal lanes/edges shall be written
449     const bool myDumpInternal;
450 
451     /// @brief Whether vehicles are tracked
452     const bool myTrackVehicles;
453 
454     /// @brief The intervals for which output still has to be generated (only in the tracking case)
455     std::list< std::pair<SUMOTime, SUMOTime> > myPendingIntervals;
456 
457 private:
458     /// @brief Invalidated copy constructor.
459     MSMeanData(const MSMeanData&);
460 
461     /// @brief Invalidated assignment operator.
462     MSMeanData& operator=(const MSMeanData&);
463 
464 };
465 
466 
467 #endif
468 
469 /****************************************************************************/
470 
471