SUMO - Simulation of Urban MObility
MSRailSignal.cpp
Go to the documentation of this file.
1 /****************************************************************************/
8 // A rail signal logic
9 /****************************************************************************/
10 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
11 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
12 /****************************************************************************/
13 //
14 // This file is part of SUMO.
15 // SUMO is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <cassert>
33 #include <utility>
34 #include <vector>
35 #include <bitset>
37 #include <microsim/MSNet.h>
38 #include <microsim/MSEdge.h>
39 #include <microsim/MSLink.h>
40 #include <microsim/MSVehicle.h>
41 #include "MSTrafficLightLogic.h"
42 #include "MSRailSignal.h"
43 #include <microsim/MSLane.h>
44 #include "MSPhaseDefinition.h"
45 #include "MSTLLogicControl.h"
46 
47 
48 class ApproachingVehicleInformation;
49 // ===========================================================================
50 // method definitions
51 // ===========================================================================
53  const std::string& id, const std::string& subid,
54  const std::map<std::string, std::string>& parameters) :
55  MSTrafficLightLogic(tlcontrol, id, subid, DELTA_T, parameters),
56  myCurrentPhase(DELTA_T, std::string(SUMO_MAX_CONNECTIONS, 'X')) { // dummy phase
58 }
59 
60 void
62  assert(myLanes.size() > 0);
63  LinkVectorVector::iterator i2; //iterator of the link indices of this junction (most likely there is just one link per index)
64  // find all outgoing lanes from the junction and its succeeding lanes leading to the next rail signal
65  // and find for every link at the junction all lanes leading from a previous signal to this link
66  for (i2 = myLinks.begin(); i2 != myLinks.end(); ++i2) { //for every link index
67  const LinkVector& links = *i2;
68  LinkVector::const_iterator i; //iterator of the links that belong to the same link index
69  for (i = links.begin(); i != links.end(); i++) { //for every link that belongs to the current index
70  MSLink* link = (*i);
71  MSLane* toLane = link->getLane(); //the lane this link is leading to
72  myLinksToLane[toLane].push_back(link);
73  myLinkIndices[link] = (int)std::distance(myLinks.begin(), i2); //assign the index of link to link
74 
75  //find all lanes leading from a previous signal to link (we presume that there exists only one path from a previous signal to link)
76  std::vector<const MSLane*> afferentBlock; //the vector of lanes leading from a previous signal to link
77  bool noRailSignal = true; //true if the considered lane is not outgoing from a rail signal
78  //get the approaching lane of the link
79  const MSLane* approachingLane = link->getLaneBefore(); //the lane this link is coming from
80  afferentBlock.push_back(approachingLane);
81  const MSLane* currentLane = approachingLane;
82  //look recursively for all lanes that lie before approachingLane and add them to afferentBlock until a rail signal is found
83  while (noRailSignal) {
84  std::vector<MSLane::IncomingLaneInfo> incomingLanes = currentLane->getIncomingLanes();
85  MSLane* precedentLane;
86  if (!incomingLanes.empty()) {
87  precedentLane = incomingLanes.front().lane;
88  } else {
89  precedentLane = 0;
90  }
91  if (precedentLane == 0) { //if there is no preceeding lane
92  noRailSignal = false;
93  } else {
94  const MSJunction* junction = precedentLane->getEdge().getToJunction();
95  if ((junction != 0) && (junction->getType() == NODETYPE_RAIL_SIGNAL)) { //if this junction exists and if it has a rail signal
96  noRailSignal = false;
97  } else {
98  afferentBlock.push_back(precedentLane);
99  currentLane = precedentLane;
100  }
101  }
102  }
103  myAfferentBlocks[link] = afferentBlock;
104 
105  //find all lanes leading from toLane to the next signal if it was not already done
106  if (std::find(myOutgoingLanes.begin(), myOutgoingLanes.end(), toLane) == myOutgoingLanes.end()) { //if toLane was not already contained in myOutgoingLanes
107  myOutgoingLanes.push_back(toLane);
108  std::vector<const MSLane*> succeedingBlock; //the vector of lanes leading to the next rail signal
109  succeedingBlock.push_back(toLane);
110  currentLane = toLane;
111  bool noRailSignalLocal = true; //true if the considered lane is not ending at a rail signal
112  while (noRailSignalLocal) {
113  //check first if the current lane is ending at a rail signal
114  std::vector<MSLink*> outGoingLinks = currentLane->getLinkCont();
115  std::vector<MSLink*>::const_iterator j;
116  for (j = outGoingLinks.begin(); j != outGoingLinks.end(); j++) {
117  const MSJunction* junction = currentLane->getEdge().getToJunction();
118  if ((junction != 0) && (junction->getType() == NODETYPE_RAIL_SIGNAL)) { //if this junctions exists and if it has a rail signal
119  noRailSignalLocal = false;
120  break;
121  }
122  }
123  if (noRailSignalLocal) { //if currentLane is not ending at a railSignal
124  //get the next lane
125  std::vector<const MSLane*> outGoingLanes = currentLane->getOutgoingLanes();
126  if (outGoingLanes.size() == 0) { //if the current lane has no outgoing lanes (deadend)
127  noRailSignalLocal = false;
128  } else {
129  if (outGoingLanes.size() > 1) {
130  WRITE_WARNING("Rail lane '" + currentLane->getID() + "' has more than one outgoing lane but does not have a rail signal at its end");
131  }
132  const MSLane* nextLane = outGoingLanes.front();
133  succeedingBlock.push_back(nextLane);
134  currentLane = nextLane;
135  }
136  }
137  }
138  mySucceedingBlocks[toLane] = succeedingBlock;
139  }
140  }
141  }
142 
143 
144  for (std::map<MSLane*, std::vector<const MSLane*> >::iterator it = mySucceedingBlocks.begin(); it != mySucceedingBlocks.end(); it++) {
145  std::queue<const MSLane*> revLanes;
146  for (std::vector<const MSLane*>::iterator laneIt = it->second.begin(); laneIt != it->second.end(); laneIt++) {
147  const MSLane* lane = *laneIt;
148 
149  const MSEdge* reverseEdge = lane->getEdge().getMyOppositeSuperposableEdge();
150  if (reverseEdge != 0) {
151  const MSLane* revLane = reverseEdge->getLanes()[0];
152  revLanes.push(revLane);
153  const MSLane* pred = revLane->getCanonicalPredecessorLane();
154  if (pred != 0) {
155  const MSLink* msLink = pred->getLinkTo(revLane);
156  mySucceedingBlocksIncommingLinks[lane] = msLink;
157  }
158  }
159  }
160 
161  while (!revLanes.empty()) {
162  const MSLane* revLane = revLanes.front();
163  it->second.push_back(revLane);
164  revLanes.pop();
165  }
166  }
167 
168  updateCurrentPhase(); //check if this is necessary or if will be done already at another stage
169  setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
170 }
171 
172 
174 
175 
176 // ----------- Handling of controlled links
177 void
181 }
182 
183 
184 // ------------ Switching and setting current rows
185 SUMOTime
188  setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
189  return DELTA_T;
190 }
191 
192 std::string
194  std::string state(myLinks.size(), 'G'); //the state of the phase definition (all signal are green)
195  std::vector<MSLane*>::const_iterator i; //the iterator of outgoing lanes of this junction
196  for (i = myOutgoingLanes.begin(); i != myOutgoingLanes.end(); i++) { //for every outgoing lane
197  MSLane* lane = (*i);
198 
199  //check if the succeeding block is used by a train
200  bool succeedingBlockOccupied = false;
201  std::vector<const MSLane*>::const_iterator j;
202  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
203  if (!(*j)->isEmpty()) { //if this lane is not empty
204  succeedingBlockOccupied = true;
205  } else {
206  std::map<const MSLane*, const MSLink*>::iterator it = mySucceedingBlocksIncommingLinks.find(lane);
207  if (it != mySucceedingBlocksIncommingLinks.end()) {
208  const MSLink* inCommingLing = it->second;
209  const std::map<const SUMOVehicle*, MSLink::ApproachingVehicleInformation> approaching = inCommingLing->getApproaching();
210  std::map<const SUMOVehicle*, MSLink::ApproachingVehicleInformation>::const_iterator apprIt = approaching.begin();
211  for (; apprIt != approaching.end(); apprIt++) {
212  MSLink::ApproachingVehicleInformation info = apprIt->second;
213  if (info.arrivalSpeedBraking > 0) {
214  succeedingBlockOccupied = true;
215  break;
216  }
217  }
218 
219  }
220  }
221  if (succeedingBlockOccupied) {
222  break;
223  }
224  }
225 
226  /*-if the succeeding block is occupied the signals for all links leading to lane will be set to red.
227  -if the succeeding block is not occupied and all blocks leading to lane are not occupied all signal
228  will keep green.
229  -if the succeeding block is not occupied and there is only one block leading to lane its signal will
230  keep green (no matter if this block is occupied or not).
231  -if the succeeding block is not occupied and there is more than one block leading to lane and some
232  of them are occupied the signals for all links leading to lane, except one whose corresponding block
233  is occupied, will be set to red. the signal for the remaining block will keep green*/
234  if (succeedingBlockOccupied) { //if the succeeding block is used by a train
235  std::vector<MSLink*>::const_iterator k;
236  for (k = myLinksToLane[lane].begin(); k != myLinksToLane[lane].end(); k++) { //for every link leading to this lane
237  state.replace(myLinkIndices[*k], 1, "r"); //set the signal of the link (*k) to red
238  }
239  } else {
240  if (myLinksToLane[lane].size() > 1) { //if there is more than one link leading to lane
241  bool hasOccupiedBlock = false;
242  std::vector<MSLink*>::const_iterator k;
243  for (k = myLinksToLane[lane].begin(); k != myLinksToLane[lane].end(); k++) { //for every link leading to lane
244  std::vector<const MSLane*>::const_iterator l;
245  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)
246  if (!(*l)->isEmpty()) { //if this lane is not empty
247  hasOccupiedBlock = true;
248  //set the signals for all links leading to lane, except for (*k), to red; the signal for (*k) will remain green
249  std::vector<MSLink*>::const_iterator m;
250  for (m = myLinksToLane[lane].begin(); m != myLinksToLane[lane].end(); m++) { //for every link leading to lane
251  if (*m != *k) { //if this link is not the one corresponding to occupiedBlock
252  state.replace(myLinkIndices[*m], 1, "r"); //set the signal of this link to red
253  }
254  }
255  break; // we don't have to check the other lanes of this block anymore
256  }
257  }
258  if (hasOccupiedBlock) { //we don't have to check the other blocks anymore
259  break;
260  }
261  }
262  }
263  }
264  }
265  return state;
266 }
267 
268 
269 void
272 }
273 
274 
275 // ------------ Static Information Retrieval
276 int
278  return 0;
279 }
280 
283  return myPhases;
284 }
285 
286 const MSPhaseDefinition&
288  return myCurrentPhase;
289 }
290 
291 // ------------ Dynamic Information Retrieval
292 int
294  return 0;
295 }
296 
297 const MSPhaseDefinition&
299  return myCurrentPhase;
300 }
301 
302 // ------------ Conversion between time and phase
303 SUMOTime
305  return 0;
306 }
307 
308 SUMOTime
310  return 0;
311 }
312 
313 int
315  return 0;
316 }
317 
318 
319 /****************************************************************************/
320 
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:582
Builds detectors for microsim.
int getCurrentPhaseIndex() const
Returns the current index within the program.
bool setTrafficLightSignals(SUMOTime t) const
Applies the current signal states to controlled links.
MSLink * getLinkTo(const MSLane *) const
returns the link to the given lane or 0, if it is not connected
Definition: MSLane.cpp:1786
void updateCurrentPhase()
updates the current phase of the signal
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:168
SUMOTime getOffsetFromIndex(int index) const
Returns the position (start of a phase during a cycle) from of a given step.
The base class for an intersection.
Definition: MSJunction.h:64
int getPhaseNumber() const
Returns the number of phases.
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:219
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:169
const MSPhaseDefinition & getPhase(int givenstep) const
Returns the definition of the phase from the given position within the plan.
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
Definition: StdDefs.h:43
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
std::map< const MSLane *, const MSLink * > mySucceedingBlocksIncommingLinks
A map of lanes to links of approaching vehicles of succeeding blocks.
Definition: MSRailSignal.h:228
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
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:216
A class that stores and controls tls and switching of their programs.
int getIndexFromOffset(SUMOTime offset) const
Returns the step (the phasenumber) of a given position of the cycle.
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:81
SUMOTime getPhaseIndexAtTime(SUMOTime simStep) const
Returns the index of the logic at the given simulation step.
std::vector< MSLane * > myOutgoingLanes
The set of lanes going out from the junction.
Definition: MSRailSignal.h:213
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:237
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:225
const MSEdge * getMyOppositeSuperposableEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
Definition: MSEdge.h:244
const MSPhaseDefinition & getCurrentPhaseDef() const
Returns the definition of the current phase.
SumoXMLNodeType getType() const
return the type of this Junction
Definition: MSJunction.h:128
SUMOTime trySwitch()
Switches to the next phase.
MSLane * getCanonicalPredecessorLane() const
Definition: MSLane.cpp:2200
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.
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2252
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.
const Phases & getPhases() const
Returns the phases of this tls program.
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:52
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1779
MSPhaseDefinition myCurrentPhase
The current phase.
Definition: MSRailSignal.h:240
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:222
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:727
The definition of a single phase of a tls logic.
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
MSRailSignal(MSTLLogicControl &tlcontrol, const std::string &id, const std::string &subid, const std::map< std::string, std::string > &parameters)
Constructor.
const MSJunction * getToJunction() const
Definition: MSEdge.h:353
~MSRailSignal()
Destructor.