Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plane: backport notch filter rework changes to 4.4.x #26099

Open
wants to merge 15 commits into
base: Plane-4.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 18 additions & 28 deletions libraries/AP_InertialSensor/AP_InertialSensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,6 @@ AP_InertialSensor::init(uint16_t loop_rate)
if (!notch.params.enabled() && !fft_enabled) {
continue;
}
notch.calculated_notch_freq_hz[0] = notch.params.center_freq_hz();
notch.num_calculated_notch_frequencies = 1;
notch.num_dynamic_notches = 1;
#if APM_BUILD_COPTER_OR_HELI || APM_BUILD_TYPE(APM_BUILD_ArduPlane)
Expand All @@ -977,15 +976,13 @@ AP_InertialSensor::init(uint16_t loop_rate)
sensors_used += _use(i);
}

uint8_t num_filters = 0;
uint16_t num_filters = 0;
for (auto &notch : harmonic_notches) {
// calculate number of notches we might want to use for harmonic notch
if (notch.params.enabled() || fft_enabled) {
const bool double_notch = notch.params.hasOption(HarmonicNotchFilterParams::Options::DoubleNotch);
const bool triple_notch = notch.params.hasOption(HarmonicNotchFilterParams::Options::TripleNotch);
const bool all_sensors = notch.params.hasOption(HarmonicNotchFilterParams::Options::EnableOnAllIMUs);
num_filters += __builtin_popcount(notch.params.harmonics())
* notch.num_dynamic_notches * (double_notch ? 2 : triple_notch ? 3 : 1)
* notch.num_dynamic_notches * notch.params.num_composite_notches()
* (all_sensors?sensors_used:1);
}
}
Expand All @@ -1000,13 +997,10 @@ AP_InertialSensor::init(uint16_t loop_rate)
if (_use(i)) {
for (auto &notch : harmonic_notches) {
if (notch.params.enabled() || fft_enabled) {
const bool double_notch = notch.params.hasOption(HarmonicNotchFilterParams::Options::DoubleNotch);
const bool triple_notch = notch.params.hasOption(HarmonicNotchFilterParams::Options::TripleNotch);
notch.filter[i].allocate_filters(notch.num_dynamic_notches,
notch.params.harmonics(), double_notch ? 2 : triple_notch ? 3 : 1);
notch.params.harmonics(), notch.params.num_composite_notches());
// initialise default settings, these will be subsequently changed in AP_InertialSensor_Backend::update_gyro()
notch.filter[i].init(_gyro_raw_sample_rates[i], notch.calculated_notch_freq_hz[0],
notch.params.bandwidth_hz(), notch.params.attenuation_dB());
notch.filter[i].init(_gyro_raw_sample_rates[i], notch.params);
}
}
}
Expand Down Expand Up @@ -1702,25 +1696,21 @@ void AP_InertialSensor::_save_gyro_calibration()
*/
void AP_InertialSensor::HarmonicNotch::update_params(uint8_t instance, bool converging, float gyro_rate)
{
const float center_freq = calculated_notch_freq_hz[0];
if (!is_equal(last_bandwidth_hz[instance], params.bandwidth_hz()) ||
!is_equal(last_attenuation_dB[instance], params.attenuation_dB()) ||
(params.tracking_mode() == HarmonicNotchDynamicMode::Fixed && !is_equal(last_center_freq_hz[instance], center_freq)) ||
(params.tracking_mode() == HarmonicNotchDynamicMode::Fixed &&
!is_equal(last_center_freq_hz[instance], params.center_freq_hz())) ||
converging) {
filter[instance].init(gyro_rate,
center_freq,
params.bandwidth_hz(),
params.attenuation_dB());
last_center_freq_hz[instance] = center_freq;
filter[instance].init(gyro_rate, params);
last_center_freq_hz[instance] = params.center_freq_hz();
last_bandwidth_hz[instance] = params.bandwidth_hz();
last_attenuation_dB[instance] = params.attenuation_dB();
} else if (params.tracking_mode() != HarmonicNotchDynamicMode::Fixed) {
if (num_calculated_notch_frequencies > 1) {
filter[instance].update(num_calculated_notch_frequencies, calculated_notch_freq_hz);
} else {
filter[instance].update(center_freq);
filter[instance].update(calculated_notch_freq_hz[0]);
}
last_center_freq_hz[instance] = center_freq;
}
}

