Eclipse SUMO - Simulation of Urban MObility
MSRailSignalControl.cpp
Go to the documentation of this file.
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 /****************************************************************************/
18 // Centralized services for rail signal control (Singleton)
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <cassert>
23 #include <utility>
24 #include <vector>
25 #include <bitset>
26 #include <microsim/MSNet.h>
27 #include <microsim/MSRoute.h>
28 #include <microsim/MSEdge.h>
29 #include "MSRailSignal.h"
30 #include "MSRailSignalControl.h"
31 
32 
33 //#define DEBUG_REGISTER_DRIVEWAY
34 //#define DEBUG_SIGNALSTATE
35 //#define DEBUG_RECHECKGREEN
36 
37 // ===========================================================================
38 // static value definitions
39 // ===========================================================================
41 
42 // ===========================================================================
43 // method definitions
44 // ===========================================================================
46 {}
47 
50  if (myInstance == nullptr) {
53  }
54  return *myInstance;
55 }
56 
57 void
59  delete myInstance;
60  myInstance = nullptr;
61 }
62 
63 void
65  if (myInstance != nullptr) {
66  myInstance->myUsedEdges.clear();
69  }
70 }
71 
72 
74 }
75 
76 void
77 MSRailSignalControl::vehicleStateChanged(const SUMOVehicle* const vehicle, MSNet::VehicleState to, const std::string& /*info*/) {
78  if (isRailway(vehicle->getVClass())) {
80  for (const MSEdge* edge : vehicle->getRoute().getEdges()) {
81  myUsedEdges.insert(edge);
82  if (myProtectedDriveways.count(edge) != 0) {
83 #ifdef DEBUG_REGISTER_DRIVEWAY
84  std::cout << "MSRailSignalControl edge=" << edge->getID() << " used by vehicle " << vehicle->getID() << ". Updating " << myProtectedDriveways[edge].size() << " driveways\n";
85 #endif
86  updateDriveways(edge);
87  }
88  }
89  }
90  if (to == MSNet::VehicleState::BUILT || (!vehicle->hasDeparted() && to == MSNet::VehicleState::NEWROUTE)) {
91  // @note we could delay initialization until the departure time
93  }
94  }
95 }
96 
97 
98 void
99 MSRailSignalControl::registerProtectedDriveway(MSRailSignal* rs, int driveWayID, const MSEdge* protectedBidi) {
100  myProtectedDriveways[protectedBidi].push_back(std::make_pair(rs, driveWayID));
101 #ifdef DEBUG_REGISTER_DRIVEWAY
102  std::cout << "MSRailSignalControl edge=" << protectedBidi->getID() << " assumed secure by driveway " << driveWayID << " at signal " << rs->getID() << "\n";
103 #endif
104 }
105 
106 void
108  for (auto item : myProtectedDriveways[used]) {
109  item.first->updateDriveway(item.second);
110  }
111  myProtectedDriveways.erase(used);
112 }
113 
114 
115 void
117  mySignals.push_back(signal);
118 }
119 
120 
121 void
123  if (mySwitchedGreenFlanks.size() > 0) {
124  for (const auto& item : mySwitchedGreenFlanks) {
125  for (const auto& item2 : mySwitchedGreenFlanks) {
126  if (item.second < item2.second) {
127  bool conflict = false;
128  std::pair<int, int> code(item.second, item2.second);
129  auto it = myDriveWayCompatibility.find(code);
130  if (it != myDriveWayCompatibility.end()) {
131  conflict = it->second;
132  } else {
133  // new driveway pair
134  const MSRailSignal* rs = static_cast<const MSRailSignal*>(item.first->getTLLogic());
135  const MSRailSignal* rs2 = static_cast<const MSRailSignal*>(item2.first->getTLLogic());
136  const MSRailSignal::DriveWay& dw = rs->retrieveDriveWay(item.second);
137  const MSRailSignal::DriveWay& dw2 = rs2->retrieveDriveWay(item2.second);
138  // overlap may return true if the driveways are consecutive forward sections
139  conflict = dw.flankConflict(dw2) || dw2.flankConflict(dw);
140  myDriveWayCompatibility[code] = conflict;
141 #ifdef DEBUG_RECHECKGREEN
142  std::cout << SIMTIME << " new code " << code.first << "," << code.second << " conflict=" << conflict << " dw=" << toString(dw.myRoute) << " dw2=" << toString(dw2.myRoute) << "\n";
143 #endif
144  }
145  if (conflict) {
146  MSRailSignal* rs = const_cast<MSRailSignal*>(static_cast<const MSRailSignal*>(item.first->getTLLogic()));
147  MSRailSignal* rs2 = const_cast<MSRailSignal*>(static_cast<const MSRailSignal*>(item2.first->getTLLogic()));
148  const MSRailSignal::Approaching& veh = rs->getClosest(item.first);
149  const MSRailSignal::Approaching& veh2 = rs2->getClosest(item2.first);
150  if (MSRailSignal::DriveWay::mustYield(veh, veh2)) {
151  std::string state = rs->getCurrentPhaseDef().getState();
152  state[item.first->getTLIndex()] = 'r';
153  const_cast<MSPhaseDefinition&>(rs->getCurrentPhaseDef()).setState(state);
155 #ifdef DEBUG_RECHECKGREEN
156  std::cout << SIMTIME << " reset to red " << getClickableTLLinkID(item.first)
157  << " (" << veh.first->getID() << " yields to " << veh2.first->getID() << "\n";
158 #endif
159 #ifdef DEBUG_SIGNALSTATE
160  if (DEBUG_HELPER(rs)) {
161  std::cout << SIMTIME << " reset to red " << getClickableTLLinkID(item.first)
162  << " (" << veh.first->getID() << " yields to " << veh2.first->getID() << "\n";
163  }
164 #endif
165  } else {
166  std::string state = rs2->getCurrentPhaseDef().getState();
167  state[item2.first->getTLIndex()] = 'r';
168  const_cast<MSPhaseDefinition&>(rs2->getCurrentPhaseDef()).setState(state);
170 #ifdef DEBUG_RECHECKGREEN
171  std::cout << SIMTIME << " reset to red " << getClickableTLLinkID(item2.first)
172  << " (" << veh2.first->getID() << " yields to " << veh.first->getID() << "\n";
173 #endif
174 #ifdef DEBUG_SIGNALSTATE
175  if (DEBUG_HELPER(rs2)) {
176  std::cout << SIMTIME << " reset to red " << getClickableTLLinkID(item2.first)
177  << " (" << veh2.first->getID() << " yields to " << veh.first->getID() << "\n";
178  }
179 #endif
180  }
181  }
182  }
183  }
184  }
185  mySwitchedGreenFlanks.clear();
186  }
187 }
188 
189 
190 /****************************************************************************/
#define DEBUG_HELPER(obj)
#define SIMTIME
Definition: SUMOTime.h:62
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a railway edge.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A road/street connecting two junctions.
Definition: MSEdge.h:77
VehicleState
Definition of a vehicle state.
Definition: MSNet.h:608
@ BUILT
The vehicle was built, but has not yet departed.
@ NEWROUTE
The vehicle got a new route.
@ DEPARTED
The vehicle has departed (was inserted into the network)
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:184
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:320
void addVehicleStateListener(VehicleStateListener *listener)
Adds a vehicle states listener.
Definition: MSNet.cpp:1250
The definition of a single phase of a tls logic.
const std::string & getState() const
Returns the state within this phase.
A signal for rails.
void addSignal(MSRailSignal *signal)
void vehicleStateChanged(const SUMOVehicle *const vehicle, MSNet::VehicleState to, const std::string &info="")
Called if a vehicle changes its state.
std::map< const MSEdge *, std::vector< std::pair< MSRailSignal *, int > > > myProtectedDriveways
map of driveways that must perform additional checks if the key edge is used by a train route
std::vector< MSRailSignal * > mySignals
list of all rail signals
MSRailSignalControl()
Constructor.
std::set< const MSEdge * > myUsedEdges
all rail edges that are part of a known route
void recheckGreen()
final check for driveway compatibility of signals that switched green in this step
static MSRailSignalControl * myInstance
static MSRailSignalControl & getInstance()
void updateDriveways(const MSEdge *used)
compute additioanl deadlock-check requirements for registered driveways
std::map< std::pair< int, int >, bool > myDriveWayCompatibility
static void clearState()
Perform resets events when quick-loading state.
std::vector< std::pair< MSLink *, int > > mySwitchedGreenFlanks
list of signals that switched green along with driveway index
void registerProtectedDriveway(MSRailSignal *rs, int driveWayID, const MSEdge *protectedBidi)
mark driveway that must receive additional checks if protectedBidi is ever used by a train route
A signal for rails.
Definition: MSRailSignal.h:46
static Approaching getClosest(MSLink *link)
get the closest vehicle approaching the given link
std::pair< const SUMOVehicle *const, const MSLink::ApproachingVehicleInformation > Approaching
Definition: MSRailSignal.h:254
const DriveWay & retrieveDriveWay(int numericalID) const
const MSPhaseDefinition & getCurrentPhaseDef() const override
Returns the definition of the current phase.
static void initDriveWays(const SUMOVehicle *ego, bool update)
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:124
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
const std::string & getID() const
Returns the id.
Definition: Named.h:74
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
Representation of a vehicle.
Definition: SUMOVehicle.h:62
virtual const MSRoute & getRoute() const =0
Returns the current route.
virtual bool hasDeparted() const =0
Returns whether this vehicle has departed.
std::vector< const MSEdge * > myRoute
list of edges for matching against train routes
Definition: MSRailSignal.h:291
bool flankConflict(const DriveWay &other) const
Wether there is a flank conflict with the given driveway.
static bool mustYield(const Approaching &veh, const Approaching &foe)
Whether veh must yield to the foe train.