SUMO - Simulation of Urban MObility
MSCFModel_Wiedemann.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2011-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // The psycho-physical model of Wiedemann
18 // references:
19 // Andre Stebens - Traffic simulation with the Wiedemann model
20 // Werner - Integration von Fahrzeugfolge- und Fahrstreifenwechselmodellen in die Nachtfahrsimulation LucidDrive
21 // Olstam, Tapani - Comparison of Car-following models
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #include <config.h>
29 
30 #include <cmath>
31 #include "MSCFModel_Wiedemann.h"
32 #include <microsim/MSVehicle.h>
33 #include <microsim/MSLane.h>
35 
36 
37 // ===========================================================================
38 // static members
39 // ===========================================================================
40 
41 // magic constant proposed by Wiedemann (based on real world measurements)
42 const double MSCFModel_Wiedemann::D_MAX = 150;
43 
44 
45 // ===========================================================================
46 // method definitions
47 // ===========================================================================
49  MSCFModel(vtype),
50  mySecurity(vtype->getParameter().getCFParam(SUMO_ATTR_CF_WIEDEMANN_SECURITY, 0.5)),
51  myEstimation(vtype->getParameter().getCFParam(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION, 0.5)),
52  myAX(vtype->getLength() + 1. + 2. * mySecurity),
53  myCX(25. *(1. + mySecurity + myEstimation)),
54  myMinAccel(0.2 * myAccel) { // +noise?
55 }
56 
57 
59 
60 
61 double
62 MSCFModel_Wiedemann::finalizeSpeed(MSVehicle* const veh, double vPos) const {
63  const double vNext = MSCFModel::finalizeSpeed(veh, vPos);
65  vars->accelSign = vNext > veh->getSpeed() ? 1. : -1.;
66  return vNext;
67 }
68 
69 
70 double
71 MSCFModel_Wiedemann::followSpeed(const MSVehicle* const veh, double /* speed */, double gap2pred, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const /*pred*/) const {
72  return _v(veh, predSpeed, gap2pred);
73 }
74 
75 
76 double
77 MSCFModel_Wiedemann::stopSpeed(const MSVehicle* const veh, const double speed, double gap) const {
78  /* Wiedemann does not handle approaching junctions or stops very well:
79  * regime approaching() fails when dv = 0 (i.e. a vehicle inserted with speed 0 does not accelerate to reach a stop)
80  * for dv ~ 0 the standard decision tree will switch to following() which
81  * does a lousy job of closing in on a stop / junction
82  * hence we borrow from Krauss here
83  */
84  return MAX2(getSpeedAfterMaxDecel(speed), MIN2(krauss_vsafe(gap, 0), maxNextSpeed(speed, veh)));
85 }
86 
87 
88 double
89 MSCFModel_Wiedemann::interactionGap(const MSVehicle* const , double vL) const {
90  UNUSED_PARAMETER(vL);
91  return D_MAX;
92 }
93 
94 
95 MSCFModel*
97  return new MSCFModel_Wiedemann(vtype);
98 }
99 
100 
101 double
102 MSCFModel_Wiedemann::_v(const MSVehicle* veh, double predSpeed, double gap) const {
104  const double dx = gap + myType->getLength(); // wiedemann uses brutto gap
105  const double v = veh->getSpeed();
106  const double vpref = veh->getMaxSpeed();
107  const double dv = v - predSpeed;
108  // desired minimum following distance at low speed difference
109  const double bx = (1 + 7 * mySecurity) * sqrt(v); // Harding propose a factor of *.8 here
110  const double abx = myAX + bx; // Harding propose a factor of *.8 here
111  const double ex = 2 - myEstimation; // + RandHelper::randNorm(0.5, 0.15)
112  const double sdx = myAX + ex * bx;
113  const double sdv_root = (dx - myAX) / myCX;
114  const double sdv = sdv_root * sdv_root;
115  const double cldv = sdv * ex * ex;
116  const double opdv = cldv * (-1 - 2 * RandHelper::randNorm(0.5, 0.15));
117  // select the regime, get new acceleration, compute new speed based
118  double accel;
119  if (dx <= abx) {
120  accel = emergency(dv, dx);
121  } else if (dx < sdx) {
122  if (dv > cldv) {
123  accel = approaching(dv, dx, abx);
124  } else if (dv > opdv) {
125  accel = following(vars->accelSign);
126  } else {
127  accel = fullspeed(v, vpref, dx, abx);
128  }
129  } else {
130  if (dv > sdv && dx < D_MAX) { //@note other versions have an disjunction instead of conjunction
131  accel = approaching(dv, dx, abx);
132  } else {
133  accel = fullspeed(v, vpref, dx, abx);
134  }
135  }
136  // since we have hard constrainst on accel we may as well use them here
137  accel = MAX2(MIN2(accel, myAccel), -myEmergencyDecel);
138  const double vNew = MAX2(0., v + ACCEL2SPEED(accel)); // don't allow negative speeds
139  return vNew;
140 }
141 
142 
143 double
144 MSCFModel_Wiedemann::fullspeed(double v, double vpref, double dx, double abx) const {
145  // maximum acceleration is reduced with increasing speed
146  double bmax = 0.2 + 0.8 * myAccel * (7 - sqrt(v));
147  // if veh just drifted out of a 'following' process the acceleration is reduced
148  double accel = dx <= 2 * abx ? MIN2(myMinAccel, bmax * (dx - abx) / abx) : bmax;
149  if (v > vpref) {
150  accel = - accel;
151  }
152  return accel;
153 }
154 
155 
156 double
157 MSCFModel_Wiedemann::following(double sign) const {
158  return myMinAccel * sign;
159 }
160 
161 
162 double
163 MSCFModel_Wiedemann::approaching(double dv, double dx, double abx) const {
164  // there is singularity in the formula. we do the sanity check outside
165  assert(abx < dx);
166  return 0.5 * dv * dv / (abx - dx); // + predAccel at t-reaction_time if this is value is above a treshold
167 }
168 
169 
170 double
171 MSCFModel_Wiedemann::emergency(double /* dv */, double /* dx */) const {
172  /* emergency according to A.Stebens
173  // wiedemann assumes that dx will always be larger than myAX (sumo may
174  // violate this assumption when crashing (-:
175  if (dx > myAX) {
176  double accel = 0.5 * dv * dv / (myAX - dx); // + predAccel at t-reaction_time if this is value is above a treshold
177  // one would assume that in an emergency accel must be negative. However the
178  // wiedemann formula allows for accel = 0 whenever dv = 0
179  assert(accel <= 0);
180  return accel;
181  } else {
182  return = -myDecel;
183  }
184  */
185 
186  // emergency according to C.Werner
187  return -myEmergencyDecel;
188 }
189 
190 
191 
192 // XXX: This could be replaced by maximumSafeStopSpeed(), refs. #2575
193 double
194 MSCFModel_Wiedemann::krauss_vsafe(double gap, double predSpeed) const {
195  if (predSpeed == 0 && gap < 0.01) {
196  return 0;
197  }
198  const double tauDecel = myDecel * myHeadwayTime;
199  const double speedReduction = ACCEL2SPEED(myDecel);
200  const int predSteps = int(predSpeed / speedReduction);
201  const double leaderContrib = 2. * myDecel * (gap + SPEED2DIST(predSteps * predSpeed - speedReduction * predSteps * (predSteps + 1) / 2));
202  return (double)(-tauDecel + sqrt(tauDecel * tauDecel + leaderContrib));
203 }
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:79
MSCFModel::VehicleVariables * getCarFollowVariables() const
Returns the vehicle&#39;s car following model variables.
Definition: MSVehicle.h:909
const MSVehicleType * myType
The type to which this model definition belongs to.
Definition: MSCFModel.h:587
#define SPEED2DIST(x)
Definition: SUMOTime.h:48
double krauss_vsafe(double gap, double predSpeed) const
vsafe from krauss since Wiedemann is deficient at approaching
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:54
double finalizeSpeed(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences.
const double myCX
perception threshold modifier
const double mySecurity
The driver&#39;s security parameter // also &#39;ZF1&#39;.
The car-following model abstraction.
Definition: MSCFModel.h:57
double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
Definition: MSCFModel.cpp:239
double myAccel
The vehicle&#39;s maximum acceleration [m/s^2].
Definition: MSCFModel.h:590
T MAX2(T a, T b)
Definition: StdDefs.h:76
double following(double sign) const
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:33
virtual double finalizeSpeed(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences. Called at most once per simulation...
Definition: MSCFModel.cpp:165
The car-following model and parameter.
Definition: MSVehicleType.h:66
double getMaxSpeed() const
Returns the maximum speed.
double interactionGap(const MSVehicle *const, double vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
static double randNorm(double mean, double variance, std::mt19937 *rng=0)
Access to a random number from a normal distribution.
Definition: RandHelper.h:141
double _v(const MSVehicle *veh, double predSpeed, double gap) const
double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0) const
Computes the vehicle&#39;s safe speed (no dawdling)
static const double D_MAX
free-flow distance in m
double emergency(double dv, double dx) const
~MSCFModel_Wiedemann()
Destructor.
T MIN2(T a, T b)
Definition: StdDefs.h:70
virtual double getSpeedAfterMaxDecel(double v) const
Returns the velocity after maximum deceleration.
Definition: MSCFModel.h:341
double accelSign
state variable for remembering the drift direction
double myDecel
The vehicle&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:593
const double myMinAccel
The vehicle&#39;s minimum acceleration [m/s^2] // also b_null.
MSCFModel * duplicate(const MSVehicleType *vtype) const
Duplicates the car-following model.
double approaching(double dv, double dx, double abx) const
double myEmergencyDecel
The vehicle&#39;s maximum emergency deceleration [m/s^2].
Definition: MSCFModel.h:595
double getLength() const
Get vehicle&#39;s length [m].
MSCFModel_Wiedemann(const MSVehicleType *vtype)
Constructor.
const double myEstimation
The driver&#39;s estimation parameter // also &#39;ZF2&#39;.
double myHeadwayTime
The driver&#39;s desired time headway (aka reaction time tau) [s].
Definition: MSCFModel.h:602
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:483
const double myAX
the minimum front-bumper to front-bumper distance when standing
double fullspeed(double v, double vpref, double dx, double bx) const