1 package org.opentrafficsim.road.gtu.lane.perception.mental.sdm;
2
3 import org.djunits.unit.DurationUnit;
4 import org.djunits.value.vdouble.scalar.Duration;
5 import org.djunits.value.vdouble.scalar.Frequency;
6 import org.djutils.exceptions.Throw;
7 import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
8 import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
9 import org.opentrafficsim.road.gtu.lane.perception.mental.Task;
10
11 import nl.tudelft.simulation.jstats.distributions.DistLogNormal;
12 import nl.tudelft.simulation.jstats.streams.StreamInterface;
13
14
15
16
17
18
19
20
21
22
23
24 public class Distraction
25 {
26
27
28 private final String id;
29
30
31 private final String description;
32
33
34 private final Frequency frequency;
35
36
37 private final double exposure;
38
39
40 private final StreamInterface stream;
41
42
43 private final TaskSupplier taskSupplier;
44
45
46 private final ContinuousDistDoubleScalar.Rel<Duration, DurationUnit> dist;
47
48
49
50
51
52
53
54
55
56
57
58
59 public Distraction(final String id, final String description, final Frequency frequency, final double exposure,
60 final Duration averageDuration, final Duration stdDuration, final StreamInterface stream,
61 final TaskSupplier taskSupplier)
62 {
63 Throw.whenNull(id, "Id may not be null.");
64 Throw.whenNull(description, "Description may not be null.");
65 Throw.whenNull(frequency, "Frequency may not be null.");
66 Throw.whenNull(averageDuration, "Average duration may not be null.");
67 Throw.whenNull(stream, "Random stream may not be null.");
68 Throw.when(exposure < 0.0 || exposure > 1.0, IllegalArgumentException.class, "Exposure should be in the range [0...1]");
69 this.id = id;
70 this.description = description;
71 this.frequency = frequency;
72 this.exposure = exposure;
73 this.stream = stream;
74 this.taskSupplier = taskSupplier;
75
76 double var = stdDuration.si * stdDuration.si;
77 double avgSqrd = averageDuration.si * averageDuration.si;
78 double mu = Math.log(avgSqrd / Math.sqrt(var + avgSqrd));
79 double sigma = Math.sqrt(Math.log(var / avgSqrd + 1.0));
80 this.dist = new ContinuousDistDoubleScalar.Rel<>(new DistLogNormal(stream, mu, sigma), DurationUnit.SECOND);
81 }
82
83
84
85
86
87 public final String getId()
88 {
89 return this.id;
90 }
91
92
93
94
95
96 public final String getDescription()
97 {
98 return this.description;
99 }
100
101
102
103
104
105 public final boolean nextExposure()
106 {
107 return this.stream.nextDouble() <= this.exposure;
108 }
109
110
111
112
113
114 public final Duration nextInterArrival()
115 {
116 return Duration.instantiateSI(-Math.log(this.stream.nextDouble()) / this.frequency.si);
117 }
118
119
120
121
122
123 public final Duration nextDuration()
124 {
125 return this.dist.draw();
126 }
127
128
129
130
131
132
133 public final Task getTask(final LaneBasedGtu gtu)
134 {
135 return this.taskSupplier.getTask(gtu);
136 }
137
138
139 @Override
140 public String toString()
141 {
142 return "Distraction [id=" + this.id + ", description=" + this.description + ", frequency=" + this.frequency
143 + ", exposure=" + this.exposure + "]";
144 }
145
146 }