While looking up documentation for wiring a gyro (specifically this one: http://frc-labs.com/wp-content/uploads/2012/03/GyroAccelerometer1.jpg), many of the sources recommend using both rate and temp. However, while actually coding it doesn’t seem that the Gyro class is able to use more than one analog port. Does anyone have any pointers for incorporating temp?
The output is wired up to the header, but I’ve never used it.
The Gyro class itself doesn’t appear to have any way of taking in the temperature output of the sensor into account. But it does make an attempt at calibrating the sensor when the robot is turned on. It looks like it takes samples from the analog channel for 5 seconds on startup and uses these samples to determine the voltage value for a rate of rotation of zero.
/** * Initialize the gyro. * Calibrate the gyro 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. */ private void initGyro() { result = new AccumulatorResult(); if (m_analog == null) { System.out.println("Null m_analog"); } m_voltsPerDegreePerSecond = kDefaultVoltsPerDegreePerSecond; m_analog.setAverageBits(kAverageBits); m_analog.setOversampleBits(kOversampleBits); double sampleRate = kSamplesPerSecond * (1 << (kAverageBits + kOversampleBits)); m_analog.getModule().setSampleRate(sampleRate); Timer.delay(1.0); m_analog.initAccumulator(); Timer.delay(kCalibrationSampleTime); m_analog.getAccumulatorOutput(result); int center = (int) ((double)result.value / (double)result.count + .5); m_offset = ((double)result.value / (double)result.count) - (double)center; m_analog.setAccumulatorCenter(center); m_analog.setAccumulatorDeadband(0); ///< TODO: compute / parameterize this m_analog.resetAccumulator(); UsageReporting.report(UsageReporting.kResourceType_Gyro, m_analog.getChannel(), m_analog.getModuleNumber()-1); LiveWindow.addSensor("Gyro", m_analog.getModuleNumber(), m_analog.getChannel(), this); }
We had pretty reliable performance with the KOP gyro this year. In past years it has been pretty flaky, but this could very well have been due to soft/hardware problems on our end which we never found solutions to.
The code we used for interfacing to the Gyro itself, boils down to the following:
//Setup
Gyro turnSense = new Gyro(RobotMap.gyroChannel);
turnSense.setSensitivity(0.0070);
resetAngle();
//Our auto mode code would perform a series of driving in straight
// lines and turns to move around the field.
//Before turning we would always zero out the gyro
turnSense.reset();
//Then turn the robot while monitoring the current angle
turnSense.getAngle();
The code was about as simple as it can get, and it worked quite effectively.
You can see a video here.
If you are set on making use of temperature compensation, I would suggest reading the application note from analog devices: http://www.analog.com/static/imported-files/application_notes/AN-1049.pdf
And this note in the datasheet may be of importance (page 9):
The temperature output is characteristically nonlinear, and any
load resistance connected to the TEMP output results in decreasing
the TEMP output and its temperature coefficient. Therefore,
buffering the output is recommended.
I’m not sure if the breakout board we get in the KOP buffers the output already or if you would need to add additional circuitry between the gyro and the DSC. Something to look in to.
I’m curious what sources have recommended using temp and how they recommend using it. Everything I’ve seen mentions temp is available, but haven’t recommended it. Given that our the temperature in a match hardly varies, I’m not sure what the benefit using temperature is, over the single point calibration the gyro class performs.
I suppose what I meant was not that the temperature was “recommended for frc use” but rather that it was a standard part of the gyro’s wiring. I’m not particularly set on using it, especially if most teams have found the gyro reliable without it.
My thought is to monitor it through a few matches and see if it is moving enough to be worth your effort. The effect I would be most concerned with is self-heating - can you see a difference between powering on the system from cold and rebooting the system after it has been on for a while?
As long as the temperature doesn’t change significantly from the time you powered the robot on, it shouldn’t make a difference, as the calibration procedure is performed on startup every time (at least in Java).
As others have mentioned the WPILib gyro class doesn’t support temperature and most teams don’t seem to use the temperature. They seem find just the gyro output calibrated from WPILib accurate enough. However, if you want to incorporate the temperature of the gyro, the best way to start is to look at the datasheet. If you look at the datatsheet[1] for your gyro, it should describe the relationship between temperature and the voltage reading. Then you can just copy the code of gyro class and create a custom class for a gyro with temperature correction that reads the temperature at calibration and uses that when calculating the angular rate. The biggest difficulty with this is that you can’t do this and use the FPGAs hardware accumulator, which may make a bigger difference depending on your application.
[1] For the 2009 Gyro. Page 9: http://www.usfirst.org/uploadedFiles/2009%20Sensor%20Manual%20Rev%20B.pdf
Self heating is definitely a factor. If you read the yaw rate output voltage right after cold boot, and then read after it has been on for a few minutes, I guarantee you will see a difference. If you calibrate the gyro (which in WPIlib usually means calling the constructor for the gyro) as soon as the robot boots, but it takes ~5-10 minutes before the match begins, your gyro will be drifting quite a bit by the time you need it.
One way to deal with the effects of self heating would be to use the temperature input and derive a model that takes into account the effects of temperature on the yaw rate output.
A far simpler way is to re-calibrate your gyro as close to the match start time as possible (this is easy to do if you make a couple of modifications to the WPIlib Gyro class - make the initGyro() method public and call it via button press from the Driver Station when you are in the Disabled state).