mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-23 19:53:34 +08:00
accel & gyro calibration helpers
This commit is contained in:
@@ -33,7 +33,6 @@
|
||||
|
||||
add_subdirectory(data_validator)
|
||||
|
||||
add_subdirectory(sensor_calibration) # used by vehicle_{acceleration, angular_velocity, imu}
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_subdirectory(vehicle_acceleration)
|
||||
add_subdirectory(vehicle_angular_velocity)
|
||||
@@ -54,6 +53,7 @@ px4_add_module(
|
||||
drivers__device
|
||||
git_ecl
|
||||
mathlib
|
||||
sensor_calibration
|
||||
vehicle_acceleration
|
||||
vehicle_angular_velocity
|
||||
vehicle_air_data
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
############################################################################
|
||||
#
|
||||
# Copyright (c) 2020 PX4 Development Team. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
px4_add_library(sensor_calibration
|
||||
SensorCalibration.cpp
|
||||
SensorCalibration.hpp
|
||||
)
|
||||
target_compile_options(sensor_calibration PRIVATE ${MAX_CUSTOM_OPT_LEVEL})
|
||||
target_include_directories(sensor_calibration PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..)
|
||||
@@ -1,252 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2020 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "SensorCalibration.hpp"
|
||||
|
||||
#include <lib/parameters/param.h>
|
||||
|
||||
using namespace matrix;
|
||||
using namespace time_literals;
|
||||
using math::radians;
|
||||
|
||||
namespace sensors
|
||||
{
|
||||
|
||||
void SensorCalibration::set_device_id(uint32_t device_id)
|
||||
{
|
||||
if (_device_id != device_id) {
|
||||
_device_id = device_id;
|
||||
SensorCorrectionsUpdate(true);
|
||||
ParametersUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
matrix::Vector3f SensorCalibration::Correct(const matrix::Vector3f &data)
|
||||
{
|
||||
SensorCorrectionsUpdate();
|
||||
return _rotation * matrix::Vector3f{(data - _thermal_offset - _offset).emult(_scale)};
|
||||
}
|
||||
|
||||
const char *SensorCalibration::SensorString() const
|
||||
{
|
||||
switch (_type) {
|
||||
case SensorType::Accelerometer:
|
||||
return "ACC";
|
||||
|
||||
case SensorType::Gyroscope:
|
||||
return "GYRO";
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int SensorCalibration::FindCalibrationIndex(uint32_t device_id) const
|
||||
{
|
||||
if (device_id == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < MAX_SENSOR_COUNT; ++i) {
|
||||
char str[16] {};
|
||||
sprintf(str, "CAL_%s%u_ID", SensorString(), i);
|
||||
|
||||
int32_t device_id_val = 0;
|
||||
|
||||
if (param_get(param_find(str), &device_id_val) != OK) {
|
||||
PX4_ERR("Could not access param %s", str);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((uint32_t)device_id_val == device_id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool SensorCalibration::CalibrationEnabled(uint8_t calibration_index) const
|
||||
{
|
||||
char str[20] {};
|
||||
sprintf(str, "CAL_%s%u_EN", SensorString(), calibration_index);
|
||||
int32_t enabled_val = 1;
|
||||
param_get(param_find(str), &enabled_val);
|
||||
|
||||
return (enabled_val != 0);
|
||||
}
|
||||
|
||||
Vector3f SensorCalibration::CalibrationOffset(uint8_t calibration_index) const
|
||||
{
|
||||
// offsets (x, y, z)
|
||||
Vector3f offset{0.f, 0.f, 0.f};
|
||||
char str[20] {};
|
||||
|
||||
sprintf(str, "CAL_%s%u_XOFF", SensorString(), calibration_index);
|
||||
param_get(param_find(str), &offset(0));
|
||||
|
||||
sprintf(str, "CAL_%s%u_YOFF", SensorString(), calibration_index);
|
||||
param_get(param_find(str), &offset(1));
|
||||
|
||||
sprintf(str, "CAL_%s%u_ZOFF", SensorString(), calibration_index);
|
||||
param_get(param_find(str), &offset(2));
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
Vector3f SensorCalibration::CalibrationScale(uint8_t calibration_index) const
|
||||
{
|
||||
// scale factors (x, y, z)
|
||||
Vector3f scale{1.f, 1.f, 1.f};
|
||||
|
||||
// gyroscope doesn't have a scale factor calibration
|
||||
if (_type != SensorType::Gyroscope) {
|
||||
char str[20] {};
|
||||
|
||||
sprintf(str, "CAL_%s%u_XSCALE", SensorString(), calibration_index);
|
||||
param_get(param_find(str), &scale(0));
|
||||
|
||||
sprintf(str, "CAL_%s%u_YSCALE", SensorString(), calibration_index);
|
||||
param_get(param_find(str), &scale(1));
|
||||
|
||||
sprintf(str, "CAL_%s%u_ZSCALE", SensorString(), calibration_index);
|
||||
param_get(param_find(str), &scale(2));
|
||||
}
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
void SensorCalibration::SensorCorrectionsUpdate(bool force)
|
||||
{
|
||||
// check if the selected sensor has updated
|
||||
if (_sensor_correction_sub.updated() || force) {
|
||||
|
||||
// valid device id required
|
||||
if (_device_id == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
sensor_correction_s corrections;
|
||||
|
||||
if (_sensor_correction_sub.copy(&corrections)) {
|
||||
// find sensor_corrections index
|
||||
for (int i = 0; i < MAX_SENSOR_COUNT; i++) {
|
||||
if ((_type == SensorType::Accelerometer) && (corrections.accel_device_ids[i] == _device_id)) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
_thermal_offset = Vector3f{corrections.accel_offset_0};
|
||||
return;
|
||||
case 1:
|
||||
_thermal_offset = Vector3f{corrections.accel_offset_1};
|
||||
return;
|
||||
case 2:
|
||||
_thermal_offset = Vector3f{corrections.accel_offset_2};
|
||||
return;
|
||||
}
|
||||
|
||||
} else if ((_type == SensorType::Gyroscope) && (corrections.gyro_device_ids[i] == _device_id)) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
_thermal_offset = Vector3f{corrections.gyro_offset_0};
|
||||
return;
|
||||
case 1:
|
||||
_thermal_offset = Vector3f{corrections.gyro_offset_1};
|
||||
return;
|
||||
case 2:
|
||||
_thermal_offset = Vector3f{corrections.gyro_offset_2};
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// zero thermal offset if not found
|
||||
_thermal_offset.zero();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorCalibration::ParametersUpdate()
|
||||
{
|
||||
if (!_external) {
|
||||
// fine tune the rotation
|
||||
float x_offset = 0.f;
|
||||
float y_offset = 0.f;
|
||||
float z_offset = 0.f;
|
||||
param_get(param_find("SENS_BOARD_X_OFF"), &x_offset);
|
||||
param_get(param_find("SENS_BOARD_Y_OFF"), &y_offset);
|
||||
param_get(param_find("SENS_BOARD_Z_OFF"), &z_offset);
|
||||
|
||||
const Dcmf board_rotation_offset(Eulerf(radians(x_offset), radians(y_offset), radians(z_offset)));
|
||||
|
||||
// get transformation matrix from sensor/board to body frame
|
||||
int32_t board_rot = 0;
|
||||
param_get(param_find("SENS_BOARD_ROT"), &board_rot);
|
||||
_rotation = board_rotation_offset * get_rot_matrix((enum Rotation)board_rot);
|
||||
|
||||
} else {
|
||||
// TODO: per sensor external rotation
|
||||
_rotation.setIdentity();
|
||||
}
|
||||
|
||||
|
||||
int calibration_index = FindCalibrationIndex(_device_id);
|
||||
|
||||
if (calibration_index >= 0) {
|
||||
_enabled = CalibrationEnabled(calibration_index);
|
||||
_offset = CalibrationOffset(calibration_index);
|
||||
_scale = CalibrationScale(calibration_index);
|
||||
|
||||
} else {
|
||||
_enabled = true;
|
||||
_offset.zero();
|
||||
_scale = Vector3f{1.f, 1.f, 1.f};
|
||||
}
|
||||
}
|
||||
|
||||
void SensorCalibration::PrintStatus()
|
||||
{
|
||||
if (_type != SensorType::Gyroscope) {
|
||||
PX4_INFO("%s %d EN: %d, offset: [%.4f %.4f %.4f] scale: [%.4f %.4f %.4f]", SensorString(), _device_id, _enabled,
|
||||
(double)_offset(0), (double)_offset(1), (double)_offset(2), (double)_scale(0), (double)_scale(1), (double)_scale(2));
|
||||
|
||||
} else {
|
||||
PX4_INFO("%s %d EN: %d, offset: [%.4f %.4f %.4f]", SensorString(), _device_id, _enabled,
|
||||
(double)_offset(0), (double)_offset(1), (double)_offset(2));
|
||||
}
|
||||
|
||||
if (_thermal_offset.norm() > 0.f) {
|
||||
PX4_INFO("%s %d temperature offset: [%.4f %.4f %.4f]", SensorString(), _device_id,
|
||||
(double)_thermal_offset(0), (double)_thermal_offset(1), (double)_thermal_offset(2));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sensors
|
||||
@@ -1,106 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2020 PX4 Development Team. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <lib/conversion/rotation.h>
|
||||
#include <lib/matrix/matrix/math.hpp>
|
||||
#include <px4_platform_common/px4_config.h>
|
||||
#include <px4_platform_common/log.h>
|
||||
#include <uORB/Subscription.hpp>
|
||||
#include <uORB/topics/sensor_correction.h>
|
||||
|
||||
namespace sensors
|
||||
{
|
||||
|
||||
class SensorCalibration
|
||||
{
|
||||
public:
|
||||
|
||||
enum class SensorType : uint8_t {
|
||||
Accelerometer,
|
||||
Gyroscope,
|
||||
};
|
||||
|
||||
SensorCalibration() = delete;
|
||||
explicit SensorCalibration(SensorType type) : _type(type) {}
|
||||
~SensorCalibration() = default;
|
||||
|
||||
void PrintStatus();
|
||||
|
||||
void set_device_id(uint32_t device_id);
|
||||
void set_external(bool external = true) { _external = external; }
|
||||
|
||||
uint32_t device_id() const { return _device_id; }
|
||||
bool enabled() const { return _enabled; }
|
||||
bool external() const { return _external; }
|
||||
|
||||
// apply offsets and scale
|
||||
// rotate corrected measurements from sensor to body frame
|
||||
matrix::Vector3f Correct(const matrix::Vector3f &data);
|
||||
|
||||
void ParametersUpdate();
|
||||
void SensorCorrectionsUpdate(bool force = false);
|
||||
|
||||
const matrix::Dcmf &getBoardRotation() const { return _rotation; }
|
||||
|
||||
private:
|
||||
|
||||
static constexpr int MAX_SENSOR_COUNT = 3;
|
||||
|
||||
int FindCalibrationIndex(uint32_t device_id) const;
|
||||
|
||||
bool CalibrationEnabled(uint8_t calibration_index) const;
|
||||
matrix::Vector3f CalibrationOffset(uint8_t calibration_index) const;
|
||||
matrix::Vector3f CalibrationScale(uint8_t calibration_index) const;
|
||||
|
||||
const char *SensorString() const;
|
||||
|
||||
uORB::Subscription _sensor_correction_sub{ORB_ID(sensor_correction)};
|
||||
|
||||
matrix::Dcmf _rotation;
|
||||
|
||||
matrix::Vector3f _offset{0.f, 0.f, 0.f};
|
||||
matrix::Vector3f _scale{1.f, 1.f, 1.f};
|
||||
|
||||
matrix::Vector3f _thermal_offset{0.f, 0.f, 0.f};
|
||||
|
||||
uint32_t _device_id{0};
|
||||
|
||||
const SensorType _type;
|
||||
|
||||
bool _enabled{true};
|
||||
bool _external{false};
|
||||
};
|
||||
|
||||
} // namespace sensors
|
||||
@@ -47,12 +47,12 @@ PARAM_DEFINE_INT32(CAL_MAG_PRIME, 0);
|
||||
* recommended.
|
||||
*
|
||||
* Bits:
|
||||
* DETECT_ORIENTATION_TAIL_DOWN = 1
|
||||
* DETECT_ORIENTATION_NOSE_DOWN = 2
|
||||
* DETECT_ORIENTATION_LEFT = 4
|
||||
* DETECT_ORIENTATION_RIGHT = 8
|
||||
* DETECT_ORIENTATION_UPSIDE_DOWN = 16
|
||||
* DETECT_ORIENTATION_RIGHTSIDE_UP = 32
|
||||
* ORIENTATION_TAIL_DOWN = 1
|
||||
* ORIENTATION_NOSE_DOWN = 2
|
||||
* ORIENTATION_LEFT = 4
|
||||
* ORIENTATION_RIGHT = 8
|
||||
* ORIENTATION_UPSIDE_DOWN = 16
|
||||
* ORIENTATION_RIGHTSIDE_UP = 32
|
||||
*
|
||||
* @min 34
|
||||
* @max 63
|
||||
|
||||
@@ -41,6 +41,6 @@ target_compile_options(vehicle_acceleration PRIVATE ${MAX_CUSTOM_OPT_LEVEL})
|
||||
target_link_libraries(vehicle_acceleration
|
||||
PRIVATE
|
||||
mathlib
|
||||
sensor_calibration
|
||||
px4_work_queue
|
||||
sensor_calibration
|
||||
)
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sensor_calibration/SensorCalibration.hpp>
|
||||
|
||||
#include <lib/sensor_calibration/Accelerometer.hpp>
|
||||
#include <lib/mathlib/math/Limits.hpp>
|
||||
#include <lib/matrix/matrix/math.hpp>
|
||||
#include <lib/mathlib/math/filter/LowPassFilter2pVector3f.hpp>
|
||||
@@ -88,7 +87,7 @@ private:
|
||||
{this, ORB_ID(sensor_accel), 2}
|
||||
};
|
||||
|
||||
SensorCalibration _calibration{SensorCalibration::SensorType::Accelerometer};
|
||||
calibration::Accelerometer _calibration{};
|
||||
|
||||
matrix::Vector3f _bias{0.f, 0.f, 0.f};
|
||||
|
||||
|
||||
@@ -41,6 +41,6 @@ target_compile_options(vehicle_angular_velocity PRIVATE ${MAX_CUSTOM_OPT_LEVEL})
|
||||
target_link_libraries(vehicle_angular_velocity
|
||||
PRIVATE
|
||||
mathlib
|
||||
sensor_calibration
|
||||
px4_work_queue
|
||||
sensor_calibration
|
||||
)
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sensor_calibration/SensorCalibration.hpp>
|
||||
|
||||
#include <lib/sensor_calibration/Gyroscope.hpp>
|
||||
#include <lib/mathlib/math/Limits.hpp>
|
||||
#include <lib/matrix/matrix/math.hpp>
|
||||
#include <lib/mathlib/math/filter/LowPassFilter2pVector3f.hpp>
|
||||
@@ -91,7 +90,7 @@ private:
|
||||
{this, ORB_ID(sensor_gyro), 2}
|
||||
};
|
||||
|
||||
SensorCalibration _calibration{SensorCalibration::SensorType::Gyroscope};
|
||||
calibration::Gyroscope _calibration{};
|
||||
|
||||
matrix::Vector3f _bias{0.f, 0.f, 0.f};
|
||||
|
||||
|
||||
@@ -38,4 +38,4 @@ px4_add_library(vehicle_imu
|
||||
VehicleIMU.hpp
|
||||
)
|
||||
target_compile_options(vehicle_imu PRIVATE ${MAX_CUSTOM_OPT_LEVEL})
|
||||
target_link_libraries(vehicle_imu PRIVATE sensor_calibration px4_work_queue)
|
||||
target_link_libraries(vehicle_imu PRIVATE px4_work_queue sensor_calibration)
|
||||
|
||||
@@ -191,6 +191,11 @@ void VehicleIMU::Run()
|
||||
|
||||
ParametersUpdate();
|
||||
|
||||
if (!_accel_calibration.enabled() || !_gyro_calibration.enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool sensor_data_gap = false;
|
||||
bool update_integrator_config = false;
|
||||
bool publish_status = false;
|
||||
@@ -269,7 +274,7 @@ void VehicleIMU::Run()
|
||||
if (accel.clip_counter[0] > 0 || accel.clip_counter[1] > 0 || accel.clip_counter[2] > 0) {
|
||||
|
||||
// rotate sensor clip counts into vehicle body frame
|
||||
const Vector3f clipping{_accel_calibration.getBoardRotation() *
|
||||
const Vector3f clipping{_accel_calibration.rotation() *
|
||||
Vector3f{(float)accel.clip_counter[0], (float)accel.clip_counter[1], (float)accel.clip_counter[2]}};
|
||||
|
||||
// round to get reasonble clip counts per axis (after board rotation)
|
||||
@@ -332,42 +337,45 @@ void VehicleIMU::Run()
|
||||
if (_accel_integrator.reset(delta_velocity, accel_integral_dt)
|
||||
&& _gyro_integrator.reset(delta_angle, gyro_integral_dt)) {
|
||||
|
||||
// delta angle: apply offsets, scale, and board rotation
|
||||
_gyro_calibration.SensorCorrectionsUpdate();
|
||||
const float gyro_dt_inv = 1.e6f / gyro_integral_dt;
|
||||
const Vector3f delta_angle_corrected{_gyro_calibration.Correct(delta_angle * gyro_dt_inv) / gyro_dt_inv};
|
||||
if (_accel_calibration.enabled() && _gyro_calibration.enabled()) {
|
||||
|
||||
// delta velocity: apply offsets, scale, and board rotation
|
||||
_accel_calibration.SensorCorrectionsUpdate();
|
||||
const float accel_dt_inv = 1.e6f / accel_integral_dt;
|
||||
Vector3f delta_velocity_corrected{_accel_calibration.Correct(delta_velocity * accel_dt_inv) / accel_dt_inv};
|
||||
// delta angle: apply offsets, scale, and board rotation
|
||||
_gyro_calibration.SensorCorrectionsUpdate();
|
||||
const float gyro_dt_inv = 1.e6f / gyro_integral_dt;
|
||||
const Vector3f delta_angle_corrected{_gyro_calibration.Correct(delta_angle * gyro_dt_inv) / gyro_dt_inv};
|
||||
|
||||
UpdateAccelVibrationMetrics(delta_velocity_corrected);
|
||||
UpdateGyroVibrationMetrics(delta_angle_corrected);
|
||||
// delta velocity: apply offsets, scale, and board rotation
|
||||
_accel_calibration.SensorCorrectionsUpdate();
|
||||
const float accel_dt_inv = 1.e6f / accel_integral_dt;
|
||||
Vector3f delta_velocity_corrected{_accel_calibration.Correct(delta_velocity * accel_dt_inv) / accel_dt_inv};
|
||||
|
||||
// vehicle_imu_status
|
||||
// publish before vehicle_imu so that error counts are available synchronously if needed
|
||||
if (publish_status || (hrt_elapsed_time(&_status.timestamp) >= 100_ms)) {
|
||||
_status.accel_device_id = _accel_calibration.device_id();
|
||||
_status.gyro_device_id = _gyro_calibration.device_id();
|
||||
_status.timestamp = hrt_absolute_time();
|
||||
_vehicle_imu_status_pub.publish(_status);
|
||||
UpdateAccelVibrationMetrics(delta_velocity_corrected);
|
||||
UpdateGyroVibrationMetrics(delta_angle_corrected);
|
||||
|
||||
// vehicle_imu_status
|
||||
// publish before vehicle_imu so that error counts are available synchronously if needed
|
||||
if (publish_status || (hrt_elapsed_time(&_status.timestamp) >= 100_ms)) {
|
||||
_status.accel_device_id = _accel_calibration.device_id();
|
||||
_status.gyro_device_id = _gyro_calibration.device_id();
|
||||
_status.timestamp = hrt_absolute_time();
|
||||
_vehicle_imu_status_pub.publish(_status);
|
||||
}
|
||||
|
||||
|
||||
// publish vehicle_imu
|
||||
vehicle_imu_s imu;
|
||||
imu.timestamp_sample = _last_timestamp_sample_gyro;
|
||||
imu.accel_device_id = _accel_calibration.device_id();
|
||||
imu.gyro_device_id = _gyro_calibration.device_id();
|
||||
delta_angle_corrected.copyTo(imu.delta_angle);
|
||||
delta_velocity_corrected.copyTo(imu.delta_velocity);
|
||||
imu.delta_angle_dt = gyro_integral_dt;
|
||||
imu.delta_velocity_dt = accel_integral_dt;
|
||||
imu.delta_velocity_clipping = _delta_velocity_clipping;
|
||||
imu.timestamp = hrt_absolute_time();
|
||||
_vehicle_imu_pub.publish(imu);
|
||||
}
|
||||
|
||||
|
||||
// publish vehicle_imu
|
||||
vehicle_imu_s imu;
|
||||
imu.timestamp_sample = _last_timestamp_sample_gyro;
|
||||
imu.accel_device_id = _accel_calibration.device_id();
|
||||
imu.gyro_device_id = _gyro_calibration.device_id();
|
||||
delta_angle_corrected.copyTo(imu.delta_angle);
|
||||
delta_velocity_corrected.copyTo(imu.delta_velocity);
|
||||
imu.delta_angle_dt = gyro_integral_dt;
|
||||
imu.delta_velocity_dt = accel_integral_dt;
|
||||
imu.delta_velocity_clipping = _delta_velocity_clipping;
|
||||
imu.timestamp = hrt_absolute_time();
|
||||
_vehicle_imu_pub.publish(imu);
|
||||
|
||||
// reset clip counts
|
||||
_delta_velocity_clipping = 0;
|
||||
|
||||
|
||||
@@ -35,11 +35,11 @@
|
||||
|
||||
#include "Integrator.hpp"
|
||||
|
||||
#include <sensor_calibration/SensorCalibration.hpp>
|
||||
|
||||
#include <lib/mathlib/math/Limits.hpp>
|
||||
#include <lib/matrix/matrix/math.hpp>
|
||||
#include <lib/perf/perf_counter.h>
|
||||
#include <lib/sensor_calibration/Accelerometer.hpp>
|
||||
#include <lib/sensor_calibration/Gyroscope.hpp>
|
||||
#include <px4_platform_common/log.h>
|
||||
#include <px4_platform_common/module_params.h>
|
||||
#include <px4_platform_common/px4_config.h>
|
||||
@@ -91,8 +91,8 @@ private:
|
||||
uORB::SubscriptionCallbackWorkItem _sensor_accel_sub;
|
||||
uORB::SubscriptionCallbackWorkItem _sensor_gyro_sub;
|
||||
|
||||
SensorCalibration _accel_calibration{SensorCalibration::SensorType::Accelerometer};
|
||||
SensorCalibration _gyro_calibration{SensorCalibration::SensorType::Gyroscope};
|
||||
calibration::Accelerometer _accel_calibration{};
|
||||
calibration::Gyroscope _gyro_calibration{};
|
||||
|
||||
Integrator _accel_integrator{}; // 200 Hz default
|
||||
Integrator _gyro_integrator{true}; // 200 Hz default, coning compensation enabled
|
||||
|
||||
Reference in New Issue
Block a user