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