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 <microsim/MSVehicle.h>
00031 #include <microsim/MSLane.h>
00032 #include "MSCFModel_Kerner.h"
00033 #include <microsim/MSAbstractLaneChangeModel.h>
00034 #include <utils/common/RandHelper.h>
00035
00036
00037
00038
00039
00040 MSCFModel_Kerner::MSCFModel_Kerner(const MSVehicleType* vtype, SUMOReal accel,
00041 SUMOReal decel, SUMOReal tau, SUMOReal k, SUMOReal phi) throw()
00042 : MSCFModel(vtype, decel), myAccel(accel), myTau(tau), myK(k), myPhi(phi) {
00043
00044 myTauDecel = decel * myTau;
00045 }
00046
00047
00048 MSCFModel_Kerner::~MSCFModel_Kerner() throw() {}
00049
00050
00051 SUMOReal
00052 MSCFModel_Kerner::moveHelper(MSVehicle * const veh, const MSLane * const lane, SUMOReal vPos) const throw() {
00053 SUMOReal oldV = veh->getSpeed();
00054 SUMOReal vSafe = MIN2(vPos, veh->processNextStop(vPos));
00055
00056
00057
00058
00059 veh->setPreDawdleAcceleration(SPEED2ACCEL(vSafe-oldV));
00060
00061 SUMOReal vNext =
00062 veh->getLaneChangeModel().patchSpeed(
00063 MAX2((SUMOReal) 0, oldV-(SUMOReal)ACCEL2SPEED(myDecel)),
00064 vSafe,
00065 MIN3(vSafe, veh->getLane().getMaxSpeed(), maxNextSpeed(oldV)),
00066 vSafe);
00067 return MIN4(vNext, vSafe, veh->getLane().getMaxSpeed(), maxNextSpeed(oldV));
00068 }
00069
00070
00071 SUMOReal
00072 MSCFModel_Kerner::ffeV(const MSVehicle * const veh, SUMOReal speed, SUMOReal gap, SUMOReal predSpeed) const throw() {
00073 return MIN2(_v(speed, maxNextSpeed(speed), gap, predSpeed), maxNextSpeed(speed));
00074 }
00075
00076
00077 SUMOReal
00078 MSCFModel_Kerner::ffeV(const MSVehicle * const veh, SUMOReal gap, SUMOReal predSpeed) const throw() {
00079 SUMOReal speed = veh->getSpeed();
00080 return MIN2(_v(speed, maxNextSpeed(speed), gap, predSpeed), maxNextSpeed(speed));
00081 }
00082
00083
00084 SUMOReal
00085 MSCFModel_Kerner::ffeV(const MSVehicle * const veh, const MSVehicle *pred) const throw() {
00086 SUMOReal speed = veh->getSpeed();
00087 return MIN2(_v(speed, maxNextSpeed(speed), veh->gap2pred(*pred), pred->getSpeed()), maxNextSpeed(speed));
00088 }
00089
00090
00091 SUMOReal
00092 MSCFModel_Kerner::ffeS(const MSVehicle * const veh, SUMOReal gap) const throw() {
00093 SUMOReal speed = veh->getSpeed();
00094 return MIN2(_v(speed, maxNextSpeed(speed), gap, 0), maxNextSpeed(speed));
00095 }
00096
00097
00098 SUMOReal
00099 MSCFModel_Kerner::interactionGap(const MSVehicle * const veh, SUMOReal vL) const throw() {
00100
00101
00102
00103 SUMOReal vNext = MIN2(maxNextSpeed(veh->getSpeed()), veh->getLane().getMaxSpeed());
00104 SUMOReal gap = (vNext - vL) *
00105 ((veh->getSpeed() + vL) * myInverseTwoDecel + myTau) +
00106 vL * myTau;
00107
00108
00109 return MAX2(gap, SPEED2DIST(vNext));
00110 }
00111
00112
00113 bool
00114 MSCFModel_Kerner::hasSafeGap(SUMOReal speed, SUMOReal gap, SUMOReal predSpeed, SUMOReal laneMaxSpeed) const throw() {
00115 if (gap<0) {
00116 return false;
00117 }
00118 SUMOReal vSafe = MIN2(_v(speed, maxNextSpeed(speed), gap, predSpeed), maxNextSpeed(speed));
00119 SUMOReal vNext = MIN3(maxNextSpeed(speed), laneMaxSpeed, vSafe);
00120 return (vNext>=getSpeedAfterMaxDecel(speed) && gap>= SPEED2DIST(speed));
00121 }
00122
00123
00124 SUMOReal
00125 MSCFModel_Kerner::_v(SUMOReal speed, SUMOReal vfree, SUMOReal gap, SUMOReal predSpeed) const throw() {
00126 if (predSpeed==0&&gap<0.01) {
00127 return 0;
00128 }
00129
00130 SUMOReal G = MAX2((SUMOReal) 0, (SUMOReal)(SPEED2DIST(myK*speed)+myPhi/myAccel*speed*(speed-predSpeed)));
00131 SUMOReal vcond = gap>G ? speed+ACCEL2SPEED(myAccel) : speed+MAX2(ACCEL2SPEED(-myDecel), MIN2(ACCEL2SPEED(myAccel), predSpeed-speed));
00132 SUMOReal vsafe = (SUMOReal)(-1. * myTauDecel + sqrt(myTauDecel*myTauDecel + (predSpeed*predSpeed) + (2. * myDecel * gap)));
00133 SUMOReal va = MAX2((SUMOReal) 0, MIN3(vfree, vsafe, vcond)) + RandHelper::rand();
00134 SUMOReal v = MAX2((SUMOReal) 0, MIN4(vfree, va, speed+ACCEL2SPEED(myAccel), vsafe));
00135 return v;
00136 }
00137
00138
00139
00140
00141