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