Visual Servoing Platform  version 3.6.1 under development (2024-05-07)
vpStatisticalTestAbstract.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  */
31 
39 #include <visp3/core/vpStatisticalTestAbstract.h>
40 
42 {
43  std::string name;
44  switch (type) {
45  case MEAN_DRIFT_NONE:
46  name = "no_drift";
47  break;
49  name = "downward_drift";
50  break;
51  case MEAN_DRIFT_UPWARD:
52  name = "upward_drift";
53  break;
54  case MEAN_DRIFT_BOTH:
55  name = "both_drift";
56  break;
57  case MEAN_DRIFT_UNKNOWN:
58  default:
59  name = "undefined_drift";
60  break;
61  }
62  return name;
63 }
64 
66 {
68  unsigned int count = static_cast<unsigned int>(MEAN_DRIFT_COUNT);
69  unsigned int id = 0;
70  bool hasNotFound = true;
71  while ((id < count) && hasNotFound) {
72  vpMeanDriftType temp = static_cast<vpMeanDriftType>(id);
73  if (vpMeanDriftTypeToString(temp) == name) {
74  result = temp;
75  hasNotFound = false;
76  }
77  ++id;
78  }
79  return result;
80 }
81 
82 std::string vpStatisticalTestAbstract::getAvailableMeanDriftType(const std::string &prefix, const std::string &sep,
83  const std::string &suffix)
84 {
85  std::string msg(prefix);
86  unsigned int count = static_cast<unsigned int>(MEAN_DRIFT_COUNT);
87  unsigned int lastId = count - 1;
88  for (unsigned int i = 0; i < lastId; i++) {
89  msg += vpMeanDriftTypeToString(static_cast<vpMeanDriftType>(i)) + sep;
90  }
91  msg += vpMeanDriftTypeToString(static_cast<vpMeanDriftType>(lastId)) + suffix;
92  return msg;
93 }
94 
96 {
97  std::cout << vpMeanDriftTypeToString(type) << " detected" << std::endl;
98 }
99 
101 {
102  m_s[static_cast<unsigned int>(m_count)] = signal;
103  m_count += 1.f;
104  m_sumForMean += signal;
105  if (static_cast<unsigned int> (m_count) >= m_nbSamplesForStatistics) {
106  // Computation of the mean
108 
109  // Computation of the stdev
110  float sumSquaredDiff = 0.f;
111  unsigned int count = static_cast<unsigned int>(m_nbSamplesForStatistics);
112  for (unsigned int i = 0; i < count; ++i) {
113  sumSquaredDiff += (m_s[i] - m_mean) * (m_s[i] - m_mean);
114  }
115  float stdev = std::sqrt(sumSquaredDiff / m_count);
116  if (m_stdevmin < 0) {
117  m_stdev = stdev;
118  }
119  else {
120  m_stdev = std::max<float>(m_stdev, m_stdevmin);
121  }
122 
124  }
126 }
127 
129  : m_areStatisticsComputed(false)
130  , m_count(0.f)
131  , m_limitDown(0.f)
132  , m_limitUp(0.f)
133  , m_mean(0.f)
134  , m_nbSamplesForStatistics(0)
135  , m_s(nullptr)
136  , m_stdev(0.f)
137  , m_stdevmin(-1.f)
138  , m_sumForMean(0.f)
139 { }
140 
142 {
143  *this = other;
144 }
145 
147 {
148  if (m_s != nullptr) {
149  delete[] m_s;
150  m_s = nullptr;
151  }
152 }
153 
155 {
156  m_areStatisticsComputed = false;
157  m_count = 0.f;
158  m_limitDown = 0.f;
159  m_limitUp = 0.f;
160  m_mean = 0.f;
162  if (m_s != nullptr) {
163  delete[] m_s;
164  m_s = nullptr;
165  }
166  m_stdev = 0.f;
167  m_sumForMean = 0.f;
168 }
169 
171 {
173  m_count = other.m_count;
174  m_limitDown = other.m_limitDown;
175  m_limitUp = other.m_limitUp;
176  m_mean = other.m_mean;
177  if (other.m_nbSamplesForStatistics > 0) {
179  }
180  else if (m_s != nullptr) {
182  delete[] m_s;
183  m_s = nullptr;
184  }
185  m_stdev = 0.f;
186  m_sumForMean = 0.f;
187  return *this;
188 }
189 
190 void vpStatisticalTestAbstract::setNbSamplesForStat(const unsigned int &nbSamples)
191 {
192  m_nbSamplesForStatistics = nbSamples;
193  if (m_s != nullptr) {
194  delete[] m_s;
195  }
196  m_s = new float[nbSamples];
197 }
198 
200 {
202  updateTestSignals(signal);
205  if ((jumpDown != MEAN_DRIFT_NONE) && (jumpUp != MEAN_DRIFT_NONE)) {
206  return MEAN_DRIFT_BOTH;
207  }
208  else if (jumpDown != MEAN_DRIFT_NONE) {
209  return jumpDown;
210  }
211  else if (jumpUp != MEAN_DRIFT_NONE) {
212  return jumpUp;
213  }
214  else {
215  return MEAN_DRIFT_NONE;
216  }
217  }
218  else {
219  updateStatistics(signal);
220  return MEAN_DRIFT_NONE;
221  }
222 }
223 
225 {
227  updateTestSignals(signal);
228  return detectDownwardMeanDrift();
229  }
230  else {
231  updateStatistics(signal);
232  return MEAN_DRIFT_NONE;
233  }
234 }
235 
237 {
239  updateTestSignals(signal);
240  return detectUpwardMeanDrift();
241  }
242  else {
243  updateStatistics(signal);
244  return MEAN_DRIFT_NONE;
245  }
246 }
Base class for methods detecting the drift of the mean of a process.
virtual ~vpStatisticalTestAbstract()
Destroy the vpStatisticalTestAbstract object.
vpMeanDriftType
Enum that indicates if a drift of the mean occurred.
static vpMeanDriftType vpMeanDriftTypeFromString(const std::string &name)
Cast a string into a vpMeanDriftType.
static std::string vpMeanDriftTypeToString(const vpMeanDriftType &type)
Cast a vpMeanDriftType into a string.
virtual vpMeanDriftType detectUpwardMeanDrift()=0
Detects if a upward mean drift occurred.
vpMeanDriftType testUpwardMeanDrift(const float &signal)
Test if an upward mean drift occurred according to the new value of the signal.
vpMeanDriftType testDownwardMeanDrift(const float &signal)
Test if a downward mean drift occurred according to the new value of the signal.
void init()
(Re)Initialize the algorithm.
vpStatisticalTestAbstract()
Construct a new vpStatisticalTestAbstract object.
virtual bool updateStatistics(const float &signal)
Update m_s and if enough values are available, compute the mean, the standard deviation and the limit...
virtual void updateTestSignals(const float &signal)=0
Update the test signals.
void setNbSamplesForStat(const unsigned int &nbSamples)
Set the number of samples required to compute the mean and standard deviation of the signal and alloc...
vpMeanDriftType testDownUpwardMeanDrift(const float &signal)
Test if a downward or an upward mean drift occurred according to the new value of the signal.
static void print(const vpMeanDriftType &type)
Print the message corresponding to the type of mean drift.
virtual vpMeanDriftType detectDownwardMeanDrift()=0
Detects if a downward mean drift occurred.
vpStatisticalTestAbstract & operator=(const vpStatisticalTestAbstract &other)
Copy operator of a vpStatisticalTestAbstract.
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.