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