bool MSTriggeredRerouter::notifyEnter(SUMOVehicle& veh, MSMoveReminder::Notification reason) { if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) { return false; } // check whether the vehicle shall be rerouted SUMOTime time = MSNet::getInstance()->getCurrentTimeStep(); if (!hasCurrentReroute(time, veh)) { return false; } SUMOReal prob = myAmInUserMode ? myUserProbability : myProbability; if (RandHelper::rand() > prob) { return false; } // get vehicle params const MSRoute& route = veh.getRoute(); const MSEdge* lastEdge = route.getLastEdge(); // get rerouting params const MSTriggeredRerouter::RerouteInterval& rerouteDef = getCurrentReroute(time, veh); const MSRoute* newRoute = rerouteDef.routeProbs.getOverallProb() > 0 ? rerouteDef.routeProbs.get() : 0; // we will use the route if given rather than calling our own dijsktra... if (newRoute != 0) { veh.replaceRoute(newRoute); return false; } const MSEdge* newEdge = lastEdge; // ok, try using a new destination const bool destUnreachable = std::find(rerouteDef.closed.begin(), rerouteDef.closed.end(), lastEdge) != rerouteDef.closed.end(); // if we have a closingReroute, only assign new destinations to vehicles which cannot reach their original destination if (rerouteDef.closed.size() == 0 || destUnreachable) { newEdge = rerouteDef.edgeProbs.getOverallProb() > 0 ? rerouteDef.edgeProbs.get() : route.getLastEdge(); if (newEdge == &mySpecialDest_terminateRoute) { newEdge = veh.getEdge(); } else if (newEdge == &mySpecialDest_keepDestination || newEdge == lastEdge) { if (destUnreachable) { WRITE_WARNING("Cannot keep destination for vehicle '" + veh.getID() + "' due to closed edges. Terminating route."); newEdge = veh.getEdge(); } else { newEdge = lastEdge; } } else if (newEdge == 0) { assert(false); // this should never happen newEdge = veh.getEdge(); } } // we have a new destination, let's replace the vehicle route std::vector<const MSEdge*> edges; MSNet::getInstance()->getRouterTT(rerouteDef.closed).compute( veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges); veh.replaceRouteEdges(edges); return false; }
void MSTriggeredRerouter::reroute(SUMOVehicle &veh, const MSEdge &src) { // check whether the vehicle shall be rerouted SUMOTime time = MSNet::getInstance()->getCurrentTimeStep(); if (!hasCurrentReroute(time, veh)) { return; } SUMOReal prob = myAmInUserMode ? myUserProbability : myProbability; if (RandHelper::rand() > prob) { return; } // get vehicle params const MSRoute &route = veh.getRoute(); const MSEdge *lastEdge = route.getLastEdge(); // get rerouting params const MSTriggeredRerouter::RerouteInterval &rerouteDef = getCurrentReroute(time, veh); const MSRoute *newRoute = rerouteDef.routeProbs.getOverallProb()>0 ? rerouteDef.routeProbs.get() : 0; // we will use the route if given rather than calling our own dijsktra... if (newRoute!=0) { veh.replaceRoute(newRoute->getEdges(), time); return; } // ok, try using a new destination const MSEdge *newEdge = rerouteDef.edgeProbs.getOverallProb()>0 ? rerouteDef.edgeProbs.get() : route.getLastEdge(); if (newEdge==0) { newEdge = lastEdge; } // we have a new destination, let's replace the vehicle route MSEdgeWeightsStorage empty; MSNet::EdgeWeightsProxi proxi(empty, MSNet::getInstance()->getWeightsStorage()); DijkstraRouterTT_ByProxi<MSEdge, SUMOVehicle, prohibited_withRestrictions<MSEdge, SUMOVehicle>, MSNet::EdgeWeightsProxi> router(MSEdge::dictSize(), true, &proxi, &MSNet::EdgeWeightsProxi::getTravelTime); router.prohibit(rerouteDef.closed); std::vector<const MSEdge*> edges; router.compute(&src, newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges); veh.replaceRoute(edges, MSNet::getInstance()->getCurrentTimeStep()); }