mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-16 15:13:35 +08:00
Merge remote-tracking branch 'upstream/master' into linux
Signed-off-by: Mark Charlebois <charlebm@gmail.com> Conflicts: src/modules/commander/gyro_calibration.cpp src/modules/mavlink/mavlink_ftp.cpp
This commit is contained in:
@@ -2164,10 +2164,12 @@ control_status_leds(vehicle_status_s *status_local, const actuator_armed_s *actu
|
||||
|
||||
if (set_normal_color) {
|
||||
/* set color */
|
||||
if (status_local->battery_warning == vehicle_status_s::VEHICLE_BATTERY_WARNING_LOW || status_local->failsafe) {
|
||||
if (status_local->failsafe) {
|
||||
rgbled_set_color(RGBLED_COLOR_PURPLE);
|
||||
} else if (status_local->battery_warning == vehicle_status_s::VEHICLE_BATTERY_WARNING_LOW) {
|
||||
rgbled_set_color(RGBLED_COLOR_AMBER);
|
||||
/* vehicle_status_s::VEHICLE_BATTERY_WARNING_CRITICAL handled as vehicle_status_s::ARMING_STATE_ARMED_ERROR / vehicle_status_s::ARMING_STATE_STANDBY_ERROR */
|
||||
|
||||
} else if (status_local->battery_warning == vehicle_status_s::VEHICLE_BATTERY_WARNING_CRITICAL) {
|
||||
rgbled_set_color(RGBLED_COLOR_RED);
|
||||
} else {
|
||||
if (status_local->condition_global_position_valid) {
|
||||
rgbled_set_color(RGBLED_COLOR_GREEN);
|
||||
@@ -2801,7 +2803,7 @@ void *commander_low_prio_loop(void *arg)
|
||||
need_param_autosave_timeout = 0;
|
||||
}
|
||||
|
||||
mavlink_log_info(mavlink_fd, "settings saved");
|
||||
/* do not spam MAVLink, but provide the answer / green led mechanism */
|
||||
answer_command(cmd, VEHICLE_CMD_RESULT_ACCEPTED);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -77,7 +77,7 @@ typedef struct {
|
||||
struct gyro_report gyro_report_0;
|
||||
} gyro_worker_data_t;
|
||||
|
||||
static calibrate_return gyro_calibration_worker(detect_orientation_return orientation, int cancel_sub, void* data)
|
||||
static calibrate_return gyro_calibration_worker(int cancel_sub, void* data)
|
||||
{
|
||||
gyro_worker_data_t* worker_data = (gyro_worker_data_t*)(data);
|
||||
unsigned calibration_counter[max_gyros] = { 0 };
|
||||
@@ -92,6 +92,7 @@ static calibrate_return gyro_calibration_worker(detect_orientation_return orient
|
||||
}
|
||||
|
||||
memset(&worker_data->gyro_report_0, 0, sizeof(worker_data->gyro_report_0));
|
||||
memset(&worker_data->gyro_scale, 0, sizeof(worker_data->gyro_scale));
|
||||
|
||||
/* use first gyro to pace, but count correctly per-gyro for statistics */
|
||||
while (calibration_counter[0] < calibration_count) {
|
||||
@@ -152,7 +153,7 @@ static calibrate_return gyro_calibration_worker(detect_orientation_return orient
|
||||
int do_gyro_calibration(int mavlink_fd)
|
||||
{
|
||||
int res = OK;
|
||||
gyro_worker_data_t worker_data;
|
||||
gyro_worker_data_t worker_data = {};
|
||||
|
||||
mavlink_log_info(mavlink_fd, CAL_QGC_STARTED_MSG, sensor_name);
|
||||
|
||||
@@ -199,51 +200,63 @@ int do_gyro_calibration(int mavlink_fd)
|
||||
for (unsigned s = 0; s < max_gyros; s++) {
|
||||
worker_data.gyro_sensor_sub[s] = orb_subscribe_multi(ORB_ID(sensor_gyro), s);
|
||||
}
|
||||
|
||||
int cancel_sub = calibrate_cancel_subscribe();
|
||||
|
||||
unsigned try_count = 0;
|
||||
unsigned max_tries = 20;
|
||||
res = ERROR;
|
||||
|
||||
// Calibrate right-side up
|
||||
|
||||
bool side_collected[detect_orientation_side_count] = { true, true, true, true, true, false };
|
||||
|
||||
int cancel_sub = calibrate_cancel_subscribe();
|
||||
calibrate_return cal_return = calibrate_from_orientation(mavlink_fd, // Mavlink fd to write output
|
||||
cancel_sub, // Subscription to vehicle_command for cancel support
|
||||
side_collected, // Sides to calibrate
|
||||
gyro_calibration_worker, // Calibration worker
|
||||
&worker_data, // Opaque data for calibration worked
|
||||
true); // true: lenient still detection
|
||||
do {
|
||||
// Calibrate gyro and ensure user didn't move
|
||||
calibrate_return cal_return = gyro_calibration_worker(cancel_sub, &worker_data);
|
||||
|
||||
if (cal_return == calibrate_return_cancelled) {
|
||||
// Cancel message already sent, we are done here
|
||||
res = ERROR;
|
||||
break;
|
||||
|
||||
} else if (cal_return == calibrate_return_error) {
|
||||
res = ERROR;
|
||||
|
||||
} else {
|
||||
/* check offsets */
|
||||
float xdiff = worker_data.gyro_report_0.x - worker_data.gyro_scale[0].x_offset;
|
||||
float ydiff = worker_data.gyro_report_0.y - worker_data.gyro_scale[0].y_offset;
|
||||
float zdiff = worker_data.gyro_report_0.z - worker_data.gyro_scale[0].z_offset;
|
||||
|
||||
/* maximum allowable calibration error in radians */
|
||||
const float maxoff = 0.0055f;
|
||||
|
||||
if (!isfinite(worker_data.gyro_scale[0].x_offset) ||
|
||||
!isfinite(worker_data.gyro_scale[0].y_offset) ||
|
||||
!isfinite(worker_data.gyro_scale[0].z_offset) ||
|
||||
fabsf(xdiff) > maxoff ||
|
||||
fabsf(ydiff) > maxoff ||
|
||||
fabsf(zdiff) > maxoff) {
|
||||
|
||||
mavlink_and_console_log_critical(mavlink_fd, "[cal] motion, retrying..");
|
||||
res = ERROR;
|
||||
|
||||
} else {
|
||||
res = OK;
|
||||
}
|
||||
}
|
||||
try_count++;
|
||||
|
||||
} while (res == ERROR && try_count <= max_tries);
|
||||
|
||||
if (try_count >= max_tries) {
|
||||
mavlink_and_console_log_critical(mavlink_fd, "[cal] ERROR: Motion during calibration");
|
||||
res = ERROR;
|
||||
}
|
||||
|
||||
calibrate_cancel_unsubscribe(cancel_sub);
|
||||
|
||||
for (unsigned s = 0; s < max_gyros; s++) {
|
||||
px4_close(worker_data.gyro_sensor_sub[s]);
|
||||
}
|
||||
|
||||
if (cal_return == calibrate_return_cancelled) {
|
||||
// Cancel message already sent, we are done here
|
||||
return ERROR;
|
||||
} else if (cal_return == calibrate_return_error) {
|
||||
res = ERROR;
|
||||
}
|
||||
|
||||
if (res == OK) {
|
||||
/* check offsets */
|
||||
float xdiff = worker_data.gyro_report_0.x - worker_data.gyro_scale[0].x_offset;
|
||||
float ydiff = worker_data.gyro_report_0.y - worker_data.gyro_scale[0].y_offset;
|
||||
float zdiff = worker_data.gyro_report_0.z - worker_data.gyro_scale[0].z_offset;
|
||||
|
||||
/* maximum allowable calibration error in radians */
|
||||
const float maxoff = 0.0055f;
|
||||
|
||||
if (!PX4_ISFINITE(worker_data.gyro_scale[0].x_offset) ||
|
||||
!PX4_ISFINITE(worker_data.gyro_scale[0].y_offset) ||
|
||||
!PX4_ISFINITE(worker_data.gyro_scale[0].z_offset) ||
|
||||
fabsf(xdiff) > maxoff ||
|
||||
fabsf(ydiff) > maxoff ||
|
||||
fabsf(zdiff) > maxoff) {
|
||||
mavlink_and_console_log_critical(mavlink_fd, "[cal] ERROR: Motion during calibration");
|
||||
res = ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (res == OK) {
|
||||
/* set offset parameters to new values */
|
||||
bool failed = false;
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <drivers/drv_accel.h>
|
||||
#include <drivers/drv_gyro.h>
|
||||
#include <uORB/topics/sensor_combined.h>
|
||||
#include <drivers/drv_mag.h>
|
||||
#include <mavlink/mavlink_log.h>
|
||||
@@ -196,7 +197,71 @@ static calibrate_return mag_calibration_worker(detect_orientation_return orienta
|
||||
|
||||
mavlink_and_console_log_info(worker_data->mavlink_fd, "[cal] Rotate vehicle around the detected orientation");
|
||||
mavlink_and_console_log_info(worker_data->mavlink_fd, "[cal] Continue rotation for %u seconds", worker_data->calibration_interval_perside_seconds);
|
||||
sleep(2);
|
||||
|
||||
/*
|
||||
* Detect if the system is rotating.
|
||||
*
|
||||
* We're detecting this as a general rotation on any axis, not necessary on the one we
|
||||
* asked the user for. This is because we really just need two roughly orthogonal axes
|
||||
* for a good result, so we're not constraining the user more than we have to.
|
||||
*/
|
||||
|
||||
hrt_abstime detection_deadline = hrt_absolute_time() + worker_data->calibration_interval_perside_useconds;
|
||||
hrt_abstime last_gyro = 0;
|
||||
float gyro_x_integral = 0.0f;
|
||||
float gyro_y_integral = 0.0f;
|
||||
float gyro_z_integral = 0.0f;
|
||||
|
||||
const float gyro_int_thresh_rad = 0.5f;
|
||||
|
||||
int sub_gyro = orb_subscribe(ORB_ID(sensor_gyro));
|
||||
|
||||
while (fabsf(gyro_x_integral) < gyro_int_thresh_rad &&
|
||||
fabsf(gyro_y_integral) < gyro_int_thresh_rad &&
|
||||
fabsf(gyro_z_integral) < gyro_int_thresh_rad) {
|
||||
|
||||
/* abort on request */
|
||||
if (calibrate_cancel_check(worker_data->mavlink_fd, cancel_sub)) {
|
||||
result = calibrate_return_cancelled;
|
||||
close(sub_gyro);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* abort with timeout */
|
||||
if (hrt_absolute_time() > detection_deadline) {
|
||||
result = calibrate_return_error;
|
||||
warnx("int: %8.4f, %8.4f, %8.4f", (double)gyro_x_integral, (double)gyro_y_integral, (double)gyro_z_integral);
|
||||
mavlink_and_console_log_critical(worker_data->mavlink_fd, "Failed: This calibration requires rotation.");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Wait clocking for new data on all gyro */
|
||||
struct pollfd fds[1];
|
||||
fds[0].fd = sub_gyro;
|
||||
fds[0].events = POLLIN;
|
||||
size_t fd_count = 1;
|
||||
|
||||
int poll_ret = poll(fds, fd_count, 1000);
|
||||
|
||||
if (poll_ret > 0) {
|
||||
struct gyro_report gyro;
|
||||
orb_copy(ORB_ID(sensor_gyro), sub_gyro, &gyro);
|
||||
|
||||
/* ensure we have a valid first timestamp */
|
||||
if (last_gyro > 0) {
|
||||
|
||||
/* integrate */
|
||||
float delta_t = (gyro.timestamp - last_gyro) / 1e6f;
|
||||
gyro_x_integral += gyro.x * delta_t;
|
||||
gyro_y_integral += gyro.y * delta_t;
|
||||
gyro_z_integral += gyro.z * delta_t;
|
||||
}
|
||||
|
||||
last_gyro = gyro.timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
close(sub_gyro);
|
||||
|
||||
uint64_t calibration_deadline = hrt_absolute_time() + worker_data->calibration_interval_perside_useconds;
|
||||
unsigned poll_errcount = 0;
|
||||
|
||||
Reference in New Issue
Block a user