1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import org.djunits.value.vdouble.scalar.Acceleration;
4 import org.djunits.value.vdouble.scalar.Length;
5 import org.djunits.value.vdouble.scalar.Speed;
6 import org.opentrafficsim.base.parameters.ParameterException;
7 import org.opentrafficsim.base.parameters.ParameterTypeAcceleration;
8 import org.opentrafficsim.base.parameters.ParameterTypeDouble;
9 import org.opentrafficsim.base.parameters.ParameterTypes;
10 import org.opentrafficsim.base.parameters.Parameters;
11 import org.opentrafficsim.core.gtu.Stateless;
12 import org.opentrafficsim.core.gtu.perception.EgoPerception;
13 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
14 import org.opentrafficsim.core.network.LateralDirectionality;
15 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
16 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
17 import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
18 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
19 import org.opentrafficsim.road.gtu.lane.perception.object.PerceivedGtu;
20 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
21 import org.opentrafficsim.road.gtu.lane.tactical.util.CarFollowingUtil;
22 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
23 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
24 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsUtil;
25 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
26 import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public final class IncentiveCourtesy implements VoluntaryIncentive, Stateless<IncentiveCourtesy>
42 {
43
44
45 protected static final ParameterTypeAcceleration B = ParameterTypes.B;
46
47
48 protected static final ParameterTypeDouble SOCIO = LmrsParameters.SOCIO;
49
50
51 public static final IncentiveCourtesy SINGLETON = new IncentiveCourtesy();
52
53 @Override
54 public IncentiveCourtesy get()
55 {
56 return SINGLETON;
57 }
58
59
60
61
62 private IncentiveCourtesy()
63 {
64
65 }
66
67 @Override
68 public Desire determineDesire(final Parameters parameters, final LanePerception perception,
69 final CarFollowingModel carFollowingModel, final Desire mandatoryDesire, final Desire voluntaryDesire)
70 throws ParameterException, OperationalPlanException
71 {
72
73 double dLeftYes = 0;
74 double dRightYes = 0;
75 double dLeftNo = 0;
76 double dRightNo = 0;
77 double socio = parameters.getParameter(SOCIO);
78 Acceleration b = parameters.getParameter(B);
79 NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
80 Speed ownSpeed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
81 InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
82 SpeedLimitInfo sli = infra.getSpeedLimitProspect(RelativeLane.CURRENT).getSpeedLimitInfo(Length.ZERO);
83 boolean leftLane = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.LEFT).si > 0.0;
84 boolean rightLane = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.RIGHT).si > 0.0;
85 for (LateralDirectionality dir : new LateralDirectionality[] {LateralDirectionality.LEFT, LateralDirectionality.RIGHT})
86 {
87 Iterable<PerceivedGtu> leaders = neighbors.getLeaders(new RelativeLane(dir, 1));
88 if (leaders != null)
89 {
90 for (PerceivedGtu leader : leaders)
91 {
92 double desire = dir.isLeft() ? leader.getBehavior().rightLaneChangeDesire()
93 : leader.getBehavior().leftLaneChangeDesire();
94 if (desire > 0)
95 {
96
97 Acceleration a =
98 CarFollowingUtil.followSingleLeader(carFollowingModel, parameters, ownSpeed, sli, leader);
99 if (a.lt0())
100 {
101 double d = desire * Math.min(-a.si / b.si, 1.0);
102 if (dir.isLeft() && rightLane)
103 {
104
105 dRightYes = dRightYes > d ? dRightYes : d;
106 }
107 else if (leftLane)
108 {
109
110 dLeftYes = dLeftYes > d ? dLeftYes : d;
111 }
112 }
113 }
114 }
115 }
116
117 Iterable<PerceivedGtu> followers = neighbors.getFollowers(new RelativeLane(dir, 2));
118 if (followers != null)
119 {
120 for (PerceivedGtu follower : followers)
121 {
122 Parameters params = follower.getBehavior().getParameters();
123 double desire = dir.isLeft() ? follower.getBehavior().rightLaneChangeDesire()
124 : follower.getBehavior().leftLaneChangeDesire();
125 Acceleration a = follower.getDistance().lt0() ? b.neg()
126 : LmrsUtil.singleAcceleration(follower.getDistance(), follower.getSpeed(), ownSpeed, desire, params,
127 follower.getBehavior().getSpeedLimitInfo(), follower.getBehavior().getCarFollowingModel());
128 if (a.lt0())
129 {
130 if (desire > 0)
131 {
132 double d = desire * Math.min(-a.si / b.si, 1.0);
133 if (dir.isLeft() && leftLane)
134 {
135
136 dLeftNo = dLeftNo > d ? dLeftNo : d;
137 }
138 else if (rightLane)
139 {
140
141 dRightNo = dRightNo > d ? dRightNo : d;
142 }
143 }
144 }
145 else
146 {
147
148 break;
149 }
150 }
151 }
152 leaders = neighbors.getLeaders(new RelativeLane(dir, 2));
153 if (leaders != null)
154 {
155 for (PerceivedGtu leader : leaders)
156 {
157 Parameters params = leader.getBehavior().getParameters();
158 double desire = dir.isLeft() ? leader.getBehavior().rightLaneChangeDesire()
159 : leader.getBehavior().leftLaneChangeDesire();
160 if (desire > 0)
161 {
162 Acceleration a = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(), desire,
163 params, sli, carFollowingModel);
164 if (a.lt0())
165 {
166 double d = desire * Math.min(-a.si / b.si, 1.0);
167 if (dir.isLeft() && leftLane)
168 {
169
170 dLeftNo = dLeftNo > d ? dLeftNo : d;
171 }
172 else if (rightLane)
173 {
174
175 dRightNo = dRightNo > d ? dRightNo : d;
176 }
177 }
178 }
179 }
180 }
181 }
182
183 dLeftYes *= socio;
184 dRightYes *= socio;
185 return new Desire(dLeftYes - dLeftNo, dRightYes - dRightNo);
186
187 }
188
189 @Override
190 public String toString()
191 {
192 return "IncentiveCourtesy";
193 }
194
195 }