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    MSDetectorControl.h
11 /// @author  Daniel Krajzewicz
12 /// @author  Laura Bieker
13 /// @author  Clemens Honomichl
14 /// @author  Sascha Krieg
15 /// @author  Michael Behrisch
16 /// @date    2005-09-15
17 /// @version $Id$
18 ///
19 // Detectors container; responsible for string and output generation
20 /****************************************************************************/
21 #ifndef MSDetectorControl_h
22 #define MSDetectorControl_h
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #include <config.h>
29 
30 #include <string>
31 #include <vector>
32 #include <utils/common/NamedObjectCont.h>
33 #include <utils/xml/SUMOXMLDefinitions.h>
34 #include <microsim/output/MSE2Collector.h>
35 #include <microsim/output/MSE3Collector.h>
36 #include <microsim/output/MSInductLoop.h>
37 #include <microsim/output/MSRouteProbe.h>
38 
39 
40 // ===========================================================================
41 // class declarations
42 // ===========================================================================
43 class MSMeanData;
44 
45 
46 // ===========================================================================
47 // class definitions
48 // ===========================================================================
49 /**
50  * @class MSDetectorControl
51  * @brief Detectors container; responsible for string and output generation
52  */
53 class MSDetectorControl {
54 public:
55     /** @brief Constructor
56      */
57     MSDetectorControl();
58 
59 
60     /** @brief Destructor
61      *
62      * Deletes all stored detectors.
63      */
64     ~MSDetectorControl();
65 
66 
67     /** @brief Closes the detector outputs
68      *
69      * Goes through the intervals to write and writes the last step using
70      *  the current simulation time as end.
71      *
72      * @param[in] step The time step (the simulation has ended at)
73      */
74     void close(SUMOTime step);
75 
76 
77     /** @brief Adds a detector/output combination into the containers
78      *
79      * The detector is tried to be added into "myDetectors". If the detector
80      *  is already known (the id was already used for a similar detector),
81      *  a ProcessError is thrown.
82      *
83      * Otherwise, the Detector2File-mechanism is instantiated for the detector.
84      *
85      * Please note, that the detector control gets responsible for the detector.
86      *
87      * @param[in] type The type of the detector
88      * @param[in] d The detector to add
89      * @param[in] device The device the detector uses
90      * @param[in] splInterval The sample interval of the detector
91      * @exception ProcessError If the detector is already known
92      */
93     void add(SumoXMLTag type, MSDetectorFileOutput* d, const std::string& device, SUMOTime splInterval, SUMOTime begin = -1);
94 
95 
96 
97     /** @brief Adds only the detector into the containers
98      *
99      * The detector is tried to be added into "myDetectors". If the detector
100      *  is already known (the id was already used for a similar detector),
101      *  a ProcessError is thrown.
102      *
103      * Please note, that the detector control gets responsible for the detector.
104      *
105      * @param[in] type The type of the detector
106      * @param[in] d The detector to add
107      * @exception ProcessError If the detector is already known
108      */
109     void add(SumoXMLTag type, MSDetectorFileOutput* d);
110 
111 
112     /** @brief Adds a mean data object
113      *
114      * The detector is pushed into the internal list.
115      *
116      * Please note, that the detector control gets responsible for the detector.
117      *
118      * @param[in] mn The mean data to add
119      * @param[in] device The output device to use
120      * @param[in] frequency The frequency for output generation
121      * @param[in] begin The begin of the first interval
122      */
123     void add(MSMeanData* mn, const std::string& device,
124              SUMOTime frequency, SUMOTime begin);
125 
126 
127 
128     /** @brief Adds one of the detectors as a new MSDetectorFileOutput
129      *
130      * @param[in] det The generator to add
131      * @param[in] device The device to use
132      * @param[in] interval The sample interval to use
133      * @param[in] begin The start of the first sample interval to use
134      */
135     void addDetectorAndInterval(MSDetectorFileOutput* det,
136                                 OutputDevice* device,
137                                 SUMOTime interval, SUMOTime begin = -1);
138 
139 
140 
141     /** @brief Returns the list of available detector types
142      *
143      * @return The list of types
144      */
145     const std::vector<SumoXMLTag> getAvailableTypes() const;
146 
147 
148     /** @brief Returns the list of detectors of the given type
149      *
150      * @param[in] type The type of detectors to be retrieved
151      * @return The container of detectors
152      */
153     const NamedObjectCont<MSDetectorFileOutput*>& getTypedDetectors(SumoXMLTag type) const;
154 
155 
156     /** @brief Computes detector values
157      *
158      * Some detectors need to be touched each time step in order to compute
159      *  values from the vehicles stored in their containers. This method
160      *  goes through all of these detectors and forces a recomputation of
161      *  the values.
162      * @param[in] step The current time step
163      */
164     void updateDetectors(const SUMOTime step);
165 
166 
167     /** @brief Writes the output to be generated within the given time step
168      *
169      * Goes through the list of intervals. If one interval has ended within the
170      *  given step or if the closing-flag is set and the output was not
171      *  written in this step already, the writeXMLOutput method is called
172      *  for all MSDetectorFileOutputs within this interval.
173      *
174      * @param[in] step The current time step
175      * @param[in] closing Whether the device is closed
176      * @exception IOError If an error on writing occurs (!!! not yet implemented)
177      */
178     void writeOutput(SUMOTime step, bool closing);
179 
180 
181 protected:
182     /// @name Structures needed for assigning detectors to intervals
183     /// @{
184 
185     /// @brief A pair of a Detector with it's associated file-stream.
186     typedef std::pair< MSDetectorFileOutput*, OutputDevice* > DetectorFilePair;
187 
188     /// @brief Container holding DetectorFilePair (with the same interval).
189     typedef std::vector< DetectorFilePair > DetectorFileVec;
190 
191     /// @brief Definition of the interval key
192     typedef std::pair<SUMOTime, SUMOTime> IntervalsKey;
193 
194     /// @brief Association of intervals to DetectorFilePair containers.
195     typedef std::map< IntervalsKey, DetectorFileVec > Intervals;
196     /// @}
197 
198     /**
199      * @struct detectorEquals
200      * @brief Returns true if detectors are equal.
201      *
202      * Binary predicate that compares the passed DetectorFilePair's
203      * detector to a fixed one. Returns true if detectors are
204      * equal. (Used to prevent multiple inclusion of a detector for
205      * the same interval.)
206      *
207      * @see addDetectorAndInterval
208      */
209     struct detectorEquals : public std::binary_function< DetectorFilePair, MSDetectorFileOutput*, bool > {
210         /** @brief Returns true if detectors are equal. */
operatordetectorEquals211         bool operator()(const DetectorFilePair& pair, const MSDetectorFileOutput* det) const {
212             return pair.first == det;
213         }
214     };
215 
216 protected:
217     /// @brief The detectors map, first by detector type, then using NamedObjectCont (@see NamedObjectCont)
218     std::map<SumoXMLTag, NamedObjectCont< MSDetectorFileOutput*> > myDetectors;
219 
220 
221     /// @brief Map that hold DetectorFileVec for given intervals
222     Intervals myIntervals;
223 
224     /// @brief The map that holds the last call for each sample interval
225     std::map<IntervalsKey, SUMOTime> myLastCalls;
226 
227     /// @brief List of harmonoise detectors
228     std::vector<MSMeanData*> myMeanData;
229 
230     /// @brief An empty container to return in getTypedDetectors() if no detectors of the asked type exist
231     NamedObjectCont< MSDetectorFileOutput*> myEmptyContainer;
232 
233 
234 private:
235     /// @brief Invalidated copy constructor.
236     MSDetectorControl(const MSDetectorControl&);
237 
238     /// @brief Invalidated assignment operator.
239     MSDetectorControl& operator=(const MSDetectorControl&);
240 
241 
242 };
243 
244 
245 #endif
246 
247 /****************************************************************************/
248 
249