aboutsummaryrefslogtreecommitdiff
path: root/apps/position_estimator_inav/position_estimator_inav_main.c
diff options
context:
space:
mode:
authorAnton <rk3dov@gmail.com>2013-03-30 01:54:04 +0400
committerAnton <rk3dov@gmail.com>2013-03-30 01:54:04 +0400
commit382af2b52d98de82c5cc0953e2c2ba7acf65501f (patch)
tree7c6e21dab83e81a7da46af0864e8693668aed1c3 /apps/position_estimator_inav/position_estimator_inav_main.c
parentfb663bbb0c02ab6d6b6e1b360f5833028cd25bdd (diff)
downloadpx4-firmware-382af2b52d98de82c5cc0953e2c2ba7acf65501f.tar.gz
px4-firmware-382af2b52d98de82c5cc0953e2c2ba7acf65501f.tar.bz2
px4-firmware-382af2b52d98de82c5cc0953e2c2ba7acf65501f.zip
Acceleration vector transform implemented. Accelerometer calibration procedure defined but not implemented yet.
Diffstat (limited to 'apps/position_estimator_inav/position_estimator_inav_main.c')
-rw-r--r--apps/position_estimator_inav/position_estimator_inav_main.c214
1 files changed, 132 insertions, 82 deletions
diff --git a/apps/position_estimator_inav/position_estimator_inav_main.c b/apps/position_estimator_inav/position_estimator_inav_main.c
index 4277fe19b..1c6d21ded 100644
--- a/apps/position_estimator_inav/position_estimator_inav_main.c
+++ b/apps/position_estimator_inav/position_estimator_inav_main.c
@@ -71,6 +71,7 @@
#include "sounds.h"
#include <drivers/drv_tone_alarm.h>
#include "kalman_filter_inertial.h"
+#include "acceleration_transform.h"
static bool thread_should_exit = false; /**< Deamon exit flag */
static bool thread_running = false; /**< Deamon status flag */
@@ -147,9 +148,18 @@ int position_estimator_inav_thread_main(int argc, char *argv[]) {
mavlink_fd = open(MAVLINK_LOG_DEVICE, 0);
mavlink_log_info(mavlink_fd, "[position_estimator_inav] started");
+ /* kalman filter K for simulation parameters:
+ * rate_accel = 200 Hz
+ * rate_baro = 100 Hz
+ * err_accel = 1.0 m/s^2
+ * err_baro = 0.2 m
+ */
+ static float k[3][2] = {
+ { 0.0262f, 0.00001f },
+ { 0.0349f, 0.00191f },
+ { 0.000259f, 0.618f }
+ };
/* initialize values */
- static float k[3][2] = { { 0.002f, 0.0f }, { 0.001f, 0.00002f }, { 0.0f,
- 0.99f } };
static float x_est[3] = { 0.0f, 0.0f, 0.0f };
static float y_est[3] = { 0.0f, 0.0f, 0.0f };
static float z_est[3] = { 0.0f, 0.0f, 0.0f };
@@ -160,7 +170,6 @@ int position_estimator_inav_thread_main(int argc, char *argv[]) {
int baro_loop_cnt = 0;
int baro_loop_end = 70; /* measurement for 1 second */
float baro_alt0 = 0.0f; /* to determin while start up */
- float rho0 = 1.293f; /* standard pressure */
const static float const_earth_gravity = 9.81f;
static double lat_current = 0.0d; //[°]] --> 47.0
@@ -203,6 +212,15 @@ int position_estimator_inav_thread_main(int argc, char *argv[]) {
/* FIRST PARAMETER UPDATE */
parameters_update(&pos_inav_param_handles, &pos_inav_params);
/* END FIRST PARAMETER UPDATE */
+
+ // TODO implement calibration procedure, now put dummy values
+ int16_t accel_offs[3] = { 0, 0, 0 };
+ float accel_T[3][3] = {
+ { 1.0f, 0.0f, 0.0f },
+ { 0.0f, 1.0f, 0.0f },
+ { 0.0f, 0.0f, 1.0f }
+ };
+
/* wait until gps signal turns valid, only then can we initialize the projection */
if (use_gps) {
struct pollfd fds_init[1] = { { .fd = vehicle_gps_position_sub,
@@ -226,12 +244,12 @@ int position_estimator_inav_thread_main(int argc, char *argv[]) {
static int printcounter = 0;
if (printcounter == 100) {
printcounter = 0;
- printf("[pos_est1D] wait for GPS fix type 3\n");
+ printf("[position_estimator_inav] wait for GPS fix type 3\n");
}
printcounter++;
}
- /* get gps value for first initialization */
+ /* get GPS position for first initialization */
orb_copy(ORB_ID(vehicle_gps_position), vehicle_gps_position_sub, &gps);
lat_current = ((double) (gps.lat)) * 1e-7;
lon_current = ((double) (gps.lon)) * 1e-7;
@@ -240,20 +258,38 @@ int position_estimator_inav_thread_main(int argc, char *argv[]) {
map_projection_init(lat_current, lon_current);
/* publish global position messages only after first GPS message */
}
- printf("[pos_est1D] initialized projection with: lat: %.10f, lon:%.10f\n",
+ printf("[position_estimator_inav] initialized projection with: lat: %.10f, lon:%.10f\n",
lat_current, lon_current);
+
hrt_abstime last_time = 0;
thread_running = true;
+ static int printatt_counter = 0;
+ uint32_t accelerometer_counter = 0;
+ uint32_t baro_counter = 0;
+ uint16_t accelerometer_updates = 0;
+ uint16_t baro_updates = 0;
+ hrt_abstime updates_counter_start = hrt_absolute_time();
+ uint32_t updates_counter_len = 1000000;
+ hrt_abstime pub_last = 0;
+ uint32_t pub_interval = 5000; // limit publish rate to 200 Hz
- /** main loop */
- struct pollfd fds[3] = { { .fd = parameter_update_sub, .events = POLLIN }, { .fd = vehicle_status_sub, .events = POLLIN }, { .fd = sensor_combined_sub, .events = POLLIN } };
+ /* main loop */
+ struct pollfd fds[3] = {
+ { .fd = parameter_update_sub, .events = POLLIN },
+ { .fd = vehicle_status_sub, .events = POLLIN },
+ { .fd = vehicle_attitude_sub, .events = POLLIN },
+ { .fd = sensor_combined_sub, .events = POLLIN },
+ { .fd = vehicle_gps_position_sub, .events = POLLIN }
+ };
printf("[position_estimator_inav] main loop started\n");
- static int printatt_counter = 0;
while (!thread_should_exit) {
- int ret = poll(fds, 3, 20); //wait maximal this 20 ms = 50 Hz minimum rate
+ bool accelerometer_updated = false;
+ bool baro_updated = false;
+ int ret = poll(fds, 5, 10); // wait maximal this 10 ms = 100 Hz minimum rate
if (ret < 0) {
/* poll error */
- } else {
+ printf("[position_estimator_inav] subscriptions poll error\n", ret);
+ } else if (ret > 0) {
/* parameter update */
if (fds[0].revents & POLLIN) {
/* read from param to clear updated flag */
@@ -262,7 +298,6 @@ int position_estimator_inav_thread_main(int argc, char *argv[]) {
&update);
/* update parameters */
parameters_update(&pos_inav_param_handles, &pos_inav_params);
- //r = pos_inav_params.r;
}
/* vehicle status */
if (fds[1].revents & POLLIN) {
@@ -270,16 +305,41 @@ int position_estimator_inav_thread_main(int argc, char *argv[]) {
&vehicle_status);
}
/* vehicle attitude */
- //if (fds[2].revents & POLLIN) {
- orb_copy(ORB_ID(vehicle_attitude), vehicle_attitude_sub, &att);
- //}
- /* sensor combined */
if (fds[2].revents & POLLIN) {
+ orb_copy(ORB_ID(vehicle_attitude), vehicle_attitude_sub, &att);
+ }
+ /* sensor combined */
+ if (fds[3].revents & POLLIN) {
orb_copy(ORB_ID(sensor_combined), sensor_combined_sub, &sensor);
+ if (sensor.accelerometer_counter > accelerometer_counter) {
+ accelerometer_updated = true;
+ accelerometer_counter = sensor.accelerometer_counter;
+ accelerometer_updates++;
+ }
+ if (sensor.baro_counter > baro_counter) {
+ baro_updated = true;
+ baro_counter = sensor.baro_counter;
+ baro_updates++;
+ }
+ // barometric pressure estimation at start up
+ if (!local_flag_baroINITdone && baro_updated) {
+ // mean calculation over several measurements
+ if (baro_loop_cnt < baro_loop_end) {
+ baro_alt0 += sensor.baro_alt_meter;
+ baro_loop_cnt++;
+ } else {
+ baro_alt0 /= (float) (baro_loop_cnt);
+ local_flag_baroINITdone = true;
+ char str[80];
+ sprintf(str, "[position_estimator_inav] barometer initialized with alt0 = %.2f", baro_alt0);
+ printf("%s\n", str);
+ mavlink_log_info(mavlink_fd, str);
+ }
+ }
}
if (use_gps) {
/* vehicle GPS position */
- //if (fds[4].revents & POLLIN) {
+ if (fds[4].revents & POLLIN) {
/* new GPS value */
orb_copy(ORB_ID(vehicle_gps_position),
vehicle_gps_position_sub, &gps);
@@ -289,75 +349,65 @@ int position_estimator_inav_thread_main(int argc, char *argv[]) {
((double) (gps.lon)) * 1e-7, &(local_pos_gps[0]),
&(local_pos_gps[1]));
local_pos_gps[2] = (float) (gps.alt * 1e-3);
- //}
- }
- // barometric pressure estimation at start up
- if (!local_flag_baroINITdone) {
- // mean calculation over several measurements
- if (baro_loop_cnt < baro_loop_end) {
- baro_alt0 += sensor.baro_alt_meter;
- baro_loop_cnt++;
- } else {
- baro_alt0 /= (float) (baro_loop_cnt);
- local_flag_baroINITdone = true;
- char *baro_m_start = "barometer initialized with alt0 = ";
- char p0_char[15];
- sprintf(p0_char, "%8.2f", baro_alt0 / 100);
- char *baro_m_end = " m";
- char str[80];
- strcpy(str, baro_m_start);
- strcat(str, p0_char);
- strcat(str, baro_m_end);
- mavlink_log_info(mavlink_fd, str);
}
}
- hrt_abstime t = hrt_absolute_time();
- float dt = (t - last_time) / 1000000.0;
- last_time = t;
- /* convert accelerations from UAV frame to NED frame */
- float accel_NED[3] = { 0.0f, 0.0f, 0.0f };
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- accel_NED[i] += att.R[i][j] * sensor.accelerometer_m_s2[j];
- }
- }
- accel_NED[2] += const_earth_gravity;
- /* prediction */
- kalman_filter_inertial_predict(dt, z_est);
- /* prepare vectors for kalman filter correction */
- float z_meas[2]; // pos, accel
- bool use_z[2] = { false, true };
- if (local_flag_baroINITdone) {
- z_meas[0] = baro_alt0 - sensor.baro_alt_meter; // Z = -alt
- use_z[0] = true;
+ } /* end of poll return value check */
+
+ hrt_abstime t = hrt_absolute_time();
+ float dt = (t - last_time) / 1000000.0;
+ last_time = t;
+ /* calculate corrected acceleration vector in UAV frame */
+ float accel_corr[3];
+ acceleration_correct(accel_corr, sensor.accelerometer_raw, accel_T, accel_offs);
+ /* transform acceleration vector from UAV frame to NED frame */
+ float accel_NED[3];
+ for (int i = 0; i < 3; i++) {
+ accel_NED[i] = 0.0f;
+ for (int j = 0; j < 3; j++) {
+ accel_NED[i] += att.R[i][j] * accel_corr[j];
}
+ }
+ accel_NED[2] += const_earth_gravity;
+ /* kalman filter prediction */
+ kalman_filter_inertial_predict(dt, z_est);
+ /* prepare vectors for kalman filter correction */
+ float z_meas[2]; // position, acceleration
+ bool use_z[2] = { false, false };
+ if (local_flag_baroINITdone && baro_updated) {
+ z_meas[0] = baro_alt0 - sensor.baro_alt_meter; // Z = -alt
+ use_z[0] = true;
+ }
+ if (accelerometer_updated) {
z_meas[1] = accel_NED[2];
+ use_z[1] = true;
+ }
+ if (use_z[0] || use_z[1]) {
/* correction */
kalman_filter_inertial_update(z_est, z_meas, k, use_z);
- if (printatt_counter == 100) {
- printatt_counter = 0;
- printf("[pos_est_inav] dt = %.6f\n", dt);
- printf("[pos_est_inav] pitch = %.3f, roll = %.3f, yaw = %.3f\n",
- att.pitch, att.roll, att.yaw);
- printf("[pos_est_inav] accel_UAV = %.3f, %.3f, %.3f\n",
- sensor.accelerometer_m_s2[0],
- sensor.accelerometer_m_s2[1],
- sensor.accelerometer_m_s2[2]);
- printf("[pos_est_inav] accel_NED = %.3f, %.3f, %.3f\n",
- accel_NED[0], accel_NED[1], accel_NED[2]);
- /*
- printf("[pos_est_inav] Rot_matrix: %.3f %.3f %.3f\n",
- att.R[0][0], att.R[0][1], att.R[0][2]);
- printf("[pos_est_inav] Rot_matrix: %.3f %.3f %.3f\n",
- att.R[1][0], att.R[1][1], att.R[1][2]);
- printf("[pos_est_inav] Rot_matrix: %.3f %.3f %.3f\n",
- att.R[2][0], att.R[2][1], att.R[2][2]);
- */
- printf("[pos_est_inav] z = %.2f, vz = %.2f, az = %.2f\n",
- z_est[0], z_est[1], z_est[2]);
- }
- printatt_counter++;
+ }
+ if (t - updates_counter_start > updates_counter_len) {
+ float updates_dt = (t - updates_counter_start) * 0.000001f;
+ printf("[position_estimator_inav] accelerometer_updates_rate = %.1/s, baro_updates_rate = %.1f/s\n", accelerometer_updates / updates_dt, baro_updates / updates_dt);
+ updates_counter_start = t;
+ }
+ if (printatt_counter == 100) {
+ printatt_counter = 0;
+ printf("[position_estimator_inav] dt = %.6f\n", dt);
+ printf("[position_estimator_inav] pitch = %.3f, roll = %.3f, yaw = %.3f\n",
+ att.pitch, att.roll, att.yaw);
+ printf("[position_estimator_inav] accel_UAV = %.3f, %.3f, %.3f\n",
+ sensor.accelerometer_m_s2[0],
+ sensor.accelerometer_m_s2[1],
+ sensor.accelerometer_m_s2[2]);
+ printf("[position_estimator_inav] accel_NED = %.3f, %.3f, %.3f\n",
+ accel_NED[0], accel_NED[1], accel_NED[2]);
+ printf("[position_estimator_inav] z = %.2f, vz = %.2f, az = %.2f\n",
+ z_est[0], z_est[1], z_est[2]);
+ }
+ printatt_counter++;
+ if (t - pub_last > pub_interval) {
+ pub_last = t;
local_pos_est.x = 0.0;
local_pos_est.vx = 0.0;
local_pos_est.y = 0.0;
@@ -374,11 +424,11 @@ int position_estimator_inav_thread_main(int argc, char *argv[]) {
vehicle_local_position), local_pos_est_pub,
&local_pos_est);
}
- } /* end of poll return value check */
+ }
}
- printf("[pos_est_inav] exiting.\n");
- mavlink_log_info(mavlink_fd, "[pos_est_inav] exiting");
+ printf("[position_estimator_inav] exiting.\n");
+ mavlink_log_info(mavlink_fd, "[position_estimator_inav] exiting");
thread_running = false;
return 0;
}