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