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>
28 #include <utils/common/RGBColor.h>
29 #include <microsim/MSGlobals.h>
30 #include <microsim/MSVehicleType.h>
31 #include <microsim/MSNet.h>
32 #include "MSLane.h"
34 #include "MSStoppingPlace.h"
35 
36 // ===========================================================================
37 // method definitions
38 // ===========================================================================
39 MSStoppingPlace::MSStoppingPlace(const std::string& id,
40  SumoXMLTag element,
41  const std::vector<std::string>& lines,
42  MSLane& lane,
43  double begPos, double endPos, const std::string name,
44  int capacity,
45  double parkingLength,
46  const RGBColor& color) :
47  Named(id),
48  myElement(element),
49  myLines(lines), myLane(lane),
50  myBegPos(begPos), myEndPos(endPos), myLastFreePos(endPos),
51  myName(name),
52  myTransportableCapacity(capacity),
53  myParkingFactor(parkingLength <= 0 ? 1 : (endPos - begPos) / parkingLength),
54  myColor(color),
55  // see MSVehicleControl defContainerType
58  for (int i = 0; i < capacity; i++) {
59  myWaitingSpots.insert(i);
60  }
61 }
62 
63 
65 
66 
67 const MSLane&
69  return myLane;
70 }
71 
72 
73 double
75  return myBegPos;
76 }
77 
78 
79 double
81  return myEndPos;
82 }
83 
87  myLane.getWidth() / 2);
88 }
89 
90 
91 void
92 MSStoppingPlace::enter(SUMOVehicle* veh, bool parking) {
93  double beg = veh->getPositionOnLane() + veh->getVehicleType().getMinGap();
94  double end = beg - veh->getVehicleType().getLengthWithGap() * (parking ? myParkingFactor : 1);
95  myEndPositions[veh] = std::make_pair(beg, end);
97 }
98 
99 
100 double
101 MSStoppingPlace::getLastFreePos(const SUMOVehicle& forVehicle, double /*brakePos*/) const {
102  if (myLastFreePos != myEndPos) {
103  const double vehGap = forVehicle.getVehicleType().getMinGap();
104  double pos = myLastFreePos - vehGap;
105  if (forVehicle.getLane() == &myLane && forVehicle.getPositionOnLane() < myEndPos && forVehicle.getPositionOnLane() > myBegPos && forVehicle.getSpeed() <= SUMO_const_haltingSpeed) {
106  return forVehicle.getPositionOnLane();
107  }
108  if (!fits(pos, forVehicle)) {
109  // try to find a place ahead of the waiting vehicles
110  const double vehLength = forVehicle.getVehicleType().getLength();
111  std::vector<std::pair<double, std::pair<double, const SUMOVehicle*> > > spaces;
112  for (auto it : myEndPositions) {
113  spaces.push_back(std::make_pair(it.second.first, std::make_pair(it.second.second, it.first)));
114  }
115  // sorted from myEndPos towars myBegPos
116  std::sort(spaces.begin(), spaces.end());
117  std::reverse(spaces.begin(), spaces.end());
118  double prev = myEndPos;
119  for (auto it : spaces) {
120  //if (forVehicle.isSelected()) {
121  // std::cout << SIMTIME << " fitPosFor " << forVehicle.getID() << " l=" << vehLength << " prev=" << prev << " vehBeg=" << it.first << " vehEnd=" << it.second.first << " found=" << (prev - it.first >= vehLength) << "\n";
122  //}
123  if (prev - it.first + NUMERICAL_EPS >= vehLength && (
124  it.second.second->isParking()
125  || it.second.second->remainingStopDuration() > TIME2STEPS(10))) {
126  return prev;
127  }
128  prev = it.second.first - vehGap;
129  }
130  }
131  return pos;
132  }
133  return myLastFreePos;
134 }
135 
136 bool
137 MSStoppingPlace::fits(double pos, const SUMOVehicle& veh) const {
138  // always fit at the default position or if at least half the vehicle length
139  // is within the stop range (debatable)
140  return pos + POSITION_EPS >= myEndPos || (pos - myBegPos >= veh.getVehicleType().getLength() * myParkingFactor / 2);
141 }
142 
143 double
145  auto it = myWaitingTransportables.find(t);
146  const double waitingWidth = myElement == SUMO_TAG_CONTAINER_STOP
149  if (it != myWaitingTransportables.end() && it->second >= 0) {
150  return myEndPos - (0.5 + (it->second) % getTransportablesAbreast()) * waitingWidth;
151  } else {
152  return (myEndPos + myBegPos) / 2;
153  }
154 }
155 
156 
157 int
159  return MAX2(1, (int)floor(length / (element == SUMO_TAG_CONTAINER_STOP
162 }
163 
164 int
167 }
168 
169 Position
171  double lanePos = getWaitingPositionOnLane(t);
172  int row = 0;
173  auto it = myWaitingTransportables.find(t);
174  if (it != myWaitingTransportables.end()) {
175  if (it->second >= 0) {
176  row = int(it->second / getTransportablesAbreast());
177  } else {
178  // invalid position, draw outside bounds
180  }
181  }
182  const double lefthandSign = (MSGlobals::gLefthand ? -1 : 1);
184  lefthandSign * (myLane.getWidth() / 2 + row * myTransportableDepth));
185 }
186 
187 
188 double
190  auto i = myEndPositions.find(veh);
191  if (i != myEndPositions.end()) {
192  return i->second.second;
193  } else {
194  return getLastFreePos(*veh);
195  }
196 }
197 
198 std::vector<const MSTransportable*>
200  std::vector<const MSTransportable*> result;
201  for (auto item : myWaitingTransportables) {
202  result.push_back(item.first);
203  }
204  return result;
205 }
206 
207 bool
209  return myWaitingSpots.size() > 0;
210 }
211 
212 bool
214  int spot = -1;
215  if (!hasSpaceForTransportable()) {
216  return false;
217  }
218  spot = *myWaitingSpots.begin();
219  myWaitingSpots.erase(myWaitingSpots.begin());
220  myWaitingTransportables[p] = spot;
221  return true;
222 }
223 
224 
225 void
227  auto i = myWaitingTransportables.find(p);
228  if (i != myWaitingTransportables.end()) {
229  if (i->second >= 0) {
230  myWaitingSpots.insert(i->second);
231  }
232  myWaitingTransportables.erase(i);
233  }
234 }
235 
236 
237 void
239  assert(myEndPositions.find(what) != myEndPositions.end());
240  myEndPositions.erase(myEndPositions.find(what));
242 }
243 
244 
245 void
248  for (auto i = myEndPositions.begin(); i != myEndPositions.end(); i++) {
249  if (myLastFreePos > (*i).second.second) {
250  myLastFreePos = (*i).second.second;
251  }
252  }
253 }
254 
255 
256 double
258  if (edge == &myLane.getEdge()) {
259  return (myBegPos + myEndPos) / 2.;
260  }
261  for (const auto& access : myAccessPos) {
262  if (edge == &std::get<0>(access)->getEdge()) {
263  return std::get<1>(access);
264  }
265  }
266  return -1.;
267 }
268 
269 
270 double
272  if (edge == &myLane.getEdge()) {
273  return 0.;
274  }
275  for (const auto& access : myAccessPos) {
276  const MSLane* const accLane = std::get<0>(access);
277  if (edge == &accLane->getEdge()) {
278  return std::get<2>(access);
279  }
280  }
281  return -1.;
282 }
283 
284 
285 const std::string&
287  return myName;
288 }
289 
290 
291 const RGBColor&
293  return myColor;
294 }
295 
296 
297 bool
298 MSStoppingPlace::addAccess(MSLane* lane, const double pos, double length) {
299  // prevent multiple accesss on the same lane
300  for (const auto& access : myAccessPos) {
301  if (lane == std::get<0>(access)) {
302  return false;
303  }
304  }
305  if (length < 0.) {
306  const Position accPos = lane->geometryPositionAtOffset(pos);
307  const Position stopPos = myLane.geometryPositionAtOffset((myBegPos + myEndPos) / 2.);
308  length = accPos.distanceTo(stopPos);
309  }
310  myAccessPos.push_back(std::make_tuple(lane, pos, length));
311  return true;
312 }
313 
314 std::vector<const SUMOVehicle*>
316  std::vector<const SUMOVehicle*> result;
317  for (auto item : myEndPositions) {
318  result.push_back(item.first);
319  }
320  return result;
321 }
322 
323 
324 void
325 MSStoppingPlace::getWaitingPersonIDs(std::vector<std::string>& into) const {
326  for (auto item : myWaitingTransportables) {
327  into.push_back(item.first->getID());
328  }
329  std::sort(into.begin(), into.end());
330 }
331 
332 
333 void
335  myEndPositions.clear();
336  myWaitingTransportables.clear();
338 }
339 
340 
341 /****************************************************************************/
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_CONTAINER_STOP
A container stop.
const double SUMO_const_waitingPersonDepth
Definition: StdDefs.h:56
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:61
T MAX2(T a, T b)
Definition: StdDefs.h:80
const double SUMO_const_waitingContainerWidth
Definition: StdDefs.h:57
const double SUMO_const_waitingPersonWidth
Definition: StdDefs.h:55
const double SUMO_const_waitingContainerDepth
Definition: StdDefs.h:58
A road/street connecting two junctions.
Definition: MSEdge.h:77
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition: MSGlobals.h:157
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:674
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:478
double interpolateLanePosToGeometryPos(double lanePos) const
Definition: MSLane.h:499
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:556
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:505
std::vector< const SUMOVehicle * > getStoppedVehicles() const
get list of vehicles waiting at this stop
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 double getSpeed() const =0
Returns the object's current speed.
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 getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
Definition: SUMOVehicle.h:60