Tuesday, 6 September 2011

Using three axis accelerometer with three axis gyroscope

here I would like to tell you how to use the output from sensors to measure the angle that you are looking for.
Firstly, lets see what we exactly want.
we want to sense the rotation of our sensor in three axis. this three axis can be considered as X, Y and Z or pitch, roll and yaw. I prefer X, Y and Z orientation since it is more mathematically represented.
now lets consider that we want to find the angular rotation over each axis using accelerometer. Well, we can find just two angles using accelerometer (if you don't know why don't worry you will see understand soon).
Now lets find the angle for one of the axis:
before we start, you should be agree that gravity is always perpendicular to the surface of earth. I know that the vehicle will have some acceleration to some directions, but compare to g, they are significant, so we can ignore it.

This is the diagram. As you can see, we assumed that gravity is always perpendicular to the earth surface.We know that our readings from accelerometer comes from three different axis. In this case we consider the X and Z axis readings.Now, we have to understand something which is really important in, when we have three axes the vector addition of acceleration in X and Z axis is not equal to gravity. However, in the diagram it may seem that it will be equal.
I talk about how to read your accelerometer here.
now lets say we have the reading in any unit. We call them, X_acceleration, Y_acceleration and Z_acceleration.
We have one variable which is called Gravity, recall from here ( How to read the output from accelerometer? ).
Now we find the angle theta which is equal to Y_angle. (it is rotation over the Y axis of sensor)
from the diagram, you can see that   Y_angle =  theta  =cos-1(  X_acceleration / Gravity )
(think of the triangle, I tried but I can't explain in words :( sorry )
we know that cos-1 has a range [0,180], but we may need to have a range from [0,360], in this case we use the Z axis reading. For my quad I used the range equal to [-90,90], this makes it easy for PID control, and much easier to understand.
now, we have Y_angle, in any form that we want from accelerometer.

For the case of gyroscope we need to use what I explained here. (How to use gyroscope?)
Y_angle can be obtain by Y_angle = previous_Y_angle + angle_change_y
previous_Y_angle is the last Y_angle we found which was measured at the last time that loop was repeated.
angle_change_Y is the out put of gyro in Y axis.
Now we have measured Y_angle using gyroscope.

Now, if you think you will notice that we do not have previous_Y_angle for the first time that we start the vehicle. They are two different approach, 1) always start the vehicle when it is flat so the previous_Y_angle is zero 2) using accelerometer to find  previous_Y_angle and counting on accelerometer reading. These are the ways comes to my mind and I don't think there is any other way. You may use average or any filter in order to read the data from accelerometer, because as you know accelerometer has a lot of fluctuation. You will read that in detail in Shane's PDF later.

They are many ways to combine these values which are explained here:
http://web.mit.edu/scolton/www/filter.pdf
I have used the complimentary filter, it works fine.

this does not contain the Kalman filter, which I did not understand it myself, but you may understand it from this website: (they are some other parts that they have explained, but I think I have explained better ;) )
http://www.starlino.com/imu_guide.html
I never understood this. It is just so hard.

I think Shane has explained everything in that PDF and everyone will understand it.

The last obvious part is that after that filtering is done you have to do this:
 previous_Y_angle =   Y_angle_output_from_filter ;
this is necessary for gyroscope future readings.

Now, if you want to test your filter output read this.

Monday, 22 August 2011

How to find dt or time interval?

Well, there are two methods mostly used by people as far as I know
1) they do not measure it every single time, they measure it once and then they use it as a constant. Because the time interval is almost the same it may change for 1 to 5 percent according to my experience. They are some people out there that they use this method although it may not look so accurate but it works. If you want to use this approach you have to use the same way that will be explained in part 2.

