|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // The Intelligent Driver Model (IDM) car-following model 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 "MSCFModel_IDM.h" 00031 #include <microsim/MSVehicle.h> 00032 #include <microsim/MSLane.h> 00033 #include <utils/common/RandHelper.h> 00034 #include <utils/common/SUMOTime.h> 00035 00036 00037 // =========================================================================== 00038 // method definitions 00039 // =========================================================================== 00040 MSCFModel_IDM::MSCFModel_IDM(const MSVehicleType* vtype, 00041 SUMOReal accel, SUMOReal decel, 00042 SUMOReal headwayTime, SUMOReal delta, 00043 SUMOReal internalStepping) 00044 : MSCFModel(vtype, accel, decel, headwayTime), myDelta(delta), 00045 myAdaptationFactor(1.), myAdaptationTime(0.), myExpFactor(0), 00046 myTwoSqrtAccelDecel(SUMOReal(2*sqrt(accel* decel))), myIterations(MAX2(1, int(TS/internalStepping + .5))) { 00047 } 00048 00049 00050 MSCFModel_IDM::MSCFModel_IDM(const MSVehicleType* vtype, 00051 SUMOReal accel, SUMOReal decel, SUMOReal headwayTime, 00052 SUMOReal adaptationFactor, SUMOReal adaptationTime, 00053 SUMOReal internalStepping) 00054 : MSCFModel(vtype, accel, decel, headwayTime), myDelta(4.), 00055 myAdaptationFactor(adaptationFactor), myAdaptationTime(adaptationTime), myExpFactor(exp(-TS/adaptationTime)), 00056 myTwoSqrtAccelDecel(SUMOReal(2*sqrt(accel* decel))), myIterations(MAX2(1, int(TS/internalStepping + .5))) { 00057 } 00058 00059 00060 MSCFModel_IDM::~MSCFModel_IDM() {} 00061 00062 00063 SUMOReal 00064 MSCFModel_IDM::moveHelper(MSVehicle* const veh, SUMOReal vPos) const { 00065 const SUMOReal vNext = MSCFModel::moveHelper(veh, vPos); 00066 if (myExpFactor > 0.) { 00067 VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables(); 00068 vars->levelOfService *= myExpFactor; 00069 vars->levelOfService += vNext/desiredSpeed(veh) * myAdaptationTime * (1. - myExpFactor); 00070 } 00071 return vNext; 00072 } 00073 00074 00075 SUMOReal 00076 MSCFModel_IDM::followSpeed(const MSVehicle* const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed, SUMOReal /*predMaxDecel*/) const { 00077 return _v(veh, gap2pred, speed, predSpeed, desiredSpeed(veh)); 00078 } 00079 00080 00081 SUMOReal 00082 MSCFModel_IDM::stopSpeed(const MSVehicle* const veh, SUMOReal gap2pred) const { 00083 if (gap2pred<0.01) { 00084 return 0; 00085 } 00086 return _v(veh, gap2pred, veh->getSpeed(), 0, desiredSpeed(veh)); 00087 } 00088 00089 00091 SUMOReal 00092 MSCFModel_IDM::interactionGap(const MSVehicle* const veh, SUMOReal vL) const { 00093 // Resolve the IDM equation to gap. Assume predecessor has 00094 // speed != 0 and that vsafe will be the current speed plus acceleration, 00095 // i.e that with this gap there will be no interaction. 00096 SUMOReal acc = myAccel * (1. - pow(veh->getSpeed()/desiredSpeed(veh), myDelta)); 00097 SUMOReal vNext = veh->getSpeed() + acc; 00098 SUMOReal gap = (vNext - vL) * (veh->getSpeed() + vL) / (2*myDecel) + vL; 00099 00100 // Don't allow timeHeadWay < deltaT situations. 00101 return MAX2(gap, SPEED2DIST(vNext)); 00102 } 00103 00104 00105 SUMOReal 00106 MSCFModel_IDM::_v(const MSVehicle* const veh, SUMOReal gap2pred, SUMOReal egoSpeed, SUMOReal predSpeed, SUMOReal desSpeed) const { 00107 gap2pred += myType->getMinGap(); 00108 SUMOReal headwayTime = myHeadwayTime; 00109 if (myExpFactor > 0.) { 00110 const VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables(); 00111 headwayTime *= myAdaptationFactor + vars->levelOfService*(1.-myAdaptationFactor); 00112 } 00113 for (int i = 0; i < myIterations; i++) { 00114 const SUMOReal delta_v = egoSpeed - predSpeed; 00115 const SUMOReal s = myType->getMinGap() + MAX2(SUMOReal(0), egoSpeed*headwayTime + egoSpeed*delta_v/myTwoSqrtAccelDecel); 00116 const SUMOReal acc = myAccel * (1. - pow(egoSpeed / desSpeed, myDelta) - (s*s)/(gap2pred*gap2pred)); 00117 egoSpeed += ACCEL2SPEED(acc)/myIterations; 00118 gap2pred -= MAX2(SUMOReal(0), SPEED2DIST(egoSpeed - predSpeed)/myIterations); 00119 } 00120 return MAX2(SUMOReal(0), egoSpeed); 00121 } 00122 00123 00124 MSCFModel* 00125 MSCFModel_IDM::duplicate(const MSVehicleType* vtype) const { 00126 return new MSCFModel_IDM(vtype, myAccel, myDecel, myHeadwayTime, myDelta, TS/myIterations); 00127 }