PDA

View Full Version : Integration of Gyro with Easy-C Pro


marccenter
01-11-2008, 12:17 PM
I am using a Vex Robot to prototype Team 47 FRC Robot this season using Easy-C Pro to switch between both bots. Chief Delphi has a white paper "Working the Angles:" authored by Jim Zondag, Team#33 - Killer Bees that I am attempting to implement. This paper shows a simple technique for gyro integration. The gyro_angle(void) function is called from Process_Data_From_Master_Up() every 26.2 msec. A simple calculation is performed. Other C functions are operated/completed and I know the loop will eventually terminate in some holding loop function until the next interrupt starts the next loop again.
How does this correlate to Easy-C implementation? If I place the function in a while loop, won't the function integrate multiple times and get different results.
What Easy-C implementation should I use with the gyro to make sure it only get's implemented once during the 18 msec(?) loop?

:confused:

Kingofl337
01-11-2008, 01:59 PM
Here is a sample of how to use the Gyro.

Also if you check out the tutorials in "Getting Started" in the help file
there is a drive strait using the gyro example.

Also easyC runs at full speed all the time even in operator control. Though the two PICs sync every 26ms because of the
master code. If there is no change or no new data from the master the same value will be loaded. For more detail you may
have to get a hold of for Brad.

BradAMiller
01-19-2008, 09:04 AM
How does this correlate to Easy-C implementation? If I place the function in a while loop, won't the function integrate multiple times and get different results.
What Easy-C implementation should I use with the gyro to make sure it only get's implemented once during the 18 msec(?) loop?
:confused:

The runtime code in easyC does the integration for the gyro in the background on a timer interrupt. So it is independent of the user/master processor data exchanges or loops in your program. When you read the gyro angle using the easyC or WPILib function, it just gives you the most recent value for the heading that was computed in the background.

Does this answer your question?

marccenter
01-25-2008, 02:48 PM
Brad,
So, the Gyro update is independent of whatever other programming I implement in Easy-C? I know that the FRC updates at 38 Hz rate (26.2 msec). I believe the VEX updates faster (18.5 msec?). What rate does the Gyro update? Because it is tied to a timer/interrupt, there must be some base rate, right? I am trying to used the Killer Bees paper "Working the Angles" to use the Gyro and am trying to figure out how to integrate the readings (thus, how often the Gryo is updated).

BradAMiller
01-28-2008, 06:20 AM
Brad,
So, the Gyro update is independent of whatever other programming I implement in Easy-C? I know that the FRC updates at 38 Hz rate (26.2 msec). I believe the VEX updates faster (18.5 msec?). What rate does the Gyro update? Because it is tied to a timer/interrupt, there must be some base rate, right? I am trying to used the Killer Bees paper "Working the Angles" to use the Gyro and am trying to figure out how to integrate the readings (thus, how often the Gryo is updated).
Every 20ms the gyro interrupt service routine reads the gyro rate and does the integration. This changes the raw turn rate value returned from the gyro to a heading. The heading is the value that is actually returned. I suspect that this is the integration they're referring to in the paper - so you probably don't need to do it again.

marccenter
01-28-2008, 12:19 PM
Brad,
Thanks for your response.

I am using the ADXRS300EB (300 degrees/sec) gyro (Digikey PN
ADXRS300EB, price $53.75/1 piece) and attempting to integrate into
a VEX controller as a prototype for the FRC controller.

Using the 20 Hz gyro rate update information that you provided, I will
update the information on Page 4 of Jim Zondag's paper "Working the
Angles" (Team 33 - Killer Bees) to become the following:

1) ADXRS300EB has 1/2 the resolution (12.8/2 = 6.4 mV/degree/second)
but twice the range (300 degrees/sec) compared to the ADXRS150EB
(150 degrees/sec) gyro.

2) Gyro loop runs at 20 Hz (versus 38.2 Hz FRC main loop)

3) At a rotation rate of 1 degree per loop, we would thus be rotating at
20 degrees/sec. Multiply this by the output sensitivity and you get:
20 deg/sec * 6.4 mV/degree/sec = 128 mVolts

4) The 10 bit A/D on the FRC/VEX robot controller has a resolution of:
5.00 V/ 1023 = 4.89 mV/bit.

5) Thus the digital input value to the CPU at 1 degree per main loop is:
128 mVolts / 4.89 mV/bit = 26.175 bits

