SUMO - Simulation of Urban MObility
MSRailSignal.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
18 // A rail signal logic
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <cassert>
32 #include <utility>
33 #include <vector>
34 #include <bitset>
36 #include <microsim/MSNet.h>
37 #include <microsim/MSEdge.h>
38 #include <microsim/MSLink.h>
39 #include <microsim/MSVehicle.h>
40 #include "MSTrafficLightLogic.h"
41 #include "MSRailSignal.h"
42 #include <microsim/MSLane.h>
43 #include "MSPhaseDefinition.h"
44 #include "MSTLLogicControl.h"
45 
46 //#define DEBUG_SUCCEEDINGBLOCKS
47 #define DEBUG_COND (getID() == "disabled")
48 
49 class ApproachingVehicleInformation;
50 // ===========================================================================
51 // method definitions
52 // ===========================================================================
54  const std::string& id, const std::string& subid,
55  const std::map<std::string, std::string>& parameters) :
56  MSTrafficLightLogic(tlcontrol, id, subid, DELTA_T, parameters),
57  myCurrentPhase(DELTA_T, std::string(SUMO_MAX_CONNECTIONS, 'X')) { // dummy phase
59 }
60 
61 void
63  assert(myLanes.size() > 0);
64  LinkVectorVector::iterator i2; //iterator of the link indices of this junction (most likely there is just one link per index)
65  // find all outgoing lanes from the junction and its succeeding lanes leading to the next rail signal
66  // and find for every link at the junction all lanes leading from a previous signal to this link
67  for (i2 = myLinks.begin(); i2 != myLinks.end(); ++i2) { //for every link index
68  const LinkVector& links = *i2;
69  LinkVector::const_iterator i; //iterator of the links that belong to the same link index
70  for (i = links.begin(); i != links.end(); i++) { //for every link that belongs to the current index
71  MSLink* link = (*i);
72  MSLane* toLane = link->getLane(); //the lane this link is leading to
73  myLinksToLane[toLane].push_back(link);
74  myLinkIndices[link] = (int)std::distance(myLinks.begin(), i2); //assign the index of link to link
75 
76  //find all lanes leading from a previous signal to link (we presume that there exists only one path from a previous signal to link)
77  std::vector<const MSLane*> afferentBlock; //the vector of lanes leading from a previous signal to link
78  bool noRailSignal = true; //true if the considered lane is not outgoing from a rail signal
79  //get the approaching lane of the link
80  const MSLane* approachingLane = link->getLaneBefore(); //the lane this link is coming from
81  afferentBlock.push_back(approachingLane);
82  const MSLane* currentLane = approachingLane;
83  //look recursively for all lanes that lie before approachingLane and add them to afferentBlock until a rail signal is found
84  while (noRailSignal) {
85  std::vector<MSLane::IncomingLaneInfo> incomingLanes = currentLane->getIncomingLanes();
86  MSLane* precedentLane;
87  if (!incomingLanes.empty()) {
88  precedentLane = incomingLanes.front().lane;
89  } else {
90  precedentLane = 0;
91  }
92  if (precedentLane == 0) { //if there is no preceeding lane
93  noRailSignal = false;
94  } else {
95  const MSJunction* junction = precedentLane->getEdge().getToJunction();
96  if ((junction != 0) && (junction->getType() == NODETYPE_RAIL_SIGNAL)) { //if this junction exists and if it has a rail signal
97  noRailSignal = false;
98  } else {
99  afferentBlock.push_back(precedentLane);
100  currentLane = precedentLane;
101  }
102  }
103  }
104  myAfferentBlocks[link] = afferentBlock;
105 
106  //find all lanes leading from toLane to the next signal if it was not already done
107  if (std::find(myOutgoingLanes.begin(), myOutgoingLanes.end(), toLane) == myOutgoingLanes.end()) { //if toLane was not already contained in myOutgoingLanes
108  myOutgoingLanes.push_back(toLane);
109  std::vector<const MSLane*> succeedingBlock; //the vector of lanes leading to the next rail signal
110  succeedingBlock.push_back(toLane);
111  currentLane = toLane;
112  bool noRailSignalLocal = true; //true if the considered lane is not ending at a rail signal
113  while (noRailSignalLocal) {
114  //check first if the current lane is ending at a rail signal
115  std::vector<MSLink*> outGoingLinks = currentLane->getLinkCont();
116  std::vector<MSLink*>::const_iterator j;
117  for (j = outGoingLinks.begin(); j != outGoingLinks.end(); j++) {
118  const MSJunction* junction = currentLane->getEdge().getToJunction();
119  if ((junction != 0) && (junction->getType() == NODETYPE_RAIL_SIGNAL)) { //if this junctions exists and if it has a rail signal
120  noRailSignalLocal = false;
121  break;
122  }
123  }
124  if (noRailSignalLocal) { //if currentLane is not ending at a railSignal
125  //get the next lane
126  std::vector<const MSLane*> outGoingLanes = currentLane->getOutgoingLanes();
127  if (outGoingLanes.size() == 0) { //if the current lane has no outgoing lanes (deadend)
128  noRailSignalLocal = false;
129  } else {
130  if (outGoingLanes.size() > 1) {
131  WRITE_WARNING("Rail lane '" + currentLane->getID() + "' has more than one outgoing lane but does not have a rail signal at its end");
132  }
133  const MSLane* nextLane = outGoingLanes.front();
134  succeedingBlock.push_back(nextLane);
135  currentLane = nextLane;
136  }
137  }
138  }
139  mySucceedingBlocks[toLane] = succeedingBlock;
140  }
141  }
142  }
143 #ifdef DEBUG_SUCCEEDINGBLOCKS
144  if (DEBUG_COND) {
145  std::cout << "railSignal=" << getID() << " mySucceedingBlocks:\n";
146  for (auto item : mySucceedingBlocks) {
147  std::cout << " toLane=" << item.first->getID() << " succ=" << toString(item.second) << "\n";
148  }
149  }
150 #endif
151 
152 
153  for (std::map<MSLane*, std::vector<const MSLane*> >::iterator it = mySucceedingBlocks.begin(); it != mySucceedingBlocks.end(); it++) {
154  std::queue<const MSLane*> revLanes;
155  for (std::vector<const MSLane*>::iterator laneIt = it->second.begin(); laneIt != it->second.end(); laneIt++) {
156  const MSLane* lane = *laneIt;
157 
158  const MSEdge* reverseEdge = lane->getEdge().getMyOppositeSuperposableEdge();
159  if (reverseEdge != 0) {
160  const MSLane* revLane = reverseEdge->getLanes()[0];
161  revLanes.push(revLane);
162  const MSLane* pred = revLane->getCanonicalPredecessorLane();
163  if (pred != 0) {
164  const MSLink* msLink = pred->getLinkTo(revLane);
165  mySucceedingBlocksIncommingLinks[lane] = msLink;
166  }
167  }
168  }
169 
170  while (!revLanes.empty()) {
171  const MSLane* revLane = revLanes.front();
172  it->second.push_back(revLane);
173  revLanes.pop();
174  }
175  }
176 
177  updateCurrentPhase(); //check if this is necessary or if will be done already at another stage
178  setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
179 }
180 
181 
183 
184 
185 // ----------- Handling of controlled links
186 void
190 }
191 
192 
193 // ------------ Switching and setting current rows
194 SUMOTime
197  setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
198  return DELTA_T;
199 }
200 
201 std::string
203  std::string state(myLinks.size(), 'G'); //the state of the phase definition (all signal are green)
204  std::vector<MSLane*>::const_iterator i; //the iterator of outgoing lanes of this junction
205  for (i = myOutgoingLanes.begin(); i != myOutgoingLanes.end(); i++) { //for every outgoing lane
206  MSLane* lane = (*i);
207 
208  //check if the succeeding block is used by a train
209  bool succeedingBlockOccupied = false;
210  std::vector<const MSLane*>::const_iterator j;
211  for (j = mySucceedingBlocks.at(lane).begin(); j != mySucceedingBlocks.at(lane).end(); j++) { //for every lane in the block between the current signal and the next signal
212  if (!(*j)->isEmpty()) { //if this lane is not empty
213  succeedingBlockOccupied = true;
214  } else {
215  std::map<const MSLane*, const MSLink*>::iterator it = mySucceedingBlocksIncommingLinks.find(lane);
216  if (it != mySucceedingBlocksIncommingLinks.end()) {
217  const MSLink* inCommingLing = it->second;
218  const std::map<const SUMOVehicle*, MSLink::ApproachingVehicleInformation, SUMOVehicle::ComparatorIdLess> approaching = inCommingLing->getApproaching();
219  std::map<const SUMOVehicle*, MSLink::ApproachingVehicleInformation>::const_iterator apprIt = approaching.begin();
220  for (; apprIt != approaching.end(); apprIt++) {
221  MSLink::ApproachingVehicleInformation info = apprIt->second;
222  if (info.arrivalSpeedBraking > 0) {
223  succeedingBlockOccupied = true;
224  break;
225  }
226  }
227 
228  }
229  }
230  if (succeedingBlockOccupied) {
231  break;
232  }
233  }
234 
235  /*-if the succeeding block is occupied the signals for all links leading to lane will be set to red.
236  -if the succeeding block is not occupied and all blocks leading to lane are not occupied all signal
237  will keep green.
238  -if the succeeding block is not occupied and there is only one block leading to lane its signal will
239  keep green (no matter if this block is occupied or not).
240  -if the succeeding block is not occupied and there is more than one block leading to lane and some
241  of them are occupied the signals for all links leading to lane, except one whose corresponding block
242  is occupied, will be set to red. the signal for the remaining block will keep green*/
243  if (succeedingBlockOccupied) { //if the succeeding block is used by a train
244  std::vector<MSLink*>::const_iterator k;
245  for (k = myLinksToLane[lane].begin(); k != myLinksToLane[lane].end(); k++) { //for every link leading to this lane
246  state.replace(myLinkIndices[*k], 1, "r"); //set the signal of the link (*k) to red
247  }
248  } else {
249  if (myLinksToLane[lane].size() > 1) { //if there is more than one link leading to lane
250  bool hasOccupiedBlock = false;
251  std::vector<MSLink*>::const_iterator k;
252  for (k = myLinksToLane[lane].begin(); k != myLinksToLane[lane].end(); k++) { //for every link leading to lane
253  std::vector<const MSLane*>::const_iterator l;
254  for (l = myAfferentBlocks[(*k)].begin(); l != myAfferentBlocks[(*k)].end(); l++) { //for every lane of the block leading from a previous signal to the link (*k)
255  if (!(*l)->isEmpty()) { //if this lane is not empty
256  hasOccupiedBlock = true;
257  //set the signals for all links leading to lane, except for (*k), to red; the signal for (*k) will remain green
258  std::vector<MSLink*>::const_iterator m;
259  for (m = myLinksToLane[lane].begin(); m != myLinksToLane[lane].end(); m++) { //for every link leading to lane
260  if (*m != *k) { //if this link is not the one corresponding to occupiedBlock
261  state.replace(myLinkIndices[*m], 1, "r"); //set the signal of this link to red
262  }
263  }
264  break; // we don't have to check the other lanes of this block anymore
265  }
266  }
267  if (hasOccupiedBlock) { //we don't have to check the other blocks anymore
268  break;
269  }
270  }
271  }
272  }
273  }
274  return state;
275 }
276 
277 
278 void
281 }
282 
283 
284 // ------------ Static Information Retrieval
285 int
287  return 0;
288 }
289 
292  return myPhases;
293 }
294 
295 const MSPhaseDefinition&
297  return myCurrentPhase;
298 }
299 
300 // ------------ Dynamic Information Retrieval
301 int
303  return 0;
304 }
305 
306 const MSPhaseDefinition&
308  return myCurrentPhase;
309 }
310 
311 // ------------ Conversion between time and phase
312 SUMOTime
314  return 0;
315 }
316 
317 SUMOTime
319  return 0;
320 }
321 
322 int
324  return 0;
325 }
326 
327 
328 /****************************************************************************/
329 
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:752
Builds detectors for microsim.
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:607
void updateCurrentPhase()
updates the current phase of the signal
const MSPhaseDefinition & getPhase(int givenstep) const
Returns the definition of the phase from the given position within the plan.
The base class for an intersection.
Definition: MSJunction.h:64
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2347
std::map< MSLane *, std::vector< MSLink * > > myLinksToLane
A map that maps an outgoing lane from the junction to its set of links that lead to this lane...
Definition: MSRailSignal.h:218
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:167
int getIndexFromOffset(SUMOTime offset) const
Returns the step (the phasenumber) of a given position of the cycle.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:167
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
Definition: StdDefs.h:42
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
std::map< const MSLane *, const MSLink * > mySucceedingBlocksIncommingLinks
A map of lanes to links of approaching vehicles of succeeding blocks.
Definition: MSRailSignal.h:227
MSLink * getLinkTo(const MSLane *) const
returns the link to the given lane or 0, if it is not connected
Definition: MSLane.cpp:1881
MSLane * getCanonicalPredecessorLane() const
Definition: MSLane.cpp:2295
const std::string & getID() const
Returns the id.
Definition: Named.h:65
const MSJunction * getToJunction() const
Definition: MSEdge.h:352
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:199
LaneVectorVector myLanes
The list of LaneVectors; each vector contains the incoming lanes that belong to the same link index...
std::map< MSLink *, int > myLinkIndices
A map that maps a link to its link index.
Definition: MSRailSignal.h:215
A class that stores and controls tls and switching of their programs.
A road/street connecting two junctions.
Definition: MSEdge.h:80
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
std::vector< MSLane * > myOutgoingLanes
The set of lanes going out from the junction.
Definition: MSRailSignal.h:212
SUMOTime myDefaultCycleTime
The cycle time (without changes)
void init(NLDetectorBuilder &nb)
Initialises the rail signal with information about adjacent rail signals.
Phases myPhases
The list of phases this logic uses.
Definition: MSRailSignal.h:236
const Phases & getPhases() const
Returns the phases of this tls program.
const MSPhaseDefinition & getCurrentPhaseDef() const
Returns the definition of the current phase.
virtual void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
std::map< MSLane *, std::vector< const MSLane * > > mySucceedingBlocks
A map that maps an outgoing lane from the junction to its vector of lanes leading to the next signal...
Definition: MSRailSignal.h:224
const MSEdge * getMyOppositeSuperposableEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
Definition: MSEdge.h:243
int getPhaseNumber() const
Returns the number of phases.
SUMOTime trySwitch()
Switches to the next phase.
#define DEBUG_COND
std::vector< MSLink * > LinkVector
Definition of the list of links that are subjected to this tls.
std::vector< MSPhaseDefinition * > Phases
Definition of a list of phases, being the junction logic.
LinkVectorVector myLinks
The list of LinkVectors; each vector contains the links that belong to the same link index...
void adaptLinkInformationFrom(const MSTrafficLightLogic &logic)
Applies information about controlled links and lanes from the given logic.
SUMOTime getPhaseIndexAtTime(SUMOTime simStep) const
Returns the index of the logic at the given simulation step.
std::string getAppropriateState()
returns the state of the signal that actually required
The parent class for traffic light logics.
long long int SUMOTime
Definition: TraCIDefs.h:51
MSPhaseDefinition myCurrentPhase
The current phase.
Definition: MSRailSignal.h:239
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1874
std::map< MSLink *, std::vector< const MSLane * > > myAfferentBlocks
A map that maps a link from the junction to its vector of lanes leading from a previous signal to thi...
Definition: MSRailSignal.h:221
SUMOTime getOffsetFromIndex(int index) const
Returns the position (start of a phase during a cycle) from of a given step.
The definition of a single phase of a tls logic.
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
MSRailSignal(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &subid, const std::map< std::string, std::string > &parameters)
Constructor.
int getCurrentPhaseIndex() const
Returns the current index within the program.
SumoXMLNodeType getType() const
return the type of this Junction
Definition: MSJunction.h:128
~MSRailSignal()
Destructor.