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