BetaFlight模組設計之十三:Gyro過濾任務分析
阿新 • 來源:網路 • 發佈:2022-05-30
BetaFlight模組設計之十三:Gyro過濾任務分析
基於BetaFlight開原始碼框架簡介的框架設計,逐步分析內部模組功能設計。
Gyro過濾任務
描述:主要是對Gyro資料的過濾處理。
├──> 初始化
│ ├──> [x]硬體初始化
│ └──> [v]業務初始化gyroInitFilters
├──> 任務
│ ├──> [v]實時任務[TASK_FILTER] = DEFINE_TASK("FILTER", NULL, NULL, taskFiltering, TASK_GYROPID_DESIRED_PERIOD, TASK_PRIORITY_REALTIME),
│ ├──> [x]事件任務
│ └──> [x]時間任務
├──> 驅動
│ ├──> [x]查詢
│ └──> [x]中斷
└──> 介面
└──> TBD
taskFiltering任務分析
沒什麼看頭,外面是一個過濾任務,裡面實質是gyro的過濾函式。
估計最初考慮很多資料平滑或者過濾都在這裡處理。而實際上這個和飛控姿態相關的資料過濾函式呼叫頻率非常高,而其他感測資料並非需要類似高的頻率。
taskFiltering
└──> gyroFiltering
gyroFiltering函式分析
gyroFiltering
├──> GYRO_FILTER_FUNCTION_NAME()
├──> <USE_DYN_NOTCH_FILTER><isDynNotchActive()>
│ └──> dynNotchUpdate
├──> <gyro.useDualGyroDebugging>
│ ├──> <GYRO_CONFIG_USE_GYRO_1>[debug資料更新]
│ ├──> <GYRO_CONFIG_USE_GYRO_2>[debug資料更新]
│ └──> <GYRO_CONFIG_USE_GYRO_BOTH>[debug資料更新]
├──> <USE_GYRO_OVERFLOW_CHECK><gyroConfig()->checkOverflow && !gyro.gyroHasOverflowProtection>
│ └──> checkForOverflow
├──> <USE_YAW_SPIN_RECOVERY><yawSpinRecoveryEnabled>
│ └──> checkForYawSpin
└──> <!overflowDetected> // integrate using trapezium rule to avoid bias
├──> accumulatedMeasurements[axis] += 0.5f * (gyroPrevious[axis] + gyro.gyroADCf[axis]) * gyro.targetLooptime;
├──> gyroPrevious[axis] = gyro.gyroADCf[axis];
└──> accumulatedMeasurementCount++;
filterGyro函式分析
這個函式有兩個變種:filterGyro和filterGyroDebug;主要問題是是否需要debug一些資料,filterGyroDebug函式以下巨集定義來資料的記錄。
#define DEBUG_SET(mode, index, value) do { if (debugMode == (mode)) { debug[(index)] = (value); } } while (0)
#define GYRO_FILTER_AXIS_DEBUG_SET(axis, mode, index, value) if (axis == (int)gyro.gyroDebugAxis) DEBUG_SET(mode, index, value)
詳見:\src\main\sensors\gyro.c
#define GYRO_FILTER_FUNCTION_NAME filterGyro
#define GYRO_FILTER_DEBUG_SET(mode, index, value) do { UNUSED(mode); UNUSED(index); UNUSED(value); } while (0)
#define GYRO_FILTER_AXIS_DEBUG_SET(axis, mode, index, value) do { UNUSED(axis); UNUSED(mode); UNUSED(index); UNUSED(value); } while (0)
#include "gyro_filter_impl.c"
#undef GYRO_FILTER_FUNCTION_NAME
#undef GYRO_FILTER_DEBUG_SET
#undef GYRO_FILTER_AXIS_DEBUG_SET
#define GYRO_FILTER_FUNCTION_NAME filterGyroDebug
#define GYRO_FILTER_DEBUG_SET DEBUG_SET
#define GYRO_FILTER_AXIS_DEBUG_SET(axis, mode, index, value) if (axis == (int)gyro.gyroDebugAxis) DEBUG_SET(mode, index, value)
#include "gyro_filter_impl.c"
#undef GYRO_FILTER_FUNCTION_NAME
實際執行或者釋出的程式碼還是使用filterGyro,這裡分析的時候直接使用了GYRO_FILTER_FUNCTION_NAME。
GYRO_FILTER_FUNCTION_NAME
├──> <loop axis> // downsample the individual gyro samples
│ ├──> <gyro.downsampleFilterEnabled> // using gyro lowpass 2 filter for downsampling
│ │ └──> gyroADCf = gyro.sampleSum[axis];
│ ├──> <!gyro.downsampleFilterEnabled> // using simple average for downsampling
│ │ └──> gyroADCf = gyro.sampleSum[axis] / gyro.sampleCount;
│ ├──> <USE_RPM_FILTER>
│ │ └──> rpmFilterGyro
│ ├──> // apply static notch filters and software lowpass filters
│ │ ├──> gyroADCf = gyro.notchFilter1ApplyFn((filter_t *)&gyro.notchFilter1[axis], gyroADCf);
│ │ ├──> gyroADCf = gyro.notchFilter2ApplyFn((filter_t *)&gyro.notchFilter2[axis], gyroADCf);
│ │ └──> gyroADCf = gyro.lowpassFilterApplyFn((filter_t *)&gyro.lowpassFilter[axis], gyroADCf);
│ ├──> <USE_DYN_NOTCH_FILTER><isDynNotchActive()>
│ │ ├──> dynNotchPush(axis, gyroADCf);
│ │ ├──> gyroADCf = dynNotchFilter(axis, gyroADCf);
│ └──> gyro.gyroADCf[axis] = gyroADCf;
└──> gyro.sampleCount = 0;
dynamic notch filter
關於dynamic notch filter我們有時間再專門針對濾波這個作為一個模組進行分析,詳見:\src\main\flight\dyn_notch_filter.c。
downsampling概念
這裡是關於資料採集以及downsampling/upsampling資料處理的演算法問題,暫不做展開,有興趣的,這裡有個連結可以簡單瞭解下。
