Files
paparazzi/sw/airborne/subsystems/imu.c
T
Gautier Hattenberger 116faaeda6 [telemetry] protect telemetry code with #if DOWNLINK
- also get rid of AP_DOWNLINK and FBW_DOWNLINK
- still needs to make it work again (for the only remaining classix in
  the world...)
2013-06-17 01:06:45 +02:00

157 lines
5.2 KiB
C

/*
* Copyright (C) 2008-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.
*/
/**
* @file subsystems/imu.c
* Inertial Measurement Unit interface.
*/
#include "subsystems/imu.h"
#if DOWNLINK
#include "subsystems/datalink/telemetry.h"
static void send_accel_raw(void) {
DOWNLINK_SEND_IMU_ACCEL_RAW(DefaultChannel, DefaultDevice,
&imu.accel_unscaled.x, &imu.accel_unscaled.y, &imu.accel_unscaled.z);
}
static void send_accel_scaled(void) {
DOWNLINK_SEND_IMU_ACCEL_SCALED(DefaultChannel, DefaultDevice,
&imu.accel.x, &imu.accel.y, &imu.accel.z);
}
static void send_accel(void) {
struct FloatVect3 accel_float;
ACCELS_FLOAT_OF_BFP(accel_float, imu.accel);
DOWNLINK_SEND_IMU_ACCEL(DefaultChannel, DefaultDevice,
&accel_float.x, &accel_float.y, &accel_float.z);
}
static void send_gyro_raw(void) {
DOWNLINK_SEND_IMU_GYRO_RAW(DefaultChannel, DefaultDevice,
&imu.gyro_unscaled.p, &imu.gyro_unscaled.q, &imu.gyro_unscaled.r);
}
static void send_gyro_scaled(void) {
DOWNLINK_SEND_IMU_GYRO_SCALED(DefaultChannel, DefaultDevice,
&imu.gyro.p, &imu.gyro.q, &imu.gyro.r);
}
static void send_gyro(void) {
struct FloatRates gyro_float;
RATES_FLOAT_OF_BFP(gyro_float, imu.gyro);
DOWNLINK_SEND_IMU_GYRO(DefaultChannel, DefaultDevice,
&gyro_float.p, &gyro_float.q, &gyro_float.r);
}
#ifdef USE_MAGNETOMETER
static void send_mag_raw(void) {
DOWNLINK_SEND_IMU_MAG_RAW(DefaultChannel, DefaultDevice,
&imu.mag_unscaled.x, &imu.mag_unscaled.y, &imu.mag_unscaled.z);
}
static void send_mag_scaled(void) {
DOWNLINK_SEND_IMU_MAG_SCALED(DefaultChannel, DefaultDevice,
&imu.mag.x, &imu.mag.y, &imu.mag.z);
}
static void send_mag(void) {
struct FloatVect3 mag_float;
MAGS_FLOAT_OF_BFP(mag_float, imu.mag);
DOWNLINK_SEND_IMU_MAG(DefaultChannel, DefaultDevice,
&mag_float.x, &mag_float.y, &mag_float.z);
}
// TODO this could be a special module ?
#include "subsystems/electrical.h"
static void send_mag_calib(void) {
DOWNLINK_SEND_IMU_MAG_CURRENT_CALIBRATION(DefaultChannel, DefaultDevice,
&imu.mag_unscaled.x, &imu.mag_unscaled.y, &imu.mag_unscaled.z,
&electrical.current);
}
#endif
#endif
struct Imu imu;
void imu_init(void) {
/* initialises neutrals */
RATES_ASSIGN(imu.gyro_neutral, IMU_GYRO_P_NEUTRAL, IMU_GYRO_Q_NEUTRAL, IMU_GYRO_R_NEUTRAL);
VECT3_ASSIGN(imu.accel_neutral, IMU_ACCEL_X_NEUTRAL, IMU_ACCEL_Y_NEUTRAL, IMU_ACCEL_Z_NEUTRAL);
#if defined IMU_MAG_X_NEUTRAL && defined IMU_MAG_Y_NEUTRAL && defined IMU_MAG_Z_NEUTRAL
VECT3_ASSIGN(imu.mag_neutral, IMU_MAG_X_NEUTRAL, IMU_MAG_Y_NEUTRAL, IMU_MAG_Z_NEUTRAL);
#else
#if USE_MAGNETOMETER
INFO("Magnetometer neutrals are set to zero, you should calibrate!")
#endif
INT_VECT3_ZERO(imu.mag_neutral);
#endif
/*
Compute quaternion and rotation matrix
for conversions between body and imu frame
*/
struct Int32Eulers body_to_imu_eulers =
{ ANGLE_BFP_OF_REAL(IMU_BODY_TO_IMU_PHI),
ANGLE_BFP_OF_REAL(IMU_BODY_TO_IMU_THETA),
ANGLE_BFP_OF_REAL(IMU_BODY_TO_IMU_PSI) };
INT32_QUAT_OF_EULERS(imu.body_to_imu_quat, body_to_imu_eulers);
INT32_QUAT_NORMALIZE(imu.body_to_imu_quat);
INT32_RMAT_OF_EULERS(imu.body_to_imu_rmat, body_to_imu_eulers);
#if DOWNLINK
register_periodic_telemetry(DefaultPeriodic, "IMU_ACCEL_RAW", send_accel_raw);
register_periodic_telemetry(DefaultPeriodic, "IMU_ACCEL_SCALED", send_accel_scaled);
register_periodic_telemetry(DefaultPeriodic, "IMU_ACCEL", send_accel);
register_periodic_telemetry(DefaultPeriodic, "IMU_GYRO_RAW", send_gyro_raw);
register_periodic_telemetry(DefaultPeriodic, "IMU_GYRO_SCALED", send_gyro_scaled);
register_periodic_telemetry(DefaultPeriodic, "IMU_GYRO", send_gyro);
#ifdef USE_MAGNETOMETER
register_periodic_telemetry(DefaultPeriodic, "IMU_MAG_RAW", send_mag_raw);
register_periodic_telemetry(DefaultPeriodic, "IMU_MAG_SCALED", send_mag_scaled);
register_periodic_telemetry(DefaultPeriodic, "IMU_MAG", send_mag);
register_periodic_telemetry(DefaultPeriodic, "IMU_MAG_CURRENT_CALIBRATION", send_mag_calib);
#endif
#endif
imu_impl_init();
}
void imu_float_init(struct ImuFloat* imuf) {
/*
Compute quaternion and rotation matrix
for conversions between body and imu frame
*/
EULERS_ASSIGN(imuf->body_to_imu_eulers,
IMU_BODY_TO_IMU_PHI, IMU_BODY_TO_IMU_THETA, IMU_BODY_TO_IMU_PSI);
FLOAT_QUAT_OF_EULERS(imuf->body_to_imu_quat, imuf->body_to_imu_eulers);
FLOAT_QUAT_NORMALIZE(imuf->body_to_imu_quat);
FLOAT_RMAT_OF_EULERS(imuf->body_to_imu_rmat, imuf->body_to_imu_eulers);
}