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