LCOV - code coverage report
Current view: top level - src/microsim/cfmodels - MSCFModel_SmartSK.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 45 54 83.3 %
Date: 2024-05-04 15:27:10 Functions: 9 10 90.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2012-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_SmartSK.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Michael Behrisch
      18             : /// @author  Peter Wagner
      19             : /// @date    Tue, 05 Jun 2012
      20             : ///
      21             : // A smarter SK
      22             : /****************************************************************************/
      23             : #include <config.h>
      24             : 
      25             : #include <map>
      26             : #include <microsim/MSVehicle.h>
      27             : #include <microsim/MSLane.h>
      28             : #include "MSCFModel_SmartSK.h"
      29             : #include <microsim/lcmodels/MSAbstractLaneChangeModel.h>
      30             : #include <utils/common/RandHelper.h>
      31             : 
      32             : //#define SmartSK_DEBUG
      33             : 
      34             : // ===========================================================================
      35             : // method definitions
      36             : // ===========================================================================
      37           7 : MSCFModel_SmartSK::MSCFModel_SmartSK(const MSVehicleType* vtype) :
      38             : // check whether setting these variables here with default values is ''good'' SUMO design
      39             : //        double tmp1=0.0, double tmp2=5.0, double tmp3=0.0, double tmp4, double tmp5)
      40             :     MSCFModel(vtype),
      41           7 :     myDawdle(vtype->getParameter().getCFParam(SUMO_ATTR_SIGMA, SUMOVTypeParameter::getDefaultImperfection(vtype->getParameter().vehicleClass))),
      42           7 :     myTauDecel(myDecel * myHeadwayTime),
      43           7 :     myTmp1(vtype->getParameter().getCFParam(SUMO_ATTR_TMP1, 1.0)),
      44           7 :     myTmp2(vtype->getParameter().getCFParam(SUMO_ATTR_TMP2, 1.0)),
      45           7 :     myTmp3(vtype->getParameter().getCFParam(SUMO_ATTR_TMP3, 1.0)),
      46           7 :     myTmp4(vtype->getParameter().getCFParam(SUMO_ATTR_TMP4, 1.0)),
      47          14 :     myTmp5(vtype->getParameter().getCFParam(SUMO_ATTR_TMP5, 1.0)) {
      48             :     // the variable tmp1 is the acceleration delay time, e.g. two seconds (or something like this).
      49             :     // for use in the upate process, a rule like if (v<myTmp1) vsafe = 0; is needed.
      50             :     // To have this, we have to transform myTmp1 (which is a time) into an equivalent speed. This is done by the
      51             :     // using the vsafe formula and computing:
      52             :     // v(t=myTmp1) = -myTauDecel + sqrt(myTauDecel*myTauDecel + accel*(accel + decel)*t*t + accel*decel*t*TS);
      53           7 :     double t = myTmp1;
      54           7 :     myS2Sspeed = -myTauDecel + sqrt(myTauDecel * myTauDecel + myAccel * (myAccel + myDecel) * t * t + myAccel * myDecel * t * TS);
      55             : #ifdef SmartSK_DEBUG
      56             :     std::cout << "# s2s-speed: " << myS2Sspeed << std::endl;
      57             : #endif
      58           7 :     if (myS2Sspeed > 5.0) {
      59           0 :         myS2Sspeed = 5.0;
      60             :     }
      61             : // double maxDeltaGap = -0.5*ACCEL2DIST(myDecel + myAccel);
      62           7 :     maxDeltaGap = -0.5 * (myDecel + myAccel) * TS * TS;
      63             : #ifdef SmartSK_DEBUG
      64             :     std::cout << "# maxDeltaGap = " << maxDeltaGap << std::endl;
      65             : #endif
      66           7 :     myTmp2 = TS / myTmp2;
      67           7 :     myTmp3 = sqrt(TS) * myTmp3;
      68           7 : }
      69             : 
      70             : 
      71          14 : MSCFModel_SmartSK::~MSCFModel_SmartSK() {}
      72             : 
      73             : 
      74             : double
      75       14950 : MSCFModel_SmartSK::finalizeSpeed(MSVehicle* const veh, double vPos) const {
      76       14950 :     const double vNext = MSCFModel::finalizeSpeed(veh, vPos);
      77       14950 :     updateMyHeadway(veh);
      78             :     SSKVehicleVariables* vars = (SSKVehicleVariables*)veh->getCarFollowVariables();
      79             : #ifdef SmartSK_DEBUG
      80             :     if (vars->ggOld.size() > 1) {
      81             :         std::cout << "# more than one entry in ggOld list. Speed is " << vPos << ", corresponding dist is " << vars->ggOld[(int) vPos] << "\n";
      82             :         for (std::map<int, double>::iterator I = vars->ggOld.begin(); I != vars->ggOld.end(); I++) {
      83             :             std::cout << "# " << (*I).first << ' ' << (*I).second << std::endl;
      84             :         }
      85             :     }
      86             : #endif
      87       14950 :     vars->gOld = vars->ggOld[(int) vPos];
      88             :     vars->ggOld.clear();
      89       14950 :     return vNext;
      90             : }
      91             : 
      92             : double
      93       14352 : MSCFModel_SmartSK::followSpeed(const MSVehicle* const veh, double speed, double gap, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const /*pred*/, const CalcReason /*usage*/) const {
      94             :     SSKVehicleVariables* vars = (SSKVehicleVariables*)veh->getCarFollowVariables();
      95             : 
      96             : // if (((gap - vars->gOld) < maxDeltaGap) && (speed>=5.0) && gap>=5.0) {
      97       14352 :     if ((gap - vars->gOld) < maxDeltaGap) {
      98           0 :         double tTauTest = gap / speed;
      99             : // allow  headway only to decrease only, never to increase. Increase is handled automatically by the headway dynamics in finalizeSpeed()!!!
     100           0 :         if ((tTauTest < vars->myHeadway) && (tTauTest > TS)) {
     101           0 :             vars->myHeadway = tTauTest;
     102             :         }
     103             :     }
     104             : 
     105       14352 :     double vsafe = _vsafe(veh, gap, predSpeed);
     106       14352 :     if ((speed <= 0.0) && (vsafe < myS2Sspeed)) {
     107             :         vsafe = 0;
     108             :     }
     109             : 
     110       28704 :     double vNew = MAX2(getSpeedAfterMaxDecel(speed), MIN2(vsafe, maxNextSpeed(speed, veh)));
     111             :     // there must be a better place to do the following assignment!!!
     112       14352 :     vars->gOld = gap;
     113       14352 :     vars->ggOld[(int)vNew] = gap;
     114       14352 :     return vNew;
     115             : }
     116             : 
     117             : double
     118       44850 : MSCFModel_SmartSK::stopSpeed(const MSVehicle* const veh, const double speed, double gap, double /*decel*/, const CalcReason /*usage*/) const {
     119             :     SSKVehicleVariables* vars = (SSKVehicleVariables*)veh->getCarFollowVariables();
     120             : 
     121             : // if (((gap - vars->gOld) < maxDeltaGap) && (speed>=5.0) && gap>=5.0) {
     122       44850 :     if ((gap - vars->gOld) < maxDeltaGap) {
     123           0 :         double tTauTest = gap / speed;
     124             : // allow  headway only to decrease only, never to increase. Increase is handled automatically by the headway dynamics in finalizeSpeed()!!!
     125           0 :         if ((tTauTest < vars->myHeadway) && (tTauTest > TS)) {
     126           0 :             vars->myHeadway = tTauTest;
     127             :         }
     128             :     }
     129             : 
     130       89700 :     return MAX2(getSpeedAfterMaxDecel(speed), MIN2(_vsafe(veh, gap, 0), maxNextSpeed(speed, veh)));
     131             : }
     132             : 
     133             : double
     134       14950 : MSCFModel_SmartSK::patchSpeedBeforeLC(const MSVehicle* veh, double /*vMin*/, double /*vMax*/) const {
     135       14950 :     return dawdle(veh->getSpeed(), veh->getRNG());
     136             : }
     137             : 
     138             : double
     139       14950 : MSCFModel_SmartSK::dawdle(double speed, SumoRNG* rng) const {
     140       14950 :     return MAX2(0., speed - ACCEL2SPEED(myDawdle * myAccel * RandHelper::rand(rng)));
     141             : }
     142             : 
     143             : 
     144             : /** Returns the SK-vsafe. */
     145       59202 : double MSCFModel_SmartSK::_vsafe(const MSVehicle* const veh, double gap, double predSpeed) const {
     146       59202 :     if (predSpeed == 0 && gap < 0.01) {
     147             :         return 0;
     148             :     }
     149             :     SSKVehicleVariables* vars = (SSKVehicleVariables*)veh->getCarFollowVariables();
     150             :     // this is the most obvious change to the normal SK: the model uses the variable vars->myHeadway instead of the constant
     151             :     // myHeadwayTime as the "desired headway" tau
     152       59202 :     double bTau = myDecel * (vars->myHeadway);
     153             :     double vsafe = (double)(-1. * bTau
     154       59202 :                             + sqrt(
     155       59202 :                                 bTau * bTau
     156       59202 :                                 + (predSpeed * predSpeed)
     157       59202 :                                 + (2. * myDecel * gap)
     158       59202 :                             ));
     159             :     assert(vsafe >= 0);
     160       59202 :     return vsafe;
     161             : }
     162             : 
     163             : 
     164             : MSCFModel*
     165           0 : MSCFModel_SmartSK::duplicate(const MSVehicleType* vtype) const {
     166           0 :     return new MSCFModel_SmartSK(vtype);
     167             : }

Generated by: LCOV version 1.14