LCOV - code coverage report
Current view: top level - src/microsim/cfmodels - MSCFModel_ACC.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 93.7 % 63 59
Test Date: 2024-12-21 15:45:41 Functions: 83.3 % 12 10

            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_ACC.cpp
      15              : /// @author  Kallirroi Porfyri
      16              : /// @date    Feb 2018
      17              : ///
      18              : // ACC car-following model based on [1], [2].
      19              : // [1] Milanes, V., and S. E. Shladover. Handling Cut-In Vehicles in Strings
      20              : //    of Cooperative Adaptive Cruise Control Vehicles. Journal of Intelligent
      21              : //     Transportation Systems, Vol. 20, No. 2, 2015, pp. 178-191.
      22              : // [2] Xiao, L., M. Wang and B. van Arem. Realistic Car-Following Models for
      23              : //    Microscopic Simulation of Adaptive and Cooperative Adaptive Cruise
      24              : //     Control Vehicles. Transportation Research Record: Journal of the
      25              : //     Transportation Research Board, No. 2623, 2017. (DOI: 10.3141/2623-01).
      26              : //[3]  Xiao, L., Wang, M., Schakel, W., & van Arem, B. (2018). Unravelling
      27              : //    effects of cooperative adaptive cruise control deactivation on
      28              : //    traffic flow characteristics at merging bottlenecks. Transportation
      29              : //    Research Part C: Emerging Technologies, 96, 380–397.
      30              : //    <https://doi.org/10.1016/j.trc.2018.10.008>
      31              : /****************************************************************************/
      32              : #include <config.h>
      33              : 
      34              : #include <stdio.h>
      35              : #include <iostream>
      36              : 
      37              : #include "MSCFModel_ACC.h"
      38              : #include <microsim/MSVehicle.h>
      39              : #include <microsim/MSLane.h>
      40              : #include <utils/common/RandHelper.h>
      41              : #include <utils/common/SUMOTime.h>
      42              : #include <microsim/lcmodels/MSAbstractLaneChangeModel.h>
      43              : #include <math.h>
      44              : #include <microsim/MSNet.h>
      45              : 
      46              : // ===========================================================================
      47              : // debug flags
      48              : // ===========================================================================
      49              : //#define DEBUG_ACC
      50              : //#define DEBUG_COND (true)
      51              : //#define DEBUG_COND (veh->isSelected())
      52              : 
      53              : 
      54              : // ===========================================================================
      55              : // defaults
      56              : // ===========================================================================
      57              : #define DEFAULT_SC_GAIN -0.4
      58              : #define DEFAULT_GCC_GAIN_SPEED 0.8
      59              : #define DEFAULT_GCC_GAIN_SPACE 0.04
      60              : #define DEFAULT_GC_GAIN_SPEED 0.07
      61              : #define DEFAULT_GC_GAIN_SPACE 0.23
      62              : #define DEFAULT_CA_GAIN_SPACE 0.8
      63              : #define DEFAULT_CA_GAIN_SPEED 0.23
      64              : 
      65              : // ===========================================================================
      66              : // thresholds
      67              : // ===========================================================================
      68              : #define GAP_THRESHOLD_SPEEDCTRL 120
      69              : #define GAP_THRESHOLD_GAPCTRL 100
      70              : // override followSpeed when deemed unsafe by the given margin (the value was selected to reduce the number of necessary interventions)
      71              : #define DEFAULT_EMERGENCY_OVERRIDE_THRESHOLD 2.0
      72              : 
      73              : /// @todo: add attributes for myCollisionAvoidanceGainSpeed and myCollisionAvoidanceGainSpace
      74              : 
      75              : // ===========================================================================
      76              : // method definitions
      77              : // ===========================================================================
      78          728 : MSCFModel_ACC::MSCFModel_ACC(const MSVehicleType* vtype) :
      79              :     MSCFModel(vtype),
      80          728 :     mySpeedControlGain(vtype->getParameter().getCFParam(SUMO_ATTR_SC_GAIN, DEFAULT_SC_GAIN)),
      81          728 :     myGapClosingControlGainSpeed(vtype->getParameter().getCFParam(SUMO_ATTR_GCC_GAIN_SPEED, DEFAULT_GCC_GAIN_SPEED)),
      82          728 :     myGapClosingControlGainSpace(vtype->getParameter().getCFParam(SUMO_ATTR_GCC_GAIN_SPACE, DEFAULT_GCC_GAIN_SPACE)),
      83          728 :     myGapControlGainSpeed(vtype->getParameter().getCFParam(SUMO_ATTR_GC_GAIN_SPEED, DEFAULT_GC_GAIN_SPEED)),
      84          728 :     myGapControlGainSpace(vtype->getParameter().getCFParam(SUMO_ATTR_GC_GAIN_SPACE, DEFAULT_GC_GAIN_SPACE)),
      85          728 :     myCollisionAvoidanceGainSpeed(vtype->getParameter().getCFParam(SUMO_ATTR_CA_GAIN_SPEED, DEFAULT_CA_GAIN_SPEED)),
      86          728 :     myCollisionAvoidanceGainSpace(vtype->getParameter().getCFParam(SUMO_ATTR_CA_GAIN_SPACE, DEFAULT_CA_GAIN_SPACE)),
      87         1456 :     myEmergencyThreshold(vtype->getParameter().getCFParam(SUMO_ATTR_CA_OVERRIDE, DEFAULT_EMERGENCY_OVERRIDE_THRESHOLD)) {
      88              :     // ACC does not drive very precise and often violates minGap
      89          728 :     myCollisionMinGapFactor = vtype->getParameter().getCFParam(SUMO_ATTR_COLLISION_MINGAP_FACTOR, 0.1);
      90          728 : }
      91              : 
      92         1017 : MSCFModel_ACC::~MSCFModel_ACC() {}
      93              : 
      94              : 
      95              : double
      96     32946580 : MSCFModel_ACC::followSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle* const /*pred*/, const CalcReason /*usage*/) const {
      97     32946580 :     const double desSpeed = MIN2(veh->getLane()->getSpeedLimit(), veh->getMaxSpeed());
      98     32946580 :     const double vACC = _v(veh, gap2pred, speed, predSpeed, desSpeed, true);
      99     32946580 :     const double vSafe = maximumSafeFollowSpeed(gap2pred, speed, predSpeed, predMaxDecel);
     100     32946580 :     if (vSafe + myEmergencyThreshold < vACC) {
     101              :         //ACCVehicleVariables* vars = (ACCVehicleVariables*)veh->getCarFollowVariables();
     102              :         //std::cout << SIMTIME << " veh=" << veh->getID() << " v=" << speed << " vL=" << predSpeed << " gap=" << gap2pred << " vACC=" << vACC << " vSafe=" << vSafe << " cm=" << vars->ACC_ControlMode << "\n";
     103       320869 :         return vSafe + myEmergencyThreshold;
     104              :     }
     105              :     return vACC;
     106              : }
     107              : 
     108              : 
     109              : double
     110     11590337 : MSCFModel_ACC::stopSpeed(const MSVehicle* const veh, const double speed, double gap, double decel, const CalcReason /*usage*/) const {
     111              :     // NOTE: This allows return of smaller values than minNextSpeed().
     112              :     // Only relevant for the ballistic update: We give the argument headway=TS, to assure that
     113              :     // the stopping position is approached with a uniform deceleration also for tau!=TS.
     114     11590337 :     return MIN2(maximumSafeStopSpeed(gap, decel, speed, false, veh->getActionStepLengthSecs()), maxNextSpeed(speed, veh));
     115              : }
     116              : 
     117              : 
     118              : double
     119     27485418 : MSCFModel_ACC::getSecureGap(const MSVehicle* const /*veh*/, const MSVehicle* const /*pred*/, const double speed, const double leaderSpeed, const double /* leaderMaxDecel */) const {
     120              :     // Accel in gap mode should vanish:
     121              :     //      0 = myGapControlGainSpeed * (leaderSpeed - speed) + myGapControlGainSpace * (g - myHeadwayTime * speed);
     122              :     // <=>  myGapControlGainSpace * g = - myGapControlGainSpeed * (leaderSpeed - speed) + myGapControlGainSpace * myHeadwayTime * speed;
     123              :     // <=>  g = - myGapControlGainSpeed * (leaderSpeed - speed) / myGapControlGainSpace + myHeadwayTime * speed;
     124     27485418 :     return myGapControlGainSpeed * (speed - leaderSpeed) / myGapControlGainSpace + myHeadwayTime * speed;
     125              : }
     126              : 
     127              : 
     128              : double
     129       162449 : MSCFModel_ACC::insertionFollowSpeed(const MSVehicle* const v, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle* const /*pred*/) const {
     130              : //#ifdef DEBUG_ACC
     131              : //        std::cout << "MSCFModel_ACC::insertionFollowSpeed(), speed="<<speed<< std::endl;
     132              : //#endif
     133              :     // iterate to find a stationary value for
     134              :     //    speed = followSpeed(v, speed, gap2pred, predSpeed, predMaxDecel, nullptr, CalcReason::FUTURE)
     135              :     const int max_iter = 50;
     136              :     int n_iter = 0;
     137              :     const double tol = 0.1;
     138              :     const double damping = 0.1;
     139              : 
     140              :     double res = speed;
     141      5026611 :     while (n_iter < max_iter) {
     142              :         // proposed acceleration
     143      4991126 :         const double a = SPEED2ACCEL(followSpeed(v, res, gap2pred, predSpeed, predMaxDecel, nullptr, CalcReason::FUTURE) - res);
     144      4991126 :         res = res + damping * a;
     145              : //#ifdef DEBUG_ACC
     146              : //        std::cout << "   n_iter=" << n_iter << ", a=" << a << ", res=" << res << std::endl;
     147              : //#endif
     148      4991126 :         if (fabs(a) < tol) {
     149              :             break;
     150              :         } else {
     151      4864162 :             n_iter++;
     152              :         }
     153              :     }
     154       162449 :     return res;
     155              : }
     156              : 
     157              : 
     158              : /// @todo update interactionGap logic
     159              : double
     160            0 : MSCFModel_ACC::interactionGap(const MSVehicle* const /*veh */, double /* vL */) const {
     161              :     /*maximum radar range is ACC is enabled*/
     162            0 :     return 250;
     163              : }
     164              : 
     165     14041954 : double MSCFModel_ACC::accelSpeedControl(double vErr) const {
     166              :     // Speed control law
     167     14041954 :     return mySpeedControlGain * vErr;
     168              : }
     169              : 
     170              : double
     171     18957267 : MSCFModel_ACC::accelGapControl(const MSVehicle* const /* veh */, const double gap2pred, const double speed, const double predSpeed, double vErr) const {
     172              :     // Gap control law
     173              :     double gclAccel = 0.0;
     174     18957267 :     const double deltaVel = predSpeed - speed;
     175              : 
     176              :     // see dynamic gap margin definition from (Xiao et. al, 2018)[3], equation 5 reformulated as min/max to avoid discontinuities
     177     18957267 :     const double d0 = MAX2(0., MIN2(75. / speed - 5., 2.));
     178              :     // this is equation 4, gap2pred is the difference in vehicle positions minus the length
     179     18957267 :     const double spacingErr = gap2pred - myHeadwayTime * speed - d0;
     180              : 
     181              : 
     182     18957267 :     if (fabs(spacingErr) < 0.2 && fabs(vErr) < 0.1) {
     183              :         // gap mode
     184         6404 :         gclAccel = myGapControlGainSpeed * deltaVel + myGapControlGainSpace * spacingErr;
     185              : #ifdef DEBUG_ACC
     186              :         if (DEBUG_COND) {
     187              :             std::cout << "        applying gap control:  spacingErr=" << spacingErr << " speedErr=" << vErr << std::endl;
     188              :         }
     189              : #endif
     190     18950863 :     } else if (spacingErr < 0)  {
     191              :         // collision avoidance mode
     192      3583228 :         gclAccel = myCollisionAvoidanceGainSpeed * deltaVel + myCollisionAvoidanceGainSpace * spacingErr;
     193              : #ifdef DEBUG_ACC
     194              :         if (DEBUG_COND) {
     195              :             std::cout << "        applying collision avoidance:  spacingErr=" << spacingErr << " speedErr=" << vErr << std::endl;
     196              :         }
     197              : #endif
     198              :     } else {
     199              :         // gap closing mode
     200     15367635 :         gclAccel = myGapClosingControlGainSpeed * deltaVel + myGapClosingControlGainSpace * spacingErr;
     201              : #ifdef DEBUG_ACC
     202              :         if (DEBUG_COND) {
     203              :             std::cout << "        applying gap closing:  spacingErr=" << spacingErr << " speedErr=" << vErr << std::endl;
     204              :         }
     205              : #endif
     206              :     }
     207     18957267 :     return gclAccel;
     208              : }
     209              : 
     210              : 
     211              : double
     212     32999221 : MSCFModel_ACC::_v(const MSVehicle* const veh, const double gap2pred, const double speed,
     213              :                   const double predSpeed, const double desSpeed, const bool /* respectMinGap */) const {
     214              : 
     215              :     double accelACC = 0;
     216              :     double gapLimit_SC = GAP_THRESHOLD_SPEEDCTRL; // lower gap limit in meters to enable speed control law
     217              :     double gapLimit_GC = GAP_THRESHOLD_GAPCTRL; // upper gap limit in meters to enable gap control law
     218              : 
     219              : #ifdef DEBUG_ACC
     220              :     if (DEBUG_COND) {
     221              :         std::cout << SIMTIME << " MSCFModel_ACC::_v() for veh '" << veh->getID() << "'\n"
     222              :                   << "        gap=" << gap2pred << " speed="  << speed << " predSpeed=" << predSpeed
     223              :                   << " desSpeed=" << desSpeed << " tau=" << myHeadwayTime << std::endl;
     224              :     }
     225              : #endif
     226              : 
     227              : 
     228              :     /* Velocity error */
     229     32999221 :     double vErr = speed - desSpeed;
     230              :     int setControlMode = 0;
     231              :     ACCVehicleVariables* vars = (ACCVehicleVariables*) veh->getCarFollowVariables();
     232     32999221 :     if (vars->lastUpdateTime != MSNet::getInstance()->getCurrentTimeStep()) {
     233      4233093 :         vars->lastUpdateTime = MSNet::getInstance()->getCurrentTimeStep();
     234              :         setControlMode = 1;
     235              :     }
     236     32999221 :     if (gap2pred > gapLimit_SC) {
     237              : 
     238              : #ifdef DEBUG_ACC
     239              :         if (DEBUG_COND) {
     240              :             std::cout << "        applying speedControl" << std::endl;
     241              :         }
     242              : #endif
     243              :         // Find acceleration - Speed control law
     244     14041588 :         accelACC = accelSpeedControl(vErr);
     245              :         // Set cl to vehicle parameters
     246     14041588 :         if (setControlMode) {
     247        19946 :             vars->ACC_ControlMode = 0;
     248              :         }
     249     18957633 :     } else if (gap2pred < gapLimit_GC) {
     250              :         // Find acceleration - Gap control law
     251     17963890 :         accelACC = accelGapControl(veh, gap2pred, speed, predSpeed, vErr);
     252              :         // Set cl to vehicle parameters
     253     17963890 :         if (setControlMode) {
     254      4212527 :             vars->ACC_ControlMode = 1;
     255              :         }
     256              :     } else {
     257              :         // Follow previous applied law
     258       993743 :         int cm = vars->ACC_ControlMode;
     259       993743 :         if (!cm) {
     260              : 
     261              : #ifdef DEBUG_ACC
     262              :             if (DEBUG_COND) {
     263              :                 std::cout << "        applying speedControl" << std::endl;
     264              :             }
     265              : #endif
     266          366 :             accelACC = accelSpeedControl(vErr);
     267              :         } else {
     268       993377 :             accelACC = accelGapControl(veh, gap2pred, speed, predSpeed, vErr);
     269              :         }
     270              : 
     271              :     }
     272              : 
     273     32999221 :     double newSpeed = speed + ACCEL2SPEED(accelACC);
     274              : 
     275              : #ifdef DEBUG_ACC
     276              :     if (DEBUG_COND) {
     277              :         std::cout << "        result: accel=" << accelACC << " newSpeed="  << newSpeed << std::endl;
     278              :     }
     279              : #endif
     280              : 
     281     32999221 :     return MAX2(0., newSpeed);
     282              : }
     283              : 
     284              : 
     285              : MSCFModel*
     286            0 : MSCFModel_ACC::duplicate(const MSVehicleType* vtype) const {
     287            0 :     return new MSCFModel_ACC(vtype);
     288              : }
        

Generated by: LCOV version 2.0-1