2) You use a timer and you count number of times that your timer overflow. you times the number of time your timer overflowed to maximum amount that your timer counts plus one (plus one is needed because your timer starts from zero) and then you add the final value of the timer to result of last multiplication. Then you times that to the 1/frequency of your timer and it gives you the time in second.
   total_timer_value = (Number_of_time_ overflowed  *  (the maximum amount that timer can hold + 1) ) + timer_value_right_now 

   time_in_seconds  = total_timer_value * ( 1 / frequency_of_timer )

If you want the accurate way you have to repeat this for every loop of your program, but if your controller is not fast enough or you want it easy way then just use method one and find the dt in same way that I just explained and use it as a constant in your program.

3) (introduction does not include this)
I recently found a new way which was done by my friend Shane colton (http://scolton.blogspot.com/), he used a timer interrupt for his quad. which means that no matter what happens in every certain period of time it will start the loop from the beginning. This method can be used, but I personally can't use it because my IMU is giving me the data in serial and I can't estimate how much time I need to read the data.(I am not using interrupt to read the data from sensor, because of my sensor)

How to use gyroscope?

I told you here, that gyro gives us angular velocity. They are two common ways that most gyro use, one is I2C or Analog output. In both methods, you have to find a value which is equivalent to zero angular velocity. In order to find this value, you have to read your sensor output while it is not moving. They are few different ways to measure this value.


1) you can read the value every time that you turn on your controller, which means your vehicle has to start while it is not moving.
2) you can read this value once, and just use that as a constant in your program
3) You can read this value when ever you want and save it in dynamic memory (you will not lose it if you turn your controller off)

So far we just found a value which represent zero. Let's call this value "zero_representer".
We refer the out put from sensor, "sensor_output"
There is a factor provided by company that gives your out put in second/degree or any equivalent unit, we call this value "factor".

angular_velocity =  (sensor_output -  zero_representer)  *  factor

