LCOV - code coverage report
Current view: top level - src/mesosim - MELSegment.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 0.0 % 30 0
Test Date: 2026-09-20 15:45:03 Functions: 0.0 % 5 0

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-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    MELSegment.cpp
      15              : /// @author  Jakob Erdmann
      16              : /// @date    Tue, July 2026
      17              : ///
      18              : // A LTM (LIFT)-model segment
      19              : /****************************************************************************/
      20              : #include <config.h>
      21              : 
      22              : #include <algorithm>
      23              : #include <limits>
      24              : #include <utils/common/StdDefs.h>
      25              : #include <microsim/MSGlobals.h>
      26              : #include <microsim/MSEdge.h>
      27              : #include <microsim/MSJunction.h>
      28              : #include <microsim/MSNet.h>
      29              : #include <microsim/MSLane.h>
      30              : #include <microsim/MSLink.h>
      31              : #include <microsim/MSMoveReminder.h>
      32              : #include <microsim/traffic_lights/MSTrafficLightLogic.h>
      33              : #include <microsim/traffic_lights/MSDriveWay.h>
      34              : #include <microsim/traffic_lights/MSRailSignalControl.h>
      35              : #include <microsim/output/MSXMLRawOut.h>
      36              : #include <microsim/output/MSDetectorFileOutput.h>
      37              : #include <microsim/MSVehicleControl.h>
      38              : #include <microsim/devices/MSDevice.h>
      39              : #include <utils/common/FileHelpers.h>
      40              : #include <utils/common/MsgHandler.h>
      41              : #include <utils/iodevices/OutputDevice.h>
      42              : #include <utils/common/RandHelper.h>
      43              : #include "MEVehicle.h"
      44              : #include "MELoop.h"
      45              : #include "MELSegment.h"
      46              : 
      47              : #define DEFAULT_VEH_LENGTH_WITH_GAP (SUMOVTypeParameter::getDefault().length + SUMOVTypeParameter::getDefault().minGap)
      48              : 
      49              : //#define DEBUG_OPENED
      50              : //#define DEBUG_JAMTHRESHOLD
      51              : //#define DEBUG_COND (getID() == "blocker")
      52              : //#define DEBUG_COND (true)
      53              : #define DEBUG_COND (myEdge.isSelected())
      54              : #define DEBUG_COND2(obj) ((obj != 0 && (obj)->isSelected()))
      55              : 
      56              : 
      57              : // ===========================================================================
      58              : // static member definition
      59              : // ===========================================================================
      60              : 
      61              : 
      62              : // ===========================================================================
      63              : // MELSegment method definitions
      64              : // ===========================================================================
      65            0 : MELSegment::MELSegment(const std::string& id,
      66              :                        const MSEdge& parent, MESegment* next,
      67              :                        const double length, const double speed,
      68              :                        const int idx,
      69              :                        const bool multiQueue,
      70            0 :                        const MesoEdgeType& edgeType):
      71            0 :     MESegment(id, parent, next, length, speed, idx, multiQueue, edgeType) {
      72            0 :     myGapTimes.resize(myQueues.size());
      73            0 : }
      74              : 
      75              : 
      76              : SUMOTime
      77            0 : MELSegment::computeHeadway(Queue& /*q*/, const Queue& /*qNext*/, const MESegment* const /*next*/, const MEVehicle* veh) const {
      78              :     // @note: it might seem sensible to check veh->getQueuingTimeLoss() here but
      79              :     // then the queing state would be "sticky" because queuingTimeLoss is computed with tau_ff
      80              :     // and every leader car that uses tau_jf applies queing timeLoss to it's followers
      81            0 :     SUMOTime headway = tauWithVehLength(veh->getWaitingTime() > 0 ? myTau_jf : myTau_ff,
      82            0 :                                         veh->getVehicleType().getLengthWithGap(),
      83            0 :                                         veh->getVehicleType().getCarFollowModel().getHeadwayTime());
      84            0 :     if (myTLSPenalty) {
      85            0 :         const MSLink* const tllink = getLink(veh, true);
      86            0 :         if (tllink != nullptr && tllink->isTLSControlled()) {
      87              :             assert(tllink->getGreenFraction() > 0);
      88            0 :             headway = (SUMOTime)((double)headway / tllink->getGreenFraction());
      89              :         }
      90              :     }
      91            0 :     return headway;
      92              : }
      93              : 
      94              : 
      95              : void
      96            0 : MELSegment::send(MEVehicle* veh, MESegment* const next, const int nextQIdx, SUMOTime time, const MSMoveReminder::Notification reason) {
      97            0 :     GapTimes& gapTimes = myGapTimes[veh->getQueIndex()];
      98              :     // record time when the gap vacated by ego will reach the upstream end of the segment
      99              :     // gaps travel quickly in free flow (the number of gaps and vehicles stays below the segment capacity)
     100              :     // but they travel more slowly when queued (startupDelay)
     101            0 :     gapTimes.insert(gapTimes.begin(), time + (SUMOTime)(myLength * (double)(veh->getQueuingTimeLoss() > 0 ? myTau_jj : myTau_ff) / DEFAULT_VEH_LENGTH_WITH_GAP));
     102            0 :     MESegment::send(veh, next, nextQIdx, time, reason);
     103            0 : }
     104              : 
     105              : 
     106              : void
     107            0 : MELSegment::updateEntryBlockTime(SUMOTime time) {
     108            0 :     for (int qIdx = 0; qIdx < (int)myQueues.size(); qIdx++) {
     109            0 :         Queue& q = myQueues[qIdx];
     110              :         GapTimes& gapTimes = myGapTimes[qIdx];
     111            0 :         while (!gapTimes.empty() && gapTimes.back() <= time) {
     112              :             gapTimes.pop_back();
     113              :         }
     114            0 :         if (!gapTimes.empty() && q.getOccupancy() + (double)gapTimes.size() * DEFAULT_VEH_LENGTH_WITH_GAP > myQueueCapacity) {
     115              :             // segment is jammed because the empty spaces have not yet reached the upstream end.
     116            0 :             q.setEntryBlockTime(MAX2(q.getEntryBlockTime(), gapTimes.back()));
     117              :         }
     118              :     }
     119            0 : }
     120              : 
     121              : 
     122              : bool
     123            0 : MELSegment::hasSpaceForInsertion(const Queue& q, int qIdx, double /*newOccupancy*/, SUMOTime entryTime) const {
     124            0 :     GapTimes& gapTimes = const_cast<GapTimes&>(myGapTimes[qIdx]);
     125            0 :     while (!gapTimes.empty() && gapTimes.back() <= entryTime) {
     126              :         gapTimes.pop_back();
     127              :     }
     128            0 :     return q.getOccupancy() + (double)gapTimes.size() * DEFAULT_VEH_LENGTH_WITH_GAP <= myQueueCapacity;
     129              : }
     130              : 
     131              : 
     132              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1