Eclipse SUMO - Simulation of Urban MObility
MSStoppingPlace.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2005-2022 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
78 return myBegPos;
79}
80
81
82double
84 return myEndPos;
85}
86
90 myLane.getWidth() / 2);
91}
92
93
94void
96 double beg = veh->getPositionOnLane() + veh->getVehicleType().getMinGap();
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 vehicle can leave
111 pos = myLastParking->getPositionOnLane() - myLastParking->getLength() - vehGap - NUMERICAL_EPS;
112 }
113 if (forVehicle.getLane() == &myLane && forVehicle.getPositionOnLane() < myEndPos && forVehicle.getPositionOnLane() > myBegPos && forVehicle.getSpeed() <= SUMO_const_haltingSpeed) {
114 return forVehicle.getPositionOnLane();
115 }
116 if (!fits(pos, forVehicle)) {
117 // try to find a place ahead of the waiting vehicles
118 const double vehLength = forVehicle.getVehicleType().getLength();
119 std::vector<std::pair<double, std::pair<double, const SUMOVehicle*> > > spaces;
120 for (auto it : myEndPositions) {
121 spaces.push_back(std::make_pair(it.second.first, std::make_pair(it.second.second, it.first)));
122 }
123 // sorted from myEndPos towars myBegPos
124 std::sort(spaces.begin(), spaces.end());
125 std::reverse(spaces.begin(), spaces.end());
126 double prev = myEndPos;
127 for (auto it : spaces) {
128 //if (forVehicle.isSelected()) {
129 // std::cout << SIMTIME << " fitPosFor " << forVehicle.getID() << " l=" << vehLength << " prev=" << prev << " vehBeg=" << it.first << " vehEnd=" << it.second.first << " found=" << (prev - it.first >= vehLength) << "\n";
130 //}
131 if (prev - it.first + NUMERICAL_EPS >= vehLength && (
132 it.second.second->isParking()
133 || it.second.second->remainingStopDuration() > TIME2STEPS(10))) {
134 return prev;
135 }
136 prev = it.second.first - vehGap;
137 }
138 }
139 return pos;
140 }
141 return myLastFreePos;
142}
143
144bool
145MSStoppingPlace::fits(double pos, const SUMOVehicle& veh) const {
146 // always fit at the default position or if at least half the vehicle length
147 // is within the stop range (debatable)
148 return pos + POSITION_EPS >= myEndPos || (pos - myBegPos >= veh.getVehicleType().getLength() * myParkingFactor / 2);
149}
150
151double
153 auto it = myWaitingTransportables.find(t);
154 const double waitingWidth = myElement == SUMO_TAG_CONTAINER_STOP
157 if (it != myWaitingTransportables.end() && it->second >= 0) {
158 return myEndPos - (0.5 + (it->second) % getTransportablesAbreast()) * waitingWidth;
159 } else {
160 return (myEndPos + myBegPos) / 2;
161 }
162}
163
164
165int
167 return MAX2(1, (int)floor(length / (element == SUMO_TAG_CONTAINER_STOP
170}
171
172int
175}
176
179 double lanePos = getWaitingPositionOnLane(t);
180 int row = 0;
181 auto it = myWaitingTransportables.find(t);
182 if (it != myWaitingTransportables.end()) {
183 if (it->second >= 0) {
184 row = int(it->second / getTransportablesAbreast());
185 } else {
186 // invalid position, draw outside bounds
188 }
189 }
190 const double lefthandSign = (MSGlobals::gLefthand ? -1 : 1);
192 lefthandSign * (myLane.getWidth() / 2 + row * myTransportableDepth));
193}
194
195
196double
198 auto i = myEndPositions.find(veh);
199 if (i != myEndPositions.end()) {
200 return i->second.second;
201 } else {
202 return getLastFreePos(*veh);
203 }
204}
205
206std::vector<const MSTransportable*>
208 std::vector<const MSTransportable*> result;
209 for (auto item : myWaitingTransportables) {
210 result.push_back(item.first);
211 }
212 return result;
213}
214
215bool
217 return myWaitingSpots.size() > 0;
218}
219
220bool
222 int spot = -1;
224 return false;
225 }
226 spot = *myWaitingSpots.begin();
227 myWaitingSpots.erase(myWaitingSpots.begin());
228 myWaitingTransportables[p] = spot;
229 return true;
230}
231
232
233void
235 auto i = myWaitingTransportables.find(p);
236 if (i != myWaitingTransportables.end()) {
237 if (i->second >= 0) {
238 myWaitingSpots.insert(i->second);
239 }
241 }
242}
243
244
245void
247 assert(myEndPositions.find(what) != myEndPositions.end());
248 myEndPositions.erase(myEndPositions.find(what));
250}
251
252
253void
256 myLastParking = nullptr;
257 for (auto item : myEndPositions) {
258 // vehicle might be stopped beyond myEndPos
259 if (myLastFreePos >= item.second.second || myLastFreePos == myEndPos) {
260 myLastFreePos = item.second.second;
261 if (item.first->isStoppedParking()) {
262 myLastParking = item.first;
263 }
264 }
265 }
266}
267
268
269double
271 if (edge == &myLane.getEdge()) {
272 return (myBegPos + myEndPos) / 2.;
273 }
274 for (const auto& access : myAccessPos) {
275 if (edge == &std::get<0>(access)->getEdge()) {
276 return std::get<1>(access);
277 }
278 }
279 return -1.;
280}
281
282
283double
285 if (edge == &myLane.getEdge()) {
286 return 0.;
287 }
288 for (const auto& access : myAccessPos) {
289 const MSLane* const accLane = std::get<0>(access);
290 if (edge == &accLane->getEdge()) {
291 return std::get<2>(access);
292 }
293 }
294 return -1.;
295}
296
297
298const std::string&
300 return myName;
301}
302
303
304const RGBColor&
306 return myColor;
307}
308
309
310bool
311MSStoppingPlace::addAccess(MSLane* lane, const double pos, double length) {
312 // prevent multiple accesss on the same lane
313 for (const auto& access : myAccessPos) {
314 if (lane == std::get<0>(access)) {
315 return false;
316 }
317 }
318 if (length < 0.) {
319 const Position accPos = lane->geometryPositionAtOffset(pos);
320 const Position stopPos = myLane.geometryPositionAtOffset((myBegPos + myEndPos) / 2.);
321 length = accPos.distanceTo(stopPos);
322 }
323 myAccessPos.push_back(std::make_tuple(lane, pos, length));
324 return true;
325}
326
327std::vector<const SUMOVehicle*>
329 std::vector<const SUMOVehicle*> result;
330 for (auto item : myEndPositions) {
331 result.push_back(item.first);
332 }
333 return result;
334}
335
336
337void
338MSStoppingPlace::getWaitingPersonIDs(std::vector<std::string>& into) const {
339 for (auto item : myWaitingTransportables) {
340 into.push_back(item.first->getID());
341 }
342 std::sort(into.begin(), into.end());
343}
344
345
346void
348 myEndPositions.clear();
351}
352
353
354/****************************************************************************/
#define SIMSTEP
Definition: SUMOTime.h:60
#define TIME2STEPS(x)
Definition: SUMOTime.h:56
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_CONTAINER_STOP
A container stop.
const double SUMO_const_waitingPersonDepth
Definition: StdDefs.h:53
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:77
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:168
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:506
double interpolateLanePosToGeometryPos(double lanePos) const
Definition: MSLane.h:527
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:713
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:590
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:533
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()
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 tranportables 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.
double getAccessDistance(const MSEdge *edge) const
the distance from the access on the given edge to the stop, -1 on failure
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.
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.
std::vector< std::tuple< MSLane *, double, double > > myAccessPos
lanes and positions connected to this stop
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 the actual stopping position of the vehicle....
void removeTransportable(const MSTransportable *p)
Removes a transportable from this stop.
virtual ~MSStoppingPlace()
Destructor.
void computeLastFreePos()
Computes the last free position on this stop.
virtual bool addAccess(MSLane *lane, const double pos, double length)
adds an access point to 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.
bool addTransportable(const MSTransportable *p)
adds a transportable to this stop
double myLastFreePos
The last free position at this stop (variable)
double getLastFreePos() const
double getAccessPos(const MSEdge *edge) const
the position on the given edge which is connected to this stop, -1 on failure
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 dimension
Definition: Position.h:242
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
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:60
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.