aboutsummaryrefslogtreecommitdiff
path: root/apps/px4/attitude_estimator_bm/attitude_estimator_bm.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/px4/attitude_estimator_bm/attitude_estimator_bm.c')
-rw-r--r--apps/px4/attitude_estimator_bm/attitude_estimator_bm.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/apps/px4/attitude_estimator_bm/attitude_estimator_bm.c b/apps/px4/attitude_estimator_bm/attitude_estimator_bm.c
new file mode 100644
index 000000000..3c6c8eec3
--- /dev/null
+++ b/apps/px4/attitude_estimator_bm/attitude_estimator_bm.c
@@ -0,0 +1,228 @@
+/****************************************************************************
+ *
+ * Copyright (C) 2012 PX4 Development Team. All rights reserved.
+ * Author: Tobias Naegeli <naegelit@student.ethz.ch>
+ * Laurens Mackay <mackayl@student.ethz.ch>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name PX4 nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/* @file Black Magic Attitude Estimator */
+
+
+
+#include <nuttx/config.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <arch/board/up_hrt.h>
+#include <string.h>
+#include <poll.h>
+#include <uORB/uORB.h>
+#include <uORB/topics/sensor_combined.h>
+#include <uORB/topics/vehicle_attitude.h>
+#include <math.h>
+#include <errno.h>
+
+#include "attitude_bm.h"
+
+static unsigned int loop_interval_alarm = 4500; // loop interval in microseconds
+
+__EXPORT int attitude_estimator_bm_main(int argc, char *argv[]);
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * user_start
+ ****************************************************************************/
+int attitude_estimator_bm_update(struct sensor_combined_s *raw, float_vect3 *euler, float_vect3 *rates, float_vect3 *x_n_b, float_vect3 *y_n_b, float_vect3 *z_n_b);
+
+int attitude_estimator_bm_update(struct sensor_combined_s *raw, float_vect3 *euler, float_vect3 *rates, float_vect3 *x_n_b, float_vect3 *y_n_b, float_vect3 *z_n_b)
+{
+ float_vect3 gyro_values;
+ gyro_values.x = raw->gyro_rad_s[0];
+ gyro_values.y = raw->gyro_rad_s[1];
+ gyro_values.z = raw->gyro_rad_s[2];
+
+ float_vect3 accel_values;
+ accel_values.x = raw->accelerometer_m_s2[0];
+ accel_values.y = raw->accelerometer_m_s2[1];
+ accel_values.z = raw->accelerometer_m_s2[2];
+
+ float_vect3 mag_values;
+ mag_values.x = raw->magnetometer_ga[0];
+ mag_values.y = raw->magnetometer_ga[1];
+ mag_values.z = raw->magnetometer_ga[2];
+
+ attitude_blackmagic(&accel_values, &mag_values, &gyro_values);
+
+ /* read out values */
+ attitude_blackmagic_get_all(euler, rates, x_n_b, y_n_b, z_n_b);
+
+ return OK;
+}
+
+
+int attitude_estimator_bm_main(int argc, char *argv[])
+{
+ // print text
+ printf("Black Magic Attitude Estimator initialized..\n\n");
+ fflush(stdout);
+
+ /* data structures to read euler angles and rotation matrix back */
+ float_vect3 euler = {.x = 0, .y = 0, .z = 0};
+ float_vect3 rates;
+ float_vect3 x_n_b;
+ float_vect3 y_n_b;
+ float_vect3 z_n_b;
+
+ int overloadcounter = 19;
+
+ /* initialize */
+ attitude_blackmagic_init();
+
+ /* store start time to guard against too slow update rates */
+ uint64_t last_run = hrt_absolute_time();
+
+ struct sensor_combined_s sensor_combined_s_local = { .gyro_raw = {0}};
+ struct vehicle_attitude_s att = {.roll = 0.0f, .pitch = 0.0f, .yaw = 0.0f,
+ .rollspeed = 0.0f, .pitchspeed = 0.0f, .yawspeed = 0.0f,
+ .R = {0}, .timestamp = 0};
+
+ uint64_t last_data = 0;
+
+ /* subscribe to raw data */
+ int sub_raw = orb_subscribe(ORB_ID(sensor_combined));
+
+ /* rate-limit raw data updates to 200Hz */
+ //orb_set_interval(sub_raw, 5);
+
+ /* advertise attitude */
+ int pub_att = orb_advertise(ORB_ID(vehicle_attitude), &att);
+
+ struct pollfd fds[] = {
+ { .fd = sub_raw, .events = POLLIN },
+ };
+
+ // int paramcounter = 100;
+
+ /* Main loop*/
+ while (true) {
+
+ /* wait for sensor update */
+ int ret = poll(fds, 1, 5000);
+
+ if (ret < 0) {
+ /* XXX this is seriously bad - should be an emergency */
+ } else if (ret == 0) {
+ /* XXX this means no sensor data - should be critical or emergency */
+ printf("[attitude estimator bm] WARNING: Not getting sensor data - sensor app running?\n");
+ continue;
+ }
+
+ orb_copy(ORB_ID(sensor_combined), sub_raw, &sensor_combined_s_local);
+
+ uint64_t now = hrt_absolute_time();
+ unsigned int time_elapsed = now - last_run;
+ last_run = now;
+
+//#if 0
+
+ if (time_elapsed > loop_interval_alarm) {
+ //TODO: add warning, cpu overload here
+ if (overloadcounter == 20) {
+ printf("CPU OVERLOAD DETECTED IN ATTITUDE ESTIMATOR BLACK MAGIC (%lu > %lu)\n", time_elapsed, loop_interval_alarm);
+ overloadcounter = 0;
+ }
+
+ overloadcounter++;
+ }
+
+//#endif
+// now = hrt_absolute_time();
+ /* filter values */
+ attitude_estimator_bm_update(&sensor_combined_s_local, &euler, &rates, &x_n_b, &y_n_b, &z_n_b);
+
+// time_elapsed = hrt_absolute_time() - now;
+// if (blubb == 20)
+// {
+// printf("Estimator: %lu\n", time_elapsed);
+// blubb = 0;
+// }
+// blubb++;
+
+// if (last_data > 0 && sensor_combined_s_local.timestamp - last_data > 8000) printf("sensor data missed! (%llu)\n", sensor_combined_s_local.timestamp - last_data);
+
+// printf("%llu -> %llu = %llu\n", last_data, sensor_combined_s_local.timestamp, sensor_combined_s_local.timestamp - last_data);
+ // last_data = sensor_combined_s_local.timestamp;
+
+ /*correct yaw */
+// euler.z = euler.z + M_PI;
+
+ /* send out */
+
+ att.timestamp = sensor_combined_s_local.timestamp;
+ att.roll = euler.x;
+ att.pitch = euler.y;
+ att.yaw = euler.z + M_PI;
+
+ if (att.yaw > 2.0f * ((float)M_PI)) {
+ att.yaw -= 2.0f * ((float)M_PI);
+ }
+
+ att.rollspeed = rates.x;
+ att.pitchspeed = rates.y;
+ att.yawspeed = rates.z;
+
+ att.R[0][0] = x_n_b.x;
+ att.R[0][1] = x_n_b.y;
+ att.R[0][2] = x_n_b.z;
+ // XXX add remaining entries
+
+ // Broadcast
+ orb_publish(ORB_ID(vehicle_attitude), pub_att, &att);
+ }
+
+ /* Should never reach here */
+ return 0;
+}
+
+