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 /****************************************************************************/
15 // A area where vehicles can park next to the road
16 /****************************************************************************/
17 
18 
19 // ===========================================================================
20 // included modules
21 // ===========================================================================
22 #include <config.h>
23 
24 #include <cassert>
27 #include <utils/geom/Position.h>
28 #include <utils/geom/GeomHelper.h>
30 #include <microsim/MSNet.h>
31 #include <microsim/MSVehicleType.h>
32 #include "MSLane.h"
33 #include "MSTransportable.h"
34 #include "MSParkingArea.h"
35 #include "MSGlobals.h"
36 
37 //#define DEBUG_RESERVATIONS
38 //#define DEBUG_COND2(obj) (obj.getID() == "v.3")
39 #define DEBUG_COND2(obj) (obj.isSelected())
40 
41 
42 // ===========================================================================
43 // method definitions
44 // ===========================================================================
45 MSParkingArea::MSParkingArea(const std::string& id,
46  const std::vector<std::string>& lines,
47  MSLane& lane,
48  double begPos, double endPos,
49  int capacity,
50  double width, double length, double angle, const std::string& name,
51  bool onRoad) :
52  MSStoppingPlace(id, lines, lane, begPos, endPos, name),
53  myCapacity(0),
54  myOnRoad(onRoad),
55  myWidth(width),
56  myLength(length),
57  myAngle(angle),
58  myEgressBlocked(false),
59  myReservationTime(-1),
60  myReservations(0),
61  myReservationMaxLength(0),
62  myNumAlternatives(0),
63  myLastStepOccupancy(0),
64  myUpdateEvent(nullptr) {
65  // initialize unspecified defaults
66  if (myWidth == 0) {
68  }
69  const double spaceDim = capacity > 0 ? myLane.interpolateLanePosToGeometryPos((myEndPos - myBegPos) / capacity) : 7.5;
70  if (myLength == 0) {
71  myLength = spaceDim;
72  }
73 
74  const double offset = MSNet::getInstance()->lefthand() ? -1 : 1;
75  myShape = lane.getShape().getSubpart(
77  lane.interpolateLanePosToGeometryPos(endPos));
78  if (!myOnRoad) {
79  myShape.move2side((lane.getWidth() / 2. + myWidth / 2.) * offset);
80  }
81  // Initialize space occupancies if there is a road-side capacity
82  // The overall number of lots is fixed and each lot accepts one vehicle regardless of size
83  for (int i = 0; i < capacity; ++i) {
84  const Position f = myShape.positionAtOffset(spaceDim * (i));
85  const Position s = myShape.positionAtOffset(spaceDim * (i + 1));
86  Position pos = myAngle == 0 ? s : (f + s) * 0.5;
87  addLotEntry(pos.x(), pos.y(), pos.z(),
89  ((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) M_PI) + myAngle);
90  mySpaceOccupancies.back().myEndPos = myBegPos + MAX2(POSITION_EPS, spaceDim * (i + 1));
91  }
93 }
94 
96 
97 void
98 MSParkingArea::addLotEntry(double x, double y, double z,
99  double width, double length, double angle) {
100  LotSpaceDefinition lsd;
101  lsd.index = (int)mySpaceOccupancies.size();
102  lsd.vehicle = nullptr;
103  lsd.myPosition = Position(x, y, z);
104  lsd.myWidth = width;
105  lsd.myLength = length;
106  lsd.myRotation = angle;
107  // If we are modelling parking set the end position to the lot position relative to the lane
108  // rather than the end of the parking area - this results in vehicles stopping nearer the space
109  // and re-entering the lane nearer the space. (If we are not modelling parking the vehicle will usually
110  // enter the space and re-enter at the end of the parking area.)
112  const double offset = this->getLane().getShape().nearest_offset_to_point2D(lsd.myPosition);
113  if (offset < getBeginLanePosition()) {
115  } else {
116  if (this->getLane().getLength() > offset) {
117  lsd.myEndPos = offset;
118  } else {
119  lsd.myEndPos = this->getLane().getLength() - POSITION_EPS;
120  }
121  }
122  // Work out the angle of the lot relative to the lane (+90 parallels the way the bay is drawn )
123  int relativeAngle = static_cast<int>(lsd.myRotation + 90. - RAD2DEG(this->getLane().getShape().rotationAtOffset(lsd.myEndPos)));
124  if (relativeAngle < 0) {
125  relativeAngle += 360;
126  }
127 
128  // use this to set the manoeuver angle - real life manoeuver will always be < 180 degrees - hence the modulus
129  // if p2.y is -ve the lot is on LHS of lane relative to lane direction
131  if (p2.y() < (0. + POSITION_EPS)) {
132  lsd.myManoeuverAngle = abs(relativeAngle) % 180;
133  } else { // lot is on RHS of lane
134  lsd.myManoeuverAngle = abs(abs(relativeAngle) % 180 - 180) % 180;
135  }
136  } else {
137  lsd.myEndPos = myEndPos;
138  lsd.myManoeuverAngle = int(angle); // unused unless gModelParkingManoeuver is true
139  }
140 
141 
142  mySpaceOccupancies.push_back(lsd);
143  myCapacity++;
145 }
146 
147 int
149  assert(myLastFreeLot >= 0);
150  assert(myLastFreeLot < (int)mySpaceOccupancies.size());
151  return (mySpaceOccupancies[myLastFreeLot].myManoeuverAngle);
152 }
153 
154 
155 
156 double
157 MSParkingArea::getLastFreePos(const SUMOVehicle& forVehicle) const {
158  if (myCapacity == (int)myEndPositions.size()) {
159  // keep enough space so that parking vehicles can leave
160  return myLastFreePos - forVehicle.getVehicleType().getMinGap() - POSITION_EPS;
161  } else {
162  // XXX if (forVehicle.getLane() == myLane && forVehicle.getPositionOnLane() > myLastFreePos) {
163  // find freePos beyond vehicle position }
164  return myLastFreePos;
165  }
166 }
167 
168 Position
170  for (const auto& lsd : mySpaceOccupancies) {
171  if (lsd.vehicle == &forVehicle) {
172  return lsd.myPosition;
173  }
174  }
175  return Position::INVALID;
176 }
177 
178 
179 double
181  for (const auto& lsd : mySpaceOccupancies) {
182  if (lsd.vehicle == &forVehicle) {
183  return lsd.myEndPos;
184  }
185  }
186  return -1;
187 }
188 
189 
190 double
191 MSParkingArea::getVehicleAngle(const SUMOVehicle& forVehicle) const {
192  for (const auto& lsd : mySpaceOccupancies) {
193  if (lsd.vehicle == &forVehicle) {
194  return (lsd.myRotation - 90.) * (double) M_PI / (double) 180.0;
195  }
196  }
197  return 0;
198 }
199 
200 
201 void
202 MSParkingArea::enter(SUMOVehicle* what, double beg, double end) {
203  assert(myLastFreePos >= 0);
204  assert(myLastFreeLot < (int)mySpaceOccupancies.size());
205  if (myUpdateEvent == nullptr) {
208  }
209  mySpaceOccupancies[myLastFreeLot].vehicle = what;
210  myEndPositions[what] = std::pair<double, double>(beg, end);
212 }
213 
214 
215 void
217  assert(myEndPositions.find(what) != myEndPositions.end());
218  if (myUpdateEvent == nullptr) {
221  }
222  for (auto& lsd : mySpaceOccupancies) {
223  if (lsd.vehicle == what) {
224  lsd.vehicle = nullptr;
225  break;
226  }
227  }
228  myEndPositions.erase(myEndPositions.find(what));
230 }
231 
232 
233 SUMOTime
236  myUpdateEvent = nullptr;
237  return 0;
238 }
239 
240 
241 void
243  myLastFreeLot = -1;
245  myEgressBlocked = false;
246  for (auto& lsd : mySpaceOccupancies) {
247  if (lsd.vehicle == nullptr
248  || (getOccupancy() == getCapacity()
249  && lsd.vehicle->remainingStopDuration() <= 0
250  && !lsd.vehicle->isStoppedTriggered())) {
251  if (lsd.vehicle == nullptr) {
252  myLastFreeLot = lsd.index;
253  myLastFreePos = lsd.myEndPos;
254  } else {
255  // vehicle wants to exit the parking area
256  myLastFreeLot = lsd.index;
257  myLastFreePos = lsd.myEndPos - lsd.vehicle->getVehicleType().getLength() - POSITION_EPS;
258  myEgressBlocked = true;
259  }
260  break;
261  } else {
263  lsd.myEndPos - lsd.vehicle->getVehicleType().getLength() - NUMERICAL_EPS);
264  }
265  }
266 }
267 
268 
269 double
271  if (forVehicle.getLane() != &myLane) {
272  // for different lanes, do not consider reservations to avoid lane-order
273  // dependency in parallel simulation
274 #ifdef DEBUG_RESERVATIONS
275  if (DEBUG_COND2(forVehicle)) {
276  std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " other lane\n";
277  }
278 #endif
279  if (myNumAlternatives > 0 && getOccupancy() == getCapacity()) {
280  // ensure that the vehicle reaches the rerouter lane
282  } else {
283  return getLastFreePos(forVehicle);
284  }
285  }
286  if (t > myReservationTime) {
287 #ifdef DEBUG_RESERVATIONS
288  if (DEBUG_COND2(forVehicle)) {
289  std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " first reservation\n";
290  }
291 #endif
292  myReservationTime = t;
293  myReservations = 1;
295  for (const auto& lsd : mySpaceOccupancies) {
296  if (lsd.vehicle != nullptr) {
297  myReservationMaxLength = MAX2(myReservationMaxLength, lsd.vehicle->getVehicleType().getLength());
298  }
299  }
300  return getLastFreePos(forVehicle);
301  } else {
303 #ifdef DEBUG_RESERVATIONS
304  if (DEBUG_COND2(forVehicle)) {
305  std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID() << " res=" << myReservations << " enough space\n";
306  }
307 #endif
308  myReservations++;
310  return getLastFreePos(forVehicle);
311  } else {
312  if (myCapacity == 0) {
313  return getLastFreePos(forVehicle);
314  } else {
315 #ifdef DEBUG_RESERVATIONS
316  if (DEBUG_COND2(forVehicle)) std::cout << SIMTIME << " pa=" << getID() << " freePosRes veh=" << forVehicle.getID()
317  << " res=" << myReservations << " resTime=" << myReservationTime << " reserved full, maxLen=" << myReservationMaxLength << " endPos=" << mySpaceOccupancies[0].myEndPos << "\n";
318 #endif
319  return (mySpaceOccupancies[0].myEndPos
321  - forVehicle.getVehicleType().getMinGap()
322  - NUMERICAL_EPS);
323  }
324  }
325  }
326 }
327 
328 
329 double
331  return myWidth;
332 }
333 
334 
335 double
337  return myLength;
338 }
339 
340 
341 double
343  return myAngle;
344 }
345 
346 
347 int
349  return myCapacity;
350 }
351 
352 
353 int
355  return (int)myEndPositions.size() - (myEgressBlocked ? 1 : 0);
356 }
357 
358 
359 int
361  return (int)myEndPositions.size();
362 }
363 
364 void
367 }
368 
369 /****************************************************************************/
MSStoppingPlace::getLane
const MSLane & getLane() const
Returns the lane this stop is located at.
Definition: MSStoppingPlace.cpp:57
MSParkingArea::LotSpaceDefinition::myRotation
double myRotation
The rotation.
Definition: MSParkingArea.h:256
MSStoppingPlace
A lane area vehicles can halt at.
Definition: MSStoppingPlace.h:59
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:73
MSEventControl::addEvent
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
Definition: MSEventControl.cpp:52
MSParkingArea::enter
void enter(SUMOVehicle *what, double beg, double end)
Called if a vehicle enters this stop.
Definition: MSParkingArea.cpp:202
MSParkingArea::updateOccupancy
SUMOTime updateOccupancy(SUMOTime currentTime)
Called at the end of the time step.
Definition: MSParkingArea.cpp:234
MSNet.h
MSLane
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
MSParkingArea::myLastFreeLot
int myLastFreeLot
Last free lot number (-1 no free lot)
Definition: MSParkingArea.h:277
MSParkingArea::myReservationMaxLength
double myReservationMaxLength
Definition: MSParkingArea.h:307
MSParkingArea::notifyEgressBlocked
void notifyEgressBlocked()
update state so that vehicles wishing to enter cooperate with exiting vehicles
Definition: MSParkingArea.cpp:365
NUMERICAL_EPS
#define NUMERICAL_EPS
Definition: config.h:148
Position::z
double z() const
Returns the z-position.
Definition: Position.h:66
Position::INVALID
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:284
SUMOTrafficObject::getVehicleType
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle's type.
MSParkingArea::LotSpaceDefinition::myWidth
double myWidth
The width.
Definition: MSParkingArea.h:258
PositionVector::getSubpart
PositionVector getSubpart(double beginOffset, double endOffset) const
get subpart of a position vector
Definition: PositionVector.cpp:706
MSParkingArea::myReservations
int myReservations
Definition: MSParkingArea.h:306
SUMOTrafficObject::getID
virtual const std::string & getID() const =0
Get the vehicle's ID.
MSStoppingPlace::getBeginLanePosition
double getBeginLanePosition() const
Returns the begin position of this stop.
Definition: MSStoppingPlace.cpp:63
WrappingCommand.h
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:34
SUMOVehicle
Representation of a vehicle.
Definition: SUMOVehicle.h:60
MSParkingArea::LotSpaceDefinition::myPosition
Position myPosition
The position of the vehicle when parking in this space.
Definition: MSParkingArea.h:254
WrappingCommand
A wrapper for a Command function.
Definition: WrappingCommand.h:51
MSParkingArea::LotSpaceDefinition::index
int index
the running index
Definition: MSParkingArea.h:250
MSParkingArea::getInsertionPosition
double getInsertionPosition(const SUMOVehicle &forVehicle) const
Returns the insertion position of a parked vehicle.
Definition: MSParkingArea.cpp:180
SUMO_const_laneWidth
const double SUMO_const_laneWidth
Definition: StdDefs.h:49
MSParkingArea::getVehiclePosition
Position getVehiclePosition(const SUMOVehicle &forVehicle) const
Returns the position of parked vehicle.
Definition: MSParkingArea.cpp:169
MSStoppingPlace::myEndPositions
std::map< const SUMOVehicle *, std::pair< double, double > > myEndPositions
A map from objects (vehicles) to the areas they acquire after entering the stop.
Definition: MSStoppingPlace.h:219
RAD2DEG
#define RAD2DEG(x)
Definition: GeomHelper.h:38
MSParkingArea::getVehicleAngle
double getVehicleAngle(const SUMOVehicle &forVehicle) const
Returns the angle of parked vehicle.
Definition: MSParkingArea.cpp:191
MSParkingArea::myAngle
double myAngle
The default angle of each parking space.
Definition: MSParkingArea.h:292
MSParkingArea::LotSpaceDefinition::myLength
double myLength
The length.
Definition: MSParkingArea.h:260
MSVehicleType.h
MSStoppingPlace::myBegPos
const double myBegPos
The begin position this bus stop is located at.
Definition: MSStoppingPlace.h:225
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:79
MSParkingArea::myReservationTime
SUMOTime myReservationTime
track parking reservations from the lane for the current time step
Definition: MSParkingArea.h:305
PositionVector::nearest_offset_to_point2D
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
Definition: PositionVector.cpp:817
SUMOVehicle.h
SIMTIME
#define SIMTIME
Definition: SUMOTime.h:63
PositionVector::transformToVectorCoordinates
Position transformToVectorCoordinates(const Position &p, bool extend=false) const
return position p within the length-wise coordinate system defined by this position vector....
Definition: PositionVector.cpp:890
MSNet::getEndOfTimestepEvents
MSEventControl * getEndOfTimestepEvents()
Returns the event control for events executed at the end of a time step.
Definition: MSNet.h:439
MSNet::lefthand
bool lefthand() const
return whether the network was built for lefthand traffic
Definition: MSNet.h:663
MSStoppingPlace::myEndPos
const double myEndPos
The end position this bus stop is located at.
Definition: MSStoppingPlace.h:228
MSParkingArea::myShape
PositionVector myShape
The roadside shape of this parkingArea.
Definition: MSParkingArea.h:299
MSParkingArea::getCapacity
int getCapacity() const
Returns the area capacity.
Definition: MSParkingArea.cpp:348
DEBUG_COND2
#define DEBUG_COND2(obj)
Definition: MSParkingArea.cpp:39
SUMOVehicle::getLane
virtual MSLane * getLane() const =0
Returns the lane the vehicle is on.
MSParkingArea::myLastStepOccupancy
int myLastStepOccupancy
Changes to the occupancy in the current time step.
Definition: MSParkingArea.h:313
PositionVector::positionAtOffset
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
Definition: PositionVector.cpp:248
MSLane::interpolateLanePosToGeometryPos
double interpolateLanePosToGeometryPos(double lanePos) const
Definition: MSLane.h:498
MSLane::getLength
double getLength() const
Returns the lane's length.
Definition: MSLane.h:540
MSParkingArea::LotSpaceDefinition::myEndPos
double myEndPos
The position along the lane that the vehicle needs to reach for entering this lot.
Definition: MSParkingArea.h:262
MSParkingArea::mySpaceOccupancies
std::vector< LotSpaceDefinition > mySpaceOccupancies
All the spaces in this parking area.
Definition: MSParkingArea.h:296
MSGlobals::gModelParkingManoeuver
static bool gModelParkingManoeuver
whether parking simulation includes manoeuver time and any associated lane blocking
Definition: MSGlobals.h:135
Position
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:38
Position::x
double x() const
Returns the x-position.
Definition: Position.h:56
MSGlobals.h
MSParkingArea::MSParkingArea
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.
Definition: MSParkingArea.cpp:45
MSVehicleType::getMinGap
double getMinGap() const
Get the free space in front of vehicles of this class.
Definition: MSVehicleType.h:125
MSParkingArea::myLength
double myLength
The default length of each parking space.
Definition: MSParkingArea.h:289
MSParkingArea.h
MSParkingArea::addLotEntry
virtual void addLotEntry(double x, double y, double z, double width, double length, double angle)
Add a lot entry to parking area.
Definition: MSParkingArea.cpp:98
MSParkingArea::LotSpaceDefinition
Representation of a single lot space.
Definition: MSParkingArea.h:248
MSParkingArea::getLength
double getLength() const
Returns the lot rectangle length.
Definition: MSParkingArea.cpp:336
MSParkingArea::myCapacity
int myCapacity
Stop area capacity.
Definition: MSParkingArea.h:280
MSParkingArea::leaveFrom
void leaveFrom(SUMOVehicle *what)
Called if a vehicle leaves this stop.
Definition: MSParkingArea.cpp:216
MSParkingArea::computeLastFreePos
void computeLastFreePos()
Computes the last free position on this stop.
Definition: MSParkingArea.cpp:242
MSParkingArea::myOnRoad
bool myOnRoad
Whether vehicles stay on the road.
Definition: MSParkingArea.h:283
Position.h
MSLane::getShape
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:477
MSParkingArea::getOccupancy
int getOccupancy() const
Returns the area occupancy.
Definition: MSParkingArea.cpp:354
MSParkingArea::getWidth
double getWidth() const
Returns the lot rectangle width.
Definition: MSParkingArea.cpp:330
MSNet::getInstance
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:167
Position::y
double y() const
Returns the y-position.
Definition: Position.h:61
MSParkingArea::getLastFreeLotAngle
int getLastFreeLotAngle() const
Return the angle of myLastFreeLot - the next parking lot only expected to be called after we have est...
Definition: MSParkingArea.cpp:148
M_PI
#define M_PI
Definition: odrSpiral.cpp:40
MSParkingArea::getLastFreePosWithReservation
double getLastFreePosWithReservation(SUMOTime t, const SUMOVehicle &forVehicle)
Returns the last free position on this stop including reservatiosn from the current lane and time ste...
Definition: MSParkingArea.cpp:270
MSVehicleType::getLength
double getLength() const
Get vehicle's length [m].
Definition: MSVehicleType.h:109
MSParkingArea::getOccupancyIncludingBlocked
int getOccupancyIncludingBlocked() const
Returns the area occupancy.
Definition: MSParkingArea.cpp:360
MSTransportable.h
MSParkingArea::LotSpaceDefinition::myManoeuverAngle
int myManoeuverAngle
The angle between lane and lot through which a vehicle must manoeuver to enter the lot.
Definition: MSParkingArea.h:264
MSStoppingPlace::myLastFreePos
double myLastFreePos
The last free position at this stop (variable)
Definition: MSStoppingPlace.h:231
MSParkingArea::~MSParkingArea
virtual ~MSParkingArea()
Destructor.
Definition: MSParkingArea.cpp:95
MSStoppingPlace::getLastFreePos
double getLastFreePos() const
Definition: MSStoppingPlace.h:172
MSLane::getWidth
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:556
config.h
GeomHelper.h
MSParkingArea::myNumAlternatives
int myNumAlternatives
the number of alternative parkingAreas that are assigned to parkingAreaRerouter
Definition: MSParkingArea.h:310
MSEventControl.h
MSLane.h
MSParkingArea::LotSpaceDefinition::vehicle
SUMOVehicle * vehicle
The last parked vehicle or 0.
Definition: MSParkingArea.h:252
MSParkingArea::getAngle
double getAngle() const
Returns the lot rectangle angle.
Definition: MSParkingArea.cpp:342
Named::getID
const std::string & getID() const
Returns the id.
Definition: Named.h:76
POSITION_EPS
#define POSITION_EPS
Definition: config.h:172
MSStoppingPlace::myLane
const MSLane & myLane
The lane this bus stop is located at.
Definition: MSStoppingPlace.h:222
MSParkingArea::myUpdateEvent
Command * myUpdateEvent
Event for updating the occupancy.
Definition: MSParkingArea.h:316
PositionVector::move2side
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
Definition: PositionVector.cpp:1103
MSParkingArea::myEgressBlocked
bool myEgressBlocked
whether a vehicle wants to exit but is blocked
Definition: MSParkingArea.h:302
MSParkingArea::myWidth
double myWidth
The default width of each parking space.
Definition: MSParkingArea.h:286