1 package org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil;
2
3 import java.util.Collection;
4 import java.util.Map;
5
6 import org.djunits.unit.AccelerationUnit;
7 import org.djunits.value.vdouble.scalar.Acceleration;
8 import org.djunits.value.vdouble.scalar.DoubleScalar;
9 import org.djunits.value.vdouble.scalar.Length;
10 import org.djunits.value.vdouble.scalar.Speed;
11 import org.opentrafficsim.core.gtu.GTUException;
12 import org.opentrafficsim.core.gtu.RelativePosition;
13 import org.opentrafficsim.core.network.LateralDirectionality;
14 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
15 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractGTUFollowingModelMobil;
16 import org.opentrafficsim.road.gtu.lane.tactical.following.DualAccelerationStep;
17 import org.opentrafficsim.road.gtu.lane.tactical.following.GTUFollowingModelOld;
18 import org.opentrafficsim.road.gtu.lane.tactical.following.HeadwayGTU;
19 import org.opentrafficsim.road.network.lane.Lane;
20
21
22
23
24
25
26
27
28
29
30
31
32 public abstract class AbstractLaneChangeModel implements LaneChangeModel
33 {
34
35 private static Acceleration extraThreshold = new Acceleration(0.000001, AccelerationUnit.SI);
36
37
38 @SuppressWarnings("checkstyle:parameternumber")
39 @Override
40 public final LaneMovementStep computeLaneChangeAndAcceleration(final LaneBasedGTU gtu,
41 final Collection<HeadwayGTU> sameLaneGTUs, final Collection<HeadwayGTU> preferredLaneGTUs,
42 final Collection<HeadwayGTU> nonPreferredLaneGTUs, final Speed speedLimit,
43 final Acceleration preferredLaneRouteIncentive, final Acceleration laneChangeThreshold,
44 final Acceleration nonPreferredLaneRouteIncentive)
45 {
46
47
48
49
50 try
51 {
52 Length.Rel headway = gtu.getBehavioralCharacteristics().getForwardHeadwayDistance();
53 Map<Lane, Length.Rel> positions = gtu.positions(RelativePosition.REFERENCE_POSITION);
54 Lane lane = positions.keySet().iterator().next();
55 Length.Rel longitudinalPosition = positions.get(lane);
56
57
58 final LateralDirectionality preferred = LateralDirectionality.RIGHT;
59 final LateralDirectionality nonPreferred = LateralDirectionality.LEFT;
60 Lane nonPreferredLane =
61 gtu.getPerception().bestAccessibleAdjacentLane(lane, nonPreferred, longitudinalPosition);
62 Lane preferredLane = gtu.getPerception().bestAccessibleAdjacentLane(lane, preferred, longitudinalPosition);
63 GTUFollowingModelOld gtuFollowingModel =
64 gtu.getStrategicalPlanner().getDrivingCharacteristics().getGTUFollowingModel();
65 if (null == gtuFollowingModel)
66 {
67 throw new Error(gtu + " has null GTUFollowingModel");
68 }
69 DualAccelerationStep straightAccelerationSteps =
70 gtuFollowingModel.computeDualAccelerationStep(gtu, sameLaneGTUs, headway, speedLimit);
71 if (straightAccelerationSteps.getLeaderAcceleration().getSI() < -9999)
72 {
73 System.out.println("Problem");
74 gtu.getStrategicalPlanner().getDrivingCharacteristics().getGTUFollowingModel()
75 .computeDualAccelerationStep(gtu, sameLaneGTUs, headway, speedLimit);
76 }
77 Acceleration straightA = applyDriverPersonality(straightAccelerationSteps).plus(laneChangeThreshold);
78 DualAccelerationStep nonPreferredAccelerationSteps =
79 null == nonPreferredLane ? null : gtu.getStrategicalPlanner().getDrivingCharacteristics()
80 .getGTUFollowingModel().computeDualAccelerationStep(gtu, nonPreferredLaneGTUs, headway, speedLimit);
81 if (null != nonPreferredAccelerationSteps
82 && nonPreferredAccelerationSteps.getFollowerAcceleration().getSI() < -gtu.getStrategicalPlanner()
83 .getDrivingCharacteristics().getGTUFollowingModel().getMaximumSafeDeceleration().getSI())
84 {
85 nonPreferredAccelerationSteps = AbstractGTUFollowingModelMobil.TOODANGEROUS;
86 }
87 if (null != nonPreferredAccelerationSteps
88 && nonPreferredAccelerationSteps.getLeaderAcceleration().getSI() < -gtu.getStrategicalPlanner()
89 .getDrivingCharacteristics().getGTUFollowingModel().getMaximumSafeDeceleration().getSI())
90 {
91 nonPreferredAccelerationSteps = AbstractGTUFollowingModelMobil.TOODANGEROUS;
92 }
93 Acceleration nonPreferredA =
94 null == nonPreferredLane ? null : applyDriverPersonality(nonPreferredAccelerationSteps);
95 DualAccelerationStep preferredAccelerationSteps =
96 null == preferredLane ? null : gtu.getStrategicalPlanner().getDrivingCharacteristics()
97 .getGTUFollowingModel().computeDualAccelerationStep(gtu, preferredLaneGTUs, headway, speedLimit);
98 if (null != preferredAccelerationSteps
99 && preferredAccelerationSteps.getFollowerAcceleration().getSI() < -gtu.getStrategicalPlanner()
100 .getDrivingCharacteristics().getGTUFollowingModel().getMaximumSafeDeceleration().getSI())
101 {
102 preferredAccelerationSteps = AbstractGTUFollowingModelMobil.TOODANGEROUS;
103 }
104 if (null != preferredAccelerationSteps
105 && preferredAccelerationSteps.getLeaderAcceleration().getSI() < -gtu.getStrategicalPlanner()
106 .getDrivingCharacteristics().getGTUFollowingModel().getMaximumSafeDeceleration().getSI())
107 {
108 preferredAccelerationSteps = AbstractGTUFollowingModelMobil.TOODANGEROUS;
109 }
110 Acceleration preferredA = null == preferredLane ? null : applyDriverPersonality(preferredAccelerationSteps);
111 if (null == preferredA)
112 {
113
114 if (null == nonPreferredA)
115 {
116
117 return new LaneMovementStep(straightAccelerationSteps.getLeaderAccelerationStep(), null);
118 }
119 else
120 {
121
122 if (DoubleScalar.plus(nonPreferredA, nonPreferredLaneRouteIncentive).gt(
123 straightA.plus(extraThreshold)))
124 {
125
126 return new LaneMovementStep(nonPreferredAccelerationSteps.getLeaderAccelerationStep(),
127 nonPreferred);
128 }
129 else
130 {
131
132 return new LaneMovementStep(straightAccelerationSteps.getLeaderAccelerationStep(), null);
133 }
134 }
135 }
136
137 if (null == nonPreferredA)
138 {
139
140 if (DoubleScalar.plus(preferredA, preferredLaneRouteIncentive).plus(extraThreshold).ge(straightA))
141 {
142
143 return new LaneMovementStep(preferredAccelerationSteps.getLeaderAccelerationStep(), preferred);
144 }
145 else
146 {
147
148 return new LaneMovementStep(straightAccelerationSteps.getLeaderAccelerationStep(), null);
149 }
150 }
151
152 Acceleration preferredAttractiveness =
153 preferredA.plus(preferredLaneRouteIncentive).minus(straightA).plus(extraThreshold);
154 Acceleration nonPreferredAttractiveness =
155 nonPreferredA.plus(nonPreferredLaneRouteIncentive).minus(straightA).minus(extraThreshold);
156 if (preferredAttractiveness.getSI() < 0 && nonPreferredAttractiveness.getSI() <= 0)
157 {
158
159 return new LaneMovementStep(straightAccelerationSteps.getLeaderAccelerationStep(), null);
160
161 }
162 if (preferredAttractiveness.getSI() >= 0 && preferredAttractiveness.gt(nonPreferredAttractiveness))
163 {
164
165 return new LaneMovementStep(preferredAccelerationSteps.getLeaderAccelerationStep(), preferred);
166 }
167
168 return new LaneMovementStep(nonPreferredAccelerationSteps.getLeaderAccelerationStep(), nonPreferred);
169 }
170 catch (GTUException exception)
171 {
172 throw new RuntimeException(exception);
173 }
174 }
175
176
177
178
179
180
181
182
183
184 public abstract Acceleration applyDriverPersonality(DualAccelerationStep accelerationSteps);
185 }