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