CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_AHRS/AP_AHRS_DCM.h
Views: 1798
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 synthetic EAS estimate (one derived from sensors
92
// other than an actual airspeed sensor), if available. return
93
// true if we have a synthetic airspeed. ret will not be modified
94
// on failure.
95
bool synthetic_airspeed_EAS(float &ret) const WARN_IF_UNUSED {
96
ret = _last_airspeed_TAS;
97
return true;
98
}
99
100
// return a ground vector estimate in meters/second, in North/East order
101
Vector2f groundspeed_vector() override;
102
103
bool use_compass() override;
104
105
// return the quaternion defining the rotation from NED to XYZ (body) axes
106
bool get_quaternion(Quaternion &quat) const override WARN_IF_UNUSED;
107
108
void estimate_wind(void);
109
110
// is the AHRS subsystem healthy?
111
bool healthy() const override;
112
113
bool get_velocity_NED(Vector3f &vec) const override;
114
115
// Get a derivative of the vertical position in m/s which is kinematically consistent with the vertical position is required by some control loops.
116
// 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.
117
bool get_vert_pos_rate_D(float &velocity) const override;
118
119
// returns false if we fail arming checks, in which case the buffer will be populated with a failure message
120
// requires_position should be true if horizontal position configuration should be checked (not used)
121
bool pre_arm_check(bool requires_position, char *failure_msg, uint8_t failure_msg_len) const override;
122
123
// relative-origin functions for fallback in AP_InertialNav
124
bool get_origin(Location &ret) const override;
125
bool get_relative_position_NED_origin(Vector3f &vec) const override;
126
bool get_relative_position_NE_origin(Vector2f &posNE) const override;
127
bool get_relative_position_D_origin(float &posD) const override;
128
129
void send_ekf_status_report(class GCS_MAVLINK &link) const override;
130
131
// return true if DCM has a yaw source
132
bool yaw_source_available(void) const;
133
134
void get_control_limits(float &ekfGndSpdLimit, float &controlScaleXY) const override;
135
136
private:
137
138
// dead-reckoning support
139
bool get_location(Location &loc) const;
140
141
// settable parameters
142
AP_Float &_kp_yaw;
143
AP_Float &_kp;
144
AP_Float &gps_gain;
145
146
AP_Float &beta;
147
148
AP_Int8 &_gps_minsats;
149
150
AP_Enum<GPSUse> &_gps_use;
151
152
// these are experimentally derived from the simulator
153
// with large drift levels
154
static constexpr float _ki = 0.0087f;
155
static constexpr float _ki_yaw = 0.01f;
156
157
// accelerometer values in the earth frame in m/s/s
158
Vector3f _accel_ef;
159
160
// Methods
161
void matrix_update(void);
162
void normalize(void);
163
void check_matrix(void);
164
bool renorm(Vector3f const &a, Vector3f &result);
165
void drift_correction(float deltat);
166
void drift_correction_yaw(void);
167
float yaw_error_compass(class Compass &compass);
168
bool have_gps(void) const;
169
bool use_fast_gains(void) const;
170
void backup_attitude(void);
171
172
// internal reset function. Called externally, we never reset the
173
// DCM matrix from the eulers. Called internally we may.
174
void reset(bool recover_eulers);
175
176
// airspeed_ret: will always be filled-in by get_unconstrained_airspeed_EAS which fills in airspeed_ret in this order:
177
// airspeed as filled-in by an enabled airspeed sensor
178
// if no airspeed sensor: airspeed estimated using the GPS speed & wind_speed_estimation
179
// Or if none of the above, fills-in using the previous airspeed estimate
180
// Return false: if we are using the previous airspeed estimate
181
bool get_unconstrained_airspeed_EAS(uint8_t airspeed_index, float &airspeed_ret) const;
182
183
// primary representation of attitude of board used for all inertial calculations
184
Matrix3f _dcm_matrix;
185
186
// primary representation of attitude of flight vehicle body
187
Matrix3f _body_dcm_matrix;
188
189
// euler angles - used for recovering if the DCM
190
// matrix becomes ill-conditioned and watchdog storage
191
float roll;
192
float pitch;
193
float yaw;
194
195
Vector3f _omega_P; // accel Omega proportional correction
196
Vector3f _omega_yaw_P; // proportional yaw correction
197
Vector3f _omega_I; // Omega Integrator correction
198
Vector3f _omega_I_sum;
199
float _omega_I_sum_time;
200
Vector3f _omega; // Corrected Gyro_Vector data
201
202
bool have_initial_yaw; // true if the yaw value has been initialised with a reference
203
204
// variables to cope with delaying the GA sum to match GPS lag
205
Vector3f ra_delayed(uint8_t instance, const Vector3f &ra);
206
Vector3f _ra_delay_buffer[INS_MAX_INSTANCES];
207
208
// P term gain based on spin rate
209
float _P_gain(float spin_rate);
210
211
// P term yaw gain based on rate of change of horiz velocity
212
float _yaw_gain(void) const;
213
214
/* returns true if attitude should be corrected from GPS-derived
215
* velocity-deltas. We turn this off for Copter and other similar
216
* vehicles while the vehicle is disarmed to avoid the HUD bobbing
217
* around while the vehicle is disarmed.
218
*/
219
bool should_correct_centrifugal() const;
220
221
// state to support status reporting
222
float _renorm_val_sum;
223
uint16_t _renorm_val_count;
224
float _error_rp{1.0f};
225
float _error_yaw{1.0f};
226
227
// time in microseconds of last compass update
228
uint32_t _compass_last_update;
229
230
// time in millis when we last got a GPS heading
231
uint32_t _gps_last_update;
232
233
// state of accel drift correction
234
Vector3f _ra_sum[INS_MAX_INSTANCES];
235
Vector3f _last_velocity;
236
float _ra_deltat;
237
uint32_t _ra_sum_start;
238
239
// which accelerometer instance is active
240
uint8_t _active_accel_instance;
241
242
// the earths magnetic field
243
float _last_declination;
244
Vector2f _mag_earth{1, 0};
245
246
// whether we have GPS lock
247
bool _have_gps_lock;
248
249
// the lat/lng where we last had GPS lock
250
int32_t _last_lat;
251
int32_t _last_lng;
252
uint32_t _last_pos_ms;
253
254
// position offset from last GPS lock
255
float _position_offset_north;
256
float _position_offset_east;
257
258
// whether we have a position estimate
259
bool _have_position;
260
261
// support for wind estimation
262
Vector3f _last_fuse;
263
Vector3f _last_vel;
264
uint32_t _last_wind_time;
265
float _last_airspeed_TAS;
266
uint32_t _last_consistent_heading;
267
268
// estimated wind in m/s
269
Vector3f _wind;
270
271
// last time AHRS failed in milliseconds
272
uint32_t _last_failure_ms;
273
274
// time when DCM was last reset
275
uint32_t _last_startup_ms;
276
277
// last origin we returned, for DCM fallback from EKF
278
Location last_origin;
279
280
// Declare filter states for HPF and LPF used by complementary
281
// filter in AP_AHRS::groundspeed_vector
282
Vector2f _lp; // ground vector low-pass filter
283
Vector2f _hp; // ground vector high-pass filter
284
Vector2f _lastGndVelADS; // previous HPF input
285
286
// pre-calculated trig cache:
287
float _sin_yaw;
288
float _cos_yaw;
289
290
uint32_t last_log_ms;
291
};
292
293
#endif // AP_AHRS_DCM_ENABLED
294
295