Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ardupilot
GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_AHRS/AP_AHRS_DCM.h
9810 views
1
#pragma once
2
3
/*
4
This program is free software: you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation, either version 3 of the License, or
7
(at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program. If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
/*
19
* DCM based AHRS (Attitude Heading Reference System) interface for
20
* ArduPilot
21
*
22
*/
23
24
#include "AP_AHRS_config.h"
25
26
#if AP_AHRS_DCM_ENABLED
27
28
#include "AP_AHRS_Backend.h"
29
30
class AP_AHRS_DCM : public AP_AHRS_Backend {
31
public:
32
33
AP_AHRS_DCM(AP_Float &kp_yaw,
34
AP_Float &kp,
35
AP_Float &_gps_gain,
36
AP_Float &_beta,
37
AP_Enum<GPSUse> &gps_use,
38
AP_Int8 &gps_minsats)
39
: AP_AHRS_Backend(),
40
_kp_yaw(kp_yaw),
41
_kp(kp),
42
gps_gain(_gps_gain),
43
beta(_beta),
44
_gps_minsats(gps_minsats),
45
_gps_use(gps_use)
46
{
47
_dcm_matrix.identity();
48
}
49
50
/* Do not allow copies */
51
CLASS_NO_COPY(AP_AHRS_DCM);
52
53
// reset the current gyro drift estimate
54
// should be called if gyro offsets are recalculated
55
void reset_gyro_drift() override;
56
57
// Methods
58
void update() override;
59
void get_results(Estimates &results) override;
60
void reset() override { reset(false); }
61
62
// return true if yaw has been initialised
63
bool yaw_initialised(void) const {
64
return have_initial_yaw;
65
}
66
67
// status reporting
68
float get_error_rp() const {
69
return _error_rp;
70
}
71
float get_error_yaw() const {
72
return _error_yaw;
73
}
74
75
// return a wind estimation vector, in m/s
76
bool wind_estimate(Vector3f &wind) const override {
77
wind = _wind;
78
return true;
79
}
80
81
void set_external_wind_estimate(float speed, float direction);
82
83
// return an airspeed estimate if available. return true
84
// if we have an estimate
85
bool airspeed_EAS(float &airspeed_ret) const override;
86
87
// return an airspeed estimate if available. return true
88
// if we have an estimate from a specific sensor index
89
bool airspeed_EAS(uint8_t airspeed_index, float &airspeed_ret) const override;
90
91
// return a ground vector estimate in meters/second, in North/East order
92
Vector2f groundspeed_vector() override;
93
94
bool use_compass() override;
95
96
void estimate_wind(void);
97
98
// is the AHRS subsystem healthy?
99
bool healthy() const override;
100
101
// returns false if we fail arming checks, in which case the buffer will be populated with a failure message
102
// requires_position should be true if horizontal position configuration should be checked (not used)
103
bool pre_arm_check(bool requires_position, char *failure_msg, uint8_t failure_msg_len) const override;
104
105
// relative-origin functions for fallback in AP_InertialNav
106
bool get_origin(Location &ret) const override;
107
bool get_relative_position_NED_origin(Vector3p &vec) const override;
108
bool get_relative_position_NE_origin(Vector2p &posNE) const override;
109
bool get_relative_position_D_origin(postype_t &posD) const override;
110
111
void send_ekf_status_report(class GCS_MAVLINK &link) const override;
112
113
// return true if DCM has a yaw source
114
bool yaw_source_available(void) const;
115
116
void get_control_limits(float &ekfGndSpdLimit, float &controlScaleXY) const override;
117
118
private:
119
120
// Get a derivative of the vertical position in m/s which is kinematically consistent with the vertical position is required by some control loops.
121
// This is different to the vertical velocity from the EKF which is not always consistent with the vertical position due to the various errors that are being corrected for.
122
bool get_vert_pos_rate_D(float &velocity) const;
123
124
bool get_velocity_NED(Vector3f &vec) const;
125
126
// dead-reckoning support
127
bool get_location(Location &loc) const;
128
129
// settable parameters
130
AP_Float &_kp_yaw;
131
AP_Float &_kp;
132
AP_Float &gps_gain;
133
134
AP_Float &beta;
135
136
AP_Int8 &_gps_minsats;
137
138
AP_Enum<GPSUse> &_gps_use;
139
140
// these are experimentally derived from the simulator
141
// with large drift levels
142
static constexpr float _ki = 0.0087f;
143
static constexpr float _ki_yaw = 0.01f;
144
145
// accelerometer values in the earth frame in m/s/s
146
Vector3f _accel_ef;
147
148
// Methods
149
void matrix_update(void);
150
void normalize(void);
151
void check_matrix(void);
152
bool renorm(Vector3f const &a, Vector3f &result);
153
void drift_correction(float deltat);
154
void drift_correction_yaw(void);
155
float yaw_error_compass(class Compass &compass);
156
bool have_gps(void) const;
157
bool use_fast_gains(void) const;
158
void backup_attitude(void);
159
160
// internal reset function. Called externally, we never reset the
161
// DCM matrix from the eulers. Called internally we may.
162
void reset(bool recover_eulers);
163
164
// airspeed_ret: will always be filled-in by get_unconstrained_airspeed_EAS which fills in airspeed_ret in this order:
165
// airspeed as filled-in by an enabled airspeed sensor
166
// if no airspeed sensor: airspeed estimated using the GPS speed & wind_speed_estimation
167
// Or if none of the above, fills-in using the previous airspeed estimate
168
// Return false: if we are using the previous airspeed estimate
169
bool get_unconstrained_airspeed_EAS(uint8_t airspeed_index, float &airspeed_ret) const;
170
171
// primary representation of attitude of board used for all inertial calculations
172
Matrix3f _dcm_matrix;
173
174
// primary representation of attitude of flight vehicle body
175
Matrix3f _body_dcm_matrix;
176
177
// euler angles - used for recovering if the DCM
178
// matrix becomes ill-conditioned and watchdog storage
179
float roll;
180
float pitch;
181
float yaw;
182
183
Vector3f _omega_P; // accel Omega proportional correction
184
Vector3f _omega_yaw_P; // proportional yaw correction
185
Vector3f _omega_I; // Omega Integrator correction
186
Vector3f _omega_I_sum;
187
float _omega_I_sum_time;
188
Vector3f _omega; // Corrected Gyro_Vector data
189
190
bool have_initial_yaw; // true if the yaw value has been initialised with a reference
191
192
// variables to cope with delaying the GA sum to match GPS lag
193
Vector3f ra_delayed(uint8_t instance, const Vector3f &ra);
194
Vector3f _ra_delay_buffer[INS_MAX_INSTANCES];
195
196
// P term gain based on spin rate
197
float _P_gain(float spin_rate);
198
199
// P term yaw gain based on rate of change of horiz velocity
200
float _yaw_gain(void) const;
201
202
/* returns true if attitude should be corrected from GPS-derived
203
* velocity-deltas. We turn this off for Copter and other similar
204
* vehicles while the vehicle is disarmed to avoid the HUD bobbing
205
* around while the vehicle is disarmed.
206
*/
207
bool should_correct_centrifugal() const;
208
209
// state to support status reporting
210
float _renorm_val_sum;
211
uint16_t _renorm_val_count;
212
float _error_rp{1.0f};
213
float _error_yaw{1.0f};
214
215
// time in microseconds of last compass update
216
uint32_t _compass_last_update;
217
218
// time in millis when we last got a GPS heading
219
uint32_t _gps_last_update;
220
221
// state of accel drift correction
222
Vector3f _ra_sum[INS_MAX_INSTANCES];
223
Vector3f _last_velocity;
224
float _ra_deltat;
225
uint32_t _ra_sum_start;
226
227
// which accelerometer instance is active
228
uint8_t _active_accel_instance;
229
230
// the earths magnetic field
231
float _last_declination;
232
Vector2f _mag_earth{1, 0};
233
234
// whether we have GPS lock
235
bool _have_gps_lock;
236
237
// the lat/lng where we last had GPS lock
238
int32_t _last_lat;
239
int32_t _last_lng;
240
uint32_t _last_pos_ms;
241
242
// position offset from last GPS lock
243
float _position_offset_north;
244
float _position_offset_east;
245
246
// whether we have a position estimate
247
bool _have_position;
248
249
// support for wind estimation
250
Vector3f _last_fuse;
251
Vector3f _last_vel;
252
uint32_t _last_wind_time;
253
float _last_airspeed_TAS;
254
uint32_t _last_consistent_heading;
255
256
// estimated wind in m/s
257
Vector3f _wind;
258
259
// last time AHRS failed in milliseconds
260
uint32_t _last_failure_ms;
261
262
// time when DCM was last reset
263
uint32_t _last_startup_ms;
264
265
// last origin we returned, for DCM fallback from EKF
266
Location last_origin;
267
268
// Declare filter states for HPF and LPF used by complementary
269
// filter in AP_AHRS::groundspeed_vector
270
Vector2f _lp; // ground vector low-pass filter
271
Vector2f _hp; // ground vector high-pass filter
272
Vector2f _lastGndVelADS; // previous HPF input
273
274
// pre-calculated trig cache:
275
float _sin_yaw;
276
float _cos_yaw;
277
278
uint32_t last_log_ms;
279
};
280
281
#endif // AP_AHRS_DCM_ENABLED
282
283