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 MSRoutingEngine.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 "MSRoutingEngine.h"
27 : #include <microsim/MSNet.h>
28 : #include <microsim/MSLane.h>
29 : #include <microsim/MSEdge.h>
30 : #include <microsim/MSEdgeControl.h>
31 : #include <microsim/MSEventControl.h>
32 : #include <microsim/MSGlobals.h>
33 : #include <microsim/MSVehicleControl.h>
34 : #include <utils/options/OptionsCont.h>
35 : #include <utils/common/WrappingCommand.h>
36 : #include <utils/common/StaticCommand.h>
37 : #include <utils/common/StringUtils.h>
38 : #include <utils/xml/SUMOSAXAttributes.h>
39 : #include <utils/router/DijkstraRouter.h>
40 : #include <utils/router/AStarRouter.h>
41 : #include <utils/router/CHRouter.h>
42 : #include <utils/router/CHRouterWrapper.h>
43 :
44 : //#define DEBUG_SEPARATE_TURNS
45 : #define DEBUG_COND(obj) (obj->isSelected())
46 :
47 : // ===========================================================================
48 : // static member variables
49 : // ===========================================================================
50 : std::vector<double> MSRoutingEngine::myEdgeSpeeds;
51 : std::vector<double> MSRoutingEngine::myEdgeBikeSpeeds;
52 : std::vector<MSRoutingEngine::TimeAndCount> MSRoutingEngine::myEdgeTravelTimes;
53 : std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeSpeeds;
54 : std::vector<std::vector<double> > MSRoutingEngine::myPastEdgeBikeSpeeds;
55 : Command* MSRoutingEngine::myEdgeWeightSettingCommand = nullptr;
56 : double MSRoutingEngine::myAdaptationWeight;
57 : int MSRoutingEngine::myAdaptationSteps;
58 : int MSRoutingEngine::myAdaptationStepsIndex = 0;
59 : SUMOTime MSRoutingEngine::myAdaptationInterval = -1;
60 : SUMOTime MSRoutingEngine::myLastAdaptation = -1;
61 : bool MSRoutingEngine::myWithTaz;
62 : bool MSRoutingEngine::myBikeSpeeds;
63 : MSRouterProvider* MSRoutingEngine::myRouterProvider = nullptr;
64 : std::map<std::pair<const MSEdge*, const MSEdge*>, ConstMSRoutePtr> MSRoutingEngine::myCachedRoutes;
65 : double MSRoutingEngine::myPriorityFactor(0);
66 : double MSRoutingEngine::myMinEdgePriority(std::numeric_limits<double>::max());
67 : double MSRoutingEngine::myEdgePriorityRange(0);
68 : std::map<std::thread::id, SumoRNG*> MSRoutingEngine::myThreadRNGs;
69 :
70 : SUMOAbstractRouter<MSEdge, SUMOVehicle>::Operation MSRoutingEngine::myEffortFunc = &MSRoutingEngine::getEffort;
71 : #ifdef HAVE_FOX
72 : FXMutex MSRoutingEngine::myRouteCacheMutex;
73 : #endif
74 :
75 :
76 : // ===========================================================================
77 : // method definitions
78 : // ===========================================================================
79 : void
80 1641864 : MSRoutingEngine::initWeightUpdate() {
81 1641864 : if (myAdaptationInterval == -1) {
82 7411 : myEdgeWeightSettingCommand = nullptr;
83 : myEdgeSpeeds.clear();
84 : myEdgeTravelTimes.clear();
85 7411 : myAdaptationSteps = -1;
86 7411 : myLastAdaptation = -1;
87 7411 : const OptionsCont& oc = OptionsCont::getOptions();
88 7411 : myWithTaz = oc.getBool("device.rerouting.with-taz");
89 7411 : myAdaptationInterval = string2time(oc.getString("device.rerouting.adaptation-interval"));
90 7411 : myAdaptationWeight = oc.getFloat("device.rerouting.adaptation-weight");
91 14822 : const SUMOTime period = string2time(oc.getString("device.rerouting.period"));
92 7411 : if (myAdaptationWeight < 1. && myAdaptationInterval > 0) {
93 7331 : myEdgeWeightSettingCommand = new StaticCommand<MSRoutingEngine>(&MSRoutingEngine::adaptEdgeEfforts);
94 7331 : MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(myEdgeWeightSettingCommand);
95 80 : } else if (period > 0) {
96 0 : WRITE_WARNING(TL("Rerouting is useless if the edge weights do not get updated!"));
97 : }
98 22233 : OutputDevice::createDeviceByOption("device.rerouting.output", "weights", "meandata_file.xsd");
99 : }
100 1641864 : }
101 :
102 :
103 : void
104 10192179 : MSRoutingEngine::initEdgeWeights(SUMOVehicleClass svc) {
105 10192179 : if (myBikeSpeeds && svc == SVC_BICYCLE) {
106 252 : _initEdgeWeights(myEdgeBikeSpeeds, myPastEdgeBikeSpeeds);
107 : } else {
108 10191927 : _initEdgeWeights(myEdgeSpeeds, myPastEdgeSpeeds);
109 : }
110 10192179 : }
111 :
112 :
113 : void
114 10192179 : MSRoutingEngine::_initEdgeWeights(std::vector<double>& edgeSpeeds, std::vector<std::vector<double> >& pastEdgeSpeeds) {
115 10192179 : if (edgeSpeeds.empty()) {
116 7281 : const OptionsCont& oc = OptionsCont::getOptions();
117 7369 : if (myAdaptationWeight == 0 || !oc.isDefault("device.rerouting.adaptation-steps")) {
118 14386 : myAdaptationSteps = oc.getInt("device.rerouting.adaptation-steps");
119 : }
120 7281 : const bool useLoaded = oc.getBool("device.rerouting.init-with-loaded-weights");
121 7281 : const double currentSecond = SIMTIME;
122 : double maxEdgePriority = -std::numeric_limits<double>::max();
123 700267 : for (const MSEdge* const edge : MSNet::getInstance()->getEdgeControl().getEdges()) {
124 1385972 : while (edge->getNumericalID() >= (int)edgeSpeeds.size()) {
125 692986 : edgeSpeeds.push_back(0);
126 692986 : if (myAdaptationSteps > 0) {
127 692314 : pastEdgeSpeeds.push_back(std::vector<double>());
128 : }
129 692986 : if (MSGlobals::gWeightsSeparateTurns && edgeSpeeds == myEdgeSpeeds) {
130 1175 : myEdgeTravelTimes.push_back(TimeAndCount(0, 0));
131 : }
132 : }
133 692986 : if (useLoaded) {
134 114 : edgeSpeeds[edge->getNumericalID()] = edge->getLength() / MSNet::getTravelTime(edge, nullptr, currentSecond);
135 : } else {
136 692872 : edgeSpeeds[edge->getNumericalID()] = edge->getMeanSpeed();
137 : }
138 692986 : if (myAdaptationSteps > 0) {
139 1384628 : pastEdgeSpeeds[edge->getNumericalID()] = std::vector<double>(myAdaptationSteps, edgeSpeeds[edge->getNumericalID()]);
140 : }
141 692986 : maxEdgePriority = MAX2(maxEdgePriority, (double)edge->getPriority());
142 1346937 : myMinEdgePriority = MIN2(myMinEdgePriority, (double)edge->getPriority());
143 : }
144 7281 : myEdgePriorityRange = maxEdgePriority - myMinEdgePriority;
145 7281 : myLastAdaptation = MSNet::getInstance()->getCurrentTimeStep();
146 7281 : myPriorityFactor = oc.getFloat("weights.priority-factor");
147 7281 : if (myPriorityFactor < 0) {
148 0 : throw ProcessError(TL("weights.priority-factor cannot be negative."));
149 : }
150 7281 : if (myPriorityFactor > 0) {
151 7 : if (myEdgePriorityRange == 0) {
152 0 : WRITE_WARNING(TL("Option weights.priority-factor does not take effect because all edges have the same priority"));
153 0 : myPriorityFactor = 0;
154 : }
155 : }
156 : }
157 10192179 : }
158 :
159 :
160 : double
161 118792120 : MSRoutingEngine::getEffort(const MSEdge* const e, const SUMOVehicle* const v, double) {
162 : const int id = e->getNumericalID();
163 118792120 : if (id < (int)myEdgeSpeeds.size()) {
164 106244117 : return MAX2(e->getLength() / MAX2(myEdgeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
165 : }
166 12596999 : return e->getMinimumTravelTime(v);
167 : }
168 :
169 :
170 : double
171 1924 : MSRoutingEngine::getEffortBike(const MSEdge* const e, const SUMOVehicle* const v, double) {
172 : const int id = e->getNumericalID();
173 1924 : if (id < (int)myEdgeBikeSpeeds.size()) {
174 1924 : return MAX2(e->getLength() / MAX2(myEdgeBikeSpeeds[id], NUMERICAL_EPS), e->getMinimumTravelTime(v));
175 : }
176 0 : return e->getMinimumTravelTime(v);
177 : }
178 :
179 : SumoRNG*
180 24825 : MSRoutingEngine::getThreadRNG() {
181 24825 : if (myThreadRNGs.size() > 0) {
182 : auto it = myThreadRNGs.find(std::this_thread::get_id());
183 0 : if (it != myThreadRNGs.end()) {
184 0 : return it->second;
185 : }
186 0 : std::cout << " something bad happended\n";
187 : }
188 : return nullptr;
189 : }
190 :
191 :
192 : double
193 30615 : MSRoutingEngine::getEffortExtra(const MSEdge* const e, const SUMOVehicle* const v, double t) {
194 2636 : double effort = (!myBikeSpeeds || v == nullptr || v->getVClass() != SVC_BICYCLE
195 32671 : ? getEffort(e, v, t)
196 580 : : getEffortBike(e, v, t));
197 30615 : if (gWeightsRandomFactor != 1.) {
198 24825 : effort *= RandHelper::rand(1., gWeightsRandomFactor, getThreadRNG());
199 : }
200 30615 : if (myPriorityFactor != 0) {
201 : // lower priority should result in higher effort (and the edge with
202 : // minimum priority receives a factor of 1 + myPriorityFactor
203 840 : const double relativeInversePrio = 1 - ((e->getPriority() - myMinEdgePriority) / myEdgePriorityRange);
204 840 : effort *= 1 + relativeInversePrio * myPriorityFactor;
205 : }
206 30615 : return effort;
207 : }
208 :
209 :
210 : double
211 5089 : MSRoutingEngine::getAssumedSpeed(const MSEdge* edge, const SUMOVehicle* veh) {
212 5089 : return edge->getLength() / myEffortFunc(edge, veh, 0);
213 : }
214 :
215 :
216 : SUMOTime
217 7856047 : MSRoutingEngine::adaptEdgeEfforts(SUMOTime currentTime) {
218 7856047 : initEdgeWeights(SVC_PASSENGER);
219 7856047 : if (myBikeSpeeds) {
220 192 : initEdgeWeights(SVC_BICYCLE);
221 : }
222 7856047 : if (MSNet::getInstance()->getVehicleControl().getDepartedVehicleNo() == 0) {
223 510224 : return myAdaptationInterval;
224 : }
225 : myCachedRoutes.clear();
226 7345823 : const MSEdgeVector& edges = MSNet::getInstance()->getEdgeControl().getEdges();
227 7345823 : const double newWeightFactor = (double)(1. - myAdaptationWeight);
228 500002497 : for (const MSEdge* const e : edges) {
229 : if (e->isDelayed()) {
230 : const int id = e->getNumericalID();
231 108596774 : double currSpeed = e->getMeanSpeed();
232 108596774 : if (MSGlobals::gWeightsSeparateTurns > 0 && e->getNumSuccessors() > 1) {
233 127595 : currSpeed = patchSpeedForTurns(e, currSpeed);
234 : }
235 : #ifdef DEBUG_SEPARATE_TURNS
236 : if (DEBUG_COND(e->getLanes()[0])) {
237 : std::cout << SIMTIME << " edge=" << e->getID()
238 : << " meanSpeed=" << e->getMeanSpeed()
239 : << " currSpeed=" << currSpeed
240 : << " oldestSpeed=" << myPastEdgeSpeeds[id][myAdaptationStepsIndex]
241 : << " oldAvg=" << myEdgeSpeeds[id]
242 : << "\n";
243 : }
244 : #endif
245 108596774 : if (myAdaptationSteps > 0) {
246 : // moving average
247 108533708 : myEdgeSpeeds[id] += (currSpeed - myPastEdgeSpeeds[id][myAdaptationStepsIndex]) / myAdaptationSteps;
248 108533708 : myPastEdgeSpeeds[id][myAdaptationStepsIndex] = currSpeed;
249 108533708 : if (myBikeSpeeds) {
250 0 : const double currBikeSpeed = e->getMeanSpeedBike();
251 0 : myEdgeBikeSpeeds[id] += (currBikeSpeed - myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex]) / myAdaptationSteps;
252 0 : myPastEdgeBikeSpeeds[id][myAdaptationStepsIndex] = currBikeSpeed;
253 : }
254 : } else {
255 : // exponential moving average
256 63066 : if (currSpeed != myEdgeSpeeds[id]) {
257 25322 : myEdgeSpeeds[id] = myEdgeSpeeds[id] * myAdaptationWeight + currSpeed * newWeightFactor;
258 : }
259 63066 : if (myBikeSpeeds) {
260 1090 : const double currBikeSpeed = e->getMeanSpeedBike();
261 1090 : if (currBikeSpeed != myEdgeBikeSpeeds[id]) {
262 722 : myEdgeBikeSpeeds[id] = myEdgeBikeSpeeds[id] * myAdaptationWeight + currBikeSpeed * newWeightFactor;
263 : }
264 : }
265 : }
266 : }
267 : }
268 7345823 : if (myAdaptationSteps > 0) {
269 7326309 : myAdaptationStepsIndex = (myAdaptationStepsIndex + 1) % myAdaptationSteps;
270 : }
271 7345823 : myLastAdaptation = currentTime + DELTA_T; // because we run at the end of the time step
272 14691646 : if (OptionsCont::getOptions().isSet("device.rerouting.output")) {
273 11539 : OutputDevice& dev = OutputDevice::getDeviceByOption("device.rerouting.output");
274 11539 : dev.openTag(SUMO_TAG_INTERVAL);
275 : dev.writeAttr(SUMO_ATTR_ID, "device.rerouting");
276 11539 : dev.writeAttr(SUMO_ATTR_BEGIN, STEPS2TIME(currentTime));
277 23078 : dev.writeAttr(SUMO_ATTR_END, STEPS2TIME(currentTime + myAdaptationInterval));
278 140799 : for (const MSEdge* e : edges) {
279 129260 : dev.openTag(SUMO_TAG_EDGE);
280 : dev.writeAttr(SUMO_ATTR_ID, e->getID());
281 129260 : dev.writeAttr("traveltime", myEffortFunc(e, nullptr, STEPS2TIME(currentTime)));
282 129260 : if (myBikeSpeeds) {
283 : // @note edge-priority is not included here
284 2688 : dev.writeAttr("traveltimeBike", getEffortBike(e, nullptr, STEPS2TIME(currentTime)));
285 : }
286 258520 : dev.closeTag();
287 : }
288 23078 : dev.closeTag();
289 : }
290 7345823 : return myAdaptationInterval;
291 : }
292 :
293 :
294 : double
295 127595 : MSRoutingEngine::patchSpeedForTurns(const MSEdge* edge, double currSpeed) {
296 : const double length = edge->getLength();
297 : double maxSpeed = 0;
298 550565 : for (const auto& pair : edge->getViaSuccessors()) {
299 422970 : if (pair.second == nullptr) {
300 40005 : continue;
301 : }
302 382965 : TimeAndCount& tc = myEdgeTravelTimes[pair.second->getNumericalID()];
303 382965 : if (tc.second > 0) {
304 53590 : const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
305 : maxSpeed = MAX2(avgSpeed, maxSpeed);
306 : }
307 : }
308 127595 : if (maxSpeed > 0) {
309 : // perform correction
310 31755 : const double correctedSpeed = MSGlobals::gWeightsSeparateTurns * maxSpeed + (1 - MSGlobals::gWeightsSeparateTurns) * currSpeed;
311 141470 : for (const auto& pair : edge->getViaSuccessors()) {
312 109715 : if (pair.second == nullptr) {
313 9815 : continue;
314 : }
315 : const int iid = pair.second->getNumericalID();
316 99900 : TimeAndCount& tc = myEdgeTravelTimes[iid];
317 99900 : if (tc.second > 0) {
318 53590 : const double avgSpeed = length / STEPS2TIME(tc.first / tc.second);
319 53590 : if (avgSpeed < correctedSpeed) {
320 22330 : double internalTT = pair.second->getLength() / pair.second->getSpeedLimit();
321 22330 : internalTT += (length / avgSpeed - length / correctedSpeed) * MSGlobals::gWeightsSeparateTurns;
322 22330 : const double origInternalSpeed = myEdgeSpeeds[iid];
323 22330 : const double newInternalSpeed = pair.second->getLength() / internalTT;
324 22330 : const double origCurrSpeed = myPastEdgeSpeeds[iid][myAdaptationStepsIndex];
325 :
326 22330 : myEdgeSpeeds[iid] = newInternalSpeed;
327 : // to ensure myEdgeSpeed reverts to the speed limit
328 : // when there are no updates, we also have to patch
329 : // myPastEdgeSpeeds with a virtual value that is consistent
330 : // with the updated speed
331 : // note: internal edges were handled before the normal ones
332 22330 : const double virtualSpeed = (newInternalSpeed - (origInternalSpeed - origCurrSpeed / myAdaptationSteps)) * myAdaptationSteps;
333 22330 : myPastEdgeSpeeds[iid][myAdaptationStepsIndex] = virtualSpeed;
334 :
335 : #ifdef DEBUG_SEPARATE_TURNS
336 : if (DEBUG_COND(pair.second->getLanes()[0])) {
337 : std::cout << SIMTIME << " edge=" << edge->getID() << " to=" << pair.first->getID() << " via=" << pair.second->getID()
338 : << " origSpeed=" << currSpeed
339 : << " maxSpeed=" << maxSpeed
340 : << " correctedSpeed=" << correctedSpeed
341 : << " avgSpeed=" << avgSpeed
342 : << " internalTT=" << internalTT
343 : << " internalSpeed=" << origInternalSpeed
344 : << " newInternalSpeed=" << newInternalSpeed
345 : << " virtualSpeed=" << virtualSpeed
346 : << "\n";
347 : }
348 : #endif
349 : }
350 53590 : if (myAdaptationStepsIndex == 0) {
351 525 : tc.first = 0;
352 525 : tc.second = 0;
353 : }
354 : }
355 : }
356 : return correctedSpeed;
357 : }
358 : return currSpeed;
359 : }
360 :
361 :
362 : ConstMSRoutePtr
363 675361 : MSRoutingEngine::getCachedRoute(const std::pair<const MSEdge*, const MSEdge*>& key) {
364 : auto routeIt = myCachedRoutes.find(key);
365 675361 : if (routeIt != myCachedRoutes.end()) {
366 : return routeIt->second;
367 : }
368 : return nullptr;
369 : }
370 :
371 :
372 : void
373 6064 : MSRoutingEngine::initRouter(SUMOVehicle* vehicle) {
374 6064 : OptionsCont& oc = OptionsCont::getOptions();
375 6064 : const std::string routingAlgorithm = oc.getString("routing-algorithm");
376 6064 : const bool hasPermissions = MSNet::getInstance()->hasPermissions();
377 6064 : myBikeSpeeds = oc.getBool("device.rerouting.bike-speeds");
378 12095 : myEffortFunc = ((gWeightsRandomFactor != 1 || myPriorityFactor != 0 || myBikeSpeeds) ? &MSRoutingEngine::getEffortExtra : &MSRoutingEngine::getEffort);
379 :
380 : SUMOAbstractRouter<MSEdge, SUMOVehicle>* router = nullptr;
381 6064 : if (routingAlgorithm == "dijkstra") {
382 5812 : router = new DijkstraRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, nullptr, true);
383 252 : } else if (routingAlgorithm == "astar") {
384 : typedef AStarRouter<MSEdge, SUMOVehicle> AStar;
385 : std::shared_ptr<const AStar::LookupTable> lookup = nullptr;
386 468 : if (oc.isSet("astar.all-distances")) {
387 0 : lookup = std::make_shared<const AStar::FLT>(oc.getString("astar.all-distances"), (int)MSEdge::getAllEdges().size());
388 468 : } else if (oc.isSet("astar.landmark-distances") && vehicle != nullptr) {
389 28 : const double speedFactor = vehicle->getChosenSpeedFactor();
390 : // we need an exemplary vehicle with speedFactor 1
391 28 : vehicle->setChosenSpeedFactor(1);
392 : CHRouterWrapper<MSEdge, SUMOVehicle> chrouter(
393 28 : MSEdge::getAllEdges(), true, &MSNet::getTravelTime,
394 84 : string2time(oc.getString("begin")), string2time(oc.getString("end")), SUMOTime_MAX, hasPermissions, 1);
395 56 : lookup = std::make_shared<const AStar::LMLT>(oc.getString("astar.landmark-distances"), MSEdge::getAllEdges(), &chrouter,
396 56 : nullptr, vehicle, "", oc.getInt("device.rerouting.threads"));
397 28 : vehicle->setChosenSpeedFactor(speedFactor);
398 28 : }
399 702 : router = new AStar(MSEdge::getAllEdges(), true, myEffortFunc, lookup, true);
400 18 : } else if (routingAlgorithm == "CH" && !hasPermissions) {
401 6 : const SUMOTime weightPeriod = myAdaptationInterval > 0 ? myAdaptationInterval : SUMOTime_MAX;
402 : router = new CHRouter<MSEdge, SUMOVehicle>(
403 6 : MSEdge::getAllEdges(), true, myEffortFunc, vehicle == nullptr ? SVC_PASSENGER : vehicle->getVClass(), weightPeriod, true, false);
404 12 : } else if (routingAlgorithm == "CHWrapper" || routingAlgorithm == "CH") {
405 : // use CHWrapper instead of CH if the net has permissions
406 12 : const SUMOTime weightPeriod = myAdaptationInterval > 0 ? myAdaptationInterval : SUMOTime_MAX;
407 : router = new CHRouterWrapper<MSEdge, SUMOVehicle>(
408 12 : MSEdge::getAllEdges(), true, myEffortFunc,
409 24 : string2time(oc.getString("begin")), string2time(oc.getString("end")), weightPeriod, hasPermissions, oc.getInt("device.rerouting.threads"));
410 : } else {
411 0 : throw ProcessError(TLF("Unknown routing algorithm '%'!", routingAlgorithm));
412 : }
413 :
414 : RailwayRouter<MSEdge, SUMOVehicle>* railRouter = nullptr;
415 6064 : if (MSNet::getInstance()->hasBidiEdges()) {
416 572 : railRouter = new RailwayRouter<MSEdge, SUMOVehicle>(MSEdge::getAllEdges(), true, myEffortFunc, nullptr, false, true, false, oc.getFloat("railway.max-train-length"));
417 : }
418 6064 : myRouterProvider = new MSRouterProvider(router, nullptr, nullptr, railRouter);
419 : #ifndef THREAD_POOL
420 : #ifdef HAVE_FOX
421 6064 : MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
422 6064 : if (threadPool.size() > 0) {
423 : const std::vector<MFXWorkerThread*>& threads = threadPool.getWorkers();
424 699 : if (static_cast<MSEdgeControl::WorkerThread*>(threads.front())->setRouterProvider(myRouterProvider)) {
425 2704 : for (std::vector<MFXWorkerThread*>::const_iterator t = threads.begin() + 1; t != threads.end(); ++t) {
426 2005 : static_cast<MSEdgeControl::WorkerThread*>(*t)->setRouterProvider(myRouterProvider->clone());
427 : }
428 : }
429 : #ifndef WIN32
430 : /*
431 : int i = 0;
432 : for (MFXWorkerThread* t : threads) {
433 : myThreadRNGs[(std::thread::id)t->id()] = new SumoRNG("routing_" + toString(i++));
434 : }
435 : */
436 : #endif
437 : }
438 : #endif
439 : #endif
440 6064 : }
441 :
442 :
443 : void
444 2099851 : MSRoutingEngine::reroute(SUMOVehicle& vehicle, const SUMOTime currentTime, const std::string& info,
445 : const bool onInit, const bool silent, const MSEdgeVector& prohibited) {
446 2099851 : if (myRouterProvider == nullptr) {
447 5983 : initRouter(&vehicle);
448 : }
449 2099851 : auto& router = myRouterProvider->getVehicleRouter(vehicle.getVClass());
450 : #ifndef THREAD_POOL
451 : #ifdef HAVE_FOX
452 2099851 : MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
453 2099851 : if (threadPool.size() > 0) {
454 129931 : threadPool.add(new RoutingTask(vehicle, currentTime, info, onInit, silent, prohibited));
455 129931 : return;
456 : }
457 : #endif
458 : #endif
459 1969920 : if (!prohibited.empty()) {
460 127 : router.prohibit(prohibited);
461 : }
462 : try {
463 1969920 : vehicle.reroute(currentTime, info, router, onInit, myWithTaz, silent);
464 98 : } catch (ProcessError&) {
465 98 : if (!silent) {
466 96 : if (!prohibited.empty()) {
467 0 : router.prohibit(MSEdgeVector());
468 : }
469 96 : throw;
470 : }
471 98 : }
472 1969824 : if (!prohibited.empty()) {
473 254 : router.prohibit(MSEdgeVector());
474 : }
475 : }
476 :
477 :
478 : void
479 10 : MSRoutingEngine::setEdgeTravelTime(const MSEdge* const edge, const double travelTime) {
480 10 : myEdgeSpeeds[edge->getNumericalID()] = edge->getLength() / travelTime;
481 10 : }
482 :
483 : void
484 10980 : MSRoutingEngine::addEdgeTravelTime(const MSEdge& edge, const SUMOTime travelTime) {
485 10980 : TimeAndCount& tc = myEdgeTravelTimes[edge.getNumericalID()];
486 10980 : tc.first += travelTime;
487 10980 : tc.second += 1;
488 10980 : }
489 :
490 :
491 : MSVehicleRouter&
492 725017 : MSRoutingEngine::getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector& prohibited) {
493 725017 : if (myRouterProvider == nullptr) {
494 81 : initWeightUpdate();
495 81 : initEdgeWeights(svc);
496 81 : initRouter();
497 : }
498 : #ifndef THREAD_POOL
499 : #ifdef HAVE_FOX
500 725017 : MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
501 725017 : if (threadPool.size() > 0) {
502 35261 : auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getRouter(svc);
503 35261 : router.prohibit(prohibited);
504 35261 : return router;
505 : }
506 : #else
507 : UNUSED_PARAMETER(rngIndex);
508 : #endif
509 : #endif
510 1379512 : myRouterProvider->getVehicleRouter(svc).prohibit(prohibited);
511 689756 : return myRouterProvider->getVehicleRouter(svc);
512 : }
513 :
514 :
515 : MSTransportableRouter&
516 0 : MSRoutingEngine::getIntermodalRouterTT(const int rngIndex, const MSEdgeVector& prohibited) {
517 0 : if (myRouterProvider == nullptr) {
518 0 : initWeightUpdate();
519 0 : initEdgeWeights(SVC_PEDESTRIAN);
520 0 : initRouter();
521 : }
522 : #ifndef THREAD_POOL
523 : #ifdef HAVE_FOX
524 0 : MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
525 0 : if (threadPool.size() > 0) {
526 0 : auto& router = static_cast<MSEdgeControl::WorkerThread*>(threadPool.getWorkers()[rngIndex % MSGlobals::gNumThreads])->getIntermodalRouter();
527 0 : router.prohibit(prohibited);
528 0 : return router;
529 : }
530 : #else
531 : UNUSED_PARAMETER(rngIndex);
532 : #endif
533 : #endif
534 0 : myRouterProvider->getIntermodalRouter().prohibit(prohibited);
535 0 : return myRouterProvider->getIntermodalRouter();
536 : }
537 :
538 :
539 : void
540 35160 : MSRoutingEngine::cleanup() {
541 35160 : myAdaptationInterval = -1; // responsible for triggering initEdgeWeights
542 : myPastEdgeSpeeds.clear();
543 : myEdgeSpeeds.clear();
544 : myEdgeTravelTimes.clear();
545 : myPastEdgeBikeSpeeds.clear();
546 : myEdgeBikeSpeeds.clear();
547 : // @todo recheck. calling release crashes in parallel routing
548 : //for (auto& item : myCachedRoutes) {
549 : // item.second->release();
550 : //}
551 : myCachedRoutes.clear();
552 35160 : myAdaptationStepsIndex = 0;
553 : #ifdef HAVE_FOX
554 35160 : if (MSGlobals::gNumThreads > 1) {
555 : // router deletion is done in thread destructor
556 3810 : myRouterProvider = nullptr;
557 3810 : return;
558 : }
559 : #endif
560 31350 : delete myRouterProvider;
561 31350 : myRouterProvider = nullptr;
562 : }
563 :
564 :
565 : #ifdef HAVE_FOX
566 : void
567 151071395 : MSRoutingEngine::waitForAll() {
568 : #ifndef THREAD_POOL
569 151071395 : MFXWorkerThread::Pool& threadPool = MSNet::getInstance()->getEdgeControl().getThreadPool();
570 151071395 : if (threadPool.size() > 0) {
571 6653712 : threadPool.waitAll();
572 : }
573 : #endif
574 151071371 : }
575 :
576 :
577 : // ---------------------------------------------------------------------------
578 : // MSRoutingEngine::RoutingTask-methods
579 : // ---------------------------------------------------------------------------
580 : void
581 129931 : MSRoutingEngine::RoutingTask::run(MFXWorkerThread* context) {
582 129931 : SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = static_cast<MSEdgeControl::WorkerThread*>(context)->getRouter(myVehicle.getVClass());
583 129931 : if (!myProhibited.empty()) {
584 54 : router.prohibit(myProhibited);
585 : }
586 : try {
587 129931 : myVehicle.reroute(myTime, myInfo, router, myOnInit, myWithTaz, mySilent);
588 25 : } catch (ProcessError&) {
589 25 : if (!mySilent) {
590 24 : if (!myProhibited.empty()) {
591 0 : router.prohibit(MSEdgeVector());
592 : }
593 24 : throw;
594 : }
595 25 : }
596 129907 : if (!myProhibited.empty()) {
597 108 : router.prohibit(MSEdgeVector());
598 : }
599 129907 : const MSEdge* source = *myVehicle.getRoute().begin();
600 129907 : const MSEdge* dest = myVehicle.getRoute().getLastEdge();
601 129907 : if (source->isTazConnector() && dest->isTazConnector()) {
602 4 : const std::pair<const MSEdge*, const MSEdge*> key = std::make_pair(source, dest);
603 : FXMutexLock lock(myRouteCacheMutex);
604 4 : if (MSRoutingEngine::myCachedRoutes.find(key) == MSRoutingEngine::myCachedRoutes.end()) {
605 6 : MSRoutingEngine::myCachedRoutes[key] = myVehicle.getRoutePtr();
606 : }
607 : }
608 129907 : }
609 : #endif
610 :
611 :
612 : /****************************************************************************/
|