5 #include <aversive/irq_lock.h>
6 #include <aversive/wait.h>
7 #include <aversive/pgmspace.h>
13 #include "MadgwickAHRS.h"
18 /* structure storing the latest imu infos returned by the sensor */
19 static struct imu_info g_imu;
21 /* structure storing the latest quaternion */
22 static struct quaternion g_quat;
24 /* structure storing the latest euler position */
25 static struct euler g_euler;
27 /* periodical timer structure */
28 static struct callout imu_timer;
30 static void quaternion2euler(const struct quaternion *quat, struct euler *euler)
37 euler->roll = atan2f(2.0f * (q0 * q1 + q2 * q3),
38 q0*q0 - q1*q1 - q2*q2 + q3*q3);
39 euler->pitch = -asinf(2.0f * (q1 * q3 - q0 * q2));
40 euler->yaw = atan2f(2.0f * (q1 * q2 + q0 * q3),
41 q0*q0 + q1*q1 - q2*q2 - q3*q3);
44 /* timer callback that polls IMU and does the calculation */
45 static void imu_cb(struct callout_mgr *cm, struct callout *tim, void *arg)
49 mpu6050_read_all_axes(&g_imu);
50 MadgwickAHRSupdate(&g_imu, &g_quat);
51 quaternion2euler(&g_quat, &g_euler);
53 /* reschedule event */
54 callout_schedule(cm, tim, 2);
61 callout_init(&imu_timer, imu_cb, NULL, IMU_PRIO);
62 callout_schedule(&imuboard.intr_cm, &imu_timer, 20); /* every 20ms */
65 void imu_get_info(struct imu_info *imu)
67 memcpy(imu, &g_imu, sizeof(*imu));
70 void imu_get_pos_quat(struct quaternion *quat)
72 memcpy(quat, &g_quat, sizeof(*quat));
75 void imu_get_pos_euler(struct euler *euler)
77 memcpy(euler, &g_euler, sizeof(*euler));
89 if (sd_log_enabled() == 0)
97 len = snprintf(buf, sizeof(buf),
99 "gyro %+3.3f\t%+3.3f\t%+3.3f\t\t"
100 "accel %+3.3f\t%+3.3f\t%+3.3f\t\t"
101 "magnet %+3.3f\t%+3.3f\t%+3.3f\r\n",
103 imu.gx, imu.gy, imu.gz,
104 imu.ax, imu.ay, imu.az,
105 imu.mx, imu.my, imu.mz);
106 if (sd_log_write(buf, len) != len) {
107 printf_P(PSTR("error writing to file\n"));