|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
||||||
|
||||||
|
Re: Gyro problem
1 degree every 5 seconds doesn't sound too bad (IE, inline with what I've seen with the new control system). You can play with AnalogChannel::SetAccumulatorDeadband if you want to (I think it is a relatively new addition). There was a big thread a few years ago debating whether it was better to have the dead band or not, as having the deadband may throw off the results once you start moving.
You may want to confirm the legality of the ADXRS300 gyro, as Analog devices has stopped making it, and it looks like most suppliers have stopped carrying it. |
|
#2
|
||||
|
||||
|
Re: Gyro problem
Quote:
By modifying the Deadband, as suggested, we got much more stable results and still observed good accuracy when moving. |
|
#3
|
|||
|
|||
|
Re: Gyro problem
After using the Reset VI for the gyro in Labview we noticed that the angle toggled between 359 360 and 0. Does anyone else have this issue? We've never seen this before with the previous controller and kevin's code.
I know 359, 360, and 0 are about the same but why would it not be -1 or -2 deg rather than 359 360. |
|
#4
|
|||
|
|||
|
Re: Gyro problem
Can you set the gyro up as an analog input (it's under i/o in the WPI stuff) and probe what it thinks is the voltage when still and when rotating?
|
|
#5
|
||||||
|
||||||
|
Re: Gyro problem
Thanks to all who have responded.
First of all, our gyro is wired and connected correctly, as we verified today. We had full confidence in the test gyro as we used it last year. Second, the thing worked better today with a lot less drift - we did take care to leave the gyro alone for an extended period following initial power up. Other than that, no changes we can think of. I would still like to know how to adjust the deadband. I did see the AnalogChannel::SetAccumulatorDeadband reference in mucking through the source code. What would the syntax be to call this for the gyro channel on analog module 1, input 1? Finally, it looks like the ADXRS610 is the replacement for the ADXRS300. I'll have to look into that one. |
|
#6
|
||||
|
||||
|
Re: Gyro problem
We combined gyro and one channel of accelerometer processing so that we could use the same calibration interval for both (and changed the calibration period to 2 seconds which seems to be plenty). Also, we wanted functions to return the filtered angular rate for the gyro and the acceleration and speed from the accelerometer. Anyway, we also used a known good 300 degrees/sec gyro as well as this year's KOP gyro. To do this we copied the WPILib code into our project and then modified it. Part of our modified code is below - notice that we set the deadband for both to 10.
Hope this helps. The code that set's up the gyro and accelerometer is here: #ifdef PRACTICE_BOT #define GYRO_SENSETIVITY 0.0055 /* LAST YEAR's GYRO */ #else #define GYRO_SENSETIVITY 0.006966667 /* 2009 Gyro */ #endif void InitializeUtilities() { m_gyro = new GYRO_ACC(1,1,1,2); m_pressure_switch = new DigitalInput(6,14); m_autonomous_alliance = new DigitalInput(4,6); m_initial_position1 = new DigitalInput(4,7); m_initial_position2 = new DigitalInput(4,8); m_play_1s = new AnalogChannel(2,3); m_play_10s = new AnalogChannel(2,4); // m_compressor_relay = new Relay(4, 1, Relay::kForwardOnly); m_gyro->SetSensitivity(GYRO_SENSETIVITY); m_gyro->SetAccSensitivity(0.009666207); m_gyro->Reset(); m_right_odo = new Encoder(6,3,6,4,false,CounterBase::k1X); m_left_odo = new Encoder(6,1,6,2,false,CounterBase::k1X); m_right_drive = new Encoder(6,7,6,8,false); m_left_drive = new Encoder(6,5,6,6,false); } /** * Initialize the GYRO_ACC. * Calibrate the GYRO_ACC by running for a number of samples and computing the center value for this * part. Then use the center value as the Accumulator center value for subsequent measurements. * It's important to make sure that the robot is not moving while the centering calculations are * in progress, this is typically done when the robot is first turned on while it's sitting at * rest before the competition starts. */ void GYRO_ACC::InitGYRO_ACC() { if (!m_analog->IsAccumulatorChannel()) { wpi_fatal(GyroNotAccumulatorChannel); if (m_channelAllocated) { delete m_analog; m_analog = NULL; } return; } if (!m_ana_accel->IsAccumulatorChannel()) { wpi_fatal(GyroNotAccumulatorChannel); if (m_accel_channelAllocated) { delete m_ana_accel; m_ana_accel = NULL; } return; } m_voltsPerDegreePerSecond = kDefaultVoltsPerDegreePerSecond; m_analog->SetAverageBits(kAverageBits); m_analog->SetOversampleBits(kOversampleBits); m_voltsPerG = kDefaultVoltsPerG; m_ana_accel->SetAverageBits(kAverageBits); m_ana_accel->SetOversampleBits(kOversampleBits); float sampleRate = kSamplesPerSecond * (1 << (kAverageBits + kOversampleBits)); m_analog->GetModule()->SetSampleRate(sampleRate); Wait(0.25); m_analog->InitAccumulator(); m_ana_accel->InitAccumulator(); Wait(kCalibrationSampleTime); INT64 value; UINT32 count; m_analog->GetAccumulatorOutput(&value, &count); UINT32 center = (UINT32)((float)value / (float)count + .5); gyro_center = (float)value/(float)count; m_offset = ((float)value / (float)count) - (float)center; m_analog->SetAccumulatorCenter(center); m_analog->SetAccumulatorDeadband(10); ///< TODO: compute / parameterize this m_analog->ResetAccumulator(); m_ana_accel->GetAccumulatorOutput(&value, &count); center = (UINT32)((float)value / (float)count + .5); accel_center = (float)value/(float)count; m_acc_offset = ((float)value / (float)count) - (float)center; m_ana_accel->SetAccumulatorCenter(center); m_ana_accel->SetAccumulatorDeadband(10); ///< TODO: compute / parameterize this m_ana_accel->ResetAccumulator(); } /** * GYRO_ACC constructor given a slot and a channel. * * @param slot The cRIO slot for the analog module the GYRO_ACC is connected to. * @param channel The analog channel the GYRO_ACC is connected to. */ GYRO_ACC::GYRO_ACC(UINT32 slot, UINT32 channel, UINT32 accel_slot, UINT32 accel_channel) { m_analog = new AnalogChannel(slot, channel); m_channelAllocated = true; m_ana_accel = new AnalogChannel(accel_slot, accel_channel); m_accel_channelAllocated = true; InitGYRO_ACC(); } /** * GYRO_ACC constructor with only a channel. * * Use the default analog module slot. * * @param channel The analog channel the GYRO_ACC is connected to. */ GYRO_ACC::GYRO_ACC(UINT32 channel, UINT32 accel_channel) { m_analog = new AnalogChannel(channel); m_channelAllocated = true; m_ana_accel = new AnalogChannel(accel_channel); m_accel_channelAllocated = true; InitGYRO_ACC(); } |
|
#7
|
||||
|
||||
|
Re: Gyro problem
In that last post, I didn't address the gyro drift performance...
With a deadband of 10 it is pretty good. For example the beginning of our navigation dump file shows that the gyro drifted from 45.0 degrees to 44.999695 degrees in the period from when the robot was turned on RobotInit() until the field enabled autonomous which is maybe a minute or two? In the dump section below, the robot was commanded to execute a CCW arc turn of 20 degrees/second with a forward speed of 0.5 until the heading was 0 degrees. x and y are the estimated field coordinates using the left and right odometry wheels and the gyro. h is the gyro heading, oh is the estimated gyro heading from using the odometry wheels alone, ox and oy are the estimated field coordinates using the left and right odometry wheels only (not the gyro). ror and rol are the raw encoder counts for the right and left odometry wheels. arc: rate: -20.000000 arc: speed: 0.500000 arc: angle: 0.000000 arc: timeout: 10.000000 Nav: x: 4.000000, y: 4.000000, h: 44.999695, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 44.999695, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 44.999695, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 45.002197, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 45.002167, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 44.997162, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 44.988068, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 44.989807, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 44.992462, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 44.992462, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 44.990997, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 44.989685, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 44.994049, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 45.000427, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 45.004486, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 45.007355, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 45.008381, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.000000, y: 4.000000, h: 45.008022, ox: 4.000000, oy: 4.000000, oh: 45.000000, ror: 5, rol: 5, Arc: Nav: x: 4.002983, y: 4.002983, h: 45.004089, ox: 4.002979, oy: 4.002987, oh: 44.925629, ror: 7, rol: 6, Arc: Nav: x: 4.003977, y: 4.003977, h: 44.996216, ox: 4.003973, oy: 4.003981, oh: 45.000000, ror: 7, rol: 7, Arc: Nav: x: 4.005965, y: 4.005966, h: 44.985992, ox: 4.005961, oy: 4.005970, oh: 45.000000, ror: 8, rol: 8, Arc: Nav: x: 4.008946, y: 4.008950, h: 44.970764, ox: 4.008940, oy: 4.008956, oh: 44.925629, ror: 10, rol: 9, Arc: Nav: x: 4.011928, y: 4.011935, h: 44.966827, ox: 4.011915, oy: 4.011947, oh: 44.851257, ror: 12, rol: 10, Arc: Nav: x: 4.013915, y: 4.013925, h: 44.959839, ox: 4.013899, oy: 4.013941, oh: 44.851257, ror: 13, rol: 11, Arc: Nav: x: 4.016895, y: 4.016910, h: 44.955292, ox: 4.016878, oy: 4.016928, oh: 44.925629, ror: 14, rol: 13, Arc: Nav: x: 4.020870, y: 4.020890, h: 44.957764, ox: 4.020850, oy: 4.020910, oh: 44.925629, ror: 17, rol: 15, Arc: Nav: x: 4.022856, y: 4.022881, h: 44.940948, ox: 4.022836, oy: 4.022902, oh: 44.925629, ror: 18, rol: 16, Arc: |
|
#8
|
|||||
|
|||||
|
Re: Gyro problem
Quote:
I've been intending to email Analog Devices to let them know of the datasheet inaccuracy, but I've been waiting until I get a round tuit. Just figured I'd try to save you the 6 or so hours we wasted figuring out the above. |
|
#9
|
||||||
|
||||||
|
Re: Gyro problem
Quote:
![]() Last edited by Joe Ross : 24-03-2009 at 09:32. |
|
#10
|
||||||
|
||||||
|
Re: Gyro problem
Quote:
|
|
#11
|
||||||
|
||||||
|
Re: Gyro problem
Thanks once again for all the code samples and other time-saving advice in this thread. I think my team will find the information very useful in the near future.
|
|
#12
|
|||
|
|||
|
Re: Gyro problem
Also, check which analog channel you're using/try changing the channel. I'm not sure if this is true for everyone, but our module didn't like using the last analog in when we had the jumper for battery voltage on (Well...I guess we never tested whether it worked without it, since changing the channel worked).
Since it hasn't been mentioned, could the OP post about how fast the gyro measurement is drifting? |
|
#13
|
||||
|
||||
|
Re: Gyro problem
Quote:
So, your experience would hold for everyone on the first cRIO slot since the battery voltage measurement is required by the rules this year. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Gyro problem..HELP! | zivo123 | Programming | 13 | 14-04-2008 12:06 |
| gyro problem | Guarana | Programming | 9 | 03-03-2008 15:48 |
| Problem with gyro... | capenga | Programming | 21 | 16-02-2006 19:25 |
| Gyro code problem | AMIRAM | Programming | 10 | 23-01-2006 04:26 |