Therefore, if the robot turns 80 degrees in 1 second, the gyro heading should output it's nominal output (480 - 520 counts on A/D) plus 26.175 bits/ degree/main loop times (80 degrees/20 Hz = 4 degrees) = 104.7 counts per gyro heading loop.

The one gyro (ADXSR300EB) I have outputs nominally about 520 counts.
So I would expect to see about 635 (520 + 105) counts for gyro heading if I spun the robot for 80 degrees in 1 second.

But, I think there may be an integration issue problem. :confused: The FRC controller updates at 38.2 Hz (26.2 ms), The VEX controller updates at 54 Hz (18.5 ms) (I have read). This is asynchronous to the gyro which updates every 20 Hz. Jim Zondag's method insures that his gyro reading (once) is synchronized to his main loop rate and his calculations are then valid.

So, I think the solution that is required is to not use the gyroangle function provided in Easy-C, but to treat the gyro as an analog input and just sample it once per loop.

Oops, is that a problem? How do I insure that the gyro analog input is just sample one per loop (FRC 26.2 ms/VEX 18.5 ms)? I guess I need to setup a simple timer loop in the Operator Control Loop that monitors 26.2/18.5 msec and then reads the gyro as an analog input? IF I set it to 26.2 msec timer rate, I can then move it easier from the VEX to the FRC controller.

So, I will rework Jim's page 4 all over again

) ADXRS300EB has 1/2 the resolution (12.8/2 = 6.4 mV/degree/second) but twice the range (300 degrees/sec) compared to the ADXRS150EB (150 degrees/sec) gyro.

2) Gyro loop runs at 38.2 Hz (same as 38.2 Hz FRC main loop)

3) At a rotation rate of 1 degree per loop, we would thus be rotating at 38.2 degrees/sec. Multiply this by the output sensitivity and you get: 38.2 deg/sec * 6.4 mV/degree/sec = 244.5 mVolts

4) The 10 bit A/D on the FRC/VEX robot controller has a resolution of: 5.00 V/ 1023 = 4.89 mV/bit.

5) Thus the digital input value to the CPU at 1 degree per main loop is: 244.5 mVolts / 4.89 mV/bit = 50 bits (CPU counts at 1 degree/38.2 kHz FRC controller main loop)

Therefore, if the robot turns 90 degrees in 1 second, the gyro heading should output it's nominal output (480 - 520 counts on A/D) plus 50 bits/ degree/main loop times (90/38.2 = 2.35 degrees = 117.8[117]) counts per gyro heading loop.

The one gyro (ADXSR300EB) I have outputs nominally about 520 counts.
So I would expect to see about 637 (520 + 117) counts for gyro heading if I spun the robot for 90 degrees in 1 second. This would results in a total integrated amount of 117 counts/loop * 38.2 loops or 4469 counts above
the nominal amount of 520 counts/loop * 38.2 loops or 19864 counts.

So, If I want to complete a 90 degree turn in 1 second, I will count up (integrate) the gyro and count to 19684 counts to indicate when a 90 degree turn has been completed. :D

BradAMiller
02-04-2008, 06:32 AM
If you are using WPILib or easyC the code to do all those calculations and the timing for sampling is built in. Here's a complete sample WPILib program that will enable a robot to drive in a straight line. This uses a set of Drive functions that can be included with easyC by doing an "Import Library..." operation.

#include "BuiltIns.h"

/*
* Sample program to have the robot drive in a straight line using
* the kit gyro sensor (connected to analog port 1).
*/

void main(void)
{
}

void IO_Initialization(void)
{
SetCompetitionMode(1); // set to competition mode
}

void Initialize(void)
{
InitGyro(1); // initialize gyro on port 1
TwoWheelDrive(2,1); // Setup 2 motor drive robot (ports 1 & 2)
}

void Autonomous(void)
{
int heading;
StartGyro(1); // start gyro sampling
while (1)
{
heading = GetGyroAngle(1); // get the current heading
Drive(80, heading/2); // turn towards the error
}
}
This should be close to what you need - it depends on the direction of rotation of your wheels. The InitGyro, StartGyro, and GetGyroAngle functions in easyC all come from the Gyro block - there are buttons to indicate which one you want. The Gyro type can also be set with the Gyro block.