DIY Quadcopter – Vibrations & gyroscope

I’m still working on my quadcopter with a DIY flight controller based on an arduino chip. After a lot of tests and mainly (to not say only) crashes I realised that my gyroscope datas were unstable, here is how i try to sort it out !

In a previous article, I explained why we need a gyroscope and an accelerometer on a quadcopter to determine its attitude (pitch, roll and maybe yaw). In this article, I will explain how to filter the raw datas coming from the gyroscope in order to use in a fusing algorithm.

yet an other crash !

yet an other crash !

Find and cancel the offset

In order to understand what is happening I wrote a code that sends raw gyro datas to my computer here is the result :

gyro_noise

The drone was not moving so what you see is only noise. The value is supposed to be 0 on each axis. When you see this graph, you quickly realize that each axis is staying around a specific value, this is the offset. Sensors are not perfect and their zero is not the real zero.

Here is my simple solution :

    //remove offset
    gyro[0] = gyro[0] + 236;
    gyro[1] = gyro[1] - 117;
    gyro[2] = gyro[2] - 296;

The values are simply the result of an average of 500 values on each axis.

offset removed

offset removed

The result is better but we still have noise. This is a simple solution that can only apply to my sensor at this specific time. The offset can move and is different from one sensor to an other. A more complex way would be to calibrate it at the beginning of each flight.

Reducing the noise

There is noise in the reading, not only because of the sensor itself but also because there are a lot of vibrations on board ! With my tests I realized that the motors tend to change the reading from my gyroscope. This is what you can see on the next graph, when the motors are not turning there is almost no noise, however when the motors are spinning there is way more noise that needs to be filtered.

Reading from the gyroscope (blue) and power on the motor (yellow)

Reading from the gyroscope (blue) and power on the motor (yellow)

So how to get of rid of this noise ? When you look at this, it looks like a sound wave, oscillating between a high and a low. If you zoom in, you can see it, one point is a high the following is a low.

So if we want to filter it we can maybe get to value in the middle between the high and the low.

Value = (high+low)/2

If the high and the low are two consecutive values this is simply a moving average with a period of two (MM2 on the graph). But can do it with a bigger period like 4 (MM4 on the graph).

A zoom at the reading from the gyroscope, with a moving average

A zoom at the reading from the gyroscope, with a moving average

We can see that the result is more smooth are also more close to the real value that a perfect gyroscope would read which is 0 (as it’s not moving during the tests).

Implement the filtering in the code

Here is the code I use in my quadcopter.

void MPU_gyro_update()
{
  //read values
  gyro[0] = MPU9150_readSensor(MPU9150_GYRO_XOUT_L,MPU9150_GYRO_XOUT_H);
  gyro[1] = MPU9150_readSensor(MPU9150_GYRO_YOUT_L,MPU9150_GYRO_YOUT_H);
  gyro[2] = MPU9150_readSensor(MPU9150_GYRO_ZOUT_L,MPU9150_GYRO_ZOUT_H);
  
  //remove offset
  gyro[0] = gyro[0] + 236;
  gyro[1] = gyro[1] - 117;
  gyro[2] = gyro[2] - 296;
    
  //shift all data from gyro_tmp
  for(int i=0;i <3;i++)
  {
    gyro_tmp[0][i] = gyro_tmp[0][i+1]; 
    gyro_tmp[1][i] = gyro_tmp[1][i+1]; 
    gyro_tmp[2][i] = gyro_tmp[2][i+1]; 
  }
     
  //add new values
  gyro_tmp[0][3] = gyro[0];
  gyro_tmp[1][3] = gyro[1];
  gyro_tmp[2][3] = gyro[2];
  
  //get the average (SMA4)
  gyro_filtered[0] = 0;
  gyro_filtered[1] = 0;
  gyro_filtered[2] = 0;
  
  for(int i=0;i<4;i++)
  {
    gyro_filtered[0] = gyro_filtered[0] + gyro_tmp[0][i];
    gyro_filtered[1] = gyro_filtered[1] + gyro_tmp[1][i];
    gyro_filtered[2] = gyro_filtered[2] + gyro_tmp[2][i];
  }
  
  gyro_filtered[0] = gyro_filtered[0]/4;
  gyro_filtered[1] = gyro_filtered[1]/4;
  gyro_filtered[2] = gyro_filtered[2]/4;
  
}

That’s all for this article, I hope it will help you too !

Advertisements

3 thoughts on “DIY Quadcopter – Vibrations & gyroscope

  1. Freeman says:

    You are doing something like a complementary filter.
    You should try this which is more efficient in term of algorithm :

    coef = 0.25
    gyro_filtered = gyro * coef + gyro_filtered * (1-coef)

    You can change the coefficient so that it will filter out more or less (the lower, the more filter you have).
    In my case, I changed it to 0.1, which is filtering the values of the 10 last loops (sort of), and I get pretty nice results with a minimal lag (0.05s).

    Like

    • Thank’s for your advice, I dont know if a complementary filter is more efficient because the gyro output is always alternating between a high and a low. I’ll run some tests and see which method turns out to be the best 😉

      Like

  2. Kork says:

    Hi there ! I am myself developing my own FC based on an Edison board. I have implemented an exponential filter as Freeman suggests. I noticed that filtering too much (i.e. variable “coeff” getting closer to zero) induces large instabilities on the attitude control. The value associated with this “too much” statement will depend on your sampling rate and on the PID coefficients you use.
    Kork.

    Like

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s