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