MSTriggeredRerouter.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Reroutes vehicles passing an edge
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
00023 // ===========================================================================
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029 
00030 #include <string>
00031 #include <algorithm>
00032 #include <utils/common/MsgHandler.h>
00033 #include <utils/common/Command.h>
00034 #include <microsim/MSLane.h>
00035 #include <microsim/MSNet.h>
00036 #include <microsim/MSGlobals.h>
00037 #include <utils/xml/SUMOXMLDefinitions.h>
00038 #include <utils/common/UtilExceptions.h>
00039 #include "MSTriggeredRerouter.h"
00040 #include <utils/xml/XMLSubSys.h>
00041 #include <utils/common/TplConvert.h>
00042 #include <utils/xml/SUMOSAXHandler.h>
00043 #include <utils/common/DijkstraRouterTT.h>
00044 #include <utils/common/RandHelper.h>
00045 #include <microsim/MSEdgeWeightsStorage.h>
00046 
00047 #ifdef HAVE_MESOSIM
00048 #include <mesosim/MELoop.h>
00049 #endif
00050 
00051 #ifdef CHECK_MEMORY_LEAKS
00052 #include <foreign/nvwa/debug_new.h>
00053 #endif // CHECK_MEMORY_LEAKS
00054 
00055 
00056 // ===========================================================================
00057 // method definitions
00058 // ===========================================================================
00059 /* -------------------------------------------------------------------------
00060  * MSTriggeredRerouter::Setter - methods
00061  * ----------------------------------------------------------------------- */
00062 MSTriggeredRerouter::Setter::Setter(MSTriggeredRerouter * const parent,
00063                                     MSLane * const lane) throw()
00064         : MSMoveReminder(lane), myParent(parent) {}
00065 
00066 
00067 MSTriggeredRerouter::Setter::~Setter() throw() {}
00068 
00069 
00070 bool
00071 MSTriggeredRerouter::Setter::isStillActive(MSVehicle& veh, SUMOReal /*oldPos*/,
00072         SUMOReal /*newPos*/, SUMOReal /*newSpeed*/) throw() {
00073     myParent->reroute(veh, myLane->getEdge());
00074     return false;
00075 }
00076 
00077 
00078 bool
00079 MSTriggeredRerouter::Setter::notifyEnter(MSVehicle& veh, bool, bool) throw() {
00080     myParent->reroute(veh, myLane->getEdge());
00081     return false;
00082 }
00083 
00084 
00085 /* -------------------------------------------------------------------------
00086  * MSTriggeredRerouter - methods
00087  * ----------------------------------------------------------------------- */
00088 MSTriggeredRerouter::MSTriggeredRerouter(const std::string &id,
00089         const std::vector<MSEdge*> &edges,
00090         SUMOReal prob, const std::string &file, bool off)
00091         : MSTrigger(id), SUMOSAXHandler(file),
00092         myProbability(prob), myUserProbability(prob), myAmInUserMode(false) {
00093     // read in the trigger description
00094     if (!XMLSubSys::runParser(*this, file)) {
00095         throw ProcessError();
00096     }
00097     // build actors
00098 #ifdef HAVE_MESOSIM
00099     if (MSGlobals::gUseMesoSim) {
00100         for (std::vector<MSEdge*>::const_iterator j=edges.begin(); j!=edges.end(); ++j) {
00101             MESegment *s = MSGlobals::gMesoNet->getSegmentForEdge(**j);
00102             s->addRerouter(this);
00103         }
00104     } else {
00105 #endif
00106         for (std::vector<MSEdge*>::const_iterator j=edges.begin(); j!=edges.end(); ++j) {
00107             const std::vector<MSLane*> &destLanes = (*j)->getLanes();
00108             for (std::vector<MSLane*>::const_iterator i=destLanes.begin(); i!=destLanes.end(); ++i) {
00109                 mySetter.push_back(new Setter(this, (*i)));
00110             }
00111         }
00112 #ifdef HAVE_MESOSIM
00113     }
00114 #endif
00115     if (off) {
00116         setUserMode(true);
00117         setUserUsageProbability(0);
00118     }
00119 }
00120 
00121 
00122 MSTriggeredRerouter::~MSTriggeredRerouter() throw() {
00123     {
00124         std::vector<Setter*>::iterator i;
00125         for (i=mySetter.begin(); i!=mySetter.end(); ++i) {
00126             delete *i;
00127         }
00128     }
00129 }
00130 
00131 // ------------ loading begin
00132 void
00133 MSTriggeredRerouter::myStartElement(SumoXMLTag element,
00134                                     const SUMOSAXAttributes &attrs) throw(ProcessError) {
00135     if (element==SUMO_TAG_INTERVAL) {
00136         bool ok = true;
00137         myCurrentIntervalBegin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, "interval", 0, ok, -1);
00138         myCurrentIntervalEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, "interval", 0, ok, -1);
00139     }
00140 
00141     if (element==SUMO_TAG_DEST_PROB_REROUTE) {
00142         // by giving probabilities of new destinations
00143         // get the destination edge
00144         std::string dest = attrs.getStringSecure(SUMO_ATTR_ID, "");
00145         if (dest=="") {
00146             throw ProcessError("MSTriggeredRerouter " + getID() + ": No destination edge id given.");
00147         }
00148         MSEdge *to = MSEdge::dictionary(dest);
00149         if (to==0) {
00150             throw ProcessError("MSTriggeredRerouter " + getID() + ": Destination edge '" + dest + "' is not known.");
00151         }
00152         // get the probability to reroute
00153         bool ok = true;
00154         SUMOReal prob = attrs.getOptSUMORealReporting(SUMO_ATTR_PROB, "rerouter/dest_prob_reroute", getID().c_str(), ok, 1.);
00155         if (!ok) {
00156             throw ProcessError();
00157         }
00158         if (prob<0) {
00159             throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + dest + "' is negative (must not).");
00160         }
00161         // add
00162         myCurrentEdgeProb.add(prob, to);
00163     }
00164 
00165     if (element==SUMO_TAG_CLOSING_REROUTE) {
00166         // by closing
00167         std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
00168         if (closed_id=="") {
00169             throw ProcessError("MSTriggeredRerouter " + getID() + ": closed edge id given.");
00170         }
00171         MSEdge *closed = MSEdge::dictionary(closed_id);
00172         if (closed==0) {
00173             throw ProcessError("MSTriggeredRerouter " + getID() + ": Edge '" + closed_id + "' to close is not known.");
00174         }
00175         myCurrentClosed.push_back(closed);
00176     }
00177 
00178     if (element==SUMO_TAG_ROUTE_PROB_REROUTE) {
00179         // by explicite rerouting using routes
00180         // check if route exists
00181         std::string routeStr = attrs.getStringSecure(SUMO_ATTR_ID, "");
00182         if (routeStr=="") {
00183             throw ProcessError("MSTriggeredRerouter " + getID() + ": No route id given.");
00184         }
00185         const MSRoute* route = MSRoute::dictionary(routeStr);
00186         if (route == 0) {
00187             throw ProcessError("MSTriggeredRerouter " + getID() + ": Route '" + routeStr + "' does not exist.");
00188         }
00189 
00190         // get the probability to reroute
00191         bool ok = true;
00192         SUMOReal prob = attrs.getOptSUMORealReporting(SUMO_ATTR_PROB, "rerouter/dest_prob_reroute", getID().c_str(), ok, 1.);
00193         if (!ok) {
00194             throw ProcessError();
00195         }
00196         if (prob<0) {
00197             throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for route '" + routeStr + "' is negative (must not).");
00198         }
00199         // add
00200         myCurrentRouteProb.add(prob, route);
00201     }
00202 }
00203 
00204 
00205 void
00206 MSTriggeredRerouter::myEndElement(SumoXMLTag element) throw(ProcessError) {
00207     if (element==SUMO_TAG_INTERVAL) {
00208         RerouteInterval ri;
00209         ri.begin = myCurrentIntervalBegin;
00210         ri.end = myCurrentIntervalEnd;
00211         ri.closed = myCurrentClosed;
00212         ri.edgeProbs = myCurrentEdgeProb;
00213         ri.routeProbs = myCurrentRouteProb;
00214         myCurrentClosed.clear();
00215         myCurrentEdgeProb.clear();
00216         myCurrentRouteProb.clear();
00217         myIntervals.push_back(ri);
00218     }
00219 }
00220 
00221 
00222 // ------------ loading end
00223 
00224 
00225 bool
00226 MSTriggeredRerouter::hasCurrentReroute(SUMOTime time, SUMOVehicle &veh) const {
00227     std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
00228     const MSRoute &route = veh.getRoute();
00229     while (i!=myIntervals.end()) {
00230         if ((*i).begin<=time && (*i).end>=time) {
00231             if ((*i).edgeProbs.getOverallProb()!=0||(*i).routeProbs.getOverallProb()!=0||route.containsAnyOf((*i).closed)) {
00232                 return true;
00233             }
00234         }
00235         i++;
00236     }
00237     return false;
00238 }
00239 
00240 
00241 bool
00242 MSTriggeredRerouter::hasCurrentReroute(SUMOTime time) const {
00243     std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
00244     while (i!=myIntervals.end()) {
00245         if ((*i).begin<=time && (*i).end>=time) {
00246             if ((*i).edgeProbs.getOverallProb()!=0||(*i).routeProbs.getOverallProb()!=0||(*i).closed.size()!=0) {
00247                 return true;
00248             }
00249         }
00250         i++;
00251     }
00252     return false;
00253 }
00254 
00255 
00256 const MSTriggeredRerouter::RerouteInterval &
00257 MSTriggeredRerouter::getCurrentReroute(SUMOTime time, SUMOVehicle &veh) const {
00258     std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
00259     const MSRoute &route = veh.getRoute();
00260     while (i!=myIntervals.end()) {
00261         if ((*i).begin<=time && (*i).end>=time) {
00262             if ((*i).edgeProbs.getOverallProb()!=0||(*i).routeProbs.getOverallProb()!=0||route.containsAnyOf((*i).closed)) {
00263                 return *i;
00264             }
00265         }
00266         i++;
00267     }
00268     throw 1;
00269 }
00270 
00271 
00272 const MSTriggeredRerouter::RerouteInterval &
00273 MSTriggeredRerouter::getCurrentReroute(SUMOTime) const {
00274     std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
00275     while (i!=myIntervals.end()) {
00276         if ((*i).edgeProbs.getOverallProb()!=0||(*i).routeProbs.getOverallProb()!=0||(*i).closed.size()!=0) {
00277             return *i;
00278         }
00279         i++;
00280     }
00281     throw 1;
00282 }
00283 
00284 
00285 
00286 void
00287 MSTriggeredRerouter::reroute(SUMOVehicle &veh, const MSEdge &src) {
00288     // check whether the vehicle shall be rerouted
00289     SUMOTime time = MSNet::getInstance()->getCurrentTimeStep();
00290     if (!hasCurrentReroute(time, veh)) {
00291         return;
00292     }
00293 
00294     SUMOReal prob = myAmInUserMode ? myUserProbability : myProbability;
00295     if (RandHelper::rand() > prob) {
00296         return;
00297     }
00298 
00299     // get vehicle params
00300     const MSRoute &route = veh.getRoute();
00301     const MSEdge *lastEdge = route.getLastEdge();
00302     // get rerouting params
00303     const MSTriggeredRerouter::RerouteInterval &rerouteDef = getCurrentReroute(time, veh);
00304     const MSRoute *newRoute = rerouteDef.routeProbs.getOverallProb()>0 ? rerouteDef.routeProbs.get() : 0;
00305     // we will use the route if given rather than calling our own dijsktra...
00306     if (newRoute!=0) {
00307         veh.replaceRoute(newRoute->getEdges(), time);
00308         return;
00309     }
00310     // ok, try using a new destination
00311     const MSEdge *newEdge = rerouteDef.edgeProbs.getOverallProb()>0 ? rerouteDef.edgeProbs.get() : route.getLastEdge();
00312     if (newEdge==0) {
00313         newEdge = lastEdge;
00314     }
00315 
00316     // we have a new destination, let's replace the vehicle route
00317     MSEdgeWeightsStorage empty;
00318     MSNet::EdgeWeightsProxi proxi(empty, MSNet::getInstance()->getWeightsStorage());
00319     DijkstraRouterTT_ByProxi<MSEdge, SUMOVehicle, prohibited_withRestrictions<MSEdge, SUMOVehicle>, MSNet::EdgeWeightsProxi> router(MSEdge::dictSize(), true, &proxi, &MSNet::EdgeWeightsProxi::getTravelTime);
00320     router.prohibit(rerouteDef.closed);
00321     std::vector<const MSEdge*> edges;
00322     router.compute(&src, newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges);
00323     veh.replaceRoute(edges, MSNet::getInstance()->getCurrentTimeStep());
00324 }
00325 
00326 
00327 void
00328 MSTriggeredRerouter::setUserMode(bool val) {
00329     myAmInUserMode = val;
00330 }
00331 
00332 
00333 void
00334 MSTriggeredRerouter::setUserUsageProbability(SUMOReal prob) {
00335     myUserProbability = prob;
00336 }
00337 
00338 
00339 bool
00340 MSTriggeredRerouter::inUserMode() const {
00341     return myAmInUserMode;
00342 }
00343 
00344 
00345 SUMOReal
00346 MSTriggeredRerouter::getProbability() const {
00347     return myAmInUserMode ? myUserProbability : myProbability;
00348 }
00349 
00350 
00351 SUMOReal
00352 MSTriggeredRerouter::getUserProbability() const {
00353     return myUserProbability;
00354 }
00355 
00356 
00357 
00358 /****************************************************************************/
00359 

Generated on Wed May 5 00:06:32 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6