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