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