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