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