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