mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-05 07:28:29 -04:00
AP_GyroFFT: correct notch calculation for FFT tune.
use freq_min_ratio for scaling add harmonic calculation test set harmonics in notch setup
This commit is contained in:
parent
20934491e5
commit
4199ccc292
@ -701,7 +701,40 @@ void AP_GyroFFT::start_notch_tune()
|
|||||||
if (!hal.dsp->fft_start_average(_state)) {
|
if (!hal.dsp->fft_start_average(_state)) {
|
||||||
gcs().send_text(MAV_SEVERITY_WARNING, "FFT: Unable to start FFT averaging");
|
gcs().send_text(MAV_SEVERITY_WARNING, "FFT: Unable to start FFT averaging");
|
||||||
}
|
}
|
||||||
|
// throttle averaging for average fft calculation
|
||||||
_avg_throttle_out = 0.0f;
|
_avg_throttle_out = 0.0f;
|
||||||
|
#if APM_BUILD_COPTER_OR_HELI || APM_BUILD_TYPE(APM_BUILD_ArduPlane)
|
||||||
|
AP_Motors* motors = AP::motors();
|
||||||
|
if (motors != nullptr) {
|
||||||
|
_avg_throttle_out = motors->get_throttle_hover();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the frequency to be used for the harmonic notch
|
||||||
|
float AP_GyroFFT::calculate_notch_frequency(float* freqs, uint16_t numpeaks, float harmonic_fit, uint8_t& harmonics)
|
||||||
|
{
|
||||||
|
float harmonic = freqs[0];
|
||||||
|
harmonics = 1;
|
||||||
|
|
||||||
|
for (uint8_t i = 1; i < numpeaks; i++) {
|
||||||
|
if (freqs[i] < harmonic) {
|
||||||
|
for (uint8_t x = 2; x <=HNF_MAX_HARMONICS; x++) {
|
||||||
|
if (is_harmonic_of(harmonic, freqs[i], x, harmonic_fit)) {
|
||||||
|
harmonic = freqs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// select the harmonics that were matched
|
||||||
|
for (uint8_t i = 0; i < numpeaks; i++) {
|
||||||
|
for (uint8_t x = 1; x <=HNF_MAX_HARMONICS; x++) {
|
||||||
|
if (is_harmonic_of(freqs[i], harmonic, x, harmonic_fit)) {
|
||||||
|
harmonics |= 1<<(x - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return harmonic;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_GyroFFT::stop_notch_tune()
|
void AP_GyroFFT::stop_notch_tune()
|
||||||
@ -718,21 +751,11 @@ void AP_GyroFFT::stop_notch_tune()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float harmonic = freqs[0];
|
uint8_t harmonics;
|
||||||
float harmonic_fit = 100.0f;
|
float harmonic = calculate_notch_frequency(freqs, numpeaks, _harmonic_fit, harmonics);
|
||||||
|
|
||||||
for (uint8_t i = 1; i < numpeaks; i++) {
|
|
||||||
if (freqs[i] < harmonic) {
|
|
||||||
const float fit = 100.0f * fabsf(harmonic - freqs[i] * _harmonic_multiplier) / harmonic;
|
|
||||||
if (isfinite(fit) && fit < _harmonic_fit && fit < harmonic_fit) {
|
|
||||||
harmonic = freqs[i];
|
|
||||||
harmonic_fit = fit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gcs().send_text(MAV_SEVERITY_INFO, "FFT: Found peaks at %.1f/%.1f/%.1fHz", freqs[0], freqs[1], freqs[2]);
|
gcs().send_text(MAV_SEVERITY_INFO, "FFT: Found peaks at %.1f/%.1f/%.1fHz", freqs[0], freqs[1], freqs[2]);
|
||||||
gcs().send_text(MAV_SEVERITY_NOTICE, "FFT: Selected %.1fHz with fit %.1f%%\n", harmonic, is_equal(harmonic_fit, 100.0f) ? 100.0f : 100.0f - harmonic_fit);
|
gcs().send_text(MAV_SEVERITY_NOTICE, "FFT: Selected %.1fHz\n", harmonic);
|
||||||
|
|
||||||
// if we don't have a throttle value then all bets are off
|
// if we don't have a throttle value then all bets are off
|
||||||
if (is_zero(_avg_throttle_out) || is_zero(harmonic)) {
|
if (is_zero(_avg_throttle_out) || is_zero(harmonic)) {
|
||||||
@ -740,17 +763,14 @@ void AP_GyroFFT::stop_notch_tune()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pick a ref which means the notch covers all the way down to FFT_MINHZ
|
if (!_ins->setup_throttle_gyro_harmonic_notch(harmonic, (float)_fft_min_hz.get(), _avg_throttle_out, harmonics)) {
|
||||||
const float thr_ref = _avg_throttle_out * sq((float)_fft_min_hz.get() / harmonic);
|
|
||||||
|
|
||||||
if (!_ins->setup_throttle_gyro_harmonic_notch((float)_fft_min_hz.get(), thr_ref)) {
|
|
||||||
gcs().send_text(MAV_SEVERITY_WARNING, "FFT: Unable to set throttle notch with %.1fHz/%.2f",
|
gcs().send_text(MAV_SEVERITY_WARNING, "FFT: Unable to set throttle notch with %.1fHz/%.2f",
|
||||||
(float)_fft_min_hz.get(), thr_ref);
|
harmonic, _avg_throttle_out);
|
||||||
// save results to FFT slots
|
// save results to FFT slots
|
||||||
_throttle_ref.set(thr_ref);
|
_throttle_ref.set(_avg_throttle_out);
|
||||||
_freq_hover_hz.set(harmonic);
|
_freq_hover_hz.set(harmonic);
|
||||||
} else {
|
} else {
|
||||||
gcs().send_text(MAV_SEVERITY_NOTICE, "FFT: Notch frequency %.1fHz and ref %.2f selected", (float)_fft_min_hz.get(), thr_ref);
|
gcs().send_text(MAV_SEVERITY_NOTICE, "FFT: Notch frequency %.1fHz and ref %.2f selected", harmonic, _avg_throttle_out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +113,11 @@ public:
|
|||||||
bool check_esc_noise() const { return (_options & uint32_t(Options::ESCNoiseCheck)) != 0; }
|
bool check_esc_noise() const { return (_options & uint32_t(Options::ESCNoiseCheck)) != 0; }
|
||||||
// look for a frequency in the detected noise
|
// look for a frequency in the detected noise
|
||||||
float has_noise_at_frequency_hz(float freq) const;
|
float has_noise_at_frequency_hz(float freq) const;
|
||||||
|
static float calculate_notch_frequency(float* freqs, uint16_t numpeaks, float harmonic_fit, uint8_t& harmonics);
|
||||||
|
static bool is_harmonic_of(float harmonic, float fundamental, uint8_t mult, float _fit) {
|
||||||
|
const float fit = 100.0f * fabsf(harmonic - fundamental * mult) / harmonic;
|
||||||
|
return (isfinite(fit) && fit < _fit);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct AP_Param::GroupInfo var_info[];
|
static const struct AP_Param::GroupInfo var_info[];
|
||||||
static AP_GyroFFT *get_singleton() { return _singleton; }
|
static AP_GyroFFT *get_singleton() { return _singleton; }
|
||||||
|
23
libraries/AP_GyroFFT/tests/test_harmonic_fit.cpp
Normal file
23
libraries/AP_GyroFFT/tests/test_harmonic_fit.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include <AP_gtest.h>
|
||||||
|
#include <AP_HAL/HAL.h>
|
||||||
|
#include <AP_HAL/Util.h>
|
||||||
|
#include <AP_GyroFFT/AP_GyroFFT.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
const AP_HAL::HAL& hal = AP_HAL::get_HAL();
|
||||||
|
|
||||||
|
TEST(harmonic_fit_Test, Basic)
|
||||||
|
{
|
||||||
|
#if HAL_GYROFFT_ENABLED
|
||||||
|
float freqs[] { 176.9, 57.2, 228.7 };
|
||||||
|
uint8_t harmonics;
|
||||||
|
float harmonic = AP_GyroFFT::calculate_notch_frequency(freqs, 3, 10, harmonics);
|
||||||
|
|
||||||
|
printf("FFT: Found peaks at %.1f/%.1f/%.1fHz\n", freqs[0], freqs[1], freqs[2]);
|
||||||
|
printf("FFT: Selected %.1fHz %d\n", harmonic, harmonics);
|
||||||
|
|
||||||
|
EXPECT_TRUE(is_equal(harmonic, 57.2f));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
AP_GTEST_MAIN()
|
7
libraries/AP_GyroFFT/tests/wscript
Normal file
7
libraries/AP_GyroFFT/tests/wscript
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
def build(bld):
|
||||||
|
bld.ap_find_tests(
|
||||||
|
use='ap',
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user