2015-10-26 12:06:30 -03:00
/****************************************************************************
*
* Copyright ( c ) 2015 PX4 Development Team . All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
*
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in
* the documentation and / or other materials provided with the
* distribution .
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING ,
* BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS
* OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
* LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @ file data_validator . h
*
* A data validation class to identify anomalies in data streams
*
* @ author Lorenz Meier < lorenz @ px4 . io >
*/
# pragma once
2019-11-22 12:16:51 -04:00
# include <math.h>
2015-10-26 12:06:30 -03:00
# include <stdint.h>
2018-05-03 15:14:12 -03:00
class DataValidator
{
2015-10-26 12:06:30 -03:00
public :
2016-06-30 08:28:01 -03:00
static const unsigned dimensions = 3 ;
2018-06-13 16:48:41 -03:00
DataValidator ( ) = default ;
~ DataValidator ( ) = default ;
2015-10-26 12:06:30 -03:00
/**
* Put an item into the validator .
*
* @ param val Item to put
*/
2016-02-18 04:31:36 -04:00
void put ( uint64_t timestamp , float val , uint64_t error_count , int priority ) ;
/**
* Put a 3 D item into the validator .
*
* @ param val Item to put
*/
2018-06-13 16:48:41 -03:00
void put ( uint64_t timestamp , const float val [ dimensions ] , uint64_t error_count , int priority ) ;
2015-10-26 12:06:30 -03:00
/**
* Get the next sibling in the group
*
* @ return the next sibling
*/
2018-05-03 15:14:12 -03:00
DataValidator * sibling ( ) { return _sibling ; }
2015-10-26 12:06:30 -03:00
2018-01-29 18:11:01 -04:00
/**
* Set the sibling to the next node in the group
*
*/
2018-05-03 15:14:12 -03:00
void setSibling ( DataValidator * new_sibling ) { _sibling = new_sibling ; }
2018-01-29 18:11:01 -04:00
2015-10-26 12:06:30 -03:00
/**
* Get the confidence of this validator
* @ return the confidence between 0 and 1
*/
float confidence ( uint64_t timestamp ) ;
/**
* Get the error count of this validator
* @ return the error count
*/
2018-06-13 16:48:41 -03:00
uint64_t error_count ( ) const { return _error_count ; }
2015-10-26 12:06:30 -03:00
/**
* Get the values of this validator
* @ return the stored value
*/
2018-05-03 15:14:12 -03:00
float * value ( ) { return _value ; }
2015-10-26 12:06:30 -03:00
/**
* Get the used status of this validator
* @ return true if this validator ever saw data
*/
2018-06-13 16:48:41 -03:00
bool used ( ) const { return ( _time_last > 0 ) ; }
2015-10-26 12:06:30 -03:00
/**
* Get the priority of this validator
* @ return the stored priority
*/
2018-06-13 16:48:41 -03:00
int priority ( ) const { return _priority ; }
2016-12-17 08:14:08 -04:00
2015-12-19 03:53:08 -04:00
/**
* Get the error state of this validator
* @ return the bitmask with the error status
*/
2018-06-13 16:48:41 -03:00
uint32_t state ( ) const { return _error_mask ; }
2016-12-17 08:14:08 -04:00
2015-12-19 03:53:08 -04:00
/**
* Reset the error state of this validator
*/
void reset_state ( ) { _error_mask = ERROR_FLAG_NO_ERROR ; }
2015-10-26 12:06:30 -03:00
/**
* Get the RMS values of this validator
* @ return the stored RMS
*/
2018-05-03 15:14:12 -03:00
float * rms ( ) { return _rms ; }
2015-10-26 12:06:30 -03:00
2016-02-25 11:54:24 -04:00
/**
* Get the vibration offset
* @ return the stored vibration offset
*/
2018-05-03 15:14:12 -03:00
float * vibration_offset ( ) { return _vibe ; }
2016-02-25 11:54:24 -04:00
2015-10-26 12:06:30 -03:00
/**
* Print the validator value
*
*/
void print ( ) ;
/**
* Set the timeout value
*
* @ param timeout_interval_us The timeout interval in microseconds
*/
2016-11-01 03:50:27 -03:00
void set_timeout ( uint32_t timeout_interval_us ) { _timeout_interval = timeout_interval_us ; }
2016-12-17 09:51:39 -04:00
/**
* Set the equal count threshold
*
* @ param threshold The number of equal values before considering the sensor stale
*/
void set_equal_value_threshold ( uint32_t threshold ) { _value_equal_count_threshold = threshold ; }
2016-11-01 03:50:27 -03:00
/**
* Get the timeout value
*
* @ return The timeout interval in microseconds
*/
2018-06-13 16:48:41 -03:00
uint32_t get_timeout ( ) const { return _timeout_interval ; }
2016-12-17 08:14:08 -04:00
2015-12-19 03:53:08 -04:00
/**
2016-12-17 08:14:08 -04:00
* Data validator error states
2015-12-19 03:53:08 -04:00
*/
static constexpr uint32_t ERROR_FLAG_NO_ERROR = ( 0x00000000U ) ;
static constexpr uint32_t ERROR_FLAG_NO_DATA = ( 0x00000001U ) ;
static constexpr uint32_t ERROR_FLAG_STALE_DATA = ( 0x00000001U < < 1 ) ;
static constexpr uint32_t ERROR_FLAG_TIMEOUT = ( 0x00000001U < < 2 ) ;
static constexpr uint32_t ERROR_FLAG_HIGH_ERRCOUNT = ( 0x00000001U < < 3 ) ;
static constexpr uint32_t ERROR_FLAG_HIGH_ERRDENSITY = ( 0x00000001U < < 4 ) ;
2015-10-26 12:06:30 -03:00
private :
2018-06-13 16:48:41 -03:00
uint32_t _error_mask { ERROR_FLAG_NO_ERROR } ; /**< sensor error state */
uint32_t _timeout_interval { 20000 } ; /**< interval in which the datastream times out in us */
uint64_t _time_last { 0 } ; /**< last timestamp */
uint64_t _event_count { 0 } ; /**< total data counter */
uint64_t _error_count { 0 } ; /**< error count */
int _error_density { 0 } ; /**< ratio between successful reads and errors */
int _priority { 0 } ; /**< sensor nominal priority */
float _mean [ dimensions ] { } ; /**< mean of value */
float _lp [ dimensions ] { } ; /**< low pass value */
float _M2 [ dimensions ] { } ; /**< RMS component value */
float _rms [ dimensions ] { } ; /**< root mean square error */
float _value [ dimensions ] { } ; /**< last value */
float _vibe [ dimensions ] { } ; /**< vibration level, in sensor unit */
unsigned _value_equal_count { 0 } ; /**< equal values in a row */
unsigned _value_equal_count_threshold { VALUE_EQUAL_COUNT_DEFAULT } ; /**< when to consider an equal count as a problem */
DataValidator * _sibling { nullptr } ; /**< sibling in the group */
2018-05-03 20:28:38 -03:00
2016-06-30 08:28:01 -03:00
static const constexpr unsigned NORETURN_ERRCOUNT = 10000 ; /**< if the error count reaches this value, return sensor as invalid */
static const constexpr float ERROR_DENSITY_WINDOW = 100.0f ; /**< window in measurement counts for errors */
2016-12-17 09:51:39 -04:00
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 */
2015-10-26 12:06:30 -03:00
/* we don't want this class to be copied */
2018-05-03 15:14:12 -03:00
DataValidator ( const DataValidator & ) = delete ;
DataValidator operator = ( const DataValidator & ) = delete ;
2015-10-26 12:06:30 -03:00
} ;