LCOV - code coverage report
Current view: top level - src/microsim/cfmodels - MSCFModel_CACC.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 94.2 % 156 147
Test Date: 2026-06-15 15:46:12 Functions: 88.2 % 17 15

            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_CACC.cpp
      15              : /// @author  Kallirroi Porfyri
      16              : /// @author  Karagounis Vasilios
      17              : /// @date    Nov 2018
      18              : ///
      19              : // CACC car-following model based on [1], [2].
      20              : // [1] Milanes, V., and S. E. Shladover. Handling Cut-In Vehicles in Strings
      21              : //    of Cooperative Adaptive Cruise Control Vehicles. Journal of Intelligent
      22              : //     Transportation Systems, Vol. 20, No. 2, 2015, pp. 178-191.
      23              : // [2] Xiao, L., M. Wang and B. van Arem. Realistic Car-Following Models for
      24              : //    Microscopic Simulation of Adaptive and Cooperative Adaptive Cruise
      25              : //     Control Vehicles. Transportation Research Record: Journal of the
      26              : //     Transportation Research Board, No. 2623, 2017. (DOI: 10.3141/2623-01).
      27              : /****************************************************************************/
      28              : #include <config.h>
      29              : 
      30              : #include <stdio.h>
      31              : #include <iostream>
      32              : 
      33              : #include "MSCFModel_CACC.h"
      34              : #include <microsim/MSVehicle.h>
      35              : #include <microsim/MSLane.h>
      36              : #include <utils/common/RandHelper.h>
      37              : #include <utils/common/SUMOTime.h>
      38              : #include <utils/common/StringUtils.h>
      39              : #include <microsim/lcmodels/MSAbstractLaneChangeModel.h>
      40              : #include <math.h>
      41              : #include <microsim/MSNet.h>
      42              : 
      43              : // ===========================================================================
      44              : // debug flags
      45              : // ===========================================================================
      46              : #define DEBUG_CACC 0
      47              : #define DEBUG_CACC_INSERTION_FOLLOW_SPEED 0
      48              : #define DEBUG_CACC_SECURE_GAP 0
      49              : #define DEBUG_COND (veh->isSelected())
      50              : //#define DEBUG_COND (veh->getID() == "flow.0")
      51              : //#define DEBUG_COND (veh->getID() == "CVflowToC2.11")
      52              : 
      53              : 
      54              : // ===========================================================================
      55              : // defaults
      56              : // ===========================================================================
      57              : #define DEFAULT_SC_GAIN_CACC -0.4
      58              : #define DEFAULT_GCC_GAIN_GAP_CACC 0.005
      59              : #define DEFAULT_GCC_GAIN_GAP_DOT_CACC 0.05
      60              : #define DEFAULT_GC_GAIN_GAP_CACC 0.45
      61              : #define DEFAULT_GC_GAIN_GAP_DOT_CACC 0.0125
      62              : #define DEFAULT_CA_GAIN_GAP_CACC 0.45
      63              : #define DEFAULT_CA_GAIN_GAP_DOT_CACC 0.05
      64              : #define DEFAULT_HEADWAYTIME_ACC 1.0
      65              : #define DEFAULT_SC_MIN_GAP 1.66
      66              : 
      67              : // override followSpeed when deemed unsafe by the given margin (the value was selected to reduce the number of necessary interventions)
      68              : #define DEFAULT_EMERGENCY_OVERRIDE_THRESHOLD 2.0
      69              : 
      70              : std::map<std::string, MSCFModel_CACC::CommunicationsOverrideMode> MSCFModel_CACC::CommunicationsOverrideModeMap = {
      71              :     {"0", CACC_NO_OVERRIDE},
      72              :     {"1", CACC_MODE_NO_LEADER},
      73              :     {"2", CACC_MODE_LEADER_NO_CAV},
      74              :     {"3", CACC_MODE_LEADER_CAV}
      75              : };
      76              : 
      77              : std::map<MSCFModel_CACC::VehicleMode, std::string> MSCFModel_CACC::VehicleModeNames = {
      78              :     {CC_MODE, "CC"},
      79              :     {ACC_MODE, "ACC"},
      80              :     {CACC_GAP_CLOSING_MODE, "CACC_GAP_CL"},
      81              :     {CACC_GAP_MODE, "CACC_GAP"},
      82              :     {CACC_COLLISION_AVOIDANCE_MODE, "CACC_CA"}
      83              : };
      84              : 
      85              : // ===========================================================================
      86              : // method definitions
      87              : // ===========================================================================
      88          450 : MSCFModel_CACC::MSCFModel_CACC(const MSVehicleType* vtype) :
      89          450 :     MSCFModel(vtype), acc_CFM(MSCFModel_ACC(vtype)),
      90          450 :     mySpeedControlGain(vtype->getParameter().getCFParam(SUMO_ATTR_SC_GAIN_CACC, DEFAULT_SC_GAIN_CACC)),
      91          450 :     myGapClosingControlGainGap(vtype->getParameter().getCFParam(SUMO_ATTR_GCC_GAIN_GAP_CACC, DEFAULT_GCC_GAIN_GAP_CACC)),
      92          450 :     myGapClosingControlGainGapDot(vtype->getParameter().getCFParam(SUMO_ATTR_GCC_GAIN_GAP_DOT_CACC, DEFAULT_GCC_GAIN_GAP_DOT_CACC)),
      93          450 :     myGapControlGainGap(vtype->getParameter().getCFParam(SUMO_ATTR_GC_GAIN_GAP_CACC, DEFAULT_GC_GAIN_GAP_CACC)),
      94          450 :     myGapControlGainGapDot(vtype->getParameter().getCFParam(SUMO_ATTR_GC_GAIN_GAP_DOT_CACC, DEFAULT_GC_GAIN_GAP_DOT_CACC)),
      95          450 :     myCollisionAvoidanceGainGap(vtype->getParameter().getCFParam(SUMO_ATTR_CA_GAIN_GAP_CACC, DEFAULT_CA_GAIN_GAP_CACC)),
      96          450 :     myCollisionAvoidanceGainGapDot(vtype->getParameter().getCFParam(SUMO_ATTR_CA_GAIN_GAP_DOT_CACC, DEFAULT_CA_GAIN_GAP_DOT_CACC)),
      97          450 :     myHeadwayTimeACC(vtype->getParameter().getCFParam(SUMO_ATTR_HEADWAY_TIME_CACC_TO_ACC, DEFAULT_HEADWAYTIME_ACC)),
      98          450 :     myApplyDriverstate(vtype->getParameter().getCFParam(SUMO_ATTR_APPLYDRIVERSTATE, 0)),
      99          450 :     myEmergencyThreshold(vtype->getParameter().getCFParam(SUMO_ATTR_CA_OVERRIDE, DEFAULT_EMERGENCY_OVERRIDE_THRESHOLD)),
     100          900 :     mySpeedControlMinGap(vtype->getParameter().getCFParam(SUMO_ATTR_SC_MIN_GAP, DEFAULT_SC_MIN_GAP)) {
     101          450 :     myCollisionMinGapFactor = vtype->getParameter().getCFParam(SUMO_ATTR_COLLISION_MINGAP_FACTOR, 0.1);
     102          450 :     acc_CFM.setHeadwayTime(myHeadwayTimeACC);
     103          450 : }
     104              : 
     105          898 : MSCFModel_CACC::~MSCFModel_CACC() {}
     106              : 
     107              : 
     108              : void
     109           10 : MSCFModel_CACC::CACCVehicleVariables::saveState(OutputDevice& out, const MSCFModel& /*cfm*/) const {
     110           10 :     out.openTag(SUMO_TAG_CFM_VARIABLES);
     111           10 :     out.writeAttr(SUMO_ATTR_ID, "CACC");
     112           10 :     std::ostringstream internals;
     113           10 :     internals << CACC_ControlMode << " ";
     114           10 :     internals << CACC_CommunicationsOverrideMode;
     115           10 :     out.writeAttr(SUMO_ATTR_STATE, internals.str());
     116           10 :     out.closeTag();
     117           10 : }
     118              : 
     119              : 
     120              : void
     121           10 : MSCFModel_CACC::CACCVehicleVariables::loadState(const SUMOSAXAttributes& attrs) {
     122           10 :     bool ok = true;
     123           10 :     const std::string cfmID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
     124           10 :     if (cfmID != "CACC") {
     125            0 :         throw ProcessError(TLF("incompatible carFollowModel '%' when loading state for CACC", cfmID));
     126              :     }
     127           10 :     std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
     128           10 :     bis >> CACC_ControlMode;
     129              :     int mode;
     130           10 :     bis >> mode;
     131           10 :     CACC_CommunicationsOverrideMode = (CommunicationsOverrideMode)mode;
     132           20 : }
     133              : 
     134              : double
     135      8125873 : MSCFModel_CACC::freeSpeed(const MSVehicle* const veh, double speed, double seen, double maxSpeed, const bool onInsertion, const CalcReason usage) const {
     136      8125873 :     if (!MSGlobals::gComputeLC && usage == CalcReason::CURRENT) {
     137              :         CACCVehicleVariables* vars = (CACCVehicleVariables*)veh->getCarFollowVariables();
     138      8118788 :         if (vars->lastUpdateTime != MSNet::getInstance()->getCurrentTimeStep()) {
     139              :             // _v was not called in this step
     140       934738 :             const_cast<SUMOVehicleParameter&>(veh->getParameter()).setParameter("caccVehicleMode", VehicleModeNames[CC_MODE]);
     141              :         }
     142              :     }
     143      8125873 :     return MSCFModel::freeSpeed(veh, speed, seen, maxSpeed, onInsertion, usage);
     144              : }
     145              : 
     146              : double
     147     25692662 : MSCFModel_CACC::followSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle* const pred, const CalcReason usage) const {
     148     25692662 :     if (myApplyDriverstate) {
     149        51045 :         applyHeadwayAndSpeedDifferencePerceptionErrors(veh, speed, gap2pred, predSpeed, predMaxDecel, pred);
     150              :     }
     151              : 
     152     25692662 :     const double desSpeed = veh->getLane()->getVehicleMaxSpeed(veh);
     153     25692662 :     const double vCACC = _v(veh, pred, gap2pred, speed, predSpeed, desSpeed, true, usage);
     154              :     // using onInsertion=true disables emergencyOverides emergency deceleration smoothing
     155     25692662 :     const double vSafe = maximumSafeFollowSpeed(gap2pred, speed, predSpeed, predMaxDecel, true);
     156              : 
     157              : #if DEBUG_CACC == 1
     158              :     if (DEBUG_COND) {
     159              :         std::cout << SIMTIME << " veh=" << veh->getID() << " pred=" << Named::getIDSecure(pred)
     160              :                   << " v=" << speed << " vL=" << predSpeed << " gap=" << gap2pred
     161              :                   << " predDecel=" << predMaxDecel << " vCACC=" << vCACC << " vSafe=" << vSafe << "\n";
     162              :     }
     163              : #else
     164              :     UNUSED_PARAMETER(pred);
     165              : #endif
     166     25692662 :     const double speedOverride = MIN2(myEmergencyThreshold, gap2pred);
     167     25692662 :     if (vSafe + speedOverride < vCACC) {
     168              : #if DEBUG_CACC == 1
     169              :         if (DEBUG_COND) {
     170              :             std::cout << "Apply Safe speed, override=" << speedOverride << "\n";
     171              :         }
     172              : #endif
     173              :         return MAX2(0.0, vSafe + speedOverride);
     174              :     }
     175              :     return vCACC;
     176              : }
     177              : 
     178              : double
     179     10886784 : MSCFModel_CACC::stopSpeed(const MSVehicle* const veh, const double speed, double gap, double decel, const CalcReason /*usage*/) const {
     180     10886784 :     if (myApplyDriverstate) {
     181         2728 :         applyHeadwayPerceptionError(veh, speed, gap);
     182              :     }
     183              : 
     184              :     // NOTE: This allows return of smaller values than minNextSpeed().
     185              :     // Only relevant for the ballistic update: We give the argument headway=TS, to assure that
     186              :     // the stopping position is approached with a uniform deceleration also for tau!=TS.
     187     10886784 :     return MIN2(maximumSafeStopSpeed(gap, decel, speed, false, veh->getActionStepLengthSecs()), maxNextSpeed(speed, veh));
     188              : }
     189              : 
     190              : double
     191     28262475 : MSCFModel_CACC::getSecureGap(const MSVehicle* const veh, const MSVehicle* const pred, const double speed, const double leaderSpeed, const double leaderMaxDecel) const {
     192              :     // Accel in gap mode should vanish:
     193              :     double desSpacing;
     194     28262475 :     if (pred->getCarFollowModel().getModelID() != SUMO_TAG_CF_CACC) {
     195              :         //      0 = myGapControlGainSpeed * (leaderSpeed - speed) + myGapControlGainSpace * (g - myHeadwayTime * speed);
     196              :         // <=>  myGapControlGainSpace * g = - myGapControlGainSpeed * (leaderSpeed - speed) + myGapControlGainSpace * myHeadwayTime * speed;
     197              :         // <=>  g = - myGapControlGainSpeed * (leaderSpeed - speed) / myGapControlGainSpace + myHeadwayTime * speed;
     198       109442 :         desSpacing = acc_CFM.myGapControlGainSpeed * (speed - leaderSpeed) / acc_CFM.myGapControlGainSpace + myHeadwayTimeACC * speed; // MSCFModel_ACC::accelGapControl
     199              :     } else {
     200     28153033 :         desSpacing = myHeadwayTime * speed; // speedGapControl
     201              :     }
     202     28262475 :     const double desSpacingDefault = MSCFModel::getSecureGap(veh, pred, speed, leaderSpeed, leaderMaxDecel);
     203              : #if DEBUG_CACC_SECURE_GAP == 1
     204              :     std::cout << SIMTIME << "MSCFModel_ACC::getSecureGap speed=" << speed << " leaderSpeed=" << leaderSpeed
     205              :               << " desSpacing=" << desSpacing << " desSpacingDefault=" << desSpacingDefault << "\n";
     206              : #endif
     207     28262475 :     return MAX2(desSpacing, desSpacingDefault);
     208              : }
     209              : 
     210              : 
     211              : double
     212       313833 : MSCFModel_CACC::insertionFollowSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle* const pred) const {
     213              : #if DEBUG_CACC_INSERTION_FOLLOW_SPEED == 1
     214              :     if (DEBUG_COND) {
     215              :         std::cout << "MSCFModel_ACC::insertionFollowSpeed(), speed=" << speed << " gap2pred=" << gap2pred << " predSpeed=" << predSpeed << "\n";
     216              :     }
     217              : #endif
     218              :     // iterate to find a stationary value for
     219              :     //    speed = followSpeed(v, speed, gap2pred, predSpeed, predMaxDecel, nullptr, CalcReason::FUTURE)
     220              :     const int max_iter = 50;
     221              :     int n_iter = 0;
     222              :     const double tol = 0.1;
     223              :     double damping = 0.8;
     224              : 
     225              :     double res = speed;
     226      3377678 :     while (n_iter < max_iter) {
     227              :         // proposed acceleration
     228      3354708 :         const double vCACC = _v(veh, pred, gap2pred, res, predSpeed, speed, true);
     229      3354708 :         const double vSafe = maximumSafeFollowSpeed(gap2pred, res, predSpeed, predMaxDecel, true);
     230      3354708 :         const double a = MIN2(vCACC, vSafe) - res;
     231      3354708 :         res = res + damping * a;
     232              : #if DEBUG_CACC_INSERTION_FOLLOW_SPEED == 1
     233              :         if (DEBUG_COND) {
     234              :             std::cout << "   n_iter=" << n_iter << " vSafe=" << vSafe << " vCACC=" << vCACC << " a=" << a << " damping=" << damping << " res=" << res << std::endl;
     235              :         }
     236              : #endif
     237      3354708 :         damping *= 0.9;
     238      3354708 :         if (fabs(a) < tol) {
     239              :             break;
     240              :         } else {
     241      3063845 :             n_iter++;
     242              :         }
     243              :     }
     244       313833 :     return res;
     245              : }
     246              : 
     247              : 
     248              : 
     249              : 
     250              : /// @todo update interactionGap logic
     251              : double
     252            0 : MSCFModel_CACC::interactionGap(const MSVehicle* const /* veh */, double /* vL */) const {
     253              :     /*maximum radar range is CACC is enabled*/
     254            0 :     return 250;
     255              : }
     256              : 
     257              : 
     258              : std::string
     259           12 : MSCFModel_CACC::getParameter(const MSVehicle* veh, const std::string& key) const {
     260              :     CACCVehicleVariables* vars = (CACCVehicleVariables*) veh->getCarFollowVariables();
     261              : 
     262           12 :     if (key.compare("caccCommunicationsOverrideMode") == 0) {
     263           12 :         return toString(vars->CACC_CommunicationsOverrideMode);
     264              :     }
     265              : 
     266            0 :     return "";
     267              : }
     268              : 
     269              : 
     270              : void
     271           12 : MSCFModel_CACC::setParameter(MSVehicle* veh, const std::string& key, const std::string& value) const {
     272              :     CACCVehicleVariables* vars = (CACCVehicleVariables*) veh->getCarFollowVariables();
     273              : 
     274              :     try {
     275           12 :         if (key.compare("caccCommunicationsOverrideMode") == 0) {
     276           12 :             vars->CACC_CommunicationsOverrideMode = CommunicationsOverrideModeMap[value];
     277              :         }
     278            0 :     } catch (NumberFormatException&) {
     279            0 :         throw InvalidArgument("Invalid value '" + value + "' for parameter '" + key + "' for vehicle '" + veh->getID() + "'");
     280            0 :     }
     281           12 : }
     282              : 
     283              : 
     284              : double
     285     22643653 : MSCFModel_CACC::speedSpeedControl(const double speed, double vErr, VehicleMode& vehMode) const {
     286              :     // Speed control law
     287     22643653 :     vehMode = CC_MODE;
     288     22643653 :     double sclAccel = mySpeedControlGain * vErr;
     289     22643653 :     double newSpeed = speed + ACCEL2SPEED(sclAccel);
     290     22643653 :     return newSpeed;
     291              : }
     292              : 
     293              : double
     294      7886570 : MSCFModel_CACC::speedGapControl(const MSVehicle* const veh, const double gap2pred,
     295              :                                 const double speed, const double predSpeed, const double desSpeed, double vErr,
     296              :                                 const MSVehicle* const pred, VehicleMode& vehMode) const {
     297              :     // Gap control law
     298              :     double newSpeed = 0.0;
     299              : 
     300      7886570 :     if (pred != nullptr) {
     301      6402694 :         if (pred->getCarFollowModel().getModelID() != SUMO_TAG_CF_CACC) {
     302        51961 :             vehMode = ACC_MODE;
     303        51961 :             newSpeed = acc_CFM._v(veh, gap2pred, speed, predSpeed, desSpeed, true);
     304              : #if DEBUG_CACC == 1
     305              :             if (DEBUG_COND) {
     306              :                 std::cout << "        acc control mode" << std::endl;
     307              :             }
     308              : #endif
     309              :         } else {
     310              : #if DEBUG_CACC == 1
     311              :             if (DEBUG_COND) {
     312              :                 std::cout << "        CACC control mode" << std::endl;
     313              :             }
     314              : #endif
     315      6350733 :             double desSpacing = myHeadwayTime * speed;
     316      6350733 :             double spacingErr = gap2pred - desSpacing;
     317      6350733 :             double accel = veh->getAcceleration();
     318      6350733 :             double speedErr = predSpeed - speed - myHeadwayTime * accel;
     319              : 
     320      6350733 :             if ((spacingErr > 0 && spacingErr < 0.2) && (vErr < 0.1)) {
     321              :                 // gap mode
     322              :                 //newSpeed = speed + 0.45 * spacingErr + 0.0125 *speedErr;
     323              : #if DEBUG_CACC == 1
     324              :                 if (DEBUG_COND) {
     325              :                     std::cout << "        applying gap control:  err=" << spacingErr << " speedErr=" << speedErr << std::endl;
     326              :                 }
     327              : #endif
     328       304136 :                 newSpeed = speed + myGapControlGainGap * spacingErr + myGapControlGainGapDot * speedErr;
     329              : 
     330       304136 :                 vehMode = CACC_GAP_MODE;
     331      2657207 :             } else if (spacingErr < 0) {
     332              :                 // collision avoidance mode
     333              :                 //newSpeed = speed + 0.45 * spacingErr + 0.05 *speedErr;
     334              : #if DEBUG_CACC == 1
     335              :                 if (DEBUG_COND) {
     336              :                     std::cout << "        applying collision avoidance:  err=" << spacingErr << " speedErr=" << speedErr << "\n";
     337              :                 }
     338              : #endif
     339      2650495 :                 newSpeed = speed + myCollisionAvoidanceGainGap * spacingErr + myCollisionAvoidanceGainGapDot * speedErr;
     340      2650495 :                 vehMode = CACC_COLLISION_AVOIDANCE_MODE;
     341              :             } else {
     342              :                 // gap closing mode
     343              : #if DEBUG_CACC == 1
     344              :                 if (DEBUG_COND) {
     345              :                     std::cout << "        applying gap closing err=" << spacingErr << " speedErr=" << speedErr << " predSpeed=" << predSpeed << " speed=" << speed << " accel=" << accel << "\n";
     346              :                 }
     347              : #endif
     348      3396102 :                 newSpeed = speed + myGapClosingControlGainGap * spacingErr + myGapClosingControlGainGapDot * speedErr;
     349              : 
     350      3396102 :                 vehMode = CACC_GAP_CLOSING_MODE;
     351              :             }
     352              :         }
     353              :     } else {
     354              :         /* no leader */
     355              : #if DEBUG_CACC == 1
     356              :         if (DEBUG_COND) {
     357              :             std::cout << "        no leader" << std::endl;
     358              :         }
     359              : #endif
     360      1483876 :         newSpeed = speedSpeedControl(speed, vErr, vehMode);
     361              :     }
     362              : 
     363      7886570 :     return newSpeed;
     364              : }
     365              : 
     366              : double
     367     29047370 : MSCFModel_CACC::_v(const MSVehicle* const veh, const MSVehicle* const pred, const double gap2pred, const double speed,
     368              :                    const double predSpeed, const double desSpeed, const bool /* respectMinGap */, const CalcReason usage) const {
     369              :     double newSpeed = 0.0;
     370     29047370 :     VehicleMode vehMode = CC_MODE;
     371              : 
     372              : #if DEBUG_CACC == 1
     373              :     if (DEBUG_COND) {
     374              :         std::cout << SIMTIME << " MSCFModel_CACC::_v() for veh '" << veh->getID()
     375              :                   << " gap=" << gap2pred << " speed="  << speed << " predSpeed=" << predSpeed
     376              :                   << " desSpeed=" << desSpeed << std::endl;
     377              :     }
     378              : #endif
     379              : 
     380              :     /* Velocity error */
     381     29047370 :     double vErr = speed - desSpeed;
     382              :     bool setControlMode = false;
     383              :     CACCVehicleVariables* vars = (CACCVehicleVariables*)veh->getCarFollowVariables();
     384     29047370 :     if (vars->lastUpdateTime != MSNet::getInstance()->getCurrentTimeStep()) {
     385      4152853 :         vars->lastUpdateTime = MSNet::getInstance()->getCurrentTimeStep();
     386              :         setControlMode = true;
     387              :     }
     388              : 
     389     29047370 :     CommunicationsOverrideMode commMode = vars->CACC_CommunicationsOverrideMode;
     390              : 
     391     29047370 :     if (commMode == CACC_NO_OVERRIDE) { // old CACC logic (rely on time gap from predecessor)
     392              :         // @note: using (gap2pred + minGap) here increases oscillations but may
     393              :         // actually be a good idea once the acceleration-spike-problem is fixed
     394     29045837 :         double time_gap = gap2pred / MAX2(NUMERICAL_EPS, speed);
     395     29045837 :         double spacingErr = gap2pred - myHeadwayTime * speed;
     396              : 
     397     29045837 :         if (time_gap > 2 && spacingErr > mySpeedControlMinGap) {
     398              : #if DEBUG_CACC == 1
     399              :             if (DEBUG_COND) {
     400              :                 std::cout << "        applying speedControl" << "  time_gap=" << time_gap << std::endl;
     401              :             }
     402              : #endif
     403              :             // Find acceleration - Speed control law
     404     16680113 :             newSpeed = speedSpeedControl(speed, vErr, vehMode);
     405              :             // Set cl to vehicle parameters
     406     16680113 :             if (setControlMode) {
     407       934196 :                 vars->CACC_ControlMode = 0;
     408              :             }
     409     12365724 :         } else if (time_gap < 1.5) {
     410              :             // Find acceleration - Gap control law
     411              : #if DEBUG_CACC == 1
     412              :             if (DEBUG_COND) {
     413              :                 std::cout << "        speedGapControl" << "  time_gap=" << time_gap << std::endl;
     414              :             }
     415              : #endif
     416              : 
     417      6189380 :             newSpeed = speedGapControl(veh, gap2pred, speed, predSpeed, desSpeed, vErr, pred, vehMode);
     418              :             // Set cl to vehicle parameters
     419      6189380 :             if (setControlMode) {
     420      1298695 :                 vars->CACC_ControlMode = 1;
     421              :             }
     422              :         } else {
     423              :             // Follow previous applied law
     424      6176344 :             int cm = vars->CACC_ControlMode;
     425      6176344 :             if (!cm) {
     426              :                 // CACC_ControlMode = speed control
     427              : 
     428              : #if DEBUG_CACC == 1
     429              :                 if (DEBUG_COND) {
     430              :                     std::cout << "        applying speedControl (previous)" <<  "  time_gap=" << time_gap << std::endl;
     431              :                 }
     432              : #endif
     433      4479154 :                 newSpeed = speedSpeedControl(speed, vErr, vehMode);
     434              :             } else {
     435              :                 // CACC_ControlMode = gap control
     436              : #if DEBUG_CACC == 1
     437              :                 if (DEBUG_COND) {
     438              :                     std::cout << "        previous speedGapControl (previous)" << "  time_gap=" << time_gap << std::endl;
     439              :                 }
     440              : #endif
     441      1697190 :                 newSpeed = speedGapControl(veh, gap2pred, speed, predSpeed, desSpeed, vErr, pred, vehMode);
     442              :             }
     443              :         }
     444         1533 :     } else if (commMode == CACC_MODE_NO_LEADER) {
     445          510 :         newSpeed = speedSpeedControl(speed, vErr, vehMode);
     446         1023 :     } else if (commMode == CACC_MODE_LEADER_NO_CAV) {
     447          510 :         newSpeed = acc_CFM._v(veh, gap2pred, speed, predSpeed, desSpeed, true);
     448          510 :         vehMode = ACC_MODE;
     449          513 :     } else if (commMode == CACC_MODE_LEADER_CAV) {
     450          513 :         double desSpacing = myHeadwayTime * speed;
     451          513 :         double spacingErr = gap2pred - desSpacing;
     452          513 :         double accel = veh->getAcceleration();
     453          513 :         double speedErr = predSpeed - speed - myHeadwayTime * accel;
     454              : 
     455          513 :         if ((spacingErr > 0 && spacingErr < 0.2) && (vErr < 0.1)) {
     456              :             // gap mode
     457              :             //newSpeed = speed + 0.45 * spacingErr + 0.0125 *speedErr;
     458          252 :             if (DEBUG_COND) {
     459              :                 std::cout << "        applying CACC_GAP_MODE " << std::endl;
     460              :             }
     461          252 :             newSpeed = speed + myGapControlGainGap * spacingErr + myGapControlGainGapDot * speedErr;
     462          252 :             vehMode = CACC_GAP_MODE;
     463           24 :         } else if (spacingErr < 0) {
     464              :             // collision avoidance mode
     465              :             //newSpeed = speed + 0.45 * spacingErr + 0.05 *speedErr;
     466           24 :             if (DEBUG_COND) {
     467              :                 std::cout << "        applying CACC_COLLISION_AVOIDANCE_MODE " << std::endl;
     468              :             }
     469           24 :             newSpeed = speed + myCollisionAvoidanceGainGap * spacingErr + myCollisionAvoidanceGainGapDot * speedErr;
     470           24 :             vehMode = CACC_COLLISION_AVOIDANCE_MODE;
     471              :         } else {
     472              :             // gap closing mode
     473          237 :             if (DEBUG_COND) {
     474              :                 std::cout << "        applying CACC_GAP_CLOSING_MODE " << std::endl;
     475              :             }
     476          237 :             newSpeed = speed + myGapClosingControlGainGap * spacingErr + myGapClosingControlGainGapDot * speedErr;
     477          237 :             vehMode = CACC_GAP_CLOSING_MODE;
     478              :         }
     479              :     }
     480              : 
     481      8410768 :     if (setControlMode && !MSGlobals::gComputeLC && usage == CalcReason::CURRENT) {
     482      8289194 :         const_cast<SUMOVehicleParameter&>(veh->getParameter()).setParameter("caccVehicleMode", VehicleModeNames[vehMode]);
     483              :     }
     484              : 
     485              :     //std::cout << veh->getID() << " commMode: " << commMode << ", caccVehicleMode: " << VehicleModeNames[vehMode]
     486              :     //            << ", gap2pred: " << gap2pred << ", newSpeed: " << newSpeed << std::endl;
     487              : 
     488              :     // newSpeed is meant for step length 0.1 but this would cause extreme
     489              :     // accelerations at lower step length
     490              :     double newSpeedScaled = newSpeed;
     491     29047370 :     if (DELTA_T < 100) {
     492        49788 :         const double accel01 = (newSpeed - speed) * 10;
     493        49788 :         newSpeedScaled = speed + ACCEL2SPEED(accel01);
     494              :     }
     495              : 
     496              : #if DEBUG_CACC == 1
     497              :     if (DEBUG_COND) {
     498              :         std::cout << "        result: rawAccel=" << SPEED2ACCEL(newSpeed - speed) << " newSpeed=" << newSpeed << " newSpeedScaled=" << newSpeedScaled << "\n";
     499              :     }
     500              : #endif
     501              : 
     502     29047370 :     return MAX2(0., newSpeedScaled);
     503              : }
     504              : 
     505              : 
     506              : 
     507              : MSCFModel*
     508            0 : MSCFModel_CACC::duplicate(const MSVehicleType* vtype) const {
     509            0 :     return new MSCFModel_CACC(vtype);
     510              : }
        

Generated by: LCOV version 2.0-1