1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import org.djunits.unit.DimensionlessUnit;
4 import org.djunits.value.vdouble.scalar.Acceleration;
5 import org.djunits.value.vdouble.scalar.Dimensionless;
6 import org.djunits.value.vdouble.scalar.Speed;
7 import org.opentrafficsim.base.parameters.ParameterException;
8 import org.opentrafficsim.base.parameters.ParameterTypeAcceleration;
9 import org.opentrafficsim.base.parameters.ParameterTypeSpeed;
10 import org.opentrafficsim.base.parameters.ParameterTypes;
11 import org.opentrafficsim.base.parameters.Parameters;
12 import org.opentrafficsim.core.gtu.Try;
13 import org.opentrafficsim.core.gtu.perception.EgoPerception;
14 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
15 import org.opentrafficsim.core.network.LateralDirectionality;
16 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
17 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
18 import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
19 import org.opentrafficsim.road.gtu.lane.perception.categories.TrafficPerception;
20 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
21 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
22 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
23 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class IncentiveSpeedWithCourtesy implements VoluntaryIncentive
48 {
49
50
51 protected static final ParameterTypeAcceleration A = ParameterTypes.A;
52
53
54 protected static final ParameterTypeSpeed VGAIN = LmrsParameters.VGAIN;
55
56
57 protected static final ParameterTypeSpeed VCONG = ParameterTypes.VCONG;
58
59
60 @Override
61 public final Desire determineDesire(final Parameters parameters, final LanePerception perception,
62 final CarFollowingModel carFollowingModel, final Desire mandatoryDesire, final Desire voluntaryDesire)
63 throws ParameterException, OperationalPlanException
64 {
65
66
67 InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
68 TrafficPerception traffic = perception.getPerceptionCategory(TrafficPerception.class);
69 EgoPerception ego = perception.getPerceptionCategory(EgoPerception.class);
70 double leftDist = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.LEFT).si;
71 double rightDist = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.RIGHT).si;
72
73
74 Speed vCur = traffic.getSpeed(RelativeLane.CURRENT);
75 Speed vGain = parameters.getParameter(VGAIN);
76
77
78 Dimensionless aGain;
79
80
81
82
83
84 Acceleration aCur = ego.getAcceleration();
85
86
87
88
89
90 aCur = Try.assign(() -> perception.getGtu().getCarFollowingAcceleration(), "Could not obtain the GTU.");
91 if (aCur.si > 0)
92 {
93 Acceleration a = parameters.getParameter(A);
94 aGain = a.minus(aCur).divideBy(a);
95 }
96 else
97 {
98 aGain = new Dimensionless(1, DimensionlessUnit.SI);
99 }
100
101
102 double dLeft;
103 if (leftDist > 0.0 && infra.getCrossSection().contains(RelativeLane.LEFT))
104 {
105 Speed vLeft = traffic.getSpeed(RelativeLane.LEFT);
106 dLeft = aGain.si * (vLeft.si - vCur.si) / vGain.si;
107 }
108 else
109 {
110 dLeft = 0.0;
111 }
112
113
114 double dRight;
115 if (rightDist > 0.0 && infra.getCrossSection().contains(RelativeLane.RIGHT))
116 {
117 Speed vRight = traffic.getSpeed(RelativeLane.RIGHT);
118 if (vCur.si >= parameters.getParameter(VCONG).si)
119 {
120 dRight = aGain.si * Math.min(vRight.si - vCur.si, 0) / vGain.si;
121 }
122 else
123 {
124 dRight = aGain.si * (vRight.si - vCur.si) / vGain.si;
125 }
126 }
127 else
128 {
129 dRight = 0.0;
130 }
131
132
133 return new Desire(dLeft, dRight);
134 }
135
136
137 @Override
138 public final String toString()
139 {
140 return "IncentiveSpeedWithCourtesy";
141 }
142
143 }