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: 2026-03-26 16:31:35 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-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    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   1994191645 : MSLeaderInfo::MSLeaderInfo(const double laneWidth, const MSVehicle* ego, const double latOffset) :
      38   1994191645 :     myWidth(laneWidth),
      39   1994191645 :     myOffset(0),
      40   1994191645 :     myVehicles(MAX2(1, int(ceil(laneWidth / MSGlobals::gLateralResolution))), (MSVehicle*)nullptr),
      41   1994191645 :     myFreeSublanes((int)myVehicles.size()),
      42   1994191645 :     egoRightMost(-1),
      43   1994191645 :     egoLeftMost(-1),
      44   1994191645 :     myHasVehicles(false) {
      45   1994191645 :     if (ego != nullptr) {
      46    258756212 :         getSubLanes(ego, latOffset, egoRightMost, egoLeftMost);
      47              :         // filter out sublanes not of interest to ego
      48    258756212 :         myFreeSublanes -= egoRightMost;
      49    258756212 :         myFreeSublanes -= (int)myVehicles.size() - 1 - egoLeftMost;
      50              :     }
      51   1994191645 : }
      52              : 
      53              : 
      54   4438702010 : MSLeaderInfo::~MSLeaderInfo() { }
      55              : 
      56              : 
      57              : int
      58   1345352807 : MSLeaderInfo::addLeader(const MSVehicle* veh, bool beyond, double latOffset) {
      59   1345352807 :     if (veh == nullptr) {
      60            0 :         return myFreeSublanes;
      61              :     }
      62   1345352807 :     if (myVehicles.size() == 1) {
      63              :         // speedup for the simple case
      64    721294415 :         if (!beyond || myVehicles[0] == 0) {
      65    721294415 :             myVehicles[0] = veh;
      66    721294415 :             myFreeSublanes = 0;
      67    721294415 :             myHasVehicles = true;
      68              :         }
      69    721294415 :         return myFreeSublanes;
      70              :     }
      71              :     // map center-line based coordinates into [0, myWidth] coordinates
      72              :     int rightmost, leftmost;
      73    624058392 :     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   2604172411 :     for (int sublane = rightmost; sublane <= leftmost; ++sublane) {
      79     18616444 :         if ((egoRightMost < 0 || (egoRightMost <= sublane && sublane <= egoLeftMost))
      80   1988718018 :                 && (!beyond || myVehicles[sublane] == 0)) {
      81   1648255133 :             if (myVehicles[sublane] == 0) {
      82    987791184 :                 myFreeSublanes--;
      83              :             }
      84   1648255133 :             myVehicles[sublane] = veh;
      85   1648255133 :             myHasVehicles = true;
      86              :         }
      87              :     }
      88    624058392 :     return myFreeSublanes;
      89              : }
      90              : 
      91              : 
      92              : void
      93       396172 : MSLeaderInfo::clear() {
      94       396172 :     myVehicles.assign(myVehicles.size(), (MSVehicle*)nullptr);
      95       396172 :     myFreeSublanes = (int)myVehicles.size();
      96       396172 :     if (egoRightMost >= 0) {
      97            0 :         myFreeSublanes -= egoRightMost;
      98            0 :         myFreeSublanes -= (int)myVehicles.size() - 1 - egoLeftMost;
      99              :     }
     100       396172 : }
     101              : 
     102              : 
     103              : void
     104   4907146244 : MSLeaderInfo::getSubLanes(const MSVehicle* veh, double latOffset, int& rightmost, int& leftmost) const {
     105   4907146244 :     if (myVehicles.size() == 1) {
     106              :         // speedup for the simple case
     107   1041209011 :         rightmost = 0;
     108   1041209011 :         leftmost = 0;
     109   1041209011 :         return;
     110              :     }
     111              :     // map center-line based coordinates into [0, myWidth] coordinates
     112   3865937233 :     const double vehCenter = veh->getLateralPositionOnLane() + 0.5 * myWidth + latOffset + myOffset * MSGlobals::gLateralResolution;
     113   3865937233 :     const double vehHalfWidth = 0.5 * veh->getVehicleType().getWidth();
     114   3865937233 :     double rightVehSide = vehCenter - vehHalfWidth;
     115   3865937233 :     double leftVehSide = vehCenter + vehHalfWidth;
     116              :     // Reserve some additional space if the vehicle is performing a maneuver continuation.
     117   3865937233 :     if (veh->getActionStepLength() != DELTA_T) {
     118    232750563 :         if (veh->getLaneChangeModel().getManeuverDist() < 0. || veh->getLaneChangeModel().getSpeedLat() < 0.) {
     119     12641786 :             const double maneuverDist = MIN2(veh->getVehicleType().getMaxSpeedLat() * veh->getActionStepLengthSecs(), -MIN2(0., veh->getLaneChangeModel().getManeuverDist()));
     120      6320893 :             rightVehSide -= maneuverDist;
     121              :         }
     122    232750563 :         if (veh->getLaneChangeModel().getManeuverDist() > 0. || veh->getLaneChangeModel().getSpeedLat() > 0.) {
     123     17468708 :             const double maneuverDist = MIN2(veh->getVehicleType().getMaxSpeedLat() * veh->getActionStepLengthSecs(), MAX2(0., veh->getLaneChangeModel().getManeuverDist()));
     124      8734354 :             leftVehSide += maneuverDist;
     125              :         }
     126              :     }
     127   3865937233 :     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     43364886 :         rightmost = -1000;
     132     43364886 :         leftmost = -2000;
     133              :     } else {
     134   3822572347 :         rightmost = MAX2(0, (int)floor((rightVehSide + NUMERICAL_EPS) / MSGlobals::gLateralResolution));
     135   7645061251 :         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    452903921 : MSLeaderInfo::getSublaneBorders(int sublane, double latOffset, double& rightSide, double& leftSide) const {
     154              :     assert(sublane >= 0);
     155              :     assert(sublane < (int)myVehicles.size());
     156    452903921 :     const double res = MSGlobals::gLateralResolution > 0 ? MSGlobals::gLateralResolution : myWidth;
     157    452903921 :     rightSide = sublane * res + latOffset - myOffset * MSGlobals::gLateralResolution;
     158    452903921 :     leftSide = MIN2((sublane + 1) * res, myWidth) + latOffset - myOffset * MSGlobals::gLateralResolution;
     159    452903921 : }
     160              : 
     161              : 
     162              : const MSVehicle*
     163   4405959671 : MSLeaderInfo::operator[](int sublane) const {
     164              :     assert(sublane >= 0);
     165              :     assert(sublane < (int)myVehicles.size());
     166   4405959671 :     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     81498675 : MSLeaderInfo::setSublaneOffset(int offset) {
     188              :     assert(MSGlobals::gLateralResolution > 0);
     189     81498675 :     myOffset = offset;
     190     81498675 : }
     191              : 
     192              : 
     193              : bool
     194    159391377 : MSLeaderInfo::hasStoppedVehicle() const {
     195    159391377 :     if (!myHasVehicles) {
     196              :         return false;
     197              :     }
     198    718547728 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     199    580344428 :         if (myVehicles[i] != 0 && myVehicles[i]->isStopped()) {
     200              :             return true;
     201              :         }
     202              :     }
     203              :     return false;
     204              : }
     205              : 
     206              : 
     207              : bool
     208      1950101 : MSLeaderInfo::hasVehicle(const MSVehicle* veh) const {
     209      1950101 :     if (!myHasVehicles) {
     210              :         return false;
     211              :     }
     212      6282523 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     213      5287476 :         if (myVehicles[i] == veh) {
     214              :             return true;
     215              :         }
     216              :     }
     217              :     return false;
     218              : }
     219              : 
     220              : void
     221       138083 : MSLeaderInfo::removeOpposite(const MSLane* lane) {
     222       653668 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     223       515585 :         const MSVehicle* veh = myVehicles[i];
     224       807415 :         if (veh != 0 &&
     225       291830 :                 (veh->getLaneChangeModel().isOpposite()
     226       286438 :                  || &lane->getEdge() != &veh->getLane()->getEdge())) {
     227         8187 :             myVehicles[i] = nullptr;
     228              :         }
     229              :     }
     230       138083 : }
     231              : 
     232              : 
     233              : // ===========================================================================
     234              : // MSLeaderDistanceInfo member method definitions
     235              : // ===========================================================================
     236    660419843 : MSLeaderDistanceInfo::MSLeaderDistanceInfo(const double laneWidth, const MSVehicle* ego, const double latOffset) :
     237              :     MSLeaderInfo(laneWidth, ego, latOffset),
     238    660419843 :     myDistances(myVehicles.size(), std::numeric_limits<double>::max()) {
     239    660419843 : }
     240              : 
     241              : 
     242    483139174 : MSLeaderDistanceInfo::MSLeaderDistanceInfo(const CLeaderDist& cLeaderDist, const double laneWidth) :
     243              :     MSLeaderInfo(laneWidth, nullptr, 0.),
     244    483139174 :     myDistances(1, cLeaderDist.second) {
     245              :     assert(myVehicles.size() == 1);
     246    483139174 :     myVehicles[0] = cLeaderDist.first;
     247    483139174 :     myHasVehicles = cLeaderDist.first != nullptr;
     248    483139174 : }
     249              : 
     250   1750976125 : MSLeaderDistanceInfo::~MSLeaderDistanceInfo() { }
     251              : 
     252              : 
     253              : int
     254    564999125 : 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    564999125 :     if (veh == nullptr) {
     259      1213519 :         return myFreeSublanes;
     260              :     }
     261    563785606 :     if (myVehicles.size() == 1) {
     262              :         // speedup for the simple case
     263              :         sublane = 0;
     264              :     }
     265    563785606 :     if (sublane >= 0 && sublane < (int)myVehicles.size()) {
     266              :         // sublane is already given
     267    562196115 :         if (gap < myDistances[sublane]) {
     268    418470591 :             if (myVehicles[sublane] == 0) {
     269    414971801 :                 myFreeSublanes--;
     270              :             }
     271    418470591 :             myVehicles[sublane] = veh;
     272    418470591 :             myDistances[sublane] = gap;
     273    418470591 :             myHasVehicles = true;
     274              :         }
     275    562196115 :         return myFreeSublanes;
     276              :     }
     277              :     int rightmost, leftmost;
     278      1589491 :     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      6072835 :     for (int sublaneIdx = rightmost; sublaneIdx <= leftmost; ++sublaneIdx) {
     284       580923 :         if ((egoRightMost < 0 || (egoRightMost <= sublaneIdx && sublaneIdx <= egoLeftMost))
     285      4968634 :                 && gap < myDistances[sublaneIdx]) {
     286      1848142 :             if (myVehicles[sublaneIdx] == 0) {
     287      1618110 :                 myFreeSublanes--;
     288              :             }
     289      1848142 :             myVehicles[sublaneIdx] = veh;
     290      1848142 :             myDistances[sublaneIdx] = gap;
     291      1848142 :             myHasVehicles = true;
     292              :         }
     293              :     }
     294      1589491 :     return myFreeSublanes;
     295              : }
     296              : 
     297              : 
     298              : void
     299      1238383 : MSLeaderDistanceInfo::addLeaders(MSLeaderDistanceInfo& other) {
     300              :     const int maxSubLane = MIN2(numSublanes(), other.numSublanes());
     301      7215178 :     for (int i = 0; i < maxSubLane; i++) {
     302      5976795 :         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      1238383 : }
     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   5086380950 : MSLeaderDistanceInfo::operator[](int sublane) const {
     320              :     assert(sublane >= 0);
     321              :     assert(sublane < (int)myVehicles.size());
     322   5086380950 :     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       448494 : MSLeaderDistanceInfo::fixOppositeGaps(bool isFollower) {
     348      2219042 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     349      1770548 :         if (myVehicles[i] != nullptr) {
     350      1289832 :             if (myVehicles[i]->getLaneChangeModel().isOpposite()) {
     351       600757 :                 myDistances[i] -= myVehicles[i]->getVehicleType().getLength();
     352       689075 :             } else if (isFollower && myDistances[i] > POSITION_EPS) {
     353              :                 // can ignore oncoming followers once they are past
     354       228613 :                 myVehicles[i] = nullptr;
     355       228613 :                 myDistances[i] = -1;
     356              :             }
     357              :         }
     358              :     }
     359       448494 : }
     360              : 
     361              : 
     362              : void
     363        88384 : MSLeaderDistanceInfo::patchGaps(double amount) {
     364       445476 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     365       357092 :         if (myVehicles[i] != nullptr) {
     366       323140 :             myDistances[i] += amount;
     367              :         }
     368              :     }
     369        88384 : }
     370              : 
     371              : CLeaderDist
     372      1364540 : MSLeaderDistanceInfo::getClosest() const {
     373              :     double minGap = -1;
     374              :     const MSVehicle* veh = nullptr;
     375      1364540 :     if (hasVehicles()) {
     376              :         minGap = std::numeric_limits<double>::max();
     377      1673411 :         for (int i = 0; i < (int)myVehicles.size(); ++i) {
     378       987662 :             if (myVehicles[i] != nullptr && myDistances[i] < minGap) {
     379              :                 minGap = myDistances[i];
     380              :                 veh = myVehicles[i];
     381              :             }
     382              :         }
     383              :     }
     384      1364540 :     return std::make_pair(veh, minGap);
     385              : }
     386              : 
     387              : 
     388              : void
     389     13070945 : MSLeaderDistanceInfo::moveSamePosTo(const MSVehicle* ego, MSLeaderDistanceInfo& other) {
     390     13070945 :     const double pos = ego->getPositionOnLane();
     391     68420759 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     392     55349814 :         if (myVehicles[i] != nullptr && myDistances[i] < 0 && myVehicles[i]->getPositionOnLane() == pos
     393     56573888 :                 && &myVehicles[i]->getLane()->getEdge() == &ego->getLane()->getEdge()) {
     394      1223879 :             other.myVehicles[i] = myVehicles[i];
     395      1223879 :             other.myDistances[i] = myDistances[i];
     396      1223879 :             myVehicles[i] = nullptr;
     397      1223879 :             myDistances[i] = -1;
     398              :         }
     399              :     }
     400     13070945 : }
     401              : 
     402              : 
     403              : double
     404        27091 : MSLeaderDistanceInfo::getMinDistToStopped() const {
     405              :     double result = std::numeric_limits<double>::max();
     406        27091 :     if (!myHasVehicles) {
     407              :         return result;
     408              :     }
     409       135028 :     for (int i = 0; i < (int)myVehicles.size(); ++i) {
     410       107937 :         if (myVehicles[i] != 0 && myVehicles[i]->isStopped()) {
     411        55080 :             result = MIN2(result, myDistances[i]);
     412              :         }
     413              :     }
     414              :     return result;
     415              : }
     416              : 
     417              : 
     418              : // ===========================================================================
     419              : // MSCriticalFollowerDistanceInfo member method definitions
     420              : // ===========================================================================
     421              : 
     422              : 
     423    305320343 : MSCriticalFollowerDistanceInfo::MSCriticalFollowerDistanceInfo(const double laneWidth, const MSVehicle* ego, const double latOffset, const bool haveOppositeLeaders) :
     424              :     MSLeaderDistanceInfo(laneWidth, ego, latOffset),
     425    610640686 :     myMissingGaps(myVehicles.size(), -std::numeric_limits<double>::max()),
     426    305320343 :     myHaveOppositeLeaders(haveOppositeLeaders)
     427    305320343 : { }
     428              : 
     429              : 
     430    305320343 : MSCriticalFollowerDistanceInfo::~MSCriticalFollowerDistanceInfo() { }
     431              : 
     432              : 
     433              : int
     434   3013286084 : MSCriticalFollowerDistanceInfo::addFollower(const MSVehicle* veh, const MSVehicle* ego, double gap, double latOffset, int sublane) {
     435   3013286084 :     if (veh == nullptr) {
     436      4058265 :         return myFreeSublanes;
     437              :     }
     438   3009227819 :     const double requiredGap = (myHaveOppositeLeaders ? 0
     439   3003581727 :                                 : veh->getCarFollowModel().getSecureGap(veh, ego, veh->getSpeed(), ego->getSpeed(), ego->getCarFollowModel().getMaxDecel()));
     440   3009227819 :     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   3009227819 :     if (myVehicles.size() == 1) {
     462              :         // speedup for the simple case
     463              :         sublane = 0;
     464              :     }
     465   3009227819 :     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    204147618 :         if ((missingGap > myMissingGaps[sublane]
     470     89614046 :                 || (missingGap > 0 && gap < myDistances[sublane])
     471     89609081 :                 || (gap < 0 && myDistances[sublane] > 0))
     472    114538540 :                 && !(gap > 0 && myDistances[sublane] < 0)
     473    318656320 :                 && !(myMissingGaps[sublane] > 0 && myDistances[sublane] < gap)
     474              :            ) {
     475    114473033 :             if (myVehicles[sublane] == 0) {
     476    101480951 :                 myFreeSublanes--;
     477              :             }
     478    114473033 :             myVehicles[sublane] = veh;
     479    114473033 :             myDistances[sublane] = gap;
     480    114473033 :             myMissingGaps[sublane] = missingGap;
     481    114473033 :             myHasVehicles = true;
     482              :         }
     483    204147618 :         return myFreeSublanes;
     484              :     }
     485              :     int rightmost, leftmost;
     486   2805080201 :     getSubLanes(veh, latOffset, rightmost, leftmost);
     487  13217976120 :     for (int sublaneIdx = rightmost; sublaneIdx <= leftmost; ++sublaneIdx) {
     488      1173663 :         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  10412778052 :                 && (missingGap > myMissingGaps[sublaneIdx]
     492     61506180 :                     || (missingGap > 0 && gap < myDistances[sublaneIdx])
     493     60112446 :                     || (gap < 0 && myDistances[sublaneIdx] > 0))
     494  10352665618 :                 && !(gap > 0 && myDistances[sublaneIdx] < 0)
     495  20765533533 :                 && !(myMissingGaps[sublaneIdx] > 0 && myDistances[sublaneIdx] < gap)
     496              :            ) {
     497  10352620100 :             if (myVehicles[sublaneIdx] == 0) {
     498    732880160 :                 myFreeSublanes--;
     499              :             }
     500  10352620100 :             myVehicles[sublaneIdx] = veh;
     501  10352620100 :             myDistances[sublaneIdx] = gap;
     502  10352620100 :             myMissingGaps[sublaneIdx] = missingGap;
     503  10352620100 :             myHasVehicles = true;
     504              :         }
     505              :     }
     506   2805080201 :     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