Eclipse SUMO - Simulation of Urban MObility
MSPushButton.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2010-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 // The class for a PushButton
19 /****************************************************************************/
20 
21 #include <microsim/MSEdge.h>
22 #include <microsim/MSLane.h>
23 #include <microsim/MSVehicle.h>
25 #include "MSPushButton.h"
26 #include "MSPhaseDefinition.h"
27 //#define SWARM_DEBUG
28 
29 
30 // ===========================================================================
31 // static members
32 // ===========================================================================
33 std::map<std::string, std::vector<std::string> > MSPedestrianPushButton::m_crossingEdgeMap;
35 
36 // ===========================================================================
37 // method definitions
38 // ===========================================================================
39 MSPushButton::MSPushButton(const MSEdge* edge, const MSEdge* crossingEdge) {
40  m_edge = edge;
41  m_crossingEdge = crossingEdge;
42 }
43 
46 }
47 
48 bool MSPushButton::anyActive(const std::vector<MSPushButton*>& pushButtons) {
49  for (std::vector<MSPushButton*>::const_iterator it = pushButtons.begin(); it != pushButtons.end(); ++it) {
50  if (it.operator * ()->isActivated()) {
51  return true;
52  }
53  }
54  return false;
55 }
56 
57 
58 MSPedestrianPushButton::MSPedestrianPushButton(const MSEdge* walkingEdge, const MSEdge* crossingEdge)
59  : MSPushButton(walkingEdge, crossingEdge) {
60  assert(walkingEdge->isWalkingArea() || ((walkingEdge->getPermissions() & SVC_PEDESTRIAN) != 0));
61  assert(crossingEdge->isCrossing());
62 }
63 
66 }
67 
68 bool MSPedestrianPushButton::isActiveForEdge(const MSEdge* walkingEdge, const MSEdge* crossing) {
69  const std::set<MSTransportable*, ComparatorNumericalIdLess> persons = walkingEdge->getPersons();
70  if (persons.size() > 0) {
71  for (std::set<MSTransportable*>::const_iterator pIt = persons.begin(); pIt != persons.end(); ++pIt) {
72  const MSPerson* person = (MSPerson*)*pIt;
73  const MSEdge* nextEdge = person->getNextEdgePtr();
76  if (person->getWaitingSeconds() >= 1 && nextEdge && nextEdge->getID() == crossing->getID()) {
77 #ifdef SWARM_DEBUG
78  std::ostringstream oss;
79  oss << "MSPedestrianPushButton::isActiveForEdge Pushbutton active for edge " << walkingEdge->getID() << " crossing " << crossing->getID()
80  << " for " << person->getID() << " wait " << person->getWaitingSeconds();
81  WRITE_MESSAGE(oss.str());
82 #endif
83  return true;
84  }
85  }
86  } else {
87  //No person currently on the edge. But there may be some vehicles of class pedestrian
88  for (std::vector<MSLane*>::const_iterator laneIt = walkingEdge->getLanes().begin();
89  laneIt != walkingEdge->getLanes().end(); ++laneIt) {
90  MSLane* lane = *laneIt;
91  MSLane::VehCont vehicles = lane->getVehiclesSecure();
92  for (MSLane::VehCont::const_iterator vehicleIt = vehicles.begin(); vehicleIt != vehicles.end(); ++vehicleIt) {
93  MSVehicle* vehicle = *vehicleIt;
94  if (vehicle->getVClass() == SVC_PEDESTRIAN) {
95  // It's a pedestrian
96  const MSEdge* nextEdge = vehicle->succEdge(1);
97  if (vehicle->getWaitingSeconds() >= 1 && nextEdge) {
98  // Next edge is not internal. Try to find if between the current vehicle edge and the next is the crossing.
99  // To do that check if between the successors (or predecessor) of crossing is the next edge and walking precedes (or ensue) it.
100  if ((std::find(crossing->getPredecessors().begin(), crossing->getPredecessors().end(), walkingEdge) != crossing->getPredecessors().end()
101  && std::find(crossing->getSuccessors().begin(), crossing->getSuccessors().end(), nextEdge) != crossing->getSuccessors().end())
102  || (std::find(crossing->getSuccessors().begin(), crossing->getSuccessors().end(), walkingEdge) != crossing->getSuccessors().end()
103  && std::find(crossing->getPredecessors().begin(), crossing->getPredecessors().end(), nextEdge) != crossing->getPredecessors().end())) {
104 #ifdef SWARM_DEBUG
105  std::ostringstream oss;
106  oss << "MSPedestrianPushButton::isActiveForEdge Pushbutton active for edge " << walkingEdge->getID() << " crossing " << crossing->getID()
107  << " for " << vehicle->getID() << " wait " << vehicle->getWaitingSeconds();
108  WRITE_MESSAGE(oss.str());
109 #endif
110  // Also release the vehicles here
111  lane->releaseVehicles();
112  return true;
113  }
114  }
115  }
116  }
117  lane->releaseVehicles();
118  }
119  }
120 #ifdef SWARM_DEBUG
121  std::ostringstream oss;
122  oss << "MSPedestrianPushButton::isActiveForEdge Pushbutton not active for edge " << walkingEdge->getID() << " crossing " << crossing->getID()
123  << " num Persons " << persons.size();
124  WRITE_MESSAGE(oss.str());
125 #endif
126  return false;
127 }
128 
129 
131 void getWalking(const std::vector<MSEdge*>& edges, std::vector< MSEdge*>& walkingEdges) {
132  for (std::vector<MSEdge*>::const_iterator it = edges.begin(); it != edges.end(); ++it) {
133  MSEdge* edge = *it;
134  if (edge->isWalkingArea() || ((edge->getPermissions() & SVC_PEDESTRIAN) != 0)) {
135  walkingEdges.push_back(edge);
136  }
137  }
138 }
139 
141 const std::vector<MSEdge*> getWalkingAreas(const MSEdge* crossing) {
142  std::vector<MSEdge*> walkingEdges;
143  getWalking(crossing->getSuccessors(), walkingEdges);
144  getWalking(crossing->getPredecessors(), walkingEdges);
145  return walkingEdges;
146 
147 }
148 
150  const std::vector<MSEdge*> walkingList = getWalkingAreas(crossing);
151  for (std::vector<MSEdge*>::const_iterator wIt = walkingList.begin(); wIt != walkingList.end(); ++wIt) {
152  MSEdge* walking = *wIt;
153  if (isActiveForEdge(walking, crossing)) {
154 #ifdef SWARM_DEBUG
155  WRITE_MESSAGE("MSPedestrianPushButton::isActiveOnAnySideOfTheRoad crossing edge " + crossing->getID() + " walking edge" + walking->getID());
156 #endif
157  return true;
158  }
159  }
160  return false;
161 }
162 
163 std::vector<MSPushButton*> MSPedestrianPushButton::loadPushButtons(const MSPhaseDefinition* phase) {
165  std::vector<MSPushButton*> pushButtons;
166  const std::vector<std::string> lanes = phase->getTargetLaneSet();
167 // Multiple lane can be of the same edge, so I avoid readding them
168  std::set<std::string> controlledEdges;
169  for (std::vector<std::string>::const_iterator lIt = lanes.begin(); lIt != lanes.end(); ++lIt) {
170  MSLane* lane = MSLane::dictionary(*lIt);
171  if (lane) {
172  MSEdge* laneEdge = &lane->getEdge();
173  if (controlledEdges.count(laneEdge->getID()) != 0) {
174  continue;
175  }
176  controlledEdges.insert(laneEdge->getID());
177  if (m_crossingEdgeMap.find(laneEdge->getID()) != m_crossingEdgeMap.end()) {
178  //For every crossing edge that crosses this edge
179  for (std::vector<std::string>::const_iterator cIt = m_crossingEdgeMap[laneEdge->getID()].begin();
180  cIt != m_crossingEdgeMap[laneEdge->getID()].end(); ++cIt) {
181  MSEdge* crossing = MSEdge::dictionary(*cIt);
182  const std::vector<MSEdge*> walkingList = getWalkingAreas(crossing);
183  for (std::vector<MSEdge*>::const_iterator wIt = walkingList.begin(); wIt != walkingList.end(); ++wIt) {
184  MSEdge* walking = *wIt;
185 #ifdef SWARM_DEBUG
186  WRITE_MESSAGE("MSPedestrianPushButton::loadPushButtons Added pushButton for walking edge " + walking->getID() + " crossing edge "
187  + crossing->getID() + " crossed edge " + laneEdge->getID() + ". Phase state " + phase->getState());
188 #endif
189  pushButtons.push_back(new MSPedestrianPushButton(walking, crossing));
190  }
191  }
192  }
193  }
194  }
195  return pushButtons;
196 }
197 
201  for (MSEdgeVector::const_iterator eIt = MSEdge::getAllEdges().begin(); eIt != MSEdge::getAllEdges().end(); ++eIt) {
202  const MSEdge* edge = *eIt;
203  if (edge->isCrossing()) {
204  for (std::vector<std::string>::const_iterator cIt = edge->getCrossingEdges().begin();
205  cIt != edge->getCrossingEdges().end(); ++cIt) {
206  m_crossingEdgeMap[*cIt].push_back(edge->getID());
207  }
208  }
209  }
210  }
211 }
const std::vector< MSEdge * > getWalkingAreas(const MSEdge *crossing)
Get the walking areas adjacent to the crossing.
void getWalking(const std::vector< MSEdge * > &edges, std::vector< MSEdge * > &walkingEdges)
Checks if any of the edges is a walking area.
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:297
@ SVC_PEDESTRIAN
pedestrian
const MSEdge * succEdge(int nSuccs) const
Returns the nSuccs'th successor of edge the vehicle is currently at.
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
SUMOVehicleClass getVClass() const
Returns the vehicle's access class.
A road/street connecting two junctions.
Definition: MSEdge.h:77
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:1022
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition: MSEdge.h:270
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
Definition: MSEdge.h:626
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:406
bool isWalkingArea() const
return whether this edge is walking area
Definition: MSEdge.h:284
const std::set< MSTransportable *, ComparatorNumericalIdLess > & getPersons() const
Returns this edge's persons set.
Definition: MSEdge.h:201
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
Definition: MSEdge.cpp:983
const std::vector< std::string > & getCrossingEdges() const
Gets the crossed edge ids.
Definition: MSEdge.h:356
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:1194
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:475
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:119
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:2385
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:756
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:505
static bool isActiveOnAnySideOfTheRoad(const MSEdge *crossing)
Static method to check if the push button is active on both side of the road.
static bool isActiveForEdge(const MSEdge *walkingEdge, const MSEdge *crossing)
Static method with the same behavior of isActivated.
static std::vector< MSPushButton * > loadPushButtons(const MSPhaseDefinition *)
Loads all the pushbuttons for all the controlled lanes of a stage.
bool isActivated() const
abstract methods inherited from PedestrianState
static bool m_crossingEdgeMapLoaded
Definition: MSPushButton.h:102
static void loadCrossingEdgeMap()
MSPedestrianPushButton(const MSEdge *walkingEdge, const MSEdge *crossingEdge)
static std::map< std::string, std::vector< std::string > > m_crossingEdgeMap
Definition: MSPushButton.h:101
const MSEdge * getNextEdgePtr() const
returns the next edge ptr if this person is walking and the pedestrian model allows it
Definition: MSPerson.cpp:234
The definition of a single phase of a tls logic.
const std::string & getState() const
Returns the state within this phase.
const std::vector< std::string > & getTargetLaneSet() const
MSPushButton(const MSEdge *edge, const MSEdge *crossingEdge)
const MSEdge * m_edge
Definition: MSPushButton.h:56
virtual ~MSPushButton()
const MSEdge * m_crossingEdge
Definition: MSPushButton.h:57
static bool anyActive(const std::vector< MSPushButton * > &)
Checks if any pushbutton in the vector is active.
virtual double getWaitingSeconds() const
the time this transportable spent waiting in seconds
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
const std::string & getID() const
Returns the id.
Definition: Named.h:74