Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSCFModel_SmartSK.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2012-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/****************************************************************************/
21// A smarter SK
22/****************************************************************************/
23#include <config.h>
24
25#include <map>
26#include <microsim/MSVehicle.h>
27#include <microsim/MSLane.h>
28#include "MSCFModel_SmartSK.h"
32
33//#define SmartSK_DEBUG
34
35// ===========================================================================
36// method definitions
37// ===========================================================================
39// check whether setting these variables here with default values is ''good'' SUMO design
40// double tmp1=0.0, double tmp2=5.0, double tmp3=0.0, double tmp4, double tmp5)
41 MSCFModel(vtype),
42 myDawdle(vtype->getParameter().getCFParam(SUMO_ATTR_SIGMA, SUMOVTypeParameter::getDefaultImperfection(vtype->getParameter().vehicleClass))),
43 myTauDecel(myDecel * myHeadwayTime),
44 myTmp1(vtype->getParameter().getCFParam(SUMO_ATTR_TMP1, 1.0)),
45 myTmp2(vtype->getParameter().getCFParam(SUMO_ATTR_TMP2, 1.0)),
46 myTmp3(vtype->getParameter().getCFParam(SUMO_ATTR_TMP3, 1.0)),
47 myTmp4(vtype->getParameter().getCFParam(SUMO_ATTR_TMP4, 1.0)),
48 myTmp5(vtype->getParameter().getCFParam(SUMO_ATTR_TMP5, 1.0)) {
49 // the variable tmp1 is the acceleration delay time, e.g. two seconds (or something like this).
50 // for use in the upate process, a rule like if (v<myTmp1) vsafe = 0; is needed.
51 // To have this, we have to transform myTmp1 (which is a time) into an equivalent speed. This is done by the
52 // using the vsafe formula and computing:
53 // v(t=myTmp1) = -myTauDecel + sqrt(myTauDecel*myTauDecel + accel*(accel + decel)*t*t + accel*decel*t*TS);
54 double t = myTmp1;
55 myS2Sspeed = -myTauDecel + sqrt(myTauDecel * myTauDecel + myAccel * (myAccel + myDecel) * t * t + myAccel * myDecel * t * TS);
56#ifdef SmartSK_DEBUG
57 std::cout << "# s2s-speed: " << myS2Sspeed << std::endl;
58#endif
59 if (myS2Sspeed > 5.0) {
60 myS2Sspeed = 5.0;
61 }
62// double maxDeltaGap = -0.5*ACCEL2DIST(myDecel + myAccel);
63 maxDeltaGap = -0.5 * (myDecel + myAccel) * TS * TS;
64#ifdef SmartSK_DEBUG
65 std::cout << "# maxDeltaGap = " << maxDeltaGap << std::endl;
66#endif
67 myTmp2 = TS / myTmp2;
68 myTmp3 = sqrt(TS) * myTmp3;
69}
70
71
73
74
75void
78 out.writeAttr(SUMO_ATTR_ID, "SmartSK");
79 std::ostringstream internals;
80 internals << gOld << " ";
81 internals << myHeadway << " ";
82 internals << ggOld.size() << " ";
83 for (auto item : ggOld) {
84 internals << item.first << " " << item.second << " ";
85 }
86 out.writeAttr(SUMO_ATTR_STATE, internals.str());
87 out.closeTag();
88}
89
90
91void
93 bool ok = true;
94 const std::string cfmID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
95 if (cfmID != "SmartSK") {
96 throw ProcessError(TLF("incompatible carFollowModel '%' when loading state for SmartSK", cfmID));
97 }
98 std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
99 bis >> gOld;
100 bis >> myHeadway;
101 int ggOldSize;
102 bis >> ggOldSize;
103 for (int i = 0; i < ggOldSize; i++) {
104 int k;
105 double v;
106 bis >> k;
107 bis >> v;
108 ggOld[k] = v;
109 }
110}
111
112
113double
114MSCFModel_SmartSK::finalizeSpeed(MSVehicle* const veh, double vPos) const {
115 const double vNext = MSCFModel::finalizeSpeed(veh, vPos);
116 updateMyHeadway(veh);
118#ifdef SmartSK_DEBUG
119 if (vars->ggOld.size() > 1) {
120 std::cout << "# more than one entry in ggOld list. Speed is " << vPos << ", corresponding dist is " << vars->ggOld[(int) vPos] << "\n";
121 for (std::map<int, double>::iterator I = vars->ggOld.begin(); I != vars->ggOld.end(); I++) {
122 std::cout << "# " << (*I).first << ' ' << (*I).second << std::endl;
123 }
124 }
125#endif
126 vars->gOld = vars->ggOld[(int) vPos];
127 vars->ggOld.clear();
128 return vNext;
129}
130
131double
132MSCFModel_SmartSK::followSpeed(const MSVehicle* const veh, double speed, double gap, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const /*pred*/, const CalcReason /*usage*/) const {
134
135// if (((gap - vars->gOld) < maxDeltaGap) && (speed>=5.0) && gap>=5.0) {
136 if ((gap - vars->gOld) < maxDeltaGap) {
137 double tTauTest = gap / speed;
138// allow headway only to decrease only, never to increase. Increase is handled automatically by the headway dynamics in finalizeSpeed()!!!
139 if ((tTauTest < vars->myHeadway) && (tTauTest > TS)) {
140 vars->myHeadway = tTauTest;
141 }
142 }
143
144 double vsafe = _vsafe(veh, gap, predSpeed);
145 if ((speed <= 0.0) && (vsafe < myS2Sspeed)) {
146 vsafe = 0;
147 }
148
149 double vNew = MAX2(getSpeedAfterMaxDecel(speed), MIN2(vsafe, maxNextSpeed(speed, veh)));
150 // there must be a better place to do the following assignment!!!
151 vars->gOld = gap;
152 vars->ggOld[(int)vNew] = gap;
153 return vNew;
154}
155
156double
157MSCFModel_SmartSK::stopSpeed(const MSVehicle* const veh, const double speed, double gap, double /*decel*/, const CalcReason /*usage*/) const {
159
160// if (((gap - vars->gOld) < maxDeltaGap) && (speed>=5.0) && gap>=5.0) {
161 if ((gap - vars->gOld) < maxDeltaGap) {
162 double tTauTest = gap / speed;
163// allow headway only to decrease only, never to increase. Increase is handled automatically by the headway dynamics in finalizeSpeed()!!!
164 if ((tTauTest < vars->myHeadway) && (tTauTest > TS)) {
165 vars->myHeadway = tTauTest;
166 }
167 }
168
169 return MAX2(getSpeedAfterMaxDecel(speed), MIN2(_vsafe(veh, gap, 0), maxNextSpeed(speed, veh)));
170}
171
172double
173MSCFModel_SmartSK::patchSpeedBeforeLC(const MSVehicle* veh, double /*vMin*/, double /*vMax*/) const {
174 return dawdle(veh->getSpeed(), veh->getRNG());
175}
176
177double
178MSCFModel_SmartSK::dawdle(double speed, SumoRNG* rng) const {
179 return MAX2(0., speed - ACCEL2SPEED(myDawdle * myAccel * RandHelper::rand(rng)));
180}
181
182
184double MSCFModel_SmartSK::_vsafe(const MSVehicle* const veh, double gap, double predSpeed) const {
185 if (predSpeed == 0 && gap < 0.01) {
186 return 0;
187 }
189 // this is the most obvious change to the normal SK: the model uses the variable vars->myHeadway instead of the constant
190 // myHeadwayTime as the "desired headway" tau
191 double bTau = myDecel * (vars->myHeadway);
192 double vsafe = (double)(-1. * bTau
193 + sqrt(
194 bTau * bTau
195 + (predSpeed * predSpeed)
196 + (2. * myDecel * gap)
197 ));
198 assert(vsafe >= 0);
199 return vsafe;
200}
201
202
205 return new MSCFModel_SmartSK(vtype);
206}
#define TLF(string,...)
Definition MsgHandler.h:306
#define ACCEL2SPEED(x)
Definition SUMOTime.h:54
#define TS
Definition SUMOTime.h:45
@ SUMO_TAG_CFM_VARIABLES
@ SUMO_ATTR_TMP4
@ SUMO_ATTR_TMP3
@ SUMO_ATTR_TMP2
@ SUMO_ATTR_ID
@ SUMO_ATTR_SIGMA
@ SUMO_ATTR_TMP1
@ SUMO_ATTR_TMP5
@ SUMO_ATTR_STATE
The state of a link.
T MIN2(T a, T b)
Definition StdDefs.h:80
T MAX2(T a, T b)
Definition StdDefs.h:86
SumoRNG * getRNG() const
void saveState(OutputDevice &out, const MSCFModel &cfm) const
Saves the vehicle variables.
void loadState(const SUMOSAXAttributes &attrs)
Loads the state of the vehicle variables from the given description.
The original Krauss (1998) car-following model and parameter.
double patchSpeedBeforeLC(const MSVehicle *veh, double vMin, double vMax) const
apply dawdling
double myTauDecel
The precomputed value for myDecel*myTau.
double myDawdle
The vehicle's dawdle-parameter. 0 for no dawdling, 1 for max.
virtual double _vsafe(const MSVehicle *const veh, double gap, double predSpeed) const
Returns the "safe" velocity.
virtual MSCFModel * duplicate(const MSVehicleType *vtype) const
Duplicates the car-following model.
virtual 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 myS2Sspeed
new variables needed in this model; myS2Sspeed is the speed below which the vehicle does not move whe...
double myTmp1
temporary (testing) parameter
virtual void updateMyHeadway(const MSVehicle *const veh) const
~MSCFModel_SmartSK()
Destructor.
MSCFModel_SmartSK(const MSVehicleType *vtype)
Constructor.
virtual double dawdle(double speed, SumoRNG *rng) const
Applies driver imperfection (dawdling / sigma)
double finalizeSpeed(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences.
virtual 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)
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.
virtual double finalizeSpeed(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences. Called at most once per simulation...
CalcReason
What the return value of stop/follow/free-Speed is used for.
Definition MSCFModel.h:95
double myDecel
The vehicle's maximum deceleration [m/s^2].
Definition MSCFModel.h:762
double myAccel
The vehicle's maximum acceleration [m/s^2].
Definition MSCFModel.h:759
virtual double getSpeedAfterMaxDecel(double v) const
Returns the velocity after maximum deceleration.
Definition MSCFModel.h:447
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
double getSpeed() const
Returns the vehicle's current speed.
Definition MSVehicle.h:490
MSCFModel::VehicleVariables * getCarFollowVariables() const
Returns the vehicle's car following model variables.
Definition MSVehicle.h:994
The car-following model and parameter.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Encapsulated SAX-Attributes.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
Structure representing possible vehicle parameter.