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.cpp
11 /// @author Daniel Krajzewicz
12 /// @author Jakob Erdmann
13 /// @author Clemens Honomichl
14 /// @author Sascha Krieg
15 /// @author Michael Behrisch
16 /// @author Laura Bieker
17 /// @date 2005-09-15
18 /// @version $Id$
19 ///
20 // Detectors container; responsible for string and output generation
21 /****************************************************************************/
22
23
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #include <config.h>
28
29 #include <iostream>
30 #include "MSDetectorControl.h"
31 #include "MSMeanData_Net.h"
32 #include <utils/options/OptionsCont.h>
33 #include <utils/options/Option.h>
34 #include <utils/common/MsgHandler.h>
35
36
37 // ===========================================================================
38 // member method definitions
39 // ===========================================================================
MSDetectorControl()40 MSDetectorControl::MSDetectorControl() {
41 }
42
43
~MSDetectorControl()44 MSDetectorControl::~MSDetectorControl() {
45 for (std::map<SumoXMLTag, NamedObjectCont<MSDetectorFileOutput*> >::iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
46 (*i).second.clear();
47 }
48 for (std::vector<MSMeanData*>::const_iterator i = myMeanData.begin(); i != myMeanData.end(); ++i) {
49 delete *i;
50 }
51 }
52
53
54 void
close(SUMOTime step)55 MSDetectorControl::close(SUMOTime step) {
56 // flush the last values
57 writeOutput(step, true);
58 // [...] files are closed on another place [...]
59 myIntervals.clear();
60 }
61
62
63 void
add(SumoXMLTag type,MSDetectorFileOutput * d,const std::string & device,SUMOTime splInterval,SUMOTime begin)64 MSDetectorControl::add(SumoXMLTag type, MSDetectorFileOutput* d, const std::string& device, SUMOTime splInterval, SUMOTime begin) {
65 if (!myDetectors[type].add(d->getID(), d)) {
66 throw ProcessError(toString(type) + " detector '" + d->getID() + "' could not be build (declared twice?).");
67 }
68 addDetectorAndInterval(d, &OutputDevice::getDevice(device), splInterval, begin);
69 }
70
71
72
73 void
add(SumoXMLTag type,MSDetectorFileOutput * d)74 MSDetectorControl::add(SumoXMLTag type, MSDetectorFileOutput* d) {
75 if (!myDetectors[type].add(d->getID(), d)) {
76 throw ProcessError(toString(type) + " detector '" + d->getID() + "' could not be build (declared twice?).");
77 }
78 }
79
80
81
82 void
add(MSMeanData * mn,const std::string & device,SUMOTime frequency,SUMOTime begin)83 MSDetectorControl::add(MSMeanData* mn, const std::string& device,
84 SUMOTime frequency, SUMOTime begin) {
85 myMeanData.push_back(mn);
86 addDetectorAndInterval(mn, &OutputDevice::getDevice(device), frequency, begin);
87 if (begin == string2time(OptionsCont::getOptions().getString("begin"))) {
88 mn->init();
89 }
90 }
91
92
93 const std::vector<SumoXMLTag>
getAvailableTypes() const94 MSDetectorControl::getAvailableTypes() const {
95 std::vector<SumoXMLTag> result;
96 for (std::map<SumoXMLTag, NamedObjectCont<MSDetectorFileOutput*> >::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
97 result.push_back(i->first);
98 }
99 return result;
100 }
101
102
103 const NamedObjectCont<MSDetectorFileOutput*>&
getTypedDetectors(SumoXMLTag type) const104 MSDetectorControl::getTypedDetectors(SumoXMLTag type) const {
105 if (myDetectors.find(type) == myDetectors.end()) {
106 return myEmptyContainer;
107 }
108 return myDetectors.find(type)->second;
109 }
110
111
112 void
updateDetectors(const SUMOTime step)113 MSDetectorControl::updateDetectors(const SUMOTime step) {
114 for (const auto& i : myDetectors) {
115 for (const auto& j : getTypedDetectors(i.first)) {
116 j.second->detectorUpdate(step);
117 }
118 }
119 for (MSMeanData* const i : myMeanData) {
120 i->detectorUpdate(step);
121 }
122 }
123
124
125 void
writeOutput(SUMOTime step,bool closing)126 MSDetectorControl::writeOutput(SUMOTime step, bool closing) {
127 for (Intervals::iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
128 IntervalsKey interval = (*i).first;
129 if (myLastCalls[interval] + interval.first <= step || (closing && myLastCalls[interval] < step)) {
130 DetectorFileVec dfVec = (*i).second;
131 SUMOTime startTime = myLastCalls[interval];
132 // check whether at the end the output was already generated
133 for (DetectorFileVec::iterator it = dfVec.begin(); it != dfVec.end(); ++it) {
134 MSDetectorFileOutput* det = it->first;
135 det->writeXMLOutput(*(it->second), startTime, step);
136 }
137 myLastCalls[interval] = step;
138 }
139 }
140 }
141
142
143 void
addDetectorAndInterval(MSDetectorFileOutput * det,OutputDevice * device,SUMOTime interval,SUMOTime begin)144 MSDetectorControl::addDetectorAndInterval(MSDetectorFileOutput* det,
145 OutputDevice* device,
146 SUMOTime interval,
147 SUMOTime begin) {
148 if (begin == -1) {
149 begin = string2time(OptionsCont::getOptions().getString("begin"));
150 }
151 IntervalsKey key = std::make_pair(interval, begin);
152 Intervals::iterator it = myIntervals.find(key);
153 // Add command for given key only once to MSEventControl...
154 if (it == myIntervals.end()) {
155 DetectorFileVec detAndFileVec;
156 detAndFileVec.push_back(std::make_pair(det, device));
157 myIntervals.insert(std::make_pair(key, detAndFileVec));
158 myLastCalls[key] = begin;
159 } else {
160 DetectorFileVec& detAndFileVec = it->second;
161 if (find_if(detAndFileVec.begin(), detAndFileVec.end(), bind2nd(detectorEquals(), det)) == detAndFileVec.end()) {
162 detAndFileVec.push_back(std::make_pair(det, device));
163 } else {
164 // detector already in container. Don't add several times
165 WRITE_WARNING("MSDetectorControl::addDetectorAndInterval: detector already in container. Ignoring.");
166 return;
167 }
168 }
169 det->writeXMLDetectorProlog(*device);
170 }
171
172
173
174 /****************************************************************************/
175
176