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 36322 : MSTransportableDevice_Routing::insertOptions(OptionsCont& oc) { 45 72644 : insertDefaultAssignmentOptions("rerouting", "Routing", oc, true); 46 72644 : oc.doRegister("person-device.rerouting.period", new Option_String("0", "TIME")); 47 72644 : oc.addSynonyme("person-device.rerouting.period", "person-device.routing.period", true); 48 72644 : oc.addDescription("person-device.rerouting.period", "Routing", TL("The period with which the person shall be rerouted")); 49 36322 : } 50 : 51 : 52 : void 53 456733 : MSTransportableDevice_Routing::buildDevices(MSTransportable& p, std::vector<MSTransportableDevice*>& into) { 54 456733 : const OptionsCont& oc = OptionsCont::getOptions(); 55 662308 : if (p.getParameter().wasSet(VEHPARS_FORCE_REROUTE) || equippedByDefaultAssignmentOptions(oc, "rerouting", p, false, true)) { 56 : // route computation is enabled 57 502316 : const SUMOTime period = string2time(oc.getString("person-device.rerouting.period")); 58 251158 : MSRoutingEngine::initWeightUpdate(); 59 : // build the device 60 458106 : into.push_back(new MSTransportableDevice_Routing(p, "routing_" + p.getID(), period)); 61 : } 62 456733 : } 63 : 64 : 65 : // --------------------------------------------------------------------------- 66 : // MSTransportableDevice_Routing-methods 67 : // --------------------------------------------------------------------------- 68 251158 : MSTransportableDevice_Routing::MSTransportableDevice_Routing(MSTransportable& holder, const std::string& id, SUMOTime period) 69 251158 : : MSTransportableDevice(holder, id), myPeriod(period), myLastRouting(-1), myRerouteCommand(0) { 70 251158 : if (holder.getParameter().wasSet(VEHPARS_FORCE_REROUTE)) { 71 : // if we don't update the edge weights, we might as well reroute now and hopefully use our threads better 72 251158 : const SUMOTime execTime = MSRoutingEngine::hasEdgeUpdates() ? holder.getParameter().depart : -1; 73 251158 : MSNet::getInstance()->getInsertionEvents()->addEvent(new WrappingCommand<MSTransportableDevice_Routing>(this, &MSTransportableDevice_Routing::wrappedRerouteCommandExecute), execTime); 74 : // the event will deschedule and destroy itself so it does not need to be stored 75 : } 76 251158 : } 77 : 78 : 79 502306 : MSTransportableDevice_Routing::~MSTransportableDevice_Routing() { 80 : // make the rerouting command invalid if there is one 81 251153 : if (myRerouteCommand != nullptr) { 82 : myRerouteCommand->deschedule(); 83 : } 84 502306 : } 85 : 86 : 87 : SUMOTime 88 234487 : MSTransportableDevice_Routing::wrappedRerouteCommandExecute(SUMOTime currentTime) { 89 234487 : reroute(currentTime); 90 234487 : return myPeriod; 91 : } 92 : 93 : 94 : void 95 234487 : MSTransportableDevice_Routing::reroute(const SUMOTime currentTime, const bool /* onInit */) { 96 234487 : MSRoutingEngine::initEdgeWeights(SVC_PEDESTRIAN); 97 : //check whether the weights did change since the last reroute 98 234487 : if (myLastRouting >= MSRoutingEngine::getLastAdaptation()) { 99 : return; 100 : } 101 234487 : myLastRouting = currentTime; 102 : // MSRoutingEngine::reroute(myHolder, currentTime, onInit); 103 : } 104 : 105 : 106 : std::string 107 0 : MSTransportableDevice_Routing::getParameter(const std::string& key) const { 108 0 : if (key == "period") { 109 0 : return time2string(myPeriod); 110 : } 111 0 : throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'"); 112 : } 113 : 114 : 115 : void 116 0 : MSTransportableDevice_Routing::setParameter(const std::string& key, const std::string& value) { 117 : double doubleValue; 118 : try { 119 0 : doubleValue = StringUtils::toDouble(value); 120 0 : } catch (NumberFormatException&) { 121 0 : throw InvalidArgument("Setting parameter '" + key + "' requires a number for device of type '" + deviceName() + "'"); 122 0 : } 123 0 : if (key == "period") { 124 0 : const SUMOTime oldPeriod = myPeriod; 125 0 : myPeriod = TIME2STEPS(doubleValue); 126 0 : if (myPeriod <= 0) { 127 0 : myRerouteCommand->deschedule(); 128 0 : } else if (oldPeriod <= 0) { 129 : // re-schedule routing command 130 0 : MSNet::getInstance()->getInsertionEvents()->addEvent(new WrappingCommand<MSTransportableDevice_Routing>(this, &MSTransportableDevice_Routing::wrappedRerouteCommandExecute), SIMSTEP + myPeriod); 131 : } 132 : } else { 133 0 : throw InvalidArgument("Setting parameter '" + key + "' is not supported for device of type '" + deviceName() + "'"); 134 : } 135 0 : } 136 : 137 : 138 : void 139 0 : MSTransportableDevice_Routing::saveState(OutputDevice& out) const { 140 0 : out.openTag(SUMO_TAG_DEVICE); 141 : out.writeAttr(SUMO_ATTR_ID, getID()); 142 : std::vector<std::string> internals; 143 0 : internals.push_back(toString(myPeriod)); 144 0 : out.writeAttr(SUMO_ATTR_STATE, toString(internals)); 145 0 : out.closeTag(); 146 0 : } 147 : 148 : 149 : void 150 0 : MSTransportableDevice_Routing::loadState(const SUMOSAXAttributes& attrs) { 151 0 : std::istringstream bis(attrs.getString(SUMO_ATTR_STATE)); 152 0 : bis >> myPeriod; 153 0 : } 154 : 155 : 156 : /****************************************************************************/