Expand Down Expand Up @@ -2152,23 +2142,23 @@ void AP_InertialSensor::acal_update()
}
#endif

// Update the harmonic notch frequency
/*
Update the harmonic notch frequency

Note that zero is a valid value and will disable the notch unless
the TreatLowAsMin option is set
*/
void AP_InertialSensor::HarmonicNotch::update_freq_hz(float scaled_freq)
{
// protect against zero as the scaled frequency
if (is_positive(scaled_freq)) {
calculated_notch_freq_hz[0] = scaled_freq;
}
calculated_notch_freq_hz[0] = scaled_freq;
num_calculated_notch_frequencies = 1;
}

// Update the harmonic notch frequency
void AP_InertialSensor::HarmonicNotch::update_frequencies_hz(uint8_t num_freqs, const float scaled_freq[]) {
// protect against zero as the scaled frequency
// note that we allow zero through, which will disable the notch
for (uint8_t i = 0; i < num_freqs; i++) {
if (is_positive(scaled_freq[i])) {
calculated_notch_freq_hz[i] = scaled_freq[i];
}
calculated_notch_freq_hz[i] = scaled_freq[i];
}
// any uncalculated frequencies will float at the previous value or the initialized freq if none
num_calculated_notch_frequencies = num_freqs;
Expand Down
7 changes: 7 additions & 0 deletions libraries/AP_Logger/AP_Logger_Backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
#include <AP_Scheduler/AP_Scheduler.h>
#include <AP_Rally/AP_Rally.h>
#include <AP_Vehicle/AP_Vehicle_Type.h>
#include <Filter/Filter.h>
#include "AP_Logger.h"

#if HAL_LOGGER_FENCE_ENABLED
#include <AC_Fence/AC_Fence.h>
#endif

extern const AP_HAL::HAL& hal;

Expand Down Expand Up @@ -562,6 +568,7 @@ bool AP_Logger_Backend::Write_VER()
fw_type: fwver.fw_type,
git_hash: fwver.fw_hash,
build_type: fwver.vehicle_type,
filter_version: AP_FILTER_VERSION,
};
strncpy(pkt.fw_string, fwver.fw_string, ARRAY_SIZE(pkt.fw_string)-1);

Expand Down
3 changes: 2 additions & 1 deletion libraries/AP_Logger/LogStructure.h
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ struct PACKED log_VER {
char fw_string[64];
uint16_t _APJ_BOARD_ID;
uint8_t build_type;
uint8_t filter_version;
};


Expand Down Expand Up @@ -1345,7 +1346,7 @@ LOG_STRUCTURE_FROM_AIS \
{ LOG_SCRIPTING_MSG, sizeof(log_Scripting), \
"SCR", "QNIii", "TimeUS,Name,Runtime,Total_mem,Run_mem", "s-sbb", "F-F--", true }, \
{ LOG_VER_MSG, sizeof(log_VER), \
"VER", "QBHBBBBIZHB", "TimeUS,BT,BST,Maj,Min,Pat,FWT,GH,FWS,APJ,BU", "s----------", "F----------", false }, \
"VER", "QBHBBBBIZHBB", "TimeUS,BT,BST,Maj,Min,Pat,FWT,GH,FWS,APJ,BU,FV", "s-----------", "F-----------", false }, \
{ LOG_MOTBATT_MSG, sizeof(log_MotBatt), \
"MOTB", "QfffffB", "TimeUS,LiftMax,BatVolt,ThLimit,ThrAvMx,ThrOut,FailFlags", "s------", "F------" , true }

Expand Down
35 changes: 6 additions & 29 deletions libraries/AP_Vehicle/AP_Vehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,6 @@ void AP_Vehicle::update_throttle_notch(AP_InertialSensor::HarmonicNotch &notch)
#if APM_BUILD_TYPE(APM_BUILD_ArduPlane)||APM_BUILD_COPTER_OR_HELI||APM_BUILD_TYPE(APM_BUILD_Rover)
const float ref_freq = notch.params.center_freq_hz();
const float ref = notch.params.reference();
const float min_ratio = notch.params.freq_min_ratio();

