49 double decel,
double emergencyDecel,
double apparentDecel,
double headwayTime) :
53 myEmergencyDecel(emergencyDecel),
54 myApparentDecel(apparentDecel),
55 myHeadwayTime(headwayTime) {
74 return speed * (headwayTime + 0.5 * speed / decel);
85 const int steps = int(speed / speedReduction);
86 return SPEED2DIST(steps * speed - speedReduction * steps * (steps + 1) / 2) + speed * headwayTime;
91 MSCFModel::freeSpeed(
const double currentSpeed,
const double decel,
const double dist,
const double targetSpeed,
const bool onInsertion) {
107 const double y =
MAX2(0.0, ((sqrt((b + 2.0 * v) * (b + 2.0 * v) + 8.0 * b * dist) - b) * 0.5 - v) / b);
108 const double yFull = floor(y);
109 const double exactGap = (yFull * yFull + yFull) * 0.5 * b + yFull * v + (y > yFull ? v : 0.0);
110 const double fullSpeedGain = (yFull + (onInsertion ? 1. : 0.)) *
ACCEL2SPEED(decel);
111 return DIST2SPEED(
MAX2(0.0, dist - exactGap) / (yFull + 1)) + fullSpeedGain + targetSpeed;
126 assert(currentSpeed >= 0);
127 assert(targetSpeed >= 0);
129 const double dt = onInsertion ? 0 :
TS;
130 const double v0 = currentSpeed;
131 const double vT = targetSpeed;
132 const double b = decel;
142 if (0.5 * (v0 + vT)*dt >= d) {
146 const double q = ((dt * v0 - 2 * d) * b - vT * vT);
147 const double p = 0.5 * b * dt;
148 return -p + sqrt(p * p - q);
154 const double oldV = veh->
getSpeed();
177 vNext =
MAX2(vNext, vMin);
190 const double gap = (vNext - vL) *
249 double leaderMinDist = gap2pred +
distAfterTime(duration, predSpeed, predMaxDecel);
254 int a = (int)ceil(duration /
TS -
TS);
257 if (bg <= leaderMinDist) {
261 if (
gDebugFlag2) std::cout <<
" followSpeedTransient" 262 <<
" duration=" << duration
263 <<
" gap=" << gap2pred
264 <<
" leaderMinDist=" << leaderMinDist
269 <<
" x=" << (b + leaderMinDist) / duration
271 return (b + leaderMinDist) / duration;
276 while (bg < leaderMinDist) {
285 const double fullBrakingSeconds = sqrt(leaderMinDist * 2 /
myDecel);
286 if (fullBrakingSeconds >= duration) {
290 return leaderMinDist / duration + duration *
getMaxDecel() / 2;
292 return fullBrakingSeconds *
myDecel;
300 if (speed <= decel * t) {
314 const double speed2 = speed - t * decel;
315 return 0.5 * (speed + speed2) * t;
322 const double accelTime = (arrivalSpeed - currentSpeed) / accel;
323 const double accelWay = accelTime * (arrivalSpeed + currentSpeed) * 0.5;
324 const double nonAccelWay =
MAX2(0., dist - accelWay);
328 return TIME2STEPS(accelTime + nonAccelWay / nonAccelSpeed);
341 if ((accel < 0. && -0.5 * speed * speed / accel < dist) || (accel <= 0. && speed == 0.)) {
350 double p = speed / accel;
354 return (-p - sqrt(p * p + 2 * dist / accel));
359 double t1 = (maxSpeed - speed) / accel;
361 double d1 = speed * t1 + 0.5 * accel * t1 * t1;
364 return (-p + sqrt(p * p + 2 * dist / accel));
366 return (-p + sqrt(p * p + 2 * d1 / accel)) + (dist - d1) / maxSpeed;
382 double arrivalSpeedBraking;
385 if (dist < currentSpeed) {
393 return arrivalSpeedBraking;
400 MSCFModel::gapExtrapolation(
const double duration,
const double currentGap,
double v1,
double v2,
double a1,
double a2,
const double maxV1,
const double maxV2) {
402 double newGap = currentGap;
405 for (
unsigned int steps = 1; steps *
TS <= duration; ++steps) {
406 v1 =
MIN2(
MAX2(v1 + a1, 0.), maxV1);
407 v2 =
MIN2(
MAX2(v2 + a2, 0.), maxV2);
408 newGap += TS * (v1 - v2);
413 double t1 = 0, t2 = 0, t3 = 0, t4 = 0;
416 if (a1 < 0 && v1 > 0) {
417 const double leaderStopTime = - v1 / a1;
418 t1 =
MIN2(leaderStopTime, duration);
419 }
else if (a1 >= 0) {
423 if (a2 < 0 && v2 > 0) {
424 const double followerStopTime = -v2 / a2;
425 t2 =
MIN2(followerStopTime, duration);
426 }
else if (a2 >= 0) {
430 if (a1 > 0 && v1 < maxV1) {
431 const double leaderMaxSpeedTime = (maxV1 - v1) / a1;
432 t3 =
MIN2(leaderMaxSpeedTime, duration);
433 }
else if (a1 <= 0) {
437 if (a2 > 0 && v2 < maxV2) {
438 const double followerMaxSpeedTime = (maxV2 - v2) / a2;
439 t4 =
MIN2(followerMaxSpeedTime, duration);
440 }
else if (a2 <= 0) {
452 std::list<double>::const_iterator i;
454 for (i = l.begin(); i != l.end(); ++i) {
456 double dt =
MIN2(*i, duration) - tLast;
459 newGap += dv * dt + da * dt * dt / 2.;
463 if (*i == t1 || *i == t3) {
468 if (*i == t2 || *i == t4) {
473 tLast =
MIN2(*i, duration);
474 if (tLast == duration) {
479 if (duration != tLast) {
481 assert(a1 == 0. && a2 == 0.);
482 double dt = duration - tLast;
494 MSCFModel::passingTime(
const double lastPos,
const double passedPos,
const double currentPos,
const double lastSpeed,
const double currentSpeed) {
496 assert(passedPos <= currentPos && passedPos >= lastPos && currentPos > lastPos);
497 assert(currentSpeed >= 0);
499 if (passedPos > currentPos || passedPos < lastPos) {
500 std::stringstream ss;
504 ss <<
"passingTime(): given argument passedPos = " << passedPos <<
" doesn't lie within [lastPos, currentPos] = [" << lastPos <<
", " << currentPos <<
"]\nExtrapolating...";
505 std::cout << ss.str() <<
"\n";
508 const double lastCoveredDist = currentPos - lastPos;
509 const double extrapolated = passedPos > currentPos ?
TS * (passedPos - lastPos) / lastCoveredDist :
TS * (currentPos - passedPos) / lastCoveredDist;
511 }
else if (currentSpeed < 0) {
512 WRITE_ERROR(
"passingTime(): given argument 'currentSpeed' is negative. This case is not handled yet.");
516 const double distanceOldToPassed = passedPos - lastPos;
520 const double t = distanceOldToPassed / currentSpeed;
528 if (currentSpeed > 0) {
533 assert(currentSpeed == 0 && lastSpeed != 0);
537 a = lastSpeed * lastSpeed / (2 * (lastPos - currentPos));
546 const double t = 2 * distanceOldToPassed / (lastSpeed + currentSpeed);
550 const double va = lastSpeed / a;
551 const double t = -va + sqrt(va * va + 2 * distanceOldToPassed / a);
552 assert(t < 1 && t >= 0);
556 const double va = lastSpeed / a;
557 const double t = -va - sqrt(va * va + 2 * distanceOldToPassed / a);
558 assert(t < 1 && t >= 0);
568 assert(t >= 0 && t <=
TS);
576 if (dist <
TS * v0 / 2) {
579 const double accel = - v0 * v0 / (2 * dist);
581 return v0 + accel * t;
584 const double accel = 2 * (dist /
TS - v0) /
TS;
586 return v0 + accel * t;
598 (double)sqrt(2 * dist * accel + v * v)));
622 const double g = gap;
632 const double n = floor(.5 - ((t + (sqrt(((s * s) + (4.0 * ((s * (2.0 * g / b - t)) + (t * t))))) * -0.5)) / s));
633 const double h = 0.5 * n * (n - 1) * b * s + n * b * t;
637 const double r = (g - h) / (n * s + t);
638 const double x = n * b + r;
663 const double btau =
myDecel * headway;
664 const double v0 = -btau + sqrt(btau * btau + 2 *
myDecel * g);
673 const double tau = headway;
674 const double v0 =
MAX2(0., v);
676 if (v0 * tau >= 2 * g) {
688 const double a = -v0 * v0 / (2 * g);
703 const double btau2 =
myDecel * tau / 2;
704 const double v1 = -btau2 + sqrt(btau2 * btau2 +
myDecel * (2 * g - tau * v0));
705 const double a = (v1 - v0) / tau;
static double speedAfterTime(const double t, const double oldSpeed, const double dist)
Calculates the speed after a time t [0,TS] given the initial speed and the distance traveled in an i...
Representation of a vehicle in the micro simulation.
const MSVehicleType * myType
The type to which this model definition belongs to.
virtual ~VehicleVariables()
virtual double moveHelper(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences.
virtual double interactionGap(const MSVehicle *const veh, double vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
double maximumSafeStopSpeed(double gap, double currentSpeed, bool onInsertion=false, double headway=-1) const
Returns the maximum next velocity for stopping within gap.
virtual double getHeadwayTime() const
Get the driver's desired headway [s].
double getMaxSpeed() const
Get vehicle's maximum speed [m/s].
double getMinimalArrivalSpeed(double dist, double currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance.
The car-following model and parameter.
MSAbstractLaneChangeModel & getLaneChangeModel()
SUMOTime getMinimalArrivalTime(double dist, double currentSpeed, double arrivalSpeed) const
Computes the minimal time needed to cover a distance given the desired speed at arrival.
static double distAfterTime(double t, double speed, double decel)
calculates the distance travelled after braking for time t
virtual double patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)=0
Called to adapt the speed in order to allow a lane change.
virtual double followSpeedTransient(double duration, const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const
Computes the vehicle's follow speed that avoids a collision for the given amount of time...
static double brakeGapEuler(const double speed, const double decel, const double headwayTime)
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
virtual double freeSpeed(const MSVehicle *const veh, double speed, double seen, double maxSpeed, const bool onInsertion=false) const
Computes the vehicle's safe speed without a leader.
double maximumSafeStopSpeedBallistic(double gap, double currentSpeed, bool onInsertion=false, double headway=-1) const
Returns the maximum next velocity for stopping within gap when using the ballistic positional update...
double maximumSafeStopSpeedEuler(double gap) const
Returns the maximum next velocity for stopping within gap when using the semi-implicit Euler update...
virtual double insertionFollowSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const
Computes the vehicle's safe speed (no dawdling) This method is used during the insertion stage...
double myDecel
The vehicle's maximum deceleration [m/s^2].
static double gapExtrapolation(const double duration, const double currentGap, double v1, double v2, double a1=0, double a2=0, const double maxV1=std::numeric_limits< double >::max(), const double maxV2=std::numeric_limits< double >::max())
return the resulting gap if, starting with gap currentGap, two vehicles continue with constant accele...
virtual ~MSCFModel()
Destructor.
static double passingTime(const double lastPos, const double passedPos, const double currentPos, const double lastSpeed, const double currentSpeed)
Calculates the time at which the position passedPosition has been passed In case of a ballistic updat...
double getMaxSpeedOnLane() const
Returns the maximal speed for the vehicle on its current lane (including speed factor and deviation...
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
double processNextStop(double currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
virtual double minNextSpeed(double speed, const MSVehicle *const veh=0) const
Returns the minimum speed given the current speed (depends on the numerical update scheme and its ste...
double myEmergencyDecel
The vehicle's maximum emergency deceleration [m/s^2].
double estimateSpeedAfterDistance(const double dist, const double v, const double accel) const
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
virtual double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const =0
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling) ...
MSCFModel(const MSVehicleType *vtype, double accel, double decel, double emergencyDecel, double apparentDecel, double headwayTime)
Constructor.
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
virtual double insertionStopSpeed(const MSVehicle *const veh, double speed, double gap) const
Computes the vehicle's safe speed for approaching an obstacle at insertion without constraints due to...
static bool gSemiImplicitEulerUpdate
const double INVALID_DOUBLE
double myHeadwayTime
The driver's desired time headway (aka reaction time tau) [s].
MSLane * getLane() const
Returns the lane the vehicle is on.
double maximumSafeFollowSpeed(double gap, double egoSpeed, double predSpeed, double predMaxDecel, bool onInsertion=false) const
Returns the maximum safe velocity for following the given leader.
double estimateArrivalTime(double dist, double speed, double maxSpeed, double accel) const
Computes the time needed to travel a distance dist given an initial speed and constant acceleration...
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i...
double getMinimalArrivalSpeedEuler(double dist, double currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance for Euler update...
double getSpeed() const
Returns the vehicle's current speed.