LCOV - code coverage report
Current view: top level - src/microsim - MSLeaderInfo.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 81.5 % 238 194
Test Date: 2025-12-06 15:35:27 Functions: 75.8 % 33 25

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2002-2025 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    MSLeaderInfo.cpp
      15              : /// @author  Jakob Erdmann
      16              : /// @date    Oct 2015
      17              : ///
      18              : // Information about vehicles ahead (may be multiple vehicles if
      19              : // lateral-resolution is active)
      20              : /****************************************************************************/
      21              : #include <config.h>
      22              : 
      23              : #include <cassert>
      24              : #include <cmath>
      25              : #include <utils/common/ToString.h>
      26              : #include <microsim/MSGlobals.h>
      27              : #include <microsim/MSVehicle.h>
      28              : #include <microsim/lcmodels/MSAbstractLaneChangeModel.h>
      29              : #include <microsim/MSNet.h>
      30              : #include <microsim/MSLane.h>
      31              : #include "MSLeaderInfo.h"
      32              : 
      33              : 
      34              : // ===========================================================================
      35              : // MSLeaderInfo member method definitions
      36              : // ===========================================================================
      37   2296991510 : MSLeaderInfo::MSLeaderInfo(const double laneWidth, const MSVehicle* ego, const double latOffset) :
      38   2296991510 :     myWidth(laneWidth),
      39   2296991510 :     myOffset(0),
      40   2296991510 :     myVehicles(MAX2(1, int(ceil(laneWidth / MSGlobals::gLateralResolution))), (MSVehicle*)nullptr),
      41   2296991510 :     myFreeSublanes((int)myVehicles.size()),
      42   2296991510 :     egoRightMost(-1),
      43   2296991510 :     egoLeftMost(-1),
      44   2296991510 :     myHasVehicles(false) {
      45   2296991510 :     if (ego != nullptr) {
      46    255312720 :         getSubLanes(ego, latOffset, egoRightMost, egoLeftMost);
      47              :         // filter out sublanes not of interest to ego
      48    255312720 :         myFreeSublanes -= egoRightMost;
      49    255312720 :         myFreeSublanes -= (int)myVehicles.size() - 1 - egoLeftMost;
      50              :     }
      51   2296991510 : }
      52              : 
      53              : 
      54   5009071099 : MSLeaderInfo::~MSLeaderInfo() { }
      55              : 
      56              : 
      57              : int
      58   1309623141 : MSLeaderInfo::addLeader(const MSVehicle* veh, bool beyond, double latOffset) {
      59   1309623141 :     if (veh == nullptr) {
      60            0 :         return myFreeSublanes;
      61              :     }
      62   1309623141 :     if (myVehicles.size() == 1) {
      63              :         // speedup for the simple case
      64    680985647 :         if (!beyond || myVehicles[0] == 0) {
      65    680985647 :             myVehicles[0] = veh;
      66    680985647 :             myFreeSublanes = 0;
      67    680985647 :             myHasVehicles = true;
      68              :         }
      69    680985647 :         return myFreeSublanes;
      70              :     }
      71              :     // map center-line based coordinates into [0, myWidth] coordinates
      72              :     int rightmost, leftmost;
      73    628637494 :     getSubLanes(veh, latOffset, rightmost, leftmost);
      74              :     //if (gDebugFlag1) std::cout << " addLeader veh=" << veh->getID() << " beyond=" << beyond << " latOffset=" << latOffset << " sublaneOffset=" << myOffset
      75              :     //    << " rightmost=" << rightmost << " leftmost=" << leftmost
      76              :     //    << " eRM=" << egoRightMost << " eLM=" << egoLeftMost
      77              :     //        << " myFreeSublanes=" << myFreeSublanes << "\n";
      78   2634218481 :     for (int sublane = rightmost; sublane <= leftmost; ++sublane) {
      79     18231666 :         if ((egoRightMost < 0 || (egoRightMost <= sublane && sublane <= egoLeftMost))
      80   2013834935 :                 && (!beyond || myVehicles[sublane] == 0)) {
      81   1666575603 :             if (myVehicles[sublane] == 0) {
      82   1011328941 :                 myFreeSublanes--;
      83              :             }
      84   1666575603 :             myVehicles[sublane] = veh;
      85   1666575603 :             myHasVehicles = true;
      86              :         }
      87              :     }
      88    628637494 :     return myFreeSublanes;
      89              : }
      90              : 
      91              : 
      92              : void
      93       401152 : MSLeaderInfo::clear() {
      94       401152 :     myVehicles.assign(myVehicles.size(), (MSVehicle*)nullptr);
      95       401152 :     myFreeSublanes = (int)myVehicles.size();
      96       401152 :     if (egoRightMost >= 0) {
      97            0 :         myFreeSublanes -= egoRightMost;
      98            0 :         myFreeSublanes -= (int)myVehicles.size() - 1 - egoLeftMost;
      99              :     }
     100       401152 : }
     101              : 
     102              : 
     103              : void
     104   4842781286 : MSLeaderInfo::getSubLanes(const MSVehicle* veh, double latOffset, int& rightmost, int& leftmost) const {
     105   4842781286 :     if (myVehicles.size() == 1) {
     106              :         // speedup for the simple case
     107    978002584 :         rightmost = 0;
     108    978002584 :         leftmost = 0;
     109    978002584 :         return;
     110              :     }
     111              :     // map center-line based coordinates into [0, myWidth] coordinates
     112   3864778702 :     const double vehCenter = veh->getLateralPositionOnLane() + 0.5 * myWidth + latOffset + myOffset * MSGlobals::gLateralResolution;
     113   3864778702 :     const double vehHalfWidth = 0.5 * veh->getVehicleType().getWidth();
     114   3864778702 :     double rightVehSide = vehCenter - vehHalfWidth;
     115   3864778702 :     double leftVehSide = vehCenter + vehHalfWidth;
     116              :     // Reserve some additional space if the vehicle is performing a maneuver continuation.
     117   3864778702 :     if (veh->getActionStepLength() != DELTA_T) {
     118    230580121 :         if (veh->getLaneChangeModel().getManeuverDist() < 0. || veh->getLaneChangeModel().getSpeedLat() < 0.) {
     119     12931632 :             const double maneuverDist = MIN2(veh->getVehicleType().getMaxSpeedLat() * veh->getActionStepLengthSecs(), -MIN2(0., veh->getLaneChangeModel().getManeuverDist()));
     120      6465816 :             rightVehSide -= maneuverDist;
     121              :         }
     122    230580121 :         if (veh->getLaneChangeModel().getManeuverDist() > 0. || veh->getLaneChangeModel().getSpeedLat() > 0.) {
     123     17623456 :             const double maneuverDist = MIN2(veh->getVehicleType().getMaxSpeedLat() * veh->getActionStepLengthSecs(), MAX2(0., veh->getLaneChangeModel().getManeuverDist()));
     124      8811728 :             leftVehSide += maneuverDist;
     125              :         }
     126              :     }
     127   3864778702 :     if (rightVehSide > myWidth || leftVehSide < 0) {
     128              :         // vehicle does not touch this lane
     129              :         // set the values so that an iteration
     130              :         // for (i = rightmost; i  <= leftmost; i++) stops immediately
     131     41562833 :         rightmost = -1000;
     132     41562833 :         leftmost = -2000;
     133              :     } else {
     134   3823215869 :         rightmost = MAX2(0, (int)floor((rightVehSide + NUMERICAL_EPS) / MSGlobals::gLateralResolution));
     135   7646348179 :         leftmost = MIN2((int)myVehicles.size() - 1, (int)floor(MAX2(0.0, leftVehSide - NUMERICAL_EPS) / MSGlobals::gLateralResolution));
     136              :     }
     137              :     //if (veh->isSelected()) std::cout << SIMTIME << " veh=" << veh->getID()
     138              :     //    << std::setprecision(2)
     139              :     //    << " posLat=" << veh->getLateralPositionOnLane()
     140              :     //    << " latOffset=" << latOffset
     141              :     //    << " vehCenter=" << vehCenter
     142              :     //    << " rightVehSide=" << rightVehSide
     143              :     //    << " leftVehSide=" << leftVehSide
     144              :     //    << " rightmost=" << rightmost
     145              :     //    << " leftmost=" << leftmost
     146              :     //    << " myOffset=" << myOffset
     147              :     //    << std::setprecision(2)
     148              :     //    << "\n";
     149              : }
     150              : 
     151              : 
     152              : void
     153    440209720 : MSLeaderInfo::getSublaneBorders(int sublane, double latOffset, double& rightSide, double& leftSide) const {
     154              :     assert(sublane >= 0);
     155              :     assert(sublane < (int)myVehicles.size());
     156    440209720 :     const double res = MSGlobals::gLateralResolution > 0 ? MSGlobals::gLateralResolution : myWidth;
     157    440209720 :     rightSide = sublane * res + latOffset - myOffset * MSGlobals::gLateralResolution;
     158    440209720 :     leftSide = MIN2((sublane + 1) * res, myWidth) + latOffset - myOffset * MSGlobals::gLateralResolution;
     159    440209720 : }
     160              : 
     161              : 
     162              : const MSVehicle*
     163   7629126863 : MSLeaderInfo::operator[](int sublane) const {
     164              :     assert(sublane >= 0);
     165              :     assert(sublane < (int)myVehicles.size());
     166   7629126863 :     return myVehicles[sublane];
     167              : }
     168              : 
     169              : 
     170              : std::string
     171            0 : MSLeaderInfo::toString() const {
     172            0 :     std::ostringstream oss;
     173              :     oss.setf(std::ios::fixed, std::ios::floatfield);
     174              :     oss << std::setprecision(2);
     175            0 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     176            0 :         oss << Named::getIDSecure(myVehicles[i]);
     177            0 :         if (i < (int)myVehicles.size() - 1) {
     178            0 :             oss << ", ";
     179              :         }
     180              :     }
     181            0 :     oss << " free=" << myFreeSublanes;
     182            0 :     return oss.str();
     183            0 : }
     184              : 
     185              : 
     186              : void
     187     81738762 : MSLeaderInfo::setSublaneOffset(int offset) {
     188              :     assert(MSGlobals::gLateralResolution > 0);
     189     81738762 :     myOffset = offset;
     190     81738762 : }
     191              : 
     192              : 
     193              : bool
     194    161778797 : MSLeaderInfo::hasStoppedVehicle() const {
     195    161778797 :     if (!myHasVehicles) {
     196              :         return false;
     197              :     }
     198    711282339 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     199    574556165 :         if (myVehicles[i] != 0 && myVehicles[i]->isStopped()) {
     200              :             return true;
     201              :         }
     202              :     }
     203              :     return false;
     204              : }
     205              : 
     206              : 
     207              : bool
     208      1389644 : MSLeaderInfo::hasVehicle(const MSVehicle* veh) const {
     209      1389644 :     if (!myHasVehicles) {
     210              :         return false;
     211              :     }
     212      4624723 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     213      3858849 :         if (myVehicles[i] == veh) {
     214              :             return true;
     215              :         }
     216              :     }
     217              :     return false;
     218              : }
     219              : 
     220              : void
     221       138571 : MSLeaderInfo::removeOpposite(const MSLane* lane) {
     222       656603 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     223       518032 :         const MSVehicle* veh = myVehicles[i];
     224       811322 :         if (veh != 0 &&
     225       293290 :                 (veh->getLaneChangeModel().isOpposite()
     226       288062 :                  || &lane->getEdge() != &veh->getLane()->getEdge())) {
     227         8022 :             myVehicles[i] = nullptr;
     228              :         }
     229              :     }
     230       138571 : }
     231              : 
     232              : 
     233              : // ===========================================================================
     234              : // MSLeaderDistanceInfo member method definitions
     235              : // ===========================================================================
     236    657443253 : MSLeaderDistanceInfo::MSLeaderDistanceInfo(const double laneWidth, const MSVehicle* ego, const double latOffset) :
     237              :     MSLeaderInfo(laneWidth, ego, latOffset),
     238    657443253 :     myDistances(myVehicles.size(), std::numeric_limits<double>::max()) {
     239    657443253 : }
     240              : 
     241              : 
     242    471247562 : MSLeaderDistanceInfo::MSLeaderDistanceInfo(const CLeaderDist& cLeaderDist, const double laneWidth) :
     243              :     MSLeaderInfo(laneWidth, nullptr, 0.),
     244    471247562 :     myDistances(1, cLeaderDist.second) {
     245              :     assert(myVehicles.size() == 1);
     246    471247562 :     myVehicles[0] = cLeaderDist.first;
     247    471247562 :     myHasVehicles = cLeaderDist.first != nullptr;
     248    471247562 : }
     249              : 
     250   1731526047 : MSLeaderDistanceInfo::~MSLeaderDistanceInfo() { }
     251              : 
     252              : 
     253              : int
     254    559628102 : MSLeaderDistanceInfo::addLeader(const MSVehicle* veh, double gap, double latOffset, int sublane) {
     255              :     //if (SIMTIME == 31 && gDebugFlag1 && veh != 0 && veh->getID() == "cars.8") {
     256              :     //    std::cout << " BREAKPOINT\n";
     257              :     //}
     258    559628102 :     if (veh == nullptr) {
     259      1228454 :         return myFreeSublanes;
     260              :     }
     261    558399648 :     if (myVehicles.size() == 1) {
     262              :         // speedup for the simple case
     263              :         sublane = 0;
     264              :     }
     265    558399648 :     if (sublane >= 0 && sublane < (int)myVehicles.size()) {
     266              :         // sublane is already given
     267    556765682 :         if (gap < myDistances[sublane]) {
     268    414490339 :             if (myVehicles[sublane] == 0) {
     269    411119776 :                 myFreeSublanes--;
     270              :             }
     271    414490339 :             myVehicles[sublane] = veh;
     272    414490339 :             myDistances[sublane] = gap;
     273    414490339 :             myHasVehicles = true;
     274              :         }
     275    556765682 :         return myFreeSublanes;
     276              :     }
     277              :     int rightmost, leftmost;
     278      1633966 :     getSubLanes(veh, latOffset, rightmost, leftmost);
     279              :     //if (gDebugFlag1) std::cout << " addLeader veh=" << veh->getID() << " gap=" << gap << " latOffset=" << latOffset << " sublaneOffset=" << myOffset
     280              :     //    << " rightmost=" << rightmost << " leftmost=" << leftmost
     281              :     //    << " eRM=" << egoRightMost << " eLM=" << egoLeftMost
     282              :     //        << " myFreeSublanes=" << myFreeSublanes << "\n";
     283      6239929 :     for (int sublaneIdx = rightmost; sublaneIdx <= leftmost; ++sublaneIdx) {
     284       591883 :         if ((egoRightMost < 0 || (egoRightMost <= sublaneIdx && sublaneIdx <= egoLeftMost))
     285      5101938 :                 && gap < myDistances[sublaneIdx]) {
     286      1859467 :             if (myVehicles[sublaneIdx] == 0) {
     287      1612179 :                 myFreeSublanes--;
     288              :             }
     289      1859467 :             myVehicles[sublaneIdx] = veh;
     290      1859467 :             myDistances[sublaneIdx] = gap;
     291      1859467 :             myHasVehicles = true;
     292              :         }
     293              :     }
     294      1633966 :     return myFreeSublanes;
     295              : }
     296              : 
     297              : 
     298              : void
     299      1222000 : MSLeaderDistanceInfo::addLeaders(MSLeaderDistanceInfo& other) {
     300              :     const int maxSubLane = MIN2(numSublanes(), other.numSublanes());
     301      7158009 :     for (int i = 0; i < maxSubLane; i++) {
     302      5936009 :         addLeader(other[i].first, other[i].second, 0, i);
     303              :         //if ((myDistances[i] > 0 && myDistances[i] > other.myDistances[i])
     304              :         //        || (other.myDistances[i] < 0 && myDistances[i] < other.myDistances[i])) {
     305              :         //    addLeader(other[i].first, other[i].second, 0, i);
     306              :         //}
     307              :     }
     308      1222000 : }
     309              : 
     310              : 
     311              : void
     312            0 : MSLeaderDistanceInfo::clear() {
     313            0 :     MSLeaderInfo::clear();
     314            0 :     myDistances.assign(myVehicles.size(), std::numeric_limits<double>::max());
     315            0 : }
     316              : 
     317              : 
     318              : CLeaderDist
     319   5016700419 : MSLeaderDistanceInfo::operator[](int sublane) const {
     320              :     assert(sublane >= 0);
     321              :     assert(sublane < (int)myVehicles.size());
     322   5016700419 :     return std::make_pair(myVehicles[sublane], myDistances[sublane]);
     323              : }
     324              : 
     325              : 
     326              : std::string
     327            0 : MSLeaderDistanceInfo::toString() const {
     328            0 :     std::ostringstream oss;
     329              :     oss.setf(std::ios::fixed, std::ios::floatfield);
     330              :     oss << std::setprecision(2);
     331            0 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     332            0 :         oss << Named::getIDSecure(myVehicles[i]) << ":";
     333            0 :         if (myVehicles[i] == 0) {
     334            0 :             oss << "inf";
     335              :         } else {
     336            0 :             oss << myDistances[i];
     337              :         }
     338            0 :         if (i < (int)myVehicles.size() - 1) {
     339            0 :             oss << ", ";
     340              :         }
     341              :     }
     342            0 :     oss << " free=" << myFreeSublanes;
     343            0 :     return oss.str();
     344            0 : }
     345              : 
     346              : void
     347       450620 : MSLeaderDistanceInfo::fixOppositeGaps(bool isFollower) {
     348      2229993 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     349      1779373 :         if (myVehicles[i] != nullptr) {
     350      1300431 :             if (myVehicles[i]->getLaneChangeModel().isOpposite()) {
     351       606490 :                 myDistances[i] -= myVehicles[i]->getVehicleType().getLength();
     352       693941 :             } else if (isFollower && myDistances[i] > POSITION_EPS) {
     353              :                 // can ignore oncoming followers once they are past
     354       229753 :                 myVehicles[i] = nullptr;
     355       229753 :                 myDistances[i] = -1;
     356              :             }
     357              :         }
     358              :     }
     359       450620 : }
     360              : 
     361              : 
     362              : void
     363        89031 : MSLeaderDistanceInfo::patchGaps(double amount) {
     364       448711 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     365       359680 :         if (myVehicles[i] != nullptr) {
     366       325780 :             myDistances[i] += amount;
     367              :         }
     368              :     }
     369        89031 : }
     370              : 
     371              : CLeaderDist
     372      1359831 : MSLeaderDistanceInfo::getClosest() const {
     373              :     double minGap = -1;
     374              :     const MSVehicle* veh = nullptr;
     375      1359831 :     if (hasVehicles()) {
     376              :         minGap = std::numeric_limits<double>::max();
     377      1669144 :         for (int i = 0; i < (int)myVehicles.size(); ++i) {
     378       985274 :             if (myVehicles[i] != nullptr && myDistances[i] < minGap) {
     379              :                 minGap = myDistances[i];
     380              :                 veh = myVehicles[i];
     381              :             }
     382              :         }
     383              :     }
     384      1359831 :     return std::make_pair(veh, minGap);
     385              : }
     386              : 
     387              : 
     388              : void
     389     12880570 : MSLeaderDistanceInfo::moveSamePosTo(const MSVehicle* ego, MSLeaderDistanceInfo& other) {
     390     12880570 :     const double pos = ego->getPositionOnLane();
     391     67379910 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     392     54499340 :         if (myVehicles[i] != nullptr && myDistances[i] < 0 && myVehicles[i]->getPositionOnLane() == pos
     393     55694188 :                 && &myVehicles[i]->getLane()->getEdge() == &ego->getLane()->getEdge()) {
     394      1194653 :             other.myVehicles[i] = myVehicles[i];
     395      1194653 :             other.myDistances[i] = myDistances[i];
     396      1194653 :             myVehicles[i] = nullptr;
     397      1194653 :             myDistances[i] = -1;
     398              :         }
     399              :     }
     400     12880570 : }
     401              : 
     402              : 
     403              : double
     404        26959 : MSLeaderDistanceInfo::getMinDistToStopped() const {
     405              :     double result = std::numeric_limits<double>::max();
     406        26959 :     if (!myHasVehicles) {
     407              :         return result;
     408              :     }
     409       134368 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     410       107409 :         if (myVehicles[i] != 0 && myVehicles[i]->isStopped()) {
     411        54655 :             result = MIN2(result, myDistances[i]);
     412              :         }
     413              :     }
     414              :     return result;
     415              : }
     416              : 
     417              : 
     418              : // ===========================================================================
     419              : // MSCriticalFollowerDistanceInfo member method definitions
     420              : // ===========================================================================
     421              : 
     422              : 
     423    300231415 : MSCriticalFollowerDistanceInfo::MSCriticalFollowerDistanceInfo(const double laneWidth, const MSVehicle* ego, const double latOffset, const bool haveOppositeLeaders) :
     424              :     MSLeaderDistanceInfo(laneWidth, ego, latOffset),
     425    600462830 :     myMissingGaps(myVehicles.size(), -std::numeric_limits<double>::max()),
     426    300231415 :     myHaveOppositeLeaders(haveOppositeLeaders)
     427    300231415 : { }
     428              : 
     429              : 
     430    300231415 : MSCriticalFollowerDistanceInfo::~MSCriticalFollowerDistanceInfo() { }
     431              : 
     432              : 
     433              : int
     434   3004680005 : MSCriticalFollowerDistanceInfo::addFollower(const MSVehicle* veh, const MSVehicle* ego, double gap, double latOffset, int sublane) {
     435   3004680005 :     if (veh == nullptr) {
     436      3702350 :         return myFreeSublanes;
     437              :     }
     438   3000977655 :     const double requiredGap = (myHaveOppositeLeaders ? 0
     439   2995229434 :                                 : veh->getCarFollowModel().getSecureGap(veh, ego, veh->getSpeed(), ego->getSpeed(), ego->getCarFollowModel().getMaxDecel()));
     440   3000977655 :     const double missingGap = requiredGap - gap;
     441              :     /*
     442              :     if (ego->getID() == "disabled" || gDebugFlag1) {
     443              :         std::cout << "   addFollower veh=" << veh->getID()
     444              :             << " ego=" << ego->getID()
     445              :             << " gap=" << gap
     446              :             << " reqGap=" << requiredGap
     447              :             << " missingGap=" << missingGap
     448              :             << " latOffset=" << latOffset
     449              :             << " sublane=" << sublane
     450              :             << "\n";
     451              :         if (sublane > 0) {
     452              :             std::cout
     453              :                 << "        dists[s]=" << myDistances[sublane]
     454              :                 << " gaps[s]=" << myMissingGaps[sublane]
     455              :                 << "\n";
     456              :         } else {
     457              :             std::cout << toString() << "\n";
     458              :         }
     459              :     }
     460              :     */
     461   3000977655 :     if (myVehicles.size() == 1) {
     462              :         // speedup for the simple case
     463              :         sublane = 0;
     464              :     }
     465   3000977655 :     if (sublane >= 0 && sublane < (int)myVehicles.size()) {
     466              :         // sublane is already given
     467              :         // overlapping vehicles are stored preferably
     468              :         // among those vehicles with missing gap, closer ones are preferred
     469    201184025 :         if ((missingGap > myMissingGaps[sublane]
     470     89081921 :                 || (missingGap > 0 && gap < myDistances[sublane])
     471     89077168 :                 || (gap < 0 && myDistances[sublane] > 0))
     472    112106860 :                 && !(gap > 0 && myDistances[sublane] < 0)
     473    313259940 :                 && !(myMissingGaps[sublane] > 0 && myDistances[sublane] < gap)
     474              :            ) {
     475    112044872 :             if (myVehicles[sublane] == 0) {
     476     99205364 :                 myFreeSublanes--;
     477              :             }
     478    112044872 :             myVehicles[sublane] = veh;
     479    112044872 :             myDistances[sublane] = gap;
     480    112044872 :             myMissingGaps[sublane] = missingGap;
     481    112044872 :             myHasVehicles = true;
     482              :         }
     483    201184025 :         return myFreeSublanes;
     484              :     }
     485              :     int rightmost, leftmost;
     486   2799793630 :     getSubLanes(veh, latOffset, rightmost, leftmost);
     487  13180724394 :     for (int sublaneIdx = rightmost; sublaneIdx <= leftmost; ++sublaneIdx) {
     488      1117578 :         if ((egoRightMost < 0 || (egoRightMost <= sublaneIdx && sublaneIdx <= egoLeftMost))
     489              :                 // overlapping vehicles are stored preferably
     490              :                 // among those vehicles with missing gap, closer ones are preferred
     491  10380864334 :                 && (missingGap > myMissingGaps[sublaneIdx]
     492     59428079 :                     || (missingGap > 0 && gap < myDistances[sublaneIdx])
     493     58090321 :                     || (gap < 0 && myDistances[sublaneIdx] > 0))
     494  10322774025 :                 && !(gap > 0 && myDistances[sublaneIdx] < 0)
     495  20703682021 :                 && !(myMissingGaps[sublaneIdx] > 0 && myDistances[sublaneIdx] < gap)
     496              :            ) {
     497  10322735990 :             if (myVehicles[sublaneIdx] == 0) {
     498    726729219 :                 myFreeSublanes--;
     499              :             }
     500  10322735990 :             myVehicles[sublaneIdx] = veh;
     501  10322735990 :             myDistances[sublaneIdx] = gap;
     502  10322735990 :             myMissingGaps[sublaneIdx] = missingGap;
     503  10322735990 :             myHasVehicles = true;
     504              :         }
     505              :     }
     506   2799793630 :     return myFreeSublanes;
     507              : }
     508              : 
     509              : 
     510              : void
     511            0 : MSCriticalFollowerDistanceInfo::clear() {
     512            0 :     MSLeaderDistanceInfo::clear();
     513            0 :     myMissingGaps.assign(myVehicles.size(), -std::numeric_limits<double>::max());
     514            0 : }
     515              : 
     516              : 
     517              : std::string
     518            0 : MSCriticalFollowerDistanceInfo::toString() const {
     519            0 :     std::ostringstream oss;
     520              :     oss.setf(std::ios::fixed, std::ios::floatfield);
     521              :     oss << std::setprecision(2);
     522            0 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     523            0 :         oss << Named::getIDSecure(myVehicles[i]) << ":";
     524            0 :         if (myVehicles[i] == 0) {
     525            0 :             oss << "inf:-inf";
     526              :         } else {
     527            0 :             oss << myDistances[i] << ":" << myMissingGaps[i];
     528              :         }
     529            0 :         if (i < (int)myVehicles.size() - 1) {
     530            0 :             oss << ", ";
     531              :         }
     532              :     }
     533            0 :     oss << " free=" << myFreeSublanes;
     534            0 :     return oss.str();
     535            0 : }
     536              : 
     537              : 
     538              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1