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 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 super("lane-changing");
39 this.lateralConsideration = lateralConsideration;
40 }
41
42
43 @Override
44 protected Duration getHeadway(final LanePerception perception, final LaneBasedGtu gtu, final Parameters parameters)
45 throws ParameterException
46 {
47 NeighborsPerception neighbors = Try.assign(() -> perception.getPerceptionCategory(NeighborsPerception.class),
48 "NeighborsPerception not available.");
49 double lat = Try.assign(() -> this.lateralConsideration.getConsideration(perception, gtu, parameters),
50 "Exception during lateral consideration.");
51 RelativeLane lane;
52 if (Math.abs(lat) < 1e-9)
53 {
54 return null;
55 }
56 if (lat < 0.0)
57 {
58 lane = RelativeLane.LEFT;
59 lat = -lat;
60 }
61 else
62 {
63 lane = RelativeLane.RIGHT;
64 }
65 if (neighbors.isGtuAlongside(lane.getLateralDirectionality()))
66 {
67 return Duration.ZERO;
68 }
69 Duration h1 = neighbors.getLeaders(lane).collect(new TaskHeadwayCollector(getSpeed()));
70 Duration h2 = neighbors.getFollowers(lane).collect(new TaskHeadwayCollector(getSpeed()));
71 if (h1 == null)
72 {
73 return h2 == null ? null : h2.divide(lat);
74 }
75 if (h2 == null)
76 {
77 return h1 == null ? null : h1.divide(lat);
78 }
79 if (h1.eq0() && h2.eq0())
80 {
81 return Duration.ZERO;
82 }
83 return Duration.instantiateSI(h1.si * h2.si / (lat * (h1.si + h2.si)));
84 }
85
86
87
88
89
90
91
92
93
94
95
96
97 public interface LateralConsideration
98 {
99
100
101 LateralConsideration DESIRE = new LateralConsideration()
102 {
103 @Override
104 public double getConsideration(final LanePerception perception, final LaneBasedGtu gtu, final Parameters parameters)
105 throws ParameterException, GtuException
106 {
107 double dLeft = gtu.getParameters().getParameter(LmrsParameters.DLEFT);
108 double dRight = gtu.getParameters().getParameter(LmrsParameters.DRIGHT);
109 if (dLeft > dRight && dLeft > 0.0)
110 {
111 return dLeft > 1.0 ? -1.0 : -dLeft;
112 }
113 else if (dRight > dLeft && dRight > 0.0)
114 {
115 return dRight > 1.0 ? 1.0 : dRight;
116 }
117 return 0.0;
118 }
119 };
120
121
122
123
124
125
126
127
128
129
130
131 double getConsideration(LanePerception perception, LaneBasedGtu gtu, Parameters parameters)
132 throws ParameterException, GtuException;
133 }
134
135 }