[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[paparazzi-commits] [6350] adding a basic implementation
From: |
antoine drouin |
Subject: |
[paparazzi-commits] [6350] adding a basic implementation |
Date: |
Thu, 04 Nov 2010 16:04:25 +0000 |
Revision: 6350
http://svn.sv.gnu.org/viewvc/?view=rev&root=paparazzi&revision=6350
Author: poine
Date: 2010-11-04 16:04:25 +0000 (Thu, 04 Nov 2010)
Log Message:
-----------
adding a basic implementation
Added Paths:
-----------
paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_cmpl_rmat.c
paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_cmpl_rmat.h
paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_utils.h
Added: paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_cmpl_rmat.c
===================================================================
--- paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_cmpl_rmat.c
(rev 0)
+++ paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_cmpl_rmat.c
2010-11-04 16:04:25 UTC (rev 6350)
@@ -0,0 +1,214 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 The Paparazzi Team
+ *
+ * This file is part of paparazzi.
+ *
+ * paparazzi is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * paparazzi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with paparazzi; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "subsystems/ahrs.h"
+#include "subsystems/ahrs/ahrs_float_cmpl_rmat.h"
+#include "subsystems/ahrs/ahrs_float_utils.h"
+#include "subsystems/ahrs/ahrs_aligner.h"
+#include "subsystems/imu.h"
+#include "math/pprz_algebra_float.h"
+#include "math/pprz_algebra_int.h"
+#include "math/pprz_simple_matrix.h"
+#include "airframe.h"
+
+#include <string.h>
+
+#include "../../test/pprz_algebra_print.h"
+
+
+static inline void compute_imu_quat_and_euler_from_rmat(void);
+static inline void compute_body_orientation_and_rates(void);
+
+
+struct AhrsFloatCmplRmat ahrs_impl;
+
+void ahrs_init(void) {
+ ahrs_float.status = AHRS_UNINIT;
+
+ /*
+ * Initialises our IMU alignement variables
+ * This should probably done in the IMU code instead
+ */
+ struct FloatEulers body_to_imu_euler =
+ {IMU_BODY_TO_IMU_PHI, IMU_BODY_TO_IMU_THETA, IMU_BODY_TO_IMU_PSI};
+ FLOAT_QUAT_OF_EULERS(ahrs_impl.body_to_imu_quat, body_to_imu_euler);
+ FLOAT_RMAT_OF_EULERS(ahrs_impl.body_to_imu_rmat, body_to_imu_euler);
+
+ /* set ltp_to_body to zero */
+ FLOAT_QUAT_ZERO(ahrs_float.ltp_to_body_quat);
+ FLOAT_EULERS_ZERO(ahrs_float.ltp_to_body_euler);
+ FLOAT_RMAT_ZERO(ahrs_float.ltp_to_body_rmat);
+ FLOAT_RATES_ZERO(ahrs_float.body_rate);
+
+ /* set ltp_to_imu so that body is zero */
+ QUAT_COPY(ahrs_float.ltp_to_imu_quat, ahrs_impl.body_to_imu_quat);
+ RMAT_COPY(ahrs_float.ltp_to_imu_rmat, ahrs_impl.body_to_imu_rmat);
+ EULERS_COPY(ahrs_float.ltp_to_imu_euler, body_to_imu_euler);
+ FLOAT_RATES_ZERO(ahrs_float.imu_rate);
+
+}
+
+
+void ahrs_align(void) {
+
+ /* Compute an initial orientation using euler angles */
+ ahrs_float_get_euler_from_accel_mag(&ahrs_float.ltp_to_imu_euler,
&ahrs_aligner.lp_accel, &ahrs_aligner.lp_mag);
+ /* Convert initial orientation in quaternion and rotation matrice
representations. */
+ FLOAT_QUAT_OF_EULERS(ahrs_float.ltp_to_imu_quat,
ahrs_float.ltp_to_imu_euler);
+ FLOAT_RMAT_OF_QUAT(ahrs_float.ltp_to_imu_rmat, ahrs_float.ltp_to_imu_quat);
+ /* Compute initial body orientation */
+ compute_body_orientation_and_rates();
+
+ /* used averaged gyro as initial value for bias */
+ struct Int32Rates bias0;
+ RATES_COPY(bias0, ahrs_aligner.lp_gyro);
+ RATES_FLOAT_OF_BFP(ahrs_impl.gyro_bias, bias0);
+
+ ahrs.status = AHRS_RUNNING;
+
+}
+
+
+void ahrs_propagate(void) {
+
+ /* converts gyro to floating point */
+ struct FloatRates gyro_float;
+ RATES_FLOAT_OF_BFP(gyro_float, imu.gyro_prev);
+ /* unbias measurement */
+ RATES_DIFF(ahrs_float.imu_rate, gyro_float, ahrs_impl.gyro_bias);
+ const float dt = 1./512.;
+ /* add correction */
+ struct FloatRates omega;
+ RATES_SUM(omega, ahrs_float.imu_rate, ahrs_impl.rate_correction);
+ // DISPLAY_FLOAT_RATES("omega ", omega);
+ /* and zeros it */
+ FLOAT_RATES_ZERO(ahrs_impl.rate_correction);
+
+ /* first order integration of rotation matrix */
+ struct FloatRMat exp_omega_dt = {
+ { 1. , dt*omega.r, -dt*omega.q,
+ -dt*omega.r, 1. , dt*omega.p,
+ dt*omega.q, -dt*omega.p, 1. }};
+ struct FloatRMat R_tdt;
+ FLOAT_RMAT_COMP(R_tdt, ahrs_float.ltp_to_imu_rmat, exp_omega_dt);
+ memcpy(&ahrs_float.ltp_to_imu_rmat, &R_tdt, sizeof(R_tdt));
+
+ float_rmat_reorthogonalize(&ahrs_float.ltp_to_imu_rmat);
+ // struct FloatRMat test;
+ // FLOAT_RMAT_COMP_INV(test, ahrs_float.ltp_to_imu_rmat,
ahrs_float.ltp_to_imu_rmat);
+ // DISPLAY_FLOAT_RMAT("foo", test);
+
+ compute_imu_quat_and_euler_from_rmat();
+ compute_body_orientation_and_rates();
+
+}
+
+void ahrs_update_accel(void) {
+
+ struct FloatVect3 accel_float;
+ ACCELS_FLOAT_OF_BFP(accel_float, imu.accel);
+ struct FloatVect3* r2 = (struct
FloatVect3*)(&RMAT_ELMT(ahrs_float.ltp_to_imu_rmat, 2,0));
+ struct FloatVect3 residual;
+ FLOAT_VECT3_CROSS_PRODUCT(residual, accel_float, (*r2));
+ /* heuristic on acceleration norm */
+ const float acc_norm = FLOAT_VECT3_NORM(accel_float);
+ const float weight = Chop(1.-2*fabs(1-acc_norm/9.81), 0., 1.);
+ //const float weight = 1.;
+ /* compute correction */
+ const float gravity_rate_update_gain = 5e-2;
+ FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.rate_correction, residual,
weight*gravity_rate_update_gain);
+ const float gravity_bias_update_gain = -5e-6;
+ FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.gyro_bias, residual,
weight*gravity_bias_update_gain);
+ /* FIXME: saturate bias */
+
+}
+
+void ahrs_update_mag(void) {
+
+ /* project mag on local tangeant plane */
+ struct FloatVect3 magf;
+ MAGS_FLOAT_OF_BFP(magf, imu.mag);
+ const float cphi = cosf(ahrs_float.ltp_to_imu_euler.phi);
+ const float sphi = sinf(ahrs_float.ltp_to_imu_euler.phi);
+ const float ctheta = cosf(ahrs_float.ltp_to_imu_euler.theta);
+ const float stheta = sinf(ahrs_float.ltp_to_imu_euler.theta);
+ const float mn = ctheta * magf.x + sphi*stheta*magf.y + cphi*stheta*magf.z;
+ const float me = 0. * magf.x + cphi *magf.y - sphi *magf.z;
+
+ const float res_norm = -RMAT_ELMT(ahrs_float.ltp_to_imu_rmat, 0,0)*me +
RMAT_ELMT(ahrs_float.ltp_to_imu_rmat, 1,0)*mn;
+ printf("res norm %f\n", res_norm);
+ struct FloatVect3* r2 = (struct
FloatVect3*)(&RMAT_ELMT(ahrs_float.ltp_to_imu_rmat, 2,0));
+ DISPLAY_FLOAT_VECT3("r2", (*r2));
+ const float mag_rate_update_gain = 2.5;
+ FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.rate_correction, (*r2),
(mag_rate_update_gain*res_norm));
+ DISPLAY_FLOAT_RATES("corr", ahrs_impl.rate_correction);
+ const float mag_bias_update_gain = -2.5e-4;
+ FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.gyro_bias, (*r2),
(mag_bias_update_gain*res_norm));
+ /* FIXME: saturate bias */
+
+}
+
+void ahrs_update_mag2(void) {
+
+ const struct FloatVect3 expected_ltp = {AHRS_H_X, AHRS_H_Y, AHRS_H_Z};
+ struct FloatVect3 expected_imu;
+ FLOAT_RMAT_VECT3_MUL(expected_imu, ahrs_float.ltp_to_imu_rmat, expected_ltp);
+
+ struct FloatVect3 measured_imu;
+ MAGS_FLOAT_OF_BFP(measured_imu, imu.mag);
+
+ struct FloatVect3 residual;
+ FLOAT_VECT3_CROSS_PRODUCT(residual, measured_imu, expected_imu);
+ // FLOAT_VECT3_DIFF(residual, expected_imu, measured_imu);
+
+ DISPLAY_FLOAT_VECT3(" expected", expected_imu);
+ DISPLAY_FLOAT_VECT3(" measured", measured_imu);
+ DISPLAY_FLOAT_VECT3("residual", residual);
+
+ const float mag_rate_update_gain = 2.5;
+ FLOAT_RATES_ADD_SCALED_VECT(ahrs_impl.rate_correction, residual,
mag_rate_update_gain);
+
+}
+
+/*
+ * Compute ltp to imu rotation in euler angles and quaternion representations
+ * from the rotation matrice representation
+ */
+static inline void compute_imu_quat_and_euler_from_rmat(void) {
+ FLOAT_QUAT_OF_RMAT(ahrs_float.ltp_to_imu_quat, ahrs_float.ltp_to_imu_rmat);
+ FLOAT_EULERS_OF_RMAT(ahrs_float.ltp_to_imu_euler,
ahrs_float.ltp_to_imu_rmat);
+}
+
+/*
+ * Compute body orientation and rates from imu orientation and rates
+ */
+static inline void compute_body_orientation_and_rates(void) {
+
+ FLOAT_QUAT_COMP_INV(ahrs_float.ltp_to_body_quat,
+ ahrs_float.ltp_to_imu_quat, ahrs_impl.body_to_imu_quat);
+ FLOAT_RMAT_COMP_INV(ahrs_float.ltp_to_body_rmat,
+ ahrs_float.ltp_to_imu_rmat, ahrs_impl.body_to_imu_rmat);
+ FLOAT_EULERS_OF_RMAT(ahrs_float.ltp_to_body_euler,
ahrs_float.ltp_to_body_rmat);
+ FLOAT_RMAT_TRANSP_RATEMULT(ahrs_float.body_rate, ahrs_impl.body_to_imu_rmat,
ahrs_float.imu_rate);
+
+}
Added: paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_cmpl_rmat.h
===================================================================
--- paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_cmpl_rmat.h
(rev 0)
+++ paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_cmpl_rmat.h
2010-11-04 16:04:25 UTC (rev 6350)
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2010 The Paparazzi Team
+ *
+ * This file is part of paparazzi.
+ *
+ * paparazzi is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * paparazzi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with paparazzi; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef AHRS_FLOAT_CMPL_RMAT
+#define AHRS_FLOAT_CMPL_RMAT
+
+struct AhrsFloatCmplRmat {
+ struct FloatRates gyro_bias;
+ struct FloatRates rate_correction;
+ /*
+ Holds float version of IMU alignement
+ in order to be able to run against the fixed point
+ version of the IMU
+ */
+ struct FloatQuat body_to_imu_quat;
+ struct FloatRMat body_to_imu_rmat;
+};
+
+extern struct AhrsFloatCmplRmat ahrs_impl;
+
+
+#endif /* AHRS_FLOAT_CMPL_RMAT */
Added: paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_utils.h
===================================================================
--- paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_utils.h
(rev 0)
+++ paparazzi3/trunk/sw/airborne/subsystems/ahrs/ahrs_float_utils.h
2010-11-04 16:04:25 UTC (rev 6350)
@@ -0,0 +1,24 @@
+#ifndef AHRS_FLOAT_UTILS_H
+#define AHRS_FLOAT_UTILS_H
+
+static inline void ahrs_float_get_euler_from_accel_mag(struct FloatEulers* e,
struct Int32Vect3* accel, struct Int32Vect3* mag) {
+ /* get phi and theta from accelerometer */
+ struct FloatVect3 accelf;
+ ACCELS_FLOAT_OF_BFP(accelf, *accel);
+ const float phi = atan2f(-accelf.y, -accelf.z);
+ const float cphi = cosf(phi);
+ const float theta = atan2f(cphi*accelf.x, -accelf.z);
+ /* get psi from magnetometer */
+ /* project mag on local tangeant plane */
+ struct FloatVect3 magf;
+ MAGS_FLOAT_OF_BFP(magf, *mag);
+ const float sphi = sinf(phi);
+ const float ctheta = cosf(theta);
+ const float stheta = sinf(theta);
+ const float mn = ctheta * magf.x + sphi*stheta*magf.y + cphi*stheta*magf.z;
+ const float me = 0. * magf.x + cphi *magf.y - sphi *magf.z;
+ const float psi = -atan2f(me, mn);
+ EULERS_ASSIGN(*e, phi, theta, psi);
+}
+
+#endif /* AHRS_FLOAT_UTILS_H */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [paparazzi-commits] [6350] adding a basic implementation,
antoine drouin <=