LCOV - code coverage report
Current view: top level - src/microsim/cfmodels - MSCFModel_W99.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 61 68 89.7 %
Date: 2024-05-05 15:31:14 Functions: 6 8 75.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2011-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_W99.cpp
      15             : /// @author  Jakob Erdmann
      16             : /// @date    June 2019
      17             : ///
      18             : // The psycho-physical model of Wiedemann (10-Parameter version from 1999)
      19             : // references:
      20             : // code adapted from https://github.com/glgh/w99-demo
      21             : // (MIT License, Copyright (c) 2016 glgh)
      22             : /****************************************************************************/
      23             : #include <config.h>
      24             : 
      25             : #include <cmath>
      26             : #include "MSCFModel_W99.h"
      27             : #include <microsim/MSVehicle.h>
      28             : #include <microsim/MSLane.h>
      29             : #include <utils/common/RandHelper.h>
      30             : #include <utils/xml/SUMOXMLDefinitions.h>
      31             : 
      32             : 
      33             : // only used by DK2008
      34             : #define INTERACTION_GAP 150
      35             : 
      36             : // ===========================================================================
      37             : // DEBUG constants
      38             : // ===========================================================================
      39             : #define DEBUG_FOLLOW_SPEED
      40             : //#define DEBUG_COND (veh->getID() == "flow.0")
      41             : #define DEBUG_COND (veh->isSelected())
      42             : 
      43             : // ===========================================================================
      44             : // static members
      45             : // ===========================================================================
      46             : 
      47             : 
      48             : // ===========================================================================
      49             : // method definitions
      50             : // ===========================================================================
      51         287 : MSCFModel_W99::MSCFModel_W99(const MSVehicleType* vtype) :
      52             :     MSCFModel(vtype),
      53         287 :     myCC1(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC1,  1.30)),
      54         287 :     myCC2(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC2,  8.00)),
      55         287 :     myCC3(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC3, -12.00)),
      56         287 :     myCC4(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC4, -0.25)),
      57         287 :     myCC5(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC5,  0.35)),
      58         287 :     myCC6(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC6,  6.00)),
      59         287 :     myCC7(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC7,  0.25)),
      60         287 :     myCC8(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC8,  2.00)),
      61         574 :     myCC9(vtype->getParameter().getCFParam(SUMO_ATTR_CF_W99_CC9,  1.50)) {
      62             :     // translate some values to make them show up correctly in the gui
      63         287 :     myHeadwayTime = myCC1;
      64         287 :     myAccel = myCC8;
      65             :     // W99 does not drive very precise and may violate minGap on occasion
      66         287 :     myCollisionMinGapFactor = vtype->getParameter().getCFParam(SUMO_ATTR_COLLISION_MINGAP_FACTOR, 0.1);
      67         287 : }
      68             : 
      69             : 
      70         574 : MSCFModel_W99::~MSCFModel_W99() {}
      71             : 
      72             : 
      73             : void
      74    85465157 : MSCFModel_W99::computeThresholds(double speed, double predSpeed, double leaderAccel, double rndVal,
      75             :                                  double& sdxc, double& sdxo, double& sdxv) const {
      76             : 
      77    85465157 :     const double dv = predSpeed - speed;
      78    85465157 :     sdxc = myType->getMinGap(); // cc0
      79    85465157 :     if (predSpeed > 0) {
      80    85045510 :         const double v_slower = (dv >= 0 || leaderAccel < 1) ? speed : predSpeed + dv * rndVal;
      81   170037068 :         sdxc += myCC1 * MAX2(0.0, v_slower);
      82             :     }
      83    85465157 :     sdxo = sdxc + myCC2; //maximum following distance (upper limit of car-following process)
      84    85465157 :     sdxv = sdxo + myCC3 * (dv - myCC4);
      85    85465157 : }
      86             : 
      87             : 
      88             : double
      89    85465157 : MSCFModel_W99::followSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const pred, const CalcReason /*usage*/) const {
      90    85465157 :     const double dx = gap2pred + myType->getMinGap();
      91    85465157 :     const double dv = predSpeed - speed;
      92             : 
      93             :     const double cc0 = myType->getMinGap();
      94             : 
      95    85465157 :     const double leaderAccel = pred != nullptr ? pred->getAcceleration() : 0;
      96    85465157 :     const double oldAccel = veh->getAcceleration();
      97             : 
      98    85465157 :     const double rndVal = speed > 0 ? RandHelper::rand(veh->getRNG()) - 0.5 : 0.5;
      99             :     double sdxc, sdxo, sdxv;
     100    85465157 :     computeThresholds(speed, predSpeed, leaderAccel, rndVal, sdxc, sdxo, sdxv);
     101             : 
     102    85465157 :     const double sdv = myCC6 * dx * dx / 10000;
     103    85465157 :     const double sdvc = speed > 0 ? myCC4 - sdv : 0; //minimum closing dv
     104    85465157 :     const double sdvo = predSpeed > myCC5 ? sdv + myCC5 : sdv; //minimum opening dv
     105             : 
     106             :     double accel = 0; // resulting acceleration
     107             :     int status = 0;
     108             : 
     109    85465157 :     if (dv < sdvo && dx <= sdxc) {
     110             :         // 'Decelerate - Increase Distance';
     111             :         accel = 0;
     112             :         // code in addtion to w99-demo to fix collision (#10472)
     113     1095594 :         if (dx - SPEED2DIST(speed) < myType->getMinGap() * myCollisionMinGapFactor) {
     114             :             // prevent crashin in the next step
     115      409821 :             accel = -SPEED2ACCEL(speed);
     116             :             status = 9;
     117             :         }
     118     1095594 :         if (predSpeed > 0) {
     119     1086650 :             if (dv < 0) {
     120     1084028 :                 if (dx > cc0) {
     121     1062907 :                     accel = MIN2(leaderAccel + dv * dv / (cc0 - dx), 0.0);
     122             :                     status = 0;
     123             :                 } else {
     124       21121 :                     accel = MIN2(leaderAccel + 0.5 * (dv - sdvo), 0.0);
     125             :                     status = 1;
     126             :                 }
     127             :             }
     128     1086650 :             if (accel > -myCC7) {
     129             :                 accel = -myCC7;
     130             :                 status = 2;
     131             :             } else {
     132     1070197 :                 accel = MAX2(accel, -10 + 0.5 * sqrt(speed));
     133             :                 status = 3;
     134             :             }
     135             :         }
     136             : 
     137    84369563 :     } else if (dv < sdvc && dx < sdxv) {
     138             :         // 'Decelerate - Decrease Distance';
     139     2983809 :         accel = 0.5 * dv * dv / (sdxc - dx - 0.1);
     140     2983809 :         status = 4;
     141             :         // deceleration is capped by myEmergencyDecel in MSCFModel::finalizeSpeed
     142    81385754 :     } else if (dv < sdvo && dx < sdxo) {
     143             :         // 'Accelerate/Decelerate - Keep Distance';
     144     5664500 :         if (oldAccel <= 0) {
     145     4540240 :             accel = MIN2(oldAccel, -myCC7);
     146             :             status = 5;
     147             :         } else {
     148     1124260 :             accel = MAX2(oldAccel, myCC7);
     149             :             status = 6;
     150             :             // acceleration is capped at desired speed in MSCFModel::finalizeSpeed
     151             :         }
     152             :     } else {
     153             :         // 'Accelerate/Relax - Increase/Keep Speed';
     154    75721254 :         if (dx > sdxc) {
     155             :             //if (follower.status === 'w') {
     156             :             //    accel = cc7;
     157             :             //} else
     158             :             {
     159    77832420 :                 const double accelMax = myCC8 + myCC9 * MIN2(speed, 80 / 3.6) + RandHelper::rand(veh->getRNG());
     160    75705203 :                 if (dx < sdxo) {
     161     1140505 :                     accel = MIN2(dv * dv / (sdxo - dx), accelMax);
     162             :                     status = 7;
     163             :                 } else {
     164             :                     accel = accelMax;
     165             :                     status = 8;
     166             :                 }
     167             :             }
     168             :             // acceleration is capped at desired speed in MSCFModel::finalizeSpeed
     169             :         }
     170             :     }
     171    85465157 :     double vNew = speed + ACCEL2SPEED(accel);
     172             : #ifdef DEBUG_FOLLOW_SPEED
     173    85465157 :     if (DEBUG_COND) {
     174           0 :         std::cout << SIMTIME << " W99::fS veh=" << veh->getID() << " pred=" << Named::getIDSecure(pred)
     175             :                   << " v=" << speed << " pV=" << predSpeed << " g=" << gap2pred
     176             :                   << " dv=" << dv << " dx=" << dx
     177           0 :                   << " sdxc=" << sdxc << " sdxo=" << sdxo << " sdxv=" << sdxv << " sdv=" << sdv << " sdvo=" << sdvo << " sdvc=" << sdvc
     178             :                   << " st=" << status
     179           0 :                   << " a=" << accel << " V=" << vNew << "\n";
     180             :     }
     181             : #else
     182             :     UNUSED_PARAMETER(status);
     183             : #endif
     184    85465157 :     if (MSGlobals::gSemiImplicitEulerUpdate) {
     185             :         vNew = MAX2(0.0, vNew);
     186             :     }
     187    85465157 :     return vNew;
     188             : }
     189             : 
     190             : 
     191             : 
     192             : double
     193    36590572 : MSCFModel_W99::stopSpeed(const MSVehicle* const veh, const double speed, double gap, double decel, const CalcReason /*usage*/) const {
     194             :     // see reasoning in MSCFModel_Wiedemann::stopSpeed
     195    36590572 :     return MIN2(maximumSafeStopSpeed(gap, decel, speed, false, veh->getActionStepLengthSecs()), maxNextSpeed(speed, veh));
     196             : }
     197             : 
     198             : 
     199             : double
     200           0 : MSCFModel_W99::interactionGap(const MSVehicle* const, double vL) const {
     201             :     UNUSED_PARAMETER(vL);
     202           0 :     return INTERACTION_GAP;
     203             : }
     204             : 
     205             : 
     206             : MSCFModel*
     207           0 : MSCFModel_W99::duplicate(const MSVehicleType* vtype) const {
     208           0 :     return new MSCFModel_W99(vtype);
     209             : }

Generated by: LCOV version 1.14