SUMO - Simulation of Urban MObility

MSDevice_Vehroutes.cpp

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines