Line data Source code
1 : /****************************************************************************/ 2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo 3 : // Copyright (C) 2001-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_Krauss.cpp 15 : /// @author Tobias Mayer 16 : /// @author Daniel Krajzewicz 17 : /// @author Jakob Erdmann 18 : /// @author Michael Behrisch 19 : /// @author Laura Bieker 20 : /// @date Mon, 04 Aug 2009 21 : /// 22 : // Krauss car-following model, with acceleration decrease and faster start 23 : /****************************************************************************/ 24 : #include <config.h> 25 : 26 : #include <microsim/MSVehicle.h> 27 : #include <microsim/MSLane.h> 28 : #include <microsim/MSGlobals.h> 29 : #include "MSCFModel_Krauss.h" 30 : #include <microsim/lcmodels/MSAbstractLaneChangeModel.h> 31 : #include <utils/common/RandHelper.h> 32 : 33 : 34 : 35 : // =========================================================================== 36 : // DEBUG constants 37 : // =========================================================================== 38 : //#define DEBUG_COND (true) 39 : #define DEBUG_COND (veh->isSelected()) 40 : #define DEBUG_DRIVER_ERRORS 41 : 42 12 : MSCFModel_Krauss::VehicleVariables::VehicleVariables(SUMOTime dawdleStep) 43 12 : : accelDawdle(1e6), updateOffset(SIMSTEP % dawdleStep + DELTA_T) { } 44 : 45 : // =========================================================================== 46 : // method definitions 47 : // =========================================================================== 48 262089 : MSCFModel_Krauss::MSCFModel_Krauss(const MSVehicleType* vtype) : 49 : MSCFModel_KraussOrig1(vtype), 50 262089 : myDawdleStep(TIME2STEPS(vtype->getParameter().getCFParam(SUMO_ATTR_SIGMA_STEP, TS))) { 51 262089 : if (myDawdleStep % DELTA_T != 0) { 52 : SUMOTime rem = myDawdleStep % DELTA_T; 53 4 : if (rem < DELTA_T / 2) { 54 0 : myDawdleStep += -rem; 55 : } else { 56 4 : myDawdleStep += DELTA_T - rem; 57 : } 58 12 : WRITE_WARNINGF(TL("Rounding 'sigmaStep' to % for vType '%'"), STEPS2TIME(myDawdleStep), vtype->getID()); 59 : 60 : } 61 262089 : } 62 : 63 : 64 517675 : MSCFModel_Krauss::~MSCFModel_Krauss() {} 65 : 66 : 67 : double 68 546694282 : MSCFModel_Krauss::patchSpeedBeforeLC(const MSVehicle* veh, double vMin, double vMax) const { 69 546694282 : const double sigma = (veh->passingMinor() 70 546694282 : ? veh->getVehicleType().getParameter().getJMParam(SUMO_ATTR_JM_SIGMA_MINOR, myDawdle) 71 : : myDawdle); 72 : double vDawdle; 73 546694282 : if (myDawdleStep > DELTA_T) { 74 : VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables(); 75 3720 : if (SIMSTEP % myDawdleStep == vars->updateOffset) { 76 412 : const double vD = MAX2(vMin, dawdle2(vMax, sigma, veh->getRNG())); 77 412 : const double a1 = SPEED2ACCEL(vMax - veh->getSpeed()); 78 412 : const double a2 = SPEED2ACCEL(vD - vMax); 79 412 : const double accelMax = (veh->getLane()->getVehicleMaxSpeed(veh) - veh->getSpeed()) / STEPS2TIME(myDawdleStep); 80 : // avoid exceeding maxSpeed before the next sigmaStep 81 412 : vars->accelDawdle = MIN2(a1, accelMax) + a2; 82 412 : vDawdle = veh->getSpeed() + ACCEL2SPEED(vars->accelDawdle); 83 : //std::cout << SIMTIME << " v=" << veh->getSpeed() << " updated vD=" << vD<< " a1=" << a1 << " a2=" << a2 << " aM=" << accelMax << " accelDawdle=" << vars->accelDawdle << " vDawdle=" << vDawdle << "\n"; 84 : } else { 85 3308 : const double safeAccel = SPEED2ACCEL(vMax - veh->getSpeed()); 86 3308 : const double accel = MIN2(safeAccel, vars->accelDawdle); 87 3308 : vDawdle = MAX2(vMin, MIN2(vMax, veh->getSpeed() + ACCEL2SPEED(accel))); 88 : //std::cout << SIMTIME << " v=" << veh->getSpeed() << " safeAccel=" << safeAccel << " accel=" << accel << " vDawdle=" << vDawdle << "\n"; 89 : } 90 : } else { 91 546690562 : vDawdle = MAX2(vMin, dawdle2(vMax, sigma, veh->getRNG())); 92 : //const double accel1 = SPEED2ACCEL(vMax - veh->getSpeed()); 93 : //const double accel2 = SPEED2ACCEL(vDawdle - vMax); 94 : //std::cout << SIMTIME << " v=" << veh->getSpeed() << " updated vDawdle=" << vDawdle << " a1=" << accel1 << " a2=" << accel2 << " accelDawdle=" << SPEED2ACCEL(vDawdle - veh->getSpeed()) << "\n"; 95 : } 96 546694282 : return vDawdle; 97 : } 98 : 99 : 100 : double 101 759759772 : MSCFModel_Krauss::stopSpeed(const MSVehicle* const veh, const double speed, double gap, double decel, const CalcReason usage) const { 102 : // NOTE: This allows return of smaller values than minNextSpeed(). 103 : // Only relevant for the ballistic update: We give the argument headway=veh->getActionStepLengthSecs(), to assure that 104 : // the stopping position is approached with a uniform deceleration also for tau!=veh->getActionStepLengthSecs(). 105 759759772 : applyHeadwayPerceptionError(veh, speed, gap); 106 759759772 : const bool relaxEmergency = usage != FUTURE; // do not relax insertionStopSpeed 107 759759772 : return MIN2(maximumSafeStopSpeed(gap, decel, speed, false, veh->getActionStepLengthSecs(), relaxEmergency), maxNextSpeed(speed, veh)); 108 : } 109 : 110 : 111 : double 112 1907542355 : MSCFModel_Krauss::followSpeed(const MSVehicle* const veh, double speed, double gap, double predSpeed, double predMaxDecel, const MSVehicle* const pred, const CalcReason /*usage*/) const { 113 : //gDebugFlag1 = DEBUG_COND; 114 1907542355 : applyHeadwayAndSpeedDifferencePerceptionErrors(veh, speed, gap, predSpeed, predMaxDecel, pred); 115 : //gDebugFlag1 = DEBUG_COND; // enable for DEBUG_EMERGENCYDECEL 116 1907542355 : const double vsafe = maximumSafeFollowSpeed(gap, speed, predSpeed, predMaxDecel); 117 : //gDebugFlag1 = false; 118 1907542355 : const double vmin = minNextSpeedEmergency(speed); 119 1907542355 : const double vmax = maxNextSpeed(speed, veh); 120 1907542355 : if (MSGlobals::gSemiImplicitEulerUpdate) { 121 : return MIN2(vsafe, vmax); 122 : } else { 123 : // ballistic 124 : // XXX: the euler variant can break as strong as it wishes immediately! The ballistic cannot, refs. #2575. 125 : return MAX2(MIN2(vsafe, vmax), vmin); 126 : } 127 : } 128 : 129 : double 130 546690974 : MSCFModel_Krauss::dawdle2(double speed, double sigma, SumoRNG* rng) const { 131 546690974 : if (!MSGlobals::gSemiImplicitEulerUpdate) { 132 : // in case of the ballistic update, negative speeds indicate 133 : // a desired stop before the completion of the next timestep. 134 : // We do not allow dawdling to overwrite this indication 135 24402404 : if (speed < 0) { 136 : return speed; 137 : } 138 : } 139 : // generate random number out of [0,1) 140 546358845 : const double random = RandHelper::rand(rng); 141 : // Dawdle. 142 546358845 : if (speed < myAccel) { 143 : // we should not prevent vehicles from driving just due to dawdling 144 : // if someone is starting, he should definitely start 145 : // (but what about slow-to-start?)!!! 146 146514369 : speed -= ACCEL2SPEED(sigma * speed * random); 147 : } else { 148 399844476 : speed -= ACCEL2SPEED(sigma * myAccel * random); 149 : } 150 : return MAX2(0., speed); 151 : } 152 : 153 : 154 : MSCFModel* 155 1267 : MSCFModel_Krauss::duplicate(const MSVehicleType* vtype) const { 156 1267 : return new MSCFModel_Krauss(vtype); 157 : } 158 : 159 : 160 : /****************************************************************************/