SUMO - Simulation of Urban MObility
|
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