APM:Libraries
AccelCalibrator.h
Go to the documentation of this file.
1 /*
2  This program is free software: you can redistribute it and/or modify
3  it under the terms of the GNU General Public License as published by
4  the Free Software Foundation, either version 3 of the License, or
5  (at your option) any later version.
6  This program is distributed in the hope that it will be useful,
7  but WITHOUT ANY WARRANTY; without even the implied warranty of
8  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  GNU General Public License for more details.
10  You should have received a copy of the GNU General Public License
11  along with this program. If not, see <http://www.gnu.org/licenses/>.
12 */
13 #pragma once
14 
15 #include <AP_Math/AP_Math.h>
16 #include <AP_Math/vectorN.h>
17 
18 #define ACCEL_CAL_MAX_NUM_PARAMS 9
19 #define ACCEL_CAL_TOLERANCE 0.1
20 #define MAX_ITERATIONS 50
27 };
28 
32 };
33 
35 public:
37 
38  //Select options, initialise variables and initiate accel calibration
39  void start(enum accel_cal_fit_type_t fit_type = ACCEL_CAL_AXIS_ALIGNED_ELLIPSOID, uint8_t num_samples = 6, float sample_time = 0.5f);
40  void start(enum accel_cal_fit_type_t fit_type, uint8_t num_samples, float sample_time, Vector3f offset, Vector3f diag, Vector3f offdiag);
41 
42  // set Accel calibrator status to make itself ready for future accel cals
43  void clear();
44 
45  // returns true if accel calibrator is running
46  bool running();
47 
48  // set Accel calibrator to start collecting samples in the next cycle
49  void collect_sample();
50 
51  // check if client's calibrator is active
52  void check_for_timeout();
53 
54  // get diag,offset or offdiag parameters as per the selected fitting surface or request
55  void get_calibration(Vector3f& offset) const;
56  void get_calibration(Vector3f& offset, Vector3f& diag) const;
57  void get_calibration(Vector3f& offset, Vector3f& diag, Vector3f& offdiag) const;
58 
59 
60  // collect and avg sample to be passed onto LSQ estimator after all requisite orientations are done
61  void new_sample(const Vector3f& delta_velocity, float dt);
62 
63  // interface for LSq estimator to read sample buffer sent after conversion from delta velocity
64  // to averaged acc over time
65  bool get_sample(uint8_t i, Vector3f& s) const;
66 
67  // returns truen and sample corrected with diag offdiag parameters as calculated by LSq estimation procedure
68  // returns false if no correct parameter exists to be applied along with existing sample without corrections
69  bool get_sample_corrected(uint8_t i, Vector3f& s) const;
70 
71  // set tolerance bar for parameter fitness value to cross so as to be deemed as correct values
72  void set_tolerance(float tolerance) { _conf_tolerance = tolerance; }
73 
74  // returns current state of accel calibrators
75  enum accel_cal_status_t get_status() const { return _status; }
76 
77  // returns number of samples collected
78  uint8_t get_num_samples_collected() const { return _samples_collected; }
79 
80  // returns mean squared fitness of sample points to the selected surface
81  float get_fitness() const { return _fitness; }
82 
83  struct param_t {
87  };
88 
89 private:
90  struct AccelSample {
92  float delta_time;
93  };
95 
96  union param_u {
97  struct param_t s;
99 
100  param_u() : a{}
101  {
102  static_assert(sizeof(*this) == sizeof(struct param_t),
103  "Invalid union members: sizes do not match");
104  }
105  };
106 
107  //configuration
112 
113  // state
118  float _fitness;
121 
122  // private methods
123  // check sanity of including the sample and add it to buffer if test is passed
124  bool accept_sample(const Vector3f& sample);
125 
126  // reset to calibrator state before the start of calibration
127  void reset_state();
128 
129  // sets status of calibrator and takes appropriate actions
130  void set_status(enum accel_cal_status_t);
131 
132  // determines if the result is acceptable
133  bool accept_result() const;
134 
135  // returns number of parameters are required for selected Fit type
136  uint8_t get_num_params() const;
137 
138  // Function related to Gauss Newton Least square regression process
139  float calc_residual(const Vector3f& sample, const struct param_t& params) const;
140  float calc_mean_squared_residuals() const;
141  float calc_mean_squared_residuals(const struct param_t& params) const;
142  void calc_jacob(const Vector3f& sample, const struct param_t& params, VectorP& ret) const;
143  void run_fit(uint8_t max_iterations, float& fitness);
144 };
bool get_sample_corrected(uint8_t i, Vector3f &s) const
struct AccelSample * _sample_buffer
float calc_residual(const Vector3f &sample, const struct param_t &params) const
void set_tolerance(float tolerance)
uint8_t get_num_params() const
uint32_t _last_samp_frag_collected_ms
void start(enum accel_cal_fit_type_t fit_type=ACCEL_CAL_AXIS_ALIGNED_ELLIPSOID, uint8_t num_samples=6, float sample_time=0.5f)
accel_cal_status_t
void calc_jacob(const Vector3f &sample, const struct param_t &params, VectorP &ret) const
uint8_t _conf_num_samples
float get_fitness() const
void get_calibration(Vector3f &offset) const
uint8_t get_num_samples_collected() const
union param_u _param
void set_status(enum accel_cal_status_t)
accel_cal_status_t _status
bool accept_sample(const Vector3f &sample)
bool accept_result() const
#define f(i)
uint8_t _samples_collected
bool get_sample(uint8_t i, Vector3f &s) const
enum accel_cal_fit_type_t _conf_fit_type
VectorN< float, ACCEL_CAL_MAX_NUM_PARAMS > a
float calc_mean_squared_residuals() const
void new_sample(const Vector3f &delta_velocity, float dt)
enum accel_cal_status_t get_status() const
accel_cal_fit_type_t
VectorN< float, ACCEL_CAL_MAX_NUM_PARAMS > VectorP
void run_fit(uint8_t max_iterations, float &fitness)