SUMO - Simulation of Urban MObility

MSBaseVehicle.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // A base class for vehicle implementations
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 // ===========================================================================
00022 // included modules
00023 // ===========================================================================
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029 
00030 #include <iostream>
00031 #include <cassert>
00032 #include <utils/common/StdDefs.h>
00033 #include <utils/common/MsgHandler.h>
00034 #include "MSVehicleType.h"
00035 #include "MSEdge.h"
00036 #include "MSLane.h"
00037 #include "MSMoveReminder.h"
00038 #include <microsim/devices/MSDevice_Vehroutes.h>
00039 #include <microsim/devices/MSDevice_Tripinfo.h>
00040 #include <microsim/devices/MSDevice_Routing.h>
00041 #include <microsim/devices/MSDevice_Person.h>
00042 #include <microsim/devices/MSDevice_HBEFA.h>
00043 #include "MSBaseVehicle.h"
00044 
00045 #ifdef CHECK_MEMORY_LEAKS
00046 #include <foreign/nvwa/debug_new.h>
00047 #endif // CHECK_MEMORY_LEAKS
00048 
00049 
00050 // ===========================================================================
00051 // method definitions
00052 // ===========================================================================
00053 MSBaseVehicle::MSBaseVehicle(SUMOVehicleParameter* pars, const MSRoute* route, const MSVehicleType* type) throw(ProcessError) :
00054     myParameter(pars),
00055     myRoute(route),
00056     myType(type),
00057     myCurrEdge(route->begin()),
00058     myIndividualMaxSpeed(0.0),
00059     myHasIndividualMaxSpeed(false),
00060     myReferenceSpeed(-1.0),
00061     myMoveReminders(0),
00062     myDeparture(-1),
00063     myArrivalPos(-1),
00064     myNumberReroutes(0) {
00065     // init devices
00066     MSDevice_Vehroutes::buildVehicleDevices(*this, myDevices);
00067     MSDevice_Tripinfo::buildVehicleDevices(*this, myDevices);
00068     MSDevice_Routing::buildVehicleDevices(*this, myDevices);
00069     MSDevice_HBEFA::buildVehicleDevices(*this, myDevices);
00070     for (std::vector< MSDevice* >::iterator dev=myDevices.begin(); dev != myDevices.end(); ++dev) {
00071         myMoveReminders.push_back(std::make_pair(*dev, 0.));
00072     }
00073     myRoute->addReference();
00074     calculateArrivalPos();
00075 }
00076 
00077 MSBaseVehicle::~MSBaseVehicle() throw() {
00078     myRoute->release();
00079     delete myParameter;
00080     for (std::vector< MSDevice* >::iterator dev=myDevices.begin(); dev != myDevices.end(); ++dev) {
00081         delete(*dev);
00082     }
00083 }
00084 
00085 
00086 const std::string&
00087 MSBaseVehicle::getID() const throw() {
00088     return myParameter->id;
00089 }
00090 
00091 
00092 const SUMOVehicleParameter&
00093 MSBaseVehicle::getParameter() const throw() {
00094     return *myParameter;
00095 }
00096 
00097 
00098 const MSRoute&
00099 MSBaseVehicle::getRoute() const throw() {
00100     return *myRoute;
00101 }
00102 
00103 
00104 const MSVehicleType&
00105 MSBaseVehicle::getVehicleType() const throw() {
00106     return *myType;
00107 }
00108 
00109 
00110 SUMOReal
00111 MSBaseVehicle::getMaxSpeed() const {
00112     if (myHasIndividualMaxSpeed) {
00113         return myIndividualMaxSpeed;
00114     }
00115     return myType->getMaxSpeed();
00116 }
00117 
00118 
00119 SUMOReal
00120 MSBaseVehicle::adaptMaxSpeed(SUMOReal referenceSpeed) {
00121     if (myType->hasSpeedDeviation() && referenceSpeed != myReferenceSpeed) {
00122         myHasIndividualMaxSpeed = true;
00123         myIndividualMaxSpeed = myType->getMaxSpeedWithDeviation(referenceSpeed);
00124         myReferenceSpeed = referenceSpeed;
00125     }
00126     if (myHasIndividualMaxSpeed) {
00127         return myIndividualMaxSpeed;
00128     }
00129     return MIN2(myType->getMaxSpeed(), referenceSpeed);
00130 }
00131 
00132 
00133 const MSEdge*
00134 MSBaseVehicle::succEdge(unsigned int nSuccs) const throw() {
00135     if (myCurrEdge + nSuccs < myRoute->end()) {
00136         return *(myCurrEdge + nSuccs);
00137     } else {
00138         return 0;
00139     }
00140 }
00141 
00142 
00143 const MSEdge*
00144 MSBaseVehicle::getEdge() const {
00145     return *myCurrEdge;
00146 }
00147 
00148 
00149 void
00150 MSBaseVehicle::reroute(SUMOTime t, SUMOAbstractRouter<MSEdge, SUMOVehicle> &router, bool withTaz) throw() {
00151     // check whether to reroute
00152     std::vector<const MSEdge*> edges;
00153     if (withTaz && MSEdge::dictionary(myParameter->fromTaz+"-source") && MSEdge::dictionary(myParameter->toTaz+"-sink")) {
00154         router.compute(MSEdge::dictionary(myParameter->fromTaz+"-source"), MSEdge::dictionary(myParameter->toTaz+"-sink"), this, t, edges);
00155         if (edges.size() >= 2) {
00156             edges.erase(edges.begin());
00157             edges.pop_back();
00158         }
00159     } else {
00160         router.compute(*myCurrEdge, myRoute->getLastEdge(), this, t, edges);
00161     }
00162     if (edges.empty()) {
00163         WRITE_WARNING("No route for vehicle '" + getID() + "' found.");
00164         return;
00165     }
00166     replaceRouteEdges(edges, withTaz);
00167 }
00168 
00169 
00170 bool
00171 MSBaseVehicle::replaceRouteEdges(const MSEdgeVector& edges, bool onInit) throw() {
00172     // build a new id, first
00173     std::string id = getID();
00174     if (id[0]!='!') {
00175         id = "!" + id;
00176     }
00177     if (myRoute->getID().find("!var#")!=std::string::npos) {
00178         id = myRoute->getID().substr(0, myRoute->getID().rfind("!var#")+4) + toString(getNumberReroutes() + 1);
00179     } else {
00180         id = id + "!var#1";
00181     }
00182     MSRoute* newRoute = new MSRoute(id, edges, 0, myRoute->getColor(), myRoute->getStops());
00183     if (!MSRoute::dictionary(id, newRoute)) {
00184         delete newRoute;
00185         return false;
00186     }
00187     if (!replaceRoute(newRoute, onInit)) {
00188         newRoute->addReference();
00189         newRoute->release();
00190         return false;
00191     }
00192     return true;
00193 }
00194 
00195 
00196 SUMOReal
00197 MSBaseVehicle::getPreDawdleAcceleration() const throw() {
00198     return 0;
00199 }
00200 
00201 
00202 void
00203 MSBaseVehicle::onDepart() throw() {
00204     myDeparture = MSNet::getInstance()->getCurrentTimeStep();
00205     MSNet::getInstance()->getVehicleControl().vehicleDeparted(*this);
00206 }
00207 
00208 
00209 SUMOTime
00210 MSBaseVehicle::getDeparture() const throw() {
00211     return myDeparture;
00212 }
00213 
00214 
00215 unsigned int
00216 MSBaseVehicle::getNumberReroutes() const throw() {
00217     return myNumberReroutes;
00218 }
00219 
00220 
00221 void
00222 MSBaseVehicle::addPerson(MSPerson* /*person*/) throw() {
00223 }
00224 
00225 bool
00226 MSBaseVehicle::isStopped() const {
00227     return false;
00228 }
00229 
00230 
00231 bool
00232 MSBaseVehicle::hasValidRoute(std::string& msg) const throw() {
00233     MSRouteIterator last = myRoute->end() - 1;
00234     // check connectivity, first
00235     for (MSRouteIterator e=myCurrEdge; e!=last; ++e) {
00236         if ((*e)->allowedLanes(**(e+1), myType->getVehicleClass())==0) {
00237             msg = "No connection between '" + (*e)->getID() + "' and '" + (*(e+1))->getID() + "'.";
00238             return false;
00239         }
00240     }
00241     last = myRoute->end();
00242     // check usable lanes, then
00243     for (MSRouteIterator e=myCurrEdge; e!=last; ++e) {
00244         if ((*e)->prohibits(this)) {
00245             msg = "Edge '" + (*e)->getID() + "' prohibits.";
00246             return false;
00247         }
00248     }
00249     return true;
00250 }
00251 
00252 
00253 void
00254 MSBaseVehicle::addReminder(MSMoveReminder* rem) throw() {
00255     myMoveReminders.push_back(std::make_pair(rem, 0.));
00256 }
00257 
00258 
00259 void
00260 MSBaseVehicle::removeReminder(MSMoveReminder* rem) throw() {
00261     for (MoveReminderCont::iterator r=myMoveReminders.begin(); r!=myMoveReminders.end(); ++r) {
00262         if (r->first == rem) {
00263             myMoveReminders.erase(r);
00264             return;
00265         }
00266     }
00267 }
00268 
00269 
00270 void
00271 MSBaseVehicle::activateReminders(const MSMoveReminder::Notification reason) throw() {
00272     for (MoveReminderCont::iterator rem=myMoveReminders.begin(); rem!=myMoveReminders.end();) {
00273         if (rem->first->notifyEnter(*this, reason)) {
00274             ++rem;
00275         } else {
00276             rem = myMoveReminders.erase(rem);
00277         }
00278     }
00279 }
00280 
00281 
00282 void
00283 MSBaseVehicle::calculateArrivalPos() throw() {
00284     const SUMOReal lastLaneLength = (myRoute->getLastEdge()->getLanes())[0]->getLength();
00285     switch (myParameter->arrivalPosProcedure) {
00286     case ARRIVAL_POS_DEFAULT:
00287     case ARRIVAL_POS_GIVEN:
00288         // Maybe we should warn the user about invalid inputs!
00289         myArrivalPos = MIN2(myParameter->arrivalPos, lastLaneLength);
00290         if (myArrivalPos < 0) {
00291             myArrivalPos = MAX2(myArrivalPos + lastLaneLength, static_cast<SUMOReal>(0));
00292         }
00293         break;
00294     case ARRIVAL_POS_RANDOM:
00295         myArrivalPos = RandHelper::rand(static_cast<SUMOReal>(0), lastLaneLength);
00296         break;
00297     case ARRIVAL_POS_MAX:
00298         myArrivalPos = lastLaneLength;
00299         break;
00300     }
00301 }
00302 
00303 
00304 /****************************************************************************/
00305 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines