Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-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 : /****************************************************************************/
14 : /// @file MSDetectorControl.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Clemens Honomichl
18 : /// @author Sascha Krieg
19 : /// @author Michael Behrisch
20 : /// @author Laura Bieker
21 : /// @date 2005-09-15
22 : ///
23 : // Detectors container; responsible for string and output generation
24 : /****************************************************************************/
25 : #include <config.h>
26 :
27 : #include <iostream>
28 : #include <utils/options/OptionsCont.h>
29 : #include <utils/options/Option.h>
30 : #include <utils/common/MsgHandler.h>
31 : #include "MSMeanData_Emissions.h"
32 : #include "MSMeanData_Net.h"
33 : #include "MSDetectorControl.h"
34 :
35 :
36 : // ===========================================================================
37 : // member method definitions
38 : // ===========================================================================
39 42726 : MSDetectorControl::MSDetectorControl() {
40 42726 : }
41 :
42 :
43 42104 : MSDetectorControl::~MSDetectorControl() {
44 54386 : for (auto i = myDetectors.begin(); i != myDetectors.end(); ++i) {
45 12282 : (*i).second.clear();
46 : }
47 64918 : for (auto item : myMeanData) {
48 46067 : for (MSMeanData* md : item.second) {
49 23253 : delete md;
50 : }
51 : }
52 : myMeanData.clear();
53 42104 : }
54 :
55 :
56 : void
57 40593 : MSDetectorControl::close(SUMOTime step) {
58 : // flush the last values
59 40593 : writeOutput(step, true);
60 : // [...] files are closed on another place [...]
61 : myIntervals.clear();
62 40593 : }
63 :
64 :
65 : void
66 36779 : MSDetectorControl::add(SumoXMLTag type, MSDetectorFileOutput* d, const std::string& device, SUMOTime interval, SUMOTime begin) {
67 36779 : if (!myDetectors[type].add(d->getID(), d)) {
68 : const std::string id = d->getID();
69 4 : delete d;
70 12 : throw ProcessError(toString(type) + " detector '" + id + "' could not be built (declared twice?).");
71 : }
72 36775 : addDetectorAndInterval(d, &OutputDevice::getDevice(device), interval, begin);
73 36761 : }
74 :
75 :
76 : void
77 3177 : MSDetectorControl::add(SumoXMLTag type, MSDetectorFileOutput* d) {
78 3177 : if (!myDetectors[type].add(d->getID(), d)) {
79 : const std::string id = d->getID();
80 0 : delete d;
81 0 : throw ProcessError(toString(type) + " detector '" + id + "' could not be built (declared twice?).");
82 : }
83 3177 : }
84 :
85 :
86 : void
87 23308 : MSDetectorControl::add(MSMeanData* md, const std::string& device,
88 : SUMOTime frequency, SUMOTime begin) {
89 23308 : myMeanData[md->getID()].push_back(md);
90 23308 : addDetectorAndInterval(md, &OutputDevice::getDevice(device), frequency, begin);
91 46616 : if (begin <= string2time(OptionsCont::getOptions().getString("begin"))) {
92 22665 : md->init();
93 : }
94 23308 : MSGlobals::gHaveEmissions |= typeid(*md) == typeid(MSMeanData_Emissions);
95 23308 : }
96 :
97 :
98 : const std::vector<SumoXMLTag>
99 8607 : MSDetectorControl::getAvailableTypes() const {
100 : std::vector<SumoXMLTag> result;
101 9377 : for (std::map<SumoXMLTag, NamedObjectCont<MSDetectorFileOutput*> >::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
102 770 : result.push_back(i->first);
103 : }
104 8607 : return result;
105 0 : }
106 :
107 :
108 : const NamedObjectCont<MSDetectorFileOutput*>&
109 11752702 : MSDetectorControl::getTypedDetectors(SumoXMLTag type) const {
110 11752702 : if (myDetectors.find(type) == myDetectors.end()) {
111 116 : return myEmptyContainer;
112 : }
113 11752586 : return myDetectors.find(type)->second;
114 : }
115 :
116 :
117 : void
118 63185998 : MSDetectorControl::updateDetectors(const SUMOTime step) {
119 74717362 : for (const auto& i : myDetectors) {
120 60043130 : for (const auto& j : getTypedDetectors(i.first)) {
121 48511766 : j.second->detectorUpdate(step);
122 : }
123 : }
124 88742633 : for (auto item : myMeanData) {
125 52019607 : for (MSMeanData* md : item.second) {
126 26462963 : md->detectorUpdate(step);
127 : }
128 : }
129 63185989 : }
130 :
131 :
132 : void
133 63226576 : MSDetectorControl::writeOutput(SUMOTime step, bool closing) {
134 87434275 : for (Intervals::iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
135 24207700 : IntervalsKey interval = (*i).first;
136 24207700 : if (myLastCalls[interval] + interval.first <= step || (closing && myLastCalls[interval] < step)) {
137 393449 : DetectorFileVec dfVec = (*i).second;
138 393449 : SUMOTime startTime = myLastCalls[interval];
139 : // check whether at the end the output was already generated
140 1505797 : for (DetectorFileVec::iterator it = dfVec.begin(); it != dfVec.end(); ++it) {
141 1112349 : MSDetectorFileOutput* det = it->first;
142 1112349 : det->writeXMLOutput(*(it->second), startTime, step);
143 : }
144 393448 : myLastCalls[interval] = step;
145 393449 : }
146 : }
147 63226575 : }
148 :
149 :
150 : void
151 60069 : MSDetectorControl::addDetectorAndInterval(MSDetectorFileOutput* det,
152 : OutputDevice* device,
153 : SUMOTime interval,
154 : SUMOTime begin) {
155 60069 : const SUMOTime simBegin = string2time(OptionsCont::getOptions().getString("begin"));
156 60069 : if (begin == -1) {
157 : begin = simBegin;
158 : }
159 60069 : 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 60069 : if (it == myIntervals.end()) {
163 : DetectorFileVec detAndFileVec;
164 23959 : detAndFileVec.push_back(std::make_pair(det, device));
165 47918 : myIntervals.insert(std::make_pair(key, detAndFileVec));
166 : SUMOTime lastCall = begin;
167 23959 : if (begin < simBegin) {
168 18 : SUMOTime divRest = (simBegin - begin) % interval;
169 18 : lastCall = simBegin - divRest;
170 : }
171 23959 : myLastCalls[key] = lastCall;
172 23959 : } else {
173 36110 : DetectorFileVec& detAndFileVec = it->second;
174 36110 : if (find_if(detAndFileVec.begin(), detAndFileVec.end(), [&](const DetectorFilePair & pair) {
175 103512 : return pair.first == det;
176 : }) == detAndFileVec.end()) {
177 36110 : detAndFileVec.push_back(std::make_pair(det, device));
178 : } else {
179 : // detector already in container. Don't add several times
180 0 : WRITE_WARNING("MSDetectorControl::addDetectorAndInterval: detector already in container. Ignoring.");
181 0 : return;
182 : }
183 : }
184 60069 : det->writeXMLDetectorProlog(*device);
185 : }
186 :
187 : const std::map<std::string, MSMoveReminder*>&
188 179 : MSDetectorControl::getAllReminders() {
189 179 : if (myReminders.empty()) {
190 30 : for (auto item : myMeanData) {
191 2 : for (MSMeanData* md : item.second) {
192 45 : for (MSMoveReminder* rem : md->getReminders()) {
193 44 : myReminders[rem->getDescription()] = rem;
194 1 : }
195 : }
196 : }
197 29 : if (myReminders.empty()) {
198 : // ensure non-empty map
199 28 : myReminders[""] = nullptr;
200 : }
201 : }
202 179 : return myReminders;
203 : }
204 :
205 : void
206 167 : MSDetectorControl::clearState(SUMOTime step) {
207 218 : for (const auto& i : myDetectors) {
208 102 : for (const auto& j : getTypedDetectors(i.first)) {
209 51 : j.second->clearState(step);
210 : }
211 : }
212 : myReminders.clear();
213 167 : }
214 :
215 : /****************************************************************************/
|