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