Eclipse SUMO - Simulation of Urban MObility
MSCFModel_IDM.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-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 /****************************************************************************/
16 // The Intelligent Driver Model (IDM) car-following model
17 /****************************************************************************/
18 
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24 
25 #include "MSCFModel_IDM.h"
26 #include <microsim/MSVehicle.h>
27 
28 //#define DEBUG_V
29 
30 // ===========================================================================
31 // method definitions
32 // ===========================================================================
33 MSCFModel_IDM::MSCFModel_IDM(const MSVehicleType* vtype, bool idmm) :
34  MSCFModel(vtype),
35  myIDMM(idmm),
36  myDelta(idmm ? 4.0 : vtype->getParameter().getCFParam(SUMO_ATTR_CF_IDM_DELTA, 4.)),
37  myAdaptationFactor(idmm ? vtype->getParameter().getCFParam(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR, 1.8) : 1.0),
38  myAdaptationTime(idmm ? vtype->getParameter().getCFParam(SUMO_ATTR_CF_IDMM_ADAPT_TIME, 600.0) : 0.0),
39  myIterations(MAX2(1, int(TS / vtype->getParameter().getCFParam(SUMO_ATTR_CF_IDM_STEPPING, .25) + .5))),
40  myTwoSqrtAccelDecel(double(2 * sqrt(myAccel * myDecel))) {
41  // IDM does not drive very precise and may violate minGap on occasion
43 }
44 
46 
47 
48 double
49 MSCFModel_IDM::finalizeSpeed(MSVehicle* const veh, double vPos) const {
50  const double vNext = MSCFModel::finalizeSpeed(veh, vPos);
51  if (myAdaptationFactor != 1.) {
53  vars->levelOfService += (vNext / veh->getLane()->getVehicleMaxSpeed(veh) - vars->levelOfService) / myAdaptationTime * TS;
54  }
55  return vNext;
56 }
57 
58 
59 double
60 MSCFModel_IDM::freeSpeed(const MSVehicle* const veh, double speed, double seen, double maxSpeed, const bool /*onInsertion*/) const {
61  if (maxSpeed < 0.) {
62  // can occur for ballistic update (in context of driving at red light)
63  return maxSpeed;
64  }
65  const double secGap = getSecureGap(veh, nullptr, maxSpeed, 0, myDecel);
66  double vSafe;
67  if (speed <= maxSpeed) {
68  // accelerate
69  vSafe = _v(veh, 1e6, speed, maxSpeed, veh->getLane()->getVehicleMaxSpeed(veh), false);
70  } else {
71  // decelerate
72  // @note relax gap to avoid emergency braking
73  // @note since the transition point does not move we set the leader speed to 0
74  vSafe = _v(veh, MAX2(seen, secGap), speed, 0, veh->getLane()->getVehicleMaxSpeed(veh), false);
75  }
76  if (seen < secGap) {
77  // avoid overshoot when close to change in speed limit
78  vSafe = MIN2(vSafe, maxSpeed);
79  }
80  //std::cout << SIMTIME << " speed=" << speed << " maxSpeed=" << maxSpeed << " seen=" << seen << " secGap=" << secGap << " vSafe=" << vSafe << "\n";
81  return vSafe;
82 }
83 
84 
85 double
86 MSCFModel_IDM::followSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle* const pred) const {
87  applyHeadwayAndSpeedDifferencePerceptionErrors(veh, speed, gap2pred, predSpeed, predMaxDecel, pred);
88 #ifdef DEBUG_V
89  gDebugFlag1 = veh->isSelected();
90 #endif
91  return _v(veh, gap2pred, speed, predSpeed, veh->getLane()->getVehicleMaxSpeed(veh));
92 }
93 
94 
95 double
96 MSCFModel_IDM::insertionFollowSpeed(const MSVehicle* const v, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle* const /*pred*/) const {
97  // see definition of s in _v()
98  double s = MAX2(0., speed * myHeadwayTime + speed * (speed - predSpeed) / myTwoSqrtAccelDecel);
99  if (gap2pred >= s) {
100  // followSpeed always stays below speed because s*s / (gap2pred * gap2pred) > 0. This would prevent insertion with maximum speed at all distances
101  return speed;
102  } else {
103  return followSpeed(v, speed, gap2pred, predSpeed, predMaxDecel);
104  }
105 }
106 
107 
108 double
109 MSCFModel_IDM::stopSpeed(const MSVehicle* const veh, const double speed, double gap) const {
110  applyHeadwayPerceptionError(veh, speed, gap);
111  if (gap < 0.01) {
112  return 0;
113  }
114  double result = _v(veh, gap, speed, 0, veh->getLane()->getVehicleMaxSpeed(veh));
115  if (gap > 0 && speed < NUMERICAL_EPS && result < NUMERICAL_EPS) {
116  // ensure that stops can be reached:
117  //std::cout << " switching to krauss: " << veh->getID() << " gap=" << gap << " speed=" << speed << " res1=" << result << " res2=" << maximumSafeStopSpeed(gap, speed, false, veh->getActionStepLengthSecs())<< "\n";
118  result = maximumSafeStopSpeed(gap, speed, false, veh->getActionStepLengthSecs());
119  }
120  //if (result * TS > gap) {
121  // std::cout << "Maximum stop speed exceeded for gap=" << gap << " result=" << result << " veh=" << veh->getID() << " speed=" << speed << " t=" << SIMTIME << "\n";
122  //}
123  return result;
124 }
125 
126 
128 double
129 MSCFModel_IDM::interactionGap(const MSVehicle* const veh, double vL) const {
130  // Resolve the IDM equation to gap. Assume predecessor has
131  // speed != 0 and that vsafe will be the current speed plus acceleration,
132  // i.e that with this gap there will be no interaction.
133  const double acc = myAccel * (1. - pow(veh->getSpeed() / veh->getLane()->getVehicleMaxSpeed(veh), myDelta));
134  const double vNext = veh->getSpeed() + acc;
135  const double gap = (vNext - vL) * (veh->getSpeed() + vL) / (2 * myDecel) + vL;
136 
137  // Don't allow timeHeadWay < deltaT situations.
138  return MAX2(gap, SPEED2DIST(vNext));
139 }
140 
141 double
142 MSCFModel_IDM::getSecureGap(const MSVehicle* const /*veh*/, const MSVehicle* const /*pred*/, const double speed, const double leaderSpeed, const double /*leaderMaxDecel*/) const {
143  const double delta_v = speed - leaderSpeed;
144  return MAX2(0.0, speed * myHeadwayTime + speed * delta_v / myTwoSqrtAccelDecel);
145 }
146 
147 
148 double
149 MSCFModel_IDM::_v(const MSVehicle* const veh, const double gap2pred, const double egoSpeed,
150  const double predSpeed, const double desSpeed, const bool respectMinGap) const {
151 // this is more or less based on http://www.vwi.tu-dresden.de/~treiber/MicroApplet/IDM.html
152 // and http://arxiv.org/abs/cond-mat/0304337
153 // we assume however constant speed for the leader
154  double headwayTime = myHeadwayTime;
155  if (myAdaptationFactor != 1.) {
157  headwayTime *= myAdaptationFactor + vars->levelOfService * (1. - myAdaptationFactor);
158  }
159  double newSpeed = egoSpeed;
160  double gap = gap2pred;
161  if (respectMinGap) {
162  // gap2pred comes with minGap already subtracted so we need to add it here again
163  gap += myType->getMinGap();
164  }
165  for (int i = 0; i < myIterations; i++) {
166  const double delta_v = newSpeed - predSpeed;
167  double s = MAX2(0., newSpeed * headwayTime + newSpeed * delta_v / myTwoSqrtAccelDecel);
168  if (respectMinGap) {
169  s += myType->getMinGap();
170  }
171  gap = MAX2(NUMERICAL_EPS, gap); // avoid singularity
172  const double acc = myAccel * (1. - pow(newSpeed / desSpeed, myDelta) - (s * s) / (gap * gap));
173 #ifdef DEBUG_V
174  if (gDebugFlag1) {
175  std::cout << " gap=" << gap << " t=" << myHeadwayTime << " t2=" << headwayTime << " s=" << s << " pow=" << pow(newSpeed / desSpeed, myDelta) << " gapDecel=" << (s * s) / (gap * gap) << " a=" << acc;
176  }
177 #endif
178  newSpeed += ACCEL2SPEED(acc) / myIterations;
179 #ifdef DEBUG_V
180  if (gDebugFlag1) {
181  std::cout << " v2=" << newSpeed << "\n";
182  }
183 #endif
184  //TODO use more realistic position update which takes accelerated motion into account
185  gap -= MAX2(0., SPEED2DIST(newSpeed - predSpeed) / myIterations);
186  }
187  return MAX2(0., newSpeed);
188 }
189 
190 
191 MSCFModel*
193  return new MSCFModel_IDM(vtype, myIDMM);
194 }
MSCFModel_IDM::MSCFModel_IDM
MSCFModel_IDM(const MSVehicleType *vtype, bool idmm)
Constructor.
Definition: MSCFModel_IDM.cpp:33
MSVehicleType
The car-following model and parameter.
Definition: MSVehicleType.h:65
SPEED2DIST
#define SPEED2DIST(x)
Definition: SUMOTime.h:46
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:73
MSCFModel_IDM::myTwoSqrtAccelDecel
const double myTwoSqrtAccelDecel
A computational shortcut.
Definition: MSCFModel_IDM.h:207
SUMO_ATTR_CF_IDMM_ADAPT_FACTOR
@ SUMO_ATTR_CF_IDMM_ADAPT_FACTOR
Definition: SUMOXMLDefinitions.h:838
SUMO_ATTR_CF_IDM_STEPPING
@ SUMO_ATTR_CF_IDM_STEPPING
Definition: SUMOXMLDefinitions.h:837
NUMERICAL_EPS
#define NUMERICAL_EPS
Definition: config.h:148
ACCEL2SPEED
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:52
MSCFModel::applyHeadwayAndSpeedDifferencePerceptionErrors
void applyHeadwayAndSpeedDifferencePerceptionErrors(const MSVehicle *const veh, double speed, double &gap, double &predSpeed, double predMaxDecel, const MSVehicle *const pred) const
Overwrites gap2pred and predSpeed by the perceived values obtained from the vehicle's driver state,...
Definition: MSCFModel.cpp:982
MSCFModel_IDM::getSecureGap
double getSecureGap(const MSVehicle *const veh, const MSVehicle *const pred, 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_IDM.cpp:142
MSCFModel_IDM::myAdaptationTime
const double myAdaptationTime
The IDMM adaptation time tau.
Definition: MSCFModel_IDM.h:201
MSCFModel_IDM::myIterations
const int myIterations
The number of iterations in speed calculations.
Definition: MSCFModel_IDM.h:204
SUMO_ATTR_CF_IDM_DELTA
@ SUMO_ATTR_CF_IDM_DELTA
Definition: SUMOXMLDefinitions.h:836
MSVehicle::getCarFollowVariables
MSCFModel::VehicleVariables * getCarFollowVariables() const
Returns the vehicle's car following model variables.
Definition: MSVehicle.h:910
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:164
MSBaseVehicle::isSelected
virtual bool isSelected() const
whether this vehicle is selected in the GUI
Definition: MSBaseVehicle.h:479
MSVehicle.h
MSCFModel_IDM::duplicate
MSCFModel * duplicate(const MSVehicleType *vtype) const
Duplicates the car-following model.
Definition: MSCFModel_IDM.cpp:192
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:79
MSCFModel_IDM::finalizeSpeed
double finalizeSpeed(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences.
Definition: MSCFModel_IDM.cpp:49
MSCFModel_IDM::~MSCFModel_IDM
~MSCFModel_IDM()
Destructor.
Definition: MSCFModel_IDM.cpp:45
MSCFModel_IDM::myDelta
const double myDelta
The IDM delta exponent.
Definition: MSCFModel_IDM.h:195
SUMO_ATTR_COLLISION_MINGAP_FACTOR
@ SUMO_ATTR_COLLISION_MINGAP_FACTOR
Definition: SUMOXMLDefinitions.h:459
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:512
TS
#define TS
Definition: SUMOTime.h:43
MSCFModel_IDM::myAdaptationFactor
const double myAdaptationFactor
The IDMM adaptation factor beta.
Definition: MSCFModel_IDM.h:198
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:711
MSCFModel::myHeadwayTime
double myHeadwayTime
The driver's desired time headway (aka reaction time tau) [s].
Definition: MSCFModel.h:629
MSCFModel_IDM::insertionFollowSpeed
double insertionFollowSpeed(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) This method is used during the insertion stage....
Definition: MSCFModel_IDM.cpp:96
MSVehicleType::getMinGap
double getMinGap() const
Get the free space in front of vehicles of this class.
Definition: MSVehicleType.h:125
MSCFModel_IDM::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_IDM.cpp:86
SUMOVTypeParameter::getCFParam
double getCFParam(const SumoXMLAttr attr, const double defaultValue) const
Returns the named value from the map, or the default if it is not contained there.
Definition: SUMOVTypeParameter.cpp:458
MSCFModel_IDM::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_IDM.cpp:109
MSVehicle::getLane
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:560
MSCFModel::myCollisionMinGapFactor
double myCollisionMinGapFactor
The factor of minGap that must be maintained to avoid a collision event.
Definition: MSCFModel.h:626
MSCFModel::myDecel
double myDecel
The vehicle's maximum deceleration [m/s^2].
Definition: MSCFModel.h:620
MSCFModel_IDM::_v
double _v(const MSVehicle *const veh, const double gap2pred, const double mySpeed, const double predSpeed, const double desSpeed, const bool respectMinGap=true) const
Definition: MSCFModel_IDM.cpp:149
MSCFModel_IDM::freeSpeed
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.
Definition: MSCFModel_IDM.cpp:60
MSVehicleType::getParameter
const SUMOVTypeParameter & getParameter() const
Definition: MSVehicleType.h:560
MSCFModel::myType
const MSVehicleType * myType
The type to which this model definition belongs to.
Definition: MSCFModel.h:614
MSCFModel_IDM::myIDMM
const bool myIDMM
whether the model is IDMM or IDM
Definition: MSCFModel_IDM.h:192
MSCFModel
The car-following model abstraction.
Definition: MSCFModel.h:56
config.h
gDebugFlag1
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:32
MSVehicle::getSpeed
double getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:476
MSCFModel::myAccel
double myAccel
The vehicle's maximum acceleration [m/s^2].
Definition: MSCFModel.h:617
MSCFModel_IDM::VehicleVariables
Definition: MSCFModel_IDM.h:177
MSLane::getVehicleMaxSpeed
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
Definition: MSLane.h:518
MSCFModel_IDM::interactionGap
double interactionGap(const MSVehicle *const, double vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
Definition: MSCFModel_IDM.cpp:129
MSCFModel::applyHeadwayPerceptionError
void applyHeadwayPerceptionError(const MSVehicle *const veh, double speed, double &gap) const
Overwrites gap by the perceived value obtained from the vehicle's driver state.
Definition: MSCFModel.cpp:1018
MSCFModel_IDM.h
MSCFModel_IDM::VehicleVariables::levelOfService
double levelOfService
state variable for remembering speed deviation history (lambda)
Definition: MSCFModel_IDM.h:181
SUMO_ATTR_CF_IDMM_ADAPT_TIME
@ SUMO_ATTR_CF_IDMM_ADAPT_TIME
Definition: SUMOXMLDefinitions.h:839
MSVehicle
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:79