Gyro Repeatability, Expected Drift ?

  1. Does anyone know what gyros were in previous First kits (or how to interpret the printing on the gyro case) ? I’m using one mounted on a dark green PCB for testing. (FIRST: Please consider printing the year on the PCB & the gyro part number too!).

  2. I’m using KWs gyro code and have read everything I can find. I have the gyro mounted on a wooden board with a compass rose on it. The chip is accurately mounted in the center with a pointer. After calibration, it largely seems to work. I can rotate it 180 degrees (fairly slowly) and get pretty close to 180 reported (actually 1800). But many times when I return it to zero, it will be 5-10 degrees off in either direction and from then on everything is off. Any idea how repeatable measurements should be on a desk ? on a robot (with all its vibration etc) ? Any suggestions ? Since I don’t know what the chip is, the software is currently set to a adxrs150.

There is significant evidence that the max rate the gyro can turn must be fairly slow else the reported numbers will be way off. But even when I rotate it slowly, its repeatability can be off by 5% or more. Is that normal ?

Kevin’s code implements a deadband. Although this is just fine
for using it to measure a turn, it is not so good for using the gyro
as a compass.

Using the gyro as a compass requires you to be entirely linear
with no deadband, and to carefully average the “no turn” output
(noise helps you here) and subtract the value using fixed binary
point arithmetic. Second order accurate time integration is also
a good idea in this case.

A drift of a couple of tenths of a degree during the 15 second
autonomous mode is achievable, but the drift is sensitive to
temperature and you either need to recalibrate, or compensate,
for that. What we do is check the drift now and then, and then
recompute the required average when the drift has picked up
due to temperature change.

Eugene

Yes, there is a deadband, but it only comes into play if the gyro’s output is within a few DN of the bias point. As long as your 'bot rotates at a rate above a few DN, every sample is included in the integration (I would argue that every FRC 'bot rotates above this rate, which is less than a degree per second). So, unless I’m missing something (which is entirely possible :)), I don’t see how it’s a problem.

-Kevin

Kevin,

You are indeed missing something. By carefully averaging
the no rotation signal, you can obtain accuracy (on average)
that is better than the ADC quantization. This improved
accuracy shows up in the resulting time integral of the gyro.

I would happily share our gyro code with you if you would
like to explore it, use it, or make some version of it generally
available. I have learned a lot about PIC interrupts studying
your code, perhaps you have one small thing to learn by
studying mine. The code, however, also uses methods to
avoid race conditions that I remember, quite well, you don’t
like.

Eugene

I certainly understand how some noise components can help improve resolution, but I just don’t see how integrating gyro noise when the 'bot is known to be still can help. Yes, I realize a deadband would cause problems in applications where precise low angular rate measurements need to be taken, but that doesn’t apply to many FRC 'bots.

Can you point me toward a paper or anything else that can help me understand your point? And yes, please send me any code you have that I can work with. I think we have a rate table at work and it might be fun to see if I can get some freebie time on it to take some data.

-Kevin

I’m not a fan of using the gyro for absolute angular position, not even over the short fifteen seconds of Hybrid mode. I do believe, however, that there are solutions that will let you do what you want with relative ease, at least over fifteen seconds:

A) Only use what the gyro actually gives you, the angular velocity. For example, for the relativly simple task of driving forwards, don’t compare the angle to zero, compare the rate of change in the angle to zero. That way you don’t have to deal with the integration.

B) In order to make turns, that do require the angle measurement, more accurate, you can look at the angle relative to where you’re now. I’ll give you an example. Say you’ve been driving roughly straight, and your angle is now 2 degrees. If you want to turn 90 degrees, set your target to 2+90 = 92, instead of to ninety. Now lets say you turned your about 90, drove straight again, and due to some drift, you’re now around 110 degrees. You want to turn ninety again, so you should probably set your target to 110+90 = 200, instead of 180. I imagine this might work better.

Any thoughts?

There is an old white paper posted on CD
http://www.chiefdelphi.com/media/papers/1449
as noted in the white paper, this game is relatively
standard in the signal processing business.

Assuming that you have a gyro that has inherent noise
that is larger than the quantization error, for a stationary
robot there will be a sequence of random (integer) values
returned by the ADC. What you want is the average and
this is not an integer. Obtaining this average, in suitable
precision, is the goal of sampling the gyro for a suitable
length of time while the robot is known to be still.

We represent the average in binary fixed point, a 32 bit
value in 256ths, so to speak. We then use this average
as the zero value for our time integration. It is very
straight forward to do, using the trapezoidal rule we
just shift the old value and the new value up by the right
number of bits before we subtract the average.

