Gyro - lisy300
Beau Schwabe
Posts: 6,566
This topic comes up from time to time, and if you've ever gone down the road of reading a Gyro or Accelerometer, you know the difficulties in determining a reliable position.
Here is a method that I have used that works well. Keep in mind however A Gyro by-itself will have drift as would an Accelerometer. To get the most accuracy, it would be ideal to combine the efforts of different types of sensors.
Tilt Orientation is also critical for a Gyro... Take this for example: If you orient a Gyro such that the rotational axis is horizontal and rotate it vertically (Perpendicular to the axis) you would expect Zero amount of influence and this would normally be true. However it's nearly impossible to rotate it exactly perpendicular to the axis, thus there would be a slight amount of 'drift' in the rotational reading. The opposite is true if you don't rotate the Gyro exactly on the intended rotational axis, you can also have a slight 'drift'.
Here is a method that I have used that works well. Keep in mind however A Gyro by-itself will have drift as would an Accelerometer. To get the most accuracy, it would be ideal to combine the efforts of different types of sensors.
Tilt Orientation is also critical for a Gyro... Take this for example: If you orient a Gyro such that the rotational axis is horizontal and rotate it vertically (Perpendicular to the axis) you would expect Zero amount of influence and this would normally be true. However it's nearly impossible to rotate it exactly perpendicular to the axis, thus there would be a slight amount of 'drift' in the rotational reading. The opposite is true if you don't rotate the Gyro exactly on the intended rotational axis, you can also have a slight 'drift'.
Theory of Operation: There are a few things that need to happen to the RAW data in order to determine a relative Deg value. As it is, the RAW data has a value associated to it of Deg/sec but there is no real weight or meaning to that value if you don't integrate time with the reading. It's just an arbitrary unit of measurement without time associated to it. We need to integrate time into the equation in order to get a valid Deg value. The easy way to do this is to clear an accumulator, take as many RAW readings as you can in a fixed or known amount of time and add those readings to the accumulator. An initial reading of the accumulator is used as a Reference to 'normalize' the remainder of the data. This isn't the best approach, but it will work for this demonstration. It's basically a single value that represents several data samples and could be looked at as though it were an average although we aren't dividing it over a number of samples like you would with an average. Ideally this value would be dynamic and track over time instead of an initial reading up front. So, the remaining values from the accumulator are subtracted from the Reference value, and added to a Rotation accumulator. The number of Samples taken within the fixed amount of time can be calculated (or even directly counted) by dividing the initial accumulator value by 512 (<- the mid position of the 10-Bit ADC representing Vdd/2) In the program Example the 'fixed time' is 1/50th of a second and the calculations are basically as follows... Hope it helps.
Comments
This looks like exactly what I have been trying to do! However I am using a Stamp 2. Will this method work on the Stamp 2 and how can I read the spin files to try and understand what's going on?
With the Propeller it is easy because you have multiple threads and can keep a good timing loop. With a BS2 it's a little more difficult, but not impossible. To do so you need to implement some sort of accurate external time base ... Something as simple as a CD4020B with a 1MHz crystal would give you 61.035 Hz ... If that's still too fast another 4020 or 4040 stage divider should get you there. The critical point here is that you know exactly what the time base is.
Since the Gyro reports in Deg/sec you are basically solving for Deg by eliminating or canceling out the time mathematically.
Here is a basic Flow-Chart of what you could do with a BS2... Keep in mind during the periods that you are determining the Degree, in other words NOT in the timing loop reading the Gyro, you are losing accuracy.
I'm sure there is a fundamental detail that I just don't get. The data sheet for the module describes full scale rotation detection up to 88 Hz. If it updates 88 times a second why would you need to take samples any faster than that? Does "up to 88 Hz" mean that the updates occur at different rates?
Sampling at a higher rate has to do more with the Nyquist sampling rate and increasing your overall signal to noise ratio. This is true for any kind of sensor, not just a Gyro.
The 88Hz is only from the Gyro itself and is useful for determining what rate it should be sampled at. The ADC that is connected to the Gyro can be read at up to 4MHz.
Nyquist dictates that you should at least read the sample twice as fast as the data rate ... 176 times per second ... to obtain a signal to noise ratio of 1
The second part of this is noise. The ADC will generate plenty of noise from external influences such as temperature, RF, etc. One way to help reduce random noise and increase your signal to noise ratio is to sample above the Nyquist.
For example if you sample at four times the data rate from the Gyro (352 times per second), you increase your signal to noise ratio by a factor of two!!! ... How?
If you sum four samples, you get a value four times larger. If you sum the noise from four samples, the result is only two times larger. That's because the noise is sometimes positive, sometimes negative, at random. When you add random positive and negative numbers together, they have a way of canceling each other out.
Thus, when you sum four samples, the 'signal' grows four times, but the 'noise' grows only two times. In this case, the signal/noise ratio increases by a factor of two.
agfa
Many thanks for posting this method of angle determination.
I must apologize, but I don't understand the theoretical reasoning regarding some of the algorithm aspects such as why an initial number of readings are used in "normalizing" subsequent data whereby these readings aren't averaged which intuitively seems the logical thing to do. Is there a name for this method where I can do further reading on it?
Also, how would the results of this method compare to the standard approximation method of taking many gyro readings whereby each reading is multiplied by the time difference in order to obtain an integration value (or using a more precise method of integration)?
In advance, thank you!
"why an initial number of readings are used in "normalizing" subsequent data whereby these readings aren't averaged which intuitively seems the logical thing to do." - In a sense they are average integrated with time and treated as a whole sum rather than divided by the number of samples. Dividing introduces truncation errors.
By 'normalizing' , the data is subtracted from an initial reading ... this basically just biases the Gyro delta to Zero before it gets added to the accumulator.
"Also, how would the results of this method compare to the standard approximation method of taking many gyro readings whereby each reading is multiplied by the time difference in order to obtain an integration value" - The result should be the same. Multiplying individual readings by the time difference should have the same answer as multiplying a sum of several readings by the time difference and dividing by the number of data samples.
The difference in the algorithm that I am using, is that the division by the number of samples to obtain an average happens 'outside' of the timing loop. This eliminates any truncation errors that may have a compounding effect when calculating an average within a critical timing loop.
What I am doing is really no different than the standard approximation method.
I'm working on this on the side between projects. The L3G4200D reports its data slightly differently, so I'm adapting Beau's algorithm appropriately.
Daniel,
Did you ever successfully adapt this algorithm for the L3G4200D?