1 package org.opentrafficsim.road.gtu.tactical.lmrs;
2
3 import java.util.function.Supplier;
4
5 import org.djunits.value.vdouble.scalar.Acceleration;
6 import org.djunits.value.vdouble.scalar.Length;
7 import org.djunits.value.vdouble.scalar.Speed;
8 import org.opentrafficsim.base.parameters.ParameterException;
9 import org.opentrafficsim.base.parameters.ParameterTypeAcceleration;
10 import org.opentrafficsim.base.parameters.ParameterTypeSpeed;
11 import org.opentrafficsim.base.parameters.ParameterTypes;
12 import org.opentrafficsim.core.gtu.GtuException;
13 import org.opentrafficsim.core.network.LateralDirectionality;
14 import org.opentrafficsim.road.gtu.LaneBasedGtu;
15 import org.opentrafficsim.road.gtu.perception.FilteredIterable;
16 import org.opentrafficsim.road.gtu.perception.PerceptionCollectable;
17 import org.opentrafficsim.road.gtu.perception.RelativeLane;
18 import org.opentrafficsim.road.gtu.perception.categories.InfrastructurePerception;
19 import org.opentrafficsim.road.gtu.perception.categories.TrafficPerception;
20 import org.opentrafficsim.road.gtu.perception.categories.neighbors.NeighborsPerception;
21 import org.opentrafficsim.road.gtu.perception.object.PerceivedGtu;
22 import org.opentrafficsim.road.gtu.tactical.TacticalContextEgo;
23 import org.opentrafficsim.road.gtu.tactical.util.CarFollowingUtil;
24 import org.opentrafficsim.road.gtu.tactical.util.lmrs.Desire;
25
26
27
28
29
30
31
32
33
34
35
36 public final class AccelerationNoSlowLaneOvertake implements AccelerationIncentive
37 {
38
39
40 public static final ParameterTypeSpeed VCONG = ParameterTypes.VCONG;
41
42
43 public static final ParameterTypeAcceleration B0 = ParameterTypes.B0;
44
45
46 private Supplier<Desire> getMandatoryDesire;
47
48
49
50
51
52 public AccelerationNoSlowLaneOvertake(final Supplier<Desire> getMandatoryDesire)
53 {
54 this.getMandatoryDesire = getMandatoryDesire;
55 }
56
57 @Override
58 public Acceleration accelerate(final TacticalContextEgo context, final RelativeLane lane, final Length mergeDistance)
59 throws ParameterException, GtuException
60 {
61
62
63 if (!lane.isCurrent() || !context.getPerception().getLaneStructure().exists(lane.getLeft())
64 || this.getMandatoryDesire.get().right() > 0.0 || this.getMandatoryDesire.get().left() < 0.0)
65 {
66 return NO_REASON;
67 }
68
69 InfrastructurePerception infra = context.getPerception().getPerceptionCategory(InfrastructurePerception.class);
70 Length legal = infra.getLegalLaneChangePossibility(RelativeLane.LEFT, LateralDirectionality.RIGHT);
71 Length ignore = legal.lt0() ? legal.neg() : Length.ZERO;
72
73 if (lane.isCurrent() && context.getPerception().getLaneStructure().exists(RelativeLane.LEFT))
74 {
75 Speed vCong = context.getParameters().getParameter(VCONG);
76 if (context.getPerception().getPerceptionCategory(TrafficPerception.class).getSpeed(RelativeLane.CURRENT,
77 context.getDesiredSpeed()).si > vCong.si)
78 {
79
80 PerceptionCollectable<PerceivedGtu, LaneBasedGtu> leaders =
81 context.getPerception().getPerceptionCategory(NeighborsPerception.class).getLeaders(RelativeLane.LEFT);
82 if (!leaders.isEmpty())
83 {
84 for (PerceivedGtu leader : ignore.le0() ? leaders
85 : new FilteredIterable<>(leaders, (leader) -> leader.getDistance().gt(ignore)))
86 {
87 if (context.getSpeed().si > leader.getSpeed().si && leader.getDistance().gt0())
88 {
89 Acceleration b0 = context.getParameters().getParameter(B0);
90 Acceleration a = CarFollowingUtil.followSingleLeader(context, leader);
91 return a.si < -b0.si ? b0.neg() : a;
92 }
93 else
94 {
95
96 return NO_REASON;
97 }
98 }
99 }
100 }
101 }
102 return NO_REASON;
103 }
104
105 }