Merge pull request #2197 from PX4/self_leveling

Self leveling
This commit is contained in:
Lorenz Meier 2015-05-19 14:52:44 +02:00
commit 607c452e71
4 changed files with 81 additions and 2 deletions

View File

@ -133,6 +133,7 @@
#include <fcntl.h>
#include <sys/prctl.h>
#include <math.h>
#include <poll.h>
#include <float.h>
#include <mathlib/mathlib.h>
#include <string.h>
@ -143,6 +144,7 @@
#include <systemlib/param/param.h>
#include <systemlib/err.h>
#include <mavlink/mavlink_log.h>
#include <uORB/topics/vehicle_attitude.h>
/* oddly, ERROR is not defined for c++ */
#ifdef ERROR
@ -552,3 +554,74 @@ calibrate_return calculate_calibration_values(unsigned sensor, float (&accel_ref
return calibrate_return_ok;
}
int do_level_calibration(int mavlink_fd) {
const unsigned cal_time = 5;
const unsigned cal_hz = 250;
const unsigned settle_time = 30;
int att_sub = orb_subscribe(ORB_ID(vehicle_attitude));
struct vehicle_attitude_s att;
memset(&att, 0, sizeof(att));
mavlink_and_console_log_info(mavlink_fd, CAL_QGC_STARTED_MSG, "level");
param_t roll_offset_handler = param_find("SENS_BOARD_X_OFF");
param_t pitch_offset_handler = param_find("SENS_BOARD_Y_OFF");
float zero = 0.0f;
param_set(roll_offset_handler, &zero);
param_set(pitch_offset_handler, &zero);
struct pollfd fds[1];
fds[0].fd = att_sub;
fds[0].events = POLLIN;
float roll_mean = 0.0f;
float pitch_mean = 0.0f;
unsigned counter = 0;
// sleep for some time
hrt_abstime start = hrt_absolute_time();
while(hrt_elapsed_time(&start) < settle_time * 1000000) {
mavlink_and_console_log_info(mavlink_fd, CAL_QGC_PROGRESS_MSG, (int)(90*hrt_elapsed_time(&start)/1e6f/(float)settle_time));
sleep(settle_time / 10);
}
start = hrt_absolute_time();
// average attitude for 5 seconds
while(hrt_elapsed_time(&start) < cal_time * 1000000) {
poll(&fds[0], (sizeof(fds) / sizeof(fds[0])), 100);
orb_copy(ORB_ID(vehicle_attitude), att_sub, &att);
roll_mean += att.roll;
pitch_mean += att.pitch;
counter++;
}
mavlink_and_console_log_info(mavlink_fd, CAL_QGC_PROGRESS_MSG, 100);
if (counter > (cal_time * cal_hz / 2 )) {
roll_mean /= counter;
pitch_mean /= counter;
} else {
mavlink_and_console_log_info(mavlink_fd, "not enough measurements taken");
return 1;
}
if (fabsf(roll_mean) > 0.8f ) {
mavlink_and_console_log_critical(mavlink_fd, "excess roll angle");
return 1;
} else if (fabsf(pitch_mean) > 0.8f ) {
mavlink_and_console_log_critical(mavlink_fd, "excess pitch angle");
return 1;
}
else {
roll_mean *= (float)M_RAD_TO_DEG;
pitch_mean *= (float)M_RAD_TO_DEG;
param_set(roll_offset_handler, &roll_mean);
param_set(pitch_offset_handler, &pitch_mean);
}
mavlink_and_console_log_info(mavlink_fd, CAL_QGC_DONE_MSG, "level");
return 0;
}

View File

@ -45,5 +45,6 @@
#include <stdint.h>
int do_accel_calibration(int mavlink_fd);
int do_level_calibration(int mavlink_fd);
#endif /* ACCELEROMETER_CALIBRATION_H_ */

View File

@ -317,6 +317,8 @@ int commander_main(int argc, char *argv[])
calib_ret = do_accel_calibration(mavlink_fd);
} else if (!strcmp(argv[2], "gyro")) {
calib_ret = do_gyro_calibration(mavlink_fd);
} else if (!strcmp(argv[2], "level")) {
calib_ret = do_level_calibration(mavlink_fd);
} else {
warnx("argument %s unsupported.", argv[2]);
}
@ -2720,7 +2722,10 @@ void *commander_low_prio_loop(void *arg)
/* accelerometer calibration */
answer_command(cmd, VEHICLE_CMD_RESULT_ACCEPTED);
calib_ret = do_accel_calibration(mavlink_fd);
} else if ((int)(cmd.param5) == 2) {
// board offset calibration
answer_command(cmd, VEHICLE_CMD_RESULT_ACCEPTED);
calib_ret = do_level_calibration(mavlink_fd);
} else if ((int)(cmd.param6) == 1) {
/* airspeed calibration */
answer_command(cmd, VEHICLE_CMD_RESULT_ACCEPTED);

View File

@ -856,7 +856,7 @@ Sensors::parameters_update()
M_DEG_TO_RAD_F * _parameters.board_offset[1],
M_DEG_TO_RAD_F * _parameters.board_offset[2]);
_board_rotation = _board_rotation * board_rotation_offset;
_board_rotation = board_rotation_offset * _board_rotation;
/* update barometer qnh setting */
param_get(_parameter_handles.baro_qnh, &(_parameters.baro_qnh));