Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2007-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 MSTransportableDevice_Routing.cpp
15 : /// @author Michael Behrisch
16 : /// @author Daniel Krajzewicz
17 : /// @author Laura Bieker
18 : /// @author Christoph Sommer
19 : /// @author Jakob Erdmann
20 : /// @date Tue, 04 Dec 2007
21 : ///
22 : // A device that performs vehicle rerouting based on current edge speeds
23 : /****************************************************************************/
24 : #include <config.h>
25 :
26 : #include <microsim/MSNet.h>
27 : #include <microsim/MSEventControl.h>
28 : #include <microsim/transportables/MSTransportable.h>
29 : #include <utils/options/OptionsCont.h>
30 : #include <utils/xml/SUMOSAXAttributes.h>
31 : #include <microsim/MSEdge.h>
32 :
33 : #include "MSRoutingEngine.h"
34 : #include "MSTransportableDevice_Routing.h"
35 :
36 :
37 : // ===========================================================================
38 : // method definitions
39 : // ===========================================================================
40 : // ---------------------------------------------------------------------------
41 : // static initialisation methods
42 : // ---------------------------------------------------------------------------
43 : void
44 43644 : MSTransportableDevice_Routing::insertOptions(OptionsCont& oc) {
45 87288 : insertDefaultAssignmentOptions("rerouting", "Routing", oc, true);
46 87288 : oc.doRegister("person-device.rerouting.period", new Option_String("0", "TIME"));
47 87288 : oc.addSynonyme("person-device.rerouting.period", "person-device.routing.period", true);
48 87288 : oc.addDescription("person-device.rerouting.period", "Routing", TL("The period with which the person shall be rerouted"));
49 :
50 87288 : oc.doRegister("person-device.rerouting.mode", new Option_String("0"));
51 87288 : oc.addDescription("person-device.rerouting.mode", "Routing", TL("Set routing flags (8 ignores temporary blockages)"));
52 :
53 87288 : oc.doRegister("person-device.rerouting.scope", new Option_String("stage"));
54 87288 : oc.addDescription("person-device.rerouting.scope", "Routing", TL("Which part of the person plan is to be replaced (stage, sequence, or trip)"));
55 43644 : }
56 :
57 :
58 : void
59 501966 : MSTransportableDevice_Routing::buildDevices(MSTransportable& p, std::vector<MSTransportableDevice*>& into) {
60 501966 : const OptionsCont& oc = OptionsCont::getOptions();
61 782173 : if (p.getParameter().wasSet(VEHPARS_FORCE_REROUTE) || equippedByDefaultAssignmentOptions(oc, "rerouting", p, false, true)) {
62 : // route computation is enabled
63 221759 : const SUMOTime period = p.getTimeParam("person-device.rerouting.period");
64 221759 : if (period > 0) {
65 7 : MSRoutingEngine::initWeightUpdate();
66 : // build the device
67 14 : into.push_back(new MSTransportableDevice_Routing(p, "routing_" + p.getID(), period));
68 : }
69 : }
70 501966 : }
71 :
72 :
73 : // ---------------------------------------------------------------------------
74 : // MSTransportableDevice_Routing-methods
75 : // ---------------------------------------------------------------------------
76 7 : MSTransportableDevice_Routing::MSTransportableDevice_Routing(MSTransportable& holder, const std::string& id, SUMOTime period)
77 7 : : MSTransportableDevice(holder, id), myPeriod(period), myLastRouting(-1), myRerouteCommand(0) {
78 14 : myScope = holder.getStringParam("person-device.rerouting.scope");
79 : // no need for initial routing here, personTrips trigger it themselves
80 7 : myRerouteCommand = new WrappingCommand<MSTransportableDevice_Routing>(this, &MSTransportableDevice_Routing::wrappedRerouteCommandExecute);
81 7 : MSNet::getInstance()->getInsertionEvents()->addEvent(myRerouteCommand, SIMSTEP + period);
82 : // the event will deschedule and destroy itself so it does not need to be stored
83 7 : }
84 :
85 :
86 14 : MSTransportableDevice_Routing::~MSTransportableDevice_Routing() {
87 : // make the rerouting command invalid if there is one
88 7 : if (myRerouteCommand != nullptr) {
89 : myRerouteCommand->deschedule();
90 : }
91 14 : }
92 :
93 :
94 : SUMOTime
95 111 : MSTransportableDevice_Routing::wrappedRerouteCommandExecute(SUMOTime currentTime) {
96 111 : reroute(currentTime);
97 111 : return myPeriod;
98 : }
99 :
100 :
101 : void
102 111 : MSTransportableDevice_Routing::reroute(const SUMOTime currentTime, const bool onInit) {
103 111 : MSRoutingEngine::initEdgeWeights(SVC_PEDESTRIAN);
104 : //check whether the weights did change since the last reroute
105 111 : if (myLastRouting >= MSRoutingEngine::getLastAdaptation()) {
106 : return;
107 : }
108 111 : myLastRouting = currentTime;
109 222 : MSRoutingEngine::reroute(myHolder, currentTime, "person-device.rerouting", onInit);
110 : }
111 :
112 :
113 : std::string
114 0 : MSTransportableDevice_Routing::getParameter(const std::string& key) const {
115 0 : if (key == "period") {
116 0 : return time2string(myPeriod);
117 : }
118 0 : throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
119 : }
120 :
121 :
122 : void
123 0 : MSTransportableDevice_Routing::setParameter(const std::string& key, const std::string& value) {
124 : double doubleValue;
125 : try {
126 0 : doubleValue = StringUtils::toDouble(value);
127 0 : } catch (NumberFormatException&) {
128 0 : throw InvalidArgument("Setting parameter '" + key + "' requires a number for device of type '" + deviceName() + "'");
129 0 : }
130 0 : if (key == "period") {
131 0 : const SUMOTime oldPeriod = myPeriod;
132 0 : myPeriod = TIME2STEPS(doubleValue);
133 0 : if (myPeriod <= 0) {
134 0 : myRerouteCommand->deschedule();
135 0 : } else if (oldPeriod <= 0) {
136 : // re-schedule routing command
137 0 : MSNet::getInstance()->getInsertionEvents()->addEvent(new WrappingCommand<MSTransportableDevice_Routing>(this, &MSTransportableDevice_Routing::wrappedRerouteCommandExecute), SIMSTEP + myPeriod);
138 : }
139 : } else {
140 0 : throw InvalidArgument("Setting parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
141 : }
142 0 : }
143 :
144 :
145 : void
146 0 : MSTransportableDevice_Routing::saveState(OutputDevice& out) const {
147 0 : out.openTag(SUMO_TAG_DEVICE);
148 : out.writeAttr(SUMO_ATTR_ID, getID());
149 : std::vector<std::string> internals;
150 0 : internals.push_back(toString(myPeriod));
151 0 : out.writeAttr(SUMO_ATTR_STATE, toString(internals));
152 0 : out.closeTag();
153 0 : }
154 :
155 :
156 : void
157 0 : MSTransportableDevice_Routing::loadState(const SUMOSAXAttributes& attrs) {
158 0 : std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
159 0 : bis >> myPeriod;
160 0 : }
161 :
162 :
163 : /****************************************************************************/
|