![]() |
Gyro problem
My teammate didn't even spin the gyro all the way around, but the numbers just kept going up, even when she stopped.
help? |
Re: Gyro problem
And we made sure the pwm cables were attached correctly.
|
Re: Gyro problem
There are two outputs on the gyro, one for temperature. and one for turn rate. if you use the wrong outputs, you will get the behavior you described. Check your wiring.
|
Re: Gyro problem
the wiring on it is right, though. we've checked it already. Which is why we're at a loss.
|
Re: Gyro problem
The gyro has to be completely still during calibration (done during open I believe) or you will get the kind of response that you are seeing.
|
Re: Gyro problem
Quote:
Rate _should_ be on the outside, temp on the inside. |
Re: Gyro problem
Quote:
|
Re: Gyro problem
Keeping the wires short will also help the drift(lower capacitance).
|
Re: Gyro problem
Quote:
|
Re: Gyro problem
The gyro produces a voltage that will charge the capacitance in the wire. The longer the wire, the larger the capacitance, longer discharge time, longer change in voltage after gyro stops accelerating. It will also catch more noise if the wires are longer.
|
Re: Gyro problem
Quote:
Your comment on phase delay is technically true, but not on a scale that is detectable. A cable that long will contribute a couple dozen picofarads. With a sampling frequency of 62,500Hz and an output impedence of 100 Ohms, you would need to add a couple hundred thousand picofarads to start to change things. Since the gyro signal is only in the 0-200Hz(ish) range, I'd wager that phase delay will continue to be imperceptible. However, the noise comment is very valid. |
Re: Gyro problem
(If you're using C++, not sure about LabView) Are you trying to read the values using printf or cout? If you output too much it all builts up in the cRIO's memory and slowly comes out the console, so you might just be seeing old data in your terminal.
~DtD |
Re: Gyro problem
OK, I am trying to implement an ADXRS300 gyro on our 2009 bot using WindRiver.
I'm starting with a known-good unit from 2008. Using our bench setup, upon outputting printf's, with the gyro completely stationary, I'm getting a steady increase in gyro angle values that (from memory) is around a degree every five seconds or so. The gyro was stationary throughout the cRIO power-up process, and it is connected to Analog Input #1 on the first input module. Last year, I used Kevin Watson's code, with much success. Kevin's code implemented a rejection deadband (ours was set to the default of 8) to help filter out junk and eliminate drift. Other than SetSensitivity (which I currently have set to 0.005 but will adjust to .00393 now that I've found the specific tuning values we used in last year's code), what other gyro setup/tuning adjustments are possible with WPILib's C++ gyro code, and how would we implement this tuning? Thanks in advance, |
Re: Gyro problem
We had the same problem. We found it to be our code by running the sample gyro code. Also check that the wires are not reversed, I know that this has been said before, but it plagued us early in the 6 weeks.
|
Re: Gyro problem
If the gyro is constantly returning the exact same high angular velocity, then the problem is your wiring. Take a multimeter and check the voltage between one of the red/black wires and the signal wire. It should be about 2.5 volts in correct operation. To confirm if this is the case, set up your gyro class so it uses an incorrect PWM input that nothing is plugged into, and see if the behavior changes.
Also, double check that your using both the correct SLOT and correct channel. If you only specify the channel, it might be attempting to read the gyro off of the incorrect cRio slot. If the gyro is constantly returning a varying low angular velocity (1 degree every 5 seconds as posted above is about right), then everything is fine and that is expected. |
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. |
Re: Gyro problem
Quote:
By modifying the Deadband, as suggested, we got much more stable results and still observed good accuracy when moving. |
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? |
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. |
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. |
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?
|
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. |
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(); } |
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: |
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. |
Re: Gyro problem
Quote:
|
Re: Gyro problem
Quote:
|
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.
|
Re: Gyro problem
Quote:
|
Re: Gyro problem
I'm using the KOP gyro with Labview. I connected it to Analog 1 and used the code in the Gyro example.
When I reset the gyro, it doesn't return to 0. The value seems to be consistent (about 0.05 or so). Is this something I can deal with using the temperature input? The VIs don't appear to have any input for temperature. What is a good a pproach for determining the Gyro offset value? |
| All times are GMT -5. The time now is 07:16. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi