Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSStoppingPlace.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2005-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/****************************************************************************/
20// A lane area vehicles can halt at
21/****************************************************************************/
22#include <config.h>
23
24#include <cassert>
25#include <map>
27#include <utils/geom/Position.h>
30#include <microsim/MSGlobals.h>
32#include <microsim/MSNet.h>
33#include <microsim/MSLane.h>
34#include <microsim/MSStop.h>
35#include "MSStoppingPlace.h"
36
37// ===========================================================================
38// method definitions
39// ===========================================================================
41 SumoXMLTag element,
42 const std::vector<std::string>& lines,
43 MSLane& lane,
44 double begPos, double endPos, const std::string name,
45 int capacity,
46 double parkingLength,
47 const RGBColor& color) :
48 Named(id),
49 myElement(element),
50 myLines(lines), myLane(lane),
51 myBegPos(begPos), myEndPos(endPos),
52 myLastFreePos(endPos),
53 myLastParking(nullptr),
54 myName(name),
55 myTransportableCapacity(capacity),
56 myParkingFactor(parkingLength <= 0 ? 1 : (endPos - begPos) / parkingLength),
57 myColor(color),
58 // see MSVehicleControl defContainerType
61 for (int i = 0; i < capacity; i++) {
62 myWaitingSpots.insert(i);
63 }
64}
65
66
68
69
70const MSLane&
72 return myLane;
73}
74
75
76double
80
81
82double
86
92
93
94void
96 double beg = veh->getPositionOnLane() + veh->getVehicleType().getMinGap() * (parking ? myParkingFactor : 1);
97 double end = beg - veh->getVehicleType().getLengthWithGap() * (parking ? myParkingFactor : 1);
98 myEndPositions[veh] = std::make_pair(beg, end);
100}
101
102
103double
104MSStoppingPlace::getLastFreePos(const SUMOVehicle& forVehicle, double /*brakePos*/) const {
105 if (getStoppedVehicleNumber() > 0) {
106 const double vehGap = forVehicle.getVehicleType().getMinGap();
107 double pos = myLastFreePos - vehGap;
108 if (myParkingFactor < 1 && myLastParking != nullptr && forVehicle.hasStops() && (forVehicle.getStops().front().pars.parking == ParkingType::ONROAD)
109 && myLastParking->remainingStopDuration() < forVehicle.getStops().front().getMinDuration(SIMSTEP)) {
110 // stop far back enough so that the previous parking vehicle can leave (even if this vehicle fits, it will
111 // be a blocker because it stops on the road)
112 pos = MIN2(pos, myLastParking->getPositionOnLane() - myLastParking->getLength() - vehGap - NUMERICAL_EPS);
113 }
114 if (forVehicle.getLane() == &myLane && forVehicle.getPositionOnLane() < myEndPos && forVehicle.getPositionOnLane() > myBegPos && forVehicle.getSpeed() <= SUMO_const_haltingSpeed) {
115 return forVehicle.getPositionOnLane();
116 }
117 if (!fits(pos, forVehicle)) {
118 // try to find a place ahead of the waiting vehicles
119 const double vehLength = forVehicle.getVehicleType().getLength() * myParkingFactor;
120 std::vector<std::pair<double, std::pair<double, const SUMOVehicle*> > > spaces;
121 for (auto it : myEndPositions) {
122 spaces.push_back(std::make_pair(it.second.first, std::make_pair(it.second.second, it.first)));
123 }
124 // sorted from myEndPos towars myBegPos
125 std::sort(spaces.begin(), spaces.end());
126 std::reverse(spaces.begin(), spaces.end());
127 double prev = myEndPos;
128 for (auto it : spaces) {
129 //if (forVehicle.isSelected()) {
130 // std::cout << SIMTIME << " fitPosFor " << forVehicle.getID() << " l=" << vehLength << " prev=" << prev << " vehBeg=" << it.first << " vehEnd=" << it.second.first << " found=" << (prev - it.first >= vehLength) << "\n";
131 //}
132 if (prev - it.first + NUMERICAL_EPS >= vehLength && (
133 it.second.second->isParking()
134 || it.second.second->remainingStopDuration() > TIME2STEPS(10))) {
135 return prev;
136 }
137 prev = it.second.first - vehGap;
138 }
139 if (myParkingFactor < 1 && myLastParking != nullptr) {
140 // stop far back enough so that the previous vehicle can leave
141 pos = MIN2(pos, myLastParking->getPositionOnLane() - myLastParking->getLength() - vehGap - NUMERICAL_EPS);
142 }
143 }
144 return pos;
145 }
146 return myLastFreePos;
147}
148
149bool
150MSStoppingPlace::fits(double pos, const SUMOVehicle& veh) const {
151 // always fit at the default position or if at least half the vehicle length
152 // is within the stop range (debatable)
153 return pos + POSITION_EPS >= myEndPos || (pos - myBegPos >= veh.getVehicleType().getLength() * myParkingFactor / 2);
154}
155
156double
158 auto it = myWaitingTransportables.find(t);
159 const double waitingWidth = myElement == SUMO_TAG_CONTAINER_STOP
162 if (it != myWaitingTransportables.end() && it->second >= 0) {
163 return myEndPos - (0.5 + (it->second) % getTransportablesAbreast()) * waitingWidth;
164 } else {
165 return (myEndPos + myBegPos) / 2;
166 }
167}
168
169
170int
172 return MAX2(1, (int)floor(length / (element == SUMO_TAG_CONTAINER_STOP
175}
176
177int
181
184 double lanePos = getWaitingPositionOnLane(t);
185 int row = 0;
186 auto it = myWaitingTransportables.find(t);
187 if (it != myWaitingTransportables.end()) {
188 if (it->second >= 0) {
189 row = int(it->second / getTransportablesAbreast());
190 } else {
191 // invalid position, draw outside bounds
193 }
194 }
195 const double lefthandSign = (MSGlobals::gLefthand ? -1 : 1);
197 lefthandSign * (myLane.getWidth() / 2 + row * myTransportableDepth));
198}
199
200
201double
203 auto i = myEndPositions.find(veh);
204 if (i != myEndPositions.end()) {
205 return i->second.second;
206 } else {
207 return getLastFreePos(*veh);
208 }
209}
210
211std::vector<const MSTransportable*>
213 std::vector<const MSTransportable*> result;
214 for (auto item : myWaitingTransportables) {
215 result.push_back(item.first);
216 }
217 return result;
218}
219
220bool
222 return myWaitingSpots.size() > 0;
223}
224
225bool
227 int spot = -1;
229 return false;
230 }
231 spot = *myWaitingSpots.begin();
232 myWaitingSpots.erase(myWaitingSpots.begin());
233 myWaitingTransportables[p] = spot;
234 return true;
235}
236
237
238void
240 auto i = myWaitingTransportables.find(p);
241 if (i != myWaitingTransportables.end()) {
242 if (i->second >= 0) {
243 myWaitingSpots.insert(i->second);
244 }
246 }
247}
248
249
250void
252 assert(myEndPositions.find(what) != myEndPositions.end());
253 myEndPositions.erase(myEndPositions.find(what));
255}
256
257
258void
261 myLastParking = nullptr;
262 for (auto item : myEndPositions) {
263 // vehicle might be stopped beyond myEndPos
264 if (myLastFreePos >= item.second.second || myLastFreePos == myEndPos) {
265 myLastFreePos = item.second.second;
266 if (item.first->isStoppedParking()) {
267 myLastParking = item.first;
268 }
269 }
270 }
271}
272
273
274double
276 if (edge == &myLane.getEdge()) {
277 return (myBegPos + myEndPos) / 2.;
278 }
279 for (const auto& access : myAccessPos) {
280 if (edge == &access.lane->getEdge()) {
281 if (rng == nullptr || access.startPos == access.endPos) {
282 return access.endPos;
283 }
284 return RandHelper::rand(access.startPos, access.endPos, rng);
285 }
286 }
287 return -1.;
288}
289
290
293 for (const auto& access : myAccessPos) {
294 if (edge == &access.lane->getEdge()) {
295 return &access;
296 }
297 }
298 return nullptr;
299}
300
301
302const std::string&
304 return myName;
305}
306
307
308const RGBColor&
310 return myColor;
311}
312
313
314bool
315MSStoppingPlace::addAccess(MSLane* const lane, const double startPos, const double endPos, double length, const MSStoppingPlace::AccessExit exit) {
316 // prevent multiple accesses on the same lane
317 for (const auto& access : myAccessPos) {
318 if (lane == access.lane) {
319 return false;
320 }
321 }
322 if (length < 0.) {
323 const Position accPos = lane->geometryPositionAtOffset((startPos + endPos) / 2.);
324 const Position stopPos = myLane.geometryPositionAtOffset((myBegPos + myEndPos) / 2.);
325 length = accPos.distanceTo(stopPos);
326 }
327 myAccessPos.push_back({lane, startPos, endPos, length, exit});
328 return true;
329}
330
331
332std::vector<const SUMOVehicle*>
334 std::vector<const SUMOVehicle*> result;
335 for (auto item : myEndPositions) {
336 result.push_back(item.first);
337 }
338 return result;
339}
340
341
342void
343MSStoppingPlace::getWaitingPersonIDs(std::vector<std::string>& into) const {
344 for (auto item : myWaitingTransportables) {
345 into.push_back(item.first->getID());
346 }
347 std::sort(into.begin(), into.end());
348}
349
350
351void
357
358
359/****************************************************************************/
#define SIMSTEP
Definition SUMOTime.h:61
#define TIME2STEPS(x)
Definition SUMOTime.h:57
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_CONTAINER_STOP
A container stop.
const double SUMO_const_waitingPersonDepth
Definition StdDefs.h:53
T MIN2(T a, T b)
Definition StdDefs.h:76
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition StdDefs.h:58
T MAX2(T a, T b)
Definition StdDefs.h:82
const double SUMO_const_waitingContainerWidth
Definition StdDefs.h:54
const double SUMO_const_waitingPersonWidth
Definition StdDefs.h:52
const double SUMO_const_waitingContainerDepth
Definition StdDefs.h:55
A road/street connecting two junctions.
Definition MSEdge.h:77
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition MSGlobals.h:174
Representation of a lane in the micro simulation.
Definition MSLane.h:84
double interpolateLanePosToGeometryPos(double lanePos) const
Definition MSLane.h:554
virtual const PositionVector & getShape(bool) const
Definition MSLane.h:294
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:764
double getWidth() const
Returns the lane's width.
Definition MSLane.h:635
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition MSLane.h:560
std::vector< const SUMOVehicle * > getStoppedVehicles() const
get list of vehicles waiting at this stop
int getStoppedVehicleNumber() const
Returns the number of stopped vehicles waiting on this stop.
const SUMOVehicle * myLastParking
The length of the last parking vehicle (or 0 if there is none)
const SumoXMLTag myElement
the type of stopping place
double getWaitingPositionOnLane(MSTransportable *t) const
Returns the lane position corresponding to getWaitPosition()
const Access * getAccess(const MSEdge *edge) const
the access on the given edge to the stop, nullptr if there is none
std::map< const MSTransportable *, int > myWaitingTransportables
Persons waiting at this stop (mapped to waiting position)
const double myBegPos
The begin position this bus stop is located at.
double getBeginLanePosition() const
Returns the begin position of this stop.
const MSLane & myLane
The lane this bus stop is located at.
bool hasSpaceForTransportable() const
whether there is still capacity for more transportables
std::map< const SUMOVehicle *, std::pair< double, double >, ComparatorNumericalIdLess > myEndPositions
A map from objects (vehicles) to the areas they acquire after entering the stop.
int getTransportablesAbreast() const
std::vector< const MSTransportable * > getTransportables() const
Returns the transportables waiting on this stop.
void clearState()
Remove all vehicles before quick-loading state.
std::set< int > myWaitingSpots
const double myParkingFactor
the scaled space capacity for parking vehicles
Position getCenterPos() const
the position in the middle of the stop shape
bool fits(double pos, const SUMOVehicle &veh) const
return whether the given vehicle fits at the given position
const std::string myName
The name of the stopping place.
MSStoppingPlace(const std::string &id, SumoXMLTag element, const std::vector< std::string > &lines, MSLane &lane, double begPos, double endPos, const std::string name="", int capacity=0, double parkingLength=0, const RGBColor &color=RGBColor::INVISIBLE)
Constructor.
std::vector< Access > myAccessPos
lanes and positions connected to this stop
const double myEndPos
The end position this bus stop is located at.
double getEndLanePosition() const
Returns the end position of this stop.
const RGBColor myColor
The color of the stopping place.
void enter(SUMOVehicle *veh, bool parking)
Called if a vehicle enters this stop.
double getStoppingPosition(const SUMOVehicle *veh) const
For vehicles at the stop this gives the actual stopping position of the vehicle. For all others the l...
void removeTransportable(const MSTransportable *p)
Removes a transportable from this stop.
virtual ~MSStoppingPlace()
Destructor.
void computeLastFreePos()
Computes the last free position on this stop.
const RGBColor & getColor() const
void getWaitingPersonIDs(std::vector< std::string > &into) const
get IDs of persons waiting at this stop
const MSLane & getLane() const
Returns the lane this stop is located at.
const int myTransportableCapacity
The number of transportables that can wait here.
const std::string & getMyName() const
Position getWaitPosition(MSTransportable *person) const
Returns the next free waiting place for pedestrians / containers.
double getAccessPos(const MSEdge *edge, SumoRNG *rng=nullptr) const
the position on the given edge which is connected to this stop, -1 on failure
virtual bool addAccess(MSLane *const lane, const double startPos, const double endPos, double length, const MSStoppingPlace::AccessExit exit)
adds an access point to this stop
bool addTransportable(const MSTransportable *p)
adds a transportable to this stop
double myLastFreePos
The last free position at this stop (variable)
double getLastFreePos() const
const double myTransportableDepth
row depth of waiting transportables
void leaveFrom(SUMOVehicle *what)
Called if a vehicle leaves this stop.
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
double getMinGap() const
Get the free space in front of vehicles of this class.
double getLength() const
Get vehicle's length [m].
Base class for objects which have an id.
Definition Named.h:54
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimensions
Definition Position.h:266
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual double getSpeed() const =0
Returns the object's current speed.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
Definition SUMOVehicle.h:62
virtual bool hasStops() const =0
Returns whether the vehicle has to stop somewhere.
virtual SUMOTime remainingStopDuration() const =0
Returns the remaining stop duration for a stopped vehicle or 0.
virtual const std::list< MSStop > & getStops() const =0
virtual double getLength() const =0
Returns the vehicles's length.