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