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