diff --git a/src/modules/commander/accelerometer_calibration.cpp b/src/modules/commander/accelerometer_calibration.cpp index efd88b3d40..f4fd88fa22 100644 --- a/src/modules/commander/accelerometer_calibration.cpp +++ b/src/modules/commander/accelerometer_calibration.cpp @@ -133,6 +133,7 @@ #include #include #include +#include #include #include #include @@ -143,6 +144,7 @@ #include #include #include +#include /* 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; + +} diff --git a/src/modules/commander/accelerometer_calibration.h b/src/modules/commander/accelerometer_calibration.h index 6b7e16d449..05c02e294d 100644 --- a/src/modules/commander/accelerometer_calibration.h +++ b/src/modules/commander/accelerometer_calibration.h @@ -45,5 +45,6 @@ #include int do_accel_calibration(int mavlink_fd); +int do_level_calibration(int mavlink_fd); #endif /* ACCELEROMETER_CALIBRATION_H_ */ diff --git a/src/modules/commander/commander.cpp b/src/modules/commander/commander.cpp index 5969de6e83..7e29dbd94d 100644 --- a/src/modules/commander/commander.cpp +++ b/src/modules/commander/commander.cpp @@ -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);