Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2012-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_Daniel1.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Tue, 05 Jun 2012
19 : ///
20 : // The original Krauss (1998) car-following model and parameter
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include <microsim/MSVehicle.h>
25 : #include <microsim/MSLane.h>
26 : #include "MSCFModel_Daniel1.h"
27 : #include <microsim/lcmodels/MSAbstractLaneChangeModel.h>
28 : #include <utils/common/RandHelper.h>
29 :
30 :
31 : // ===========================================================================
32 : // method definitions
33 : // ===========================================================================
34 20 : MSCFModel_Daniel1::MSCFModel_Daniel1(const MSVehicleType* vtype) :
35 : MSCFModel(vtype),
36 20 : myDawdle(vtype->getParameter().getCFParam(SUMO_ATTR_SIGMA, SUMOVTypeParameter::getDefaultImperfection(vtype->getParameter().vehicleClass))),
37 20 : myTauDecel(myDecel * myHeadwayTime),
38 20 : myTmp1(vtype->getParameter().getCFParam(SUMO_ATTR_TMP1, 1.0)),
39 20 : myTmp2(vtype->getParameter().getCFParam(SUMO_ATTR_TMP2, 1.0)),
40 20 : myTmp3(vtype->getParameter().getCFParam(SUMO_ATTR_TMP3, 1.0)),
41 20 : myTmp4(vtype->getParameter().getCFParam(SUMO_ATTR_TMP4, 1.0)),
42 40 : myTmp5(vtype->getParameter().getCFParam(SUMO_ATTR_TMP5, 1.0)) {
43 20 : }
44 :
45 :
46 40 : MSCFModel_Daniel1::~MSCFModel_Daniel1() {}
47 :
48 :
49 : double
50 0 : MSCFModel_Daniel1::finalizeSpeed(MSVehicle* const veh, double vPos) const {
51 0 : const double oldV = veh->getSpeed(); // save old v for optional acceleration computation
52 0 : const double vSafe = MIN2(vPos, veh->processNextStop(vPos)); // process stops
53 : // we need the acceleration for emission computation;
54 : // in this case, we neglect dawdling, nonetheless, using
55 : // vSafe does not incorporate speed reduction due to interaction
56 : // on lane changing
57 0 : const double vMin = getSpeedAfterMaxDecel(oldV);
58 0 : const double vMax = MIN3(veh->getLane()->getVehicleMaxSpeed(veh), maxNextSpeed(oldV, veh), vSafe);
59 : #ifdef _DEBUG
60 : if (vMin > vMax) {
61 : WRITE_WARNINGF(TL("Maximum speed of vehicle '%' is lower than the minimum speed (min: %, max: %)."), veh->getID(), toString(vMin), toString(vMax));
62 : }
63 : #endif
64 0 : return veh->getLaneChangeModel().patchSpeed(vMin, MAX2(vMin, dawdle(vMax, veh->getRNG())), vMax, *this);
65 : }
66 :
67 :
68 : double
69 0 : MSCFModel_Daniel1::followSpeed(const MSVehicle* const veh, double speed, double gap, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const /*pred*/, const CalcReason /*usage*/) const {
70 0 : return MIN2(_vsafe(gap, predSpeed), maxNextSpeed(speed, veh));
71 : }
72 :
73 :
74 : double
75 0 : MSCFModel_Daniel1::stopSpeed(const MSVehicle* const veh, const double speed, double gap, double /*decel*/, const CalcReason /*usage*/) const {
76 0 : return MIN2(_vsafe(gap, 0), maxNextSpeed(speed, veh));
77 : }
78 :
79 :
80 : double
81 0 : MSCFModel_Daniel1::dawdle(double speed, SumoRNG* rng) const {
82 0 : return MAX2(0., speed - ACCEL2SPEED(myDawdle * myAccel * RandHelper::rand(rng)));
83 : }
84 :
85 :
86 : /** Returns the SK-vsafe. */
87 0 : double MSCFModel_Daniel1::_vsafe(double gap, double predSpeed) const {
88 0 : if (predSpeed == 0 && gap < 0.01) {
89 : return 0;
90 : }
91 : double vsafe = (double)(-1. * myTauDecel
92 0 : + sqrt(
93 0 : myTauDecel * myTauDecel
94 0 : + (predSpeed * predSpeed)
95 0 : + (2. * myDecel * gap)
96 0 : ));
97 : assert(vsafe >= 0);
98 0 : return vsafe;
99 : }
100 :
101 :
102 : MSCFModel*
103 0 : MSCFModel_Daniel1::duplicate(const MSVehicleType* vtype) const {
104 0 : return new MSCFModel_Daniel1(vtype);
105 : }
|