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.dev/sumo
3 // Copyright (C) 2011-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // The psycho-physical model of Wiedemann (10-Parameter version from 1999)
19 // references:
20 // code adapted from https://github.com/glgh/w99-demo
21 // (MIT License, Copyright (c) 2016 glgh)
22 /****************************************************************************/
23 #include <config.h>
24 
25 #include <cmath>
26 #include "MSCFModel_W99.h"
27 #include <microsim/MSVehicle.h>
28 #include <microsim/MSLane.h>
31 
32 
33 // only used by DK2008
34 #define INTERACTION_GAP 150
35 
36 // ===========================================================================
37 // DEBUG constants
38 // ===========================================================================
39 #define DEBUG_FOLLOW_SPEED
40 //#define DEBUG_COND (veh->getID() == "flow.0")
41 #define DEBUG_COND (veh->isSelected())
42 
43 // ===========================================================================
44 // static members
45 // ===========================================================================
46 
47 
48 // ===========================================================================
49 // method definitions
50 // ===========================================================================
52  MSCFModel(vtype),
53  myCC1(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC1, 1.30)),
54  myCC2(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC2, 8.00)),
55  myCC3(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC3, -12.00)),
56  myCC4(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC4, -0.25)),
57  myCC5(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC5, 0.35)),
58  myCC6(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC6, 6.00)),
59  myCC7(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC7, 0.25)),
60  myCC8(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC8, 2.00)),
61  myCC9(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC9, 1.50)) {
62  // translate some values to make them show up correctly in the gui
64  myAccel = myCC8;
65  // W99 does not drive very precise and may violate minGap on occasion
67 }
68 
69 
71 
72 
73 void
74 MSCFModel_W99::computeThresholds(double speed, double predSpeed, double leaderAccel, double rndVal,
75  double& sdxc, double& sdxo, double& sdxv) const {
76 
77  const double dv = predSpeed - speed;
78  sdxc = myType->getMinGap(); // cc0
79  if (predSpeed > 0) {
80  const double v_slower = (dv >= 0 || leaderAccel < 1) ? speed : predSpeed + dv * rndVal;
81  sdxc += myCC1 * MAX2(0.0, v_slower);
82  }
83  sdxo = sdxc + myCC2; //maximum following distance (upper limit of car-following process)
84  sdxv = sdxo + myCC3 * (dv - myCC4);
85 }
86 
87 
88 double
89 MSCFModel_W99::followSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const pred, const CalcReason /*usage*/) const {
90  const double dx = gap2pred + myType->getMinGap();
91  const double dv = predSpeed - speed;
92 
93  const double cc0 = myType->getMinGap();
94 
95  const double leaderAccel = pred != nullptr ? pred->getAcceleration() : 0;
96  const double oldAccel = veh->getAcceleration();
97 
98  const double rndVal = speed > 0 ? RandHelper::rand(veh->getRNG()) - 0.5 : 0.5;
99  double sdxc, sdxo, sdxv;
100  computeThresholds(speed, predSpeed, leaderAccel, rndVal, sdxc, sdxo, sdxv);
101 
102  const double sdv = myCC6 * dx * dx / 10000;
103  const double sdvc = speed > 0 ? myCC4 - sdv : 0; //minimum closing dv
104  const double sdvo = predSpeed > myCC5 ? sdv + myCC5 : sdv; //minimum opening dv
105 
106  double accel = 0; // resulting acceleration
107  int status = 0;
108 
109  if (dv < sdvo && dx <= sdxc) {
110  // 'Decelerate - Increase Distance';
111  accel = 0;
112  // code in addtion to w99-demo to fix collision (#10472)
113  if (dx - SPEED2DIST(speed) < myType->getMinGap() * myCollisionMinGapFactor) {
114  // prevent crashin in the next step
115  accel = -SPEED2ACCEL(speed);
116  status = 9;
117  }
118  if (predSpeed > 0) {
119  if (dv < 0) {
120  if (dx > cc0) {
121  accel = MIN2(leaderAccel + dv * dv / (cc0 - dx), 0.0);
122  status = 0;
123  } else {
124  accel = MIN2(leaderAccel + 0.5 * (dv - sdvo), 0.0);
125  status = 1;
126  }
127  }
128  if (accel > -myCC7) {
129  accel = -myCC7;
130  status = 2;
131  } else {
132  accel = MAX2(accel, -10 + 0.5 * sqrt(speed));
133  status = 3;
134  }
135  }
136 
137  } else if (dv < sdvc && dx < sdxv) {
138  // 'Decelerate - Decrease Distance';
139  accel = 0.5 * dv * dv / (sdxc - dx - 0.1);
140  status = 4;
141  // deceleration is capped by myEmergencyDecel in MSCFModel::finalizeSpeed
142  } else if (dv < sdvo && dx < sdxo) {
143  // 'Accelerate/Decelerate - Keep Distance';
144  if (oldAccel <= 0) {
145  accel = MIN2(oldAccel, -myCC7);
146  status = 5;
147  } else {
148  accel = MAX2(oldAccel, myCC7);
149  status = 6;
150  // acceleration is capped at desired speed in MSCFModel::finalizeSpeed
151  }
152  } else {
153  // 'Accelerate/Relax - Increase/Keep Speed';
154  if (dx > sdxc) {
155  //if (follower.status === 'w') {
156  // accel = cc7;
157  //} else
158  {
159  const double accelMax = myCC8 + myCC9 * MIN2(speed, 80 / 3.6) + RandHelper::rand(veh->getRNG());
160  if (dx < sdxo) {
161  accel = MIN2(dv * dv / (sdxo - dx), accelMax);
162  status = 7;
163  } else {
164  accel = accelMax;
165  status = 8;
166  }
167  }
168  // acceleration is capped at desired speed in MSCFModel::finalizeSpeed
169  }
170  }
171  double vNew = speed + ACCEL2SPEED(accel);
172 #ifdef DEBUG_FOLLOW_SPEED
173  if (DEBUG_COND) {
174  std::cout << SIMTIME << " W99::fS veh=" << veh->getID() << " pred=" << Named::getIDSecure(pred)
175  << " v=" << speed << " pV=" << predSpeed << " g=" << gap2pred
176  << " dv=" << dv << " dx=" << dx
177  << " sdxc=" << sdxc << " sdxo=" << sdxo << " sdxv=" << sdxv << " sdv=" << sdv << " sdvo=" << sdvo << " sdvc=" << sdvc
178  << " st=" << status
179  << " a=" << accel << " V=" << vNew << "\n";
180  }
181 #else
182  UNUSED_PARAMETER(status);
183 #endif
185  vNew = MAX2(0.0, vNew);
186  }
187  return vNew;
188 }
189 
190 
191 
192 double
193 MSCFModel_W99::stopSpeed(const MSVehicle* const veh, const double speed, double gap, double decel, const CalcReason /*usage*/) const {
194  // see reasoning in MSCFModel_Wiedemann::stopSpeed
195  return MIN2(maximumSafeStopSpeed(gap, decel, speed, false, veh->getActionStepLengthSecs()), maxNextSpeed(speed, veh));
196 }
197 
198 
199 double
200 MSCFModel_W99::interactionGap(const MSVehicle* const, double vL) const {
201  UNUSED_PARAMETER(vL);
202  return INTERACTION_GAP;
203 }
204 
205 
206 MSCFModel*
208  return new MSCFModel_W99(vtype);
209 }
#define INTERACTION_GAP
#define DEBUG_COND
#define SPEED2DIST(x)
Definition: SUMOTime.h:45
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:51
#define SIMTIME
Definition: SUMOTime.h:62
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:53
@ SUMO_ATTR_CF_W99_CC9
@ SUMO_ATTR_CF_W99_CC5
@ SUMO_ATTR_CF_W99_CC8
@ SUMO_ATTR_CF_W99_CC3
@ SUMO_ATTR_COLLISION_MINGAP_FACTOR
@ SUMO_ATTR_CF_W99_CC2
@ SUMO_ATTR_CF_W99_CC4
@ SUMO_ATTR_CF_W99_CC6
@ SUMO_ATTR_CF_W99_CC7
@ SUMO_ATTR_CF_W99_CC1
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:30
T MIN2(T a, T b)
Definition: StdDefs.h:76
T MAX2(T a, T b)
Definition: StdDefs.h:82
SumoRNG * getRNG() const
const double myCC8
const double myCC7
const double myCC6
MSCFModel_W99(const MSVehicleType *vtype)
Constructor.
const double myCC9
const double myCC2
double interactionGap(const MSVehicle *const, double vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
const double myCC1
const double myCC5
const double myCC3
double stopSpeed(const MSVehicle *const veh, const double speed, double gap, double decel, const CalcReason usage=CalcReason::CURRENT) const
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
void computeThresholds(double speed, double predSpeed, double leaderAccel, double rndVal, double &sdxc, double &sdxo, double &sdxv) const
~MSCFModel_W99()
Destructor.
const double myCC4
double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0, const CalcReason usage=CalcReason::CURRENT) const
Computes the vehicle's safe speed (no dawdling)
MSCFModel * duplicate(const MSVehicleType *vtype) const
Duplicates the car-following model.
The car-following model abstraction.
Definition: MSCFModel.h:55
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
Definition: MSCFModel.cpp:292
CalcReason
What the return value of stop/follow/free-Speed is used for.
Definition: MSCFModel.h:77
double myCollisionMinGapFactor
The factor of minGap that must be maintained to avoid a collision event.
Definition: MSCFModel.h:707
double maximumSafeStopSpeed(double gap, double decel, double currentSpeed, bool onInsertion=false, double headway=-1, bool relaxEmergency=true) const
Returns the maximum next velocity for stopping within gap.
Definition: MSCFModel.cpp:774
double myAccel
The vehicle's maximum acceleration [m/s^2].
Definition: MSCFModel.h:698
const MSVehicleType * myType
The type to which this model definition belongs to.
Definition: MSCFModel.h:695
double myHeadwayTime
The driver's desired time headway (aka reaction time tau) [s].
Definition: MSCFModel.h:710
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:53
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
double getActionStepLengthSecs() const
Returns the vehicle's action step length in secs, i.e. the interval between two action points.
Definition: MSVehicle.h:536
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:517
The car-following model and parameter.
Definition: MSVehicleType.h:63
double getMinGap() const
Get the free space in front of vehicles of this class.
const SUMOVTypeParameter & getParameter() const
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:67
const std::string & getID() const
Returns the id.
Definition: Named.h:74
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.cpp:94
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.