1 package org.opentrafficsim.road.gtu.lane.perception.mental;
2
3 import org.djunits.value.vdouble.scalar.Duration;
4 import org.opentrafficsim.base.parameters.ParameterException;
5 import org.opentrafficsim.base.parameters.Parameters;
6 import org.opentrafficsim.core.gtu.GTUException;
7 import org.opentrafficsim.core.gtu.Try;
8 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
9 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
10 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
11 import org.opentrafficsim.road.gtu.lane.perception.categories.NeighborsPerception;
12 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
13
14
15
16
17
18
19
20
21
22
23
24
25
26 public class TaskLaneChanging extends TaskHeadwayBased
27 {
28
29
30 private final LateralConsideration lateralConsideration;
31
32
33
34
35
36 public TaskLaneChanging(final LateralConsideration lateralConsideration)
37 {
38 this.lateralConsideration = lateralConsideration;
39 }
40
41
42 @Override
43 protected Duration getHeadway(final LanePerception perception, final LaneBasedGTU gtu, final Parameters parameters)
44 throws ParameterException
45 {
46 NeighborsPerception neighbors = Try.assign(() -> perception.getPerceptionCategory(NeighborsPerception.class),
47 "NeighborsPerception not available.");
48 double lat = Try.assign(() -> this.lateralConsideration.getConsideration(perception, gtu, parameters),
49 "Exception during lateral consideration.");
50 RelativeLane lane;
51 if (Math.abs(lat) < 1e-9)
52 {
53 return null;
54 }
55 if (lat < 0.0)
56 {
57 lane = RelativeLane.LEFT;
58 lat = -lat;
59 }
60 else
61 {
62 lane = RelativeLane.RIGHT;
63 }
64 Try.execute(() -> neighbors.updateGtuAlongside(lane.getLateralDirectionality()), "Exception while updating alongside.");
65 if (neighbors.isGtuAlongside(lane.getLateralDirectionality()))
66 {
67 return Duration.ZERO;
68 }
69 Try.execute(() -> neighbors.updateLeaders(lane), "Exception while updating adjacent leaders.");
70 Try.execute(() -> neighbors.updateFollowers(lane), "Exception while updating adjacent followers.");
71 Duration h1 = neighbors.getLeaders(lane).collect(new TaskHeadwayCollector(getSpeed()));
72 Duration h2 = neighbors.getFollowers(lane).collect(new TaskHeadwayCollector(getSpeed()));
73 if (h1 == null)
74 {
75 return h2 == null ? null : h2.divideBy(lat);
76 }
77 if (h2 == null)
78 {
79 return h1 == null ? null : h1.divideBy(lat);
80 }
81 if (h1.eq0() && h2.eq0())
82 {
83 return Duration.ZERO;
84 }
85 return Duration.createSI(h1.si * h2.si / (lat * (h1.si + h2.si)));
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100 public interface LateralConsideration
101 {
102
103
104 LateralConsideration DESIRE = new LateralConsideration()
105 {
106 @Override
107 public double getConsideration(final LanePerception perception, final LaneBasedGTU gtu, final Parameters parameters)
108 throws ParameterException, GTUException
109 {
110 double dLeft = gtu.getParameters().getParameter(LmrsParameters.DLEFT);
111 double dRight = gtu.getParameters().getParameter(LmrsParameters.DRIGHT);
112 if (dLeft > dRight && dLeft > 0.0)
113 {
114 return dLeft > 1.0 ? -1.0 : -dLeft;
115 }
116 else if (dRight > dLeft && dRight > 0.0)
117 {
118 return dRight > 1.0 ? 1.0 : dRight;
119 }
120 return 0.0;
121 }
122 };
123
124
125
126
127
128
129
130
131
132
133 double getConsideration(LanePerception perception, LaneBasedGTU gtu, Parameters parameters)
134 throws ParameterException, GTUException;
135 }
136
137 }