|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00009 // A device which collects info on the vehicle trip 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 // included modules 00025 // =========================================================================== 00026 #ifdef _MSC_VER 00027 #include <windows_config.h> 00028 #else 00029 #include <config.h> 00030 #endif 00031 00032 #include <microsim/MSNet.h> 00033 #include <microsim/MSLane.h> 00034 #include <utils/options/OptionsCont.h> 00035 #include <utils/iodevices/OutputDevice_String.h> 00036 #include "MSDevice_Vehroutes.h" 00037 00038 #ifdef CHECK_MEMORY_LEAKS 00039 #include <foreign/nvwa/debug_new.h> 00040 #endif // CHECK_MEMORY_LEAKS 00041 00042 00043 // =========================================================================== 00044 // static member variables 00045 // =========================================================================== 00046 bool MSDevice_Vehroutes::mySaveExits = false; 00047 bool MSDevice_Vehroutes::myLastRouteOnly = false; 00048 bool MSDevice_Vehroutes::mySorted = false; 00049 bool MSDevice_Vehroutes::myWithTaz = false; 00050 MSDevice_Vehroutes::StateListener MSDevice_Vehroutes::myStateListener; 00051 std::map<const SUMOTime, int> MSDevice_Vehroutes::myDepartureCounts; 00052 std::map<const SUMOTime, std::string> MSDevice_Vehroutes::myRouteInfos; 00053 00054 00055 // =========================================================================== 00056 // method definitions 00057 // =========================================================================== 00058 // --------------------------------------------------------------------------- 00059 // static initialisation methods 00060 // --------------------------------------------------------------------------- 00061 void 00062 MSDevice_Vehroutes::init() { 00063 if (OptionsCont::getOptions().isSet("vehroute-output")) { 00064 OutputDevice::createDeviceByOption("vehroute-output", "routes"); 00065 mySaveExits = OptionsCont::getOptions().getBool("vehroute-output.exit-times"); 00066 myLastRouteOnly = OptionsCont::getOptions().getBool("vehroute-output.last-route"); 00067 mySorted = OptionsCont::getOptions().getBool("vehroute-output.sorted"); 00068 myWithTaz = OptionsCont::getOptions().getBool("device.rerouting.with-taz"); 00069 MSNet::getInstance()->addVehicleStateListener(&myStateListener); 00070 } 00071 } 00072 00073 00074 MSDevice_Vehroutes* 00075 MSDevice_Vehroutes::buildVehicleDevices(SUMOVehicle& v, std::vector<MSDevice*> &into, unsigned int maxRoutes) { 00076 if (maxRoutes < INT_MAX) { 00077 return new MSDevice_Vehroutes(v, "vehroute_" + v.getID(), maxRoutes); 00078 } 00079 if (OptionsCont::getOptions().isSet("vehroute-output")) { 00080 if (myLastRouteOnly) { 00081 maxRoutes = 0; 00082 } 00083 myStateListener.myDevices[&v] = new MSDevice_Vehroutes(v, "vehroute_" + v.getID(), maxRoutes); 00084 into.push_back(myStateListener.myDevices[&v]); 00085 return myStateListener.myDevices[&v]; 00086 } 00087 return 0; 00088 } 00089 00090 00091 // --------------------------------------------------------------------------- 00092 // MSDevice_Vehroutes::StateListener-methods 00093 // --------------------------------------------------------------------------- 00094 void 00095 MSDevice_Vehroutes::StateListener::vehicleStateChanged(const SUMOVehicle* const vehicle, MSNet::VehicleState to) { 00096 if (to == MSNet::VEHICLE_STATE_NEWROUTE) { 00097 myDevices[vehicle]->addRoute(); 00098 } 00099 } 00100 00101 00102 // --------------------------------------------------------------------------- 00103 // MSDevice_Vehroutes-methods 00104 // --------------------------------------------------------------------------- 00105 MSDevice_Vehroutes::MSDevice_Vehroutes(SUMOVehicle& holder, const std::string& id, unsigned int maxRoutes) 00106 : MSDevice(holder, id), myCurrentRoute(&holder.getRoute()), myMaxRoutes(maxRoutes), myLastSavedAt(0) { 00107 myCurrentRoute->addReference(); 00108 } 00109 00110 00111 MSDevice_Vehroutes::~MSDevice_Vehroutes() { 00112 for (std::vector<RouteReplaceInfo>::iterator i = myReplacedRoutes.begin(); i != myReplacedRoutes.end(); ++i) { 00113 (*i).route->release(); 00114 } 00115 myCurrentRoute->release(); 00116 myStateListener.myDevices.erase(&myHolder); 00117 } 00118 00119 00120 bool 00121 MSDevice_Vehroutes::notifyEnter(SUMOVehicle& veh, MSMoveReminder::Notification reason) { 00122 if (mySorted && reason == NOTIFICATION_DEPARTED && myStateListener.myDevices[&veh] == this) { 00123 myDepartureCounts[MSNet::getInstance()->getCurrentTimeStep()]++; 00124 } 00125 return mySaveExits; 00126 } 00127 00128 00129 bool 00130 MSDevice_Vehroutes::notifyLeave(SUMOVehicle& veh, SUMOReal /*lastPos*/, MSMoveReminder::Notification reason) { 00131 if (mySaveExits && reason != NOTIFICATION_LANE_CHANGE) { 00132 if (reason != NOTIFICATION_TELEPORT && myLastSavedAt == veh.getEdge()) { // need to check this for internal lanes 00133 myExits.back() = MSNet::getInstance()->getCurrentTimeStep(); 00134 } else { 00135 myExits.push_back(MSNet::getInstance()->getCurrentTimeStep()); 00136 myLastSavedAt = veh.getEdge(); 00137 } 00138 } 00139 return mySaveExits; 00140 } 00141 00142 00143 void 00144 MSDevice_Vehroutes::writeXMLRoute(OutputDevice& os, int index) const { 00145 // check if a previous route shall be written 00146 os.openTag("route"); 00147 if (index >= 0) { 00148 assert((int) myReplacedRoutes.size() > index); 00149 // write edge on which the vehicle was when the route was valid 00150 os << " replacedOnEdge=\""; 00151 if (myReplacedRoutes[index].edge) { 00152 os << myReplacedRoutes[index].edge->getID(); 00153 } 00154 // write the time at which the route was replaced 00155 os << "\" replacedAtTime=\"" << time2string(myReplacedRoutes[index].time) << "\" probability=\"0\" edges=\""; 00156 // get the route 00157 int i = index; 00158 while (i > 0 && myReplacedRoutes[i - 1].edge) { 00159 i--; 00160 } 00161 const MSEdge* lastEdge = 0; 00162 for (; i < index; ++i) { 00163 myReplacedRoutes[i].route->writeEdgeIDs(os, lastEdge, myReplacedRoutes[i].edge); 00164 lastEdge = myReplacedRoutes[i].edge; 00165 } 00166 myReplacedRoutes[index].route->writeEdgeIDs(os, lastEdge); 00167 } else { 00168 os << " edges=\""; 00169 const MSEdge* lastEdge = 0; 00170 if (myHolder.getNumberReroutes() > 0) { 00171 assert(myReplacedRoutes.size() <= myHolder.getNumberReroutes()); 00172 unsigned int i = static_cast<unsigned int>(myReplacedRoutes.size()); 00173 while (i > 0 && myReplacedRoutes[i - 1].edge) { 00174 i--; 00175 } 00176 for (; i < myReplacedRoutes.size(); ++i) { 00177 myReplacedRoutes[i].route->writeEdgeIDs(os, lastEdge, myReplacedRoutes[i].edge); 00178 lastEdge = myReplacedRoutes[i].edge; 00179 } 00180 } 00181 myCurrentRoute->writeEdgeIDs(os, lastEdge); 00182 if (mySaveExits) { 00183 os << "\" exitTimes=\""; 00184 for (std::vector<SUMOTime>::const_iterator it = myExits.begin(); it != myExits.end(); ++it) { 00185 if (it != myExits.begin()) { 00186 os << " "; 00187 } 00188 os << time2string(*it); 00189 } 00190 } 00191 } 00192 (os << "\"").closeTag(true); 00193 } 00194 00195 00196 void 00197 MSDevice_Vehroutes::generateOutput() const { 00198 OutputDevice_String od(1); 00199 od.openTag("vehicle").writeAttr(SUMO_ATTR_ID, myHolder.getID()); 00200 if (myHolder.getVehicleType().getID() != DEFAULT_VTYPE_ID) { 00201 od.writeAttr(SUMO_ATTR_TYPE, myHolder.getVehicleType().getID()); 00202 } 00203 od.writeAttr(SUMO_ATTR_DEPART, time2string(myHolder.getDeparture())); 00204 od.writeAttr("arrival", time2string(MSNet::getInstance()->getCurrentTimeStep())); 00205 if (myWithTaz) { 00206 od.writeAttr(SUMO_ATTR_FROM_TAZ, myHolder.getParameter().fromTaz).writeAttr(SUMO_ATTR_TO_TAZ, myHolder.getParameter().toTaz); 00207 } 00208 od << ">\n"; 00209 if (myReplacedRoutes.size() > 0) { 00210 od.openTag("routeDistribution") << ">\n"; 00211 for (unsigned int i = 0; i < myReplacedRoutes.size(); ++i) { 00212 writeXMLRoute(od, i); 00213 } 00214 } 00215 writeXMLRoute(od); 00216 if (myReplacedRoutes.size() > 0) { 00217 od.closeTag(); 00218 } 00219 od.closeTag(); 00220 od << "\n"; 00221 if (mySorted) { 00222 myRouteInfos[myHolder.getDeparture()] += od.getString(); 00223 myDepartureCounts[myHolder.getDeparture()]--; 00224 std::map<const SUMOTime, int>::iterator it = myDepartureCounts.begin(); 00225 while (it != myDepartureCounts.end() && it->second == 0) { 00226 OutputDevice::getDeviceByOption("vehroute-output") << myRouteInfos[it->first]; 00227 myRouteInfos.erase(it->first); 00228 myDepartureCounts.erase(it); 00229 it = myDepartureCounts.begin(); 00230 } 00231 } else { 00232 OutputDevice::getDeviceByOption("vehroute-output") << od.getString(); 00233 } 00234 } 00235 00236 00237 const MSRoute* 00238 MSDevice_Vehroutes::getRoute(int index) const { 00239 return myReplacedRoutes[index].route; 00240 } 00241 00242 00243 void 00244 MSDevice_Vehroutes::addRoute() { 00245 if (myMaxRoutes > 0) { 00246 if (myHolder.getDeparture() >= 0) { 00247 myReplacedRoutes.push_back(RouteReplaceInfo(myHolder.getEdge(), MSNet::getInstance()->getCurrentTimeStep(), myCurrentRoute)); 00248 } else { 00249 myReplacedRoutes.push_back(RouteReplaceInfo(0, MSNet::getInstance()->getCurrentTimeStep(), myCurrentRoute)); 00250 } 00251 if (myReplacedRoutes.size() > myMaxRoutes) { 00252 myReplacedRoutes.front().route->release(); 00253 myReplacedRoutes.erase(myReplacedRoutes.begin()); 00254 } 00255 } else { 00256 myCurrentRoute->release(); 00257 } 00258 myCurrentRoute = &myHolder.getRoute(); 00259 myCurrentRoute->addReference(); 00260 } 00261 00262 00263 /****************************************************************************/ 00264