1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import java.util.SortedSet;
4
5 import org.djunits.value.vdouble.scalar.Speed;
6 import org.opentrafficsim.core.gtu.behavioralcharacteristics.BehavioralCharacteristics;
7 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterException;
8 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterTypes;
9 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
10 import org.opentrafficsim.road.gtu.lane.perception.InfrastructureLaneChangeInfo;
11 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
12 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
13 import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
14 import org.opentrafficsim.road.gtu.lane.perception.categories.NeighborsPerception;
15 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
16 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
17 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
18 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
19 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;
20
21
22
23
24
25
26
27
28
29
30
31
32
33 public class IncentiveGetInLane implements MandatoryIncentive
34 {
35
36
37 @Override
38 public Desire determineDesire(final BehavioralCharacteristics behavioralCharacteristics, final LanePerception perception,
39 final CarFollowingModel carFollowingModel, final Desire mandatoryDesire)
40 throws ParameterException, OperationalPlanException
41 {
42
43 Speed vCong = behavioralCharacteristics.getParameter(ParameterTypes.VCONG);
44 double hierarchy = behavioralCharacteristics.getParameter(LmrsParameters.HIERARCHY);
45 InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
46 NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
47 SortedSet<InfrastructureLaneChangeInfo> info = infra.getInfrastructureLaneChangeInfo(RelativeLane.CURRENT);
48 double dCur = info.isEmpty() ? Double.POSITIVE_INFINITY
49 : info.first().getRemainingDistance().si / info.first().getRequiredNumberOfLaneChanges();
50 double left = 0;
51 double right = 0;
52 double vCur = Double.POSITIVE_INFINITY;
53
54 for (RelativeLane lane : new RelativeLane[] { RelativeLane.LEFT, RelativeLane.RIGHT })
55 {
56 if (infra.getCrossSection().contains(lane))
57 {
58 SortedSet<InfrastructureLaneChangeInfo> adjInfo = infra.getInfrastructureLaneChangeInfo(lane);
59 double dAdj = adjInfo.isEmpty() ? Double.POSITIVE_INFINITY
60 : adjInfo.first().getRemainingDistance().si / adjInfo.first().getRequiredNumberOfLaneChanges();
61 if (!info.isEmpty() && !info.first().isDeadEnd() && dCur < dAdj)
62 {
63 double v = Double.POSITIVE_INFINITY;
64 for (HeadwayGTU neighbor : neighbors.getLeaders(lane))
65 {
66 v = Math.min(v, neighbor.getSpeed().si);
67 }
68 if (lane.isLeft())
69 {
70 double d = Math.max(0.0, 1.0 - v / vCong.si);
71 left += d;
72
73 }
74 else
75 {
76 double d = Math.max(0.0, 1.0 - v / vCong.si);
77 right += d;
78
79 }
80 }
81 if (!adjInfo.isEmpty() && !adjInfo.first().isDeadEnd()
82 && (info.isEmpty() || (!info.isEmpty() && !info.first().isDeadEnd())) && dCur > dAdj)
83 {
84 if (Double.isInfinite(vCur))
85 {
86 for (HeadwayGTU neighbor : neighbors.getLeaders(RelativeLane.CURRENT))
87 {
88 vCur = Math.min(vCur, neighbor.getSpeed().si);
89 }
90 }
91 if (lane.isLeft())
92 {
93 left -= Math.max(0.0, 1.0 - vCur / vCong.si);
94 }
95 else
96 {
97 right -= Math.max(0.0, 1.0 - vCur / vCong.si);
98 }
99 }
100 }
101 }
102 return new Desire(left * hierarchy, right * hierarchy);
103 }
104
105
106 @Override
107 public final String toString()
108 {
109 return "IncentiveGetInLane";
110 }
111
112 }