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