mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-06-05 06:54:49 +08:00
ahrs_int_cmpl_quat: yaw update via heading measurement
- added ahrs_update_heading which gets called from ahrs_update_gps with gps course - define AHRS_USE_GPS_HEADING in your airframe file to use it
This commit is contained in:
@@ -25,7 +25,7 @@
|
|||||||
<subsystem name="imu" type="aspirin_v1.5"/>
|
<subsystem name="imu" type="aspirin_v1.5"/>
|
||||||
<subsystem name="gps" type="ublox"/>
|
<subsystem name="gps" type="ublox"/>
|
||||||
<subsystem name="stabilization" type="euler"/>
|
<subsystem name="stabilization" type="euler"/>
|
||||||
<subsystem name="ahrs" type="int_cmpl_euler"/>
|
<subsystem name="ahrs" type="int_cmpl_quat"/>
|
||||||
</firmware>
|
</firmware>
|
||||||
|
|
||||||
<firmware name="lisa_m_test_progs">
|
<firmware name="lisa_m_test_progs">
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
// TODO
|
// TODO
|
||||||
//
|
//
|
||||||
// gravity heuristic
|
// gravity heuristic
|
||||||
// gps update for yaw on fixed wing ?
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "subsystems/ahrs/ahrs_int_cmpl.h"
|
#include "subsystems/ahrs/ahrs_int_cmpl.h"
|
||||||
@@ -321,6 +320,60 @@ void ahrs_update_gps(void) {
|
|||||||
ahrs_impl.ltp_vel_norm_valid = FALSE;
|
ahrs_impl.ltp_vel_norm_valid = FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if AHRS_USE_GPS_HEADING && USE_GPS
|
||||||
|
//got a 3d fix and ground speed is more than 0.5 m/s
|
||||||
|
if(gps.fix == GPS_FIX_3D && gps.gspeed>= 500) {
|
||||||
|
// gps.course is in rad * 1e7, we need it in rad * 2^INT32_ANGLE_FRAC
|
||||||
|
int32_t course = gps.course * ((1<<INT32_ANGLE_FRAC) / 1e7);
|
||||||
|
ahrs_update_course(course);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update yaw based on a heading measurement.
|
||||||
|
* e.g. from GPS course
|
||||||
|
* @param heading Heading in radians (CW/north) with #INT32_ANGLE_FRAC
|
||||||
|
*/
|
||||||
|
void ahrs_update_heading(int32_t heading) {
|
||||||
|
|
||||||
|
INT32_ANGLE_NORMALIZE(heading);
|
||||||
|
|
||||||
|
// row 0 of ltp_to_body_rmat = body x-axis in ltp frame
|
||||||
|
// we only consider x and y
|
||||||
|
struct Int32Vect2 expected_ltp =
|
||||||
|
{ RMAT_ELMT(ahrs.ltp_to_body_rmat, 0, 0),
|
||||||
|
RMAT_ELMT(ahrs.ltp_to_body_rmat, 0, 1) };
|
||||||
|
|
||||||
|
int32_t heading_x, heading_y;
|
||||||
|
PPRZ_ITRIG_COS(heading_x, heading); // measured course in x-direction
|
||||||
|
PPRZ_ITRIG_SIN(heading_y, heading); // measured course in y-direction
|
||||||
|
|
||||||
|
// expected_heading cross measured_heading ??
|
||||||
|
struct Int32Vect3 residual_ltp =
|
||||||
|
{ 0,
|
||||||
|
0,
|
||||||
|
(expected_ltp.x * heading_y - expected_ltp.y * heading_x)/(1<<INT32_ANGLE_FRAC)};
|
||||||
|
|
||||||
|
struct Int32Vect3 residual_imu;
|
||||||
|
INT32_RMAT_VMULT(residual_imu, ahrs.ltp_to_imu_rmat, residual_ltp);
|
||||||
|
|
||||||
|
// residual FRAC = TRIG_FRAC + TRIG_FRAC = 14 + 14 = 28
|
||||||
|
// rate_correction FRAC = RATE_FRAC = 12
|
||||||
|
// 2^12 / 2^28 * 4.0 = 1/2^14
|
||||||
|
// (1<<INT32_ANGLE_FRAC)/2^14 = 1/4
|
||||||
|
ahrs_impl.rate_correction.p += residual_imu.x/4;
|
||||||
|
ahrs_impl.rate_correction.q += residual_imu.y/4;
|
||||||
|
ahrs_impl.rate_correction.r += residual_imu.z/4;
|
||||||
|
|
||||||
|
// residual_ltp FRAC = 2 * TRIG_FRAC = 28
|
||||||
|
// high_rez_bias = RATE_FRAC+28 = 40
|
||||||
|
// 2^40 / 2^28 * 2.5e-4 = 1
|
||||||
|
ahrs_impl.high_rez_bias.p -= residual_imu.x*(1<<INT32_ANGLE_FRAC);
|
||||||
|
ahrs_impl.high_rez_bias.q -= residual_imu.y*(1<<INT32_ANGLE_FRAC);
|
||||||
|
ahrs_impl.high_rez_bias.r -= residual_imu.z*(1<<INT32_ANGLE_FRAC);
|
||||||
|
|
||||||
|
INT_RATES_RSHIFT(ahrs_impl.gyro_bias, ahrs_impl.high_rez_bias, 28);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute ltp to imu rotation in quaternion and rotation matrice representation
|
/* Compute ltp to imu rotation in quaternion and rotation matrice representation
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ struct AhrsIntCmpl {
|
|||||||
|
|
||||||
extern struct AhrsIntCmpl ahrs_impl;
|
extern struct AhrsIntCmpl ahrs_impl;
|
||||||
|
|
||||||
|
void ahrs_update_heading(int32_t heading);
|
||||||
|
|
||||||
#ifdef AHRS_UPDATE_FW_ESTIMATOR
|
#ifdef AHRS_UPDATE_FW_ESTIMATOR
|
||||||
// TODO copy ahrs to state instead of estimator
|
// TODO copy ahrs to state instead of estimator
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ struct GpsState {
|
|||||||
struct NedCoor_i ned_vel; ///< speed NED in cm/s
|
struct NedCoor_i ned_vel; ///< speed NED in cm/s
|
||||||
int16_t gspeed; ///< norm of 2d ground speed in cm/s
|
int16_t gspeed; ///< norm of 2d ground speed in cm/s
|
||||||
int16_t speed_3d; ///< norm of 3d speed in cm/s
|
int16_t speed_3d; ///< norm of 3d speed in cm/s
|
||||||
int32_t course; ///< GPS heading in rad*1e7
|
int32_t course; ///< GPS heading in rad*1e7 (CW/north)
|
||||||
uint32_t pacc; ///< position accuracy
|
uint32_t pacc; ///< position accuracy
|
||||||
uint32_t sacc; ///< speed accuracy
|
uint32_t sacc; ///< speed accuracy
|
||||||
uint16_t pdop; ///< dilution of precision
|
uint16_t pdop; ///< dilution of precision
|
||||||
|
|||||||
Reference in New Issue
Block a user