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