1 package org.opentrafficsim.road.network.sampling.data;
2
3 import java.util.HashMap;
4 import java.util.HashSet;
5 import java.util.Map;
6 import java.util.Set;
7
8 import org.djunits.unit.DurationUnit;
9 import org.djunits.value.vdouble.scalar.Length;
10 import org.djunits.value.vdouble.scalar.Speed;
11 import org.djunits.value.vdouble.scalar.Time;
12 import org.djunits.value.vfloat.scalar.FloatDuration;
13 import org.opentrafficsim.core.gtu.GTUDirectionality;
14 import org.opentrafficsim.core.gtu.GTUException;
15 import org.opentrafficsim.core.gtu.RelativePosition;
16 import org.opentrafficsim.kpi.sampling.data.ExtendedDataTypeDuration;
17 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
18 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
19 import org.opentrafficsim.road.network.lane.Lane;
20 import org.opentrafficsim.road.network.lane.LaneDirection;
21 import org.opentrafficsim.road.network.sampling.GtuData;
22
23
24
25
26
27
28
29
30
31
32
33
34 public class TimeToCollision extends ExtendedDataTypeDuration<GtuData>
35 {
36
37
38
39
40 public TimeToCollision()
41 {
42 super("timeToCollision");
43 }
44
45
46 @Override
47 public final FloatDuration getValue(final GtuData gtu)
48 {
49 LaneBasedGTU gtuObj = gtu.getGtu();
50 try
51 {
52 DirectedLanePosition ref = gtuObj.getReferencePosition();
53 Map<Lane, GTUDirectionality> map = new HashMap<>();
54 Set<LaneDirection> visited = new HashSet<>();
55 map.put(ref.getLane(), ref.getGtuDirection());
56 Length pos = ref.getPosition();
57 Length cumulDist = Length.ZERO;
58 Time now = gtuObj.getSimulator().getSimulatorTime();
59 LaneBasedGTU next = null;
60 while (map.size() == 1)
61 {
62 Lane lane = map.keySet().iterator().next();
63 GTUDirectionality dir = map.get(lane);
64 if (cumulDist.gt0())
65 {
66 pos = dir.isPlus() ? Length.ZERO : lane.getLength();
67 }
68 next = lane.getGtuAhead(pos, dir, RelativePosition.REAR, now);
69 if (next == null)
70 {
71 LaneDirection laneDir = new LaneDirection(lane, map.get(lane));
72 if (visited.contains(laneDir))
73 {
74 break;
75 }
76 visited.add(laneDir);
77 cumulDist = cumulDist.plus(lane.getLength());
78 map = lane.downstreamLanes(dir, gtuObj.getGTUType());
79 }
80 else
81 {
82
83 if (next.getSpeed().ge(gtuObj.getSpeed()))
84 {
85 return new FloatDuration(Double.NaN, DurationUnit.SI);
86 }
87 Length ownPos = gtuObj.position(ref.getLane(), gtuObj.getFront());
88 Length nextPos = next.position(lane, next.getRear());
89 Length dist = nextPos.minus(ownPos).plus(cumulDist);
90 Speed dv = gtuObj.getSpeed().minus(next.getSpeed());
91 return new FloatDuration(dist.si / dv.si, DurationUnit.SI);
92 }
93 }
94 return new FloatDuration(Float.NaN, DurationUnit.SI);
95 }
96 catch (@SuppressWarnings("unused") GTUException exception)
97 {
98
99 return new FloatDuration(Float.NaN, DurationUnit.SI);
100 }
101 }
102
103
104 @Override
105 public final String toString()
106 {
107 return "TTC";
108 }
109
110 }