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 /****************************************************************************/
17 // The Intelligent Driver Model (IDM) car-following model
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include "MSCFModel_IDM.h"
27 #include <microsim/MSVehicle.h>
28 
29 //#define DEBUG_V
30 
31 // ===========================================================================
32 // method definitions
33 // ===========================================================================
34 MSCFModel_IDM::MSCFModel_IDM(const MSVehicleType* vtype, bool idmm) :
35  MSCFModel(vtype),
36  myIDMM(idmm),
37  myDelta(idmm ? 4.0 : vtype->getParameter().getCFParam(SUMO_ATTR_CF_IDM_DELTA, 4.)),
38  myAdaptationFactor(idmm ? vtype->getParameter().getCFParam(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR, 1.8) : 1.0),
39  myAdaptationTime(idmm ? vtype->getParameter().getCFParam(SUMO_ATTR_CF_IDMM_ADAPT_TIME, 600.0) : 0.0),
40  myIterations(MAX2(1, int(TS / vtype->getParameter().getCFParam(SUMO_ATTR_CF_IDM_STEPPING, .25) + .5))),
41  myTwoSqrtAccelDecel(double(2 * sqrt(myAccel * myDecel))) {
42  // IDM does not drive very precise and may violate minGap on occasion
44 }
45 
47 
48 
49 double
50 MSCFModel_IDM::finalizeSpeed(MSVehicle* const veh, double vPos) const {
51  const double vNext = MSCFModel::finalizeSpeed(veh, vPos);
52  if (myAdaptationFactor != 1.) {
54  vars->levelOfService += (vNext / veh->getLane()->getVehicleMaxSpeed(veh) - vars->levelOfService) / myAdaptationTime * TS;
55  }
56  return vNext;
57 }
58 
59 
60 double
61 MSCFModel_IDM::followSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const /*pred*/) const {
62 #ifdef DEBUG_V
63  gDebugFlag1 = veh->isSelected();
64 #endif
65  return _v(veh, gap2pred, speed, predSpeed, veh->getLane()->getVehicleMaxSpeed(veh));
66 }
67 
68 
69 double
70 MSCFModel_IDM::insertionFollowSpeed(const MSVehicle* const v, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle* const /*pred*/) const {
71  // see definition of s in _v()
72  double s = MAX2(0., speed * myHeadwayTime + speed * (speed - predSpeed) / myTwoSqrtAccelDecel);
73  if (gap2pred >= s) {
74  // followSpeed always stays below speed because s*s / (gap2pred * gap2pred) > 0. This would prevent insertion with maximum speed at all distances
75  return speed;
76  } else {
77  return followSpeed(v, speed, gap2pred, predSpeed, predMaxDecel);
78  }
79 }
80 
81 
82 double
83 MSCFModel_IDM::stopSpeed(const MSVehicle* const veh, const double speed, double gap) const {
84  if (gap < 0.01) {
85  return 0;
86  }
87  double result = _v(veh, gap, speed, 0, veh->getLane()->getVehicleMaxSpeed(veh));
88  if (gap > 0 && speed < NUMERICAL_EPS && result < NUMERICAL_EPS) {
89  // ensure that stops can be reached:
90  //std::cout << " switching to krauss: " << veh->getID() << " gap=" << gap << " speed=" << speed << " res1=" << result << " res2=" << maximumSafeStopSpeed(gap, speed, false, veh->getActionStepLengthSecs())<< "\n";
91  result = maximumSafeStopSpeed(gap, speed, false, veh->getActionStepLengthSecs());
92  }
93  //if (result * TS > gap) {
94  // std::cout << "Maximum stop speed exceeded for gap=" << gap << " result=" << result << " veh=" << veh->getID() << " speed=" << speed << " t=" << SIMTIME << "\n";
95  //}
96  return result;
97 }
98 
99 
101 double
102 MSCFModel_IDM::interactionGap(const MSVehicle* const veh, double vL) const {
103  // Resolve the IDM equation to gap. Assume predecessor has
104  // speed != 0 and that vsafe will be the current speed plus acceleration,
105  // i.e that with this gap there will be no interaction.
106  const double acc = myAccel * (1. - pow(veh->getSpeed() / veh->getLane()->getVehicleMaxSpeed(veh), myDelta));
107  const double vNext = veh->getSpeed() + acc;
108  const double gap = (vNext - vL) * (veh->getSpeed() + vL) / (2 * myDecel) + vL;
109 
110  // Don't allow timeHeadWay < deltaT situations.
111  return MAX2(gap, SPEED2DIST(vNext));
112 }
113 
114 double
115 MSCFModel_IDM::getSecureGap(const double speed, const double leaderSpeed, const double /*leaderMaxDecel*/) const {
116  const double delta_v = speed - leaderSpeed;
117  return MAX2(0.0, speed * myHeadwayTime + speed * delta_v / myTwoSqrtAccelDecel);
118 }
119 
120 
121 double
122 MSCFModel_IDM::_v(const MSVehicle* const veh, const double gap2pred, const double egoSpeed,
123  const double predSpeed, const double desSpeed, const bool respectMinGap) const {
124 // this is more or less based on http://www.vwi.tu-dresden.de/~treiber/MicroApplet/IDM.html
125 // and http://arxiv.org/abs/cond-mat/0304337
126 // we assume however constant speed for the leader
127  double headwayTime = myHeadwayTime;
128  if (myAdaptationFactor != 1.) {
130  headwayTime *= myAdaptationFactor + vars->levelOfService * (1. - myAdaptationFactor);
131  }
132  double newSpeed = egoSpeed;
133  double gap = gap2pred;
134  if (respectMinGap) {
135  // gap2pred comes with minGap already subtracted so we need to add it here again
136  gap += myType->getMinGap();
137  }
138  for (int i = 0; i < myIterations; i++) {
139  const double delta_v = newSpeed - predSpeed;
140  double s = MAX2(0., newSpeed * headwayTime + newSpeed * delta_v / myTwoSqrtAccelDecel);
141  if (respectMinGap) {
142  s += myType->getMinGap();
143  }
144  gap = MAX2(NUMERICAL_EPS, gap); // avoid singularity
145  const double acc = myAccel * (1. - pow(newSpeed / desSpeed, myDelta) - (s * s) / (gap * gap));
146 #ifdef DEBUG_V
147  if (gDebugFlag1) {
148  std::cout << " gap=" << gap << " t=" << myHeadwayTime << " t2=" << headwayTime << " s=" << s << " pow=" << pow(newSpeed / desSpeed, myDelta) << " gapDecel=" << (s * s) / (gap * gap) << " a=" << acc;
149  }
150 #endif
151  newSpeed += ACCEL2SPEED(acc) / myIterations;
152 #ifdef DEBUG_V
153  if (gDebugFlag1) {
154  std::cout << " v2=" << newSpeed << "\n";
155  }
156 #endif
157  //TODO use more realistic position update which takes accelerated motion into account
158  gap -= MAX2(0., SPEED2DIST(newSpeed - predSpeed) / myIterations);
159  }
160  return MAX2(0., newSpeed);
161 }
162 
163 
164 MSCFModel*
166  return new MSCFModel_IDM(vtype, myIDMM);
167 }
MSCFModel_IDM::MSCFModel_IDM
MSCFModel_IDM(const MSVehicleType *vtype, bool idmm)
Constructor.
Definition: MSCFModel_IDM.cpp:34
MSVehicleType
The car-following model and parameter.
Definition: MSVehicleType.h:66
SPEED2DIST
#define SPEED2DIST(x)
Definition: SUMOTime.h:47
MSCFModel_IDM::myTwoSqrtAccelDecel
const double myTwoSqrtAccelDecel
A computational shortcut.
Definition: MSCFModel_IDM.h:192
SUMO_ATTR_CF_IDMM_ADAPT_FACTOR
Definition: SUMOXMLDefinitions.h:835
SUMO_ATTR_CF_IDM_STEPPING
Definition: SUMOXMLDefinitions.h:834
NUMERICAL_EPS
#define NUMERICAL_EPS
Definition: config.h:145
ACCEL2SPEED
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:53
MSCFModel_IDM::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_IDM.cpp:115
MSCFModel_IDM::myAdaptationTime
const double myAdaptationTime
The IDMM adaptation time tau.
Definition: MSCFModel_IDM.h:186
MSCFModel_IDM::myIterations
const int myIterations
The number of iterations in speed calculations.
Definition: MSCFModel_IDM.h:189
SUMO_ATTR_CF_IDM_DELTA
Definition: SUMOXMLDefinitions.h:833
MSVehicle::getCarFollowVariables
MSCFModel::VehicleVariables * getCarFollowVariables() const
Returns the vehicle's car following model variables.
Definition: MSVehicle.h:911
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
MSBaseVehicle::isSelected
virtual bool isSelected() const
whether this vehicle is selected in the GUI
Definition: MSBaseVehicle.h:463
MSVehicle.h
MSCFModel_IDM::duplicate
MSCFModel * duplicate(const MSVehicleType *vtype) const
Duplicates the car-following model.
Definition: MSCFModel_IDM.cpp:165
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:80
MSCFModel_IDM::finalizeSpeed
double finalizeSpeed(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences.
Definition: MSCFModel_IDM.cpp:50
MSCFModel_IDM::~MSCFModel_IDM
~MSCFModel_IDM()
Destructor.
Definition: MSCFModel_IDM.cpp:46
MSCFModel_IDM::myDelta
const double myDelta
The IDM delta exponent.
Definition: MSCFModel_IDM.h:180
SUMO_ATTR_COLLISION_MINGAP_FACTOR
Definition: SUMOXMLDefinitions.h:461
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
TS
#define TS
Definition: SUMOTime.h:44
MSCFModel_IDM::myAdaptationFactor
const double myAdaptationFactor
The IDMM adaptation factor beta.
Definition: MSCFModel_IDM.h:183
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::myHeadwayTime
double myHeadwayTime
The driver's desired time headway (aka reaction time tau) [s].
Definition: MSCFModel.h:628
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:70
MSVehicleType::getMinGap
double getMinGap() const
Get the free space in front of vehicles of this class.
Definition: MSVehicleType.h:126
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:61
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:406
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:83
MSVehicle::getLane
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:561
MSCFModel::myCollisionMinGapFactor
double myCollisionMinGapFactor
The factor of minGap that must be maintained to avoid a collision event.
Definition: MSCFModel.h:625
MSCFModel::myDecel
double myDecel
The vehicle's maximum deceleration [m/s^2].
Definition: MSCFModel.h:619
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:122
MSVehicleType::getParameter
const SUMOVTypeParameter & getParameter() const
Definition: MSVehicleType.h:556
MSCFModel::myType
const MSVehicleType * myType
The type to which this model definition belongs to.
Definition: MSCFModel.h:613
MSCFModel_IDM::myIDMM
const bool myIDMM
whether the model is IDMM or IDM
Definition: MSCFModel_IDM.h:177
MSCFModel
The car-following model abstraction.
Definition: MSCFModel.h:57
config.h
gDebugFlag1
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:33
MSVehicle::getSpeed
double getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:477
MSCFModel::myAccel
double myAccel
The vehicle's maximum acceleration [m/s^2].
Definition: MSCFModel.h:616
MSCFModel_IDM::VehicleVariables
Definition: MSCFModel_IDM.h:162
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:519
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:102
MSCFModel_IDM.h
MSCFModel_IDM::VehicleVariables::levelOfService
double levelOfService
state variable for remembering speed deviation history (lambda)
Definition: MSCFModel_IDM.h:166
SUMO_ATTR_CF_IDMM_ADAPT_TIME
Definition: SUMOXMLDefinitions.h:836
MSVehicle
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80