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 <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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines