LCOV - code coverage report
Current view: top level - src/microsim/traffic_lights - MSRailCrossing.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 78 89 87.6 %
Date: 2024-05-19 15:37:39 Functions: 8 12 66.7 %

          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         175 : MSRailCrossing::MSRailCrossing(MSTLLogicControl& tlcontrol,
      42             :                                const std::string& id, const std::string& programID, SUMOTime delay,
      43         175 :                                const Parameterised::Map& parameters) :
      44         350 :     MSSimpleTrafficLightLogic(tlcontrol, id, programID, 0, TrafficLightType::RAIL_CROSSING, Phases(), 0, delay, parameters) {
      45             :     // dummy phase, used to avoid crashing in MSTrafficLightLogic::setTrafficLightSignals()
      46         175 :     myPhases.push_back(new MSPhaseDefinition(1, std::string(SUMO_MAX_CONNECTIONS, 'X')));
      47         175 :     myDefaultCycleTime = 1;
      48         175 : }
      49             : 
      50             : 
      51         525 : MSRailCrossing::~MSRailCrossing() {}
      52             : 
      53             : 
      54             : void
      55         175 : MSRailCrossing::init(NLDetectorBuilder&) {
      56         175 :     const Parameterised::Map test = getParametersMap();
      57         175 :     myTimeGap = string2time(getParameter("time-gap", "15"));
      58             :     //use time-gap by default
      59         175 :     mySpaceGap = StringUtils::toDouble(getParameter("space-gap", "-1"));
      60         175 :     myMinGreenTime = string2time(getParameter("min-green", "5"));
      61         175 :     myOpeningDelay = string2time(getParameter("opening-delay", "3"));
      62         175 :     myOpeningTime = string2time(getParameter("opening-time", "3")); // red-yellow while opening
      63             :     /// XXX compute reasonable time depending on link length
      64         175 :     myYellowTime = string2time(getParameter("yellow-time", "5"));
      65         175 :     delete myPhases.front();
      66         175 :     myPhases.clear();
      67         175 :     myPhases.push_back(new MSPhaseDefinition(1, std::string(myLinks.size(), LINKSTATE_TL_GREEN_MAJOR)));
      68         175 :     myPhases.push_back(new MSPhaseDefinition(myYellowTime, std::string(myLinks.size(), LINKSTATE_TL_YELLOW_MINOR)));
      69         175 :     myPhases.push_back(new MSPhaseDefinition(1, std::string(myLinks.size(), LINKSTATE_TL_RED)));
      70         175 :     myPhases.push_back(new MSPhaseDefinition(myOpeningTime, std::string(myLinks.size(), LINKSTATE_TL_REDYELLOW)));
      71             :     // init phases
      72         175 :     updateCurrentPhase();
      73         175 :     setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
      74         175 :     myNumLinks = (int)myLinks.size();
      75         175 : }
      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      226345 : MSRailCrossing::trySwitch() {
     109      226345 :     const int oldStep = myStep;
     110      226345 :     SUMOTime nextTry = updateCurrentPhase();
     111             :     //if (getID() == "cluster_1088529493_1260626727") std::cout << " myStep=" << myStep << " nextTry=" << nextTry << "\n";
     112      226345 :     if (myStep != oldStep) {
     113        5756 :         myPhases[myStep]->myLastSwitch = MSNet::getInstance()->getCurrentTimeStep();
     114             :     }
     115      226345 :     return nextTry;
     116             : }
     117             : 
     118             : 
     119             : SUMOTime
     120      226520 : MSRailCrossing::updateCurrentPhase() {
     121      226520 :     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      769780 :     for (const MSLink* const link : myIncomingRailLinks) {
     126      588418 :         for (const auto& it_avi : link->getApproaching()) {
     127             :             const MSLink::ApproachingVehicleInformation& avi = it_avi.second;
     128       45158 :             if (avi.arrivalTime - myYellowTime - now < myTimeGap) {
     129        3268 :                 stayRedUntil = MAX2(stayRedUntil, avi.leavingTime + myOpeningDelay);
     130             :             }
     131       45158 :             if (mySpaceGap >= 0 && avi.dist < mySpaceGap) {
     132             :                 // TODO maybe check the incoming lanes because stopped vehicles do not register at the oncoming junction
     133         242 :                 stayRedUntil = MAX2(stayRedUntil, avi.leavingTime + myOpeningDelay);
     134             :             }
     135             :         }
     136      543260 :         if (link->getViaLane() != nullptr && link->getViaLane()->getVehicleNumberWithPartials() > 0) {
     137             :             // do not open if there is still a train on the crossing
     138         190 :             stayRedUntil = MAX2(stayRedUntil, now + DELTA_T + myOpeningDelay);
     139             :         }
     140             :     }
     141             :     //if (getID() == "cluster_1088529493_1260626727") std::cout << SIMTIME << " stayRedUntil=" << stayRedUntil;
     142      226520 :     const SUMOTime wait = stayRedUntil - now;
     143             : 
     144      226520 :     if (myStep == 0) {
     145             :         // 'G': check whether the crossing can stay open
     146      221494 :         if (wait == 0) {
     147      220116 :             return DELTA_T;
     148             :         } else {
     149        1378 :             myStep++;
     150        1378 :             return myYellowTime;
     151             :         }
     152        5026 :     } else if (myStep == 1) {
     153             :         // 'y': yellow time is over. switch to red
     154        1378 :         myStep++;
     155        1378 :         return MAX2(DELTA_T, wait);
     156        3648 :     } else if (myStep == 2) {
     157             :         // 'r': check whether we may open again
     158        2148 :         if (wait == 0) {
     159        1500 :             myStep++;
     160        1500 :             return myOpeningTime;
     161             :         } else {
     162             :             return wait;
     163             :         }
     164             :     } else { // (myStep == 3)
     165             :         // 'u': opening time is over, switch to green
     166        1500 :         if (wait == 0) {
     167        1378 :             myStep = 0;
     168        1378 :             return myMinGreenTime;
     169             :         } else {
     170             :             // train approached during opening sequence, close again
     171         122 :             myStep = 2;
     172         122 :             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         574 : MSRailCrossing::addLink(MSLink* link, MSLane* lane, int pos) {
     197         574 :     if (pos >= 0) {
     198         200 :         MSTrafficLightLogic::addLink(link, lane, pos);
     199             :     } else {
     200         374 :         myIncomingRailLinks.push_back(link);
     201             :     }
     202         574 : }
     203             : 
     204             : 
     205             : /****************************************************************************/

Generated by: LCOV version 1.14