SUMO - Simulation of Urban MObility

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 (C) 2001-2011 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 #include <mesosim/MESegment.h>
00050 #endif
00051 
00052 #ifdef CHECK_MEMORY_LEAKS
00053 #include <foreign/nvwa/debug_new.h>
00054 #endif // CHECK_MEMORY_LEAKS
00055 
00056 
00057 // ===========================================================================
00058 // method definitions
00059 // ===========================================================================
00060 bool MSTriggeredRerouter::myHaveWarnedAboutDeprecatedDestProbReroute = false;
00061 bool MSTriggeredRerouter::myHaveWarnedAboutDeprecatedClosingReroute = false;
00062 bool MSTriggeredRerouter::myHaveWarnedAboutDeprecatedRouteReroute = false;
00063 
00064 
00065 // ===========================================================================
00066 // method definitions
00067 // ===========================================================================
00068 MSTriggeredRerouter::MSTriggeredRerouter(const std::string& id,
00069         const std::vector<MSEdge*> &edges,
00070         SUMOReal prob, const std::string& file, bool off)
00071     : MSTrigger(id), MSMoveReminder(), SUMOSAXHandler(file),
00072       myProbability(prob), myUserProbability(prob), myAmInUserMode(false) {
00073     // read in the trigger description
00074     if (!XMLSubSys::runParser(*this, file)) {
00075         throw ProcessError();
00076     }
00077     // build actors
00078     for (std::vector<MSEdge*>::const_iterator j=edges.begin(); j!=edges.end(); ++j) {
00079 #ifdef HAVE_MESOSIM
00080         if (MSGlobals::gUseMesoSim) {
00081             MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(**j);
00082             s->addDetector(this);
00083             continue;
00084         }
00085 #endif
00086         const std::vector<MSLane*> &destLanes = (*j)->getLanes();
00087         for (std::vector<MSLane*>::const_iterator i=destLanes.begin(); i!=destLanes.end(); ++i) {
00088             (*i)->addMoveReminder(this);
00089         }
00090     }
00091     if (off) {
00092         setUserMode(true);
00093         setUserUsageProbability(0);
00094     }
00095 }
00096 
00097 
00098 MSTriggeredRerouter::~MSTriggeredRerouter() throw() {
00099 }
00100 
00101 // ------------ loading begin
00102 void
00103 MSTriggeredRerouter::myStartElement(int element,
00104                                     const SUMOSAXAttributes& attrs) throw(ProcessError) {
00105     if (element==SUMO_TAG_INTERVAL) {
00106         bool ok = true;
00107         myCurrentIntervalBegin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, 0, ok, -1);
00108         myCurrentIntervalEnd = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, 0, ok, -1);
00109     }
00110 
00111     if (element==SUMO_TAG_DEST_PROB_REROUTE__DEPRECATED&&!myHaveWarnedAboutDeprecatedDestProbReroute) {
00112         myHaveWarnedAboutDeprecatedDestProbReroute = true;
00113         WRITE_WARNING("'" + toString(SUMO_TAG_DEST_PROB_REROUTE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_DEST_PROB_REROUTE) + "'.");
00114     }
00115     if (element==SUMO_TAG_DEST_PROB_REROUTE||element==SUMO_TAG_DEST_PROB_REROUTE__DEPRECATED) {
00116         // by giving probabilities of new destinations
00117         // get the destination edge
00118         std::string dest = attrs.getStringSecure(SUMO_ATTR_ID, "");
00119         if (dest=="") {
00120             throw ProcessError("MSTriggeredRerouter " + getID() + ": No destination edge id given.");
00121         }
00122         MSEdge* to = MSEdge::dictionary(dest);
00123         if (to==0) {
00124             throw ProcessError("MSTriggeredRerouter " + getID() + ": Destination edge '" + dest + "' is not known.");
00125         }
00126         // get the probability to reroute
00127         bool ok = true;
00128         SUMOReal prob = attrs.getOptSUMORealReporting(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
00129         if (!ok) {
00130             throw ProcessError();
00131         }
00132         if (prob<0) {
00133             throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for destination '" + dest + "' is negative (must not).");
00134         }
00135         // add
00136         myCurrentEdgeProb.add(prob, to);
00137     }
00138 
00139     if (element==SUMO_TAG_CLOSING_REROUTE__DEPRECATED&&!myHaveWarnedAboutDeprecatedClosingReroute) {
00140         myHaveWarnedAboutDeprecatedClosingReroute = true;
00141         WRITE_WARNING("'" + toString(SUMO_TAG_CLOSING_REROUTE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_CLOSING_REROUTE) + "'.");
00142     }
00143     if (element==SUMO_TAG_CLOSING_REROUTE||element==SUMO_TAG_CLOSING_REROUTE) {
00144         // by closing
00145         std::string closed_id = attrs.getStringSecure(SUMO_ATTR_ID, "");
00146         if (closed_id=="") {
00147             throw ProcessError("MSTriggeredRerouter " + getID() + ": closed edge id given.");
00148         }
00149         MSEdge* closed = MSEdge::dictionary(closed_id);
00150         if (closed==0) {
00151             throw ProcessError("MSTriggeredRerouter " + getID() + ": Edge '" + closed_id + "' to close is not known.");
00152         }
00153         myCurrentClosed.push_back(closed);
00154     }
00155 
00156     if (element==SUMO_TAG_ROUTE_PROB_REROUTE__DEPRECATED&&!myHaveWarnedAboutDeprecatedRouteReroute) {
00157         myHaveWarnedAboutDeprecatedRouteReroute = true;
00158         WRITE_WARNING("'" + toString(SUMO_TAG_ROUTE_PROB_REROUTE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_ROUTE_PROB_REROUTE) + "'.");
00159     }
00160     if (element==SUMO_TAG_ROUTE_PROB_REROUTE||element==SUMO_TAG_ROUTE_PROB_REROUTE__DEPRECATED) {
00161         // by explicit rerouting using routes
00162         // check if route exists
00163         std::string routeStr = attrs.getStringSecure(SUMO_ATTR_ID, "");
00164         if (routeStr=="") {
00165             throw ProcessError("MSTriggeredRerouter " + getID() + ": No route id given.");
00166         }
00167         const MSRoute* route = MSRoute::dictionary(routeStr);
00168         if (route == 0) {
00169             throw ProcessError("MSTriggeredRerouter " + getID() + ": Route '" + routeStr + "' does not exist.");
00170         }
00171 
00172         // get the probability to reroute
00173         bool ok = true;
00174         SUMOReal prob = attrs.getOptSUMORealReporting(SUMO_ATTR_PROB, getID().c_str(), ok, 1.);
00175         if (!ok) {
00176             throw ProcessError();
00177         }
00178         if (prob<0) {
00179             throw ProcessError("MSTriggeredRerouter " + getID() + ": Attribute 'probability' for route '" + routeStr + "' is negative (must not).");
00180         }
00181         // add
00182         myCurrentRouteProb.add(prob, route);
00183     }
00184 }
00185 
00186 
00187 void
00188 MSTriggeredRerouter::myEndElement(int element) throw(ProcessError) {
00189     if (element==SUMO_TAG_INTERVAL) {
00190         RerouteInterval ri;
00191         ri.begin = myCurrentIntervalBegin;
00192         ri.end = myCurrentIntervalEnd;
00193         ri.closed = myCurrentClosed;
00194         ri.edgeProbs = myCurrentEdgeProb;
00195         ri.routeProbs = myCurrentRouteProb;
00196         myCurrentClosed.clear();
00197         myCurrentEdgeProb.clear();
00198         myCurrentRouteProb.clear();
00199         myIntervals.push_back(ri);
00200     }
00201 }
00202 
00203 
00204 // ------------ loading end
00205 
00206 
00207 bool
00208 MSTriggeredRerouter::hasCurrentReroute(SUMOTime time, SUMOVehicle& veh) const {
00209     std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
00210     const MSRoute& route = veh.getRoute();
00211     while (i!=myIntervals.end()) {
00212         if ((*i).begin<=time && (*i).end>=time) {
00213             if ((*i).edgeProbs.getOverallProb()!=0||(*i).routeProbs.getOverallProb()!=0||route.containsAnyOf((*i).closed)) {
00214                 return true;
00215             }
00216         }
00217         i++;
00218     }
00219     return false;
00220 }
00221 
00222 
00223 bool
00224 MSTriggeredRerouter::hasCurrentReroute(SUMOTime time) const {
00225     std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
00226     while (i!=myIntervals.end()) {
00227         if ((*i).begin<=time && (*i).end>=time) {
00228             if ((*i).edgeProbs.getOverallProb()!=0||(*i).routeProbs.getOverallProb()!=0||(*i).closed.size()!=0) {
00229                 return true;
00230             }
00231         }
00232         i++;
00233     }
00234     return false;
00235 }
00236 
00237 
00238 const MSTriggeredRerouter::RerouteInterval&
00239 MSTriggeredRerouter::getCurrentReroute(SUMOTime time, SUMOVehicle& veh) const {
00240     std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
00241     const MSRoute& route = veh.getRoute();
00242     while (i!=myIntervals.end()) {
00243         if ((*i).begin<=time && (*i).end>=time) {
00244             if ((*i).edgeProbs.getOverallProb()!=0||(*i).routeProbs.getOverallProb()!=0||route.containsAnyOf((*i).closed)) {
00245                 return *i;
00246             }
00247         }
00248         i++;
00249     }
00250     throw 1;
00251 }
00252 
00253 
00254 const MSTriggeredRerouter::RerouteInterval&
00255 MSTriggeredRerouter::getCurrentReroute(SUMOTime) const {
00256     std::vector<RerouteInterval>::const_iterator i = myIntervals.begin();
00257     while (i!=myIntervals.end()) {
00258         if ((*i).edgeProbs.getOverallProb()!=0||(*i).routeProbs.getOverallProb()!=0||(*i).closed.size()!=0) {
00259             return *i;
00260         }
00261         i++;
00262     }
00263     throw 1;
00264 }
00265 
00266 
00267 
00268 bool
00269 MSTriggeredRerouter::notifyEnter(SUMOVehicle& veh, MSMoveReminder::Notification reason) throw() {
00270     if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
00271         return false;
00272     }
00273     // check whether the vehicle shall be rerouted
00274     SUMOTime time = MSNet::getInstance()->getCurrentTimeStep();
00275     if (!hasCurrentReroute(time, veh)) {
00276         return false;
00277     }
00278 
00279     SUMOReal prob = myAmInUserMode ? myUserProbability : myProbability;
00280     if (RandHelper::rand() > prob) {
00281         return false;
00282     }
00283 
00284     // get vehicle params
00285     const MSRoute& route = veh.getRoute();
00286     const MSEdge* lastEdge = route.getLastEdge();
00287     // get rerouting params
00288     const MSTriggeredRerouter::RerouteInterval& rerouteDef = getCurrentReroute(time, veh);
00289     const MSRoute* newRoute = rerouteDef.routeProbs.getOverallProb()>0 ? rerouteDef.routeProbs.get() : 0;
00290     // we will use the route if given rather than calling our own dijsktra...
00291     if (newRoute!=0) {
00292         veh.replaceRoute(newRoute);
00293         return false;
00294     }
00295     // ok, try using a new destination
00296     const MSEdge* newEdge = rerouteDef.edgeProbs.getOverallProb()>0 ? rerouteDef.edgeProbs.get() : route.getLastEdge();
00297     if (newEdge==0) {
00298         newEdge = lastEdge;
00299     }
00300 
00301     // we have a new destination, let's replace the vehicle route
00302     MSEdgeWeightsStorage empty;
00303     MSNet::EdgeWeightsProxi proxi(empty, MSNet::getInstance()->getWeightsStorage());
00304     DijkstraRouterTT_ByProxi<MSEdge, SUMOVehicle, prohibited_withRestrictions<MSEdge, SUMOVehicle>, MSNet::EdgeWeightsProxi> router(MSEdge::dictSize(), true, &proxi, &MSNet::EdgeWeightsProxi::getTravelTime);
00305     router.prohibit(rerouteDef.closed);
00306     std::vector<const MSEdge*> edges;
00307     router.compute(veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges);
00308     veh.replaceRouteEdges(edges);
00309     return false;
00310 }
00311 
00312 
00313 void
00314 MSTriggeredRerouter::setUserMode(bool val) {
00315     myAmInUserMode = val;
00316 }
00317 
00318 
00319 void
00320 MSTriggeredRerouter::setUserUsageProbability(SUMOReal prob) {
00321     myUserProbability = prob;
00322 }
00323 
00324 
00325 bool
00326 MSTriggeredRerouter::inUserMode() const {
00327     return myAmInUserMode;
00328 }
00329 
00330 
00331 SUMOReal
00332 MSTriggeredRerouter::getProbability() const {
00333     return myAmInUserMode ? myUserProbability : myProbability;
00334 }
00335 
00336 
00337 SUMOReal
00338 MSTriggeredRerouter::getUserProbability() const {
00339     return myUserProbability;
00340 }
00341 
00342 
00343 
00344 /****************************************************************************/
00345 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines