1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import org.djunits.unit.LengthUnit;
4 import org.djunits.value.vdouble.scalar.Acceleration;
5 import org.djunits.value.vdouble.scalar.Length;
6 import org.djunits.value.vdouble.scalar.Speed;
7 import org.djunits.value.vdouble.scalar.Time;
8 import org.opentrafficsim.base.parameters.ParameterException;
9 import org.opentrafficsim.base.parameters.Parameters;
10 import org.opentrafficsim.core.gtu.GTUException;
11 import org.opentrafficsim.core.gtu.perception.EgoPerception;
12 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
13 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
14 import org.opentrafficsim.road.gtu.lane.perception.FilteredIterable;
15 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
16 import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable;
17 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
18 import org.opentrafficsim.road.gtu.lane.perception.categories.BusStopPerception;
19 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayBusStop;
20 import org.opentrafficsim.road.gtu.lane.plan.operational.SimpleOperationalPlan;
21 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
22 import org.opentrafficsim.road.gtu.lane.tactical.pt.BusSchedule;
23 import org.opentrafficsim.road.gtu.lane.tactical.util.CarFollowingUtil;
24 import org.opentrafficsim.road.network.lane.object.BusStop;
25 import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
26
27
28
29
30
31
32
33
34
35
36
37 public class AccelerationBusStop implements AccelerationIncentive
38 {
39
40
41
42 private static final Length STOP_DISTANCE = new Length(15.0, LengthUnit.SI);
43
44
45 @Override
46 @SuppressWarnings("checkstyle:parameternumber")
47 public final void accelerate(final SimpleOperationalPlan simplePlan, final RelativeLane lane, final Length mergeDistance,
48 final LaneBasedGTU gtu, final LanePerception perception, final CarFollowingModel carFollowingModel,
49 final Speed speed, final Parameters params, final SpeedLimitInfo speedLimitInfo)
50 throws OperationalPlanException, ParameterException, GTUException
51 {
52 PerceptionCollectable<HeadwayBusStop, BusStop> stops =
53 perception.getPerceptionCategory(BusStopPerception.class).getBusStops();
54 if (stops.isEmpty())
55 {
56 return;
57 }
58 BusSchedule busSchedule = (BusSchedule) gtu.getStrategicalPlanner().getRoute();
59 Time now = gtu.getSimulator().getSimulatorAbsTime();
60 Iterable<HeadwayBusStop> it = lane.isCurrent() ? stops : new FilteredIterable<>(stops, (busStop) ->
61 {
62 return busStop.getDistance().gt(mergeDistance);
63 });
64 for (HeadwayBusStop stop : it)
65 {
66 String busStopId = stop.getId();
67 if (busSchedule.isLineStop(busStopId, now))
68 {
69
70
71 boolean stoppedAtStop = stop.getRelativeLane().isCurrent() && stop.getDistance().le(STOP_DISTANCE)
72 && perception.getPerceptionCategory(EgoPerception.class).getSpeed().eq0();
73 if (busSchedule.getActualDepartureBusStop(busStopId) == null)
74 {
75 if (stoppedAtStop)
76 {
77
78 Time departureTime = now.plus(busSchedule.getDwellTime(busStopId));
79 if (busSchedule.isForceSchedule(busStopId))
80 {
81 departureTime = Time.max(departureTime, busSchedule.getDepartureTime(busStopId));
82 }
83 busSchedule.setActualDeparture(busStopId, stop.getConflictIds(), departureTime);
84 }
85 }
86
87
88 if (busSchedule.getActualDepartureBusStop(busStopId) == null
89 || now.lt(busSchedule.getActualDepartureBusStop(busStopId)))
90 {
91 if (stoppedAtStop)
92 {
93
94 simplePlan.minimizeAcceleration(Acceleration.ZERO);
95 }
96 else
97 {
98
99 simplePlan.minimizeAcceleration(
100 CarFollowingUtil.stop(carFollowingModel, params, speed, speedLimitInfo, stop.getDistance()));
101 }
102 }
103 }
104 }
105 }
106
107
108 @Override
109 public final String toString()
110 {
111 return "AccelerationBusStop";
112 }
113
114 }