Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2014-2026 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 MSPModel_Interacting.cpp
15 : /// @author Jakob Erdmann
16 : /// @author Michael Behrisch
17 : /// @date Mon, 13 Jan 2014
18 : ///
19 : // The pedestrian following model (prototype)
20 : /****************************************************************************/
21 : #include <config.h>
22 :
23 : #include <microsim/MSGlobals.h>
24 : #include <microsim/MSLane.h>
25 : #include <microsim/MSLink.h>
26 : #include <microsim/MSNet.h>
27 : #include "MSPModel_Interacting.h"
28 :
29 : //#define DEBUG_INTERACTING
30 : //#define DEBUG_CROSSING_APPROACH
31 :
32 : #define DEBUGCOND(PED) ((PED)->getPerson()->isSelected())
33 :
34 : // ===========================================================================
35 : // static members
36 : // ===========================================================================
37 : MSPModel_Interacting::Pedestrians MSPModel_Interacting::noPedestrians;
38 :
39 :
40 : // ===========================================================================
41 : // MSPModel_Interacting method definitions
42 : // ===========================================================================
43 6073 : MSPModel_Interacting::~MSPModel_Interacting() {
44 6073 : clearState();
45 6073 : }
46 :
47 :
48 : void
49 12171 : MSPModel_Interacting::clearState() {
50 : myActiveLanes.clear();
51 12171 : myNumActivePedestrians = 0;
52 12171 : myAmActive = false;
53 12171 : }
54 :
55 :
56 : void
57 1661 : MSPModel_Interacting::remove(MSTransportableStateAdapter* state) {
58 1661 : Pedestrians& pedestrians = myActiveLanes[state->getLane()];
59 1661 : MSPModel_InteractingState* const p = static_cast<MSPModel_InteractingState*>(state);
60 1661 : const auto& it = std::find(pedestrians.begin(), pedestrians.end(), p);
61 1661 : if (it != pedestrians.end()) {
62 1661 : if (p->getNextCrossing() != nullptr) {
63 25 : unregisterCrossingApproach(*p, p->getNextCrossing());
64 : }
65 : pedestrians.erase(it);
66 1661 : myNumActivePedestrians--;
67 : }
68 1661 : }
69 :
70 :
71 : bool
72 6064046 : MSPModel_Interacting::blockedAtDist(const SUMOTrafficObject* ego, const MSLane* lane, double vehCenter, double vehWidth,
73 : double oncomingGap, std::vector<const MSPerson*>* collectBlockers) {
74 6205498 : for (const MSPModel_InteractingState* ped : getPedestrians(lane)) {
75 660876 : const double leaderFrontDist = (ped->getDirection() == FORWARD ? vehCenter - ped->getEdgePos(0) : ped->getEdgePos(0) - vehCenter) - vehWidth * 0.5;
76 660876 : const double leaderBackDist = leaderFrontDist + ped->getPerson()->getVehicleType().getLength();
77 : #ifdef DEBUG_INTERACTING
78 : if DEBUGCOND(ped) {
79 : std::cout << SIMTIME << " lane=" << lane->getID() << " dir=" << ped->getDirection() << " pX=" << ped->getEdgePos(0) << " pL=" << ped->getPerson()->getVehicleType().getLength()
80 : << " vehCenter=" << vehCenter
81 : << " vehWidth=" << vehWidth
82 : << " lBD=" << leaderBackDist
83 : << " lFD=" << leaderFrontDist
84 : << "\n";
85 : }
86 : #endif
87 660876 : if (leaderBackDist >= -vehWidth
88 660876 : && (leaderFrontDist < 0
89 : // give right of way to (close) approaching pedestrians unless they are standing
90 206541 : || (leaderFrontDist <= oncomingGap && ped->getWaitingTime() < TIME2STEPS(2.0)))) {
91 519454 : if (MSLink::ignoreFoe(ego, ped->getPerson())) {
92 30 : continue;
93 : }
94 : // found one pedestrian that is not completely past the crossing point
95 : //std::cout << SIMTIME << " blocking pedestrian foeLane=" << lane->getID() << " ped=" << ped->getPerson()->getID() << " dir=" << ped->getDirection() << " pX=" << ped->getEdgePos(0) << " pL=" << ped.getLength() << " fDTC=" << distToCrossing << " lBD=" << leaderBackDist << "\n";
96 519424 : if (collectBlockers == nullptr) {
97 : return true;
98 : }
99 0 : collectBlockers->push_back(ped->getPerson());
100 : }
101 : }
102 5544622 : if (collectBlockers == nullptr) {
103 : return false;
104 : }
105 0 : return collectBlockers->size() > 0;
106 : }
107 :
108 :
109 : bool
110 4959302 : MSPModel_Interacting::hasPedestrians(const MSLane* lane) {
111 4959302 : return getPedestrians(lane).size() > 0;
112 : }
113 :
114 :
115 : bool
116 124328 : MSPModel_Interacting::usingInternalLanes() {
117 124328 : return usingInternalLanesStatic();
118 : }
119 :
120 :
121 : bool
122 133132 : MSPModel_Interacting::usingInternalLanesStatic() {
123 133132 : return MSGlobals::gUsingInternalLanes && MSNet::getInstance()->hasInternalLinks() && MSNet::getInstance()->hasPedestrianNetwork();
124 : }
125 :
126 :
127 : PersonDist
128 702129 : MSPModel_Interacting::nextBlocking(const MSLane* lane, double minPos, double minRight, double maxLeft, double stopTime, bool bidi) {
129 : PersonDist result((const MSPerson*)nullptr, std::numeric_limits<double>::max());
130 4267573 : for (const MSPModel_InteractingState* ped : getPedestrians(lane)) {
131 : // account for distance covered by oncoming pedestrians
132 3565444 : double relX2 = ped->getEdgePos(0) - (ped->getDirection() == FORWARD ? 0 : stopTime * ped->getPerson()->getMaxSpeed());
133 3565444 : double dist = ((relX2 - minPos) * (bidi ? -1 : 1)
134 3565444 : - (ped->getDirection() == FORWARD ? ped->getPerson()->getVehicleType().getLength() : 0));
135 3565444 : const bool aheadOfVehicle = bidi ? ped->getEdgePos(0) < minPos : ped->getEdgePos(0) > minPos;
136 3565444 : if (aheadOfVehicle && dist < result.second) {
137 1592059 : const double center = ped->getLatOffset() + 0.5 * lane->getWidth();
138 1592059 : const double halfWidth = 0.5 * ped->getPerson()->getVehicleType().getWidth();
139 1592059 : const bool overlap = (center + halfWidth > minRight && center - halfWidth < maxLeft);
140 : #ifdef DEBUG_INTERACTING
141 : if DEBUGCOND(ped) {
142 : std::cout << " nextBlocking lane=" << lane->getID() << " bidi=" << bidi
143 : << " minPos=" << minPos << " minRight=" << minRight << " maxLeft=" << maxLeft
144 : << " stopTime=" << stopTime
145 : << " ped=" << ped->getID()
146 : << " pedX=" << ped->getEdgePos(0)
147 : << " relX2=" << relX2
148 : << " center=" << center
149 : << " pedLeft=" << center + halfWidth
150 : << " pedRight=" << center - halfWidth
151 : << " overlap=" << overlap
152 : << "\n";
153 : }
154 : #endif
155 : if (overlap) {
156 : result.first = ped->getPerson();
157 : result.second = dist;
158 : }
159 : }
160 : }
161 702129 : return result;
162 : }
163 :
164 :
165 : MSPModel_Interacting::Pedestrians&
166 14077740 : MSPModel_Interacting::getPedestrians(const MSLane* lane) {
167 : ActiveLanes::iterator it = myActiveLanes.find(lane);
168 14077740 : if (it != myActiveLanes.end()) {
169 : //std::cout << " found lane=" << lane->getID() << " n=" << it->second.size() << "\n";
170 5424915 : return (it->second);
171 : }
172 : return noPedestrians;
173 : }
174 :
175 :
176 : void
177 31307 : MSPModel_Interacting::unregisterCrossingApproach(const MSPModel_InteractingState& ped, const MSLane* crossing) {
178 : // person has entered the crossing
179 31307 : crossing->getIncomingLanes()[0].viaLink->removeApproachingPerson(ped.getPerson());
180 : #ifdef DEBUG_CROSSING_APPROACH
181 : if DEBUGCOND(&ped) {
182 : std::cout << SIMTIME << " unregister " << ped.getPerson()->getID() << " at crossing " << crossing->getID() << "\n";
183 : }
184 : #endif
185 31307 : }
186 :
187 :
188 : /****************************************************************************/
|