Files
ExtendedLibs/MyLibs/Inc/filters.h
Razvalyaev 9b9969dd7c Доработки фильтров:
- универсализированы проверки состояния инициализации фильтров
- avg сделан скользящий и обычный
- плюс еще что-то наверное
2025-11-11 17:24:53 +03:00

280 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
* @file filters.h
* @brief Заголовочный файл библиотеки фильтров
******************************************************************************
* @addtogroup FILTERS Filters Library
* @brief Библиотека математических фильтров и коррекций
* @details
Поддерживает:
- Медианную фильтрацию (float и int32_t)
- Экспоненциальное скользящее среднее (float и int32_t)
- Скользящее среднее арифметическое (float и int32_t)
- Полиномиальную коррекцию (float и int32_t)
- Табличный фильтр LUT (Look-Up Table) (float и int32_t)
Параметры для конфигурации:
- @ref FILTERS_ENABLE - Включить библиотеку фильтров
- @ref FILTER_MEDIAN_MAX_SIZE - Размер окна медианного фильтра (по умолчанию 5)
- @ref FILTER_AVERAGE_MAX_SIZE - Размер окна усредняющего фильтра (по умолчанию 8)
- @ref FILTER_POLY_MAX_ORDER - Максимальный порядок полинома (по умолчанию 4)
@par Пример использования:
@code
#include "filters.h"
// Фильтры для float
FilterMedian_t median_f;
FilterExp_t exp_f;
FilterAverage_t avg_f;
FilterPoly_t poly_f;
// Фильтры для int32_t
FilterMedianInt_t median_i;
FilterExpInt_t exp_i;
FilterAverageInt_t avg_i;
FilterPolyInt_t poly_i;
// Коэффициенты полинома
float poly_coeffs[3] = {0.0f, 1.1f, -0.05f};
int32_t poly_coeffs_int[3] = {0, 110, -5}; // 1.1 и -0.05 с масштабом 100
void filters_init(void) {
// Float версии
FilterMedian_Init(&median_f);
FilterExp_Init(&exp_f, 0.1f);
FilterAverage_Init(&avg_f);
FilterPoly_Init(&poly_f, poly_coeffs, 3);
// Int версии
FilterMedianInt_Init(&median_i);
FilterExpInt_Init(&exp_i, 10); // alpha = 0.1 с масштабом 100
FilterAverageInt_Init(&avg_i);
FilterPolyInt_Init(&poly_i, poly_coeffs_int, 3, 100); // масштаб 100
}
// Обработка float значений
float process_value_float(float raw) {
float filtered;
filtered = FilterMedian_Process(&median_f, raw);
filtered = FilterExp_Process(&exp_f, filtered);
filtered = FilterAverage_Process(&avg_f, filtered);
filtered = FilterPoly_Process(&poly_f, filtered);
return filtered;
}
// Обработка int32_t значений (квантов АЦП)
int32_t process_value_int(int32_t raw_adc_quant) {
int32_t filtered;
filtered = FilterMedianInt_Process(&median_i, raw_adc_quant);
filtered = FilterExpInt_Process(&exp_i, filtered);
filtered = FilterAverageInt_Process(&avg_i, filtered);
filtered = FilterPolyInt_Process(&poly_i, filtered);
return filtered;
}
@endcode
* @{
*****************************************************************************/
#ifndef __FILTERS_H_
#define __FILTERS_H_
#include "mylibs_defs.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#ifdef FILTERS_ENABLE
#ifndef FILTER_AVERAGE_MAX_SIZE
#define FILTER_AVERAGE_MAX_SIZE 100 ///< Размер окна усредняющего фильтра
#endif
#ifndef FILTER_MEDIAN_MAX_SIZE
#define FILTER_MEDIAN_MAX_SIZE 10 ///< Размер окна медианного фильтра
#endif
#ifndef FILTER_POLY_MAX_ORDER
#define FILTER_POLY_MAX_ORDER 4 ///< Максимальный порядок полинома
#endif
/**
* @brief Запуск фильтра
* @param filter Указатель на структуру фильтра
* @details Запускает фильтр только если он в состоянии готовности.
* Если он не инициализирован или уже запущен - ничего не делается
*/
#define Filter_Start(_fltr_) \
do{ if(Filter_isReady(_fltr_)) (_fltr_)->state = FILTER_ENABLE; }while(0);
/**
* @brief Остановка работы фильтра
* @param filter Указатель на структуру фильтра
* @details Останавливет фильтр только если он запущен @ref Filter_Start.
* Если он не инициализирован или уже остановлен - ничего не делается
*/
#define Filter_Stop(_fltr_) \
do{ if(Filter_isStart(_fltr_)) (_fltr_)->state = FILTER_READY; }while(0);
#define Filter_GetState(_fltr_) (_fltr_)->state
#define Filter_isInit(_fltr_) !(Filter_GetState(_fltr_) == FILTER_NOT_INIT)
#define Filter_isReady(_fltr_) (Filter_GetState(_fltr_) == FILTER_READY)
#define Filter_isStart(_fltr_) (Filter_GetState(_fltr_) == FILTER_ENABLE)
typedef enum
{
FILTER_NOT_INIT,
FILTER_READY,
FILTER_ENABLE
}FilterState_t;
typedef enum
{
FILTER_MODE_DEFAULT = 0,
FILTER_MODE_MOVING,
} FilterMode_t;
// ==================== FLOAT ВЕРСИИ ====================
/**
* @brief Структура медианного фильтра (float)
*/
typedef struct {
FilterState_t state; ///< Состояние фильтра
float buffer[FILTER_MEDIAN_MAX_SIZE]; ///< Буфер значений
uint8_t index; ///< Текущий индекс
uint8_t size; ///< Фактический размер фильтра
} FilterMedian_t;
/**
* @brief Структура экспоненциального фильтра (float)
*/
typedef struct {
FilterState_t state; ///< Состояние фильтра
float alpha; ///< Коэффициент сглаживания (0..1)
float value; ///< Текущее значение
uint8_t initialized; ///< Флаг инициализации
} FilterExp_t;
/**
* @brief Структура фильтра скользящего среднего (float)
*/
typedef struct {
FilterState_t state; ///< Состояние фильтра
FilterMode_t mode; ///< Режим фильтра
float buffer[FILTER_AVERAGE_MAX_SIZE]; ///< Буфер значений
uint8_t size; ///< Фактический размер фильтра
float sum; ///< Сумма значений
uint8_t index; ///< Текущий индекс
uint8_t count; ///< Количество элементов
float lastValue; ///< Последнее измеренное значение
} FilterAverage_t;
/**
* @brief Структура полиномиальной коррекции (float)
*/
typedef struct {
FilterState_t state; ///< Состояние фильтра
float coefficients[FILTER_POLY_MAX_ORDER + 1]; ///< Коэффициенты полинома
uint8_t order; ///< Порядок полинома
} FilterPoly_t;
/**
* @brief Структура табличного фильтра (float)
*/
typedef struct {
FilterState_t state; ///< Состояние фильтра
float* input_values; // Массив входных значений
float* output_values; // Массив выходных значений
uint16_t size; // Размер таблицы
uint8_t interpolation; // Флаг интерполяции (0 - отключена, 1 - линейная)
} FilterLUT_t;
// Float версии функций
int FilterMedian_Init(FilterMedian_t* filter, uint8_t size);
float FilterMedian_Process(FilterMedian_t* filter, float input);
int FilterExp_Init(FilterExp_t* filter, float alpha);
float FilterExp_Process(FilterExp_t* filter, float input);
int FilterAverage_Init(FilterAverage_t* filter, uint8_t size, FilterMode_t mode);
float FilterAverage_Process(FilterAverage_t* filter, float input);
int FilterPoly_Init(FilterPoly_t* filter, float* coeffs, uint8_t order);
float FilterPoly_Process(FilterPoly_t* filter, float input);
int FilterLUT_Init(FilterLUT_t* filter, float* input_arr, float* output_arr, uint16_t size, uint8_t interpolation);
float FilterLUT_Process(FilterLUT_t* filter, float input);
// ==================== INT32_T ВЕРСИИ ====================
/**
* @brief Структура медианного фильтра (int32_t)
*/
typedef struct {
FilterState_t state; ///< Состояние фильтра
int32_t buffer[FILTER_MEDIAN_MAX_SIZE]; ///< Буфер значений
uint8_t index; ///< Текущий индекс
uint8_t size; ///< Фактический размер фильтра
} FilterMedianInt_t;
/**
* @brief Структура экспоненциального фильтра (int32_t)
*/
typedef struct {
FilterState_t state; ///< Состояние фильтра
int32_t alpha; ///< Коэффициент сглаживания (в масштабе scale)
int32_t value; ///< Текущее значение
uint8_t initialized; ///< Флаг инициализации
int32_t scale; ///< Масштаб коэффициента (например 100 для 0.01)
} FilterExpInt_t;
/**
* @brief Структура фильтра скользящего среднего (int32_t)
*/
typedef struct {
FilterState_t state; ///< Состояние фильтра
FilterMode_t mode; ///< Режим фильтра
int32_t buffer[FILTER_AVERAGE_MAX_SIZE]; ///< Буфер значений
uint8_t size; ///< Фактический размер фильтра
int64_t sum; ///< Сумма значений
uint8_t index; ///< Текущий индекс
uint8_t count; ///< Количество элементов
uint32_t lastValue; ///< Последнее измеренное значение
} FilterAverageInt_t;
/**
* @brief Структура полиномиальной коррекции (int32_t)
*/
typedef struct {
FilterState_t state; ///< Состояние фильтра
int32_t coefficients[FILTER_POLY_MAX_ORDER + 1]; ///< Коэффициенты полинома
uint8_t order; ///< Порядок полинома
int32_t scale; ///< Масштаб коэффициентов
} FilterPolyInt_t;
/**
* @brief Структура табличного фильтра (int32_t)
*/
typedef struct {
FilterState_t state; ///< Состояние фильтра
int32_t* input_values; // Массив входных значений
int32_t* output_values; // Массив выходных значений
uint16_t size; // Размер таблицы
uint8_t interpolation; // Флаг интерполяции
} FilterLUTInt_t;
// Int32_t версии функций
int FilterMedianInt_Init(FilterMedianInt_t* filter, uint8_t size);
int32_t FilterMedianInt_Process(FilterMedianInt_t* filter, int32_t input);
int FilterExpInt_Init(FilterExpInt_t* filter, int32_t alpha, int32_t scale);
int32_t FilterExpInt_Process(FilterExpInt_t* filter, int32_t input);
int FilterAverageInt_Init(FilterAverageInt_t* filter, uint8_t size, FilterMode_t mode);
int32_t FilterAverageInt_Process(FilterAverageInt_t* filter, int32_t input);
int FilterPolyInt_Init(FilterPolyInt_t* filter, int32_t* coeffs, uint8_t order, int32_t scale);
int32_t FilterPolyInt_Process(FilterPolyInt_t* filter, int32_t input);
int FilterLUTInt_Init(FilterLUTInt_t* filter, int32_t* input_arr, int32_t* output_arr, uint16_t size, uint8_t interpolation);
int32_t FilterLUTInt_Process(FilterLUTInt_t* filter, int32_t input);
#else // FILTERS_ENABLE
#endif // FILTERS_ENABLE
#endif // __FILTERS_H_