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