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