LCOV - code coverage report
Current view: top level - src/microsim/traffic_lights - MSRailCrossing.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 87.5 % 88 77
Test Date: 2024-11-22 15:46:21 Functions: 66.7 % 12 8

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-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    MSRailCrossing.cpp
      15              : /// @author  Jakob Erdmann
      16              : /// @author  Erik Tunsch
      17              : /// @date    Dez 2015
      18              : ///
      19              : // A rail signal logic
      20              : /****************************************************************************/
      21              : #include <config.h>
      22              : 
      23              : #include <cassert>
      24              : #include <utility>
      25              : #include <vector>
      26              : #include <bitset>
      27              : #include <utils/common/StringUtils.h>
      28              : #include <microsim/MSEventControl.h>
      29              : #include <microsim/MSNet.h>
      30              : #include <microsim/MSEdge.h>
      31              : #include "MSTrafficLightLogic.h"
      32              : #include "MSRailCrossing.h"
      33              : #include <microsim/MSLane.h>
      34              : #include "MSPhaseDefinition.h"
      35              : #include "MSTLLogicControl.h"
      36              : 
      37              : 
      38              : // ===========================================================================
      39              : // method definitions
      40              : // ===========================================================================
      41          133 : MSRailCrossing::MSRailCrossing(MSTLLogicControl& tlcontrol,
      42              :                                const std::string& id, const std::string& programID, SUMOTime delay,
      43          133 :                                const Parameterised::Map& parameters) :
      44          133 :     MSSimpleTrafficLightLogic(tlcontrol, id, programID, 0, TrafficLightType::RAIL_CROSSING, Phases(), 0, delay, parameters) {
      45              :     // dummy phase, used to avoid crashing in MSTrafficLightLogic::setTrafficLightSignals()
      46          399 :     myPhases.push_back(new MSPhaseDefinition(1, std::string(SUMO_MAX_CONNECTIONS, 'X')));
      47          133 :     myDefaultCycleTime = 1;
      48          133 : }
      49              : 
      50              : 
      51          266 : MSRailCrossing::~MSRailCrossing() {}
      52              : 
      53              : 
      54              : void
      55          133 : MSRailCrossing::init(NLDetectorBuilder&) {
      56          133 :     const Parameterised::Map test = getParametersMap();
      57          266 :     myTimeGap = string2time(getParameter("time-gap", "15"));
      58              :     //use time-gap by default
      59          266 :     mySpaceGap = StringUtils::toDouble(getParameter("space-gap", "-1"));
      60          266 :     myMinGreenTime = string2time(getParameter("min-green", "5"));
      61          266 :     myOpeningDelay = string2time(getParameter("opening-delay", "3"));
      62          266 :     myOpeningTime = string2time(getParameter("opening-time", "3")); // red-yellow while opening
      63              :     /// XXX compute reasonable time depending on link length
      64          266 :     myYellowTime = string2time(getParameter("yellow-time", "5"));
      65          133 :     delete myPhases.front();
      66              :     myPhases.clear();
      67          399 :     myPhases.push_back(new MSPhaseDefinition(1, std::string(myLinks.size(), LINKSTATE_TL_GREEN_MAJOR)));
      68          399 :     myPhases.push_back(new MSPhaseDefinition(myYellowTime, std::string(myLinks.size(), LINKSTATE_TL_YELLOW_MINOR)));
      69          399 :     myPhases.push_back(new MSPhaseDefinition(1, std::string(myLinks.size(), LINKSTATE_TL_RED)));
      70          399 :     myPhases.push_back(new MSPhaseDefinition(myOpeningTime, std::string(myLinks.size(), LINKSTATE_TL_REDYELLOW)));
      71              :     // init phases
      72          133 :     updateCurrentPhase();
      73          133 :     setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
      74          133 :     myNumLinks = (int)myLinks.size();
      75          133 : }
      76              : 
      77              : 
      78              : void
      79           36 : MSRailCrossing::setParameter(const std::string& key, const std::string& value) {
      80              :     // some pre-defined parameters can be updated at runtime
      81           36 :     if (key == "time-gap") {
      82           12 :         myTimeGap = string2time(value);
      83           24 :     } else if (key == "space-gap") {
      84            6 :         mySpaceGap = StringUtils::toDouble(value);
      85           18 :     } else if (key == "min-green") {
      86            0 :         myMinGreenTime = string2time(value);
      87           18 :     } else if (key == "opening-delay") {
      88            6 :         myOpeningDelay = string2time(value);
      89           12 :     } else if (key == "opening-time") {
      90            6 :         myOpeningTime = string2time(value); // TODO update phases
      91            6 :     } else if (key == "yellow-time") {
      92            6 :         myYellowTime = string2time(value); // TODO update phases
      93              :     }
      94           36 :     Parameterised::setParameter(key, value);
      95           36 : }
      96              : 
      97              : 
      98              : // ----------- Handling of controlled links
      99              : void
     100            0 : MSRailCrossing::adaptLinkInformationFrom(const MSTrafficLightLogic& logic) {
     101            0 :     MSTrafficLightLogic::adaptLinkInformationFrom(logic);
     102            0 :     updateCurrentPhase();
     103            0 : }
     104              : 
     105              : 
     106              : // ------------ Switching and setting current rows
     107              : SUMOTime
     108       200190 : MSRailCrossing::trySwitch() {
     109       200190 :     const int oldStep = myStep;
     110       200190 :     SUMOTime nextTry = updateCurrentPhase();
     111              :     //if (getID() == "cluster_1088529493_1260626727") std::cout << " myStep=" << myStep << " nextTry=" << nextTry << "\n";
     112       200190 :     if (myStep != oldStep) {
     113         4484 :         myPhases[myStep]->myLastSwitch = MSNet::getInstance()->getCurrentTimeStep();
     114              :     }
     115       200190 :     return nextTry;
     116              : }
     117              : 
     118              : 
     119              : SUMOTime
     120       200323 : MSRailCrossing::updateCurrentPhase() {
     121       200323 :     const SUMOTime now = MSNet::getInstance()->getCurrentTimeStep();
     122              :     SUMOTime stayRedUntil = now;
     123              :     // check rail links for approaching foes to determine whether and how long
     124              :     // the crossing must remain closed
     125       586090 :     for (const MSLink* const link : myIncomingRailLinks) {
     126       409514 :         for (const auto& it_avi : link->getApproaching()) {
     127              :             const MSLink::ApproachingVehicleInformation& avi = it_avi.second;
     128        23747 :             if (avi.arrivalTime - myYellowTime - now < myTimeGap) {
     129         2333 :                 stayRedUntil = MAX2(stayRedUntil, avi.leavingTime + myOpeningDelay);
     130              :             }
     131        23747 :             if (mySpaceGap >= 0 && avi.dist < mySpaceGap) {
     132              :                 // TODO maybe check the incoming lanes because stopped vehicles do not register at the oncoming junction
     133          244 :                 stayRedUntil = MAX2(stayRedUntil, avi.leavingTime + myOpeningDelay);
     134              :             }
     135              :         }
     136       385767 :         if (link->getViaLane() != nullptr && link->getViaLane()->getVehicleNumberWithPartials() > 0) {
     137              :             // do not open if there is still a train on the crossing
     138          166 :             stayRedUntil = MAX2(stayRedUntil, now + DELTA_T + myOpeningDelay);
     139              :         }
     140              :     }
     141              :     //if (getID() == "cluster_1088529493_1260626727") std::cout << SIMTIME << " stayRedUntil=" << stayRedUntil;
     142       200323 :     const SUMOTime wait = stayRedUntil - now;
     143              : 
     144       200323 :     if (myStep == 0) {
     145              :         // 'G': check whether the crossing can stay open
     146       196422 :         if (wait == 0) {
     147       195341 :             return DELTA_T;
     148              :         } else {
     149         1081 :             myStep++;
     150         1081 :             return myYellowTime;
     151              :         }
     152         3901 :     } else if (myStep == 1) {
     153              :         // 'y': yellow time is over. switch to red
     154         1081 :         myStep++;
     155         1081 :         return MAX2(DELTA_T, wait);
     156         2820 :     } else if (myStep == 2) {
     157              :         // 'r': check whether we may open again
     158         1659 :         if (wait == 0) {
     159         1161 :             myStep++;
     160         1161 :             return myOpeningTime;
     161              :         } else {
     162              :             return wait;
     163              :         }
     164              :     } else { // (myStep == 3)
     165              :         // 'u': opening time is over, switch to green
     166         1161 :         if (wait == 0) {
     167         1081 :             myStep = 0;
     168         1081 :             return myMinGreenTime;
     169              :         } else {
     170              :             // train approached during opening sequence, close again
     171           80 :             myStep = 2;
     172           80 :             return wait;
     173              :         }
     174              :     }
     175              : }
     176              : 
     177              : 
     178              : // ------------ Conversion between time and phase
     179              : SUMOTime
     180            0 : MSRailCrossing::getPhaseIndexAtTime(SUMOTime) const {
     181            0 :     return 0;
     182              : }
     183              : 
     184              : SUMOTime
     185            0 : MSRailCrossing::getOffsetFromIndex(int) const {
     186            0 :     return 0;
     187              : }
     188              : 
     189              : int
     190            0 : MSRailCrossing::getIndexFromOffset(SUMOTime) const {
     191            0 :     return 0;
     192              : }
     193              : 
     194              : 
     195              : void
     196          468 : MSRailCrossing::addLink(MSLink* link, MSLane* lane, int pos) {
     197          468 :     if (pos >= 0) {
     198          194 :         MSTrafficLightLogic::addLink(link, lane, pos);
     199              :     } else {
     200          274 :         myIncomingRailLinks.push_back(link);
     201              :     }
     202          468 : }
     203              : 
     204              : 
     205              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1