1 package org.opentrafficsim.road.gtu.lane.perception.mental.channel;
2
3 import java.util.Iterator;
4 import java.util.Set;
5 import java.util.function.Function;
6
7 import org.djunits.value.vdouble.scalar.Length;
8 import org.djunits.value.vdouble.scalar.Speed;
9 import org.djutils.exceptions.Try;
10 import org.opentrafficsim.base.parameters.ParameterTypeLength;
11 import org.opentrafficsim.base.parameters.ParameterTypeSpeed;
12 import org.opentrafficsim.base.parameters.ParameterTypes;
13 import org.opentrafficsim.core.gtu.Stateless;
14 import org.opentrafficsim.core.gtu.perception.EgoPerception;
15 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
16 import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
17 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
18 import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable.UnderlyingDistance;
19 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
20 import org.opentrafficsim.road.gtu.lane.perception.categories.IntersectionPerception;
21 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
22 import org.opentrafficsim.road.gtu.lane.perception.mental.AbstractTask;
23
24
25
26
27
28
29
30
31
32
33
34 public class ChannelTaskAcceleration extends AbstractTask implements ChannelTask, Stateless<ChannelTaskAcceleration>
35 {
36
37
38 public static final ParameterTypeLength X0 = ParameterTypes.LOOKAHEAD;
39
40
41 public static final ParameterTypeSpeed VCONG = ParameterTypes.VCONG;
42
43
44 public static final ChannelTaskAcceleration SINGLETON = new ChannelTaskAcceleration();
45
46
47 private static final Set<ChannelTask> SET = Set.of(SINGLETON);
48
49
50 public static final Function<LanePerception, Set<ChannelTask>> SUPPLIER = (p) -> SET;
51
52
53
54
55 public ChannelTaskAcceleration()
56 {
57 super("acceleration");
58 }
59
60 @Override
61 public ChannelTaskAcceleration get()
62 {
63 return SINGLETON;
64 }
65
66 @Override
67 public Object getChannel()
68 {
69 return FRONT;
70 }
71
72 @Override
73 public double calculateTaskDemand(final LanePerception perception)
74 {
75 NeighborsPerception neighbors = Try.assign(() -> perception.getPerceptionCategory(NeighborsPerception.class),
76 "NeighborsPerception not present.");
77 EgoPerception<?, ?> ego =
78 Try.assign(() -> perception.getPerceptionCategory(EgoPerception.class), "EgoPerception not present.");
79 Speed v = ego.getSpeed();
80 Speed vCong = Try.assign(() -> perception.getGtu().getParameters().getParameter(VCONG), "Parameter VCONG not present");
81 Length x0 = Try.assign(() -> perception.getGtu().getParameters().getParameter(X0), "Parameter LOOKAHEAD not present.");
82 Iterator<UnderlyingDistance<LaneBasedGtu>> leaders =
83 neighbors.getLeaders(RelativeLane.CURRENT).underlyingWithDistance();
84
85
86
87
88 Length limit = Length.POSITIVE_INFINITY;
89 try
90 {
91 var conflicts = perception.getPerceptionCategory(IntersectionPerception.class).getConflicts(RelativeLane.CURRENT);
92 if (!conflicts.isEmpty())
93 {
94 limit = conflicts.first().getDistance();
95 }
96 }
97 catch (OperationalPlanException ex)
98 {
99
100 }
101 double td = 0.0;
102 while (leaders.hasNext())
103 {
104 UnderlyingDistance<LaneBasedGtu> leader = leaders.next();
105 if (leader.distance().gt(limit))
106 {
107 break;
108 }
109 Speed vLead = leader.object().getSpeed();
110 Length s = leader.distance();
111 td = Math.max(td, Math.max(Math.min((vLead.si - v.si) / vCong.si, 1.0), 0.0) * (1.0 - s.si / x0.si));
112 }
113 return td >= 1.0 ? 0.999 : td;
114 }
115
116 }