Page 1 of 8
hitechnic Gyro sensor (NGY1044) noise
Posted: 03 Oct 2010, 22:20
by loopymech
I recently bought the hitechnic Gyro sensor (
http://www.hitechnic.com/cgi-bin/commer ... ey=NGY1044) and immediately built the HTWay with great success. More accurately, my son built it, while I provided superb assistance (staging the parts, d/l'ing & installing the pre-fab code, paging thru the pdf file instructions as needed). You know...the heavy lifting - haha.
I didn't have the IR Receiver, so I just stubbed out the one or two related blocks and settled for a bot that could stand in place. Very fun to build and watch it go. Later, I also added bluetooth remote using a second NXT and HT Accel sensor.
Regarding sensor noise:
I've since tried some ad-hoc testing with the gyro (using NXT-G) - doing things like integrating the output, setting the offset both manually and automatically (using code examples provided). What I found is that I need to set a pretty sturdy (read 'wide') dead-band near zero in order to keep from integrating noise and have the results go drifting to the moon. I think I ended up with +/- 8 for the dead zone, and that seems like an awful lot to me.
Anyone else have similar experience or know of some good noise cancellation methods? Would be kinda nice to know the expected noise level specs for the sensor if anyone knows where to find that data.
-Loopy
Re: hitechnic Gyro sensor (NGY1044) noise
Posted: 04 Oct 2010, 05:15
by mightor
Loopy,
gyros are prone to drifiting. I was having the same issues you were having with my omniwheeled robot. I used the following (ROBOTC) code to solve this problem:
Code: Select all
// Task to keep track of the current heading using the HT Gyro
task getHeading () {
float delTime = 0;
float prevHeading = 0;
float curRate = 0;
HTGYROstartCal(GYRO);
PlaySound(soundBeepBeep);
while (true) {
time1[T1] = 0;
curRate = HTGYROreadRot(GYRO);
if (abs(curRate) > 3) {
prevHeading = currHeading;
currHeading = prevHeading + curRate * delTime;
if (currHeading > 360) currHeading -= 360;
else if (currHeading < 0) currHeading += 360;
}
relHeading = round(currHeading - targetHeading + 540) % 360 - 180;
wait1Msec(5);
delTime = ((float)time1[T1]) / 1000;
}
}
So I have a dead band of +/-3 and that seems to work fine. I used this code for my spinning omniwheels and as you could see from the
video, it works quite nicely.
- Xander
Re: hitechnic Gyro sensor (NGY1044) noise
Posted: 04 Oct 2010, 14:32
by aswin0
Hi,
All sensors are noisy. To cancel out the effects of noise you'll have to understand your sensor well. The gyro has four aspects to keep in mind.
First, it needs an offset. When determing the offset you already have to take noise into account. That is why you shouldn't base your offset on a single measurement. It is better to take the average of multiple measurements. I think Xander uses four measurements but I normally take 100. When determing the offset you'll also have to give the sensor some time to stabilise after shutting it on. That's why it is best to add a time-out before you start determing the offset.
Second, there is always some random noise in sensor readings. For the gyro sensor this random noise has is 1 or 2 degrees in most cases. Add one degree as a margin and you have the dead zone of 3 degrees that Xander uses.
Third. Not all the noise comes from the sensor itself. Also the robot or the environment can cause additional noise. Things like surface, tires, the mounting of the sensor and plate tectonics
are obvious causes of additional noise.
Fourth, a gyro suffers from drift. This means that the offset changes (in one direction) over time. If you are lucky you can compensate for that using another sensor. But this isn't easy, for this other sensor is noisy too. Drift is the one of the reasons why most self balancing robots ultimately do loose their balance.
To cut a long story short. Look at the offset you use and try to minimize the noise from external sources.
Re: hitechnic Gyro sensor (NGY1044) noise
Posted: 05 Oct 2010, 00:51
by dhystad
Instead of noise is sounds like you have an offset. The nice thing about a gyro (as opposed to an accelerometer) is that unless you mount it on something that is spinning the average output of the gyro over time should be zero. To remove the offset on such a device I suggest using a simple filter. Something like this:
offset = sensorValue
LOOP BEGIN
offset = offset * 0.99 + sensorValue * 0.01
offsetSensorValue = sensorValue - offset
... use the sensor value ...
LOOP END
I'm just guessing at the gain value of 0.01.
A gyro sensor is going to be noisy (signal value changes quickly and often) due to the nature of what it is measuring. Usually this is OK, because it will the frequency of the noise far exceeds your ability to respond. But if you want a smoother looking signal you can use a similar filter to remove the high frequency content. Something like this:
offset = sensorValue
filteredValue = sensorValue
LOOP BEGIN
filteredValue = filteredValue * 0.75 + sensorValue * 0.25
offset = offset * 0.99 + sensorValue * 0.01
offsetSensorValue = filteredValue - offset
... use the sensor value ...
LOOP END
Again, the gain of 0.75 is just a guess.
You can make much more sophisticated filteres that only remove signal content below and/or above the desired frequency range, but this works well for many applications.
Re: hitechnic Gyro sensor (NGY1044) noise
Posted: 05 Oct 2010, 06:23
by loopymech
thanks guys...awesome feedback. Much appreciated!
I was using the 100 sample average (or more) method to obtain a good offset, but I had not thought to use a wait before grabbing samples. Nor had I thought of filtering by frequency - greats ideas. Also, very interesting how Dean's filter constantly feeds new sensor readings back into the offset - presumably to cancel drift. I think the HTWay code uses a similar technique.
I was thinking drift had to be a big part of the problem I was seeing, since random noise should more-or-less cancel itself out in a average but I was seeing compounding error.
-Loopy
p.s. Nice bot, Xander...fun to watch it whirling around...I suppose that makes it hard to navigate by compass tho.
p.p.s. Ahhhhh...of course! I keep forgetting to compensate for the plate tectonics!
Re: hitechnic Gyro sensor (NGY1044) noise
Posted: 05 Oct 2010, 06:48
by physics-matt
loopymech wrote:
I was thinking drift had to be a big part of the problem I was seeing, since random noise should more-or-less cancel itself out in a average but I was seeing compounding error.
If you're integrating the output, then even just random zero-average noise will cause the result to appear to "drift" over time. This is because even though the average of these values is zero, the probability that the sum of these values is anywhere near zero at any one point in time becomes very small.
Matt
Re: hitechnic Gyro sensor (NGY1044) noise
Posted: 05 Oct 2010, 08:06
by mightor
That is something I noticed before I added the "don't integrate unless the value - offset is more than 3". The heading would drift with almost a degree per second, which is an awful lot when standing perfectly still
- Xander
Re: hitechnic Gyro sensor (NGY1044) noise
Posted: 05 Oct 2010, 17:17
by aswin0
A drift of one degree a second? I think this can't be just drift. It would mean that the sensor returns only 0's or 1023's after about ten minutes.
Yesterday a measured drift over a time span of 3 minutes and found values of 0.16 degrees a minute. The measurements were made on a motionless robot and I used a proper statistic method.
I like the method from above where the offset is constantly adjusted. But one should be aware that this only works in situations where there is a a state of equilibrium as in a balancing robot.
Re: hitechnic Gyro sensor (NGY1044) noise
Posted: 05 Oct 2010, 17:47
by mightor
Aswin,
This is the code I had back then:
Code: Select all
#pragma config(Sensor, S3, GYRO, sensorRawValue)
//*!!Code automatically generated by 'ROBOTC' configuration wizard !!*//
#include "drivers/HTGYRO-driver.h"
// Current heading of the robot
float currHeading = 0;
// Task to keep track of the current heading using the HT Gyro
task getHeading () {
float delTime = 0;
float prevHeading = 0;
float curRate = 0;
HTGYROstartCal(GYRO);
PlaySound(soundBeepBeep);
while (true) {
time1[T1] = 0;
curRate = HTGYROreadRot(GYRO);
prevHeading = currHeading;
currHeading = prevHeading + curRate * delTime;
if (currHeading > 360) currHeading -= 360;
else if (currHeading < 0) currHeading += 360;
wait1Msec(5);
delTime = ((float)time1[T1]) / 1000;
//delTime /= 1000;
}
}
/*
Main task
*/
task main () {
StartTask(getHeading);
wait1Msec(500);
while (true) {
nxtDisplayBigTextLine(2, "%3.2f", currHeading);
wait1Msec(50);
}
}
Watch the calculated heading increase by a couple of centi-degrees per second. I am obviously doing something wrong, but I am not sure what.
- Xander
Re: hitechnic Gyro sensor (NGY1044) noise
Posted: 05 Oct 2010, 21:34
by aswin0
Xander,
I think the problem comes from using an integer type offset in the HTGYRO-driver. This is an approximation of the true offset. The error in the offset adds to the error in the calculated heading everytime it is updated with a new reading. So it is not drift your seeing but the accumulation of errors.
The solution might seem simple, change the offset to a float. But the nasty thing is that you would alsoe have to change most of the functions in this driver as well.