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 @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 if (perception.getLaneStructure().exists(lane) && neighbors.isGtuAlongside(lane.getLateralDirectionality()))
65 {
66 return Duration.ZERO;
67 }
68 Duration h1 = neighbors.getLeaders(lane).collect(new TaskHeadwayCollector(getSpeed()));
69 Duration h2 = neighbors.getFollowers(lane).collect(new TaskHeadwayCollector(getSpeed()));
70 if (h1 == null)
71 {
72 return h2 == null ? null : h2.divide(lat);
73 }
74 if (h2 == null)
75 {
76 return h1 == null ? null : h1.divide(lat);
77 }
78 if (h1.eq0() && h2.eq0())
79 {
80 return Duration.ZERO;
81 }
82 return Duration.instantiateSI(h1.si * h2.si / (lat * (h1.si + h2.si)));
83 }
84
85
86
87
88
89
90
91
92
93
94
95
96 public interface LateralConsideration
97 {
98
99
100 LateralConsideration DESIRE = new LateralConsideration()
101 {
102 @Override
103 public double getConsideration(final LanePerception perception, final LaneBasedGtu gtu, final Parameters parameters)
104 throws ParameterException, GtuException
105 {
106 double dLeft = gtu.getParameters().getParameter(LmrsParameters.DLEFT);
107 double dRight = gtu.getParameters().getParameter(LmrsParameters.DRIGHT);
108 if (dLeft > dRight && dLeft > 0.0)
109 {
110 return dLeft > 1.0 ? -1.0 : -dLeft;
111 }
112 else if (dRight > dLeft && dRight > 0.0)
113 {
114 return dRight > 1.0 ? 1.0 : dRight;
115 }
116 return 0.0;
117 }
118 };
119
120
121
122
123
124
125
126
127
128
129
130 double getConsideration(LanePerception perception, LaneBasedGtu gtu, Parameters parameters)
131 throws ParameterException, GtuException;
132 }
133
134 }