Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2010-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 : /****************************************************************************/
14 : /// @file MSCFModel_PWag2009.cpp
15 : /// @author Peter Wagner
16 : /// @author Daniel Krajzewicz
17 : /// @author Laura Bieker
18 : /// @author Michael Behrisch
19 : /// @date 03.04.2010
20 : ///
21 : // Scalable model based on Krauss by Peter Wagner
22 : /****************************************************************************/
23 : #include <config.h>
24 :
25 : #include <microsim/MSVehicle.h>
26 : #include <microsim/MSLane.h>
27 : #include "MSCFModel_PWag2009.h"
28 : #include <utils/common/RandHelper.h>
29 :
30 :
31 : // ===========================================================================
32 : // method definitions
33 : // ===========================================================================
34 10 : MSCFModel_PWag2009::MSCFModel_PWag2009(const MSVehicleType* vtype) :
35 : MSCFModel(vtype),
36 10 : myDawdle(vtype->getParameter().getCFParam(SUMO_ATTR_SIGMA, SUMOVTypeParameter::getDefaultImperfection(vtype->getParameter().vehicleClass))),
37 10 : myTauDecel(myDecel * myHeadwayTime),
38 10 : myDecelDivTau(myDecel / myHeadwayTime),
39 10 : myTauLastDecel(myDecel * vtype->getParameter().getCFParam(SUMO_ATTR_CF_PWAGNER2009_TAULAST, 0.3)),
40 20 : myActionPointProbability(vtype->getParameter().getCFParam(SUMO_ATTR_CF_PWAGNER2009_APPROB, 0.5)) {
41 : // PWag2009 does not drive very precise and may violate minGap on occasion
42 10 : myCollisionMinGapFactor = vtype->getParameter().getCFParam(SUMO_ATTR_COLLISION_MINGAP_FACTOR, 0.1);
43 10 : }
44 :
45 :
46 20 : MSCFModel_PWag2009::~MSCFModel_PWag2009() {}
47 :
48 :
49 : double
50 0 : MSCFModel_PWag2009::finalizeSpeed(MSVehicle* const veh, double vPos) const {
51 0 : const double vNext = MSCFModel::finalizeSpeed(veh, vPos);
52 : VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables();
53 0 : double apref = SPEED2ACCEL(vNext - veh->getSpeed());
54 0 : vars->aOld = apref;
55 0 : return vNext;
56 : }
57 :
58 : double
59 0 : MSCFModel_PWag2009::patchSpeedBeforeLC(const MSVehicle* veh, double vMin, double vMax) const {
60 : UNUSED_PARAMETER(veh);
61 : UNUSED_PARAMETER(vMin);
62 0 : return vMax;
63 : }
64 :
65 : // in addition, the parameters myTauLast, probAP, and sigmaAcc are needed; sigmaAcc can use myDawdle
66 : // myTauLast might use the current time-step size, but this yields eventually an extreme model, I would be
67 : // more careful and set it to something around 0.3 or 0.4, which are among the shortest headways I have
68 : // seen so far in data ...
69 :
70 : double
71 0 : MSCFModel_PWag2009::followSpeed(const MSVehicle* const veh, double speed, double gap, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const /*pred*/, const CalcReason /*usage*/) const {
72 0 : if (predSpeed == 0 && gap < 0.01) {
73 : return 0;
74 : }
75 0 : const double vsafe = -myTauLastDecel + sqrt(myTauLastDecel * myTauLastDecel + predSpeed * predSpeed + 2.0 * myDecel * gap);
76 0 : const double asafe = SPEED2ACCEL(vsafe - speed);
77 : VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables();
78 0 : double apref = vars->aOld;
79 0 : if (apref <= asafe && RandHelper::rand(veh->getRNG()) <= myActionPointProbability * TS) {
80 0 : apref = myDecelDivTau * (gap + (predSpeed - speed) * myHeadwayTime - speed * myHeadwayTime) / (speed + myTauDecel);
81 0 : apref = MIN2(apref, myAccel);
82 0 : apref = MAX2(apref, -myDecel);
83 0 : apref += myDawdle * RandHelper::rand((double) - 1., (double)1., veh->getRNG());
84 : }
85 0 : if (apref > asafe) {
86 : apref = asafe;
87 : }
88 0 : return MAX2(0., speed + ACCEL2SPEED(apref));
89 : }
90 :
91 : // uses the safe speed and preferred acceleration with the same NORMAL tau to compute stopSpeed
92 : double
93 0 : MSCFModel_PWag2009::stopSpeed(const MSVehicle* const /* veh */, const double speed, double gap, double /*decel*/, const CalcReason /*usage*/) const {
94 0 : if (gap < 0.01) {
95 : return 0.;
96 : }
97 0 : const double vsafe = -myTauDecel + sqrt(myTauDecel * myTauDecel + 2.0 * myDecel * gap);
98 0 : const double asafe = SPEED2ACCEL(vsafe - speed);
99 : // VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables();
100 0 : double apref = myDecelDivTau * (gap - 2 * speed * myHeadwayTime) / (speed + myTauDecel);
101 0 : if (apref <= asafe) {
102 0 : apref = MIN2(apref, myAccel);
103 0 : apref = MAX2(apref, -myDecel);
104 : } else {
105 : apref = asafe;
106 : }
107 0 : return MAX2(0., vsafe + ACCEL2SPEED(apref));
108 : }
109 :
110 :
111 : MSCFModel*
112 0 : MSCFModel_PWag2009::duplicate(const MSVehicleType* vtype) const {
113 0 : return new MSCFModel_PWag2009(vtype);
114 : }
|