blob: 9e82d132bb6e30eb84969be9dafbbf6666821ac4 [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
James Kuszmaulb7f45bb2020-02-26 20:27:48 -080038void ImuZeroer::InsertAndProcessMeasurement(const IMUValues &values) {
39 InsertMeasurement(values);
40 ProcessMeasurements();
41}
42
43void ImuZeroer::InsertMeasurement(const IMUValues &values) {
James Kuszmauld3f9eb22020-01-12 15:02:07 -080044 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 Kuszmaulb7f45bb2020-02-26 20:27:48 -080049}
50
51void ImuZeroer::ProcessMeasurements() {
James Kuszmauld3f9eb22020-01-12 15:02:07 -080052 if (GyroZeroReady() && AccelZeroReady()) {
James Kuszmaulb1e29372020-02-11 16:55:36 -080053 ++good_iters_;
James Kuszmaulb7f45bb2020-02-26 20:27:48 -080054 if (good_iters_ > kSamplesToAverage / 40) {
James Kuszmaulb1e29372020-02-11 16:55:36 -080055 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 Kuszmauld3f9eb22020-01-12 15:02:07 -080062 }
James Kuszmaulb1e29372020-02-11 16:55:36 -080063 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 Kuszmauld3f9eb22020-01-12 15:02:07 -080073 }
James Kuszmaulb1e29372020-02-11 16:55:36 -080074 } else {
75 good_iters_ = 0;
James Kuszmauld3f9eb22020-01-12 15:02:07 -080076 }
77}
78
James Kuszmaulb1e29372020-02-11 16:55:36 -080079flatbuffers::Offset<control_loops::drivetrain::ImuZeroerState>
80ImuZeroer::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 Kuszmauld3f9eb22020-01-12 15:02:07 -080094} // namespace frc971::zeroing