00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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 <microsim/MSAbstractLaneChangeModel.h>
00034 #include <utils/common/RandHelper.h>
00035
00036
00037
00038
00039
00040 #define DELTA_IDM 4.0
00041
00042
00043
00044
00045
00046 MSCFModel_IDM::MSCFModel_IDM(const MSVehicleType* vtype,
00047 SUMOReal accel, SUMOReal decel,
00048 SUMOReal timeHeadWay, SUMOReal mingap, SUMOReal tau) throw()
00049 : MSCFModel(vtype, decel),
00050 myAccel(accel), myTimeHeadWay(timeHeadWay), myMinSpace(mingap), myTau(tau) {
00051
00052 }
00053
00054
00055 MSCFModel_IDM::~MSCFModel_IDM() throw() {}
00056
00057
00058 SUMOReal
00059 MSCFModel_IDM::moveHelper(MSVehicle * const veh, const MSLane * const lane, SUMOReal vPos) const throw() {
00060 SUMOReal oldV = veh->getSpeed();
00061 vPos = MIN2(vPos, veh->processNextStop(vPos));
00062
00063
00064
00065
00066 veh->setPreDawdleAcceleration(SPEED2ACCEL(vPos-oldV));
00067
00068 SUMOReal vNext = vPos;
00069 return
00070 veh->getLaneChangeModel().patchSpeed(
00071 MAX2((SUMOReal) 0, veh->getSpeed()-(SUMOReal)ACCEL2SPEED(myDecel)),
00072 vNext,
00073 MIN3(vNext, lane->getMaxSpeed(), maxNextSpeed(oldV)),
00074 vNext);
00075 }
00076
00077
00078 SUMOReal
00079 MSCFModel_IDM::ffeV(const MSVehicle * const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed) const throw() {
00080 return _updateSpeed(gap2pred, speed, predSpeed, desiredSpeed(veh));
00081 }
00082
00083
00084 SUMOReal
00085 MSCFModel_IDM::ffeV(const MSVehicle * const veh, SUMOReal gap2pred, SUMOReal predSpeed) const throw() {
00086 return _updateSpeed(gap2pred, veh->getSpeed(), predSpeed, desiredSpeed(veh));
00087 }
00088
00089
00090 SUMOReal
00091 MSCFModel_IDM::ffeV(const MSVehicle * const veh, const MSVehicle * const pred) const throw() {
00092 return _updateSpeed(veh->gap2pred(*pred), veh->getSpeed(), pred->getSpeed(), desiredSpeed(veh));
00093 }
00094
00095
00096 SUMOReal
00097 MSCFModel_IDM::ffeS(const MSVehicle * const veh, SUMOReal gap2pred) const throw() {
00098 SUMOReal desSpeed = desiredSpeed(veh);
00099 return _updateSpeed(gap2pred, veh->getSpeed(), desSpeed, desSpeed);
00100 }
00101
00102
00104 SUMOReal
00105 MSCFModel_IDM::interactionGap(const MSVehicle * const veh, SUMOReal vL) const throw() {
00106
00107
00108
00109 SUMOReal acc = myAccel * (1. - pow((double)(veh->getSpeed()/desiredSpeed(veh)), (double) DELTA_IDM));
00110 SUMOReal vNext = veh->getSpeed() + acc;
00111 SUMOReal gap = (vNext - vL) *
00112 ((veh->getSpeed() + vL) * myInverseTwoDecel) +
00113 vL * 1;
00114
00115
00116 return MAX2(gap, SPEED2DIST(vNext));
00117 }
00118
00119
00121 bool
00122 MSCFModel_IDM::hasSafeGap(SUMOReal speed, SUMOReal gap, SUMOReal predSpeed, SUMOReal laneMaxSpeed) const throw() {
00123 if (gap<0) {
00124 return false;
00125 }
00126 SUMOReal vSafe = _updateSpeed(speed, gap, predSpeed, laneMaxSpeed);
00127 SUMOReal vNext = MIN3(maxNextSpeed(speed), laneMaxSpeed, vSafe);
00128 return (vNext>=getSpeedAfterMaxDecel(speed) && gap >= SPEED2DIST(speed));
00129 }
00130
00131
00132 SUMOReal
00133 MSCFModel_IDM::_updateSpeed(SUMOReal gap2pred, SUMOReal mySpeed, SUMOReal predSpeed, SUMOReal desSpeed) const throw() {
00134 SUMOReal delta_v = mySpeed - predSpeed;
00135 SUMOReal s_star_raw = myMinSpace + mySpeed*myTimeHeadWay + (mySpeed*delta_v)/(2*sqrt(myAccel*myDecel));
00136 SUMOReal s_star = MAX2(s_star_raw, myMinSpace);
00137 SUMOReal acc = myAccel * (1. - pow((double)(mySpeed/desSpeed), (double) DELTA_IDM) - (s_star*s_star)/(gap2pred*gap2pred));
00138 SUMOReal vNext = mySpeed + ACCEL2SPEED(acc);
00139 return vNext;
00140 }
00141
00142
00143
00144
00145
00146