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    MSMeanData_Amitran.cpp
11 /// @author  Daniel Krajzewicz
12 /// @author  Michael Behrisch
13 /// @date    Mon, 10.05.2004
14 /// @version $Id$
15 ///
16 // Network state mean data collector for edges/lanes
17 /****************************************************************************/
18 
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24 
25 #include <microsim/MSEdgeControl.h>
26 #include <microsim/MSEdge.h>
27 #include <microsim/MSLane.h>
28 #include <microsim/MSVehicle.h>
29 #include <utils/common/SUMOTime.h>
30 #include <utils/common/ToString.h>
31 #include <utils/iodevices/OutputDevice.h>
32 #include "MSMeanData_Amitran.h"
33 #include <limits>
34 
35 
36 // ===========================================================================
37 // method definitions
38 // ===========================================================================
39 // ---------------------------------------------------------------------------
40 // MSMeanData_Amitran::MSLaneMeanDataValues - methods
41 // ---------------------------------------------------------------------------
MSLaneMeanDataValues(MSLane * const lane,const double length,const bool doAdd,const MSMeanData_Amitran * parent)42 MSMeanData_Amitran::MSLaneMeanDataValues::MSLaneMeanDataValues(MSLane* const lane,
43         const double length,
44         const bool doAdd,
45         const MSMeanData_Amitran* parent)
46     : MSMeanData::MeanDataValues(lane, length, doAdd, parent), amount(0) {}
47 
48 
~MSLaneMeanDataValues()49 MSMeanData_Amitran::MSLaneMeanDataValues::~MSLaneMeanDataValues() {
50 }
51 
52 
53 void
reset(bool)54 MSMeanData_Amitran::MSLaneMeanDataValues::reset(bool) {
55     amount = 0;
56     typedAmount.clear();
57     typedSamples.clear();
58     typedTravelDistance.clear();
59 }
60 
61 
62 void
addTo(MSMeanData::MeanDataValues & val) const63 MSMeanData_Amitran::MSLaneMeanDataValues::addTo(MSMeanData::MeanDataValues& val) const {
64     MSLaneMeanDataValues& v = (MSLaneMeanDataValues&) val;
65     v.amount += amount;
66     v.sampleSeconds += sampleSeconds;
67     v.travelledDistance += travelledDistance;
68     for (std::map<const MSVehicleType*, int>::const_iterator it = typedAmount.begin(); it != typedAmount.end(); ++it) {
69         v.typedAmount[it->first] += it->second;
70     }
71     for (std::map<const MSVehicleType*, double>::const_iterator it = typedSamples.begin(); it != typedSamples.end(); ++it) {
72         v.typedSamples[it->first] += it->second;
73     }
74     for (std::map<const MSVehicleType*, double>::const_iterator it = typedTravelDistance.begin(); it != typedTravelDistance.end(); ++it) {
75         v.typedTravelDistance[it->first] += it->second;
76     }
77 }
78 
79 
80 void
notifyMoveInternal(const SUMOTrafficObject & veh,const double,const double timeOnLane,const double,const double,const double,const double travelledDistanceVehicleOnLane,const double)81 MSMeanData_Amitran::MSLaneMeanDataValues::notifyMoveInternal(const SUMOTrafficObject& veh, const double /* frontOnLane */, const double timeOnLane, const double /*meanSpeedFrontOnLane*/, const double /*meanSpeedVehicleOnLane*/, const double /*travelledDistanceFrontOnLane*/, const double travelledDistanceVehicleOnLane, const double /* meanLengthOnLane */) {
82     sampleSeconds += timeOnLane;
83     travelledDistance += travelledDistanceVehicleOnLane;
84     typedSamples[&veh.getVehicleType()] += timeOnLane;
85     typedTravelDistance[&veh.getVehicleType()] += travelledDistanceVehicleOnLane;
86 }
87 
88 
89 bool
notifyEnter(SUMOTrafficObject & veh,MSMoveReminder::Notification reason,const MSLane *)90 MSMeanData_Amitran::MSLaneMeanDataValues::notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
91     if (myParent->vehicleApplies(veh)) {
92         if (getLane() == nullptr || getLane() == static_cast<MSVehicle&>(veh).getLane()) {
93             if (reason == MSMoveReminder::NOTIFICATION_DEPARTED || reason == MSMoveReminder::NOTIFICATION_JUNCTION) {
94                 ++amount;
95                 typedAmount[&veh.getVehicleType()]++;
96             }
97         }
98         return true;
99     }
100     return false;
101 }
102 
103 
104 bool
isEmpty() const105 MSMeanData_Amitran::MSLaneMeanDataValues::isEmpty() const {
106     return sampleSeconds == 0 && amount == 0;
107 }
108 
109 
110 void
write(OutputDevice & dev,const SUMOTime,const double,const double defaultTravelTime,const int) const111 MSMeanData_Amitran::MSLaneMeanDataValues::write(OutputDevice& dev, const SUMOTime /* period */,
112         const double /* numLanes */, const double defaultTravelTime, const int /* numVehicles */) const {
113     if (sampleSeconds > 0) {
114         dev.writeAttr("amount", amount).writeAttr("averageSpeed", int(100 * travelledDistance / sampleSeconds));
115     } else if (defaultTravelTime >= 0.) {
116         dev.writeAttr("amount", amount).writeAttr("averageSpeed", int(100 * myLaneLength / defaultTravelTime));
117     } else {
118         dev.writeAttr("amount", amount).writeAttr("averageSpeed", "-1");
119     }
120     if (myParent->isTyped()) {
121         for (std::map<const MSVehicleType*, int>::const_iterator it = typedAmount.begin(); it != typedAmount.end(); ++it) {
122             dev.openTag("actorConfig").writeAttr(SUMO_ATTR_ID, it->first->getNumericalID());
123             dev.writeAttr("amount", it->second).writeAttr("averageSpeed", int(100 * typedTravelDistance.find(it->first)->second / typedSamples.find(it->first)->second));
124             dev.closeTag();
125         }
126     }
127     dev.closeTag();
128 }
129 
130 // ---------------------------------------------------------------------------
131 // MSMeanData_Amitran - methods
132 // ---------------------------------------------------------------------------
MSMeanData_Amitran(const std::string & id,const SUMOTime dumpBegin,const SUMOTime dumpEnd,const bool useLanes,const bool withEmpty,const bool printDefaults,const bool withInternal,const bool trackVehicles,const int detectPersons,const double maxTravelTime,const double minSamples,const double haltSpeed,const std::string & vTypes)133 MSMeanData_Amitran::MSMeanData_Amitran(const std::string& id,
134                                        const SUMOTime dumpBegin,
135                                        const SUMOTime dumpEnd, const bool useLanes,
136                                        const bool withEmpty, const bool printDefaults,
137                                        const bool withInternal,
138                                        const bool trackVehicles,
139                                        const int detectPersons,
140                                        const double maxTravelTime,
141                                        const double minSamples,
142                                        const double haltSpeed,
143                                        const std::string& vTypes)
144     : MSMeanData(id, dumpBegin, dumpEnd, useLanes, withEmpty, printDefaults,
145                  withInternal, trackVehicles, detectPersons, maxTravelTime, minSamples, vTypes),
146       myHaltSpeed(haltSpeed) {
147 }
148 
149 
~MSMeanData_Amitran()150 MSMeanData_Amitran::~MSMeanData_Amitran() {}
151 
152 
153 void
writeXMLDetectorProlog(OutputDevice & dev) const154 MSMeanData_Amitran::writeXMLDetectorProlog(OutputDevice& dev) const {
155     dev.writeXMLHeader("linkData", "amitran/linkdata.xsd");
156 }
157 
158 
159 std::string
getEdgeID(const MSEdge * const edge)160 MSMeanData_Amitran::getEdgeID(const MSEdge* const edge) {
161     return toString(edge->getNumericalID());
162 }
163 
164 
165 void
openInterval(OutputDevice & dev,const SUMOTime startTime,const SUMOTime stopTime)166 MSMeanData_Amitran::openInterval(OutputDevice& dev, const SUMOTime startTime, const SUMOTime stopTime) {
167     const int duration = int(1000 * STEPS2TIME(stopTime - startTime) + 0.5);
168     dev.openTag(SUMO_TAG_TIMESLICE).writeAttr(SUMO_ATTR_STARTTIME, int(1000 * STEPS2TIME(startTime) + 0.5)).writeAttr(SUMO_ATTR_DURATION, duration);
169 }
170 
171 
172 bool
writePrefix(OutputDevice & dev,const MeanDataValues & values,const SumoXMLTag,const std::string id) const173 MSMeanData_Amitran::writePrefix(OutputDevice& dev, const MeanDataValues& values, const SumoXMLTag /* tag */, const std::string id) const {
174     if (myDumpEmpty || !values.isEmpty()) {
175         dev.openTag("link").writeAttr(SUMO_ATTR_ID, id);
176         return true;
177     }
178     return false;
179 }
180 
181 
182 MSMeanData::MeanDataValues*
createValues(MSLane * const lane,const double length,const bool doAdd) const183 MSMeanData_Amitran::createValues(MSLane* const lane, const double length, const bool doAdd) const {
184     return new MSLaneMeanDataValues(lane, length, doAdd, this);
185 }
186 
187 
188 /****************************************************************************/
189 
190