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