LCOV - code coverage report
Current view: top level - src/microsim/traffic_lights - MSPushButton.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 0.0 % 84 0
Test Date: 2024-11-22 15:46:21 Functions: 0.0 % 12 0

            Line data    Source code
       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              : /****************************************************************************/
      14              : /// @file    MSPushButton.cpp
      15              : /// @author  Federico Caselli
      16              : /// @date    2015-07-15
      17              : ///
      18              : // The class for a PushButton
      19              : /****************************************************************************/
      20              : 
      21              : #include <microsim/MSEdge.h>
      22              : #include <microsim/MSLane.h>
      23              : #include <microsim/MSVehicle.h>
      24              : #include <microsim/transportables/MSPerson.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;
      34              : bool MSPedestrianPushButton::m_crossingEdgeMapLoaded = false;
      35              : 
      36              : // ===========================================================================
      37              : // method definitions
      38              : // ===========================================================================
      39            0 : MSPushButton::MSPushButton(const MSEdge* edge, const MSEdge* crossingEdge) {
      40            0 :     m_edge = edge;
      41            0 :     m_crossingEdge = crossingEdge;
      42            0 : }
      43              : 
      44            0 : MSPushButton::~MSPushButton() {
      45              :     /// do not delete the MSEdge here
      46            0 : }
      47              : 
      48            0 : bool MSPushButton::anyActive(const std::vector<MSPushButton*>& pushButtons) {
      49            0 :     for (std::vector<MSPushButton*>::const_iterator it = pushButtons.begin(); it != pushButtons.end(); ++it) {
      50            0 :         if (it.operator * ()->isActivated()) {
      51              :             return true;
      52              :         }
      53              :     }
      54              :     return false;
      55              : }
      56              : 
      57              : 
      58            0 : MSPedestrianPushButton::MSPedestrianPushButton(const MSEdge* walkingEdge, const MSEdge* crossingEdge)
      59            0 :     : MSPushButton(walkingEdge, crossingEdge) {
      60              :     assert(walkingEdge->isWalkingArea() || ((walkingEdge->getPermissions() & SVC_PEDESTRIAN) != 0));
      61              :     assert(crossingEdge->isCrossing());
      62            0 : }
      63              : 
      64            0 : bool MSPedestrianPushButton::isActivated() const {
      65            0 :     return isActiveForEdge(m_edge, m_crossingEdge);
      66              : }
      67              : 
      68            0 : bool MSPedestrianPushButton::isActiveForEdge(const MSEdge* walkingEdge, const MSEdge* crossing) {
      69            0 :     const std::set<MSTransportable*, ComparatorNumericalIdLess> persons = walkingEdge->getPersons();
      70            0 :     if (persons.size() > 0) {
      71            0 :         for (std::set<MSTransportable*>::const_iterator pIt = persons.begin(); pIt != persons.end(); ++pIt) {
      72            0 :             const MSPerson* person = (MSPerson*)*pIt;
      73            0 :             const MSEdge* nextEdge = person->getNextEdgePtr();
      74              :             ///TODO keep using >= 1 or switch to ==1. Should change return value from always active to active only when pressed?
      75              :             ///TODO If changed the swarm logic must be changed since it relies on this behavior that keeps it active
      76            0 :             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            0 :         for (std::vector<MSLane*>::const_iterator laneIt = walkingEdge->getLanes().begin();
      89            0 :                 laneIt != walkingEdge->getLanes().end(); ++laneIt) {
      90            0 :             MSLane* lane = *laneIt;
      91            0 :             MSLane::VehCont vehicles = lane->getVehiclesSecure();
      92            0 :             for (MSLane::VehCont::const_iterator vehicleIt = vehicles.begin(); vehicleIt != vehicles.end(); ++vehicleIt) {
      93            0 :                 MSVehicle* vehicle = *vehicleIt;
      94            0 :                 if (vehicle->getVClass() == SVC_PEDESTRIAN) {
      95              :                     // It's a pedestrian
      96            0 :                     const MSEdge* nextEdge = vehicle->succEdge(1);
      97            0 :                     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            0 :                         if ((std::find(crossing->getPredecessors().begin(), crossing->getPredecessors().end(), walkingEdge) != crossing->getPredecessors().end()
     101            0 :                                 && std::find(crossing->getSuccessors().begin(), crossing->getSuccessors().end(), nextEdge) != crossing->getSuccessors().end())
     102            0 :                                 || (std::find(crossing->getSuccessors().begin(), crossing->getSuccessors().end(), walkingEdge) != crossing->getSuccessors().end()
     103            0 :                                     && 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            0 :                             lane->releaseVehicles();
     112            0 :                             return true;
     113              :                         }
     114              :                     }
     115              :                 }
     116              :             }
     117            0 :             lane->releaseVehicles();
     118            0 :         }
     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              : 
     130              : ///@brief Checks if any of the edges is a walking area
     131            0 : void getWalking(const std::vector<MSEdge*>& edges, std::vector< MSEdge*>& walkingEdges) {
     132            0 :     for (std::vector<MSEdge*>::const_iterator it = edges.begin(); it != edges.end(); ++it) {
     133            0 :         MSEdge* edge = *it;
     134            0 :         if (edge->isWalkingArea() || ((edge->getPermissions() & SVC_PEDESTRIAN) != 0)) {
     135            0 :             walkingEdges.push_back(edge);
     136              :         }
     137              :     }
     138            0 : }
     139              : 
     140              : ///@brief Get the walking areas adjacent to the crossing
     141            0 : const std::vector<MSEdge*> getWalkingAreas(const MSEdge* crossing) {
     142              :     std::vector<MSEdge*> walkingEdges;
     143            0 :     getWalking(crossing->getSuccessors(), walkingEdges);
     144            0 :     getWalking(crossing->getPredecessors(), walkingEdges);
     145            0 :     return walkingEdges;
     146              : 
     147            0 : }
     148              : 
     149            0 : bool MSPedestrianPushButton::isActiveOnAnySideOfTheRoad(const MSEdge* crossing) {
     150            0 :     const std::vector<MSEdge*> walkingList = getWalkingAreas(crossing);
     151            0 :     for (std::vector<MSEdge*>::const_iterator wIt = walkingList.begin(); wIt != walkingList.end(); ++wIt) {
     152            0 :         MSEdge* walking = *wIt;
     153            0 :         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            0 : }
     162              : 
     163            0 : std::vector<MSPushButton*> MSPedestrianPushButton::loadPushButtons(const MSPhaseDefinition* phase) {
     164            0 :     loadCrossingEdgeMap();
     165              :     std::vector<MSPushButton*> pushButtons;
     166            0 :     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            0 :     for (std::vector<std::string>::const_iterator lIt = lanes.begin(); lIt != lanes.end(); ++lIt) {
     170            0 :         MSLane* lane = MSLane::dictionary(*lIt);
     171            0 :         if (lane) {
     172              :             MSEdge* laneEdge = &lane->getEdge();
     173            0 :             if (controlledEdges.count(laneEdge->getID()) != 0) {
     174            0 :                 continue;
     175              :             }
     176              :             controlledEdges.insert(laneEdge->getID());
     177            0 :             if (m_crossingEdgeMap.find(laneEdge->getID()) != m_crossingEdgeMap.end()) {
     178              :                 //For every crossing edge that crosses this edge
     179            0 :                 for (std::vector<std::string>::const_iterator cIt = m_crossingEdgeMap[laneEdge->getID()].begin();
     180            0 :                         cIt != m_crossingEdgeMap[laneEdge->getID()].end(); ++cIt) {
     181            0 :                     MSEdge* crossing = MSEdge::dictionary(*cIt);
     182            0 :                     const std::vector<MSEdge*> walkingList = getWalkingAreas(crossing);
     183            0 :                     for (std::vector<MSEdge*>::const_iterator wIt = walkingList.begin(); wIt != walkingList.end(); ++wIt) {
     184            0 :                         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            0 :                         pushButtons.push_back(new MSPedestrianPushButton(walking, crossing));
     190              :                     }
     191            0 :                 }
     192              :             }
     193              :         }
     194              :     }
     195            0 :     return pushButtons;
     196            0 : }
     197              : 
     198            0 : void MSPedestrianPushButton::loadCrossingEdgeMap() {
     199            0 :     if (!m_crossingEdgeMapLoaded) {
     200            0 :         m_crossingEdgeMapLoaded = true;
     201            0 :         for (MSEdgeVector::const_iterator eIt = MSEdge::getAllEdges().begin(); eIt != MSEdge::getAllEdges().end(); ++eIt) {
     202            0 :             const MSEdge* edge = *eIt;
     203            0 :             if (edge->isCrossing()) {
     204            0 :                 for (std::vector<std::string>::const_iterator cIt = edge->getCrossingEdges().begin();
     205            0 :                         cIt != edge->getCrossingEdges().end(); ++cIt) {
     206            0 :                     m_crossingEdgeMap[*cIt].push_back(edge->getID());
     207              :                 }
     208              :             }
     209              :         }
     210              :     }
     211            0 : }
        

Generated by: LCOV version 2.0-1