1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import java.util.SortedSet;
4
5 import org.djunits.value.vdouble.scalar.Length;
6 import org.djunits.value.vdouble.scalar.Speed;
7 import org.opentrafficsim.base.parameters.ParameterException;
8 import org.opentrafficsim.base.parameters.ParameterTypeDuration;
9 import org.opentrafficsim.base.parameters.ParameterTypeLength;
10 import org.opentrafficsim.base.parameters.ParameterTypes;
11 import org.opentrafficsim.base.parameters.Parameters;
12 import org.opentrafficsim.core.gtu.Stateless;
13 import org.opentrafficsim.core.gtu.perception.EgoPerception;
14 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
15 import org.opentrafficsim.core.network.LateralDirectionality;
16 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
17 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
18 import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
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.MandatoryIncentive;
22 import org.opentrafficsim.road.network.LaneChangeInfo;
23
24
25
26
27
28
29
30
31
32
33
34
35
36 public final class IncentiveRoute implements MandatoryIncentive, Stateless<IncentiveRoute>
37 {
38
39
40 protected static final ParameterTypeLength LOOKAHEAD = ParameterTypes.LOOKAHEAD;
41
42
43 public static final ParameterTypeDuration T0 = ParameterTypes.T0;
44
45
46 public static final IncentiveRoute SINGLETON = new IncentiveRoute();
47
48 @Override
49 public IncentiveRoute get()
50 {
51 return SINGLETON;
52 }
53
54
55
56
57 private IncentiveRoute()
58 {
59
60 }
61
62 @Override
63 public Desire determineDesire(final Parameters parameters, final LanePerception perception,
64 final CarFollowingModel carFollowingModel, final Desire mandatoryDesire)
65 throws ParameterException, OperationalPlanException
66 {
67 Speed speed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
68 InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
69
70
71 SortedSet<LaneChangeInfo> currentInfo = infra.getLegalLaneChangeInfo(RelativeLane.CURRENT);
72 Length currentFirst = currentInfo.isEmpty() || currentInfo.first().numberOfLaneChanges() == 0 ? Length.POSITIVE_INFINITY
73 : currentInfo.first().remainingDistance();
74 double dCurr = getDesireToLeave(parameters, infra, RelativeLane.CURRENT, speed);
75 double dLeft = 0;
76 if (perception.getLaneStructure().exists(RelativeLane.LEFT)
77 && infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.LEFT).neg().lt(currentFirst))
78 {
79
80 dLeft = getDesireToLeave(parameters, infra, RelativeLane.LEFT, speed);
81
82 dLeft = dLeft < dCurr ? dCurr : dLeft > dCurr ? -dLeft : 0;
83 }
84 double dRigh = 0;
85 if (perception.getLaneStructure().exists(RelativeLane.RIGHT) && infra
86 .getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.RIGHT).neg().lt(currentFirst))
87 {
88
89 dRigh = getDesireToLeave(parameters, infra, RelativeLane.RIGHT, speed);
90
91 dRigh = dRigh < dCurr ? dCurr : dRigh > dCurr ? -dRigh : 0;
92 }
93 return new Desire(dLeft, dRigh);
94 }
95
96
97
98
99
100
101
102
103
104
105
106 private static double getDesireToLeave(final Parameters params, final InfrastructurePerception infra,
107 final RelativeLane lane, final Speed speed) throws ParameterException, OperationalPlanException
108 {
109 double dOut = 0.0;
110 if (infra.getCrossSection().contains(lane))
111 {
112 for (LaneChangeInfo info : infra.getLegalLaneChangeInfo(lane))
113 {
114 double d = info.remainingDistance().lt0() ? info.numberOfLaneChanges()
115 : getDesireToLeave(params, info.remainingDistance(), info.numberOfLaneChanges(), speed);
116 dOut = d > dOut ? d : dOut;
117 }
118 }
119 return dOut;
120 }
121
122
123
124
125
126
127
128
129
130
131 public static double getDesireToLeave(final Parameters params, final Length x, final int n, final Speed v)
132 throws ParameterException
133 {
134 double d1 = 1 - x.si / (n * params.getParameter(LOOKAHEAD).si);
135 double d2 = 1 - (x.si / v.si) / (n * params.getParameter(T0).si);
136 d1 = d2 > d1 ? d2 : d1;
137 return d1 < 0 ? 0 : d1;
138 }
139
140 @Override
141 public String toString()
142 {
143 return "IncentiveRoute";
144 }
145
146 }