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

            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     85507937 : MSCFModel_W99::computeThresholds(double speed, double predSpeed, double leaderAccel, double rndVal,
      75              :                                  double& sdxc, double& sdxo, double& sdxv) const {
      76              : 
      77     85507937 :     const double dv = predSpeed - speed;
      78     85507937 :     sdxc = myType->getMinGap(); // cc0
      79     85507937 :     if (predSpeed > 0) {
      80     85081120 :         const double v_slower = (dv >= 0 || leaderAccel < 1) ? speed : predSpeed + dv * rndVal;
      81    170108309 :         sdxc += myCC1 * MAX2(0.0, v_slower);
      82              :     }
      83     85507937 :     sdxo = sdxc + myCC2; //maximum following distance (upper limit of car-following process)
      84     85507937 :     sdxv = sdxo + myCC3 * (dv - myCC4);
      85     85507937 : }
      86              : 
      87              : 
      88              : double
      89     85507937 : MSCFModel_W99::followSpeed(const MSVehicle* const veh, double speed, double gap2pred, double predSpeed, double /*predMaxDecel*/, const MSVehicle* const pred, const CalcReason /*usage*/) const {
      90     85507937 :     const double dx = gap2pred + myType->getMinGap();
      91     85507937 :     const double dv = predSpeed - speed;
      92              : 
      93              :     const double cc0 = myType->getMinGap();
      94              : 
      95     85507937 :     const double leaderAccel = pred != nullptr ? pred->getAcceleration() : 0;
      96     85507937 :     const double oldAccel = veh->getAcceleration();
      97              : 
      98     85507937 :     const double rndVal = speed > 0 ? RandHelper::rand(veh->getRNG()) - 0.5 : 0.5;
      99              :     double sdxc, sdxo, sdxv;
     100     85507937 :     computeThresholds(speed, predSpeed, leaderAccel, rndVal, sdxc, sdxo, sdxv);
     101              : 
     102     85507937 :     const double sdv = myCC6 * dx * dx / 10000;
     103     85507937 :     const double sdvc = speed > 0 ? myCC4 - sdv : 0; //minimum closing dv
     104     85507937 :     const double sdvo = predSpeed > myCC5 ? sdv + myCC5 : sdv; //minimum opening dv
     105              : 
     106              :     double accel = 0; // resulting acceleration
     107              :     int status = 0;
     108              : 
     109     85507937 :     if (dv < sdvo && dx <= sdxc) {
     110              :         // 'Decelerate - Increase Distance';
     111              :         accel = 0;
     112              :         // code in addtion to w99-demo to fix collision (#10472)
     113      1097499 :         if (dx - SPEED2DIST(speed) < myType->getMinGap() * myCollisionMinGapFactor) {
     114              :             // prevent crashin in the next step
     115       410343 :             accel = -SPEED2ACCEL(speed);
     116              :             status = 9;
     117              :         }
     118      1097499 :         if (predSpeed > 0) {
     119      1088051 :             if (dv < 0) {
     120      1085354 :                 if (dx > cc0) {
     121      1063834 :                     accel = MIN2(leaderAccel + dv * dv / (cc0 - dx), 0.0);
     122              :                     status = 0;
     123              :                 } else {
     124        21520 :                     accel = MIN2(leaderAccel + 0.5 * (dv - sdvo), 0.0);
     125              :                     status = 1;
     126              :                 }
     127              :             }
     128      1088051 :             if (accel > -myCC7) {
     129              :                 accel = -myCC7;
     130              :                 status = 2;
     131              :             } else {
     132      1071244 :                 accel = MAX2(accel, -10 + 0.5 * sqrt(speed));
     133              :                 status = 3;
     134              :             }
     135              :         }
     136              : 
     137     84410438 :     } else if (dv < sdvc && dx < sdxv) {
     138              :         // 'Decelerate - Decrease Distance';
     139      2992290 :         accel = 0.5 * dv * dv / (sdxc - dx - 0.1);
     140      2992290 :         status = 4;
     141              :         // deceleration is capped by myEmergencyDecel in MSCFModel::finalizeSpeed
     142     81418148 :     } else if (dv < sdvo && dx < sdxo) {
     143              :         // 'Accelerate/Decelerate - Keep Distance';
     144      5667953 :         if (oldAccel <= 0) {
     145      4542310 :             accel = MIN2(oldAccel, -myCC7);
     146              :             status = 5;
     147              :         } else {
     148      1125643 :             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     75750195 :         if (dx > sdxc) {
     155              :             //if (follower.status === 'w') {
     156              :             //    accel = cc7;
     157              :             //} else
     158              :             {
     159     77859963 :                 const double accelMax = myCC8 + myCC9 * MIN2(speed, 80 / 3.6) + RandHelper::rand(veh->getRNG());
     160     75733715 :                 if (dx < sdxo) {
     161      1146958 :                     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     85507937 :     double vNew = speed + ACCEL2SPEED(accel);
     172              : #ifdef DEBUG_FOLLOW_SPEED
     173     85507937 :     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     85507937 :     if (MSGlobals::gSemiImplicitEulerUpdate) {
     185              :         vNew = MAX2(0.0, vNew);
     186              :     }
     187     85507937 :     return vNew;
     188              : }
     189              : 
     190              : 
     191              : 
     192              : double
     193     36620044 : 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     36620044 :     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 2.0-1