Visual Servoing Platform
version 3.7.0
Toggle main menu visibility
Loading...
Searching...
No Matches
vpStatisticalTestShewhart.cpp
1
/*
2
* ViSP, open source Visual Servoing Platform software.
3
* Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4
*
5
* This software is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
9
* See the file LICENSE.txt at the root directory of this source
10
* distribution for additional information about the GNU GPL.
11
*
12
* For using ViSP with software that can not be combined with the GNU
13
* GPL, please contact Inria about acquiring a ViSP Professional
14
* Edition License.
15
*
16
* See https://visp.inria.fr for more information.
17
*
18
* This software was developed at:
19
* Inria Rennes - Bretagne Atlantique
20
* Campus Universitaire de Beaulieu
21
* 35042 Rennes Cedex
22
* France
23
*
24
* If you have questions regarding the use of this file, please contact
25
* Inria at visp@inria.fr
26
*
27
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29
*/
30
38
39
#include <visp3/core/vpStatisticalTestShewhart.h>
40
41
#include<cstring>
42
#include<sstream>
43
44
#include <visp3/core/vpException.h>
45
#include <visp3/core/vpMath.h>
46
47
BEGIN_VISP_NAMESPACE
48
const
unsigned
int
vpStatisticalTestShewhart::NB_DATA_SIGNAL
;
49
50
#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_17)
51
const
std::vector<bool>
vpStatisticalTestShewhart::CONST_ALL_WECO_ACTIVATED
= std::vector<bool>(
vpStatisticalTestShewhart::COUNT_WECO
-1,
true
);
52
#endif
53
54
std::string
vpStatisticalTestShewhart::vpWecoRulesAlarmToString
(
const
vpStatisticalTestShewhart::vpWecoRulesAlarm
&alarm)
55
{
56
std::string name;
57
switch
(alarm) {
58
case
THREE_SIGMA_WECO
:
59
name =
"3-sigma alarm"
;
60
break
;
61
case
TWO_SIGMA_WECO
:
62
name =
"2-sigma alarm"
;
63
break
;
64
case
ONE_SIGMA_WECO
:
65
name =
"1-sigma alarm"
;
66
break
;
67
case
SAME_SIDE_WECO
:
68
name =
"Same-side alarm"
;
69
break
;
70
case
NONE_WECO
:
71
name =
"No alarm"
;
72
break
;
73
case
COUNT_WECO
:
74
default
:
75
name =
"Unknown WECO alarm"
;
76
}
77
return
name;
78
}
79
80
void
vpStatisticalTestShewhart::computeLimits
()
81
{
82
float
delta = 3.f *
m_stdev
;
83
m_limitDown
=
m_mean
- delta;
84
m_limitUp
=
m_mean
+ delta;
85
m_oneSigmaNegLim
=
m_mean
-
m_stdev
;
86
m_oneSigmaPosLim
=
m_mean
+
m_stdev
;
87
m_twoSigmaNegLim
=
m_mean
- 2.f *
m_stdev
;
88
m_twoSigmaPosLim
=
m_mean
+ 2.f *
m_stdev
;
89
}
90
91
vpStatisticalTestAbstract::vpMeanDriftType
vpStatisticalTestShewhart::detectDownwardMeanDrift
()
92
{
93
if
(
m_nbDataInBuffer
<
NB_DATA_SIGNAL
) {
94
return
vpStatisticalTestAbstract::MEAN_DRIFT_NONE
;
95
}
96
if
((
m_signal_vec
[
m_idCurrentData
] <=
m_limitDown
) &&
m_activatedWECOrules
[
THREE_SIGMA_WECO
]) {
97
m_alarm
=
THREE_SIGMA_WECO
;
98
return
vpStatisticalTestAbstract::MEAN_DRIFT_DOWNWARD
;
99
}
100
if
(!
m_activateWECOrules
) {
101
return
vpStatisticalTestAbstract::MEAN_DRIFT_NONE
;
102
}
103
vpStatisticalTestAbstract::vpMeanDriftType
result =
vpStatisticalTestAbstract::MEAN_DRIFT_NONE
;
104
unsigned
int
id
=
vpMath::modulo
(
m_idCurrentData
- (
NB_DATA_SIGNAL
- 1),
NB_DATA_SIGNAL
);
105
unsigned
int
i = 0;
106
unsigned
int
nbAboveMean = 0;
107
unsigned
int
nbAbove2SigmaLimit = 0;
108
unsigned
int
nbAbove1SigmaLimit = 0;
109
while
(i <
NB_DATA_SIGNAL
) {
110
// Reinit for next iteration
111
nbAbove2SigmaLimit = 0;
112
nbAbove1SigmaLimit = 0;
113
if
(
m_signal_vec
[
id
] <
m_mean
&&
m_activatedWECOrules
[
SAME_SIDE_WECO
]) {
114
// Single-side test
115
++nbAboveMean;
116
}
117
if
(i > 3 &&
m_activatedWECOrules
[
TWO_SIGMA_WECO
]) {
118
// Two sigma test
119
for
(
unsigned
int
idPrev =
vpMath::modulo
(
id
- 2,
NB_DATA_SIGNAL
); idPrev != id; idPrev =
vpMath::modulo
(idPrev + 1,
NB_DATA_SIGNAL
)) {
120
if
(
m_signal_vec
[idPrev] <=
m_twoSigmaNegLim
) {
121
++nbAbove2SigmaLimit;
122
}
123
}
124
if
(
m_signal_vec
[
id
] <=
m_twoSigmaNegLim
) {
125
++nbAbove2SigmaLimit;
126
}
127
if
(nbAbove2SigmaLimit >= 2) {
128
break
;
129
}
130
}
131
if
(i > 5 &&
m_activatedWECOrules
[
ONE_SIGMA_WECO
]) {
132
// One sigma test
133
for
(
unsigned
int
idPrev =
vpMath::modulo
(
id
- 4,
NB_DATA_SIGNAL
); idPrev != id; idPrev =
vpMath::modulo
(idPrev + 1,
NB_DATA_SIGNAL
)) {
134
if
(
m_signal_vec
[idPrev] <=
m_oneSigmaNegLim
) {
135
++nbAbove1SigmaLimit;
136
}
137
}
138
if
(
m_signal_vec
[
id
] <=
m_oneSigmaNegLim
) {
139
++nbAbove1SigmaLimit;
140
}
141
if
(nbAbove1SigmaLimit >= 4) {
142
break
;
143
}
144
}
145
id
=
vpMath::modulo
(
id
+ 1,
NB_DATA_SIGNAL
);
146
++i;
147
}
148
if
(nbAboveMean ==
NB_DATA_SIGNAL
) {
149
m_alarm
=
SAME_SIDE_WECO
;
150
result =
MEAN_DRIFT_DOWNWARD
;
151
}
152
else
if
(nbAbove2SigmaLimit >= 2) {
153
m_alarm
=
TWO_SIGMA_WECO
;
154
result =
MEAN_DRIFT_DOWNWARD
;
155
}
156
else
if
(nbAbove1SigmaLimit >= 4) {
157
m_alarm
=
ONE_SIGMA_WECO
;
158
result =
MEAN_DRIFT_DOWNWARD
;
159
}
160
return
result;
161
}
162
163
vpStatisticalTestAbstract::vpMeanDriftType
vpStatisticalTestShewhart::detectUpwardMeanDrift
()
164
{
165
if
(
m_nbDataInBuffer
<
NB_DATA_SIGNAL
) {
166
return
vpStatisticalTestAbstract::MEAN_DRIFT_NONE
;
167
}
168
if
((
m_signal_vec
[
m_idCurrentData
] >=
m_limitUp
) &&
m_activatedWECOrules
[
THREE_SIGMA_WECO
]) {
169
m_alarm
=
THREE_SIGMA_WECO
;
170
return
vpStatisticalTestAbstract::MEAN_DRIFT_UPWARD
;
171
}
172
if
(!
m_activateWECOrules
) {
173
return
vpStatisticalTestAbstract::MEAN_DRIFT_NONE
;
174
}
175
vpStatisticalTestAbstract::vpMeanDriftType
result =
vpStatisticalTestAbstract::MEAN_DRIFT_NONE
;
176
unsigned
int
id
=
vpMath::modulo
(
m_idCurrentData
- (
NB_DATA_SIGNAL
- 1),
NB_DATA_SIGNAL
);
177
unsigned
int
i = 0;
178
unsigned
int
nbAboveMean = 0;
179
unsigned
int
nbAbove2SigmaLimit = 0;
180
unsigned
int
nbAbove1SigmaLimit = 0;
181
while
(i <
NB_DATA_SIGNAL
) {
182
// Reinit for next iteration
183
nbAbove2SigmaLimit = 0;
184
nbAbove1SigmaLimit = 0;
185
if
(
m_signal_vec
[
id
] >
m_mean
&&
m_activatedWECOrules
[
SAME_SIDE_WECO
]) {
186
// Single-side test
187
++nbAboveMean;
188
}
189
if
(i > 3 &&
m_activatedWECOrules
[
TWO_SIGMA_WECO
]) {
190
// Two sigma test
191
for
(
unsigned
int
idPrev =
vpMath::modulo
(
id
- 2,
NB_DATA_SIGNAL
); idPrev != id; idPrev =
vpMath::modulo
(idPrev + 1,
NB_DATA_SIGNAL
)) {
192
if
(
m_signal_vec
[idPrev] >=
m_twoSigmaPosLim
) {
193
++nbAbove2SigmaLimit;
194
}
195
}
196
if
(
m_signal_vec
[
id
] >=
m_twoSigmaPosLim
) {
197
++nbAbove2SigmaLimit;
198
}
199
if
(nbAbove2SigmaLimit >= 2) {
200
break
;
201
}
202
}
203
if
(i > 5 &&
m_activatedWECOrules
[
ONE_SIGMA_WECO
]) {
204
// One sigma test
205
for
(
unsigned
int
idPrev =
vpMath::modulo
(
id
- 4,
NB_DATA_SIGNAL
); idPrev != id; idPrev =
vpMath::modulo
(idPrev + 1,
NB_DATA_SIGNAL
)) {
206
if
(
m_signal_vec
[idPrev] >=
m_oneSigmaPosLim
) {
207
++nbAbove1SigmaLimit;
208
}
209
}
210
if
(
m_signal_vec
[
id
] >=
m_oneSigmaPosLim
) {
211
++nbAbove1SigmaLimit;
212
}
213
if
(nbAbove1SigmaLimit >= 4) {
214
break
;
215
}
216
}
217
id
=
vpMath::modulo
(
id
+ 1,
NB_DATA_SIGNAL
);
218
++i;
219
}
220
if
(nbAboveMean ==
NB_DATA_SIGNAL
) {
221
m_alarm
=
SAME_SIDE_WECO
;
222
result =
MEAN_DRIFT_UPWARD
;
223
}
224
else
if
(nbAbove2SigmaLimit >= 2) {
225
m_alarm
=
TWO_SIGMA_WECO
;
226
result =
MEAN_DRIFT_UPWARD
;
227
}
228
else
if
(nbAbove1SigmaLimit >= 4) {
229
m_alarm
=
ONE_SIGMA_WECO
;
230
result =
MEAN_DRIFT_UPWARD
;
231
}
232
return
result;
233
}
234
235
bool
vpStatisticalTestShewhart::updateStatistics
(
const
float
&signal)
236
{
237
bool
areStatsAvailable =
vpStatisticalTestAbstract::updateStatistics
(signal);
238
updateTestSignals
(signal);
// Store the signal in the circular buffer too.
239
if
(areStatsAvailable) {
240
computeLimits
();
241
}
242
return
areStatsAvailable;
243
}
244
245
void
vpStatisticalTestShewhart::updateTestSignals
(
const
float
&signal)
246
{
247
m_idCurrentData
= (
m_idCurrentData
+ 1) %
NB_DATA_SIGNAL
;
248
m_signal_vec
[
m_idCurrentData
] = signal;
249
if
(
m_nbDataInBuffer
<
NB_DATA_SIGNAL
) {
250
++
m_nbDataInBuffer
;
251
}
252
}
253
254
vpStatisticalTestShewhart::vpStatisticalTestShewhart
(
const
bool
&activateWECOrules,
const
std::vector<bool> &activatedRules,
const
unsigned
int
&nbSamplesForStats)
255
:
vpStatisticalTestSigma
(3, nbSamplesForStats)
256
,
m_nbDataInBuffer
(0)
257
,
m_activateWECOrules
(activateWECOrules)
258
,
m_idCurrentData
(0)
259
,
m_alarm
(
NONE_WECO
)
260
,
m_oneSigmaNegLim
(0.f)
261
,
m_oneSigmaPosLim
(0.f)
262
,
m_twoSigmaNegLim
(0.f)
263
,
m_twoSigmaPosLim
(0.f)
264
{
265
init
(activateWECOrules, activatedRules, nbSamplesForStats);
266
}
267
268
vpStatisticalTestShewhart::vpStatisticalTestShewhart
(
const
bool
&activateWECOrules,
const
std::vector<bool> &activatedRules,
const
float
&mean,
const
float
&stdev)
269
:
vpStatisticalTestSigma
(3)
270
,
m_nbDataInBuffer
(0)
271
,
m_activateWECOrules
(activateWECOrules)
272
,
m_idCurrentData
(0)
273
,
m_alarm
(
NONE_WECO
)
274
,
m_oneSigmaNegLim
(0.f)
275
,
m_oneSigmaPosLim
(0.f)
276
,
m_twoSigmaNegLim
(0.f)
277
,
m_twoSigmaPosLim
(0.f)
278
{
279
init
(activateWECOrules, activatedRules, mean, stdev);
280
}
281
282
std::vector<float>
vpStatisticalTestShewhart::getSignals
()
const
283
{
284
std::vector<float> signals;
285
for
(
unsigned
int
i = 0; i <
NB_DATA_SIGNAL
; ++i) {
286
unsigned
int
id
=
vpMath::modulo
(
m_idCurrentData
- (
NB_DATA_SIGNAL
- i - 1),
NB_DATA_SIGNAL
);
287
signals.push_back(
m_signal_vec
[
id
]);
288
}
289
return
signals;
290
}
291
292
void
vpStatisticalTestShewhart::init
(
const
bool
&activateWECOrules,
const
std::vector<bool> &activatedRules,
const
unsigned
int
&nbSamplesForStats)
293
{
294
vpStatisticalTestSigma::init
(3.f, nbSamplesForStats);
295
m_nbDataInBuffer
= 0;
296
memset(
m_signal_vec
, 0,
NB_DATA_SIGNAL
*
sizeof
(
float
));
297
m_activateWECOrules
= activateWECOrules;
298
if
(activatedRules.size() !=
COUNT_WECO
- 1) {
299
std::stringstream errMsg;
300
errMsg <<
"Error: the expected number of rules is "
<<
COUNT_WECO
-1 <<
", the number given to the method is "
<< activatedRules.size() << std::endl;
301
throw
(
vpException
(
vpException::dimensionError
, errMsg.str()));
302
}
303
m_activatedWECOrules
= activatedRules;
304
m_idCurrentData
= 0;
305
m_alarm
=
NONE_WECO
;
306
m_oneSigmaNegLim
= 0.f;
307
m_oneSigmaPosLim
= 0.f;
308
m_twoSigmaNegLim
= 0.f;
309
m_twoSigmaPosLim
= 0.f;
310
}
311
312
void
vpStatisticalTestShewhart::init
(
const
bool
&activateWECOrules,
const
std::vector<bool> &activatedRules,
const
float
&mean,
const
float
&stdev)
313
{
314
vpStatisticalTestShewhart::init
(activateWECOrules, activatedRules, 30);
315
m_mean
= mean;
316
m_stdev
= stdev;
317
computeLimits
();
318
m_areStatisticsComputed
=
true
;
319
}
320
END_VISP_NAMESPACE
vpException
error that can be emitted by ViSP classes.
Definition
vpException.h:60
vpException::dimensionError
@ dimensionError
Bad dimension.
Definition
vpException.h:71
vpMath::modulo
static float modulo(const float &value, const float &modulo)
Gives the rest of value divided by modulo when the quotient can only be an integer.
Definition
vpMath.h:177
vpStatisticalTestAbstract::m_limitUp
float m_limitUp
Definition
vpStatisticalTestAbstract.h:117
vpStatisticalTestAbstract::vpMeanDriftType
vpMeanDriftType
Enum that indicates if a drift of the mean occurred.
Definition
vpStatisticalTestAbstract.h:70
vpStatisticalTestAbstract::MEAN_DRIFT_UPWARD
@ MEAN_DRIFT_UPWARD
Definition
vpStatisticalTestAbstract.h:73
vpStatisticalTestAbstract::MEAN_DRIFT_DOWNWARD
@ MEAN_DRIFT_DOWNWARD
Definition
vpStatisticalTestAbstract.h:72
vpStatisticalTestAbstract::MEAN_DRIFT_NONE
@ MEAN_DRIFT_NONE
Definition
vpStatisticalTestAbstract.h:71
vpStatisticalTestAbstract::init
void init()
(Re)Initialize the algorithm.
Definition
vpStatisticalTestAbstract.cpp:157
vpStatisticalTestAbstract::m_limitDown
float m_limitDown
Definition
vpStatisticalTestAbstract.h:116
vpStatisticalTestAbstract::updateStatistics
virtual bool updateStatistics(const float &signal)
Update m_s and if enough values are available, compute the mean, the standard deviation and the limit...
Definition
vpStatisticalTestAbstract.cpp:103
vpStatisticalTestAbstract::m_mean
float m_mean
Definition
vpStatisticalTestAbstract.h:118
vpStatisticalTestAbstract::m_stdev
float m_stdev
Definition
vpStatisticalTestAbstract.h:121
vpStatisticalTestAbstract::m_areStatisticsComputed
bool m_areStatisticsComputed
Definition
vpStatisticalTestAbstract.h:114
vpStatisticalTestShewhart::vpStatisticalTestShewhart
vpStatisticalTestShewhart(const bool &activateWECOrules=true, const std::vector< bool > &activatedRules=CONST_ALL_WECO_ACTIVATED, const unsigned int &nbSamplesForStats=30)
Construct a new vpStatisticalTestShewhart object.
Definition
vpStatisticalTestShewhart.cpp:254
vpStatisticalTestShewhart::updateStatistics
virtual bool updateStatistics(const float &signal) VP_OVERRIDE
Update m_s and if enough values are available, compute the mean, the standard deviation and the limit...
Definition
vpStatisticalTestShewhart.cpp:235
vpStatisticalTestShewhart::NB_DATA_SIGNAL
static const unsigned int NB_DATA_SIGNAL
Definition
vpStatisticalTestShewhart.h:100
vpStatisticalTestShewhart::detectUpwardMeanDrift
virtual vpMeanDriftType detectUpwardMeanDrift() VP_OVERRIDE
Detects if an upward mean drift occurred on the mean.
Definition
vpStatisticalTestShewhart.cpp:163
vpStatisticalTestShewhart::CONST_ALL_WECO_ACTIVATED
static VP_ATTRIBUTE_NO_DESTROY const std::vector< bool > CONST_ALL_WECO_ACTIVATED
Definition
vpStatisticalTestShewhart.h:96
vpStatisticalTestShewhart::detectDownwardMeanDrift
virtual vpMeanDriftType detectDownwardMeanDrift() VP_OVERRIDE
Detects if a downward mean drift occurred.
Definition
vpStatisticalTestShewhart.cpp:91
vpStatisticalTestShewhart::vpWecoRulesAlarm
vpWecoRulesAlarm
Definition
vpStatisticalTestShewhart.h:84
vpStatisticalTestShewhart::COUNT_WECO
@ COUNT_WECO
Definition
vpStatisticalTestShewhart.h:90
vpStatisticalTestShewhart::SAME_SIDE_WECO
@ SAME_SIDE_WECO
Definition
vpStatisticalTestShewhart.h:88
vpStatisticalTestShewhart::THREE_SIGMA_WECO
@ THREE_SIGMA_WECO
Definition
vpStatisticalTestShewhart.h:85
vpStatisticalTestShewhart::ONE_SIGMA_WECO
@ ONE_SIGMA_WECO
Definition
vpStatisticalTestShewhart.h:87
vpStatisticalTestShewhart::TWO_SIGMA_WECO
@ TWO_SIGMA_WECO
Definition
vpStatisticalTestShewhart.h:86
vpStatisticalTestShewhart::NONE_WECO
@ NONE_WECO
Definition
vpStatisticalTestShewhart.h:89
vpStatisticalTestShewhart::m_twoSigmaNegLim
float m_twoSigmaNegLim
Definition
vpStatisticalTestShewhart.h:114
vpStatisticalTestShewhart::updateTestSignals
virtual void updateTestSignals(const float &signal) VP_OVERRIDE
Update the test signals.
Definition
vpStatisticalTestShewhart.cpp:245
vpStatisticalTestShewhart::getSignals
std::vector< float > getSignals() const
Get the NB_DATA_SIGNAL last signal values, sorted from the latest [0] to the newest [NB_DATA_SIGNAL -...
Definition
vpStatisticalTestShewhart.cpp:282
vpStatisticalTestShewhart::m_activatedWECOrules
std::vector< bool > m_activatedWECOrules
Definition
vpStatisticalTestShewhart.h:107
vpStatisticalTestShewhart::m_oneSigmaPosLim
float m_oneSigmaPosLim
Definition
vpStatisticalTestShewhart.h:113
vpStatisticalTestShewhart::m_nbDataInBuffer
unsigned int m_nbDataInBuffer
Definition
vpStatisticalTestShewhart.h:103
vpStatisticalTestShewhart::m_idCurrentData
unsigned int m_idCurrentData
Definition
vpStatisticalTestShewhart.h:110
vpStatisticalTestShewhart::m_alarm
vpWecoRulesAlarm m_alarm
Definition
vpStatisticalTestShewhart.h:111
vpStatisticalTestShewhart::m_twoSigmaPosLim
float m_twoSigmaPosLim
Definition
vpStatisticalTestShewhart.h:115
vpStatisticalTestShewhart::m_signal_vec
float m_signal_vec[NB_DATA_SIGNAL]
Definition
vpStatisticalTestShewhart.h:104
vpStatisticalTestShewhart::computeLimits
virtual void computeLimits() VP_OVERRIDE
Compute the upper and lower limits of the test signal.
Definition
vpStatisticalTestShewhart.cpp:80
vpStatisticalTestShewhart::m_oneSigmaNegLim
float m_oneSigmaNegLim
Definition
vpStatisticalTestShewhart.h:112
vpStatisticalTestShewhart::vpWecoRulesAlarmToString
static std::string vpWecoRulesAlarmToString(const vpWecoRulesAlarm &alarm)
Definition
vpStatisticalTestShewhart.cpp:54
vpStatisticalTestShewhart::m_activateWECOrules
bool m_activateWECOrules
Definition
vpStatisticalTestShewhart.h:105
vpStatisticalTestSigma::vpStatisticalTestSigma
vpStatisticalTestSigma(const float &h=3.f, const unsigned int &nbSamplesForStats=30)
Construct a new vpStatisticalTestSigma object.
Definition
vpStatisticalTestSigma.cpp:83
BEGIN_VISP_NAMESPACE
Definition
vpMbtDistanceCircle.cpp:55
modules
core
src
math
misc
vpStatisticalTestShewhart.cpp
Generated by
1.17.0