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 14 : MSCFModel_PWag2009::MSCFModel_PWag2009(const MSVehicleType* vtype) : 35 : MSCFModel(vtype), 36 14 : myDawdle(vtype->getParameter().getCFParam(SUMO_ATTR_SIGMA, SUMOVTypeParameter::getDefaultImperfection(vtype->getParameter().vehicleClass))), 37 14 : myTauDecel(myDecel * myHeadwayTime), 38 14 : myDecelDivTau(myDecel / myHeadwayTime), 39 14 : myTauLastDecel(myDecel * vtype->getParameter().getCFParam(SUMO_ATTR_CF_PWAGNER2009_TAULAST, 0.3)), 40 28 : 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 14 : myCollisionMinGapFactor = vtype->getParameter().getCFParam(SUMO_ATTR_COLLISION_MINGAP_FACTOR, 0.1); 43 14 : } 44 : 45 : 46 28 : MSCFModel_PWag2009::~MSCFModel_PWag2009() {} 47 : 48 : 49 : double 50 14950 : MSCFModel_PWag2009::finalizeSpeed(MSVehicle* const veh, double vPos) const { 51 14950 : const double vNext = MSCFModel::finalizeSpeed(veh, vPos); 52 : VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables(); 53 14950 : double apref = SPEED2ACCEL(vNext - veh->getSpeed()); 54 14950 : vars->aOld = apref; 55 14950 : return vNext; 56 : } 57 : 58 : double 59 14950 : MSCFModel_PWag2009::patchSpeedBeforeLC(const MSVehicle* veh, double vMin, double vMax) const { 60 : UNUSED_PARAMETER(veh); 61 : UNUSED_PARAMETER(vMin); 62 14950 : 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 38212 : MSCFModel_PWag2009::followSpeed(const MSVehicle* const veh, double speed, double gap, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const /*pred*/, const CalcReason /*usage*/) const { 72 38212 : if (predSpeed == 0 && gap < 0.01) { 73 : return 0; 74 : } 75 37166 : const double vsafe = -myTauLastDecel + sqrt(myTauLastDecel * myTauLastDecel + predSpeed * predSpeed + 2.0 * myDecel * gap); 76 37166 : const double asafe = SPEED2ACCEL(vsafe - speed); 77 : VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables(); 78 37166 : double apref = vars->aOld; 79 37166 : if (apref <= asafe && RandHelper::rand(veh->getRNG()) <= myActionPointProbability * TS) { 80 18476 : apref = myDecelDivTau * (gap + (predSpeed - speed) * myHeadwayTime - speed * myHeadwayTime) / (speed + myTauDecel); 81 18476 : apref = MIN2(apref, myAccel); 82 18476 : apref = MAX2(apref, -myDecel); 83 36952 : apref += myDawdle * RandHelper::rand((double) - 1., (double)1., veh->getRNG()); 84 : } 85 37166 : if (apref > asafe) { 86 : apref = asafe; 87 : } 88 37166 : 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 44806 : MSCFModel_PWag2009::stopSpeed(const MSVehicle* const /* veh */, const double speed, double gap, double /*decel*/, const CalcReason /*usage*/) const { 94 44806 : if (gap < 0.01) { 95 : return 0.; 96 : } 97 44780 : const double vsafe = -myTauDecel + sqrt(myTauDecel * myTauDecel + 2.0 * myDecel * gap); 98 44780 : const double asafe = SPEED2ACCEL(vsafe - speed); 99 : // VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables(); 100 44780 : double apref = myDecelDivTau * (gap - 2 * speed * myHeadwayTime) / (speed + myTauDecel); 101 44780 : if (apref <= asafe) { 102 0 : apref = MIN2(apref, myAccel); 103 0 : apref = MAX2(apref, -myDecel); 104 : } else { 105 : apref = asafe; 106 : } 107 44780 : 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 : }