View Full Version : Yaw Sensor
Phil_Lutz
11-02-2004, 21:02
Can someone tell me how to operate a Yaw Sensor?
Where is it hooked up on the robot controller. Digital or Analog.
We did printf's to see what settings were occurring as we rotated it around, but the code only ever showed 135.....
Help.
Thanks,
Phil
KenWittlief
11-02-2004, 21:13
the yaw sensor is an analog device - and you have to supply it with power on its +5V pin - you should see it sitting at 127 or 128 when the bot is not turning, and go up to 254 and down to 0 if you turn the robot fast enough
also, make sure you know the axis of rotation for the sensor - it only senses rotation on one axis.
FotoPlasma
11-02-2004, 21:27
the yaw sensor is an analog device - and you have to supply it with power on its +5V pin - you should see it sitting at 127 or 128 when the bot is not turning, and go up to 254 and down to 0 if you turn the robot fast enough
also, make sure you know the axis of rotation for the sensor - it only senses rotation on one axis.
None of the FIRST-supplied Yaw Rate Sensors I have had the privilege to play around with have had different neutral outputs. Some have been upwards of 140, while others have been below 110. If you want to effectively utilize any of these Yaw Rate sensors, you'll have to find out what the neutral output is, and use that as your static state. This will limit the sensing ability of the sensor in one direction, while increasing the sensor's ability in the opposite direction (however slightly, in either case, depending on the deviation from "normal").
Also, the Yaw Rate Sensor supplied for the 2003 season has a higher angular rate capacity than the sensors provided in previous years. The 2003 sensors had a theoretical (according to the datasheet) maximum of 75deg/sec, while previous years' had a theoretical maximum of 64deg/sec.
Phil_Lutz
11-02-2004, 21:31
But even with the sensor reading 137, when we move the sensor in ANY direction, tilting up/down, or rotating left/right, no change in the 137 value.....
Thanks,
Phil
FotoPlasma
11-02-2004, 21:39
If you're patient enough, you can take the sensor off the control system and supply it with 5V, connect GND, and use either a multimeter or an oscilloscope to watch the output to see if it changes at all, or even if the normal output is around 2.66V ((5/254)135).
On the other side of things, you can try to determine whether the analog input to the control system is working properly. You can connect a regular potentiometer to the analog input, and see if the read value changes respectively. If that fails, I would check to make sure that the potentometer works properly, etc.
Hope this helps.
seanwitte
11-02-2004, 21:50
Can someone tell me how to operate a Yaw Sensor?
Where is it hooked up on the robot controller. Digital or Analog.
We did printf's to see what settings were occurring as we rotated it around, but the code only ever showed 135.....l
What part are you using?
the yaw rate sensors are analog, and you need to call Get_Analog_Value() on the variable in order to get the actual value. reading it directly won't work (and it looks like that's what you're doing).
also, remember that the analog inputs on the rc are now 10-bit, so without moving the sensor, you should get a reading around 512.
hope that helps.
Mark McLeod
12-02-2004, 12:07
But even with the sensor reading 137, when we move the sensor in ANY direction, tilting up/down, or rotating left/right, no change in the 137 value.....
Thanks,
PhilAs a double check here is the test code we used on the EDU controller.
Hold the gyro level and twist it quickly 90 degrees or more in the horizontal plane.
// this assumes in User_Initialization() at least...
IO1 = INPUT;
Set_Number_of_Analog_Channels(ONE_ANALOG);
// in Process_Data_From_Master_uP():
unsigned int gyro;
static unsigned long gyroSum=0;
static unsigned int counter=0;
/* This sample assumes a 26.2ms loop */
gyro = Get_Analog_Value(rc_dig_in01);
gyroSum += gyro;
counter++;
if (counter > 40)
{
gyroSum = gyroSum/counter;
printf(" gyro = %d \n", (int)gyroSum); /* values are in the range 0-1023 */
counter = 0;
gyroSum = 0;
}
[edit] Fixed small bug in printf. We use different print functions, Sorry.
Phil_Lutz
12-02-2004, 17:32
As a double check here is the test code we used on the EDU controller.
Hold the gyro level and twist it quickly 90 degrees or more in the horizontal plane.
I will test this code out tonight.
Boy am I new to this stuff.
Coding no problem, but a Robot isn't a Database. :)
Thanks,
Phil
Larry Barello
14-02-2004, 10:16
Here is the code from team 492's current robot. It uses the ADXRS150 evaluation board. They are available from Future, but I got ours as samples directly from Analog. The basic code works for any gyro, you just need to adjust the various #defines.
Wiring is simple too. The evaluation board is a 20pin dip. You need to connect two pins to ground and two to +5v and one pin is the output. A standard three conductor servo cable is all you need. I put ours on a bit of breadboard + a socket along with some other stuff.
Note, our code is called at 100hz. The Gyro has a bandwidth > 40hz so you want to sample it much faster. It wouldn't hurt to sample at 200-400hz, but 100 seems good enough. 38hz (the 26.2ms loop rate for IFI) is too slow.
Also note, below, that our observed scale was more like 200deg/sec range vs the specified 150. The scale changes with temperature, so if you want really accurate results you need to use the built in temperature sensor to compensate. I am going to just calibrate at the competition and trust that the temperature will be reasonably constant over the day.
/********************** Gyro Task ***************************************
Gyro output is from .25 to 4.25 volts/5v range. ADC is 10 bits.
Full scale output is +/- 150 deg/sec. Sampling rate is SYSCLOCK hz.
Adjust FULLSCALEINPUT & OUTPUT to match the observed values
so that when the robot is turned 360 deg the reported angle is
360. Double check by returning robot to starting position and
verifying angle is 0.
Note: The gyro reading is 10bits, but I shift it over 4 to get a 16 bit value.
This allows a fractional "offset" value which, when integrated over time
will give a more accurate "zero" value.
*/
#define FULLSCALEINPUT (203.0 * 2.0)
#define FULLSCALEOUTPUT (1023.0 * 16.0)
#define PERIOD (1.0/GYROCLOCK)
#define GYROSCALE (FULLSCALEINPUT * PERIOD / FULLSCALEOUTPUT)
// GyroTask called at the primary loop rate of 100hz. Delay 1.28 seconds before
// setting the basic gyro offset. Gyro seems stable enough to last the 2 minute
// match without drifting significantly. Only high speed turns will mess it up.
#define GYRODELAY 128
int InitGyro = GYRODELAY;
int GyroOffset;
int iGyroTheta, iGyroRate; // These are Zero at boot time
long temp;
float fTheta = GYROSCALE;
void Gyro_Task(void)
{
int GyroVal = GetADC(Gyro) << 4;
switch(InitGyro)
{
default: // Delay until stable reading
InitGyro--;
temp += GyroVal;// Get average ADC value over 1 second
break;
case 0:
InitGyro = -1;
GyroOffset = temp / GYRODELAY;
break;
case -1:
iGyroRate = GyroVal - GyroOffset;
fTheta += (float)iGyroRate * GYROSCALE;
iGyroTheta = fTheta; // Make integer version available.
break;
}
}
KenWittlief
14-02-2004, 17:34
only thing I disagree with on your post is the sensor has a bandwith of 40Hz or so, but your bot is heavy enough that IT wont have a bandwith anywheres near the 26mS sample loop
your motors will not be able to spin the bot around so quick that you need to worry about the bandwidth of the sensor
if your bot is jittering and twitching at 38Hz, you've got more problems to worry about than using a gyro :c)
WizardOfAz
25-02-2004, 10:41
I want to sample some analog inputs at 4ms.
The first way I tried this was to set up a timer interrupt at 4ms and in the ISR, set a tic4ms flag. Then in the polling loop, whenever the tic4ms flag was set, I'd clear it and run the sampling code. The problem with this is that my main processing, which runs every 26ms, uses about 9ms and I miss some of the 4ms tics.
Next try was to read the analog inputs in the ISR itself. I hoped that doing
#pragma interruptlow InterruptHandlerLow save=PROD, section(".tmpdata")
would save enough context, but it evidently does not - I am getting a smattering of wild data now in the main polling process. First I thought this was because I was calling Get_Analog_Value in the ISR as well as in the main process. Get_Analog_Value uses some SFRs, and they are not saved across the interrupt, so this would be expected to at least give some bad samples if not worse data mangling. But I moved all the analog sampling to the ISR so Get_Analog_Value would be called from only one thread. This did not eliminate the problem.
Anybody have suggestions?
Also, my assumption is that Get_Analog_Value only runs a few tens of microseconds (15-30 or so) so I can do many of them in a 4ms ISR w/o an overrun problem. This is what it looks like in the pic datasheet. Can anyone confirm this?
Thanks for any help.
Bill
Larry Barello
25-02-2004, 11:27
...
Next try was to read the analog inputs in the ISR itself. I hoped that doing
#pragma interruptlow InterruptHandlerLow save=PROD, section(".tmpdata")
would save enough context, but it evidently does not - I am getting a smattering of wild data now in the main polling process. First I thought this was because I was calling Get_Analog_Value in the ISR as well as in the main process. Get_Analog_Value uses some SFRs, and they are not saved across the interrupt, so this would be expected to at least give some bad samples if not worse data mangling. But I moved all the analog sampling to the ISR so Get_Analog_Value would be called from only one thread. This did not eliminate the problem.
Anybody have suggestions?
Also, my assumption is that Get_Analog_Value only runs a few tens of microseconds (15-30 or so) so I can do many of them in a 4ms ISR w/o an overrun problem. This is what it looks like in the pic datasheet. Can anyone confirm this?
Thanks for any help.
Bill
According to the C compiler manual you need to save additional context when calling functions that return values. Specifically, for 8 & 16 bit return values you need to save 'PROD'. I believe it is page 28...
Team 492 samples the ADXSR150 at 100hz (10ms). Our basic logic is a 1khz timer that increments a byte counter (atomic operation). In the fast loop of the IFI code we check that counter and do stuff when it increments.
The fast loop is called often enough to sample the timer directly (e.g. no interrupts) but we used them anyway in case some code in the Autonomous routines took longer than a milli-second to run.
void Process_Tasks(void)
{
static char GyroTimer = 0, PrintTimer = 0;
Poll_Rx1(); // The fast loop runs > 100khz
Poll_Tx1(); // Poll rather than interrupts
Poll_Rx2();
Poll_Tx2();
while (MsTimer) // Incremented by TimerInterrupt.
{
MsTimer--; // Section.
if (++GyroTimer == 10) // 100hz
{
GyroTimer = 0;
Gyro_Task();
} // END GyroTimer
if (++PrintTimer == 100) // 10hz
{
SysTimer++; // General timer for system
PrintTimer = 0;
TetherTask(STDIO);
} // END Print task
}// END Tasking
}
Here is a snipped of our interrupt code
/************************************************** *****************************
* FUNCTION NAME: InterruptHandlerLow
*
* If you want to use these external low priority interrupts or any of the
* peripheral interrupts then you must enable them in your initialization
* routine. Read p. 28 of the "MPLAB(R) C18 C Compiler User's Guide" for
* information on context saving.
*
* Because this handler calls something, it must save ".tmpdata". If the called
* routine returned a 16 bit variable, "PROD" would need to be saved as well.
************************************************** *****************************/
#pragma code
#pragma interruptlow InterruptHandlerLow save=section(".tmpdata")/* You may want to save additional symbols. */
void InterruptHandlerLow ()
{
If (INTCONbits.RBIF) /* INTERRUPTS 3-4 (RB4, RB5, RB6, or RB7) changed. */
{
DecodeQuadrature(PORTB); // Read PORTB and clear IF to
INTCONbits.RBIF = 0; // clear interrupt
}
if (PIR1bits.TMR2IF) // timer 2 interrupt?
{
PIR1bits.TMR2IF = 0; // clear the timer 2 interrupt flag [92]
MsTimer++; // Increment millisecond timer
}
}
scottm87
25-02-2004, 12:02
Just a heads up... You cant use the gyro from last years kit (very clear... see the QA id's #341, 346, 190). Therefore, you have to use a different one under the custom electronics pricing. The only real viable option is the ADXRS series from Analog Devices, and if you need more then 150 deg/sec, then it will get much harder (the Evaluation Board version of the 300 deg/sec model is just barely over the price limit... you will need to mount 300 deg/sec yourself). Nobody made it very clear in the previous posts, and I didnt know what gyro you were using to begin with.
Phil_Lutz
25-02-2004, 13:27
We were going to use last years gyro at "custom electronics cost" but it is a none issue now as we have gone another route.
Dead rec with timing loop on the turn.
Thanks,
Phil
Kevin Watson
25-02-2004, 13:51
only thing I disagree with on your post is the sensor has a bandwith of 40Hz or so, but your bot is heavy enough that IT wont have a bandwith anywheres near the 26mS sample loopSampling at 38Hz will only allow you to resolve frequencies as high as 19Hz. Anything above 19Hz will be reflected back below 19Hz through a process called aliasing (http://www.physlink.com/Education/AskExperts/ae490.cfm). 19Hz is called the Nyquist frequency (I know you know this Ken; I just thought others might find this interesting). Here is an excerpt that I ganked from the web that gives an overview:
Nyquist's Signal Sampling Theory
In the late 1920s, the only technology to preserve musical recordings was to copy sound waves in wax. Harry Nyquist, an AT&T scientist, thought there was a better way. He wrote a landmark paper (Nyquist, Harry, "Certain topics in Telegraph Transmission Theory," published in 1928) describing the criteria for what we know today as sampled data systems. Nyquist taught us that for periodic functions, if you sampled at a rate that was at least twice as fast as the signal of interest, then no information (data) would be lost upon reconstruction. And since Fourier had already shown that all alternating signals are made up of nothing more than a sum of harmonically related sine and cosine waves, then audio signals are periodic functions and can be sampled without lost of information following Nyquist's instructions. This became known as the Nyquist frequency, which is the highest frequency that may be accurately sampled, and is one-half of the sampling frequency
The full text can be found here (http://www.geocities.com/bioelectrochemistry/nyquist.htm).
-Kevin
WizardOfAz
25-02-2004, 13:55
Just a heads up... You cant use the gyro from last years kit (very clear... see the QA id's #341, 346, 190). Therefore, you have to use a different one under the custom electronics pricing. The only real viable option is the ADXRS series from Analog Devices, and if you need more then 150 deg/sec, then it will get much harder (the Evaluation Board version of the 300 deg/sec model is just barely over the price limit... you will need to mount 300 deg/sec yourself). Nobody made it very clear in the previous posts, and I didnt know what gyro you were using to begin with.
We are planning to use the ADXRS300EB. It's the same price ($50) as the ADXRS150EB, at least from some suppliers, and was in stock at the time I checked. I'm supposed to have it in the mail tomorrow. I found the $50 price at analog.com (in stock) and avnet.com (not in stock but was a few days ago). Digikey sells it for $75 but it's out of stock. Future-active sells it for $100.50, just over the limit. But the rules don't say where you have to buy it, just that it must be available from one of the preferred suppliers. So buying at $50 from somewhere else is fine by my reading.
For development, we used the BEI unit from last year. Except for a different scale factor, the software should be the same, except also that the AD units saturate at much higher rates (that's goodness) and have corresponding less resolution (badness but not significant to me). So even though I won't have the AD unit before competition, we'll change the wiring and socketing for it today, and hopefully I can just plug it in at the competition, change a constant, and be up and running.
Bill
WizardOfAz
25-02-2004, 14:15
According to the C compiler manual you need to save additional context when calling functions that return values. Specifically, for 8 & 16 bit return values you need to save 'PROD'. I believe it is page 28...
Team 492 samples the ADXSR150 at 100hz (10ms). Our basic logic is a 1khz timer that increments a byte counter (atomic operation). In the fast loop of the IFI code we check that counter and do stuff when it increments.
The fast loop is called often enough to sample the timer directly (e.g. no interrupts) but we used them anyway in case some code in the Autonomous routines took longer than a milli-second to run.
Yep, I'm saving PROD as well as .tmpdata. But Get_Analog_Value uses other SFRs which I'm not saving, and it would do no good anyway I guess, since if one Get_Analog_Value is interrupted by another, the first one will get a mangled value at best anyway. I suppose a possible solution is to disable interrupts in the main code while using Get_Analog_Value.
Your code suffers in a way I was trying to avoid, but may well be insignificant. But here's my issue with it anyway: the "fast" process executes really often, as you say, probably well in excess of 100 kHz, but clearly depending on what you do in it, EXCEPT when data is ready from the master processor. Then the "slow" process is called, and the "fast" process doesn't get called at all while that is happening. In my case that's about 10ms, so I miss a couple of the 4ms interrupts. You code partly deals with this problem, since it counts up 1ms interrupts and later uses them all up, even if more than 10 of them happened without any "slow" process service. So what will happen in your code, if the "slow" process is longer than 10ms, is that sometimes the 10ms code will get called at different than 10ms intervals, causing some jitter in your sampling rate. You'll get the right number of calls, just not at precise intervals. If your slow process does not exceed 10ms, your code is perfect. In my case the desired sample rate was 4ms, and I couldn't get the "slow" code to run that fast, so I miss samples. I should at least switch to your interrupt counting method so as not to miss samples, only have some delayed.
Hope this long post was not too incoherent. Thanks for the code snippet. Even though it's not what I wanted, it's an improvement over how I'm doing it and I'll use it if I can't solve the problem another way.
Bill
seanwitte
25-02-2004, 14:44
Yep, I'm saving PROD as well as .tmpdata. But Get_Analog_Value uses other SFRs which I'm not saving, and it would do no good anyway I guess, since if one Get_Analog_Value is interrupted by another, the first one will get a mangled value at best anyway. I suppose a possible solution is to disable interrupts in the main code while using Get_Analog_Value.
We're running the intergration at 100Hz using timer3. We had to disable the low priority interrupts before using Get_Analog_Value() in the mainline code, now it seems fine. The bit is INTCONbits.GIEL. Set it low to disable the low priority interrupts and high to enable them. The ISR makes one call to Get_Analog_Value() to grab the current value from the ADXRS150.
Larry Barello
25-02-2004, 15:08
Just a heads up... You cant use the gyro from last years kit (very clear... see the QA id's #341, 346, 190). Therefore, you have to use a different one under the custom electronics pricing. The only real viable option is the ADXRS series from Analog Devices, and if you need more then 150 deg/sec, then it will get much harder (the Evaluation Board version of the 300 deg/sec model is just barely over the price limit... you will need to mount 300 deg/sec yourself). Nobody made it very clear in the previous posts, and I didnt know what gyro you were using to begin with.
The ADXRS150EB and 300 are available as samples from http://www.analog.com, the manufacture. It doesn't matter where you get them from as long as they are "available" from an allowed distributer.
Also, pay attention to the spec sheet for those devices. You can extend the 150's range up to 4x - that is 600 deg/sec. My team has found the 150/sec adequate for even vigorous spins (i.e. bouncing off things).
Larry Barello
25-02-2004, 15:28
...
Your code suffers in a way I was trying to avoid, but may well be insignificant. But here's my issue with it anyway: the "fast" process executes really often, as you say, probably well in excess of 100 kHz, but clearly depending on what you do in it, EXCEPT when data is ready from the master processor. Then the "slow" process is called, and the "fast" process doesn't get called at all while that is happening. In my case that's about 10ms, so I miss a couple of the 4ms interrupts. You code partly deals with this problem, since it counts up 1ms interrupts and later uses them all up, even if more than 10 of them happened without any "slow" process service. ...
Your analysis is correct. You should figure out why you are burning so much tmie in the user code. 10ms is a lot of instructions! Calling the ADC stuff from the interrupt handler should be Ok too as long as that is the only place you call it. Better yet, make the ADC stuff in-line so you don't even need to save .tmpdata or PROD - look at the assembly code and you'll understand why that is a big win (the PIC is terrible when saving context).
I essentially re-wrote all the IFI analog stuff to make it smaller (and to understand the PIC): From "sensor.h"
enum AdcValues
{
Gyro,
ArmPositionFeedback,
szAdcVal
};
and "sensor.c"
//*************************** ADC Task ****************************************
// Note: OpenADC configures all the input port bits appropriately.
// Individual conversions, however, just reset the ADC hardware
// as the ADC turns off periodically for some unknown reason.
void Init_ADC_Task(void)
{
OpenADC( ADC_FOSC_RC & ADC_RIGHT_JUST & (~szAdcVal),
ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS );
}
int GetADC(enum AdcValues chan)
{
ADCON1 = ~szAdcVal & 0x0F; // Configure # channels and vref
ADCON2 = 0x80 | 0x03; // Right Justify & internal RC clock
ADCON0 = (chan<<2) | 0x01; // Set channel and turn on.
Delay10TCYx(10); // Let things settle
ConvertADC(); // Start conversion
while (BusyADC()); // Wait conversion done
return ReadADC(); // Return word
}
Note: my code only allocates the required number of ADC lines, so I can use the other ones for general digital I/O. The main reason I published this is so you can see how to in-line the conversion in your interrupt handler... If you only have three or four channels, it would be relatively efficient and fast to do it that way.
WizardOfAz
25-02-2004, 16:25
Thanks Larry. I've changed my code to process an interrupt count outside of the ISR, following the method in your earlier post of counting up interrupts in the ISR and counting them down in the main thread. Even with the jitter this introduces, the gyro is now performing very nicely.
We have been doing much in haste lately, and I multiplex across all the tasks on the build team. So I have not yet taken time to do much optimization of code, or to understand how we're managing to use 10ms. We do table lookup and interpolation for a couple of math functions (arctan and sqrt), but these are 64 entry tables and using a binary search (6 compares per lookup) so I don't think they're consuming a lot of time. The other thing is I do some arithmetic in 32 bits where I know with more careful planning, I could use smaller variables. This is clearly eating up some time too. Maybe after we ship tomorrow I'll have time to scrub the code good.
Bill
Larry Barello
25-02-2004, 16:39
32 bit math will chew up time. With the AVR processors (my fav) 32 bit floating point is marginally slower than long, so I tend to use float for stuff that might need several scaling operations with integer math. I suspect something similar might be going on with the PIC. The nice thing about float is that scaling comes for free (with caveats, of course).
You must be doing wheel encoder odometry. I skipped the trig stuff and just use the Gyro for heading and the wheel encoders for velocity control and overall distance traveled. We do odometry (using the heading and distance) off line (via the dashport) and, apparently, the PC tracks the actual robot position pretty well.
Good luck! I ship in the next hour - and I am GLAD to have it gone!
DougHogg
28-02-2004, 01:53
Just a heads up... You cant use the gyro from last years kit (very clear... see the QA id's #341, 346, 190). Therefore, you have to use a different one under the custom electronics pricing. The only real viable option is the ADXRS series from Analog Devices, and if you need more then 150 deg/sec, then it will get much harder (the Evaluation Board version of the 300 deg/sec model is just barely over the price limit... you will need to mount 300 deg/sec yourself). Nobody made it very clear in the previous posts, and I didnt know what gyro you were using to begin with.
If any team still wants a gyro, per the FIRST Question and Answer site, it is legal to buy one after the ship date and install it at the regional.
Also I found the 300 deg/sec gyro (evaluation board model) on the Digikey site for $75.00 (300 deg/sec gyro - click here and then on "Search again" (http://www.digikey.com/scripts/DkSearch/dksus.dll?PName?Name=ADXRS300EB)), so it is legal to order it from Analog Devices for $50.00. See http://www.analog.com (http://www.analog.com/index_noflash.html) and enter "ADXSR300EB" or "ADXSR150EB" in the search field, depending on which version you want.
Either way, make sure you get the EB (Evaluation Board) version. Otherwise, you wind up with a tiny (7 mm square) surface-mount chip with no leads. I have several of them to return to Digikey.
KenWittlief
28-02-2004, 13:19
originally posted by WizardofAz:
hopefully I can just plug it in at the competition, change a constant, and be up and running.
[plan on adjusting your zero point too. Our reads 141 when its not turning, instead of 127 after a gyro>>2.
or you could have your bot read the zero value at some point when you know the bot is not running, like when its disabled by the comp port at the start of the match.
WizardOfAz
29-02-2004, 18:02
[plan on adjusting your zero point too. Our reads 141 when its not turning, instead of 127 after a gyro>>2.
or you could have your bot read the zero value at some point when you know the bot is not running, like when its disabled by the comp port at the start of the match.
Thanks. I have code that automatically computes the zero point. It skips the first 100 4ms samples after power up then sums the next 100 4ms samples (summing (sample - 512)). This assumes that the robot is still at power up, which we try to ensure. This number is then divided by 4 to get a 100ms correction. I apply correction/25 to every 4ms sample, then correction%25 every 100ms.
Since you mentioned it, I wonder how stable you other guys are finding the zero point to be. The 100ms correction computed as above varies by about +/- 10% (100 to 120). I haven't tried to determine if this is because of routing the cable near noise sources or is just the nature of the gyro. Would like to know others' experiences.
In your case Ken, since you're immediately dividing by 4, a +/- 10% variation would only be +/- 1 or 2 I guess.
Bill
KenWittlief
29-02-2004, 18:48
keep in mind - where is your power switch on your bot?
if the operator bumps the bot while/after turning it on, the gyro will read the motion as the zero point
I am thinking of using the 'disable' variable to know when the bot is not yet running, and taking the zero point then, assuming this is before the match starts and auton is not yet running.
jacob_dilles
29-02-2004, 19:09
or you could get a continously running avrage from when its turned on to when its enabled and take that as the zero point. thats pretty much error free unless your in california :p
velocipenguin
29-02-2004, 21:33
Any of you who are using the ADXRS150EB should keep in mind that sampling faster than 40 Hz is useless. According to the ADXRS150EB datasheet, the evaluation board contains components that set the bandwidth to 40 Hz. Sampling more frequently won't do you any good and increases the likelihood that you'll sample and integrate random electromagnetic interference.
seanwitte
29-02-2004, 21:50
Any of you who are using the ADXRS150EB should keep in mind that sampling faster than 40 Hz is useless. According to the ADXRS150EB datasheet, the evaluation board contains components that set the bandwidth to 40 Hz. Sampling more frequently won't do you any good and increases the likelihood that you'll sample and integrate random electromagnetic interference.
Kevin Watson already posted an explaination above. If the bandwidth is 40Hz, then to measure it you need to do it at least twice as fast. For the ADXRS150EB stock you'd want to sample at not less than 80Hz.
KenWittlief
29-02-2004, 22:30
theres no way your bot can move with a 40Hz response rate - to make a mass of 130 pounds move with unique yaw rates at 25mS intervals would take hundreds of HP
we only have about 2HP at our disposal
I wish I had the time to instrument the step response of our bot - switch the steering from zero to a full power spin on its axis and measure how fast the robot torques up to speed
trust me on this, you will not see any drastic changes in yaw rate a 25mS intervals with these machines - there is no need to sample the yaw rate any faster than that - the bot has too much inertia to be twittering around at 40Hz or more like a hummingbird :c)
Kevin Watson
29-02-2004, 23:17
theres no way your bot can move with a 40Hz response rate - to make a mass of 130 pounds move with unique yaw rates at 25mS intervals would take hundreds of HPIt can easily see fundamental or harmonic frequencies of 40Hz if it runs into something hard :D.
-Kevin
KenWittlief
29-02-2004, 23:21
I agree with that - there is no yaw sensor that can measure what happens when you get smacked by another bot - if you get bashed your yaw rate sensor will either max out, or glitch - so even then, it dosnt matter how fast you sample it- the output you get will be wrong for a sample or two.
WizardOfAz
29-02-2004, 23:37
Ken,
I don't think zero to full power spin is the limiting case. The worst case impulse in yaw rate is probably during a collision. That's when I expect the integrated gyro to get wrong - no longer represent my absolute turn angle. My intuition may be wrong here, and I'd love to see an explanation, but my swag is that in a full speed collision we could see a change of 30 degrees or so in a tenth of a second or so. If that happened, the sensor is saturated without even starting to consider bandwidth, since that guess yields a 300 degrees/second change. What's the frequency content of such a change? I dunno, too late tonight for me to want to think that hard. Seems like more than 20 Hz though, which is all the bandwidth you can get sampling at 25ms. Moreover, don't you have to use pretty good low pass filters if you're sampling near the Nyquist limit? Which probably none of us are doing. In order to get by with lousy or no filters, you have to sample quite a bit faster than Nyquist's limit. OK, am I all screwed up about this? I'll admit it's been a long time since I've done much with signal processing.
Bill
velocipenguin
01-03-2004, 00:02
If you want to sample at the Nyquist frequency, you can. However, given that analog sensors are prone to noise, I think it makes more sense to sample at the lowest frequency that will yield usable information in order to reduce the risk of sampling brief electromagnetic transients. I do not anticipate that our robot is likely to be able to navigate if it experiences yaw rates anywhere near the ADXRS150EB's maximum during autonomous mode; whether this would be due to mechanical failure or lack of usable sensor data remains to be seen, but I would prefer that the system be less useful in extreme conditions to having the robot wander all over the place due to EMI from fluorescent lighting or other sources.
jacob_dilles
01-03-2004, 06:48
However, given that analog sensors are prone to noise, I think it makes more sense to sample at the lowest frequency that will yield usable information in order to reduce the risk of sampling brief electromagnetic transients.
i dont think this is entirly accurate. though you may not be getting usable information in real time, it is still best to sample at fastest practical frequeency possable. take a metaphor for a moment: say you are driving. is it better that you blink 40 times a minute for 1/10 of a second or 10 times a minute for 3 seconds?
WizardOfAz
01-03-2004, 16:38
With all this sidetrack on sampling rate, one of my original questions got lost. I'm wondering how much variation people are seeing on the no-motion output of the ADXRS150 or 300. I am using the 300, since it happened to be in stock as a free sample at the time. In my setup, it has about +/- 10% variation, and I'm wondering if that's typical or should I try to figure out why?
Thanks
Bill
Kevin Watson
01-03-2004, 16:53
With all this sidetrack on sampling rate, one of my original questions got lost. I'm wondering how much variation people are seeing on the no-motion output of the ADXRS150 or 300. I am using the 300, since it happened to be in stock as a free sample at the time. In my setup, it has about +/- 10% variation, and I'm wondering if that's typical or should I try to figure out why?
Thanks
Bill
Bill,
Gyro drift is very common. The simple way around it is to just periodically sample the output when you know you aren't moving and using that value as a baseline. Another cool thing to look into is the use of a Kalman filter (http://www.cs.unc.edu/~welch/kalman/) to reduce the amount of noise in your measurements.
-Kevin
Mark McLeod
01-03-2004, 16:53
With all this sidetrack on sampling rate, one of my original questions got lost. I'm wondering how much variation people are seeing on the no-motion output of the ADXRS150 or 300. I am using the 300, since it happened to be in stock as a free sample at the time. In my setup, it has about +/- 10% variation, and I'm wondering if that's typical or should I try to figure out why?
Thanks
BillWith our 150, at startup our neutral varies between 519 and 521. We are ignoring the first 5 to 10 samples @ 4ms sample rate, and averaging the next 25 to 250 samples (rounding the average).
[edit]We aren't getting no-motion drift if we refrain from trying to increase the accuracy.
[edit][edit] Ran a Kalman filter on it and didn't significantly improve drift results while moving, but that may be due to the individual robot nature of the noise. Didn't try it with no-motion. I need to revisit the errors in drift. Maybe play with more filter variations.
KenWittlief
01-03-2004, 21:18
these Analog Device parts do have a temp output, and you can correct the output for temp, which would reduce the drift over time
I think the spec sheet called out something like 300° accumulated drift over one hour if you compensate for temp
+/- 10% seems too high if the bot is sitting perfectly still - are you sure you are not hitting the analog to digital converter too fast? I dont know its max sample rate
I would look at the output on a scope if you are getting that much drift - seems way to high to me.
nother thought - where are your signal wires running? ours are very short, and there are no power wires or pwm wires in the area- if you have the gyro cable bundled up with other wires you could be getting a lot of cross talk from them.
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.