AP_AHRS.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. #pragma once
  2. /*
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /*
  15. * AHRS (Attitude Heading Reference System) interface for ArduPilot
  16. *
  17. */
  18. #include <AP_Math/AP_Math.h>
  19. #include <inttypes.h>
  20. #include <AP_Compass/AP_Compass.h>
  21. #include <AP_Airspeed/AP_Airspeed.h>
  22. #include <AP_Beacon/AP_Beacon.h>
  23. #include <AP_InertialSensor/AP_InertialSensor.h>
  24. #include <AP_Param/AP_Param.h>
  25. #include <AP_Common/Location.h>
  26. class AP_NMEA_Output;
  27. class OpticalFlow;
  28. #define AP_AHRS_TRIM_LIMIT 10.0f // maximum trim angle in degrees
  29. #define AP_AHRS_RP_P_MIN 0.05f // minimum value for AHRS_RP_P parameter
  30. #define AP_AHRS_YAW_P_MIN 0.05f // minimum value for AHRS_YAW_P parameter
  31. enum AHRS_VehicleClass : uint8_t {
  32. AHRS_VEHICLE_UNKNOWN,
  33. AHRS_VEHICLE_GROUND,
  34. AHRS_VEHICLE_COPTER,
  35. AHRS_VEHICLE_FIXED_WING,
  36. AHRS_VEHICLE_SUBMARINE,
  37. };
  38. // forward declare view class
  39. class AP_AHRS_View;
  40. class AP_AHRS
  41. {
  42. public:
  43. friend class AP_AHRS_View;
  44. // Constructor
  45. AP_AHRS() :
  46. _vehicle_class(AHRS_VEHICLE_UNKNOWN),
  47. _cos_roll(1.0f),
  48. _cos_pitch(1.0f),
  49. _cos_yaw(1.0f)
  50. {
  51. _singleton = this;
  52. // load default values from var_info table
  53. AP_Param::setup_object_defaults(this, var_info);
  54. // base the ki values by the sensors maximum drift
  55. // rate.
  56. _gyro_drift_limit = AP::ins().get_gyro_drift_rate();
  57. // enable centrifugal correction by default
  58. _flags.correct_centrifugal = true;
  59. _last_trim = _trim.get();
  60. _rotation_autopilot_body_to_vehicle_body.from_euler(_last_trim.x, _last_trim.y, 0.0f);
  61. _rotation_vehicle_body_to_autopilot_body = _rotation_autopilot_body_to_vehicle_body.transposed();
  62. }
  63. // empty virtual destructor
  64. virtual ~AP_AHRS() {}
  65. // get singleton instance
  66. static AP_AHRS *get_singleton() {
  67. return _singleton;
  68. }
  69. // init sets up INS board orientation
  70. virtual void init();
  71. // Accessors
  72. void set_fly_forward(bool b) {
  73. _flags.fly_forward = b;
  74. }
  75. bool get_fly_forward(void) const {
  76. return _flags.fly_forward;
  77. }
  78. /*
  79. set the "likely flying" flag. This is not guaranteed to be
  80. accurate, but is the vehicle codes best guess as to the whether
  81. the vehicle is currently flying
  82. */
  83. void set_likely_flying(bool b) {
  84. if (b && !_flags.likely_flying) {
  85. _last_flying_ms = AP_HAL::millis();
  86. }
  87. _flags.likely_flying = b;
  88. }
  89. /*
  90. get the likely flying status. Returns true if the vehicle code
  91. thinks we are flying at the moment. Not guaranteed to be
  92. accurate
  93. */
  94. bool get_likely_flying(void) const {
  95. return _flags.likely_flying;
  96. }
  97. /*
  98. return time in milliseconds since likely_flying was set
  99. true. Returns zero if likely_flying is currently false
  100. */
  101. uint32_t get_time_flying_ms(void) const {
  102. if (!_flags.likely_flying) {
  103. return 0;
  104. }
  105. return AP_HAL::millis() - _last_flying_ms;
  106. }
  107. AHRS_VehicleClass get_vehicle_class(void) const {
  108. return _vehicle_class;
  109. }
  110. void set_vehicle_class(AHRS_VehicleClass vclass) {
  111. _vehicle_class = vclass;
  112. }
  113. void set_wind_estimation(bool b) {
  114. _flags.wind_estimation = b;
  115. }
  116. void set_compass(Compass *compass) {
  117. _compass = compass;
  118. update_orientation();
  119. }
  120. const Compass* get_compass() const {
  121. return _compass;
  122. }
  123. void set_optflow(const OpticalFlow *optflow) {
  124. _optflow = optflow;
  125. }
  126. const OpticalFlow* get_optflow() const {
  127. return _optflow;
  128. }
  129. // allow for runtime change of orientation
  130. // this makes initial config easier
  131. void update_orientation();
  132. void set_airspeed(AP_Airspeed *airspeed) {
  133. _airspeed = airspeed;
  134. }
  135. const AP_Airspeed *get_airspeed(void) const {
  136. return _airspeed;
  137. }
  138. // get the index of the current primary accelerometer sensor
  139. virtual uint8_t get_primary_accel_index(void) const {
  140. return AP::ins().get_primary_accel();
  141. }
  142. // get the index of the current primary gyro sensor
  143. virtual uint8_t get_primary_gyro_index(void) const {
  144. return AP::ins().get_primary_gyro();
  145. }
  146. // accelerometer values in the earth frame in m/s/s
  147. virtual const Vector3f &get_accel_ef(uint8_t i) const {
  148. return _accel_ef[i];
  149. }
  150. virtual const Vector3f &get_accel_ef(void) const {
  151. return get_accel_ef(AP::ins().get_primary_accel());
  152. }
  153. // blended accelerometer values in the earth frame in m/s/s
  154. virtual const Vector3f &get_accel_ef_blended(void) const {
  155. return _accel_ef_blended;
  156. }
  157. // get yaw rate in earth frame in radians/sec
  158. float get_yaw_rate_earth(void) const {
  159. return get_gyro() * get_rotation_body_to_ned().c;
  160. }
  161. // Methods
  162. virtual void update(bool skip_ins_update=false) = 0;
  163. // report any reason for why the backend is refusing to initialise
  164. virtual const char *prearm_failure_reason(void) const {
  165. return nullptr;
  166. }
  167. // check all cores providing consistent attitudes for prearm checks
  168. virtual bool attitudes_consistent(char *failure_msg, const uint8_t failure_msg_len) const { return true; }
  169. // is the EKF backend doing its own sensor logging?
  170. virtual bool have_ekf_logging(void) const {
  171. return false;
  172. }
  173. // see if EKF lane switching is possible to avoid EKF failsafe
  174. virtual void check_lane_switch(void) {}
  175. // Euler angles (radians)
  176. float roll;
  177. float pitch;
  178. float yaw;
  179. float get_roll() const { return roll; }
  180. float get_pitch() const { return pitch; }
  181. float get_yaw() const { return yaw; }
  182. // integer Euler angles (Degrees * 100)
  183. int32_t roll_sensor;
  184. int32_t pitch_sensor;
  185. int32_t yaw_sensor;
  186. // return a smoothed and corrected gyro vector in radians/second
  187. virtual const Vector3f &get_gyro(void) const = 0;
  188. // return a smoothed and corrected gyro vector in radians/second using the latest ins data (which may not have been consumed by the EKF yet)
  189. Vector3f get_gyro_latest(void) const;
  190. // return the current estimate of the gyro drift
  191. virtual const Vector3f &get_gyro_drift(void) const = 0;
  192. // reset the current gyro drift estimate
  193. // should be called if gyro offsets are recalculated
  194. virtual void reset_gyro_drift(void) = 0;
  195. // reset the current attitude, used on new IMU calibration
  196. virtual void reset(bool recover_eulers=false) = 0;
  197. // reset the current attitude, used on new IMU calibration
  198. virtual void reset_attitude(const float &roll, const float &pitch, const float &yaw) = 0;
  199. // return the average size of the roll/pitch error estimate
  200. // since last call
  201. virtual float get_error_rp(void) const = 0;
  202. // return the average size of the yaw error estimate
  203. // since last call
  204. virtual float get_error_yaw(void) const = 0;
  205. // return a DCM rotation matrix representing our current attitude
  206. virtual const Matrix3f &get_rotation_body_to_ned(void) const = 0;
  207. // return a Quaternion representing our current attitude
  208. void get_quat_body_to_ned(Quaternion &quat) const {
  209. quat.from_rotation_matrix(get_rotation_body_to_ned());
  210. }
  211. const Matrix3f& get_rotation_autopilot_body_to_vehicle_body(void) const { return _rotation_autopilot_body_to_vehicle_body; }
  212. const Matrix3f& get_rotation_vehicle_body_to_autopilot_body(void) const { return _rotation_vehicle_body_to_autopilot_body; }
  213. // get rotation matrix specifically from DCM backend (used for compass calibrator)
  214. virtual const Matrix3f &get_DCM_rotation_body_to_ned(void) const = 0;
  215. // get our current position estimate. Return true if a position is available,
  216. // otherwise false. This call fills in lat, lng and alt
  217. virtual bool get_position(struct Location &loc) const = 0;
  218. // get latest altitude estimate above ground level in meters and validity flag
  219. virtual bool get_hagl(float &height) const { return false; }
  220. // return a wind estimation vector, in m/s
  221. virtual Vector3f wind_estimate(void) const = 0;
  222. // return an airspeed estimate if available. return true
  223. // if we have an estimate
  224. virtual bool airspeed_estimate(float *airspeed_ret) const WARN_IF_UNUSED;
  225. // return a true airspeed estimate (navigation airspeed) if
  226. // available. return true if we have an estimate
  227. bool airspeed_estimate_true(float *airspeed_ret) const WARN_IF_UNUSED {
  228. if (!airspeed_estimate(airspeed_ret)) {
  229. return false;
  230. }
  231. *airspeed_ret *= get_EAS2TAS();
  232. return true;
  233. }
  234. // get apparent to true airspeed ratio
  235. float get_EAS2TAS(void) const;
  236. // return true if airspeed comes from an airspeed sensor, as
  237. // opposed to an IMU estimate
  238. bool airspeed_sensor_enabled(void) const {
  239. return _airspeed != nullptr && _airspeed->use() && _airspeed->healthy();
  240. }
  241. // return the parameter AHRS_WIND_MAX in metres per second
  242. uint8_t get_max_wind() const {
  243. return _wind_max;
  244. }
  245. // return a ground vector estimate in meters/second, in North/East order
  246. virtual Vector2f groundspeed_vector(void);
  247. // return a ground velocity in meters/second, North/East/Down
  248. // order. This will only be accurate if have_inertial_nav() is
  249. // true
  250. virtual bool get_velocity_NED(Vector3f &vec) const WARN_IF_UNUSED {
  251. return false;
  252. }
  253. // returns the expected NED magnetic field
  254. virtual bool get_expected_mag_field_NED(Vector3f &ret) const WARN_IF_UNUSED {
  255. return false;
  256. }
  257. // returns the estimated magnetic field offsets in body frame
  258. virtual bool get_mag_field_correction(Vector3f &ret) const WARN_IF_UNUSED {
  259. return false;
  260. }
  261. // return a position relative to home in meters, North/East/Down
  262. // order. This will only be accurate if have_inertial_nav() is
  263. // true
  264. virtual bool get_relative_position_NED_home(Vector3f &vec) const WARN_IF_UNUSED {
  265. return false;
  266. }
  267. // return a position relative to origin in meters, North/East/Down
  268. // order. This will only be accurate if have_inertial_nav() is
  269. // true
  270. virtual bool get_relative_position_NED_origin(Vector3f &vec) const WARN_IF_UNUSED {
  271. return false;
  272. }
  273. // return a position relative to home in meters, North/East
  274. // order. Return true if estimate is valid
  275. virtual bool get_relative_position_NE_home(Vector2f &vecNE) const WARN_IF_UNUSED {
  276. return false;
  277. }
  278. // return a position relative to origin in meters, North/East
  279. // order. Return true if estimate is valid
  280. virtual bool get_relative_position_NE_origin(Vector2f &vecNE) const WARN_IF_UNUSED {
  281. return false;
  282. }
  283. // return a Down position relative to home in meters
  284. // if EKF is unavailable will return the baro altitude
  285. virtual void get_relative_position_D_home(float &posD) const = 0;
  286. // return a Down position relative to origin in meters
  287. // Return true if estimate is valid
  288. virtual bool get_relative_position_D_origin(float &posD) const WARN_IF_UNUSED {
  289. return false;
  290. }
  291. // return ground speed estimate in meters/second. Used by ground vehicles.
  292. float groundspeed(void) {
  293. return groundspeed_vector().length();
  294. }
  295. // return true if we will use compass for yaw
  296. virtual bool use_compass(void) {
  297. return _compass && _compass->use_for_yaw();
  298. }
  299. // return true if yaw has been initialised
  300. bool yaw_initialised(void) const {
  301. return _flags.have_initial_yaw;
  302. }
  303. // set the correct centrifugal flag
  304. // allows arducopter to disable corrections when disarmed
  305. void set_correct_centrifugal(bool setting) {
  306. _flags.correct_centrifugal = setting;
  307. }
  308. // get the correct centrifugal flag
  309. bool get_correct_centrifugal(void) const {
  310. return _flags.correct_centrifugal;
  311. }
  312. // get trim
  313. const Vector3f &get_trim() const {
  314. return _trim.get();
  315. }
  316. // set trim
  317. void set_trim(const Vector3f &new_trim);
  318. // add_trim - adjust the roll and pitch trim up to a total of 10 degrees
  319. void add_trim(float roll_in_radians, float pitch_in_radians, bool save_to_eeprom = true);
  320. // helper trig value accessors
  321. float cos_roll() const {
  322. return _cos_roll;
  323. }
  324. float cos_pitch() const {
  325. return _cos_pitch;
  326. }
  327. float cos_yaw() const {
  328. return _cos_yaw;
  329. }
  330. float sin_roll() const {
  331. return _sin_roll;
  332. }
  333. float sin_pitch() const {
  334. return _sin_pitch;
  335. }
  336. float sin_yaw() const {
  337. return _sin_yaw;
  338. }
  339. // for holding parameters
  340. static const struct AP_Param::GroupInfo var_info[];
  341. // return secondary attitude solution if available, as eulers in radians
  342. virtual bool get_secondary_attitude(Vector3f &eulers) const WARN_IF_UNUSED {
  343. return false;
  344. }
  345. // return secondary attitude solution if available, as quaternion
  346. virtual bool get_secondary_quaternion(Quaternion &quat) const WARN_IF_UNUSED {
  347. return false;
  348. }
  349. // return secondary position solution if available
  350. virtual bool get_secondary_position(struct Location &loc) const WARN_IF_UNUSED {
  351. return false;
  352. }
  353. // get the home location. This is const to prevent any changes to
  354. // home without telling AHRS about the change
  355. const struct Location &get_home(void) const {
  356. return _home;
  357. }
  358. // functions to handle locking of home. Some vehicles use this to
  359. // allow GCS to lock in a home location.
  360. void lock_home() {
  361. _home_locked = true;
  362. }
  363. bool home_is_locked() const {
  364. return _home_locked;
  365. }
  366. // returns true if home is set
  367. bool home_is_set(void) const {
  368. return _home_is_set;
  369. }
  370. // set the home location in 10e7 degrees. This should be called
  371. // when the vehicle is at this position. It is assumed that the
  372. // current barometer and GPS altitudes correspond to this altitude
  373. virtual bool set_home(const Location &loc) WARN_IF_UNUSED = 0;
  374. // set the EKF's origin location in 10e7 degrees. This should only
  375. // be called when the EKF has no absolute position reference (i.e. GPS)
  376. // from which to decide the origin on its own
  377. virtual bool set_origin(const Location &loc) WARN_IF_UNUSED { return false; }
  378. // returns the inertial navigation origin in lat/lon/alt
  379. virtual bool get_origin(Location &ret) const WARN_IF_UNUSED { return false; }
  380. void Log_Write_Home_And_Origin();
  381. // return true if the AHRS object supports inertial navigation,
  382. // with very accurate position and velocity
  383. virtual bool have_inertial_nav(void) const {
  384. return false;
  385. }
  386. // return the active accelerometer instance
  387. uint8_t get_active_accel_instance(void) const {
  388. return _active_accel_instance;
  389. }
  390. // is the AHRS subsystem healthy?
  391. virtual bool healthy(void) const = 0;
  392. virtual bool prearm_healthy(void) const { return healthy(); }
  393. // true if the AHRS has completed initialisation
  394. virtual bool initialised(void) const {
  395. return true;
  396. };
  397. // return the amount of yaw angle change due to the last yaw angle reset in radians
  398. // returns the time of the last yaw angle reset or 0 if no reset has ever occurred
  399. virtual uint32_t getLastYawResetAngle(float &yawAng) const {
  400. return 0;
  401. };
  402. // return the amount of NE position change in metres due to the last reset
  403. // returns the time of the last reset or 0 if no reset has ever occurred
  404. virtual uint32_t getLastPosNorthEastReset(Vector2f &pos) const WARN_IF_UNUSED {
  405. return 0;
  406. };
  407. // return the amount of NE velocity change in metres/sec due to the last reset
  408. // returns the time of the last reset or 0 if no reset has ever occurred
  409. virtual uint32_t getLastVelNorthEastReset(Vector2f &vel) const WARN_IF_UNUSED {
  410. return 0;
  411. };
  412. // return the amount of vertical position change due to the last reset in meters
  413. // returns the time of the last reset or 0 if no reset has ever occurred
  414. virtual uint32_t getLastPosDownReset(float &posDelta) const WARN_IF_UNUSED {
  415. return 0;
  416. };
  417. // Resets the baro so that it reads zero at the current height
  418. // Resets the EKF height to zero
  419. // Adjusts the EKf origin height so that the EKF height + origin height is the same as before
  420. // Returns true if the height datum reset has been performed
  421. // If using a range finder for height no reset is performed and it returns false
  422. virtual bool resetHeightDatum(void) WARN_IF_UNUSED {
  423. return false;
  424. }
  425. // get_variances - provides the innovations normalised using the innovation variance where a value of 0
  426. // indicates perfect consistency between the measurement and the EKF solution and a value of of 1 is the maximum
  427. // inconsistency that will be accepted by the filter
  428. // boolean false is returned if variances are not available
  429. virtual bool get_variances(float &velVar, float &posVar, float &hgtVar, Vector3f &magVar, float &tasVar, Vector2f &offset) const {
  430. return false;
  431. }
  432. // get the selected ekf type, for allocation decisions
  433. int8_t get_ekf_type(void) const {
  434. return _ekf_type;
  435. }
  436. // Retrieves the corrected NED delta velocity in use by the inertial navigation
  437. virtual void getCorrectedDeltaVelocityNED(Vector3f& ret, float& dt) const {
  438. ret.zero();
  439. const AP_InertialSensor &_ins = AP::ins();
  440. _ins.get_delta_velocity(ret);
  441. dt = _ins.get_delta_velocity_dt();
  442. }
  443. // create a view
  444. AP_AHRS_View *create_view(enum Rotation rotation, float pitch_trim_deg=0);
  445. // return calculated AOA
  446. float getAOA(void);
  447. // return calculated SSA
  448. float getSSA(void);
  449. // rotate a 2D vector from earth frame to body frame
  450. // in result, x is forward, y is right
  451. Vector2f rotate_earth_to_body2D(const Vector2f &ef_vector) const;
  452. // rotate a 2D vector from earth frame to body frame
  453. // in input, x is forward, y is right
  454. Vector2f rotate_body_to_earth2D(const Vector2f &bf) const;
  455. virtual void update_AOA_SSA(void);
  456. // get_hgt_ctrl_limit - get maximum height to be observed by the
  457. // control loops in meters and a validity flag. It will return
  458. // false when no limiting is required
  459. virtual bool get_hgt_ctrl_limit(float &limit) const WARN_IF_UNUSED { return false; };
  460. // Write position and quaternion data from an external navigation system
  461. virtual void writeExtNavData(const Vector3f &sensOffset, const Vector3f &pos, const Quaternion &quat, float posErr, float angErr, uint32_t timeStamp_ms, uint32_t resetTime_ms) { }
  462. // allow threads to lock against AHRS update
  463. HAL_Semaphore &get_semaphore(void) {
  464. return _rsem;
  465. }
  466. protected:
  467. void update_nmea_out();
  468. // multi-thread access support
  469. HAL_Semaphore_Recursive _rsem;
  470. AHRS_VehicleClass _vehicle_class;
  471. // settable parameters
  472. // these are public for ArduCopter
  473. AP_Float _kp_yaw;
  474. AP_Float _kp;
  475. AP_Float gps_gain;
  476. AP_Float beta;
  477. AP_Int8 _gps_use;
  478. AP_Int8 _wind_max;
  479. AP_Int8 _board_orientation;
  480. AP_Int8 _gps_minsats;
  481. AP_Int8 _gps_delay;
  482. AP_Int8 _ekf_type;
  483. AP_Float _custom_roll;
  484. AP_Float _custom_pitch;
  485. AP_Float _custom_yaw;
  486. Matrix3f _custom_rotation;
  487. // flags structure
  488. struct ahrs_flags {
  489. uint8_t have_initial_yaw : 1; // whether the yaw value has been intialised with a reference
  490. uint8_t fly_forward : 1; // 1 if we can assume the aircraft will be flying forward on its X axis
  491. uint8_t correct_centrifugal : 1; // 1 if we should correct for centrifugal forces (allows arducopter to turn this off when motors are disarmed)
  492. uint8_t wind_estimation : 1; // 1 if we should do wind estimation
  493. uint8_t likely_flying : 1; // 1 if vehicle is probably flying
  494. } _flags;
  495. // time when likely_flying last went true
  496. uint32_t _last_flying_ms;
  497. // calculate sin/cos of roll/pitch/yaw from rotation
  498. void calc_trig(const Matrix3f &rot,
  499. float &cr, float &cp, float &cy,
  500. float &sr, float &sp, float &sy) const;
  501. // update_trig - recalculates _cos_roll, _cos_pitch, etc based on latest attitude
  502. // should be called after _dcm_matrix is updated
  503. void update_trig(void);
  504. // update roll_sensor, pitch_sensor and yaw_sensor
  505. void update_cd_values(void);
  506. // pointer to compass object, if available
  507. Compass * _compass;
  508. // pointer to OpticalFlow object, if available
  509. const OpticalFlow *_optflow;
  510. // pointer to airspeed object, if available
  511. AP_Airspeed * _airspeed;
  512. // time in microseconds of last compass update
  513. uint32_t _compass_last_update;
  514. // a vector to capture the difference between the controller and body frames
  515. AP_Vector3f _trim;
  516. // cached trim rotations
  517. Vector3f _last_trim;
  518. Matrix3f _rotation_autopilot_body_to_vehicle_body;
  519. Matrix3f _rotation_vehicle_body_to_autopilot_body;
  520. // the limit of the gyro drift claimed by the sensors, in
  521. // radians/s/s
  522. float _gyro_drift_limit;
  523. // accelerometer values in the earth frame in m/s/s
  524. Vector3f _accel_ef[INS_MAX_INSTANCES];
  525. Vector3f _accel_ef_blended;
  526. // Declare filter states for HPF and LPF used by complementary
  527. // filter in AP_AHRS::groundspeed_vector
  528. Vector2f _lp; // ground vector low-pass filter
  529. Vector2f _hp; // ground vector high-pass filter
  530. Vector2f _lastGndVelADS; // previous HPF input
  531. // reference position for NED positions
  532. struct Location _home;
  533. bool _home_is_set :1;
  534. bool _home_locked :1;
  535. // helper trig variables
  536. float _cos_roll, _cos_pitch, _cos_yaw;
  537. float _sin_roll, _sin_pitch, _sin_yaw;
  538. // which accelerometer instance is active
  539. uint8_t _active_accel_instance;
  540. // optional view class
  541. AP_AHRS_View *_view;
  542. // AOA and SSA
  543. float _AOA, _SSA;
  544. uint32_t _last_AOA_update_ms;
  545. private:
  546. static AP_AHRS *_singleton;
  547. AP_NMEA_Output* _nmea_out;
  548. };
  549. #include "AP_AHRS_DCM.h"
  550. #include "AP_AHRS_NavEKF.h"
  551. #if AP_AHRS_NAVEKF_AVAILABLE
  552. #define AP_AHRS_TYPE AP_AHRS_NavEKF
  553. #else
  554. #define AP_AHRS_TYPE AP_AHRS
  555. #endif
  556. namespace AP {
  557. AP_AHRS &ahrs();
  558. // use ahrs_navekf() only where the AHRS interface doesn't expose the
  559. // functionality you require:
  560. #if AP_AHRS_NAVEKF_AVAILABLE
  561. AP_AHRS_NavEKF &ahrs_navekf();
  562. #endif
  563. };