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 @Override
55 public final DirectedLaneMovementStep computeLaneChangeAndAcceleration(final LaneBasedGtu gtu,
56 final LateralDirectionality direction, final Collection<Headway> sameLaneGTUs,
57 final Collection<Headway> otherLaneGTUs, final Length maxDistance, final Speed speedLimit,
58 final Acceleration otherLaneRouteIncentive, final Acceleration laneChangeThreshold, final Duration laneChangeTime)
59 throws GtuException, ParameterException
60 {
61 Lane lane = gtu.getReferencePosition().lane();
62 Length longitudinalPosition = gtu.getReferencePosition().position();
63 Lane otherLane = getPerception().getPerceptionCategory(DefaultSimplePerception.class).bestAccessibleAdjacentLane(lane,
64 direction, longitudinalPosition);
65 GtuFollowingModelOld gtuFollowingModel = (GtuFollowingModelOld) gtu.getTacticalPlanner().getCarFollowingModel();
66 if (null == gtuFollowingModel)
67 {
68 throw new GtuException(gtu + " has null GtuFollowingModel");
69 }
70 DualAccelerationStep thisLaneAccelerationSteps =
71 gtuFollowingModel.computeDualAccelerationStep(gtu, sameLaneGTUs, maxDistance, speedLimit, laneChangeTime);
72 if (thisLaneAccelerationSteps.getLeaderAcceleration().getSI() < -9999)
73 {
74 System.out.println(gtu + " has a problem: straightAccelerationSteps.getLeaderAcceleration().getSI() < -9999");
75 }
76 Acceleration straightA = applyDriverPersonality(thisLaneAccelerationSteps).plus(laneChangeThreshold);
77 DualAccelerationStep otherLaneAccelerationSteps = null == otherLane ? null
78 : gtuFollowingModel.computeDualAccelerationStep(gtu, otherLaneGTUs, maxDistance, speedLimit, laneChangeTime);
79 if (null != otherLaneAccelerationSteps
80 && otherLaneAccelerationSteps.getFollowerAcceleration().getSI() < -gtu.getParameters().getParameter(B).getSI())
81 {
82 otherLane = null;
83 }
84 Acceleration otherLaneAcceleration = (null == otherLane) ? null : applyDriverPersonality(otherLaneAccelerationSteps);
85 if (null == otherLaneAcceleration)
86 {
87
88 return new DirectedLaneMovementStep(thisLaneAccelerationSteps.getLeaderAccelerationStep(), null);
89 }
90
91 if (DoubleScalar.plus(otherLaneAcceleration, otherLaneRouteIncentive).plus(extraThreshold).ge(straightA))
92 {
93
94 return new DirectedLaneMovementStep(otherLaneAccelerationSteps.getLeaderAccelerationStep(), direction);
95 }
96 else
97 {
98
99 return new DirectedLaneMovementStep(thisLaneAccelerationSteps.getLeaderAccelerationStep(), null);
100 }
101 }
102
103
104
105
106
107
108
109
110
111 public abstract Acceleration applyDriverPersonality(DualAccelerationStep accelerationStep);
112
113 @Override
114 public final LanePerception getPerception()
115 {
116 return this.perception;
117 }
118 }