Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2008-2026 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 : // ===========================================================================
39 : // method definitions
40 : // ===========================================================================
41 474 : MSRouteProbe::MSRouteProbe(const std::string& id, const MSEdge* edge, const std::string& distID, const std::string& lastID,
42 474 : const std::string& vTypes) :
43 : MSDetectorFileOutput(id, vTypes), MSMoveReminder(id),
44 474 : myDistID(distID),
45 474 : myLastID(lastID),
46 474 : myLastRouteDistribution(nullptr),
47 474 : myCurrentRouteDistribution(nullptr),
48 948 : myEdge(edge) {
49 474 : if (MSGlobals::gUseMesoSim) {
50 20 : MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(*edge);
51 88 : while (seg != nullptr) {
52 68 : seg->addDetector(this);
53 : seg = seg->getNextSegment();
54 : }
55 : return;
56 : }
57 1312 : for (std::vector<MSLane*>::const_iterator it = edge->getLanes().begin(); it != edge->getLanes().end(); ++it) {
58 858 : (*it)->addMoveReminder(this);
59 : }
60 0 : }
61 :
62 :
63 948 : MSRouteProbe::~MSRouteProbe() {
64 948 : }
65 :
66 :
67 : void
68 0 : MSRouteProbe::clearState(SUMOTime step) {
69 : UNUSED_PARAMETER(step);
70 0 : myCurrentRouteDistribution = nullptr;
71 0 : myLastRouteDistribution = nullptr;
72 0 : }
73 :
74 :
75 : void
76 5881 : MSRouteProbe::initDistributions() {
77 5881 : if (myCurrentRouteDistribution == nullptr) {
78 128 : myCurrentRouteDistribution = MSRoute::distDictionary(myDistID);
79 128 : if (myCurrentRouteDistribution == 0) {
80 128 : myCurrentRouteDistribution = new RandomDistributor<ConstMSRoutePtr>();
81 128 : MSRoute::dictionary(myDistID, myCurrentRouteDistribution, false);
82 : }
83 128 : myLastRouteDistribution = MSRoute::distDictionary(myLastID);
84 : }
85 5881 : }
86 :
87 :
88 : bool
89 6034 : MSRouteProbe::notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
90 6034 : if (!vehicleApplies(veh)) {
91 : return false;
92 : }
93 6003 : if (reason != MSMoveReminder::NOTIFICATION_SEGMENT && reason != MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
94 5881 : SUMOVehicle* vehicle = dynamic_cast<SUMOVehicle*>(&veh);
95 5881 : if (vehicle != nullptr) {
96 5881 : initDistributions();
97 11762 : myCurrentRouteDistribution->add(vehicle->getRoutePtr(), 1.);
98 : }
99 : }
100 : return false;
101 : }
102 :
103 :
104 : void
105 5467 : MSRouteProbe::writeXMLOutput(OutputDevice& dev,
106 : SUMOTime startTime, SUMOTime stopTime) {
107 5467 : if (myCurrentRouteDistribution && myCurrentRouteDistribution->getOverallProb() > 0) {
108 968 : dev.openTag(SUMO_TAG_ROUTE_DISTRIBUTION).writeAttr(SUMO_ATTR_ID, getID() + "_" + time2string(startTime, false));
109 484 : const std::vector<ConstMSRoutePtr>& routes = myCurrentRouteDistribution->getVals();
110 : const std::vector<double>& probs = myCurrentRouteDistribution->getProbs();
111 1075 : for (int j = 0; j < (int)routes.size(); ++j) {
112 1182 : dev.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_ID, routes[j]->getID() + "_" + time2string(startTime, false))
113 1182 : .writeAttr(SUMO_ATTR_EDGES, toString(routes[j]->getEdges())).writeAttr(SUMO_ATTR_PROB, probs[j]).closeTag();
114 : }
115 484 : dev.closeTag();
116 484 : if (myLastRouteDistribution != 0) {
117 356 : MSRoute::checkDist(myLastID);
118 : }
119 484 : myLastRouteDistribution = myCurrentRouteDistribution;
120 484 : myLastID = myDistID;
121 968 : myDistID = getID() + "_" + toString(stopTime);
122 484 : myCurrentRouteDistribution = new RandomDistributor<ConstMSRoutePtr>();
123 484 : MSRoute::dictionary(myDistID, myCurrentRouteDistribution, false);
124 : }
125 5467 : }
126 :
127 :
128 : void
129 474 : MSRouteProbe::writeXMLDetectorProlog(OutputDevice& dev) const {
130 948 : dev.writeXMLHeader("routes", "routes_file.xsd");
131 474 : }
132 :
133 :
134 : ConstMSRoutePtr
135 2730 : MSRouteProbe::sampleRoute(bool last) const {
136 2730 : if (myLastRouteDistribution == 0 || !last) {
137 1508 : if (myCurrentRouteDistribution && myCurrentRouteDistribution->getOverallProb() > 0) {
138 906 : return myCurrentRouteDistribution->get();
139 : }
140 : return nullptr;
141 : }
142 1222 : return myLastRouteDistribution->get();
143 : }
|