Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ardupilot
GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_AHRS/AP_AHRS_Backend.h
9742 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
* AHRS (Attitude Heading Reference System) interface for ArduPilot
20
*
21
*/
22
23
#include <AP_Math/AP_Math.h>
24
#include <inttypes.h>
25
#include <AP_Airspeed/AP_Airspeed.h>
26
#include <AP_InertialSensor/AP_InertialSensor.h>
27
#include <AP_Common/Location.h>
28
#include <AP_NavEKF/AP_NavEKF_Source.h>
29
30
#define AP_AHRS_TRIM_LIMIT 10.0f // maximum trim angle in degrees
31
#define AP_AHRS_RP_P_MIN 0.05f // minimum value for AHRS_RP_P parameter
32
#define AP_AHRS_YAW_P_MIN 0.05f // minimum value for AHRS_YAW_P parameter
33
34
enum class GPSUse : uint8_t {
35
Disable = 0,
36
Enable = 1,
37
EnableWithHeight = 2,
38
};
39
40
class AP_AHRS_Backend
41
{
42
public:
43
44
// Constructor
45
AP_AHRS_Backend() {}
46
47
// empty virtual destructor
48
virtual ~AP_AHRS_Backend() {}
49
50
CLASS_NO_COPY(AP_AHRS_Backend);
51
52
// structure to retrieve results from backends:
53
struct Estimates {
54
// if attitude_valid is true then all of the
55
// eulers/quaternion/matrix must be valid:
56
bool attitude_valid;
57
float roll_rad;
58
float pitch_rad;
59
float yaw_rad;
60
Matrix3f dcm_matrix;
61
Quaternion quaternion;
62
63
Vector3f gyro_estimate;
64
Vector3f gyro_drift;
65
Vector3f accel_ef;
66
Vector3f accel_bias;
67
68
// a ground velocity in meters/second, North/East/Down
69
Vector3f velocity_NED;
70
bool velocity_NED_valid;
71
// return a ground velocity in meters/second, North/East/Down
72
bool get_velocity_NED(Vector3f &vel) const WARN_IF_UNUSED {
73
if (!velocity_NED_valid) {
74
return false;
75
}
76
vel = velocity_NED;
77
return true;
78
};
79
80
// a derivative of the vertical position in m/s which is
81
// kinematically consistent with the vertical position is
82
// required by some control loops.
83
// This is different to the vertical velocity from the EKF
84
// which is not always consistent with the vertical position
85
// due to the various errors that are being corrected for.
86
float vert_pos_rate_D;
87
bool vert_pos_rate_D_valid;
88
// Get a derivative of the vertical position in m/s which is
89
// kinematically consistent with the vertical position is
90
// required by some control loops.
91
// This is different to the vertical velocity from the EKF
92
// which is not always consistent with the vertical position
93
// due to the various errors that are being corrected for.
94
bool get_vert_pos_rate_D(float &velocity) const {
95
if (!vert_pos_rate_D_valid) {
96
return false;
97
}
98
velocity = vert_pos_rate_D;
99
return true;
100
}
101
102
Location location;
103
bool location_valid;
104
105
bool get_location(Location &loc) const {
106
loc = location;
107
return location_valid;
108
};
109
};
110
111
// init sets up INS board orientation
112
virtual void init();
113
114
// get the index of the current primary gyro sensor
115
virtual uint8_t get_primary_gyro_index(void) const {
116
#if AP_INERTIALSENSOR_ENABLED
117
return AP::ins().get_first_usable_gyro();
118
#else
119
return 0;
120
#endif
121
}
122
123
// Methods
124
virtual void update() = 0;
125
126
virtual void get_results(Estimates &results) = 0;
127
128
// returns false if we fail arming checks, in which case the buffer will be populated with a failure message
129
// requires_position should be true if horizontal position configuration should be checked
130
virtual bool pre_arm_check(bool requires_position, char *failure_msg, uint8_t failure_msg_len) const = 0;
131
132
// see if EKF lane switching is possible to avoid EKF failsafe
133
virtual void check_lane_switch(void) {}
134
135
// request EKF yaw reset to try and avoid the need for an EKF lane switch or failsafe
136
virtual void request_yaw_reset(void) {}
137
138
// set position, velocity and yaw sources to either 0=primary, 1=secondary, 2=tertiary
139
virtual void set_posvelyaw_source_set(AP_NavEKF_Source::SourceSetSelection source_set_idx) {}
140
141
// reset the current gyro drift estimate
142
// should be called if gyro offsets are recalculated
143
virtual void reset_gyro_drift(void) = 0;
144
145
// reset the current attitude, used on new IMU calibration
146
virtual void reset() = 0;
147
148
// get latest altitude estimate above ground level in meters and validity flag
149
virtual bool get_hagl(float &height) const WARN_IF_UNUSED { return false; }
150
151
// return a wind estimation vector, in m/s
152
virtual bool wind_estimate(Vector3f &wind) const = 0;
153
154
// return an airspeed estimate if available. return true
155
// if we have an estimate
156
virtual bool airspeed_EAS(float &airspeed_ret) const WARN_IF_UNUSED { return false; }
157
virtual bool airspeed_EAS(uint8_t airspeed_index, float &airspeed_ret) const { return false; }
158
159
// return a true airspeed estimate (navigation airspeed) if
160
// available. return true if we have an estimate
161
bool airspeed_TAS(float &airspeed_ret) const WARN_IF_UNUSED {
162
if (!airspeed_EAS(airspeed_ret)) {
163
return false;
164
}
165
airspeed_ret *= get_EAS2TAS();
166
return true;
167
}
168
169
// get apparent to true airspeed ratio
170
static float get_EAS2TAS(void);
171
static float get_TAS2EAS(void) { return 1.0/get_EAS2TAS(); }
172
173
// return true if airspeed comes from an airspeed sensor, as
174
// opposed to an IMU estimate
175
static bool airspeed_sensor_enabled(void) {
176
#if AP_AIRSPEED_ENABLED
177
const AP_Airspeed *_airspeed = AP::airspeed();
178
return _airspeed != nullptr && _airspeed->use() && _airspeed->healthy();
179
#else
180
return false;
181
#endif
182
}
183
184
// return true if airspeed comes from a specific airspeed sensor, as
185
// opposed to an IMU estimate
186
static bool airspeed_sensor_enabled(uint8_t airspeed_index) {
187
#if AP_AIRSPEED_ENABLED
188
const AP_Airspeed *_airspeed = AP::airspeed();
189
return _airspeed != nullptr && _airspeed->use(airspeed_index) && _airspeed->healthy(airspeed_index);
190
#else
191
return false;
192
#endif
193
}
194
195
// return a ground vector estimate in meters/second, in North/East order
196
virtual Vector2f groundspeed_vector(void) = 0;
197
198
virtual bool set_origin(const Location &loc) {
199
return false;
200
}
201
virtual bool get_origin(Location &ret) const = 0;
202
203
// return a position relative to origin in meters, North/East/Down
204
// order. This will only be accurate if have_inertial_nav() is
205
// true
206
virtual bool get_relative_position_NED_origin(Vector3p &vec) const WARN_IF_UNUSED {
207
return false;
208
}
209
210
// return a position relative to origin in meters, North/East
211
// order. Return true if estimate is valid
212
virtual bool get_relative_position_NE_origin(Vector2p &vecNE) const WARN_IF_UNUSED {
213
return false;
214
}
215
216
// return a Down position relative to origin in meters
217
// Return true if estimate is valid
218
virtual bool get_relative_position_D_origin(postype_t &posD) const WARN_IF_UNUSED {
219
return false;
220
}
221
222
// return true if we will use compass for yaw
223
virtual bool use_compass(void) = 0;
224
225
// is the AHRS subsystem healthy?
226
virtual bool healthy(void) const = 0;
227
228
// true if the AHRS has completed initialisation
229
virtual bool initialised(void) const {
230
return true;
231
};
232
virtual bool started(void) const {
233
return initialised();
234
};
235
236
// return the amount of yaw angle change due to the last yaw angle reset in radians
237
// returns the time of the last yaw angle reset or 0 if no reset has ever occurred
238
virtual uint32_t getLastYawResetAngle(float &yawAng) {
239
return 0;
240
};
241
242
// return the amount of NE position change in metres due to the last reset
243
// returns the time of the last reset or 0 if no reset has ever occurred
244
virtual uint32_t getLastPosNorthEastReset(Vector2f &pos) WARN_IF_UNUSED {
245
return 0;
246
};
247
248
// return the amount of NE velocity change in metres/sec due to the last reset
249
// returns the time of the last reset or 0 if no reset has ever occurred
250
virtual uint32_t getLastVelNorthEastReset(Vector2f &vel) const WARN_IF_UNUSED {
251
return 0;
252
};
253
254
// return the amount of vertical position change due to the last reset in meters
255
// returns the time of the last reset or 0 if no reset has ever occurred
256
virtual uint32_t getLastPosDownReset(float &posDelta) WARN_IF_UNUSED {
257
return 0;
258
};
259
260
// Resets the baro so that it reads zero at the current height
261
// Resets the EKF height to zero
262
// Adjusts the EKf origin height so that the EKF height + origin height is the same as before
263
virtual void resetHeightDatum(void) { }
264
265
// return the innovations for the specified instance
266
// An out of range instance (eg -1) returns data for the primary instance
267
virtual bool get_innovations(Vector3f &velInnov, Vector3f &posInnov, Vector3f &magInnov, float &tasInnov, float &yawInnov) const {
268
return false;
269
}
270
271
virtual bool get_filter_status(union nav_filter_status &status) const {
272
return false;
273
}
274
275
// get_variances - provides the innovations normalised using the innovation variance where a value of 0
276
// indicates perfect consistency between the measurement and the EKF solution and a value of 1 is the maximum
277
// inconsistency that will be accepted by the filter
278
// boolean false is returned if variances are not available
279
virtual bool get_variances(float &velVar, float &posVar, float &hgtVar, Vector3f &magVar, float &tasVar) const {
280
return false;
281
}
282
283
virtual void send_ekf_status_report(class GCS_MAVLINK &link) const = 0;
284
285
// Set to true if the terrain underneath is stable enough to be used as a height reference
286
// this is not related to terrain following
287
virtual void set_terrain_hgt_stable(bool stable) {}
288
289
virtual void get_control_limits(float &ekfGndSpdLimit, float &controlScaleXY) const = 0;
290
};
291
292