Eclipse SUMO - Simulation of Urban MObility
MSCFModel_W99.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 /****************************************************************************/
14 // The psycho-physical model of Wiedemann (10-Parameter version from 1999)
15 // references:
16 // code adapted from https://github.com/glgh/w99-demo
17 // (MIT License, Copyright (c) 2016 glgh)
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <cmath>
27 #include "MSCFModel_W99.h"
28 #include <microsim/MSVehicle.h>
29 #include <microsim/MSLane.h>
32 
33 
34 // only used by DK2008
35 #define INTERACTION_GAP 150
36 
37 // ===========================================================================
38 // DEBUG constants
39 // ===========================================================================
40 #define DEBUG_FOLLOW_SPEED
41 //#define DEBUG_COND (veh->getID() == "flow.0")
42 #define DEBUG_COND (veh->isSelected())
43 
44 // ===========================================================================
45 // static members
46 // ===========================================================================
47 
48 
49 // ===========================================================================
50 // method definitions
51 // ===========================================================================
53  MSCFModel(vtype),
54  myCC1(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC1, 1.30)),
55  myCC2(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC2, 8.00)),
56  myCC3(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC3, -12.00)),
57  myCC4(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC4, -0.25)),
58  myCC5(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC5, 0.35)),
59  myCC6(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC6, 6.00)),
60  myCC7(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC7, 0.25)),
61  myCC8(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC8, 2.00)),
62  myCC9(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC9, 1.50)) {
63  // translate some values to make them show up correctly in the gui
65  myAccel = myCC8;
66  // W99 does not drive very precise and may violate minGap on occasion
68 }
69 
70 
72 
73 
74 void
75 MSCFModel_W99::computeThresholds(double speed, double predSpeed, double leaderAccel, double rndVal,
76  double& sdxc, double& sdxo, double& sdxv) const {
77 
78  const double dv = predSpeed - speed;
79  sdxc = myType->getMinGap(); // cc0
80  if (speed > 0) {
81  const double v_slower = (dv >= 0 || leaderAccel < 1) ? speed : predSpeed + dv * rndVal;
82  sdxc += myCC1 * MAX2(0.0, v_slower);
83  }
84  sdxo = sdxc + myCC2; //maximum following distance (upper limit of car-following process)
85  sdxv = sdxo + myCC3 * (dv - myCC4);
86 }
87 
88 
89 double
90 MSCFModel_W99::followSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const pred) const {
91  const double dx = gap2pred + myType->getMinGap();
92  const double dv = predSpeed - speed;
93 
94  const double cc0 = myType->getMinGap();
95 
96  const double leaderAccel = pred != nullptr ? pred->getAcceleration() : 0;
97  const double oldAccel = veh->getAcceleration();
98 
99  const double rndVal = speed > 0 ? RandHelper::rand(veh->getRNG()) - 0.5 : 0.5;
100  double sdxc, sdxo, sdxv;
101  computeThresholds(speed, predSpeed, leaderAccel, rndVal, sdxc, sdxo, sdxv);
102 
103  const double sdv = myCC6 * dx * dx / 10000;
104  const double sdvc = speed > 0 ? myCC4 - sdv : 0; //minimum closing dv
105  const double sdvo = predSpeed > myCC5 ? sdv + myCC5 : sdv; //minimum opening dv
106 
107  double accel = 0; // resulting acceleration
108  int status = 0;
109 
110  if (dv < sdvo && dx <= sdxc) {
111  // 'Decelerate - Increase Distance';
112  accel = 0;
113  if (predSpeed > 0) {
114  if (dv < 0) {
115  if (dx > cc0) {
116  accel = MIN2(leaderAccel + dv * dv / (cc0 - dx), 0.0);
117  status = 0;
118  } else {
119  accel = MIN2(leaderAccel + 0.5 * (dv - sdvo), 0.0);
120  status = 1;
121  }
122  }
123  if (accel > -myCC7) {
124  accel = -myCC7;
125  status = 2;
126  } else {
127  accel = MAX2(accel, -10 + 0.5 * sqrt(speed));
128  status = 3;
129  }
130  }
131 
132  } else if (dv < sdvc && dx < sdxv) {
133  // 'Decelerate - Decrease Distance';
134  accel = 0.5 * dv * dv / (sdxc - dx - 0.1);
135  status = 4;
136  // deceleration is capped by myEmergencyDecel in MSCFModel::finalizeSpeed
137  } else if (dv < sdvo && dx < sdxo) {
138  // 'Accelerate/Decelerate - Keep Distance';
139  if (oldAccel <= 0) {
140  accel = MIN2(oldAccel, -myCC7);
141  status = 5;
142  } else {
143  accel = MAX2(oldAccel, myCC7);
144  status = 6;
145  // acceleration is capped at desired speed in MSCFModel::finalizeSpeed
146  }
147  } else {
148  // 'Accelerate/Relax - Increase/Keep Speed';
149  if (dx > sdxc) {
150  //if (follower.status === 'w') {
151  // accel = cc7;
152  //} else
153  {
154  const double accelMax = myCC8 + myCC9 * MIN2(speed, 80 / 3.6) + RandHelper::rand(veh->getRNG());
155  if (dx < sdxo) {
156  accel = MIN2(dv * dv / (sdxo - dx), accelMax);
157  status = 7;
158  } else {
159  accel = accelMax;
160  status = 8;
161  }
162  }
163  // acceleration is capped at desired speed in MSCFModel::finalizeSpeed
164  }
165  }
166  double vNew = speed + ACCEL2SPEED(accel);
167 #ifdef DEBUG_FOLLOW_SPEED
168  if (DEBUG_COND) {
169  std::cout << SIMTIME << " W99::fS veh=" << veh->getID() << " pred=" << Named::getIDSecure(pred)
170  << " v=" << speed << " pV=" << predSpeed << " g=" << gap2pred
171  << " dv=" << dv << " dx=" << dx
172  << " sdxc=" << sdxc << " sdxo=" << sdxo << " sdxv=" << sdxv << " sdv=" << sdv << " sdvo=" << sdvo << " sdvc=" << sdvc
173  << " st=" << status
174  << " a=" << accel << " V=" << vNew << "\n";
175  }
176 #else
177  UNUSED_PARAMETER(status);
178 #endif
180  vNew = MAX2(0.0, vNew);
181  }
182  return vNew;
183 }
184 
185 
186 
187 double
188 MSCFModel_W99::stopSpeed(const MSVehicle* const veh, const double speed, double gap) const {
189  // W99 doesn't stop on point so we add some slack
190  const double vFollow = followSpeed(veh, speed, gap + sqrt(gap) + 2, 0, 4.5, 0);
191  return MIN3(vFollow, maximumSafeStopSpeed(gap, speed, false, veh->getActionStepLengthSecs()), maxNextSpeed(speed, veh));
192 }
193 
194 
195 double
196 MSCFModel_W99::interactionGap(const MSVehicle* const, double vL) const {
197  UNUSED_PARAMETER(vL);
198  return INTERACTION_GAP;
199 }
200 
201 
202 MSCFModel*
204  return new MSCFModel_W99(vtype);
205 }
206 
207 
208 double
209 MSCFModel_W99::getSecureGap(const MSVehicle* const veh, const MSVehicle* const pred, const double speed, const double leaderSpeed, const double leaderMaxDecel) const {
210  double sdxc, sdxo, sdxv;
211  computeThresholds(speed, leaderSpeed, 0, 0.5, sdxc, sdxo, sdxv);
212  return MAX2(sdxv, MSCFModel::getSecureGap(veh, pred, speed, leaderSpeed, leaderMaxDecel));
213 }
214 
215 
MSVehicleType
The car-following model and parameter.
Definition: MSVehicleType.h:65
UNUSED_PARAMETER
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:31
SUMO_ATTR_CF_W99_CC8
@ SUMO_ATTR_CF_W99_CC8
Definition: SUMOXMLDefinitions.h:850
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:73
SUMO_ATTR_CF_W99_CC2
@ SUMO_ATTR_CF_W99_CC2
Definition: SUMOXMLDefinitions.h:844
MSCFModel::maxNextSpeed
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
Definition: MSCFModel.cpp:238
ACCEL2SPEED
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:52
MSCFModel::getSecureGap
virtual double getSecureGap(const MSVehicle *const, const MSVehicle *const, 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:329
MSCFModel_W99::computeThresholds
void computeThresholds(double speed, double predSpeed, double leaderAccel, double rndVal, double &sdxc, double &sdxo, double &sdxv) const
Definition: MSCFModel_W99.cpp:75
MSCFModel_W99.h
MSCFModel_W99::myCC7
const double myCC7
Definition: MSCFModel_W99.h:146
SUMO_ATTR_CF_W99_CC1
@ SUMO_ATTR_CF_W99_CC1
Definition: SUMOXMLDefinitions.h:843
MSCFModel_W99::myCC9
const double myCC9
Definition: MSCFModel_W99.h:148
SUMO_ATTR_CF_W99_CC9
@ SUMO_ATTR_CF_W99_CC9
Definition: SUMOXMLDefinitions.h:851
MSVehicle.h
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:79
RandHelper::rand
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:53
SUMO_ATTR_CF_W99_CC7
@ SUMO_ATTR_CF_W99_CC7
Definition: SUMOXMLDefinitions.h:849
SIMTIME
#define SIMTIME
Definition: SUMOTime.h:63
SUMO_ATTR_COLLISION_MINGAP_FACTOR
@ SUMO_ATTR_COLLISION_MINGAP_FACTOR
Definition: SUMOXMLDefinitions.h:459
MSCFModel_W99::myCC2
const double myCC2
Definition: MSCFModel_W99.h:141
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
SUMO_ATTR_CF_W99_CC5
@ SUMO_ATTR_CF_W99_CC5
Definition: SUMOXMLDefinitions.h:847
MSCFModel_W99::myCC3
const double myCC3
Definition: MSCFModel_W99.h:142
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_W99::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_W99.cpp:209
MSCFModel::myHeadwayTime
double myHeadwayTime
The driver's desired time headway (aka reaction time tau) [s].
Definition: MSCFModel.h:629
MSCFModel_W99::myCC1
const double myCC1
Definition: MSCFModel_W99.h:140
MSVehicleType::getMinGap
double getMinGap() const
Get the free space in front of vehicles of this class.
Definition: MSVehicleType.h:125
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
INTERACTION_GAP
#define INTERACTION_GAP
Definition: MSCFModel_W99.cpp:35
MSCFModel_W99::duplicate
MSCFModel * duplicate(const MSVehicleType *vtype) const
Duplicates the car-following model.
Definition: MSCFModel_W99.cpp:203
MSCFModel_W99::MSCFModel_W99
MSCFModel_W99(const MSVehicleType *vtype)
Constructor.
Definition: MSCFModel_W99.cpp:52
MSCFModel_W99::myCC6
const double myCC6
Definition: MSCFModel_W99.h:145
MSCFModel::myCollisionMinGapFactor
double myCollisionMinGapFactor
The factor of minGap that must be maintained to avoid a collision event.
Definition: MSCFModel.h:626
MSCFModel_W99::interactionGap
double interactionGap(const MSVehicle *const, double vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
Definition: MSCFModel_W99.cpp:196
MSVehicleType::getParameter
const SUMOVTypeParameter & getParameter() const
Definition: MSVehicleType.h:560
MSBaseVehicle::getID
const std::string & getID() const
Returns the name of the vehicle.
Definition: MSBaseVehicle.cpp:138
DEBUG_COND
#define DEBUG_COND
Definition: MSCFModel_W99.cpp:42
MSCFModel::myType
const MSVehicleType * myType
The type to which this model definition belongs to.
Definition: MSCFModel.h:614
MSVehicle::getAcceleration
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
Definition: MSVehicle.h:493
MSCFModel
The car-following model abstraction.
Definition: MSCFModel.h:56
SUMO_ATTR_CF_W99_CC6
@ SUMO_ATTR_CF_W99_CC6
Definition: SUMOXMLDefinitions.h:848
config.h
Named::getIDSecure
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:69
RandHelper.h
MSCFModel_W99::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_W99.cpp:90
SUMO_ATTR_CF_W99_CC3
@ SUMO_ATTR_CF_W99_CC3
Definition: SUMOXMLDefinitions.h:845
MSCFModel::myAccel
double myAccel
The vehicle's maximum acceleration [m/s^2].
Definition: MSCFModel.h:617
MSLane.h
MSCFModel_W99::myCC5
const double myCC5
Definition: MSCFModel_W99.h:144
MSGlobals::gSemiImplicitEulerUpdate
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:55
MIN3
T MIN3(T a, T b, T c)
Definition: StdDefs.h:86
MSCFModel_W99::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_W99.cpp:188
MSCFModel_W99::myCC8
const double myCC8
Definition: MSCFModel_W99.h:147
MSCFModel_W99::myCC4
const double myCC4
Definition: MSCFModel_W99.h:143
MSCFModel_W99::~MSCFModel_W99
~MSCFModel_W99()
Destructor.
Definition: MSCFModel_W99.cpp:71
SUMOXMLDefinitions.h
MSBaseVehicle::getRNG
std::mt19937 * getRNG() const
Definition: MSBaseVehicle.cpp:758
SUMO_ATTR_CF_W99_CC4
@ SUMO_ATTR_CF_W99_CC4
Definition: SUMOXMLDefinitions.h:846
MSVehicle
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:79