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.Duration;
9 import org.opentrafficsim.base.DistancedObject;
10 import org.opentrafficsim.base.OtsRuntimeException;
11 import org.opentrafficsim.base.parameters.ParameterTypeDuration;
12 import org.opentrafficsim.core.gtu.perception.EgoPerception;
13 import org.opentrafficsim.road.gtu.LaneBasedGtu;
14 import org.opentrafficsim.road.gtu.perception.LanePerception;
15 import org.opentrafficsim.road.gtu.perception.RelativeLane;
16 import org.opentrafficsim.road.gtu.perception.categories.neighbors.NeighborsPerception;
17 import org.opentrafficsim.road.gtu.perception.mental.AbstractTask;
18 import org.opentrafficsim.road.gtu.perception.mental.ar.ArTaskCarFollowingExp;
19
20
21
22
23
24
25
26
27
28
29 public class ChannelTaskCarFollowing extends AbstractTask implements ChannelTask
30 {
31
32
33 public static final ParameterTypeDuration HEXP = ArTaskCarFollowingExp.HEXP;
34
35
36 private static final ChannelTaskCarFollowing DEFAULT = new ChannelTaskCarFollowing();
37
38
39 private static final Set<ChannelTask> SET = Set.of(DEFAULT);
40
41
42 public static final Function<LanePerception, Set<ChannelTask>> SUPPLIER = (p) -> SET;
43
44
45 private final Function<LanePerception, DistancedObject<LaneBasedGtu>> leaderSupplier;
46
47
48
49
50 public ChannelTaskCarFollowing()
51 {
52 this((perception) ->
53 {
54 NeighborsPerception neighbors = perception.getPerceptionCategoryOptional(NeighborsPerception.class)
55 .orElseThrow(() -> new NoSuchElementException("NeighborsPerception not present."));
56 Iterator<DistancedObject<LaneBasedGtu>> leader =
57 neighbors.getLeaders(RelativeLane.CURRENT).underlyingWithDistance();
58 if (!leader.hasNext())
59 {
60 return null;
61 }
62 return leader.next();
63 });
64 }
65
66
67
68
69
70 public ChannelTaskCarFollowing(final Function<LanePerception, DistancedObject<LaneBasedGtu>> leaderSupplier)
71 {
72 super("car-following (front)");
73 this.leaderSupplier = leaderSupplier;
74 }
75
76 @Override
77 public String getId()
78 {
79 return "car-following (front)";
80 }
81
82 @Override
83 public Object getChannel()
84 {
85 return FRONT;
86 }
87
88 @Override
89 public double calculateTaskDemand(final LanePerception perception)
90 {
91 DistancedObject<LaneBasedGtu> leader = this.leaderSupplier.apply(perception);
92 if (leader == null)
93 {
94 return 0.0;
95 }
96 EgoPerception<?, ?> ego = perception.getPerceptionCategoryOptional(EgoPerception.class)
97 .orElseThrow(() -> new NoSuchElementException("EgoPerception not present."));
98 Duration headway = leader.distance().divide(ego.getSpeed());
99 Duration h = perception.getGtu().getParameters().getOptionalParameter(HEXP)
100 .orElseThrow(() -> new OtsRuntimeException("Parameter h_exp not present."));
101 return headway.si <= 0.0 ? 0.999 : Math.exp(-headway.si / h.si);
102 }
103
104 }