1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file MSRailCrossing.cpp
11 /// @author Jakob Erdmann
12 /// @date Dez 2015
13 /// @version $Id$
14 ///
15 // A rail signal logic
16 /****************************************************************************/
17
18
19 // ===========================================================================
20 // included modules
21 // ===========================================================================
22 #include <config.h>
23
24 #include <cassert>
25 #include <utility>
26 #include <vector>
27 #include <bitset>
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 // ===========================================================================
MSRailCrossing(MSTLLogicControl & tlcontrol,const std::string & id,const std::string & programID,const std::map<std::string,std::string> & parameters)41 MSRailCrossing::MSRailCrossing(MSTLLogicControl& tlcontrol,
42 const std::string& id, const std::string& programID,
43 const std::map<std::string, std::string>& parameters) :
44 MSSimpleTrafficLightLogic(tlcontrol, id, programID, TLTYPE_RAIL_CROSSING, Phases(), 0, DELTA_T, parameters),
45 // XXX make this configurable
46 mySecurityGap(TIME2STEPS(15)),
47 myMinGreenTime(TIME2STEPS(5)),
48 /// XXX compute reasonable time depending on link length
49 myYellowTime(TIME2STEPS(5)) {
50 // dummy phase, used to avoid crashing in MSTrafficLightLogic::setTrafficLightSignals()
51 myPhases.push_back(new MSPhaseDefinition(1, std::string(SUMO_MAX_CONNECTIONS, 'X')));
52 }
53
54 void
init(NLDetectorBuilder &)55 MSRailCrossing::init(NLDetectorBuilder&) {
56 delete myPhases.front();
57 myPhases.clear();
58 myPhases.push_back(new MSPhaseDefinition(1, std::string(myLinks.size(), 'G')));
59 myPhases.push_back(new MSPhaseDefinition(myYellowTime, std::string(myLinks.size(), 'y')));
60 myPhases.push_back(new MSPhaseDefinition(1, std::string(myLinks.size(), 'r')));
61 // init phases
62 updateCurrentPhase();
63 setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
64 }
65
66
~MSRailCrossing()67 MSRailCrossing::~MSRailCrossing() {}
68
69
70 // ----------- Handling of controlled links
71 void
adaptLinkInformationFrom(const MSTrafficLightLogic & logic)72 MSRailCrossing::adaptLinkInformationFrom(const MSTrafficLightLogic& logic) {
73 MSTrafficLightLogic::adaptLinkInformationFrom(logic);
74 updateCurrentPhase();
75 }
76
77
78 // ------------ Switching and setting current rows
79 SUMOTime
trySwitch()80 MSRailCrossing::trySwitch() {
81 SUMOTime nextTry = updateCurrentPhase();
82 setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
83 //if (getID() == "cluster_1088529493_1260626727") std::cout << " myStep=" << myStep << " nextTry=" << nextTry << "\n";
84 return nextTry;
85 }
86
87
88 SUMOTime
updateCurrentPhase()89 MSRailCrossing::updateCurrentPhase() {
90 const SUMOTime now = MSNet::getInstance()->getCurrentTimeStep();
91 SUMOTime stayRedUntil = now;
92 // check rail links for approaching foes to determine whether and how long
93 // the crossing must remain closed
94 for (std::vector<MSLink*>::const_iterator it_link = myIncomingRailLinks.begin(); it_link != myIncomingRailLinks.end(); ++it_link) {
95
96 for (auto it_avi : (*it_link)->getApproaching()) {
97 const MSLink::ApproachingVehicleInformation& avi = it_avi.second;
98 if (avi.arrivalTime - myYellowTime - now < mySecurityGap) {
99 stayRedUntil = MAX2(stayRedUntil, avi.leavingTime);
100 }
101 }
102 if ((*it_link)->getViaLane() != nullptr && (*it_link)->getViaLane()->getVehicleNumberWithPartials() > 0) {
103 // do not open if there is still a train on the crossing
104 stayRedUntil = MAX2(stayRedUntil, now + DELTA_T);
105 }
106 }
107 //if (getID() == "cluster_1088529493_1260626727") std::cout << SIMTIME << " stayRedUntil=" << stayRedUntil;
108 const SUMOTime wait = stayRedUntil - now;
109
110 if (myStep == 0) {
111 // 'G': check whether the crossing can stay open
112 if (wait == 0) {
113 return DELTA_T;
114 } else {
115 myStep++;
116 return myYellowTime;
117 }
118 } else if (myStep == 1) {
119 // 'y': yellow time is over. switch to red
120 myStep++;
121 return MAX2(DELTA_T, wait);
122 } else {
123 // 'r': check whether we may open again
124 if (wait == 0) {
125 myStep = 0;
126 return myMinGreenTime;
127 } else {
128 return wait;
129 }
130 }
131 }
132
133
134 // ------------ Conversion between time and phase
135 SUMOTime
getPhaseIndexAtTime(SUMOTime) const136 MSRailCrossing::getPhaseIndexAtTime(SUMOTime) const {
137 return 0;
138 }
139
140 SUMOTime
getOffsetFromIndex(int) const141 MSRailCrossing::getOffsetFromIndex(int) const {
142 return 0;
143 }
144
145 int
getIndexFromOffset(SUMOTime) const146 MSRailCrossing::getIndexFromOffset(SUMOTime) const {
147 return 0;
148 }
149
150
151 void
addLink(MSLink * link,MSLane * lane,int pos)152 MSRailCrossing::addLink(MSLink* link, MSLane* lane, int pos) {
153 if (pos >= 0) {
154 MSTrafficLightLogic::addLink(link, lane, pos);
155 } else {
156 myIncomingRailLinks.push_back(link);
157 }
158 }
159
160
161 /****************************************************************************/
162
163