blob: b13b43d12fb3ea9fb72799683b7b9bf0d60e3451 [file] [log] [blame]
James Kuszmauld3f9eb22020-01-12 15:02:07 -08001#include "frc971/zeroing/imu_zeroer.h"
2
3namespace frc971::zeroing {
4
5ImuZeroer::ImuZeroer() {
6 gyro_average_.setZero();
James Kuszmaulb1e29372020-02-11 16:55:36 -08007 accel_average_.setZero();
James Kuszmauld3f9eb22020-01-12 15:02:07 -08008 last_gyro_sample_.setZero();
9 last_accel_sample_.setZero();
10}
11
James Kuszmaulb1e29372020-02-11 16:55:36 -080012bool ImuZeroer::Zeroed() const {
13 return num_zeroes_ > kRequiredZeroPoints || Faulted();
14}
James Kuszmauld3f9eb22020-01-12 15:02:07 -080015
16bool ImuZeroer::Faulted() const { return faulted_; }
17
18Eigen::Vector3d ImuZeroer::ZeroedGyro() const {
19 return last_gyro_sample_ - gyro_average_;
20}
James Kuszmaulb1e29372020-02-11 16:55:36 -080021Eigen::Vector3d ImuZeroer::ZeroedAccel() const {
22 return last_accel_sample_ - accel_average_;
23}
James Kuszmauld3f9eb22020-01-12 15:02:07 -080024Eigen::Vector3d ImuZeroer::GyroOffset() const { return gyro_average_; }
25
26bool ImuZeroer::GyroZeroReady() const {
James Kuszmaulb1e29372020-02-11 16:55:36 -080027 return gyro_averager_.full() &&
28 gyro_averager_.GetRange() < kGyroMaxVariation &&
29 (last_gyro_sample_.lpNorm<Eigen::Infinity>() <
30 kGyroMaxZeroingMagnitude);
James Kuszmauld3f9eb22020-01-12 15:02:07 -080031}
32
33bool ImuZeroer::AccelZeroReady() const {
34 return accel_averager_.full() &&
35 accel_averager_.GetRange() < kAccelMaxVariation;
36}
37
38void ImuZeroer::ProcessMeasurement(const IMUValues &values) {
39 last_gyro_sample_ << values.gyro_x(), values.gyro_y(), values.gyro_z();
40 gyro_averager_.AddData(last_gyro_sample_);
41 last_accel_sample_ << values.accelerometer_x(), values.accelerometer_y(),
42 values.accelerometer_z();
43 accel_averager_.AddData(last_accel_sample_);
44 if (GyroZeroReady() && AccelZeroReady()) {
James Kuszmaulb1e29372020-02-11 16:55:36 -080045 ++good_iters_;
46 if (good_iters_ > kSamplesToAverage / 4) {
47 const Eigen::Vector3d current_gyro_average = gyro_averager_.GetAverage();
48 constexpr double kAverageUpdateWeight = 0.05;
49 if (num_zeroes_ > 0) {
50 gyro_average_ +=
51 (current_gyro_average - gyro_average_) * kAverageUpdateWeight;
52 } else {
53 gyro_average_ = current_gyro_average;
James Kuszmauld3f9eb22020-01-12 15:02:07 -080054 }
James Kuszmaulb1e29372020-02-11 16:55:36 -080055 if (num_zeroes_ > 0) {
56 // If we got a new zero and it is substantially different from the
57 // original zero, fault.
58 if ((current_gyro_average - gyro_average_).norm() >
59 kGyroFaultVariation) {
60 faulted_ = true;
61 }
62 }
63 ++num_zeroes_;
64 gyro_averager_.Reset();
James Kuszmauld3f9eb22020-01-12 15:02:07 -080065 }
James Kuszmaulb1e29372020-02-11 16:55:36 -080066 } else {
67 good_iters_ = 0;
James Kuszmauld3f9eb22020-01-12 15:02:07 -080068 }
69}
70
James Kuszmaulb1e29372020-02-11 16:55:36 -080071flatbuffers::Offset<control_loops::drivetrain::ImuZeroerState>
72ImuZeroer::PopulateStatus(flatbuffers::FlatBufferBuilder *fbb) const {
73 control_loops::drivetrain::ImuZeroerState::Builder builder(*fbb);
74
75 builder.add_zeroed(Zeroed());
76 builder.add_faulted(Faulted());
77 builder.add_number_of_zeroes(num_zeroes_);
78
79 builder.add_gyro_x_average(GyroOffset().x());
80 builder.add_gyro_y_average(GyroOffset().y());
81 builder.add_gyro_z_average(GyroOffset().z());
82
83 return builder.Finish();
84}
85
James Kuszmauld3f9eb22020-01-12 15:02:07 -080086} // namespace frc971::zeroing