Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
tutorial-meandrift.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2024 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
32
33#include <cstring> //std::memcpy
34
35#include <visp3/core/vpConfig.h>
36#include <visp3/core/vpGaussRand.h>
37#include <visp3/core/vpStatisticalTestEWMA.h>
38#include <visp3/core/vpStatisticalTestHinkley.h>
39#include <visp3/core/vpStatisticalTestMeanAdjustedCUSUM.h>
40#include <visp3/core/vpStatisticalTestShewhart.h>
41#include <visp3/core/vpStatisticalTestSigma.h>
42#include <visp3/gui/vpPlot.h>
43
44#ifdef ENABLE_VISP_NAMESPACE
45using namespace VISP_NAMESPACE_NAME;
46#endif
47
48#if defined(VISP_HAVE_DISPLAY)
49namespace TutorialMeanDrift
50{
52
56typedef enum TypeTest
57{
58 HINLKEY_TYPE_TEST = 0,
59 EWMA_TYPE_TEST = 1,
60 MEAN_ADJUSTED_CUSUM_TYPE_TEST = 2,
61 SHEWHART_TYPE_TEST = 3,
62 SIGMA_TYPE_TEST = 4,
63 COUNT_TYPE_TEST = 5,
64 UNKOWN_TYPE_TEST = COUNT_TYPE_TEST
65}TypeTest;
67
74std::string typeTestToString(const TypeTest &type)
75{
76 std::string result;
77 switch (type) {
78 case HINLKEY_TYPE_TEST:
79 result = "hinkley";
80 break;
81 case EWMA_TYPE_TEST:
82 result = "ewma";
83 break;
84 case MEAN_ADJUSTED_CUSUM_TYPE_TEST:
85 result = "cusum";
86 break;
87 case SHEWHART_TYPE_TEST:
88 result = "shewhart";
89 break;
90 case SIGMA_TYPE_TEST:
91 result = "sigma";
92 break;
93 case UNKOWN_TYPE_TEST:
94 default:
95 result = "unknown-type-test";
96 break;
97 }
98 return result;
99}
100
108TypeTest typeTestFromString(const std::string &name)
109{
110 TypeTest result = UNKOWN_TYPE_TEST;
111 unsigned int count = static_cast<unsigned int>(COUNT_TYPE_TEST);
112 unsigned int id = 0;
113 bool hasNotFound = true;
114 while ((id < count) && hasNotFound) {
115 TypeTest temp = static_cast<TypeTest>(id);
116 if (typeTestToString(temp) == name) {
117 result = temp;
118 hasNotFound = false;
119 }
120 ++id;
121 }
122 return result;
123}
124
133std::string getAvailableTypeTest(const std::string &prefix = "<", const std::string &sep = " , ",
134 const std::string &suffix = ">")
135{
136 std::string msg(prefix);
137 unsigned int count = static_cast<unsigned int>(COUNT_TYPE_TEST);
138 unsigned int lastId = count - 1;
139 for (unsigned int i = 0; i < lastId; i++) {
140 msg += typeTestToString(static_cast<TypeTest>(i)) + sep;
141 }
142 msg += typeTestToString(static_cast<TypeTest>(lastId)) + suffix;
143 return msg;
144}
145
153template <typename T>
154std::string numberToString(const T &number)
155{
156 std::stringstream ss;
157 ss << number;
158 return ss.str();
159}
160
167std::string boolToString(const bool &boolean)
168{
169 if (boolean) {
170 return "true";
171 }
172 else {
173 return "false";
174 }
175}
176
186std::string wecoRulesToString(const std::vector<bool> &rules, const std::string &prefix = "[", const std::string &suffix = "]", const std::string &sep = " , ")
187{
188 std::string rulesAsString = prefix;
189 for (unsigned int i = 0; i < rules.size() - 1; ++i) {
190 if (rules[i]) {
191 rulesAsString += "ON";
192 }
193 else {
194 rulesAsString += "OFF";
195 }
196 rulesAsString += sep;
197 }
198 if (rules[rules.size() - 1]) {
199 rulesAsString += "ON";
200 }
201 else {
202 rulesAsString += "OFF";
203 }
204 rulesAsString += suffix;
205 return rulesAsString;
206}
207
211const bool CONST_ALL_ALARM_OFF[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT] = { false, false, false, false };
212
216const bool CONST_ALL_ALARM_ON[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT] = { true, true, true, true };
217
225void vectorOfStringToMeanDriftTypeArray(const std::vector<std::string> &names, bool array[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT])
226{
227 std::memcpy(array, CONST_ALL_ALARM_OFF, vpStatisticalTestAbstract::MEAN_DRIFT_COUNT * sizeof(bool));
228 size_t nbNames = names.size();
229 for (size_t i = 0; i < nbNames; ++i) {
231 std::cout << "alarm[" << names[i] << "] (i.e. " << static_cast<unsigned int>(alarmToActivate) << ") set to true" << std::endl;
232 array[static_cast<unsigned int>(alarmToActivate)] = true;
233 if (alarmToActivate == vpStatisticalTestAbstract::MEAN_DRIFT_BOTH) {
236 }
237 }
240 }
241}
242
250std::vector<std::string> meanDriftArrayToVectorOfString(const bool array[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT])
251{
252 std::vector<std::string> listActivatedAlarms;
253 unsigned int nbTypeTests = static_cast<unsigned int>(vpStatisticalTestAbstract::MEAN_DRIFT_COUNT);
254 for (unsigned int id = 0; id < nbTypeTests; ++id) {
255 if (array[id]) {
257 std::string testName = vpStatisticalTestAbstract::vpMeanDriftTypeToString(test);
258 listActivatedAlarms.push_back(testName);
259 }
260 }
261 return listActivatedAlarms;
262}
263
274std::string meanDriftArrayToString(const bool array[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT],
275 const std::string &prefix = "[", const std::string &sep = " , ",
276 const std::string &suffix = "]")
277{
278 std::vector<std::string> listActivatedAlarms = meanDriftArrayToVectorOfString(array);
279 std::string result = prefix;
280 size_t nbTestActivated = listActivatedAlarms.size();
281 if (nbTestActivated == 0) {
282 return prefix + " " + suffix;
283 }
284 for (size_t i = 0; i < nbTestActivated - 1; ++i) {
285 result += listActivatedAlarms[i] + sep;
286 }
287 result += listActivatedAlarms[nbTestActivated - 1] + suffix;
288 return result;
289}
290
297unsigned int meanDriftArrayToNbActivated(const bool array[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT])
298{
299 unsigned int nbActivated = 0;
300 unsigned int nbTypeAlarms = static_cast<unsigned int>(vpStatisticalTestAbstract::MEAN_DRIFT_COUNT);
301 for (unsigned int id = 0; id < nbTypeAlarms; ++id) {
302 if (array[id]) {
303 ++nbActivated;
304 }
305 }
306 return nbActivated;
307}
308
309#ifndef DOXYGEN_SHOULD_SKIP_THIS
311
314typedef struct ParametersForAlgo
315{
316 unsigned int m_test_nbsamples;
317 bool m_test_activatedalarms[vpStatisticalTestAbstract::MEAN_DRIFT_COUNT];
318 unsigned int m_test_nbactivatedalarms;
319 float m_cusum_h;
320 float m_cusum_k;
321 float m_ewma_alpha;
322 float m_hinkley_alpha;
323 float m_hinkley_delta;
324 bool m_hinkley_computealphadelta;
325 float m_hinkley_h;
326 float m_hinkley_k;
327 bool m_shewhart_useWECO;
328 std::vector<bool> m_shewhart_rules;
329 float m_sigma_h;
330
331 ParametersForAlgo()
332 : m_test_nbsamples(30)
333 , m_cusum_h(4.76f)
334 , m_cusum_k(1.f)
335 , m_ewma_alpha(0.1f)
336 , m_hinkley_alpha(4.76f)
337 , m_hinkley_delta(1.f)
338 , m_hinkley_computealphadelta(false)
339 , m_hinkley_h(4.76f)
340 , m_hinkley_k(1.f)
341 , m_shewhart_useWECO(false)
342 , m_sigma_h(3.f)
343 {
345 memcpy(m_test_activatedalarms, CONST_ALL_ALARM_ON, vpStatisticalTestAbstract::MEAN_DRIFT_COUNT * sizeof(bool));
346 m_test_activatedalarms[vpStatisticalTestAbstract::MEAN_DRIFT_NONE] = false;
347 m_test_nbactivatedalarms = meanDriftArrayToNbActivated(m_test_activatedalarms);
348 }
349}ParametersForAlgo;
351}
352#endif // DOXYGEN_SHOULD_SKIP_THIS
353
354int testOnSynthetic(const TutorialMeanDrift::TypeTest &type, const TutorialMeanDrift::ParametersForAlgo parameters,
355 const float &mean, const float &mean_drift, const float &stdev)
356{
357 const float dt = 10.f; // Emulate a 10ms period
358
360 vpPlot plotter(1);
361 plotter.initGraph(0, 1);
362 plotter.setTitle(0, "Evolution of the signal");
363 plotter.setUnitX(0, "Frame ID");
364 plotter.setUnitY(0, "No units");
366
368 unsigned int idFrame = 0;
369 vpStatisticalTestAbstract *p_test = nullptr;
370 switch (type) {
371 case TutorialMeanDrift::EWMA_TYPE_TEST:
372 p_test = new vpStatisticalTestEWMA(parameters.m_ewma_alpha);
373 break;
374 case TutorialMeanDrift::HINLKEY_TYPE_TEST:
375 p_test = new vpStatisticalTestHinkley(parameters.m_hinkley_alpha, parameters.m_hinkley_delta, parameters.m_test_nbsamples);
376 break;
377 case TutorialMeanDrift::MEAN_ADJUSTED_CUSUM_TYPE_TEST:
378 p_test = new vpStatisticalTestMeanAdjustedCUSUM(parameters.m_cusum_h, parameters.m_cusum_k, parameters.m_test_nbsamples);
379 break;
380 case TutorialMeanDrift::SHEWHART_TYPE_TEST:
381 p_test = new vpStatisticalTestShewhart(parameters.m_shewhart_useWECO, parameters.m_shewhart_rules, parameters.m_test_nbsamples);
382 break;
383 case TutorialMeanDrift::SIGMA_TYPE_TEST:
384 p_test = new vpStatisticalTestSigma(parameters.m_sigma_h, parameters.m_test_nbsamples);
385 break;
386 default:
387 throw(vpException(vpException::badValue, TutorialMeanDrift::typeTestToString(type) + " is not handled."));
388 break;
389 }
390
391 if ((type == TutorialMeanDrift::HINLKEY_TYPE_TEST) && parameters.m_hinkley_computealphadelta) {
392 // Initialization of Hinkley's test in automatic mode
393 delete p_test;
394 p_test = new vpStatisticalTestHinkley(parameters.m_hinkley_h, parameters.m_hinkley_k, true, parameters.m_test_nbsamples);
395 }
397
398 float signal;
399
401 // Initial computation of the mean and stdev of the input signal
402 for (unsigned int i = 0; i < parameters.m_test_nbsamples; ++i) {
403 vpGaussRand rndGen(stdev, mean, static_cast<long>(idFrame * dt));
404 signal = static_cast<float>(rndGen());
405 p_test->testDownUpwardMeanDrift(signal);
406 ++idFrame;
407 }
409
410 std::cout << "Estimated mean of the input signal: " << p_test->getMean() << std::endl;
411 std::cout << "Estimated stdev of the input signal: " << p_test->getStdev() << std::endl;
412
414 float mean_eff = mean;
415 bool hasToRun = true;
417 while (hasToRun) {
418 vpGaussRand rndGen(stdev, mean_eff, static_cast<long>(idFrame * dt));
419 signal = static_cast<float>(rndGen());
420 plotter.plot(0, 0, idFrame - parameters.m_test_nbsamples, signal);
421 drift_type = p_test->testDownUpwardMeanDrift(signal);
422 if ((drift_type != vpStatisticalTestAbstract::MEAN_DRIFT_NONE) && (parameters.m_test_activatedalarms[drift_type])) {
423 hasToRun = false;
424 }
425 else {
426 mean_eff += mean_drift;
427 ++idFrame;
428 }
429 }
431
433 std::cout << "Test failed at frame: " << idFrame - parameters.m_test_nbsamples << std::endl;
434 std::cout << "Type of mean drift: " << vpStatisticalTestAbstract::vpMeanDriftTypeToString(drift_type) << std::endl;
435 std::cout << "Last signal value: " << signal << std::endl;
436 if (type == TutorialMeanDrift::EWMA_TYPE_TEST) {
437 vpStatisticalTestEWMA *p_testEwma = dynamic_cast<vpStatisticalTestEWMA *>(p_test);
438 std::cout << "\tw(t) = " << p_testEwma->getWt() << std::endl;
439 }
440 else if (type == TutorialMeanDrift::MEAN_ADJUSTED_CUSUM_TYPE_TEST) {
441 vpStatisticalTestMeanAdjustedCUSUM *p_testCusum = dynamic_cast<vpStatisticalTestMeanAdjustedCUSUM *>(p_test);
442 std::cout << "\tLower cusum = " << p_testCusum->getTestSignalMinus() << std::endl;
443 std::cout << "\tUpper cusum = " << p_testCusum->getTestSignalPlus() << std::endl;
444 }
445 else if (type==TutorialMeanDrift::SHEWHART_TYPE_TEST) {
446 vpStatisticalTestShewhart *p_testShewhart = dynamic_cast<vpStatisticalTestShewhart *>(p_test);
447 std::vector<float> signal = p_testShewhart->getSignals();
448 size_t nbSignal = signal.size();
449 std::cout << "Signal history = [ ";
450 for (size_t i = 0; i < nbSignal; ++i) {
451 std::cout << signal[i] << " ";
452 }
453 std::cout << "]" << std::endl;
454 std::cout << "\tWECO alarm type = " << vpStatisticalTestShewhart::vpWecoRulesAlarmToString(p_testShewhart->getAlarm()) << std::endl;
455 }
456 else if (type == TutorialMeanDrift::HINLKEY_TYPE_TEST) {
457 vpStatisticalTestHinkley *p_hinkley = dynamic_cast<vpStatisticalTestHinkley *>(p_test);
458 float Mk = p_hinkley->getMk();
459 float Nk = p_hinkley->getNk();
460 float Sk = p_hinkley->getSk();
461 float Tk = p_hinkley->getTk();
462 std::cout << "S+(t) = " << Tk - Nk <<std::endl;
463 std::cout << "S-(t) = " << Mk - Sk <<std::endl;
464 }
465 float limitDown = 0.f, limitUp = 0.f;
466 p_test->getLimits(limitDown, limitUp);
467 std::cout << "\tLimit down = " << limitDown << std::endl;
468 std::cout << "\tLimit up = " << limitUp << std::endl;
470 std::cout << "End of test on synthetic data. Press enter to leave." << std::endl;
471 std::cin.get();
472 delete p_test;
473 return EXIT_SUCCESS;
474}
475
476int main(int argc, char *argv[])
477{
478 TutorialMeanDrift::TypeTest opt_typeTest = TutorialMeanDrift::MEAN_ADJUSTED_CUSUM_TYPE_TEST;
479 TutorialMeanDrift::ParametersForAlgo parameters;
480 float opt_mean = 6.f;
481 float opt_meandrift = 0.f;
482 float opt_stdev = 2.f;
483
484 int i = 1;
485 while (i < argc) {
486 if ((std::string(argv[i]) == "--test") && ((i + 1) < argc)) {
487 opt_typeTest = TutorialMeanDrift::typeTestFromString(argv[i + 1]);
488 ++i;
489 }
490 else if ((std::string(argv[i]) == "--nb-samples") && ((i + 1) < argc)) {
491 parameters.m_test_nbsamples = std::atoi(argv[i + 1]);
492 ++i;
493 }
494 else if ((std::string(argv[i]) == "--mean") && ((i + 1) < argc)) {
495 opt_mean = static_cast<float>(std::atof(argv[i + 1]));
496 ++i;
497 }
498 else if ((std::string(argv[i]) == "--mean-drift") && ((i + 1) < argc)) {
499 opt_meandrift = static_cast<float>(std::atof(argv[i + 1]));
500 ++i;
501 }
502 else if ((std::string(argv[i]) == "--stdev") && ((i + 1) < argc)) {
503 opt_stdev = static_cast<float>(std::atof(argv[i + 1]));
504 ++i;
505 }
506 else if ((std::string(argv[i]) == "--alarms")) {
507 unsigned int nbArguments = 0;
508 std::vector<std::string> alarmNames;
509 bool hasNotFoundNextParams = true;
510 for (int j = 1; ((i + j) < argc) && hasNotFoundNextParams; ++j) {
511 std::string candidate(argv[i+j]);
512 if (candidate.find("--") != std::string::npos) {
513 // This is the next command line parameter
514 hasNotFoundNextParams = false;
515 }
516 else {
517 // This is a name
518 alarmNames.push_back(candidate);
519 ++nbArguments;
520 }
521 }
522 TutorialMeanDrift::vectorOfStringToMeanDriftTypeArray(alarmNames, parameters.m_test_activatedalarms);
523 parameters.m_test_nbactivatedalarms = TutorialMeanDrift::meanDriftArrayToNbActivated(parameters.m_test_activatedalarms);
524 i += nbArguments;
525 }
526 else if ((std::string(argv[i]) == "--cusum-h") && ((i + 1) < argc)) {
527 parameters.m_cusum_h = static_cast<float>(std::atof(argv[i + 1]));
528 ++i;
529 }
530 else if ((std::string(argv[i]) == "--cusum-k") && ((i + 1) < argc)) {
531 parameters.m_cusum_k = static_cast<float>(std::atof(argv[i + 1]));
532 ++i;
533 }
534 else if ((std::string(argv[i]) == "--ewma-alpha") && ((i + 1) < argc)) {
535 parameters.m_ewma_alpha = static_cast<float>(std::atof(argv[i + 1]));
536 ++i;
537 }
538 else if ((std::string(argv[i]) == "--hinkley-alpha") && ((i + 1) < argc)) {
539 parameters.m_hinkley_alpha = static_cast<float>(std::atof(argv[i + 1]));
540 ++i;
541 }
542 else if ((std::string(argv[i]) == "--hinkley-delta") && ((i + 1) < argc)) {
543 parameters.m_hinkley_delta = static_cast<float>(std::atof(argv[i + 1]));
544 ++i;
545 }
546 else if (std::string(argv[i]) == "--hinkley-compute") {
547 parameters.m_hinkley_computealphadelta = true;
548 }
549 else if ((std::string(argv[i]) == "--hinkley-h") && ((i + 1) < argc)) {
550 parameters.m_hinkley_h = static_cast<float>(std::atof(argv[i + 1]));
551 ++i;
552 }
553 else if ((std::string(argv[i]) == "--hinkley-k") && ((i + 1) < argc)) {
554 parameters.m_hinkley_k = static_cast<float>(std::atof(argv[i + 1]));
555 ++i;
556 }
557 else if ((std::string(argv[i]) == "--shewhart-rules") && (i + vpStatisticalTestShewhart::COUNT_WECO - 1 < argc)) {
558 for (int j = 0; j < vpStatisticalTestShewhart::COUNT_WECO - 1; ++j) {
559 std::string argument = std::string(argv[i + 1 + j]);
560 if ((argument.find("on") != std::string::npos) || (argument.find("ON") != std::string::npos)) {
561 parameters.m_shewhart_rules[j] = true;
562 }
563 else {
564 parameters.m_shewhart_rules[j] = false;
565 }
566 }
568 }
569 else if (std::string(argv[i]) == "--shewhart-weco") {
570 parameters.m_shewhart_useWECO = true;
571 }
572 else if ((std::string(argv[i]) == "--sigma-h") && ((i + 1) < argc)) {
573 parameters.m_sigma_h = static_cast<float>(std::atof(argv[i + 1]));
574 ++i;
575 }
576 else if ((std::string(argv[i]) == "--help") || (std::string(argv[i]) == "-h")) {
577 std::cout << "\nSYNOPSIS " << std::endl
578 << argv[0]
579 << " [--test <type>]"
580 << " [--nb-samples <value>]"
581 << " [--alarms <name_1 ... name_n>]"
582 << " [--mean <value>]"
583 << " [--mean-drift <value>]"
584 << " [--stdev <value>]"
585 << " [--cusum-h <value>]"
586 << " [--cusum-k <value>]"
587 << " [--ewma-alpha <value ]0; 1[>]"
588 << " [--hinkley-alpha <]0; inf[>]"
589 << " [--hinkley-delta <]0; inf[>]"
590 << " [--hinkley-compute]"
591 << " [--hinkley-h <]0; inf[>]"
592 << " [--hinkley-k <]0; inf[>]"
593 << " [--shewhart-rules <3-sigma:{on|off} 2-sigma:{on|off} 1-sigma:{on|off} same-side:{on|off}>"
594 << " [--shewhart-weco]"
595 << " [--sigma-h <value>]"
596 << " [--help,-h]" << std::endl;
597 std::cout << "\nOPTIONS " << std::endl
598 << " --test <type-name>" << std::endl
599 << " Type of test to perform on the data." << std::endl
600 << " Available values: " << TutorialMeanDrift::getAvailableTypeTest() << std::endl
601 << std::endl
602 << " --nb-samples <value>" << std::endl
603 << " Number of samples to compute the mean and standard deviation of the monitored signal." << std::endl
604 << " Default: " << parameters.m_test_nbsamples << std::endl
605 << std::endl
606 << " --alarms <name_1 .. name_n>" << std::endl
607 << " Set the mean drift alarms to monitor." << std::endl
608 << " Default: " << TutorialMeanDrift::meanDriftArrayToString(parameters.m_test_activatedalarms) << std::endl
609 << " Available: " << vpStatisticalTestAbstract::getAvailableMeanDriftType() << std::endl
610 << std::endl
611 << " --mean <value>" << std::endl
612 << " Mean of the signal." << std::endl
613 << " Default: " << opt_mean<< std::endl
614 << std::endl
615 << " --mean-drift <value>" << std::endl
616 << " Mean drift for the synthetic data." << std::endl
617 << " Default: " << opt_meandrift << std::endl
618 << std::endl
619 << " --stdev <value>" << std::endl
620 << " Standard deviation of the signal." << std::endl
621 << " Default: " << opt_stdev << std::endl
622 << std::endl
623 << " --cusum-h <value>" << std::endl
624 << " The alarm factor that permits to the CUSUM test to determine when the process is out of control" << std::endl
625 << " from the standard deviation of the signal." << std::endl
626 << " Default: " << parameters.m_cusum_h << std::endl
627 << std::endl
628 << " --cusum-k <value>" << std::endl
629 << " The factor that permits to determine the slack of the CUSUM test, " << std::endl
630 << " i.e. the minimum value of the jumps we want to detect, from the standard deviation of the signal." << std::endl
631 << " Default: " << parameters.m_cusum_k << std::endl
632 << std::endl
633 << " --ewma-alpha <value ]0; 1[>" << std::endl
634 << " Forgetting factor for the Exponential Weighted Moving Average (EWMA)." << std::endl
635 << " Default: " << parameters.m_ewma_alpha << std::endl
636 << std::endl
637 << " --hinkley-alpha <value ]0; inf[>" << std::endl
638 << " The alarm threshold indicating that a mean drift occurs for the Hinkley's test." << std::endl
639 << " Default: " << parameters.m_hinkley_alpha << std::endl
640 << std::endl
641 << " --hinkley-delta <value>" << std::endl
642 << " Detection threshold indicating minimal magnitude we want to detect for the Hinkley's test." << std::endl
643 << " Default: " << parameters.m_hinkley_delta << std::endl
644 << std::endl
645 << " --hinkley-compute" << std::endl
646 << " If set, the Hinkley's test will compute the alarm and detection thresholds" << std::endl
647 << " from the standard deviation of the input signal." << std::endl
648 << " Default: disabled" << std::endl
649 << std::endl
650 << " --hinkley-h <value>" << std::endl
651 << " Alarm factor permitting to compute the alarm threshold for the Hinkley's test." << std::endl
652 << " Default: " << parameters.m_hinkley_h << std::endl
653 << std::endl
654 << " --hinkley-k <value>" << std::endl
655 << " Detection factor permitting to compute the Detection threshold for the Hinkley's test." << std::endl
656 << " Default: " << parameters.m_hinkley_k << std::endl
657 << std::endl
658 << " --shewhart-rules <3-sigma:{on|off} 2-sigma:{on|off} 1-sigma:{on|off} same-side:{on|off}>" << std::endl
659 << " Choose the WECO additional tests for the Shewhart's test to use. To activate them, --shewart-weco must be used." << std::endl
660 << " Default: ON ON ON ON" << std::endl
661 << std::endl
662 << " --shewhart-weco" << std::endl
663 << " Activate the WECO additional tests for the Shewhart's test." << std::endl
664 << " Default: deactivated" << std::endl
665 << std::endl
666 << " --sigma-h <value>" << std::endl
667 << " The alarm factor of the sigma test." << std::endl
668 << " Default: " << parameters.m_sigma_h << std::endl
669 << std::endl
670 << " --help, -h" << std::endl
671 << " Display this helper message." << std::endl
672 << std::endl;
673 return EXIT_SUCCESS;
674 }
675 else {
676 std::cout << "\nERROR " << std::endl << " Unknown option " << argv[i] << std::endl;
677 return EXIT_FAILURE;
678 }
679 ++i;
680 }
681
682 if (parameters.m_test_nbactivatedalarms == 0) {
683 throw(vpException(vpException::badValue, "Error, at least one type of alarm must be monitored. See " + std::string(argv[0]) + " --help"));
684 return EXIT_FAILURE;
685 }
686
687 std::cout << " Activated statistical test : " << TutorialMeanDrift::typeTestToString(opt_typeTest) << std::endl;
688 std::cout << " Activated alarms : " << TutorialMeanDrift::meanDriftArrayToString(parameters.m_test_activatedalarms) << std::endl;
689 std::cout << " Nb samples for statistics computation: " << parameters.m_test_nbsamples << std::endl;
690 std::cout << " Alarm factor CUSUM test : " << (opt_typeTest == TutorialMeanDrift::MEAN_ADJUSTED_CUSUM_TYPE_TEST ? TutorialMeanDrift::numberToString(parameters.m_cusum_h) : "N/A") << std::endl;
691 std::cout << " Detection factor CUSUM test : " << (opt_typeTest == TutorialMeanDrift::MEAN_ADJUSTED_CUSUM_TYPE_TEST ? TutorialMeanDrift::numberToString(parameters.m_cusum_k) : "N/A") << std::endl;
692 std::cout << " Forgetting factor EWMA test : " << (opt_typeTest == TutorialMeanDrift::EWMA_TYPE_TEST ? TutorialMeanDrift::numberToString(parameters.m_ewma_alpha) : "N/A") << std::endl;
693 std::cout << " Alarm threshold Hinkley's test : " << ((opt_typeTest == TutorialMeanDrift::HINLKEY_TYPE_TEST) && (!parameters.m_hinkley_computealphadelta) ? TutorialMeanDrift::numberToString(parameters.m_hinkley_alpha) : "N/A") << std::endl;
694 std::cout << " Detection threshold Hinkley's test : " << ((opt_typeTest == TutorialMeanDrift::HINLKEY_TYPE_TEST) && (!parameters.m_hinkley_computealphadelta) ? TutorialMeanDrift::numberToString(parameters.m_hinkley_delta) : "N/A") << std::endl;
695 std::cout << " Alarm factor Hinkley's test : " << ((opt_typeTest == TutorialMeanDrift::HINLKEY_TYPE_TEST) && parameters.m_hinkley_computealphadelta ? TutorialMeanDrift::numberToString(parameters.m_hinkley_h) : "N/A") << std::endl;
696 std::cout << " Detection factor Hinkley's test : " << ((opt_typeTest == TutorialMeanDrift::HINLKEY_TYPE_TEST) && parameters.m_hinkley_computealphadelta ? TutorialMeanDrift::numberToString(parameters.m_hinkley_k) : "N/A") << std::endl;
697 std::cout << " Shewhart's test set of WECO rules : " << (parameters.m_shewhart_useWECO && (opt_typeTest == TutorialMeanDrift::SHEWHART_TYPE_TEST) ? TutorialMeanDrift::wecoRulesToString(parameters.m_shewhart_rules) : "N/A") << std::endl;
698 std::cout << " Shewhart's test use WECO rules : " << (opt_typeTest == TutorialMeanDrift::SHEWHART_TYPE_TEST ? TutorialMeanDrift::boolToString(parameters.m_shewhart_useWECO && (opt_typeTest == TutorialMeanDrift::SHEWHART_TYPE_TEST)) : "N/A") << std::endl;
699 std::cout << " Alarm factor Sigma test : " << (opt_typeTest == TutorialMeanDrift::SIGMA_TYPE_TEST ? TutorialMeanDrift::numberToString(parameters.m_sigma_h) : "N/A") << std::endl;
700 std::cout << " Actual mean of the input signal: " << opt_mean << std::endl;
701 std::cout << " Actual stdev of the input signal: " << opt_stdev << std::endl;
702 std::cout << " Mean drift of the input signal: " << opt_meandrift << std::endl;
703
704 return testOnSynthetic(opt_typeTest, parameters, opt_mean, opt_meandrift, opt_stdev);
705}
706#else
707int main()
708{
709 std::cerr << "Recompile ViSP with display capabilities in order to use this tutorial." << std::endl;
710 return EXIT_FAILURE;
711}
712#endif
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition vpException.h:73
Class for generating random number with normal probability density.
This class enables real time drawing of 2D or 3D graphics. An instance of the class open a window whi...
Definition vpPlot.h:117
Base class for methods detecting the drift of the mean of a process.
static std::string vpMeanDriftTypeToString(const vpMeanDriftType &type)
Cast a vpMeanDriftType into a string.
vpMeanDriftType
Enum that indicates if a drift of the mean occurred.
static vpMeanDriftType vpMeanDriftTypeFromString(const std::string &name)
Cast a string into a vpMeanDriftType.
void getLimits(float &limitDown, float &limitUp) const
Get the upper and lower limits of the test signal.
vpMeanDriftType testDownUpwardMeanDrift(const float &signal)
Test if a downward or an upward mean drift occurred according to the new value of the signal.
float getMean() const
Get the mean used as reference.
float getStdev() const
Get the standard deviation used as reference.
static std::string getAvailableMeanDriftType(const std::string &prefix="<", const std::string &sep=" , ", const std::string &suffix=">")
Get the list of available vpMeanDriftType objects that are handled.
Class that permits to perform Exponentially Weighted Moving Average mean drft tests.
float getWt() const
Get the current value of the test signal.
This class implements the Hinkley's cumulative sum test.
float getNk() const
Get the minimum of the test signal for upward mean drift .
float getTk() const
Get the test signal for upward mean drift..
float getSk() const
Get the test signal for downward mean drift.
float getMk() const
Get the maximum of the test signal for downward mean drift .
Class that permits to perform a mean adjusted Cumulative Sum test.
float getTestSignalMinus() const
Get the latest value of the test signal for downward jumps of the mean.
float getTestSignalPlus() const
Get the latest value of the test signal for upward jumps of the mean.
Class that permits a Shewhart's test.
static VP_ATTRIBUTE_NO_DESTROY const std::vector< bool > CONST_ALL_WECO_ACTIVATED
vpWecoRulesAlarm getAlarm() const
Get the alarm raised by the last test due to the WECO's rules.
std::vector< float > getSignals() const
Get the NB_DATA_SIGNAL last signal values, sorted from the latest [0] to the newest [NB_DATA_SIGNAL -...
static std::string vpWecoRulesAlarmToString(const vpWecoRulesAlarm &alarm)
Class that permits a simple test comparing the current value to the standard deviation of the signal.