1 package org.opentrafficsim.road.network.sampling.data;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import org.djunits.unit.DurationUnit;
7 import org.djunits.value.vdouble.scalar.Length;
8 import org.djunits.value.vdouble.scalar.Speed;
9 import org.djunits.value.vdouble.scalar.Time;
10 import org.djunits.value.vfloat.scalar.FloatDuration;
11 import org.opentrafficsim.core.gtu.GTUDirectionality;
12 import org.opentrafficsim.core.gtu.GTUException;
13 import org.opentrafficsim.core.gtu.RelativePosition;
14 import org.opentrafficsim.kpi.interfaces.GtuDataInterface;
15 import org.opentrafficsim.kpi.sampling.data.ExtendedDataTypeDuration;
16 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
17 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
18 import org.opentrafficsim.road.network.lane.Lane;
19 import org.opentrafficsim.road.network.sampling.GtuData;
20
21 import nl.tudelft.simulation.language.Throw;
22
23
24
25
26
27
28
29
30
31
32
33 public class TimeToCollision extends ExtendedDataTypeDuration
34 {
35
36
37
38
39 public TimeToCollision()
40 {
41 super("timeToCollision");
42 }
43
44
45 @Override
46 public final FloatDuration getValue(final GtuDataInterface gtu)
47 {
48 Throw.when(!(gtu instanceof GtuData), IllegalArgumentException.class,
49 "Extended data type ReferenceSpeed can only be used with GtuData.");
50 LaneBasedGTU gtuObj = ((GtuData) gtu).getGtu();
51 try
52 {
53 DirectedLanePosition ref = gtuObj.getReferencePosition();
54 Map<Lane, GTUDirectionality> map = new HashMap<>();
55 map.put(ref.getLane(), ref.getGtuDirection());
56 Length pos = ref.getPosition();
57 Length cumulDist = Length.ZERO;
58 Time now = gtuObj.getSimulator().getSimulatorTime().getTime();
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 cumulDist = cumulDist.plus(lane.getLength());
72 map = lane.downstreamLanes(dir, gtuObj.getGTUType());
73 }
74 else
75 {
76
77 if (next.getSpeed().ge(gtuObj.getSpeed()))
78 {
79 return new FloatDuration(Double.NaN, DurationUnit.SI);
80 }
81 Length ownPos = gtuObj.position(ref.getLane(), gtuObj.getFront());
82 Length nextPos = next.position(lane, next.getRear());
83 Length dist = nextPos.minus(ownPos).plus(cumulDist);
84 Speed dv = gtuObj.getSpeed().minus(next.getSpeed());
85 return new FloatDuration(dist.si / dv.si, DurationUnit.SI);
86 }
87 }
88 return new FloatDuration(Float.NaN, DurationUnit.SI);
89 }
90 catch (GTUException exception)
91 {
92
93 return new FloatDuration(Float.NaN, DurationUnit.SI);
94 }
95 }
96
97
98 @Override
99 public String toString()
100 {
101 return "TTC";
102 }
103
104 }