Eclipse 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-2019 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 //#define DEBUG_V
37 
38 // ===========================================================================
39 // static members
40 // ===========================================================================
41 
42 // magic constant proposed by Wiedemann (based on real world measurements)
43 const double MSCFModel_Wiedemann::D_MAX = 150;
44 
45 
46 // ===========================================================================
47 // method definitions
48 // ===========================================================================
50  MSCFModel(vtype),
51  mySecurity(vtype->getParameter().getCFParam(SUMO_ATTR_CF_WIEDEMANN_SECURITY, 0.5)),
52  myEstimation(vtype->getParameter().getCFParam(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION, 0.5)),
53  myAX(vtype->getLength() + 1. + 2. * mySecurity),
54  myCX(25. *(1. + mySecurity + myEstimation)),
55  myMinAccel(0.2 * myAccel) { // +noise?
56 }
57 
58 
60 
61 
62 double
63 MSCFModel_Wiedemann::finalizeSpeed(MSVehicle* const veh, double vPos) const {
64  const double vNext = MSCFModel::finalizeSpeed(veh, vPos);
66  vars->accelSign = vNext > veh->getSpeed() ? 1. : -1.;
67  return vNext;
68 }
69 
70 
71 double
72 MSCFModel_Wiedemann::followSpeed(const MSVehicle* const veh, double /* speed */, double gap2pred, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const /*pred*/) const {
73  return _v(veh, predSpeed, gap2pred);
74 }
75 
76 
77 double
78 MSCFModel_Wiedemann::stopSpeed(const MSVehicle* const veh, const double speed, double gap) const {
79  /* Wiedemann does not handle approaching junctions or stops very well:
80  * regime approaching() fails when dv = 0 (i.e. a vehicle inserted with speed 0 does not accelerate to reach a stop)
81  * for dv ~ 0 the standard decision tree will switch to following() which
82  * does a lousy job of closing in on a stop / junction
83  * hence we borrow from Krauss here
84  */
85  return MIN2(maximumSafeStopSpeed(gap, speed, false, veh->getActionStepLengthSecs()), maxNextSpeed(speed, veh));
86 }
87 
88 
89 double
90 MSCFModel_Wiedemann::interactionGap(const MSVehicle* const, double vL) const {
91  UNUSED_PARAMETER(vL);
92  return D_MAX;
93 }
94 
95 
96 MSCFModel*
98  return new MSCFModel_Wiedemann(vtype);
99 }
100 
101 
102 double
103 MSCFModel_Wiedemann::getSecureGap(const double speed, const double leaderSpeed, const double leaderMaxDecel) const {
104  const double bx = (1 + 7 * mySecurity) * sqrt(speed);
105  const double abx = myAX + bx - myType->getLength(); // abx is the brutto gap
106  return MAX2(abx, MSCFModel::getSecureGap(speed, leaderSpeed, leaderMaxDecel));
107 }
108 
109 
110 double
111 MSCFModel_Wiedemann::_v(const MSVehicle* veh, double predSpeed, double gap) const {
113  const double dx = gap + myType->getLength(); // wiedemann uses brutto gap
114  const double v = veh->getSpeed();
115  const double vpref = veh->getMaxSpeed();
116  const double dv = v - predSpeed;
117  // desired minimum following distance at low speed difference
118  const double bx = (1 + 7 * mySecurity) * sqrt(v); // Harding propose a factor of *.8 here
119  const double abx = myAX + bx; // Harding propose a factor of *.8 here
120  const double ex = 2 - myEstimation; // + RandHelper::randNorm(0.5, 0.15)
121  const double sdx = myAX + ex * bx;
122  const double sdv_root = (dx - myAX) / myCX;
123  const double sdv = sdv_root * sdv_root;
124  const double cldv = sdv * ex * ex;
125  const double opdv = cldv * (-1 - 2 * RandHelper::randNorm(0.5, 0.15, veh->getRNG()));
126  // select the regime, get new acceleration, compute new speed based
127  double accel;
128  if (dx <= abx) {
129  accel = emergency(dv, dx);
130  } else if (dx < sdx) {
131  if (dv > cldv) {
132  accel = approaching(dv, dx, abx);
133  } else if (dv > opdv) {
134  accel = following(vars->accelSign);
135  } else {
136  accel = fullspeed(v, vpref, dx, abx);
137  }
138  } else {
139  if (dv > sdv && dx < D_MAX) { //@note other versions have an disjunction instead of conjunction
140  accel = approaching(dv, dx, abx);
141  } else {
142  accel = fullspeed(v, vpref, dx, abx);
143  }
144  }
145  // since we have hard constrainst on accel we may as well use them here
146  accel = MAX2(MIN2(accel, myAccel), -myEmergencyDecel);
147  const double vNew = MAX2(0., v + ACCEL2SPEED(accel)); // don't allow negative speeds
148 #ifdef DEBUG_V
149  if (veh->isSelected()) {
150  std::cout << SIMTIME << " Wiedemann::_v veh=" << veh->getID()
151  << " predSpeed=" << predSpeed << " gap=" << gap
152  << " dv=" << dv << " dx=" << dx << " ax=" << myAX << " bx=" << bx << " abx=" << abx
153  << " sdx=" << sdx << " sdv=" << sdv << " cldv=" << cldv << " opdv=" << opdv
154  << " accel=" << accel << " vNew=" << vNew << "\n";
155  }
156 #endif
157  return vNew;
158 }
159 
160 
161 double
162 MSCFModel_Wiedemann::fullspeed(double v, double vpref, double dx, double abx) const {
163  // maximum acceleration is reduced with increasing speed
164  double bmax = 0.2 + 0.8 * myAccel * (7 - sqrt(v));
165  // if veh just drifted out of a 'following' process the acceleration is reduced
166  double accel = dx <= 2 * abx ? MIN2(myMinAccel, bmax * (dx - abx) / abx) : bmax;
167  if (v > vpref) {
168  accel = - accel;
169  }
170  return accel;
171 }
172 
173 
174 double
175 MSCFModel_Wiedemann::following(double sign) const {
176  return myMinAccel * sign;
177 }
178 
179 
180 double
181 MSCFModel_Wiedemann::approaching(double dv, double dx, double abx) const {
182  // there is singularity in the formula. we do the sanity check outside
183  assert(abx < dx);
184  return 0.5 * dv * dv / (abx - dx); // + predAccel at t-reaction_time if this is value is above a treshold
185 }
186 
187 
188 double
189 MSCFModel_Wiedemann::emergency(double dv, double dx) const {
190  // wiedemann assumes that dx will always be larger than myAX (sumo may
191  // violate this assumption when crashing (-:
192  if (dx > myAX) {
193  double accel = 0.5 * dv * dv / (myAX - dx); // + predAccel at t-reaction_time if this is value is above a treshold
194  // one would assume that in an emergency accel must be negative. However the
195  // wiedemann formula allows for accel = 0 whenever dv = 0
196  assert(accel <= 0);
197  return accel;
198  } else {
199  return -myEmergencyDecel;
200  }
201 
202  // emergency according to C.Werner
203  //return -myEmergencyDecel;
204 }
MSVehicleType
The car-following model and parameter.
Definition: MSVehicleType.h:66
UNUSED_PARAMETER
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:32
SUMO_ATTR_CF_WIEDEMANN_ESTIMATION
Definition: SUMOXMLDefinitions.h:839
MSCFModel_Wiedemann::VehicleVariables
Definition: MSCFModel_Wiedemann.h:127
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:74
MSCFModel::maxNextSpeed
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
Definition: MSCFModel.cpp:239
MSCFModel_Wiedemann::finalizeSpeed
double finalizeSpeed(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences.
Definition: MSCFModel_Wiedemann.cpp:63
MSCFModel_Wiedemann::mySecurity
const double mySecurity
The driver's security parameter // also 'ZF1'.
Definition: MSCFModel_Wiedemann.h:154
MSCFModel_Wiedemann::MSCFModel_Wiedemann
MSCFModel_Wiedemann(const MSVehicleType *vtype)
Constructor.
Definition: MSCFModel_Wiedemann.cpp:49
ACCEL2SPEED
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:53
MSCFModel_Wiedemann::following
double following(double sign) const
Definition: MSCFModel_Wiedemann.cpp:175
MSCFModel_Wiedemann::fullspeed
double fullspeed(double v, double vpref, double dx, double bx) const
Definition: MSCFModel_Wiedemann.cpp:162
RandHelper::randNorm
static double randNorm(double mean, double variance, std::mt19937 *rng=0)
Access to a random number from a normal distribution.
Definition: RandHelper.h:140
MSCFModel_Wiedemann::approaching
double approaching(double dv, double dx, double abx) const
Definition: MSCFModel_Wiedemann.cpp:181
MSVehicle::getCarFollowVariables
MSCFModel::VehicleVariables * getCarFollowVariables() const
Returns the vehicle's car following model variables.
Definition: MSVehicle.h:911
MSCFModel_Wiedemann.h
MSCFModel::finalizeSpeed
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
MSCFModel_Wiedemann::followSpeed
double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0) const
Computes the vehicle's safe speed (no dawdling)
Definition: MSCFModel_Wiedemann.cpp:72
MSCFModel_Wiedemann::~MSCFModel_Wiedemann
~MSCFModel_Wiedemann()
Destructor.
Definition: MSCFModel_Wiedemann.cpp:59
MSBaseVehicle::getMaxSpeed
double getMaxSpeed() const
Returns the maximum speed.
Definition: MSBaseVehicle.cpp:154
MSBaseVehicle::isSelected
virtual bool isSelected() const
whether this vehicle is selected in the GUI
Definition: MSBaseVehicle.h:463
MSVehicle.h
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:80
MSCFModel::myEmergencyDecel
double myEmergencyDecel
The vehicle's maximum emergency deceleration [m/s^2].
Definition: MSCFModel.h:621
SIMTIME
#define SIMTIME
Definition: SUMOTime.h:64
MSCFModel_Wiedemann::VehicleVariables::accelSign
double accelSign
state variable for remembering the drift direction
Definition: MSCFModel_Wiedemann.h:131
MSCFModel_Wiedemann::_v
double _v(const MSVehicle *veh, double predSpeed, double gap) const
Definition: MSCFModel_Wiedemann.cpp:111
MSVehicle::getActionStepLengthSecs
double getActionStepLengthSecs() const
Returns the vehicle's action step length in secs, i.e. the interval between two action points.
Definition: MSVehicle.h:513
MSCFModel::maximumSafeStopSpeed
double maximumSafeStopSpeed(double gap, double currentSpeed, bool onInsertion=false, double headway=-1) const
Returns the maximum next velocity for stopping within gap.
Definition: MSCFModel.cpp:712
MSCFModel_Wiedemann::D_MAX
static const double D_MAX
free-flow distance in m
Definition: MSCFModel_Wiedemann.h:169
MSCFModel_Wiedemann::interactionGap
double interactionGap(const MSVehicle *const, double vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
Definition: MSCFModel_Wiedemann.cpp:90
MSCFModel_Wiedemann::getSecureGap
double getSecureGap(const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
Definition: MSCFModel_Wiedemann.cpp:103
MSCFModel_Wiedemann::myEstimation
const double myEstimation
The driver's estimation parameter // also 'ZF2'.
Definition: MSCFModel_Wiedemann.h:157
SUMO_ATTR_CF_WIEDEMANN_SECURITY
Definition: SUMOXMLDefinitions.h:838
MSCFModel::getSecureGap
virtual double getSecureGap(const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
Definition: MSCFModel.h:328
MSCFModel_Wiedemann::duplicate
MSCFModel * duplicate(const MSVehicleType *vtype) const
Duplicates the car-following model.
Definition: MSCFModel_Wiedemann.cpp:97
MSVehicleType::getLength
double getLength() const
Get vehicle's length [m].
Definition: MSVehicleType.h:110
MSCFModel_Wiedemann::emergency
double emergency(double dv, double dx) const
Definition: MSCFModel_Wiedemann.cpp:189
MSBaseVehicle::getID
const std::string & getID() const
Returns the name of the vehicle.
Definition: MSBaseVehicle.cpp:137
MSCFModel::myType
const MSVehicleType * myType
The type to which this model definition belongs to.
Definition: MSCFModel.h:613
MSCFModel
The car-following model abstraction.
Definition: MSCFModel.h:57
MSCFModel_Wiedemann::myAX
const double myAX
the minimum front-bumper to front-bumper distance when standing
Definition: MSCFModel_Wiedemann.h:160
config.h
MSVehicle::getSpeed
double getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:477
RandHelper.h
MSCFModel::myAccel
double myAccel
The vehicle's maximum acceleration [m/s^2].
Definition: MSCFModel.h:616
MSLane.h
MSCFModel_Wiedemann::myCX
const double myCX
perception threshold modifier
Definition: MSCFModel_Wiedemann.h:163
MSCFModel_Wiedemann::myMinAccel
const double myMinAccel
The vehicle's minimum acceleration [m/s^2] // also b_null.
Definition: MSCFModel_Wiedemann.h:166
MSCFModel_Wiedemann::stopSpeed
double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
Definition: MSCFModel_Wiedemann.cpp:78
MSBaseVehicle::getRNG
std::mt19937 * getRNG() const
Definition: MSBaseVehicle.cpp:712
MSVehicle
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80