1 package org.opentrafficsim.road.gtu.lane.tactical.directedlanechange;
2
3 import java.util.Collection;
4 import java.util.Map;
5
6 import org.djunits.unit.AccelerationUnit;
7 import org.djunits.value.vdouble.scalar.Acceleration;
8 import org.djunits.value.vdouble.scalar.DoubleScalar;
9 import org.djunits.value.vdouble.scalar.Duration;
10 import org.djunits.value.vdouble.scalar.Length;
11 import org.djunits.value.vdouble.scalar.Speed;
12 import org.opentrafficsim.core.gtu.GTUException;
13 import org.opentrafficsim.core.gtu.RelativePosition;
14 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterException;
15 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterTypes;
16 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
17 import org.opentrafficsim.core.network.LateralDirectionality;
18 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
19 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
20 import org.opentrafficsim.road.gtu.lane.perception.categories.DefaultSimplePerception;
21 import org.opentrafficsim.road.gtu.lane.perception.headway.Headway;
22 import org.opentrafficsim.road.gtu.lane.tactical.AbstractLaneBasedTacticalPlanner;
23 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractGTUFollowingModelMobil;
24 import org.opentrafficsim.road.gtu.lane.tactical.following.DualAccelerationStep;
25 import org.opentrafficsim.road.gtu.lane.tactical.following.GTUFollowingModelOld;
26 import org.opentrafficsim.road.network.lane.Lane;
27
28
29
30
31
32
33
34
35
36
37
38
39 public abstract class AbstractDirectedLaneChangeModel implements DirectedLaneChangeModel
40 {
41
42 private static Acceleration extraThreshold = new Acceleration(0.000001, AccelerationUnit.SI);
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 Map<Lane, Length> positions = gtu.positions(RelativePosition.REFERENCE_POSITION);
65 Lane lane = positions.keySet().iterator().next();
66 Length longitudinalPosition = positions.get(lane);
67 Lane otherLane =
68 getPerception().getPerceptionCategory(DefaultSimplePerception.class).bestAccessibleAdjacentLane(lane, direction,
69 longitudinalPosition);
70 GTUFollowingModelOld gtuFollowingModel =
71 (GTUFollowingModelOld) ((AbstractLaneBasedTacticalPlanner) gtu.getTacticalPlanner()).getCarFollowingModel();
72 if (null == gtuFollowingModel)
73 {
74 throw new Error(gtu + " has null GTUFollowingModel");
75 }
76 DualAccelerationStep thisLaneAccelerationSteps =
77 gtuFollowingModel.computeDualAccelerationStep(gtu, sameLaneGTUs, maxDistance, speedLimit, laneChangeTime);
78 if (thisLaneAccelerationSteps.getLeaderAcceleration().getSI() < -9999)
79 {
80 System.out.println(gtu + " has a problem: straightAccelerationSteps.getLeaderAcceleration().getSI() < -9999");
81 }
82 Acceleration straightA = applyDriverPersonality(thisLaneAccelerationSteps).plus(laneChangeThreshold);
83 DualAccelerationStep otherLaneAccelerationSteps =
84 null == otherLane ? null : gtuFollowingModel.computeDualAccelerationStep(gtu, otherLaneGTUs, maxDistance,
85 speedLimit, laneChangeTime);
86 if (null != otherLaneAccelerationSteps
87 && otherLaneAccelerationSteps.getFollowerAcceleration().getSI() < -gtu.getBehavioralCharacteristics()
88 .getParameter(ParameterTypes.B).getSI())
89 {
90 otherLaneAccelerationSteps = AbstractGTUFollowingModelMobil.TOODANGEROUS;
91 }
92 Acceleration otherLaneAcceleration = null == otherLane ? null : applyDriverPersonality(otherLaneAccelerationSteps);
93 if (null == otherLaneAcceleration)
94 {
95
96 return new DirectedLaneMovementStep(thisLaneAccelerationSteps.getLeaderAccelerationStep(), null);
97 }
98
99 if (DoubleScalar.plus(otherLaneAcceleration, otherLaneRouteIncentive).plus(extraThreshold).ge(straightA))
100 {
101
102 return new DirectedLaneMovementStep(otherLaneAccelerationSteps.getLeaderAccelerationStep(), direction);
103 }
104 else
105 {
106
107 return new DirectedLaneMovementStep(thisLaneAccelerationSteps.getLeaderAccelerationStep(), null);
108 }
109 }
110
111
112
113
114
115
116
117
118
119 public abstract Acceleration applyDriverPersonality(DualAccelerationStep accelerationStep);
120
121
122 @Override
123 public final LanePerception getPerception()
124 {
125 return this.perception;
126 }
127 }