inav icon indicating copy to clipboard operation
inav copied to clipboard

Please, correct error in anti-aliasing filter for gyro

Open and-sh opened this issue 10 months ago • 6 comments

Current Behavior

The 250 Hz pt1 filter used as anti-aliasing filter for gyro. It have attenuation about 1/5 at 1kHz, that is very insufficient.

Steps to Reproduce

model pt1 filter 250Hz, sampling rate 4kHz and measure attenuation at 1kHz.

Image

Expected behavior

attenuation, at fS/2 should more than the signal-to-noise ratio (SNR) of the sampling system.

https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ApplicationNotes/ApplicationNotes/00699b.pdf https://electronics.stackexchange.com/questions/274696/anti-aliasing-filter-design

For 16bit representation this is about 90dB.

Suggested solution(s)

Use much effective filters.

Additional context

All versions of Inav have this problem.

and-sh avatar Feb 18 '25 06:02 and-sh

Part of the issue is that for flight control case, we are interested not only in attenuation but also introduced group delay. I've run some numbers and current PT1 used indroduces 0.5ms of group delay. Doubling attenuation would double group delay as well (BiQuad). Increasing filter order would increase delay even more

DzikuVx avatar Feb 18 '25 10:02 DzikuVx

Yes, but ignoring Dr. Nyquist will result in high frequency noise being pushed into the low frequency region. And filtering out low frequency noise will result in more delay. There is usually a lot of high frequency noise in a gyroscope.

and-sh avatar Feb 18 '25 13:02 and-sh

Maybe not ignoring Dr. Nyquist. Rather compromising. Anyway, I quickly added https://github.com/iNavFlight/inav/pull/10710 but not really tested it yet

DzikuVx avatar Feb 18 '25 15:02 DzikuVx

You are fast. I make two avereging. tested on bench. Next week will try to fly.


    const bool ack = busReadBuf(gyro->busDev, ICM45600_RA_ACCEL_DATA_X1, data, 12);
    if (!ack) {
        return;
    }
//(rand()%10000-5000);

    GYRO_A[0]-= (int32_t) GYRO_V[0][IMU_ptr];
    GYRO_V[0][IMU_ptr] = (int16_t)(rand()%10000-5000);//int16_val_little_endian(data, 3);
    GYRO_A[0]+= (int32_t) GYRO_V[0][IMU_ptr];

        GYRO_A1[0]-= GYRO_V1[0][IMU_ptr1];
        GYRO_V1[0][IMU_ptr1] = GYRO_A[0];
        GYRO_A1[0]+= GYRO_V1[0][IMU_ptr1];

    GYRO_A[1]-= (int32_t) GYRO_V[1][IMU_ptr];
    GYRO_V[1][IMU_ptr] = int16_val_little_endian(data, 4);
    GYRO_A[1]+= (int32_t) GYRO_V[1][IMU_ptr];

        GYRO_A1[1]-= GYRO_V1[1][IMU_ptr1];
        GYRO_V1[1][IMU_ptr1] = GYRO_A[1];
        GYRO_A1[1]+= GYRO_V1[1][IMU_ptr1];

    GYRO_A[2]-= (int32_t) GYRO_V[2][IMU_ptr];
    GYRO_V[2][IMU_ptr] = int16_val_little_endian(data, 5);
    GYRO_A[2]+= (int32_t) GYRO_V[2][IMU_ptr];

        GYRO_A1[2]-= GYRO_V1[2][IMU_ptr1];
        GYRO_V1[2][IMU_ptr1] = GYRO_A[2];
        GYRO_A1[2]+= GYRO_V1[2][IMU_ptr1];


    ACC_A[0]-= (int32_t) ACC_V[0][IMU_ptr];
    ACC_V[0][IMU_ptr] = int16_val_little_endian(data, 0);
    ACC_A[0]+= (int32_t) ACC_V[0][IMU_ptr];

        ACC_A1[0]-= ACC_V1[0][IMU_ptr1];
        ACC_V1[0][IMU_ptr1] = ACC_A[0];
        ACC_A1[0]+= ACC_V1[0][IMU_ptr1];

    ACC_A[1]-= (int32_t) ACC_V[1][IMU_ptr];
    ACC_V[1][IMU_ptr] = int16_val_little_endian(data, 1);
    ACC_A[1]+= (int32_t) ACC_V[1][IMU_ptr];

        ACC_A1[1]-= ACC_V1[1][IMU_ptr1];
        ACC_V1[1][IMU_ptr1] = ACC_A[1];
        ACC_A1[1]+= ACC_V1[1][IMU_ptr1];

    ACC_A[2]-= (int32_t) ACC_V[2][IMU_ptr];
    ACC_V[2][IMU_ptr] = int16_val_little_endian(data, 2);
    ACC_A[2]+= (int32_t) ACC_V[2][IMU_ptr];

        ACC_A1[2]-= ACC_V1[2][IMU_ptr1];
        ACC_V1[2][IMU_ptr1] = ACC_A[2];
        ACC_A1[2]+= ACC_V1[2][IMU_ptr1];

    IMU_ptr++;
    if(IMU_ptr>=n)
    {
        IMU_ptr=0;
    } 
 
    IMU_ptr1++;
    if(IMU_ptr1>=n1)
    {
        IMU_ptr1=0;
    } 


and-sh avatar Feb 18 '25 16:02 and-sh

Spectrum and step response 1 and 2 averaging 20 and 14 points in comparison to pt1 250Hz.

Image

and-sh avatar Feb 18 '25 17:02 and-sh

Tested Flies no worse than with standard filters. There is a little less noise.

  1. Standard filters. All by default.

Image

  1. All standard filters off, except Kalman

Image

It is interesting that despite the delay of about 6 ms, there is practically no prop wash. I even lowered the idle to 5 percent. https://youtu.be/yxB54G2ou74

and-sh avatar Feb 25 '25 13:02 and-sh