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