There is now way improving this reading as far as I know.
Now we have to integrate (in order to integrate you have to turn on a timer and count time between your readings).
dt is the time interval. they are two ways measuring this that you can find it here.

 angle_change = angular_velocity * dt   (formula # 1)
this basically shows how many degrees you have changed over an specific axis during dt.

they are ways that you can make this more accurate which is using the following procedure:
you use this formula
 angle_change =   angle_change  + ( angular_velocity * dt )
 You let this formula to run in your controller and after certain time, let's say two minutes you read the out put.  Keep in mind that during this two minutes you will not move the gyroscope.
 Now imagine in two minutes your reading is 2 degree. Which means that the rate for drifting is equal to 2degree/2min which is equal to 1 degree/min. You have to change the time unite to the same unit that you used for dt. Let's say our dt was in second, so here our rate will be 1/60 degree/second.

now we use this rate in formula #1:
    angle_change =  (angular_velocity * dt ) - (rate * dt)     (formula # 2)

now we know that this is more accurate.
As far as I know there is no other way make this more accurate.

I stop this here, you may think that it does not make any sense to calculate angle_change but later I show you how we use this.

Friday, 19 August 2011

How does gyroscope work?


Well, I am not so sure how gyroscope in exact details but I can tell you some important fact about gyros.
Gyro basically gives you angular velocity.
Let’s say you have velocity how do you find displacement? You integrate velocity and you will find displacement. Here we have the same story, we have to integrate our gyros output to find angle of headings.
There is a problem with gyros, no matter how accurate they are but they will drift. Imagine a car is sliding; the wheels are not moving so your velocity is zero but you have displacement. Same thing happens for gyros over time so they are not reliable source for reading angles that we need. The other issue is that integrating is not so accurate itself as well. How we integrate in digital world is different from what we learnt in schools. What happens is that we have to measure time interval and multiply that to your sensor reading, which gives us the area under the curve however it is not so accurate. As you can see in picture the gray parts are extra or less measured values that in long term will cause a huge error.

  So errors come in gyros reading from two factors and therefore they are not reliable to be used alone.
  These are the reasons that we can't use gyros alone.

This post needs to be better but for now this is enough :)

How does accelerometer work?

To understand this unit we'll start with the accelerometer. When thinking about accelerometers it is often useful to image a box in shape of a cube with a ball inside it. You may imagine something else like a cookie or a donut , but I'll imagine a ball:
If we take this box in a place with no gravitation fields or for that matter with no other fields that might affect the ball's position – the ball will simply float in the middle of the box. You can imagine the box is in outer-space far-far away from any cosmic bodies, or if such a place is hard to find imagine at least a space craft orbiting around the planet where everything is in weightless state . From the picture above you can see that we assign to each axis a pair of walls (we removed the wall Y+ so we can look inside the box). Imagine that each wall is pressure sensitive. If we move suddenly the box to the left (we accelerate it with acceleration 1g = 9.8m/s^2), the ball will hit the wall X-. We then measure the pressure force that the ball applies to the wall and output a value of -1g on the X axis.
Please note that the accelerometer will actually detect a force that is directed in the opposite direction from the acceleration vector. This force is often called Inertial Force or Fictitious Force . One thing you should learn from this is that an accelerometer measures acceleration indirectly through a force that is applied to one of it's walls (according to our model, it might be a spring or something else in real life accelerometers). This force can be caused by the acceleration , but as we'll see in the next example it is not always caused by acceleration.

If we take our model and put it on Earth the ball will fall on the Z- wall and will apply a force of 1g on the bottom wall, as shown in the picture below:
In this case the box isn't moving but we still get a reading of -1g on the Z axis. The pressure that the ball has applied on the wall was caused by a gravitation force. In theory it could be a different type of force – for example, if you imagine that our ball is metallic, placing a magnet next to the box could move the ball so it hits another wall. This was said just to prove that in essence accelerometer measures force not acceleration. It just happens that acceleration causes an inertial force that is captured by the force detection mechanism of the accelerometer.

While this model is not exactly how a MEMS sensor is constructed it is often useful in solving accelerometer related problems. There are actually similar sensors that have metallic balls inside, they are called tilt switches, however they are more primitive and usually they can only tell if the device is inclined within some range or not, not the extent of inclination.

So far we have analyzed the accelerometer output on a single axis and this is all you'll get with a single axis accelerometers. The real value of triaxial accelerometers comes from the fact that they can detect inertial forces on all three axes. Let's go back to our box model, and let's rotate the box 45 degrees to the right. The ball will touch 2 walls now: Z- and X- as shown in the picture below:
This is direct copy and paste from Starlino
http://www.starlino.com/imu_guide.html
since there is no better way to explain this part I just copy and paste it from this website, but I personally don't like the rest of their explanations in this topic.

Just there is something about last picture that I would like to explain as you may noticed:
square root of 0.5g is approximately 0.71g. So the resultant acceleration is:
  SQRT{  (0.71g) ^ 2 + (0.71g) ^ 2 }
which is equal to:
SQRT { 0.5g + 0.5g }
which is equal to:
1g
So we can see that when gravity is applied at 45 degree the resultant will remains at the same value because it is caused by same gravity.

Sensors for finding heading


Sensors for finding heading
Well, finding heading basically help you to balance your quadrocopter.

They are two different ways that comes to my mind for now and I tried.
    1)Using three axis accelerometer with three axis gyroscope
          2)Using three axis accelerometer with three axis gyroscope and three axis magnetometer

I have used both methods but in first method I know everything although in second method I am not that sure, because I used 9 Degrees of Freedom - Razor IMU which has all three sensors. I never wrote my own program for it. It has few problems but in future I will go through it and solve them
If you are not that pro, I suggest you use the first method which is very simple.

I explain full detail about using method one in following link:

I explain full detail about using method two in following link:


Start of Blog

Hi
I am starting this web site just because I have nothing else to do for three days. I promise to keep this work up and help you in your projects. Right now I can see many stuff for designing my blog but it takes a long time and I think later on I can spend more time for it.
wish you a great time