Eclipse SUMO - Simulation of Urban MObility
MSDetectorControl.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 /****************************************************************************/
23 // Detectors container; responsible for string and output generation
24 /****************************************************************************/
25 #include <config.h>
26 
27 #include <iostream>
29 #include <utils/options/Option.h>
31 #include "MSMeanData_Emissions.h"
32 #include "MSMeanData_Net.h"
33 #include "MSDetectorControl.h"
34 
35 
36 // ===========================================================================
37 // member method definitions
38 // ===========================================================================
40 }
41 
42 
44  for (auto i = myDetectors.begin(); i != myDetectors.end(); ++i) {
45  (*i).second.clear();
46  }
47  for (auto item : myMeanData) {
48  for (MSMeanData* md : item.second) {
49  delete md;
50  }
51  }
52  myMeanData.clear();
53 }
54 
55 
56 void
58  // flush the last values
59  writeOutput(step, true);
60  // [...] files are closed on another place [...]
61  myIntervals.clear();
62 }
63 
64 
65 void
66 MSDetectorControl::add(SumoXMLTag type, MSDetectorFileOutput* d, const std::string& device, SUMOTime interval, SUMOTime begin) {
67  if (!myDetectors[type].add(d->getID(), d)) {
68  const std::string id = d->getID();
69  delete d;
70  throw ProcessError(toString(type) + " detector '" + id + "' could not be built (declared twice?).");
71  }
72  addDetectorAndInterval(d, &OutputDevice::getDevice(device), interval, begin);
73 }
74 
75 
76 void
78  if (!myDetectors[type].add(d->getID(), d)) {
79  const std::string id = d->getID();
80  delete d;
81  throw ProcessError(toString(type) + " detector '" + id + "' could not be built (declared twice?).");
82  }
83 }
84 
85 
86 void
87 MSDetectorControl::add(MSMeanData* md, const std::string& device,
88  SUMOTime frequency, SUMOTime begin) {
89  myMeanData[md->getID()].push_back(md);
90  addDetectorAndInterval(md, &OutputDevice::getDevice(device), frequency, begin);
91  if (begin <= string2time(OptionsCont::getOptions().getString("begin"))) {
92  md->init();
93  }
94  MSGlobals::gHaveEmissions |= typeid(*md) == typeid(MSMeanData_Emissions);
95 }
96 
97 
98 const std::vector<SumoXMLTag>
100  std::vector<SumoXMLTag> result;
101  for (std::map<SumoXMLTag, NamedObjectCont<MSDetectorFileOutput*> >::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
102  result.push_back(i->first);
103  }
104  return result;
105 }
106 
107 
110  if (myDetectors.find(type) == myDetectors.end()) {
111  return myEmptyContainer;
112  }
113  return myDetectors.find(type)->second;
114 }
115 
116 
117 void
119  for (const auto& i : myDetectors) {
120  for (const auto& j : getTypedDetectors(i.first)) {
121  j.second->detectorUpdate(step);
122  }
123  }
124  for (auto item : myMeanData) {
125  for (MSMeanData* md : item.second) {
126  md->detectorUpdate(step);
127  }
128  }
129 }
130 
131 
132 void
134  for (Intervals::iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
135  IntervalsKey interval = (*i).first;
136  if (myLastCalls[interval] + interval.first <= step || (closing && myLastCalls[interval] < step)) {
137  DetectorFileVec dfVec = (*i).second;
138  SUMOTime startTime = myLastCalls[interval];
139  // check whether at the end the output was already generated
140  for (DetectorFileVec::iterator it = dfVec.begin(); it != dfVec.end(); ++it) {
141  MSDetectorFileOutput* det = it->first;
142  det->writeXMLOutput(*(it->second), startTime, step);
143  }
144  myLastCalls[interval] = step;
145  }
146  }
147 }
148 
149 
150 void
152  OutputDevice* device,
153  SUMOTime interval,
154  SUMOTime begin) {
155  const SUMOTime simBegin = string2time(OptionsCont::getOptions().getString("begin"));
156  if (begin == -1) {
157  begin = simBegin;
158  }
159  IntervalsKey key = std::make_pair(interval, begin);
160  Intervals::iterator it = myIntervals.find(key);
161  // Add command for given key only once to MSEventControl...
162  if (it == myIntervals.end()) {
163  DetectorFileVec detAndFileVec;
164  detAndFileVec.push_back(std::make_pair(det, device));
165  myIntervals.insert(std::make_pair(key, detAndFileVec));
166  SUMOTime lastCall = begin;
167  if (begin < simBegin) {
168  SUMOTime divRest = (simBegin - begin) % interval;
169  lastCall = simBegin - divRest;
170  }
171  myLastCalls[key] = lastCall;
172  } else {
173  DetectorFileVec& detAndFileVec = it->second;
174  if (find_if(detAndFileVec.begin(), detAndFileVec.end(), [&](const DetectorFilePair & pair) {
175  return pair.first == det;
176  }) == detAndFileVec.end()) {
177  detAndFileVec.push_back(std::make_pair(det, device));
178  } else {
179  // detector already in container. Don't add several times
180  WRITE_WARNING("MSDetectorControl::addDetectorAndInterval: detector already in container. Ignoring.");
181  return;
182  }
183  }
184  det->writeXMLDetectorProlog(*device);
185 }
186 
187 void
189  for (const auto& i : myDetectors) {
190  for (const auto& j : getTypedDetectors(i.first)) {
191  j.second->clearState(step);
192  }
193  }
194 }
195 
196 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:46
SumoXMLTag
Numbers representing SUMO-XML - element names.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
void writeOutput(SUMOTime step, bool closing)
Writes the output to be generated within the given time step.
std::pair< SUMOTime, SUMOTime > IntervalsKey
Definition of the interval key (interval, begin)
const NamedObjectCont< MSDetectorFileOutput * > & getTypedDetectors(SumoXMLTag type) const
Returns the list of detectors of the given type.
std::map< IntervalsKey, SUMOTime > myLastCalls
The map that holds the last call for each sample interval.
Intervals myIntervals
Map that hold DetectorFileVec for given intervals.
void clearState(SUMOTime step)
Remove all vehicles before quick-loading state.
~MSDetectorControl()
Destructor.
void updateDetectors(const SUMOTime step)
Computes detector values.
void add(SumoXMLTag type, MSDetectorFileOutput *d, const std::string &device, SUMOTime interval, SUMOTime begin=-1)
Adds a detector/output combination into the containers.
std::vector< DetectorFilePair > DetectorFileVec
Container holding DetectorFilePair (with the same interval).
std::map< std::string, std::vector< MSMeanData * > > myMeanData
List of meanData detectors.
void close(SUMOTime step)
Closes the detector outputs.
const std::vector< SumoXMLTag > getAvailableTypes() const
Returns the list of available detector types.
MSDetectorControl()
Constructor.
std::pair< MSDetectorFileOutput *, OutputDevice * > DetectorFilePair
A pair of a Detector with it's associated file-stream.
NamedObjectCont< MSDetectorFileOutput * > myEmptyContainer
An empty container to return in getTypedDetectors() if no detectors of the asked type exist.
std::map< SumoXMLTag, NamedObjectCont< MSDetectorFileOutput * > > myDetectors
The detectors map, first by detector type, then using NamedObjectCont (.
void addDetectorAndInterval(MSDetectorFileOutput *det, OutputDevice *device, SUMOTime interval, SUMOTime begin=-1)
Adds one of the detectors as a new MSDetectorFileOutput.
Base of value-generating classes (detectors)
virtual void writeXMLDetectorProlog(OutputDevice &dev) const =0
Open the XML-output.
virtual void writeXMLOutput(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime)=0
Write the generated output to the given device.
static bool gHaveEmissions
Whether emission output of some type is needed (files or GUI)
Definition: MSGlobals.h:180
Emission data collector for edges/lanes.
Data collector for edges/lanes.
Definition: MSMeanData.h:57
virtual void detectorUpdate(const SUMOTime step)
Updates the detector.
Definition: MSMeanData.cpp:754
void init()
Adds the value collectors to all relevant edges.
Definition: MSMeanData.cpp:443
const std::string & getID() const
Returns the id.
Definition: Named.h:74
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.