James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 1 | #ifndef FRC971_ZEROING_IMU_ZEROER_H_ |
| 2 | #define FRC971_ZEROING_IMU_ZEROER_H_ |
| 3 | |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 4 | #include "frc971/control_loops/drivetrain/drivetrain_status_generated.h" |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 5 | #include "frc971/wpilib/imu_generated.h" |
| 6 | #include "frc971/zeroing/averager.h" |
| 7 | |
| 8 | namespace frc971::zeroing { |
| 9 | |
| 10 | // This class handles processing IMU measurements and zeroing them once it is |
| 11 | // able to do so. |
| 12 | class ImuZeroer { |
| 13 | public: |
James Kuszmaul | 30aca50 | 2020-01-19 15:05:33 -0800 | [diff] [blame] | 14 | // Average 0.5 seconds of data (assuming 2kHz sampling rate). |
James Kuszmaul | 3e1bb27 | 2020-01-17 18:38:19 -0800 | [diff] [blame] | 15 | // TODO(james): Make the gyro zero in a constant amount of time, rather than a |
| 16 | // constant number of samples... |
James Kuszmaul | 30aca50 | 2020-01-19 15:05:33 -0800 | [diff] [blame] | 17 | // TODO(james): Run average and GetRange calculations over every sample on |
| 18 | // every timestep, to provide consistent timing. |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 19 | static constexpr size_t kSamplesToAverage = 1000; |
| 20 | static constexpr size_t kRequiredZeroPoints = 10; |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 21 | |
| 22 | ImuZeroer(); |
| 23 | bool Zeroed() const; |
| 24 | bool Faulted() const; |
| 25 | void ProcessMeasurement(const IMUValues &values); |
| 26 | Eigen::Vector3d GyroOffset() const; |
| 27 | Eigen::Vector3d ZeroedGyro() const; |
| 28 | Eigen::Vector3d ZeroedAccel() const; |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 29 | |
| 30 | flatbuffers::Offset<control_loops::drivetrain::ImuZeroerState> PopulateStatus( |
| 31 | flatbuffers::FlatBufferBuilder *fbb) const; |
| 32 | |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 33 | private: |
| 34 | // Max variation (difference between the maximum and minimum value) in a |
| 35 | // kSamplesToAverage range before we allow using the samples for zeroing. |
| 36 | // These values are currently based on looking at results from the ADIS16448. |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 37 | static constexpr double kGyroMaxVariation = 0.02; // rad / sec |
| 38 | // Maximum magnitude we allow the gyro zero to have--this is used to prevent |
| 39 | // us from zeroing the gyro if we just happen to be spinning at a very |
| 40 | // consistent non-zero rate. Currently this is only plausible in simulation. |
| 41 | static constexpr double kGyroMaxZeroingMagnitude = 0.1; // rad / sec |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 42 | // Max variation in the range before we consider the accelerometer readings to |
| 43 | // be steady. |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 44 | static constexpr double kAccelMaxVariation = 0.05; // g's |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 45 | // If we ever are able to rezero and get a zero that is more than |
| 46 | // kGyroFaultVariation away from the original zeroing, fault. |
| 47 | static constexpr double kGyroFaultVariation = 0.005; // rad / sec |
| 48 | |
| 49 | bool GyroZeroReady() const; |
| 50 | bool AccelZeroReady() const; |
| 51 | |
| 52 | Averager<double, kSamplesToAverage, 3> gyro_averager_; |
| 53 | // Averager for the accelerometer readings--we don't currently actually |
| 54 | // average the readings, but we do check that the accelerometer readings have |
| 55 | // stayed roughly constant during the calibration period. |
| 56 | Averager<double, kSamplesToAverage, 3> accel_averager_; |
| 57 | // The average zero position of the gyro. |
| 58 | Eigen::Vector3d gyro_average_; |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 59 | Eigen::Vector3d accel_average_; |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 60 | Eigen::Vector3d last_gyro_sample_; |
| 61 | Eigen::Vector3d last_accel_sample_; |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 62 | // Whether the zeroing has faulted at any point thus far. |
| 63 | bool faulted_ = false; |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 64 | size_t good_iters_ = 0; |
| 65 | size_t num_zeroes_ = 0; |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 66 | }; |
| 67 | |
| 68 | } // namespace frc971::zeroing |
| 69 | #endif // FRC971_ZEROING_IMU_ZEROER_H_ |