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