Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSCFModel_NaSch.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2026-2026 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 Nagel-Schreckenberg (1992) cellular automaton car-following model
19/****************************************************************************/
20#include <config.h>
21
22#include <limits>
23#include <microsim/MSVehicle.h>
24#include <microsim/MSLane.h>
25#include <microsim/MSGlobals.h>
26#include "MSCFModel_NaSch.h"
28
29// ===========================================================================
30// method definitions
31// ===========================================================================
32MSCFModel_NaSch::MSCFModel_NaSch(const MSVehicleType* vtype, double dawdle) :
33 MSCFModel(vtype),
34 myDawdle(dawdle),
35 // The classic NaSch cell length is the distance covered by accelerating
36 // for one simulation step, i.e. the "accel" attribute doubles as the
37 // cell size (in meters) when using the default step-length of 1s,
38 // see https://github.com/eclipse-sumo/sumo/issues/12182
39 myCellSpeed(ACCEL2SPEED(myAccel)) {
40}
41
42
44
45
46double
47MSCFModel_NaSch::roundToCell(double speed) const {
48 if (speed <= 0. || myCellSpeed <= 0.) {
49 return 0.;
50 }
51 return floor(speed / myCellSpeed + NUMERICAL_EPS) * myCellSpeed;
52}
53
54
55double
56MSCFModel_NaSch::vsafe(const MSVehicle* const veh, double speed, double gap) const {
57 if (gap < NUMERICAL_EPS) {
58 return 0.;
59 }
60 // NaSch rule 1 (acceleration) followed by rule 2 (slowing down): unlike the
61 // Krauss-derived models, the leader's speed does not enter the computation at
62 // all -- the gap alone caps how far ego may move this step, see issue #12182
63 // ("replace leaderSpeed with gap").
64 const double vAccel = maxNextSpeed(speed, veh);
65 const double vGapLimited = MIN2(vAccel, DIST2SPEED(gap));
66 return roundToCell(MAX2(0., vGapLimited));
67}
68
69
70double
71MSCFModel_NaSch::followSpeed(const MSVehicle* const veh, double speed, double gap2pred,
72 double /*predSpeed*/, double /*predMaxDecel*/, const MSVehicle* const /*pred*/, const CalcReason /*usage*/) const {
73 return vsafe(veh, speed, gap2pred);
74}
75
76double
77MSCFModel_NaSch::insertionFollowSpeed(const MSVehicle* const veh, double speed, double gap2pred, double /*predSpeed*/, double /*predMaxDecel*/, const MSVehicle* const /*pred*/) const {
78 return vsafe(veh, speed, gap2pred);
79}
80
81
82double
83MSCFModel_NaSch::stopSpeed(const MSVehicle* const veh, const double speed, double gap2pred, double /*decel*/, const CalcReason /*usage*/) const {
84 return vsafe(veh, speed, gap2pred);
85}
86
87
88double
89MSCFModel_NaSch::patchSpeedBeforeLC(const MSVehicle* veh, double vMin, double vMax) const {
90 // NaSch rule 3 (randomization): with probability sigma, dawdle by exactly
91 // one cell -- not a continuously distributed amount as in the Krauss dawdle.
92 if (vMax > 0. && myDawdle > 0. && RandHelper::rand(veh->getRNG()) < myDawdle) {
93 return MAX2(vMin, roundToCell(vMax - myCellSpeed));
94 }
95 return vMax;
96}
97
98
99double
100MSCFModel_NaSch::minNextSpeedEmergency(double /*speed*/, const MSVehicle* const /*veh*/) const {
101 // NaSch rule 4 (movement) permits vehicles to stop dead within a single
102 // step whenever the gap requires it, i.e. emergency deceleration is not
103 // bounded, see issue #12182 ("do not bound emergency decel").
105 return 0.;
106 }
107 return -std::numeric_limits<double>::max();
108}
109
110
113 return new MSCFModel_NaSch(vtype, myDawdle);
114}
115
116
117/****************************************************************************/
#define ACCEL2SPEED(x)
Definition SUMOTime.h:54
#define DIST2SPEED(x)
Definition SUMOTime.h:50
T MIN2(T a, T b)
Definition StdDefs.h:80
T MAX2(T a, T b)
Definition StdDefs.h:86
SumoRNG * getRNG() const
The Nagel-Schreckenberg (1992) cellular automaton car-following model.
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)
double myDawdle
The probability of randomized deceleration by one cell per step ("sigma")
double patchSpeedBeforeLC(const MSVehicle *veh, double vMin, double vMax) const
NaSch rule 3 ("randomization"): dawdle by exactly one cell with probability sigma.
double vsafe(const MSVehicle *const veh, double speed, double gap) const
the safe speed considering only the gap to the leader/obstacle (NaSch rule 1+2)
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....
~MSCFModel_NaSch()
Destructor.
double stopSpeed(const MSVehicle *const veh, const double speed, double gap2pred, double decel, const CalcReason usage=CalcReason::CURRENT) const
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
MSCFModel * duplicate(const MSVehicleType *vtype) const
Duplicates the car-following model.
double minNextSpeedEmergency(double speed, const MSVehicle *const veh=0) const
NaSch does not impose an extra bound on emergency braking: a vehicle may always come to a full (Euler...
MSCFModel_NaSch(const MSVehicleType *vtype, double dawdle)
Constructor.
double myCellSpeed
The speed gained per step by accelerating at myAccel, i.e. one cell's worth of speed.
double roundToCell(double speed) const
Rounds a speed down to the nearest multiple of the cell speed (the speed gained by accelerating for e...
The car-following model abstraction.
Definition MSCFModel.h:59
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
CalcReason
What the return value of stop/follow/free-Speed is used for.
Definition MSCFModel.h:95
static bool gSemiImplicitEulerUpdate
Definition MSGlobals.h:53
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
The car-following model and parameter.
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)