LCOV - code coverage report
Current view: top level - src/microsim/cfmodels - MSCFModel_Krauss.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 96.9 % 64 62
Test Date: 2026-06-15 15:46:12 Functions: 100.0 % 11 11

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-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              : /****************************************************************************/
      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              : #include <utils/xml/SUMOSAXAttributes.h>
      33              : 
      34              : 
      35              : 
      36              : // ===========================================================================
      37              : // DEBUG constants
      38              : // ===========================================================================
      39              : //#define DEBUG_COND (true)
      40              : #define DEBUG_COND (veh->isSelected())
      41              : #define DEBUG_DRIVER_ERRORS
      42              : 
      43           32 : MSCFModel_Krauss::VehicleVariables::VehicleVariables(SUMOTime dawdleStep)
      44           32 :     : accelDawdle(1e6), updateOffset(SIMSTEP % dawdleStep + DELTA_T) { }
      45              : 
      46              : // ===========================================================================
      47              : // method definitions
      48              : // ===========================================================================
      49       307991 : MSCFModel_Krauss::MSCFModel_Krauss(const MSVehicleType* vtype) :
      50              :     MSCFModel_KraussOrig1(vtype),
      51       307991 :     myDawdleStep(TIME2STEPS(vtype->getParameter().getCFParam(SUMO_ATTR_SIGMA_STEP, TS))) {
      52       307991 :     if (myDawdleStep % DELTA_T != 0) {
      53              :         SUMOTime rem = myDawdleStep % DELTA_T;
      54            4 :         if (rem < DELTA_T / 2) {
      55            0 :             myDawdleStep += -rem;
      56              :         } else {
      57            4 :             myDawdleStep += DELTA_T - rem;
      58              :         }
      59           12 :         WRITE_WARNINGF(TL("Rounding 'sigmaStep' to % for vType '%'"), STEPS2TIME(myDawdleStep), vtype->getID());
      60              : 
      61              :     }
      62       307991 : }
      63              : 
      64              : 
      65       608247 : MSCFModel_Krauss::~MSCFModel_Krauss() {}
      66              : 
      67              : 
      68              : void
      69           10 : MSCFModel_Krauss::VehicleVariables::saveState(OutputDevice& out, const MSCFModel& /*cfm*/) const {
      70           10 :     out.openTag(SUMO_TAG_CFM_VARIABLES);
      71           10 :     out.writeAttr(SUMO_ATTR_ID, "Krauss");
      72           10 :     std::ostringstream internals;
      73           10 :     internals << accelDawdle << " ";
      74           10 :     internals << updateOffset;
      75           10 :     out.writeAttr(SUMO_ATTR_STATE, internals.str());
      76           10 :     out.closeTag();
      77           10 : }
      78              : 
      79              : 
      80              : void
      81           10 : MSCFModel_Krauss::VehicleVariables::loadState(const SUMOSAXAttributes& attrs) {
      82           10 :     bool ok = true;
      83           10 :     const std::string cfmID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
      84           10 :     if (cfmID != "Krauss") {
      85            0 :         throw ProcessError(TLF("incompatible carFollowModel '%' when loading state for Krauss", cfmID));
      86              :     }
      87           10 :     std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
      88           10 :     bis >> accelDawdle;
      89           10 :     bis >> updateOffset;
      90           20 : }
      91              : 
      92              : 
      93              : double
      94    549981867 : MSCFModel_Krauss::patchSpeedBeforeLC(const MSVehicle* veh, double vMin, double vMax) const {
      95    549981867 :     const double sigma = (veh->passingMinor()
      96    549981867 :                           ? veh->getVehicleType().getParameter().getJMParam(SUMO_ATTR_JM_SIGMA_MINOR, myDawdle)
      97              :                           : myDawdle);
      98              :     double vDawdle;
      99    549981867 :     if (myDawdleStep > DELTA_T) {
     100              :         VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables();
     101         5753 :         if (SIMSTEP % myDawdleStep == vars->updateOffset) {
     102         1428 :             const double vD = MAX2(vMin, dawdle2(vMax, sigma, veh->getRNG()));
     103         1428 :             const double a1 = SPEED2ACCEL(vMax - veh->getSpeed());
     104         1428 :             const double a2 = SPEED2ACCEL(vD - vMax);
     105         1428 :             const double accelMax = (veh->getLane()->getVehicleMaxSpeed(veh) - veh->getSpeed()) / STEPS2TIME(myDawdleStep);
     106              :             // avoid exceeding maxSpeed before the next sigmaStep
     107         1428 :             vars->accelDawdle = MIN2(a1, accelMax) + a2;
     108         1428 :             vDawdle = veh->getSpeed() + ACCEL2SPEED(vars->accelDawdle);
     109              :             //std::cout << SIMTIME << " v=" << veh->getSpeed() << " updated vD=" << vD<< " a1=" << a1 << " a2=" << a2 << " aM=" << accelMax << " accelDawdle=" << vars->accelDawdle << " vDawdle=" << vDawdle << "\n";
     110              :         } else {
     111         4325 :             const double safeAccel = SPEED2ACCEL(vMax - veh->getSpeed());
     112         4325 :             const double accel = MIN2(safeAccel, vars->accelDawdle);
     113         4325 :             vDawdle = MAX2(vMin, MIN2(vMax, veh->getSpeed() + ACCEL2SPEED(accel)));
     114              :             //std::cout << SIMTIME << " v=" << veh->getSpeed() << " safeAccel=" << safeAccel << " accel=" << accel << " vDawdle=" << vDawdle << "\n";
     115              :         }
     116              :     } else {
     117    549976114 :         vDawdle = MAX2(vMin, dawdle2(vMax, sigma, veh->getRNG()));
     118              :         //const double accel1 = SPEED2ACCEL(vMax - veh->getSpeed());
     119              :         //const double accel2 = SPEED2ACCEL(vDawdle - vMax);
     120              :         //std::cout << SIMTIME << " v=" << veh->getSpeed() << " updated vDawdle=" << vDawdle << " a1=" << accel1 << " a2=" << accel2 << " accelDawdle=" << SPEED2ACCEL(vDawdle - veh->getSpeed()) << "\n";
     121              :     }
     122    549981867 :     return vDawdle;
     123              : }
     124              : 
     125              : 
     126              : double
     127    736446278 : MSCFModel_Krauss::stopSpeed(const MSVehicle* const veh, const double speed, double gap, double decel, const CalcReason usage) const {
     128              :     // NOTE: This allows return of smaller values than minNextSpeed().
     129              :     // Only relevant for the ballistic update: We give the argument headway=veh->getActionStepLengthSecs(), to assure that
     130              :     // the stopping position is approached with a uniform deceleration also for tau!=veh->getActionStepLengthSecs().
     131    736446278 :     applyHeadwayPerceptionError(veh, speed, gap);
     132    736446278 :     const bool relaxEmergency = usage != FUTURE; // do not relax insertionStopSpeed
     133    736446278 :     return MIN2(maximumSafeStopSpeed(gap, decel, speed, false, veh->getActionStepLengthSecs(), relaxEmergency), maxNextSpeed(speed, veh));
     134              : }
     135              : 
     136              : 
     137              : double
     138   2172620679 : MSCFModel_Krauss::followSpeed(const MSVehicle* const veh, double speed, double gap, double predSpeed, double predMaxDecel, const MSVehicle* const pred, const CalcReason /*usage*/) const {
     139              :     //gDebugFlag1 = DEBUG_COND;
     140   2172620679 :     applyHeadwayAndSpeedDifferencePerceptionErrors(veh, speed, gap, predSpeed, predMaxDecel, pred);
     141              :     //gDebugFlag1 = DEBUG_COND; // enable for DEBUG_EMERGENCYDECEL
     142   2172620679 :     const double vsafe = maximumSafeFollowSpeed(gap, speed, predSpeed, predMaxDecel);
     143              :     //gDebugFlag1 = false;
     144   2172620679 :     const double vmax = maxNextSpeed(speed, veh);
     145   2172620679 :     if (MSGlobals::gSemiImplicitEulerUpdate) {
     146              :         return MIN2(vsafe, vmax);
     147              :     } else {
     148              :         // ballistic
     149              :         // XXX: the euler variant can break as strong as it wishes immediately! The ballistic cannot, refs. #2575.
     150    172456055 :         return MAX2(MIN2(vsafe, vmax), minNextSpeedEmergency(speed));
     151              :     }
     152              : }
     153              : 
     154              : double
     155    549977542 : MSCFModel_Krauss::dawdle2(double speed, double sigma, SumoRNG* rng) const {
     156    549977542 :     if (!MSGlobals::gSemiImplicitEulerUpdate) {
     157              :         // in case of the ballistic update, negative speeds indicate
     158              :         // a desired stop before the completion of the next timestep.
     159              :         // We do not allow dawdling to overwrite this indication
     160     25972740 :         if (speed < 0) {
     161              :             return speed;
     162              :         }
     163              :     }
     164              :     // generate random number out of [0,1)
     165    549541194 :     const double random = RandHelper::rand(rng);
     166              :     // Dawdle.
     167    549541194 :     if (speed < myAccel) {
     168              :         // we should not prevent vehicles from driving just due to dawdling
     169              :         //  if someone is starting, he should definitely start
     170              :         // (but what about slow-to-start?)!!!
     171    122217882 :         speed -= ACCEL2SPEED(sigma * speed * random);
     172              :     } else {
     173    427323312 :         speed -= ACCEL2SPEED(sigma * myAccel * random);
     174              :     }
     175              :     return MAX2(0., speed);
     176              : }
     177              : 
     178              : 
     179              : MSCFModel*
     180         1390 : MSCFModel_Krauss::duplicate(const MSVehicleType* vtype) const {
     181         1390 :     return new MSCFModel_Krauss(vtype);
     182              : }
     183              : 
     184              : 
     185              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1