Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Motors (http://www.chiefdelphi.com/forums/forumdisplay.php?f=52)
-   -   Yaw Sensor (http://www.chiefdelphi.com/forums/showthread.php?t=25133)

Kevin Watson 25-02-2004 13:51

Re: Yaw Sensor
 
Quote:

Originally Posted by KenWittlief
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

Sampling 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. 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:


Quote:

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.

-Kevin

WizardOfAz 25-02-2004 13:55

Re: Yaw Sensor
 
Quote:

Originally Posted by scottm87
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

Re: Get_Analog_Value in an ISR
 
Quote:

Originally Posted by Larry Barello
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

Re: Get_Analog_Value in an ISR
 
Quote:

Originally Posted by WizardOfAz
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

Re: Yaw Sensor
 
Quote:

Originally Posted by scottm87
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

Re: Get_Analog_Value in an ISR
 
Quote:

Originally Posted by WizardOfAz
...
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"
Code:

enum AdcValues
{
        Gyro,
        ArmPositionFeedback,
        szAdcVal
};

and "sensor.c"
Code:


//*************************** 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

Re: Get_Analog_Value in an ISR
 
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

Re: Yaw Sensor
 
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

Re: Yaw Sensor
 
Quote:

Originally Posted by scottm87
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"), so it is legal to order it from Analog Devices for $50.00. See http://www.analog.com 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

Re: Yaw Sensor
 
Quote:

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

dynamic zero point determination
 
Quote:

Originally Posted by KenWittlief
[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

Re: Yaw Sensor
 
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

Re: Yaw Sensor
 
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

Re: Yaw Sensor
 
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

Re: Yaw Sensor
 
Quote:

Originally Posted by velocipenguin
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.


All times are GMT -5. The time now is 21:48.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi