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-07-26 16:30:20 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              : {
      73            0 :     myGapTimes.resize(myQueues.size());
      74            0 : }
      75              : 
      76              : 
      77              : SUMOTime
      78            0 : MELSegment::computeHeadway(Queue& /*q*/, const Queue& /*qNext*/, const MESegment* const /*next*/, const MEVehicle* veh) const {
      79              :     // @note: it might seem sensible to check veh->getQueuingTimeLoss() here but
      80              :     // then the queing state would be "sticky" because queuingTimeLoss is computed with tau_ff 
      81              :     // and every leader car that uses tau_jf applies queing timeLoss to it's followers
      82            0 :     SUMOTime headway = tauWithVehLength(veh->getWaitingTime() > 0 ? myTau_jf : myTau_ff,
      83            0 :             veh->getVehicleType().getLengthWithGap(),
      84            0 :             veh->getVehicleType().getCarFollowModel().getHeadwayTime());
      85            0 :     if (myTLSPenalty) {
      86            0 :         const MSLink* const tllink = getLink(veh, true);
      87            0 :         if (tllink != nullptr && tllink->isTLSControlled()) {
      88              :             assert(tllink->getGreenFraction() > 0);
      89            0 :             headway = (SUMOTime)((double)headway / tllink->getGreenFraction());
      90              :         }
      91              :     }
      92            0 :     return headway;
      93              : }
      94              : 
      95              : 
      96              : void
      97            0 : MELSegment::send(MEVehicle* veh, MESegment* const next, const int nextQIdx, SUMOTime time, const MSMoveReminder::Notification reason) {
      98            0 :     GapTimes& gapTimes = myGapTimes[veh->getQueIndex()];
      99              :     // record time when the gap vacated by ego will reach the upstream end of the segment
     100              :     // gaps travel quickly in free flow (the number of gaps and vehicles stays below the segment capacity)
     101              :     // but they travel more slowly when queued (startupDelay)
     102            0 :     gapTimes.insert(gapTimes.begin(), time + myLength * (veh->getQueuingTimeLoss() > 0 ? myTau_jj : myTau_ff) / DEFAULT_VEH_LENGTH_WITH_GAP);
     103            0 :     MESegment::send(veh, next, nextQIdx, time, reason);
     104            0 : }
     105              : 
     106              : 
     107              : void
     108            0 : MELSegment::updateEntryBlockTime(SUMOTime time) {
     109            0 :     for (int qIdx = 0; qIdx < (int)myQueues.size(); qIdx++) {
     110            0 :         Queue& q = myQueues[qIdx];
     111              :         GapTimes& gapTimes = myGapTimes[qIdx];
     112            0 :         while (!gapTimes.empty() && gapTimes.back() <= time) {
     113              :             gapTimes.pop_back();
     114              :         }
     115            0 :         if (!gapTimes.empty() && q.getOccupancy() + gapTimes.size() * DEFAULT_VEH_LENGTH_WITH_GAP > myQueueCapacity) {
     116              :             // segment is jammed because the empty spaces have not yet reached the upstream end.
     117            0 :             q.setEntryBlockTime(MAX2(q.getEntryBlockTime(), gapTimes.back()));
     118              :         }
     119              :     }
     120            0 : }
     121              : 
     122              : 
     123              : bool
     124            0 : MELSegment::hasSpaceForInsertion(const Queue& q, int qIdx, double /*newOccupancy*/, SUMOTime entryTime) const {
     125            0 :     GapTimes& gapTimes = const_cast<GapTimes&>(myGapTimes[qIdx]);
     126            0 :     while (!gapTimes.empty() && gapTimes.back() <= entryTime) {
     127              :         gapTimes.pop_back();
     128              :     }
     129            0 :     return q.getOccupancy() + gapTimes.size() * DEFAULT_VEH_LENGTH_WITH_GAP < myQueueCapacity;
     130              : }
     131              : 
     132              : 
     133              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1