SUMO - Simulation of Urban MObility
MSPushButton.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // The class for a PushButton
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2010-2017 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 #define SWARM_DEBUG
23 #include "MSPushButton.h"
24 #include "MSPhaseDefinition.h"
25 #include "../MSEdge.h"
26 #include "../MSLane.h"
27 #include "../MSVehicle.h"
29 
30 MSPushButton::MSPushButton(const MSEdge* edge, const MSEdge* crossingEdge) {
31  m_edge = edge;
32  m_crossingEdge = crossingEdge;
33 }
34 
37 }
38 
39 bool MSPushButton::anyActive(const std::vector<MSPushButton*>& pushButtons) {
40  for (std::vector<MSPushButton*>::const_iterator it = pushButtons.begin(); it != pushButtons.end(); ++it) {
41  if (it.operator * ()->isActivated()) {
42  return true;
43  }
44  }
45  return false;
46 }
47 
48 std::map<std::string, std::vector<std::string> > MSPedestrianPushButton::m_crossingEdgeMap;
50 
51 MSPedestrianPushButton::MSPedestrianPushButton(const MSEdge* walkingEdge, const MSEdge* crossingEdge)
52  : MSPushButton(walkingEdge, crossingEdge) {
53  assert(walkingEdge->isWalkingArea() || ((walkingEdge->getPermissions() & SVC_PEDESTRIAN) != 0));
54  assert(crossingEdge->isCrossing());
55 }
56 
59 }
60 
61 bool MSPedestrianPushButton::isActiveForEdge(const MSEdge* walkingEdge, const MSEdge* crossing) {
62  const std::set<MSTransportable*> persons = walkingEdge->getPersons();
63  if (persons.size() > 0) {
64  for (std::set<MSTransportable*>::const_iterator pIt = persons.begin(); pIt != persons.end(); ++pIt) {
65  const MSPerson* person = (MSPerson*)*pIt;
66  const MSEdge* nextEdge = person->getNextEdgePtr();
69  if (person->getWaitingSeconds() >= 1 && nextEdge && nextEdge->getID() == crossing->getID()) {
70  DBG(
71  std::ostringstream oss;
72  oss << "MSPedestrianPushButton::isActiveForEdge Pushbutton active for edge " << walkingEdge->getID() << " crossing " << crossing->getID()
73  << " for " << person->getID() << " wait " << person->getWaitingSeconds();
74  WRITE_MESSAGE(oss.str());
75  );
76  return true;
77  }
78  }
79  } else {
80  //No person currently on the edge. But there may be some vehicles of class pedestrian
81  for (std::vector<MSLane*>::const_iterator laneIt = walkingEdge->getLanes().begin();
82  laneIt != walkingEdge->getLanes().end(); ++laneIt) {
83  MSLane* lane = *laneIt;
84  MSLane::VehCont vehicles = lane->getVehiclesSecure();
85  for (MSLane::VehCont::const_iterator vehicleIt = vehicles.begin(); vehicleIt != vehicles.end(); ++vehicleIt) {
86  MSVehicle* vehicle = *vehicleIt;
87  if (vehicle->getVClass() == SVC_PEDESTRIAN) {
88  // It's a pedestrian
89  const MSEdge* nextEdge = vehicle->succEdge(1);
90  if (vehicle->getWaitingSeconds() >= 1 && nextEdge) {
91  // Next edge is not internal. Try to find if between the current vehicle edge and the next is the crossing.
92  // To do that check if between the successors (or predecessor) of crossing is the next edge and walking precedes (or ensue) it.
93  if ((std::find(crossing->getPredecessors().begin(), crossing->getPredecessors().end(), walkingEdge) != crossing->getPredecessors().end()
94  && std::find(crossing->getSuccessors().begin(), crossing->getSuccessors().end(), nextEdge) != crossing->getSuccessors().end())
95  || (std::find(crossing->getSuccessors().begin(), crossing->getSuccessors().end(), walkingEdge) != crossing->getSuccessors().end()
96  && std::find(crossing->getPredecessors().begin(), crossing->getPredecessors().end(), nextEdge) != crossing->getPredecessors().end())) {
97  DBG(
98  std::ostringstream oss;
99  oss << "MSPedestrianPushButton::isActiveForEdge Pushbutton active for edge " << walkingEdge->getID() << " crossing " << crossing->getID()
100  << " for " << vehicle->getID() << " wait " << vehicle->getWaitingSeconds(); WRITE_MESSAGE(oss.str()););
101  // Also release the vehicles here
102  lane->releaseVehicles();
103  return true;
104  }
105  }
106  }
107  }
108  lane->releaseVehicles();
109  }
110  }
111  DBG(
112  std::ostringstream oss;
113  oss << "MSPedestrianPushButton::isActiveForEdge Pushbutton not active for edge " << walkingEdge->getID() << " crossing " << crossing->getID()
114  << " num Persons " << persons.size();
115  WRITE_MESSAGE(oss.str());
116  );
117  return false;
118 }
119 
120 
122 void getWalking(const std::vector<MSEdge*>& edges, std::vector< MSEdge*>& walkingEdges) {
123  for (std::vector<MSEdge*>::const_iterator it = edges.begin(); it != edges.end(); ++it) {
124  MSEdge* edge = *it;
125  if (edge->isWalkingArea() || ((edge->getPermissions() & SVC_PEDESTRIAN) != 0)) {
126  walkingEdges.push_back(edge);
127  }
128  }
129 }
130 
132 const std::vector<MSEdge*> getWalkingAreas(const MSEdge* crossing) {
133  std::vector<MSEdge*> walkingEdges;
134  getWalking(crossing->getSuccessors(), walkingEdges);
135  getWalking(crossing->getPredecessors(), walkingEdges);
136  return walkingEdges;
137 
138 }
139 
141  const std::vector<MSEdge*> walkingList = getWalkingAreas(crossing);
142  for (std::vector<MSEdge*>::const_iterator wIt = walkingList.begin(); wIt != walkingList.end(); ++wIt) {
143  MSEdge* walking = *wIt;
144  if (isActiveForEdge(walking, crossing)) {
145  DBG(WRITE_MESSAGE("MSPedestrianPushButton::isActiveOnAnySideOfTheRoad crossing edge " + crossing->getID() + " walking edge" + walking->getID()););
146  return true;
147  }
148  }
149  return false;
150 }
151 
152 std::vector<MSPushButton*> MSPedestrianPushButton::loadPushButtons(const MSPhaseDefinition* phase) {
154  std::vector<MSPushButton*> pushButtons;
155  const std::vector<std::string> lanes = phase->getTargetLaneSet();
156 // Multiple lane can be of the same edge, so I avoid readding them
157  std::set<std::string> controlledEdges;
158  for (std::vector<std::string>::const_iterator lIt = lanes.begin(); lIt != lanes.end(); ++lIt) {
159  MSLane* lane = MSLane::dictionary(*lIt);
160  if (lane) {
161  MSEdge* laneEdge = &lane->getEdge();
162  if (controlledEdges.count(laneEdge->getID()) != 0) {
163  continue;
164  }
165  controlledEdges.insert(laneEdge->getID());
166  if (m_crossingEdgeMap.find(laneEdge->getID()) != m_crossingEdgeMap.end()) {
167  //For every crossing edge that crosses this edge
168  for (std::vector<std::string>::const_iterator cIt = m_crossingEdgeMap[laneEdge->getID()].begin();
169  cIt != m_crossingEdgeMap[laneEdge->getID()].end(); ++cIt) {
170  MSEdge* crossing = MSEdge::dictionary(*cIt);
171  const std::vector<MSEdge*> walkingList = getWalkingAreas(crossing);
172  for (std::vector<MSEdge*>::const_iterator wIt = walkingList.begin(); wIt != walkingList.end(); ++wIt) {
173  MSEdge* walking = *wIt;
174  DBG(WRITE_MESSAGE("MSPedestrianPushButton::loadPushButtons Added pushButton for walking edge " + walking->getID() + " crossing edge "
175  + crossing->getID() + " crossed edge " + laneEdge->getID() + ". Phase state " + phase->getState()););
176  pushButtons.push_back(new MSPedestrianPushButton(walking, crossing));
177  }
178  }
179  }
180  }
181  }
182  return pushButtons;
183 }
184 
188  for (MSEdgeVector::const_iterator eIt = MSEdge::getAllEdges().begin(); eIt != MSEdge::getAllEdges().end(); ++eIt) {
189  const MSEdge* edge = *eIt;
190  if (edge->isCrossing()) {
191  for (std::vector<std::string>::const_iterator cIt = edge->getCrossingEdges().begin();
192  cIt != edge->getCrossingEdges().end(); ++cIt) {
193  m_crossingEdgeMap[*cIt].push_back(edge->getID());
194  }
195  }
196  }
197  }
198 }
199 
const std::string & getState() const
Returns the state within this phase.
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:582
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
is a pedestrian
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:570
static void loadCrossingEdgeMap()
static std::map< std::string, std::vector< std::string > > m_crossingEdgeMap
Definition: MSPushButton.h:101
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:363
const std::vector< MSEdge * > getWalkingAreas(const MSEdge *crossing)
Get the walking areas adjacent to the crossing.
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:192
const std::vector< std::string > & getCrossingEdges() const
Gets the crossed edge ids.
Definition: MSEdge.h:310
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:379
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn&#39;t already in the dictionary...
Definition: MSEdge.cpp:728
const std::string & getID() const
Returns the id.
Definition: Named.h:66
static bool m_crossingEdgeMapLoaded
Definition: MSPushButton.h:102
A road/street connecting two junctions.
Definition: MSEdge.h:80
const std::set< MSTransportable * > & getPersons() const
Returns this edge&#39;s persons set.
Definition: MSEdge.h:201
static bool isActiveOnAnySideOfTheRoad(const MSEdge *crossing)
Static method to check if the push button is active on both side of the road.
const MSEdge * m_edge
Definition: MSPushButton.h:56
const std::string & getID() const
returns the id of the transportable
const MSEdge * m_crossingEdge
Definition: MSPushButton.h:57
MSPedestrianPushButton(const MSEdge *walkingEdge, const MSEdge *crossingEdge)
#define DBG(X)
Definition: SwarmDebug.h:30
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition: MSEdge.h:259
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:91
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1371
SUMOVehicleClass getVClass() const
Returns the vehicle&#39;s access class.
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:761
static std::vector< MSPushButton * > loadPushButtons(const MSPhaseDefinition *)
Loads all the pushbuttons for all the controlled lanes of a stage.
const MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:339
static bool isActiveForEdge(const MSEdge *walkingEdge, const MSEdge *crossing)
Static method with the same behavior of isActivated.
const MSEdge * succEdge(int nSuccs) const
Returns the nSuccs&#39;th successor of edge the vehicle is currently at.
const MSEdge * getNextEdgePtr() const
returns the next edge ptr if this person is walking and the pedestrian model allows it ...
Definition: MSPerson.cpp:348
bool isWalkingArea() const
return whether this edge is walking area
Definition: MSEdge.h:264
virtual double getWaitingSeconds() const
the time this transportable spent waiting in seconds
void getWalking(const std::vector< MSEdge *> &edges, std::vector< MSEdge *> &walkingEdges)
Checks if any of the edges is a walking area.
const LaneIdVector & getTargetLaneSet() const
SVCPermissions getPermissions() const
Definition: MSEdge.h:557
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:201
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:406
bool isActivated() const
abstract methods inherited from PedestrianState
static bool anyActive(const std::vector< MSPushButton *> &)
Checks if any pushbutton in the vector is active.
const std::string & getID() const
Returns the name of the vehicle.
The definition of a single phase of a tls logic.
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
virtual ~MSPushButton()
MSPushButton(const MSEdge *edge, const MSEdge *crossingEdge)