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-2020 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 /****************************************************************************/
19 // A lane area vehicles can halt at
20 /****************************************************************************/
21 #include <config.h>
22 
23 #include <cassert>
24 #include <map>
26 #include <utils/geom/Position.h>
27 #include <microsim/MSGlobals.h>
28 #include <microsim/MSVehicleType.h>
29 #include <microsim/MSNet.h>
30 #include "MSLane.h"
32 #include "MSStoppingPlace.h"
33 
34 // ===========================================================================
35 // method definitions
36 // ===========================================================================
37 MSStoppingPlace::MSStoppingPlace(const std::string& id,
38  const std::vector<std::string>& lines,
39  MSLane& lane,
40  double begPos, double endPos, const std::string name,
41  int capacity,
42  double parkingLength) :
43  Named(id), myLines(lines), myLane(lane),
44  myBegPos(begPos), myEndPos(endPos), myLastFreePos(endPos),
45  myName(name),
46  myTransportableCapacity(capacity),
47  myParkingFactor(parkingLength <= 0 ? 1 : (endPos - begPos) / parkingLength) {
49  for (int i = 0; i < capacity; i++) {
50  myWaitingSpots.insert(i);
51  }
52 }
53 
54 
56 
57 
58 const MSLane&
60  return myLane;
61 }
62 
63 
64 double
66  return myBegPos;
67 }
68 
69 
70 double
72  return myEndPos;
73 }
74 
75 
76 void
77 MSStoppingPlace::enter(SUMOVehicle* veh, bool parking) {
78  double beg = veh->getPositionOnLane() + veh->getVehicleType().getMinGap();
79  double end = beg - veh->getVehicleType().getLengthWithGap() * (parking ? myParkingFactor : 1);
80  myEndPositions[veh] = std::make_pair(beg, end);
82 }
83 
84 
85 double
86 MSStoppingPlace::getLastFreePos(const SUMOVehicle& forVehicle) const {
87  if (myLastFreePos != myEndPos) {
88  const double vehGap = forVehicle.getVehicleType().getMinGap();
89  double pos = myLastFreePos - vehGap;
90  if (forVehicle.getLane() == &myLane && forVehicle.getPositionOnLane() < myEndPos && forVehicle.getPositionOnLane() > myBegPos && forVehicle.getSpeed() <= SUMO_const_haltingSpeed) {
91  return forVehicle.getPositionOnLane();
92  }
93  if (!fits(pos, forVehicle)) {
94  // try to find a place ahead of the waiting vehicles
95  const double vehLength = forVehicle.getVehicleType().getLength();
96  std::vector<std::pair<double, std::pair<double, const SUMOVehicle*> > > spaces;
97  for (auto it : myEndPositions) {
98  spaces.push_back(std::make_pair(it.second.first, std::make_pair(it.second.second, it.first)));
99  }
100  // sorted from myEndPos towars myBegPos
101  std::sort(spaces.begin(), spaces.end());
102  std::reverse(spaces.begin(), spaces.end());
103  double prev = myEndPos;
104  for (auto it : spaces) {
105  //if (forVehicle.isSelected()) {
106  // std::cout << SIMTIME << " fitPosFor " << forVehicle.getID() << " l=" << vehLength << " prev=" << prev << " vehBeg=" << it.first << " vehEnd=" << it.second.first << " found=" << (prev - it.first >= vehLength) << "\n";
107  //}
108  if (prev - it.first + NUMERICAL_EPS >= vehLength && (
109  it.second.second->isParking()
110  || it.second.second->remainingStopDuration() > TIME2STEPS(10))) {
111  return prev;
112  }
113  prev = it.second.first - vehGap;
114  }
115  }
116  return pos;
117  }
118  return myLastFreePos;
119 }
120 
121 bool
122 MSStoppingPlace::fits(double pos, const SUMOVehicle& veh) const {
123  // always fit at the default position or if at least half the vehicle length
124  // is within the stop range (debatable)
125  return pos + POSITION_EPS >= myEndPos || (pos - myBegPos >= veh.getVehicleType().getLength() * myParkingFactor / 2);
126 }
127 
128 double
130  auto it = myWaitingTransportables.find(t);
131  if (it != myWaitingTransportables.end() && it->second >= 0) {
132  return myEndPos - (0.5 + (it->second) % getPersonsAbreast()) * SUMO_const_waitingPersonWidth;
133  } else {
134  return (myEndPos + myBegPos) / 2;
135  }
136 }
137 
138 
139 int
141  return MAX2(1, (int)floor(length / SUMO_const_waitingPersonWidth));
142 }
143 
144 int
147 }
148 
149 Position
151  double lanePos = getWaitingPositionOnLane(t);
152  int row = 0;
153  auto it = myWaitingTransportables.find(t);
154  if (it != myWaitingTransportables.end()) {
155  if (it->second >= 0) {
156  row = int(it->second / getPersonsAbreast());
157  } else {
158  // invalid position, draw outside bounds
160  }
161  }
162  const double lefthandSign = (MSGlobals::gLefthand ? -1 : 1);
164  lefthandSign * (myLane.getWidth() / 2 + row * SUMO_const_waitingPersonDepth));
165 }
166 
167 
168 double
170  auto i = myEndPositions.find(veh);
171  if (i != myEndPositions.end()) {
172  return i->second.second;
173  } else {
174  return getLastFreePos(*veh);
175  }
176 }
177 
178 std::vector<MSTransportable*>
180  std::vector<MSTransportable*> result;
181  for (std::map<MSTransportable*, int>::const_iterator it = myWaitingTransportables.begin(); it != myWaitingTransportables.end(); it++) {
182  result.push_back(it->first);
183  }
184  return result;
185 }
186 
187 bool
189  return myWaitingSpots.size() > 0;
190 }
191 
192 bool
194  int spot = -1;
195  if (!hasSpaceForTransportable()) {
196  return false;
197  }
198  spot = *myWaitingSpots.begin();
199  myWaitingSpots.erase(myWaitingSpots.begin());
200  myWaitingTransportables[p] = spot;
201  return true;
202 }
203 
204 
205 void
207  auto i = myWaitingTransportables.find(p);
208  if (i != myWaitingTransportables.end()) {
209  if (i->second >= 0) {
210  myWaitingSpots.insert(i->second);
211  }
212  myWaitingTransportables.erase(i);
213  }
214 }
215 
216 
217 void
219  assert(myEndPositions.find(what) != myEndPositions.end());
220  myEndPositions.erase(myEndPositions.find(what));
222 }
223 
224 
225 void
228  for (auto i = myEndPositions.begin(); i != myEndPositions.end(); i++) {
229  if (myLastFreePos > (*i).second.second) {
230  myLastFreePos = (*i).second.second;
231  }
232  }
233 }
234 
235 
236 double
238  if (edge == &myLane.getEdge()) {
239  return (myBegPos + myEndPos) / 2.;
240  }
241  for (const auto& access : myAccessPos) {
242  if (edge == &std::get<0>(access)->getEdge()) {
243  return std::get<1>(access);
244  }
245  }
246  return -1.;
247 }
248 
249 
250 double
252  if (edge == &myLane.getEdge()) {
253  return 0.;
254  }
255  for (const auto& access : myAccessPos) {
256  const MSLane* const accLane = std::get<0>(access);
257  if (edge == &accLane->getEdge()) {
258  const double length = std::get<2>(access);
259  if (length >= 0.) {
260  return length;
261  }
262  const Position accPos = accLane->geometryPositionAtOffset(std::get<1>(access));
263  const Position stopPos = myLane.geometryPositionAtOffset((myBegPos + myEndPos) / 2.);
264  return accPos.distanceTo(stopPos);
265  }
266  }
267  return -1.;
268 }
269 
270 
271 const std::string&
273  return myName;
274 }
275 
276 
277 bool
278 MSStoppingPlace::addAccess(MSLane* lane, const double pos, const double length) {
279  // prevent multiple accesss on the same lane
280  for (const auto& access : myAccessPos) {
281  if (lane == std::get<0>(access)) {
282  return false;
283  }
284  }
285  myAccessPos.push_back(std::make_tuple(lane, pos, length));
286  return true;
287 }
288 
289 std::vector<const SUMOVehicle*>
291  std::vector<const SUMOVehicle*> result;
292  for (auto item : myEndPositions) {
293  result.push_back(item.first);
294  }
295  return result;
296 }
297 
298 
299 void
300 MSStoppingPlace::getWaitingPersonIDs(std::vector<std::string>& into) const {
301  for (auto item : myWaitingTransportables) {
302  into.push_back(item.first->getID());
303  }
304  std::sort(into.begin(), into.end());
305 }
306 
307 
308 void
310  myEndPositions.clear();
311  myWaitingTransportables.clear();
313 }
314 
315 
316 /****************************************************************************/
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
const double SUMO_const_waitingPersonDepth
Definition: StdDefs.h:55
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:60
T MAX2(T a, T b)
Definition: StdDefs.h:79
const double SUMO_const_waitingPersonWidth
Definition: StdDefs.h:54
A road/street connecting two junctions.
Definition: MSEdge.h:77
static bool gLefthand
Whether lefthand-drive is being simulated.
Definition: MSGlobals.h:136
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:673
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:476
double interpolateLanePosToGeometryPos(double lanePos) const
Definition: MSLane.h:497
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:555
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:503
std::vector< const SUMOVehicle * > getStoppedVehicles() const
get list of vehicles waiting at this stop
std::vector< MSTransportable * > getTransportables() const
Returns the tranportables waiting on this stop.
double getWaitingPositionOnLane(MSTransportable *t) const
Returns the lane position corresponding to getWaitPosition()
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.
std::map< MSTransportable *, int > myWaitingTransportables
Persons waiting at this stop (mapped to waiting position)
void clearState()
Remove all vehicles before quick-loading state.
std::set< int > myWaitingSpots
const double myParkingFactor
the scaled space capacity for parking vehicles
MSStoppingPlace(const std::string &id, const std::vector< std::string > &lines, MSLane &lane, double begPos, double endPos, const std::string name="", int capacity=0, double parkingLength=0)
Constructor.
bool fits(double pos, const SUMOVehicle &veh) const
return whether the given vehicle fits at the given position
bool addTransportable(MSTransportable *p)
adds a transportable to this stop
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
const double myEndPos
The end position this bus stop is located at.
int getPersonsAbreast() const
double getEndLanePosition() const
Returns the end position of this stop.
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.
void removeTransportable(MSTransportable *p)
Removes a transportable from this stop.
double getStoppingPosition(const SUMOVehicle *veh) const
For vehicles at the stop this gives the the actual stopping position of the vehicle....
virtual ~MSStoppingPlace()
Destructor.
void computeLastFreePos()
Computes the last free position on this stop.
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
virtual Position getWaitPosition(MSTransportable *person) const
Returns the next free waiting place for pedestrians / containers.
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
void leaveFrom(SUMOVehicle *what)
Called if a vehicle leaves this stop.
virtual bool addAccess(MSLane *lane, const double pos, const double length)
adds an access point to 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:53
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:231
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:58