#if APM_BUILD_TYPE(APM_BUILD_ArduPlane)||APM_BUILD_COPTER_OR_HELI
const AP_Motors* motors = AP::motors();
Expand All @@ -522,7 +521,7 @@ void AP_Vehicle::update_throttle_notch(AP_InertialSensor::HarmonicNotch &notch)
const float motors_throttle = motors != nullptr ? abs(motors->get_throttle() / 100.0f) : 0;
#endif

float throttle_freq = ref_freq * MAX(min_ratio, sqrtf(motors_throttle / ref));
float throttle_freq = ref_freq * sqrtf(MAX(0,motors_throttle) / ref);

notch.update_freq_hz(throttle_freq);
#endif
Expand All @@ -542,17 +541,6 @@ void AP_Vehicle::update_dynamic_notch(AP_InertialSensor::HarmonicNotch &notch)
return;
}

#if APM_BUILD_TYPE(APM_BUILD_ArduPlane)||APM_BUILD_COPTER_OR_HELI
const AP_Motors* motors = AP::motors();
if (motors != nullptr && motors->get_spool_state() == AP_Motors::SpoolState::SHUT_DOWN) {
notch.set_inactive(true);
} else {
notch.set_inactive(false);
}
#else // APM_BUILD_Rover: keep notch active
notch.set_inactive(false);
#endif

switch (notch.params.tracking_mode()) {
case HarmonicNotchDynamicMode::UpdateThrottle: // throttle based tracking
// set the harmonic notch filter frequency approximately scaled on motor rpm implied by throttle
Expand All @@ -567,9 +555,9 @@ void AP_Vehicle::update_dynamic_notch(AP_InertialSensor::HarmonicNotch &notch)
float rpm;
if (rpm_sensor != nullptr && rpm_sensor->get_rpm(sensor, rpm)) {
// set the harmonic notch filter frequency from the main rotor rpm
notch.update_freq_hz(MAX(ref_freq, rpm * ref * (1.0/60)));
notch.update_freq_hz(rpm * ref * (1.0/60));
} else {
notch.update_freq_hz(ref_freq);
notch.update_freq_hz(0);
}
break;
}
Expand All @@ -581,18 +569,13 @@ void AP_Vehicle::update_dynamic_notch(AP_InertialSensor::HarmonicNotch &notch)
float notches[INS_MAX_NOTCHES];
// ESC telemetry will return 0 for missing data, but only after 1s
const uint8_t num_notches = AP::esc_telem().get_motor_frequencies_hz(INS_MAX_NOTCHES, notches);
for (uint8_t i = 0; i < num_notches; i++) {
if (!is_zero(notches[i])) {
notches[i] = MAX(ref_freq, notches[i]);
}
}
if (num_notches > 0) {
notch.update_frequencies_hz(num_notches, notches);
} else { // throttle fallback
update_throttle_notch(notch);
}
} else {
notch.update_freq_hz(MAX(ref_freq, AP::esc_telem().get_average_motor_frequency_hz() * ref));
notch.update_freq_hz(AP::esc_telem().get_average_motor_frequency_hz() * ref);
}
break;
#endif
Expand All @@ -604,20 +587,14 @@ void AP_Vehicle::update_dynamic_notch(AP_InertialSensor::HarmonicNotch &notch)
const uint8_t peaks = gyro_fft.get_weighted_noise_center_frequencies_hz(notch.num_dynamic_notches, notches);

if (peaks > 0) {
for (uint8_t i = 0; i < peaks; i++) {
notches[i] = MAX(ref_freq, notches[i]);
}
notch.set_inactive(false);
notch.update_frequencies_hz(peaks, notches);
} else { // since FFT can be used post-filter it is better to disable the notch when there is no data
notch.set_inactive(true);
}
} else {
float center_freq = gyro_fft.get_weighted_noise_center_freq_hz();
if (!is_zero(center_freq)) {
notch.update_freq_hz(MAX(ref_freq, center_freq));
} else { // since FFT can be used post-filter it is better to disable the notch when there is no data
notch.set_inactive(true);
}
notch.update_freq_hz(center_freq);
}
break;
#endif
Expand Down
9 changes: 9 additions & 0 deletions libraries/Filter/Filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,12 @@
#include "LowPassFilter.h"
#include "ModeFilter.h"
#include "Butter.h"

/*
the filter version is logged in the VER message to assist the online
analysis tools, so they can display the right filter formulas for
this version of the code
This should be incremented on significant filtering changes
*/
#define AP_FILTER_VERSION 2

Loading
Loading