PX4 Firmware
PX4 Autopilot Software http://px4.io
data_validator.h
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2015 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file data_validator.h
36  *
37  * A data validation class to identify anomalies in data streams
38  *
39  * @author Lorenz Meier <lorenz@px4.io>
40  */
41 
42 #pragma once
43 
44 #include <math.h>
45 #include <stdint.h>
46 
48 {
49 public:
50  static const unsigned dimensions = 3;
51 
52  DataValidator() = default;
53  ~DataValidator() = default;
54 
55  /**
56  * Put an item into the validator.
57  *
58  * @param val Item to put
59  */
60  void put(uint64_t timestamp, float val, uint64_t error_count, int priority);
61 
62  /**
63  * Put a 3D item into the validator.
64  *
65  * @param val Item to put
66  */
67  void put(uint64_t timestamp, const float val[dimensions], uint64_t error_count, int priority);
68 
69  /**
70  * Get the next sibling in the group
71  *
72  * @return the next sibling
73  */
75 
76  /**
77  * Set the sibling to the next node in the group
78  *
79  */
80  void setSibling(DataValidator *new_sibling) { _sibling = new_sibling; }
81 
82  /**
83  * Get the confidence of this validator
84  * @return the confidence between 0 and 1
85  */
86  float confidence(uint64_t timestamp);
87 
88  /**
89  * Get the error count of this validator
90  * @return the error count
91  */
92  uint64_t error_count() const { return _error_count; }
93 
94  /**
95  * Get the values of this validator
96  * @return the stored value
97  */
98  float *value() { return _value; }
99 
100  /**
101  * Get the used status of this validator
102  * @return true if this validator ever saw data
103  */
104  bool used() const { return (_time_last > 0); }
105 
106  /**
107  * Get the priority of this validator
108  * @return the stored priority
109  */
110  int priority() const { return _priority; }
111 
112  /**
113  * Get the error state of this validator
114  * @return the bitmask with the error status
115  */
116  uint32_t state() const { return _error_mask; }
117 
118  /**
119  * Reset the error state of this validator
120  */
122 
123  /**
124  * Get the RMS values of this validator
125  * @return the stored RMS
126  */
127  float *rms() { return _rms; }
128 
129  /**
130  * Get the vibration offset
131  * @return the stored vibration offset
132  */
133  float *vibration_offset() { return _vibe; }
134 
135  /**
136  * Print the validator value
137  *
138  */
139  void print();
140 
141  /**
142  * Set the timeout value
143  *
144  * @param timeout_interval_us The timeout interval in microseconds
145  */
146  void set_timeout(uint32_t timeout_interval_us) { _timeout_interval = timeout_interval_us; }
147 
148  /**
149  * Set the equal count threshold
150  *
151  * @param threshold The number of equal values before considering the sensor stale
152  */
153  void set_equal_value_threshold(uint32_t threshold) { _value_equal_count_threshold = threshold; }
154 
155  /**
156  * Get the timeout value
157  *
158  * @return The timeout interval in microseconds
159  */
160  uint32_t get_timeout() const { return _timeout_interval; }
161 
162  /**
163  * Data validator error states
164  */
165  static constexpr uint32_t ERROR_FLAG_NO_ERROR = (0x00000000U);
166  static constexpr uint32_t ERROR_FLAG_NO_DATA = (0x00000001U);
167  static constexpr uint32_t ERROR_FLAG_STALE_DATA = (0x00000001U << 1);
168  static constexpr uint32_t ERROR_FLAG_TIMEOUT = (0x00000001U << 2);
169  static constexpr uint32_t ERROR_FLAG_HIGH_ERRCOUNT = (0x00000001U << 3);
170  static constexpr uint32_t ERROR_FLAG_HIGH_ERRDENSITY = (0x00000001U << 4);
171 
172 private:
173  uint32_t _error_mask{ERROR_FLAG_NO_ERROR}; /**< sensor error state */
174 
175  uint32_t _timeout_interval{20000}; /**< interval in which the datastream times out in us */
176 
177  uint64_t _time_last{0}; /**< last timestamp */
178  uint64_t _event_count{0}; /**< total data counter */
179  uint64_t _error_count{0}; /**< error count */
180 
181  int _error_density{0}; /**< ratio between successful reads and errors */
182 
183  int _priority{0}; /**< sensor nominal priority */
184 
185  float _mean[dimensions] {}; /**< mean of value */
186  float _lp[dimensions] {}; /**< low pass value */
187  float _M2[dimensions] {}; /**< RMS component value */
188  float _rms[dimensions] {}; /**< root mean square error */
189  float _value[dimensions] {}; /**< last value */
190  float _vibe[dimensions] {}; /**< vibration level, in sensor unit */
191 
192  unsigned _value_equal_count{0}; /**< equal values in a row */
193  unsigned _value_equal_count_threshold{VALUE_EQUAL_COUNT_DEFAULT}; /**< when to consider an equal count as a problem */
194 
195  DataValidator *_sibling{nullptr}; /**< sibling in the group */
196 
197  static const constexpr unsigned NORETURN_ERRCOUNT = 10000; /**< if the error count reaches this value, return sensor as invalid */
198  static const constexpr float ERROR_DENSITY_WINDOW = 100.0f; /**< window in measurement counts for errors */
199  static const constexpr unsigned VALUE_EQUAL_COUNT_DEFAULT = 100; /**< if the sensor value is the same (accumulated also between axes) this many times, flag it */
200 
201  /* we don't want this class to be copied */
202  DataValidator(const DataValidator &) = delete;
203  DataValidator operator=(const DataValidator &) = delete;
204 };
int priority() const
Get the priority of this validator.
uint32_t get_timeout() const
Get the timeout value.
static constexpr uint32_t ERROR_FLAG_NO_ERROR
Data validator error states.
bool used() const
Get the used status of this validator.
static const constexpr unsigned VALUE_EQUAL_COUNT_DEFAULT
if the sensor value is the same (accumulated also between axes) this many times, flag it ...
void reset_state()
Reset the error state of this validator.
static constexpr uint32_t ERROR_FLAG_TIMEOUT
float _lp[dimensions]
low pass value
float _value[dimensions]
last value
float _vibe[dimensions]
vibration level, in sensor unit
static constexpr uint32_t ERROR_FLAG_STALE_DATA
int _priority
sensor nominal priority
unsigned _value_equal_count
equal values in a row
static constexpr uint32_t ERROR_FLAG_HIGH_ERRCOUNT
float _rms[dimensions]
root mean square error
float _M2[dimensions]
RMS component value.
void print()
Print the validator value.
void set_timeout(uint32_t timeout_interval_us)
Set the timeout value.
void setSibling(DataValidator *new_sibling)
Set the sibling to the next node in the group.
uint32_t _timeout_interval
interval in which the datastream times out in us
~DataValidator()=default
uint32_t _error_mask
sensor error state
uint64_t _event_count
total data counter
uint32_t state() const
Get the error state of this validator.
float * rms()
Get the RMS values of this validator.
float _mean[dimensions]
mean of value
unsigned _value_equal_count_threshold
when to consider an equal count as a problem
static constexpr uint32_t ERROR_FLAG_NO_DATA
float * value()
Get the values of this validator.
DataValidator * sibling()
Get the next sibling in the group.
static constexpr uint32_t ERROR_FLAG_HIGH_ERRDENSITY
void set_equal_value_threshold(uint32_t threshold)
Set the equal count threshold.
uint64_t _error_count
error count
int _error_density
ratio between successful reads and errors
DataValidator operator=(const DataValidator &)=delete
float * vibration_offset()
Get the vibration offset.
void put(uint64_t timestamp, float val, uint64_t error_count, int priority)
Put an item into the validator.
uint64_t _time_last
last timestamp
static const constexpr unsigned NORETURN_ERRCOUNT
if the error count reaches this value, return sensor as invalid
float confidence(uint64_t timestamp)
Get the confidence of this validator.
DataValidator()=default
DataValidator * _sibling
sibling in the group
static const constexpr float ERROR_DENSITY_WINDOW
window in measurement counts for errors
uint64_t error_count() const
Get the error count of this validator.
static const unsigned dimensions