1 package org.opentrafficsim.road.gtu.lane.tactical.directedlanechange;
2
3 import java.util.Collection;
4
5 import org.djunits.unit.AccelerationUnit;
6 import org.djunits.value.vdouble.scalar.Acceleration;
7 import org.djunits.value.vdouble.scalar.DoubleScalar;
8 import org.djunits.value.vdouble.scalar.Duration;
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.ParameterTypes;
14 import org.opentrafficsim.core.gtu.GTUException;
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.following.DualAccelerationStep;
22 import org.opentrafficsim.road.gtu.lane.tactical.following.GTUFollowingModelOld;
23 import org.opentrafficsim.road.network.lane.Lane;
24
25
26
27
28
29
30
31
32
33
34
35
36 public abstract class AbstractDirectedLaneChangeModel implements DirectedLaneChangeModel
37 {
38
39 private static Acceleration extraThreshold = new Acceleration(0.000001, AccelerationUnit.SI);
40
41
42 protected static final ParameterTypeAcceleration B = ParameterTypes.B;
43
44
45 private final LanePerception perception;
46
47
48
49
50
51 public AbstractDirectedLaneChangeModel(final LanePerception perception)
52 {
53 this.perception = perception;
54 }
55
56
57 @Override
58 public final DirectedLaneMovementStep computeLaneChangeAndAcceleration(final LaneBasedGTU gtu,
59 final LateralDirectionality direction, final Collection<Headway> sameLaneGTUs,
60 final Collection<Headway> otherLaneGTUs, final Length maxDistance, final Speed speedLimit,
61 final Acceleration otherLaneRouteIncentive, final Acceleration laneChangeThreshold, final Duration laneChangeTime)
62 throws GTUException, ParameterException, OperationalPlanException
63 {
64 Lane lane = gtu.getReferencePosition().getLane();
65 Length longitudinalPosition = gtu.getReferencePosition().getPosition();
66 Lane otherLane = getPerception().getPerceptionCategory(DefaultSimplePerception.class).bestAccessibleAdjacentLane(lane,
67 direction, longitudinalPosition);
68 GTUFollowingModelOld gtuFollowingModel = (GTUFollowingModelOld) gtu.getTacticalPlanner().getCarFollowingModel();
69 if (null == gtuFollowingModel)
70 {
71 throw new GTUException(gtu + " has null GTUFollowingModel");
72 }
73 DualAccelerationStep thisLaneAccelerationSteps =
74 gtuFollowingModel.computeDualAccelerationStep(gtu, sameLaneGTUs, maxDistance, speedLimit, laneChangeTime);
75 if (thisLaneAccelerationSteps.getLeaderAcceleration().getSI() < -9999)
76 {
77 System.out.println(gtu + " has a problem: straightAccelerationSteps.getLeaderAcceleration().getSI() < -9999");
78 }
79 Acceleration straightA = applyDriverPersonality(thisLaneAccelerationSteps).plus(laneChangeThreshold);
80 DualAccelerationStep otherLaneAccelerationSteps = null == otherLane ? null
81 : gtuFollowingModel.computeDualAccelerationStep(gtu, otherLaneGTUs, maxDistance, speedLimit, laneChangeTime);
82 if (null != otherLaneAccelerationSteps && otherLaneAccelerationSteps.getFollowerAcceleration()
83 .getSI() < -gtu.getParameters().getParameter(B).getSI())
84 {
85 otherLane = null;
86 }
87 Acceleration otherLaneAcceleration = (null == otherLane) ? null : applyDriverPersonality(otherLaneAccelerationSteps);
88 if (null == otherLaneAcceleration)
89 {
90
91 return new DirectedLaneMovementStep(thisLaneAccelerationSteps.getLeaderAccelerationStep(), null);
92 }
93
94 if (DoubleScalar.plus(otherLaneAcceleration, otherLaneRouteIncentive).plus(extraThreshold).ge(straightA))
95 {
96
97 return new DirectedLaneMovementStep(otherLaneAccelerationSteps.getLeaderAccelerationStep(), direction);
98 }
99 else
100 {
101
102 return new DirectedLaneMovementStep(thisLaneAccelerationSteps.getLeaderAccelerationStep(), null);
103 }
104 }
105
106
107
108
109
110
111
112
113
114 public abstract Acceleration applyDriverPersonality(DualAccelerationStep accelerationStep);
115
116
117 @Override
118 public final LanePerception getPerception()
119 {
120 return this.perception;
121 }
122 }