blob: 2a5036d19246c40d23efbb9559e1b8d83d376c54 [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
33 explicit ImuZeroer(FaultBehavior fault_behavior = FaultBehavior::kLatch);
James Kuszmauld3f9eb22020-01-12 15:02:07 -080034 bool Zeroed() const;
35 bool Faulted() const;
James Kuszmaul6d6e1302022-03-12 15:22:48 -080036 bool InsertMeasurement(const IMUValues &values);
James Kuszmaulb7f45bb2020-02-26 20:27:48 -080037 // PErforms the heavier-duty processing for managing zeroing.
38 void ProcessMeasurements();
39 void InsertAndProcessMeasurement(const IMUValues &values);
James Kuszmauld3f9eb22020-01-12 15:02:07 -080040 Eigen::Vector3d GyroOffset() const;
James Kuszmaul6d6e1302022-03-12 15:22:48 -080041 std::optional<Eigen::Vector3d> ZeroedGyro() const;
42 std::optional<Eigen::Vector3d> ZeroedAccel() const;
James Kuszmaulb1e29372020-02-11 16:55:36 -080043
44 flatbuffers::Offset<control_loops::drivetrain::ImuZeroerState> PopulateStatus(
45 flatbuffers::FlatBufferBuilder *fbb) const;
46
James Kuszmauld3f9eb22020-01-12 15:02:07 -080047 private:
48 // Max variation (difference between the maximum and minimum value) in a
49 // kSamplesToAverage range before we allow using the samples for zeroing.
50 // These values are currently based on looking at results from the ADIS16448.
Philipp Schrader790cb542023-07-05 21:06:52 -070051 static constexpr double kGyroMaxVariation = 0.02; // rad / sec
James Kuszmaulb1e29372020-02-11 16:55:36 -080052 // Maximum magnitude we allow the gyro zero to have--this is used to prevent
53 // us from zeroing the gyro if we just happen to be spinning at a very
54 // consistent non-zero rate. Currently this is only plausible in simulation.
55 static constexpr double kGyroMaxZeroingMagnitude = 0.1; // rad / sec
James Kuszmauld3f9eb22020-01-12 15:02:07 -080056 // Max variation in the range before we consider the accelerometer readings to
57 // be steady.
Philipp Schrader790cb542023-07-05 21:06:52 -070058 static constexpr double kAccelMaxVariation = 0.05; // g's
James Kuszmauld3f9eb22020-01-12 15:02:07 -080059 // If we ever are able to rezero and get a zero that is more than
60 // kGyroFaultVariation away from the original zeroing, fault.
James Kuszmaulad2f8db2021-10-24 17:02:57 -070061 static constexpr double kGyroFaultVariation = 0.05; // rad / sec
James Kuszmauld3f9eb22020-01-12 15:02:07 -080062
63 bool GyroZeroReady() const;
64 bool AccelZeroReady() const;
65
66 Averager<double, kSamplesToAverage, 3> gyro_averager_;
67 // Averager for the accelerometer readings--we don't currently actually
68 // average the readings, but we do check that the accelerometer readings have
69 // stayed roughly constant during the calibration period.
70 Averager<double, kSamplesToAverage, 3> accel_averager_;
71 // The average zero position of the gyro.
72 Eigen::Vector3d gyro_average_;
73 Eigen::Vector3d last_gyro_sample_;
74 Eigen::Vector3d last_accel_sample_;
James Kuszmaul6d6e1302022-03-12 15:22:48 -080075
76 const FaultBehavior fault_behavior_;
77 bool reading_faulted_ = false;
78 bool zeroing_faulted_ = false;
79
James Kuszmaulb1e29372020-02-11 16:55:36 -080080 size_t good_iters_ = 0;
81 size_t num_zeroes_ = 0;
James Kuszmauld3f9eb22020-01-12 15:02:07 -080082};
83
84} // namespace frc971::zeroing
85#endif // FRC971_ZEROING_IMU_ZEROER_H_