Line data Source code
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 : /****************************************************************************/ 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 35457 : MSDetectorControl::MSDetectorControl() { 40 35457 : } 41 : 42 : 43 34942 : MSDetectorControl::~MSDetectorControl() { 44 39124 : for (auto i = myDetectors.begin(); i != myDetectors.end(); ++i) { 45 4182 : (*i).second.clear(); 46 : } 47 39695 : for (auto item : myMeanData) { 48 10179 : for (MSMeanData* md : item.second) { 49 5426 : delete md; 50 : } 51 4753 : } 52 : myMeanData.clear(); 53 34942 : } 54 : 55 : 56 : void 57 33184 : MSDetectorControl::close(SUMOTime step) { 58 : // flush the last values 59 33184 : writeOutput(step, true); 60 : // [...] files are closed on another place [...] 61 : myIntervals.clear(); 62 33184 : } 63 : 64 : 65 : void 66 14051 : MSDetectorControl::add(SumoXMLTag type, MSDetectorFileOutput* d, const std::string& device, SUMOTime interval, SUMOTime begin) { 67 14051 : if (!myDetectors[type].add(d->getID(), d)) { 68 : const std::string id = d->getID(); 69 4 : delete d; 70 8 : throw ProcessError(toString(type) + " detector '" + id + "' could not be built (declared twice?)."); 71 : } 72 14047 : addDetectorAndInterval(d, &OutputDevice::getDevice(device), interval, begin); 73 14033 : } 74 : 75 : 76 : void 77 4684 : MSDetectorControl::add(SumoXMLTag type, MSDetectorFileOutput* d) { 78 4684 : 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 4684 : } 84 : 85 : 86 : void 87 5427 : MSDetectorControl::add(MSMeanData* md, const std::string& device, 88 : SUMOTime frequency, SUMOTime begin) { 89 5427 : myMeanData[md->getID()].push_back(md); 90 5427 : addDetectorAndInterval(md, &OutputDevice::getDevice(device), frequency, begin); 91 10854 : if (begin <= string2time(OptionsCont::getOptions().getString("begin"))) { 92 4808 : md->init(); 93 : } 94 5427 : MSGlobals::gHaveEmissions |= typeid(*md) == typeid(MSMeanData_Emissions); 95 5427 : } 96 : 97 : 98 : const std::vector<SumoXMLTag> 99 6985 : MSDetectorControl::getAvailableTypes() const { 100 : std::vector<SumoXMLTag> result; 101 7468 : for (std::map<SumoXMLTag, NamedObjectCont<MSDetectorFileOutput*> >::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) { 102 483 : result.push_back(i->first); 103 : } 104 6985 : return result; 105 : } 106 : 107 : 108 : const NamedObjectCont<MSDetectorFileOutput*>& 109 5598974 : MSDetectorControl::getTypedDetectors(SumoXMLTag type) const { 110 5598974 : if (myDetectors.find(type) == myDetectors.end()) { 111 89 : return myEmptyContainer; 112 : } 113 5598885 : return myDetectors.find(type)->second; 114 : } 115 : 116 : 117 : void 118 79566219 : MSDetectorControl::updateDetectors(const SUMOTime step) { 119 85014969 : for (const auto& i : myDetectors) { 120 28913264 : for (const auto& j : getTypedDetectors(i.first)) { 121 23464514 : j.second->detectorUpdate(step); 122 : } 123 : } 124 86797316 : for (auto item : myMeanData) { 125 15853341 : for (MSMeanData* md : item.second) { 126 8622244 : md->detectorUpdate(step); 127 : } 128 7231097 : } 129 79566219 : } 130 : 131 : 132 : void 133 79599397 : MSDetectorControl::writeOutput(SUMOTime step, bool closing) { 134 89108451 : for (Intervals::iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) { 135 9509056 : IntervalsKey interval = (*i).first; 136 9509056 : if (myLastCalls[interval] + interval.first <= step || (closing && myLastCalls[interval] < step)) { 137 555194 : DetectorFileVec dfVec = (*i).second; 138 555194 : SUMOTime startTime = myLastCalls[interval]; 139 : // check whether at the end the output was already generated 140 2380565 : for (DetectorFileVec::iterator it = dfVec.begin(); it != dfVec.end(); ++it) { 141 1825373 : MSDetectorFileOutput* det = it->first; 142 1825373 : det->writeXMLOutput(*(it->second), startTime, step); 143 : } 144 555192 : myLastCalls[interval] = step; 145 : } 146 : } 147 79599395 : } 148 : 149 : 150 : void 151 19460 : MSDetectorControl::addDetectorAndInterval(MSDetectorFileOutput* det, 152 : OutputDevice* device, 153 : SUMOTime interval, 154 : SUMOTime begin) { 155 38920 : const SUMOTime simBegin = string2time(OptionsCont::getOptions().getString("begin")); 156 19460 : if (begin == -1) { 157 : begin = simBegin; 158 : } 159 19460 : 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 19460 : if (it == myIntervals.end()) { 163 : DetectorFileVec detAndFileVec; 164 6682 : detAndFileVec.push_back(std::make_pair(det, device)); 165 0 : myIntervals.insert(std::make_pair(key, detAndFileVec)); 166 : SUMOTime lastCall = begin; 167 6682 : if (begin < simBegin) { 168 18 : SUMOTime divRest = (simBegin - begin) % interval; 169 18 : lastCall = simBegin - divRest; 170 : } 171 6682 : myLastCalls[key] = lastCall; 172 : } else { 173 12778 : DetectorFileVec& detAndFileVec = it->second; 174 12778 : if (find_if(detAndFileVec.begin(), detAndFileVec.end(), [&](const DetectorFilePair & pair) { 175 101053 : return pair.first == det; 176 : }) == detAndFileVec.end()) { 177 12778 : 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 19460 : det->writeXMLDetectorProlog(*device); 185 : } 186 : 187 : void 188 222 : MSDetectorControl::clearState(SUMOTime step) { 189 294 : for (const auto& i : myDetectors) { 190 144 : for (const auto& j : getTypedDetectors(i.first)) { 191 72 : j.second->clearState(step); 192 : } 193 : } 194 222 : } 195 : 196 : /****************************************************************************/