blob: 52f6cc051b90615291f0c004bd66927b840d44b7 [file] [log] [blame]
James Kuszmauld3f9eb22020-01-12 15:02:07 -08001#ifndef FRC971_ZEROING_IMU_ZEROER_H_
2#define FRC971_ZEROING_IMU_ZEROER_H_
3
James Kuszmaul6d6e1302022-03-12 15:22:48 -08004#include <optional>
5
James Kuszmaulb1e29372020-02-11 16:55:36 -08006#include "frc971/control_loops/drivetrain/drivetrain_status_generated.h"
James Kuszmauld3f9eb22020-01-12 15:02:07 -08007#include "frc971/wpilib/imu_generated.h"
8#include "frc971/zeroing/averager.h"
9
10namespace frc971::zeroing {
11
12// This class handles processing IMU measurements and zeroing them once it is
13// able to do so.
14class ImuZeroer {
15 public:
James Kuszmaul30aca502020-01-19 15:05:33 -080016 // Average 0.5 seconds of data (assuming 2kHz sampling rate).
James Kuszmaul3e1bb272020-01-17 18:38:19 -080017 // TODO(james): Make the gyro zero in a constant amount of time, rather than a
18 // constant number of samples...
James Kuszmaul30aca502020-01-19 15:05:33 -080019 // TODO(james): Run average and GetRange calculations over every sample on
20 // every timestep, to provide consistent timing.
James Kuszmaul0a981402021-10-09 21:00:34 -070021 static constexpr size_t kSamplesToAverage = 200;
James Kuszmaulb1e29372020-02-11 16:55:36 -080022 static constexpr size_t kRequiredZeroPoints = 10;
James Kuszmauld3f9eb22020-01-12 15:02:07 -080023
James Kuszmaul6d6e1302022-03-12 15:22:48 -080024 enum class FaultBehavior {
25 // When we encounter a fault, latch and stay in an errored state
26 // indefinitely.
27 kLatch,
28 // When we encounter a fault, don't process the reading and return nullopt
29 // for all measurements.
30 kTemporary
31 };
32
James Kuszmauldb85fa32024-03-16 16:55:47 -070033 // Max variation (difference between the maximum and minimum value) in a
34 // kSamplesToAverage range before we allow using the samples for zeroing.
35 // These values are currently based on looking at results from the ADIS16448.
36 static constexpr double kGyroMaxVariation = 0.02; // rad / sec
37
38 explicit ImuZeroer(FaultBehavior fault_behavior = FaultBehavior::kLatch,
39 double gyro_max_variation = kGyroMaxVariation);
James Kuszmauld3f9eb22020-01-12 15:02:07 -080040 bool Zeroed() const;
41 bool Faulted() const;
James Kuszmaul6d6e1302022-03-12 15:22:48 -080042 bool InsertMeasurement(const IMUValues &values);
James Kuszmaulb7f45bb2020-02-26 20:27:48 -080043 // PErforms the heavier-duty processing for managing zeroing.
44 void ProcessMeasurements();
45 void InsertAndProcessMeasurement(const IMUValues &values);
James Kuszmauld3f9eb22020-01-12 15:02:07 -080046 Eigen::Vector3d GyroOffset() const;
James Kuszmaul6d6e1302022-03-12 15:22:48 -080047 std::optional<Eigen::Vector3d> ZeroedGyro() const;
48 std::optional<Eigen::Vector3d> ZeroedAccel() const;
James Kuszmaulb1e29372020-02-11 16:55:36 -080049
50 flatbuffers::Offset<control_loops::drivetrain::ImuZeroerState> PopulateStatus(
51 flatbuffers::FlatBufferBuilder *fbb) const;
52
James Kuszmauld3f9eb22020-01-12 15:02:07 -080053 private:
James Kuszmaulb1e29372020-02-11 16:55:36 -080054 // Maximum magnitude we allow the gyro zero to have--this is used to prevent
55 // us from zeroing the gyro if we just happen to be spinning at a very
56 // consistent non-zero rate. Currently this is only plausible in simulation.
57 static constexpr double kGyroMaxZeroingMagnitude = 0.1; // rad / sec
James Kuszmauld3f9eb22020-01-12 15:02:07 -080058 // Max variation in the range before we consider the accelerometer readings to
59 // be steady.
Philipp Schrader790cb542023-07-05 21:06:52 -070060 static constexpr double kAccelMaxVariation = 0.05; // g's
James Kuszmauld3f9eb22020-01-12 15:02:07 -080061 // If we ever are able to rezero and get a zero that is more than
62 // kGyroFaultVariation away from the original zeroing, fault.
James Kuszmaulad2f8db2021-10-24 17:02:57 -070063 static constexpr double kGyroFaultVariation = 0.05; // rad / sec
James Kuszmauld3f9eb22020-01-12 15:02:07 -080064
65 bool GyroZeroReady() const;
66 bool AccelZeroReady() const;
67
68 Averager<double, kSamplesToAverage, 3> gyro_averager_;
69 // Averager for the accelerometer readings--we don't currently actually
70 // average the readings, but we do check that the accelerometer readings have
71 // stayed roughly constant during the calibration period.
72 Averager<double, kSamplesToAverage, 3> accel_averager_;
73 // The average zero position of the gyro.
74 Eigen::Vector3d gyro_average_;
75 Eigen::Vector3d last_gyro_sample_;
76 Eigen::Vector3d last_accel_sample_;
James Kuszmaul6d6e1302022-03-12 15:22:48 -080077
78 const FaultBehavior fault_behavior_;
James Kuszmauldb85fa32024-03-16 16:55:47 -070079 const double gyro_max_variation_;
James Kuszmaul6d6e1302022-03-12 15:22:48 -080080 bool reading_faulted_ = false;
81 bool zeroing_faulted_ = false;
82
James Kuszmaulb1e29372020-02-11 16:55:36 -080083 size_t good_iters_ = 0;
84 size_t num_zeroes_ = 0;
James Kuszmauld3f9eb22020-01-12 15:02:07 -080085};
86
87} // namespace frc971::zeroing
88#endif // FRC971_ZEROING_IMU_ZEROER_H_