Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2008-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 MSRouteProbe.cpp
15 : /// @author Michael Behrisch
16 : /// @author Daniel Krajzewicz
17 : /// @author Tino Morenz
18 : /// @author Jakob Erdmann
19 : /// @date Thu, 04.12.2008
20 : ///
21 : // Writes route distributions at a certain edge
22 : /****************************************************************************/
23 : #include <config.h>
24 :
25 : #include <string>
26 : #include <microsim/MSEdge.h>
27 : #include <microsim/MSLane.h>
28 : #include <microsim/MSGlobals.h>
29 : #include <microsim/MSRoute.h>
30 : #include <microsim/MSVehicle.h>
31 : #include <utils/common/ToString.h>
32 : #include <utils/iodevices/OutputDevice.h>
33 : #include <mesosim/MELoop.h>
34 : #include <mesosim/MESegment.h>
35 : #include "MSRouteProbe.h"
36 :
37 : // ===========================================================================
38 : // static members
39 : // ===========================================================================
40 :
41 : // ===========================================================================
42 : // method definitions
43 : // ===========================================================================
44 518 : MSRouteProbe::MSRouteProbe(const std::string& id, const MSEdge* edge, const std::string& distID, const std::string& lastID,
45 518 : const std::string& vTypes) :
46 : MSDetectorFileOutput(id, vTypes), MSMoveReminder(id),
47 518 : myDistID(distID),
48 518 : myLastID(lastID),
49 518 : myLastRouteDistribution(nullptr),
50 518 : myCurrentRouteDistribution(nullptr),
51 1036 : myEdge(edge) {
52 518 : if (MSGlobals::gUseMesoSim) {
53 18 : MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(*edge);
54 80 : while (seg != nullptr) {
55 62 : seg->addDetector(this);
56 : seg = seg->getNextSegment();
57 : }
58 : return;
59 : }
60 1462 : for (std::vector<MSLane*>::const_iterator it = edge->getLanes().begin(); it != edge->getLanes().end(); ++it) {
61 962 : (*it)->addMoveReminder(this);
62 : }
63 0 : }
64 :
65 :
66 1036 : MSRouteProbe::~MSRouteProbe() {
67 1036 : }
68 :
69 : void
70 0 : MSRouteProbe::clearState(SUMOTime step) {
71 : UNUSED_PARAMETER(step);
72 0 : myCurrentRouteDistribution = nullptr;
73 0 : myLastRouteDistribution = nullptr;
74 0 : }
75 :
76 : void
77 5151 : MSRouteProbe::initDistributions() {
78 5151 : if (myCurrentRouteDistribution == nullptr) {
79 122 : myCurrentRouteDistribution = MSRoute::distDictionary(myDistID);
80 122 : if (myCurrentRouteDistribution == 0) {
81 122 : myCurrentRouteDistribution = new RandomDistributor<ConstMSRoutePtr>();
82 122 : MSRoute::dictionary(myDistID, myCurrentRouteDistribution, false);
83 : }
84 122 : myLastRouteDistribution = MSRoute::distDictionary(myLastID);
85 : }
86 5151 : }
87 :
88 : bool
89 5261 : MSRouteProbe::notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
90 5261 : if (!vehicleApplies(veh)) {
91 : return false;
92 : }
93 5233 : if (reason != MSMoveReminder::NOTIFICATION_SEGMENT && reason != MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
94 5151 : SUMOVehicle* vehicle = dynamic_cast<SUMOVehicle*>(&veh);
95 5151 : if (vehicle != nullptr) {
96 5151 : initDistributions();
97 10302 : myCurrentRouteDistribution->add(vehicle->getRoutePtr(), 1.);
98 : }
99 : }
100 : return false;
101 : }
102 :
103 :
104 : void
105 5197 : MSRouteProbe::writeXMLOutput(OutputDevice& dev,
106 : SUMOTime startTime, SUMOTime stopTime) {
107 5197 : if (myCurrentRouteDistribution && myCurrentRouteDistribution->getOverallProb() > 0) {
108 906 : dev.openTag("routeDistribution") << " id=\"" << getID() + "_" + time2string(startTime) << "\"";
109 453 : const std::vector<ConstMSRoutePtr>& routes = myCurrentRouteDistribution->getVals();
110 : const std::vector<double>& probs = myCurrentRouteDistribution->getProbs();
111 971 : for (int j = 0; j < (int)routes.size(); ++j) {
112 518 : ConstMSRoutePtr r = routes[j];
113 1036 : dev.openTag("route") << " id=\"" << r->getID() + "_" + time2string(startTime) << "\" edges=\"";
114 3670 : for (MSRouteIterator i = r->begin(); i != r->end(); ++i) {
115 3152 : if (i != r->begin()) {
116 2634 : dev << " ";
117 : }
118 3152 : dev << (*i)->getID();
119 : }
120 518 : dev << "\" probability=\"" << probs[j] << "\"";
121 1036 : dev.closeTag();
122 : }
123 453 : dev.closeTag();
124 453 : if (myLastRouteDistribution != 0) {
125 331 : MSRoute::checkDist(myLastID);
126 : }
127 453 : myLastRouteDistribution = myCurrentRouteDistribution;
128 453 : myLastID = myDistID;
129 906 : myDistID = getID() + "_" + toString(stopTime);
130 453 : myCurrentRouteDistribution = new RandomDistributor<ConstMSRoutePtr>();
131 453 : MSRoute::dictionary(myDistID, myCurrentRouteDistribution, false);
132 : }
133 5197 : }
134 :
135 :
136 : void
137 518 : MSRouteProbe::writeXMLDetectorProlog(OutputDevice& dev) const {
138 1036 : dev.writeXMLHeader("routes", "routes_file.xsd");
139 518 : }
140 :
141 :
142 : ConstMSRoutePtr
143 2730 : MSRouteProbe::sampleRoute(bool last) const {
144 2730 : if (myLastRouteDistribution == 0 || !last) {
145 1500 : if (myCurrentRouteDistribution && myCurrentRouteDistribution->getOverallProb() > 0) {
146 865 : return myCurrentRouteDistribution->get();
147 : }
148 : return nullptr;
149 : }
150 1230 : return myLastRouteDistribution->get();
151 : }
|