LCOV - code coverage report
Current view: top level - src/microsim/cfmodels - MSCFModel_NaSch.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 92.6 % 27 25
Test Date: 2026-09-05 15:36:08 Functions: 90.9 % 11 10

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2026-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_NaSch.cpp
      15              : /// @author  Jerry Lin
      16              : /// @date    Thu, 13 Aug 2026
      17              : ///
      18              : // The Nagel-Schreckenberg (1992) cellular automaton car-following model
      19              : /****************************************************************************/
      20              : #include <config.h>
      21              : 
      22              : #include <limits>
      23              : #include <microsim/MSVehicle.h>
      24              : #include <microsim/MSLane.h>
      25              : #include <microsim/MSGlobals.h>
      26              : #include "MSCFModel_NaSch.h"
      27              : #include <utils/common/RandHelper.h>
      28              : 
      29              : // ===========================================================================
      30              : // method definitions
      31              : // ===========================================================================
      32           36 : MSCFModel_NaSch::MSCFModel_NaSch(const MSVehicleType* vtype, double dawdle) :
      33              :     MSCFModel(vtype),
      34           36 :     myDawdle(dawdle),
      35              :     // The classic NaSch cell length is the distance covered by accelerating
      36              :     // for one simulation step, i.e. the "accel" attribute doubles as the
      37              :     // cell size (in meters) when using the default step-length of 1s,
      38              :     // see https://github.com/eclipse-sumo/sumo/issues/12182
      39           36 :     myCellSpeed(ACCEL2SPEED(myAccel)) {
      40           36 : }
      41              : 
      42              : 
      43           72 : MSCFModel_NaSch::~MSCFModel_NaSch() {}
      44              : 
      45              : 
      46              : double
      47     62418217 : MSCFModel_NaSch::roundToCell(double speed) const {
      48     62418217 :     if (speed <= 0. || myCellSpeed <= 0.) {
      49              :         return 0.;
      50              :     }
      51     62249777 :     return floor(speed / myCellSpeed + NUMERICAL_EPS) * myCellSpeed;
      52              : }
      53              : 
      54              : 
      55              : double
      56     61599074 : MSCFModel_NaSch::vsafe(const MSVehicle* const veh, double speed, double gap) const {
      57     61599074 :     if (gap < NUMERICAL_EPS) {
      58              :         return 0.;
      59              :     }
      60              :     // NaSch rule 1 (acceleration) followed by rule 2 (slowing down): unlike the
      61              :     // Krauss-derived models, the leader's speed does not enter the computation at
      62              :     // all -- the gap alone caps how far ego may move this step, see issue #12182
      63              :     // ("replace leaderSpeed with gap").
      64     61490925 :     const double vAccel = maxNextSpeed(speed, veh);
      65     61490925 :     const double vGapLimited = MIN2(vAccel, DIST2SPEED(gap));
      66     61490925 :     return roundToCell(MAX2(0., vGapLimited));
      67              : }
      68              : 
      69              : 
      70              : double
      71     45375323 : MSCFModel_NaSch::followSpeed(const MSVehicle* const veh, double speed, double gap2pred,
      72              :                              double /*predSpeed*/, double /*predMaxDecel*/, const MSVehicle* const /*pred*/, const CalcReason /*usage*/) const {
      73     45375323 :     return vsafe(veh, speed, gap2pred);
      74              : }
      75              : 
      76              : double
      77         7871 : MSCFModel_NaSch::insertionFollowSpeed(const MSVehicle* const veh, double speed, double gap2pred, double /*predSpeed*/, double /*predMaxDecel*/, const MSVehicle* const /*pred*/) const {
      78         7871 :     return vsafe(veh, speed, gap2pred);
      79              : }
      80              : 
      81              : 
      82              : double
      83     16215880 : MSCFModel_NaSch::stopSpeed(const MSVehicle* const veh, const double speed, double gap2pred, double /*decel*/, const CalcReason /*usage*/) const {
      84     16215880 :     return vsafe(veh, speed, gap2pred);
      85              : }
      86              : 
      87              : 
      88              : double
      89      5514132 : MSCFModel_NaSch::patchSpeedBeforeLC(const MSVehicle* veh, double vMin, double vMax) const {
      90              :     // NaSch rule 3 (randomization): with probability sigma, dawdle by exactly
      91              :     // one cell -- not a continuously distributed amount as in the Krauss dawdle.
      92      5514132 :     if (vMax > 0. && myDawdle > 0. && RandHelper::rand(veh->getRNG()) < myDawdle) {
      93       927292 :         return MAX2(vMin, roundToCell(vMax - myCellSpeed));
      94              :     }
      95              :     return vMax;
      96              : }
      97              : 
      98              : 
      99              : double
     100      5514132 : MSCFModel_NaSch::minNextSpeedEmergency(double /*speed*/, const MSVehicle* const /*veh*/) const {
     101              :     // NaSch rule 4 (movement) permits vehicles to stop dead within a single
     102              :     // step whenever the gap requires it, i.e. emergency deceleration is not
     103              :     // bounded, see issue #12182 ("do not bound emergency decel").
     104      5514132 :     if (MSGlobals::gSemiImplicitEulerUpdate) {
     105      5514132 :         return 0.;
     106              :     }
     107              :     return -std::numeric_limits<double>::max();
     108              : }
     109              : 
     110              : 
     111              : MSCFModel*
     112            0 : MSCFModel_NaSch::duplicate(const MSVehicleType* vtype) const {
     113            0 :     return new MSCFModel_NaSch(vtype, myDawdle);
     114              : }
     115              : 
     116              : 
     117              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1