The resulting accuracy is good enough that the temperature
dependent drift of the gyro can become significant.
We address this by watching the drift of the integral and
re-measuring the required average when the drift becomes
larger than we want. Another approach is to read the temperature
output signal provided and compensate.

I’ll package our code for this year’s robot in a zip file and
put it in a place accessible to you and send you an email
when I have done that.

We’d be interested in seeing this code as well. We’re using the gyro code from WPILib, but it’s apparently unsuitable for anything other than just driving straight. We finally just gave up on using the gyro for turns and now count gearteeth.

Ouch. I was hoping there would be a simple answer like yes this is normal or no its defective or something !

Thanks for the suggestions on how to handle it. yes I would love to see the code too.

Being a brand new user of gyros (haven’t even had the time to figure out what technology they are based on, obviously not a spinning top), I’m obviously trying to run up the learning curve as fast as possible.

I’m hoping the lack of repeatability may not be a show stopper for the 15 seconds. But I am concerned the rate of the First gyro may be too slow. Its probably too late for us to get a 300 deg/sec one.

Are many teams able to do relative extreme navigating using the gyro (and perhaps the gear tooth for straight travel) ? By extreme, I mean, at least one 90 degree turn or better still three 90s (ie one loop around the course) ?

Kevin, is it possible for you to give a 20 word description of this deadband, its magnitude and how it comes in to play for repeatability ?

Thanks

Our robot is capable of doing repeatable 90deg turns just using the gear teeth sensors. It’s not perfect, and it depends on traction, but we couldn’t get the gyro to behave reliably. We were consistently getting 3 lines, and had the IR worked at a greater distance we could have hit 4.

Team 435 can do a full lap plus in automode using the KoP gryo for both the turns and maintaining alignment while driving straight. We are using a modified version of Kevin’s code. (QuickADC and only reading the gryo once every 26ms.)

Last year we were unsuccessful with using the gryo, the robot’s momentum would carry it past the 90 turn and we were never able to get a consistent turn amount.

What sample rate are you running at?

In 2005, we ran many tests with sample rates from 200hz to 12800 hz. While we have since lost the raw data from the tests, the results were that we saw improvements in performance up to 1600hz and beyond that there were no noticeable improvements. We have since always used 1600hz and get results that are repeatable to within the accuracy of our measurement method.

Dr. Brooks’ marklars are wise and true :slight_smile:

One of the best thing that you can do to help reduce the drift is use a very large average during disabled mode to get the sensor bias, and don’t throw out resolution when you’re done with the average.

I think I posted a similar example in a different thread within the last couple months, but here is an example of what you want to do.

  • assume you want to use a 32-bit variable for your integral.

  • Let’s assume we want to use a 64 sample average to get the sensor bias. Use the following code to calculate your bias (do this code ONLY in disabled mode).

        
tempAngRate = Get_Analog_Value(angRate);
angRateBias = (angRateBias - angRateArray[angRateBiasCounter]) + tempAngRate;
angRateArray[angRateBiasCounter] = tempAngRate;
angRateBiasCounter++;
if (angRateBiasCounter > 63)
{
    angRateBiasCounter = 0;
}

  • Once disable mode is over, the above angularRateBias value contains the bias of the sensor. Just note that it is a 64 sample SUM, but you can think of it as the average * 64. At this point you DO NOT want to divide by 64, since you would then be throwing out the “decimal portion”. Just multiply you A/D sample by 64 to bring it up to the same resolution of the bias value. See the following code:

angRateValue = Get_Analog_Value(angRate);
robotHeading += (s32)angRateValue*(s32)64 - angRateBias

Now you have a nice integral with 6 bits worth of fractional-resolution. If you want your fractional portion to be 7 bits, use 128 samples in the average, etc.

Well, let me just say the KOP isn’t very good and that you’d be better off using a ADXRS300 for this application.

You could probably overnight one from SparkFun.

Yes, quite a few. Team 1024 sent me this link to a match at Chicago where they do 1.5 laps in autonomous.

This is the code we’re talking about:


*// get the latest measured gyro rate*
temp_gyro_rate **=** (**int**)**Get_ADC_Result**(GYRO_CHANNEL) **-** gyro_bias;
 
*// update reported gyro rate and angle only if *
*// measured gyro rate lies outside the deadband*
**if**(temp_gyro_rate **<****-**GYRO_DEADBAND **||** temp_gyro_rate **>** GYRO_DEADBAND)
{
// process gyro data
}
**else**
{
gyro_rate **=**0;
}
 

