James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 1 | #include "frc971/zeroing/imu_zeroer.h" |
| 2 | |
| 3 | namespace frc971::zeroing { |
| 4 | |
| 5 | ImuZeroer::ImuZeroer() { |
| 6 | gyro_average_.setZero(); |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 7 | accel_average_.setZero(); |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 8 | last_gyro_sample_.setZero(); |
| 9 | last_accel_sample_.setZero(); |
| 10 | } |
| 11 | |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 12 | bool ImuZeroer::Zeroed() const { |
| 13 | return num_zeroes_ > kRequiredZeroPoints || Faulted(); |
| 14 | } |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 15 | |
| 16 | bool ImuZeroer::Faulted() const { return faulted_; } |
| 17 | |
| 18 | Eigen::Vector3d ImuZeroer::ZeroedGyro() const { |
| 19 | return last_gyro_sample_ - gyro_average_; |
| 20 | } |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 21 | Eigen::Vector3d ImuZeroer::ZeroedAccel() const { |
| 22 | return last_accel_sample_ - accel_average_; |
| 23 | } |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 24 | Eigen::Vector3d ImuZeroer::GyroOffset() const { return gyro_average_; } |
| 25 | |
| 26 | bool ImuZeroer::GyroZeroReady() const { |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 27 | return gyro_averager_.full() && |
| 28 | gyro_averager_.GetRange() < kGyroMaxVariation && |
| 29 | (last_gyro_sample_.lpNorm<Eigen::Infinity>() < |
| 30 | kGyroMaxZeroingMagnitude); |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 31 | } |
| 32 | |
| 33 | bool ImuZeroer::AccelZeroReady() const { |
| 34 | return accel_averager_.full() && |
| 35 | accel_averager_.GetRange() < kAccelMaxVariation; |
| 36 | } |
| 37 | |
James Kuszmaul | b7f45bb | 2020-02-26 20:27:48 -0800 | [diff] [blame^] | 38 | void ImuZeroer::InsertAndProcessMeasurement(const IMUValues &values) { |
| 39 | InsertMeasurement(values); |
| 40 | ProcessMeasurements(); |
| 41 | } |
| 42 | |
| 43 | void ImuZeroer::InsertMeasurement(const IMUValues &values) { |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 44 | last_gyro_sample_ << values.gyro_x(), values.gyro_y(), values.gyro_z(); |
| 45 | gyro_averager_.AddData(last_gyro_sample_); |
| 46 | last_accel_sample_ << values.accelerometer_x(), values.accelerometer_y(), |
| 47 | values.accelerometer_z(); |
| 48 | accel_averager_.AddData(last_accel_sample_); |
James Kuszmaul | b7f45bb | 2020-02-26 20:27:48 -0800 | [diff] [blame^] | 49 | } |
| 50 | |
| 51 | void ImuZeroer::ProcessMeasurements() { |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 52 | if (GyroZeroReady() && AccelZeroReady()) { |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 53 | ++good_iters_; |
James Kuszmaul | b7f45bb | 2020-02-26 20:27:48 -0800 | [diff] [blame^] | 54 | if (good_iters_ > kSamplesToAverage / 40) { |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 55 | const Eigen::Vector3d current_gyro_average = gyro_averager_.GetAverage(); |
| 56 | constexpr double kAverageUpdateWeight = 0.05; |
| 57 | if (num_zeroes_ > 0) { |
| 58 | gyro_average_ += |
| 59 | (current_gyro_average - gyro_average_) * kAverageUpdateWeight; |
| 60 | } else { |
| 61 | gyro_average_ = current_gyro_average; |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 62 | } |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 63 | if (num_zeroes_ > 0) { |
| 64 | // If we got a new zero and it is substantially different from the |
| 65 | // original zero, fault. |
| 66 | if ((current_gyro_average - gyro_average_).norm() > |
| 67 | kGyroFaultVariation) { |
| 68 | faulted_ = true; |
| 69 | } |
| 70 | } |
| 71 | ++num_zeroes_; |
| 72 | gyro_averager_.Reset(); |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 73 | } |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 74 | } else { |
| 75 | good_iters_ = 0; |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 76 | } |
| 77 | } |
| 78 | |
James Kuszmaul | b1e2937 | 2020-02-11 16:55:36 -0800 | [diff] [blame] | 79 | flatbuffers::Offset<control_loops::drivetrain::ImuZeroerState> |
| 80 | ImuZeroer::PopulateStatus(flatbuffers::FlatBufferBuilder *fbb) const { |
| 81 | control_loops::drivetrain::ImuZeroerState::Builder builder(*fbb); |
| 82 | |
| 83 | builder.add_zeroed(Zeroed()); |
| 84 | builder.add_faulted(Faulted()); |
| 85 | builder.add_number_of_zeroes(num_zeroes_); |
| 86 | |
| 87 | builder.add_gyro_x_average(GyroOffset().x()); |
| 88 | builder.add_gyro_y_average(GyroOffset().y()); |
| 89 | builder.add_gyro_z_average(GyroOffset().z()); |
| 90 | |
| 91 | return builder.Finish(); |
| 92 | } |
| 93 | |
James Kuszmaul | d3f9eb2 | 2020-01-12 15:02:07 -0800 | [diff] [blame] | 94 | } // namespace frc971::zeroing |