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