Eclipse SUMO - Simulation of Urban MObility
MSParkingArea.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2015-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
16 // A area where vehicles can park next to the road
17 /****************************************************************************/
18 
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24 
25 #include <cassert>
27 #include <utils/geom/Position.h>
28 #include <utils/geom/GeomHelper.h>
29 #include <microsim/MSNet.h>
30 #include <microsim/MSVehicleType.h>
31 #include "MSLane.h"
32 #include "MSTransportable.h"
33 #include "MSParkingArea.h"
34 
35 //#define DEBUG_RESERVATIONS
36 //#define DEBUG_COND2(obj) (obj.getID() == "v.3")
37 #define DEBUG_COND2(obj) (obj.isSelected())
38 
39 
40 // ===========================================================================
41 // method definitions
42 // ===========================================================================
43 MSParkingArea::MSParkingArea(const std::string& id,
44  const std::vector<std::string>& lines,
45  MSLane& lane,
46  double begPos, double endPos,
47  int capacity,
48  double width, double length, double angle, const std::string& name,
49  bool onRoad) :
50  MSStoppingPlace(id, lines, lane, begPos, endPos, name),
51  myCapacity(0),
52  myOnRoad(onRoad),
53  myWidth(width),
54  myLength(length),
55  myAngle(angle),
56  myEgressBlocked(false),
57  myReservationTime(-1),
58  myReservations(0),
59  myReservationMaxLength(0),
60  myNumAlternatives(0) {
61  // initialize unspecified defaults
62  if (myWidth == 0) {
64  }
65  const double spaceDim = capacity > 0 ? myLane.interpolateLanePosToGeometryPos((myEndPos - myBegPos) / capacity) : 7.5;
66  if (myLength == 0) {
67  myLength = spaceDim;
68  }
69 
70  const double offset = MSNet::getInstance()->lefthand() ? -1 : 1;
71  myShape = lane.getShape().getSubpart(
73  lane.interpolateLanePosToGeometryPos(endPos));
74  if (!myOnRoad) {
75  myShape.move2side((lane.getWidth() / 2. + myWidth / 2.) * offset);
76  }
77  // Initialize space occupancies if there is a road-side capacity
78  // The overall number of lots is fixed and each lot accepts one vehicle regardless of size
79  for (int i = 0; i < capacity; ++i) {
80  const Position f = myShape.positionAtOffset(spaceDim * (i));
81  const Position s = myShape.positionAtOffset(spaceDim * (i + 1));
82  Position pos = myAngle == 0 ? s : (f + s) * 0.5;
83  addLotEntry(pos.x(), pos.y(), pos.z(),
85  ((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) M_PI) + myAngle);
86  mySpaceOccupancies.back().myEndPos = myBegPos + MAX2(POSITION_EPS, spaceDim * (i + 1));
87  }
89 }
90 
92 
93 void
94 MSParkingArea::addLotEntry(double x, double y, double z,
95  double width, double length, double angle) {
97  lsd.index = (int)mySpaceOccupancies.size();
98  lsd.vehicle = nullptr;
99  lsd.myPosition = Position(x, y, z);
100  lsd.myWidth = width;
101  lsd.myLength = length;
102  lsd.myRotation = angle;
103  lsd.myEndPos = myEndPos;
104  mySpaceOccupancies.push_back(lsd);
105  myCapacity++;
107 }
108 
109 
110 
111 
112 double
113 MSParkingArea::getLastFreePos(const SUMOVehicle& forVehicle) const {
114  if (myCapacity == (int)myEndPositions.size()) {
115  // keep enough space so that parking vehicles can leave
116  return myLastFreePos - forVehicle.getVehicleType().getMinGap() - POSITION_EPS;
117  } else {
118  // XXX if (forVehicle.getLane() == myLane && forVehicle.getPositionOnLane() > myLastFreePos) {
119  // find freePos beyond vehicle position }
120  return myLastFreePos;
121  }
122 }
123 
124 Position
126  for (const auto& lsd : mySpaceOccupancies) {
127  if (lsd.vehicle == &forVehicle) {
128  return lsd.myPosition;
129  }
130  }
131  return Position::INVALID;
132 }
133 
134 
135 double
137  for (const auto& lsd : mySpaceOccupancies) {
138  if (lsd.vehicle == &forVehicle) {
139  return lsd.myEndPos;
140  }
141  }
142  return -1;
143 }
144 
145 
146 double
147 MSParkingArea::getVehicleAngle(const SUMOVehicle& forVehicle) const {
148  for (const auto& lsd : mySpaceOccupancies) {
149  if (lsd.vehicle == &forVehicle) {
150  return (lsd.myRotation - 90.) * (double) M_PI / (double) 180.0;
151  }
152  }
153  return 0;
154 }
155 
156 
157 void
158 MSParkingArea::enter(SUMOVehicle* what, double beg, double end) {
159  assert(myLastFreePos >= 0);
160  assert(myLastFreeLot < (int)mySpaceOccupancies.size());
161  mySpaceOccupancies[myLastFreeLot].vehicle = what;
162  myEndPositions[what] = std::pair<double, double>(beg, end);
164 }
165 
166 
167 void
169  assert(myEndPositions.find(what) != myEndPositions.end());
170  for (auto& lsd : mySpaceOccupancies) {
171  if (lsd.vehicle == what) {
172  lsd.vehicle = nullptr;
173  break;
174  }
175  }
176  myEndPositions.erase(myEndPositions.find(what));
178 }
179 
180 
181 void
183  myLastFreeLot = -1;
185  myEgressBlocked = false;
186  for (auto& lsd : mySpaceOccupancies) {
187  if (lsd.vehicle == nullptr
188  || (getOccupancy() == getCapacity()
189  && lsd.vehicle->remainingStopDuration() <= 0
190  && !lsd.vehicle->isStoppedTriggered())) {
191  if (lsd.vehicle == nullptr) {
192  myLastFreeLot = lsd.index;
193  myLastFreePos = lsd.myEndPos;
194  } else {
195  // vehicle wants to exit the parking area
196  myLastFreeLot = lsd.index;
197  myLastFreePos = lsd.myEndPos - lsd.vehicle->getVehicleType().getLength() - POSITION_EPS;
198  myEgressBlocked = true;
199  }
200  break;
201  } else {
203  lsd.myEndPos - lsd.vehicle->getVehicleType().getLength() - NUMERICAL_EPS);
204  }
205  }
206 }
207 
208 
209 double
211  if (forVehicle.getLane() != &myLane) {
212  // for different lanes, do not consider reservations to avoid lane-order
213  // dependency in parallel simulation
214 #ifdef DEBUG_RESERVATIONS
215  if (DEBUG_COND2(forVehicle)) {
216  std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " other lane\n";
217  }
218 #endif
219  if (myNumAlternatives > 0 && getOccupancy() == getCapacity()) {
220  // ensure that the vehicle reaches the rerouter lane
222  } else {
223  return getLastFreePos(forVehicle);
224  }
225  }
226  if (t > myReservationTime) {
227 #ifdef DEBUG_RESERVATIONS
228  if (DEBUG_COND2(forVehicle)) {
229  std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " first reservation\n";
230  }
231 #endif
232  myReservationTime = t;
233  myReservations = 1;
235  for (const auto& lsd : mySpaceOccupancies) {
236  if (lsd.vehicle != nullptr) {
237  myReservationMaxLength = MAX2(myReservationMaxLength, lsd.vehicle->getVehicleType().getLength());
238  }
239  }
240  return getLastFreePos(forVehicle);
241  } else {
243 #ifdef DEBUG_RESERVATIONS
244  if (DEBUG_COND2(forVehicle)) {
245  std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " res=" << myReservations << " enough space\n";
246  }
247 #endif
248  myReservations++;
250  return getLastFreePos(forVehicle);
251  } else {
252  if (myCapacity == 0) {
253  return getLastFreePos(forVehicle);
254  } else {
255 #ifdef DEBUG_RESERVATIONS
256  if (DEBUG_COND2(forVehicle)) std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID()
257  << " res=" << myReservations << " resTime=" << myReservationTime << " reserved full, maxLen=" << myReservationMaxLength << " endPos=" << mySpaceOccupancies[0].myEndPos << "\n";
258 #endif
259  return (mySpaceOccupancies[0].myEndPos
261  - forVehicle.getVehicleType().getMinGap()
262  - NUMERICAL_EPS);
263  }
264  }
265  }
266 }
267 
268 
269 double
271  return myWidth;
272 }
273 
274 
275 double
277  return myLength;
278 }
279 
280 
281 double
283  return myAngle;
284 }
285 
286 
287 int
289  return myCapacity;
290 }
291 
292 
293 int
295  return (int)myEndPositions.size() - (myEgressBlocked ? 1 : 0);
296 }
297 
298 
299 int
301  return (int)myEndPositions.size();
302 }
303 
304 void
307 }
308 
309 /****************************************************************************/
std::map< const SUMOVehicle *, std::pair< double, double > > myEndPositions
A map from objects (vehicles) to the areas they acquire after entering the stop.
Position myPosition
The position of the vehicle when parking in this space.
int myLastFreeLot
Last free lot number (-1 no free lot)
long long int SUMOTime
Definition: SUMOTime.h:35
void notifyEgressBlocked()
update state so that vehicles wishing to enter cooperate with exiting vehicles
double z() const
Returns the z-position.
Definition: Position.h:67
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
A lane area vehicles can halt at.
void enter(SUMOVehicle *what, double beg, double end)
Called if a vehicle enters this stop.
double myReservationMaxLength
const double myEndPos
The end position this bus stop is located at.
const double SUMO_const_laneWidth
Definition: StdDefs.h:50
double getInsertionPosition(const SUMOVehicle &forVehicle) const
Returns the insertion position of a parked vehicle.
double y() const
Returns the y-position.
Definition: Position.h:62
Position getVehiclePosition(const SUMOVehicle &forVehicle) const
Returns the position of parked vehicle.
double x() const
Returns the x-position.
Definition: Position.h:57
virtual MSLane * getLane() const =0
Returns the lane the vehicle is on.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:168
T MAX2(T a, T b)
Definition: StdDefs.h:80
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:478
const std::string & getID() const
Returns the id.
Definition: Named.h:77
double getVehicleAngle(const SUMOVehicle &forVehicle) const
Returns the angle of parked vehicle.
#define DEBUG_COND2(obj)
double getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:557
#define SIMTIME
Definition: SUMOTime.h:64
double myAngle
The default angle of each parking space.
const MSLane & myLane
The lane this bus stop is located at.
SUMOTime myReservationTime
track parking reservations from the lane for the current time step
Representation of a vehicle.
Definition: SUMOVehicle.h:61
double myLastFreePos
The last free position at this stop (variable)
double myEndPos
The position along the lane that the vehicle needs to reach for entering this lot.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
PositionVector myShape
The roadside shape of this parkingArea.
double myLength
The default length of each parking space.
int getCapacity() const
Returns the area capacity.
T MIN2(T a, T b)
Definition: StdDefs.h:74
std::vector< LotSpaceDefinition > mySpaceOccupancies
All the spaces in this parking area.
#define POSITION_EPS
Definition: config.h:169
double getMinGap() const
Get the free space in front of vehicles of this class.
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
void computeLastFreePos()
Computes the last free position on this stop.
MSParkingArea(const std::string &id, const std::vector< std::string > &lines, MSLane &lane, double begPos, double endPos, int capacity, double width, double length, double angle, const std::string &name, bool onRoad)
Constructor.
bool lefthand() const
return whether the network was built for lefthand traffic
Definition: MSNet.h:662
int getOccupancy() const
Returns the area occupancy.
virtual void addLotEntry(double x, double y, double z, double width, double length, double angle)
Add a lot entry to parking area.
double getLength() const
Returns the lot rectangle length.
const double myBegPos
The begin position this bus stop is located at.
int myCapacity
Stop area capacity.
bool myOnRoad
Whether vehicles stay on the road.
void leaveFrom(SUMOVehicle *what)
Called if a vehicle leaves this stop.
int getOccupancyIncludingBlocked() const
Returns the area occupancy.
double getWidth() const
Returns the lot rectangle width.
#define M_PI
Definition: odrSpiral.cpp:40
virtual ~MSParkingArea()
Destructor.
double getLastFreePosWithReservation(SUMOTime t, const SUMOVehicle &forVehicle)
Returns the last free position on this stop including reservatiosn from the current lane and time ste...
double interpolateLanePosToGeometryPos(double lanePos) const
Definition: MSLane.h:499
double getLength() const
Get vehicle&#39;s length [m].
#define NUMERICAL_EPS
Definition: config.h:145
Representation of a single lot space.
double getLastFreePos() const
int myNumAlternatives
the number of alternative parkingAreas that are assigned to parkingAreaRerouter
bool myEgressBlocked
whether a vehicle wants to exit but is blocked
double myWidth
The default width of each parking space.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
Representation of a lane in the micro simulation.
Definition: MSLane.h:83
double getAngle() const
Returns the lot rectangle angle.
SUMOVehicle * vehicle
The last parked vehicle or 0.
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:285
double myRotation
The rotation.