If the turning rate is very, very small (i.e., less than a degree per second) the data is thrown away and not used in the rate or angle calculations. This can improve the angle estimation because we’re not including (actually, integrating) the measurement noise while the 'bot is not rotating. How do I know the ‘bot isn’t rotating? Well, I think it’s a safe bet that most, if not all, FRC ‘bots are incapable of rotating at these rates. This has no effect on repeatability (someone else mentioned that these gyros may have a problem where the sensitivity may be different between rotating CW versus CCW, which may be what you’re seeing). Using my code and a pretty good Silicon Sensing Systems’ CRS03-02 gyro, my Vex ‘bot can drive the edge of a 4’ x 4’ square for twenty minutes and not deviate more than a few degrees over that period .

Now, Eugene is suggesting (I believe) that I don’t need a deadband if I use a higher resolution bias value in my calculations and he may be right. I’m already oversampling the signal, so I don’t know if I can really do much better without using a better ADC.

Eugene is also using trapizoidal integration, which works great at lower sampling rates, but doesn’t help much (I suspect) at the high rates I sample the gyro at. I have a version that uses trapazoidal integration, but I haven’t taken the time to do much testing (I wiil though).

Sorry, it’s a few more than twenty words <grin>.

-Kevin

Edit: Okay I just read Chris’ posting and I believe we’re on the same page now. I’m already oversampling the gyro output to reduce the effects of gaussian noise sources and to gain resolution through interpolation, which is what Chris discusses in his posting. For the bias calculation, I use a circular buffer to store the last sixty-four Gyro rate updates (each update contains the average of many gyro samples) and when Stop_Gyro_Bias_Calc( ) is called (presumably just as autonomous period starts), I add up those sixty-four samples and use that value for the bias. The difference is that I don’t retain all of those ~18-bits for use in my calculations. I only retain what theoretically makes sense. Classic textbook oversampling and decimation theory states that for every extra bit of resolution, a signal must be sampled four times and the results added together (this is the oversampling part) and then divided by two (the decimation part). This is exactly what I do in my code.

Now is it possible that I may be discarding valid data when I do the decimation? My understanding of the theory says no, but there could be some aspect of the theory that I don’t fully understand. Either way it’ll be fun to try it out to see if I can wring a little more performance out of the FRC gyro.

-Kevin

**Another edit: **I Googled and found an excellent application note that discusses the theory behind my code. It’s for Atmel AVR microcontrollers, but it’s also applicable to the PIC in the FRC robot controller.

-Kevin

If you carefully tune the gyro, with no deadband, and use it as a
compass; you can feed the error in the heading back into the
motor power. It keeps the robot on track when it gets bumped,
and it automatically corrects for overshoot in turns.

Eugene

We do our averaging to get the bias in the pit where we can be sure
that the robot is not disturbed while the data is being taken. The
resulting number is then hard coded.

I will be heading to SanJose this evening, but I can post
snippets of the code I use from there and will be happy to do so.

re sparkfun’s ADXRS300.

In light of the lack of time and my inexperience, I need to ask a dumb question. Is it as simple as hooking up VCC, GRD and RateOut as per the FIRST one, change the def in gyro.h and go ? (or is there any other hardware etc needed ?

Thanks everyone.

Dr Brooks:

  • would greatly appreciate your code spinnets.
  • what gyro chip is your team using ?
  • given you calculate the bias in the pits and hard code it, am I correct that the bias is individual chip by chip specific and is temperature specific but once in a stable temperature, it can be calced and hardcoded for the duration of the regional ?

Kevin, thanks for the clear coverage on the deadband. I can see why you do it. We are looking closely at the Sparkfun unit. We are just waiting for clarification as to whether using it is as simple as connecting the 5v, grd and rate to AI 1. Unfortunately due to our location, it will cost us over $60 in shipping alone :frowning:

Looking at their schematic, it should be that simple.

I’ll tell you what, if you’re not happy with the performance of the gyro, I’ll reimburse your team for the cost of the gyro plus shipping (yes, I’m serious :D).

-Kevin

We do ours immediately before every match by using the disabled_mode flag. In other words, we’re running a moving average right up until they enable the robots. Since everyone is required to be off the field for the last few seconds before the match start, you’re pretty much guaranteed to get have the robot undisturbed and still, and you get the bias as close to what you’re going to have in the match.

The code is more or less:


static char runBais = 1;
if (disabled_mode && runBias)
{
    // run moving-average bias code
}
else
{
    // the bias has now been captured and is held
    // don't let the bias run again if the robot is disabled for a short period of time
    runBias = 0;
    // run integral code
}