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