|
|
|
@@ -106,10 +106,12 @@ bool VehicleAngularVelocity::UpdateSampleRate()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// calculate sensor update rate
|
|
|
|
|
if (PX4_ISFINITE(sample_rate_hz) && PX4_ISFINITE(publish_rate_hz)) {
|
|
|
|
|
if ((sample_rate_hz > 0) && PX4_ISFINITE(sample_rate_hz) && (publish_rate_hz > 0) && PX4_ISFINITE(publish_rate_hz)) {
|
|
|
|
|
// check if sample rate error is greater than 1%
|
|
|
|
|
if ((fabsf(sample_rate_hz - _filter_sample_rate_hz) / sample_rate_hz) > 0.01f) {
|
|
|
|
|
PX4_DEBUG("resetting filters, sample rate: %.3f Hz -> %.3f Hz", (double)_filter_sample_rate_hz, (double)sample_rate_hz);
|
|
|
|
|
if ((_filter_sample_rate_hz <= FLT_EPSILON) || !PX4_ISFINITE(_filter_sample_rate_hz)
|
|
|
|
|
|| (fabsf(sample_rate_hz - _filter_sample_rate_hz) / sample_rate_hz) > 0.01f) {
|
|
|
|
|
|
|
|
|
|
PX4_DEBUG("updating sample rate: %.3f Hz -> %.3f Hz", (double)_filter_sample_rate_hz, (double)sample_rate_hz);
|
|
|
|
|
_reset_filters = true;
|
|
|
|
|
_filter_sample_rate_hz = sample_rate_hz;
|
|
|
|
|
|
|
|
|
@@ -137,46 +139,46 @@ bool VehicleAngularVelocity::UpdateSampleRate()
|
|
|
|
|
_publish_interval_min_us = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_filter_sample_rate_hz > 0.f) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
return PX4_ISFINITE(_filter_sample_rate_hz) && (_filter_sample_rate_hz > 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VehicleAngularVelocity::ResetFilters()
|
|
|
|
|
void VehicleAngularVelocity::ResetFilters(float new_scale)
|
|
|
|
|
{
|
|
|
|
|
const Vector3f angular_velocity{GetResetAngularVelocity()};
|
|
|
|
|
const Vector3f angular_acceleration{GetResetAngularAcceleration()};
|
|
|
|
|
if ((_filter_sample_rate_hz > 0) && PX4_ISFINITE(_filter_sample_rate_hz)) {
|
|
|
|
|
|
|
|
|
|
for (int axis = 0; axis < 3; axis++) {
|
|
|
|
|
// angular velocity low pass
|
|
|
|
|
_lp_filter_velocity[axis].set_cutoff_frequency(_filter_sample_rate_hz, _param_imu_gyro_cutoff.get());
|
|
|
|
|
_lp_filter_velocity[axis].reset(angular_velocity(axis));
|
|
|
|
|
const Vector3f angular_velocity{GetResetAngularVelocity(new_scale)};
|
|
|
|
|
const Vector3f angular_acceleration{GetResetAngularAcceleration(new_scale)};
|
|
|
|
|
|
|
|
|
|
// angular velocity notch
|
|
|
|
|
_notch_filter_velocity[axis].setParameters(_filter_sample_rate_hz, _param_imu_gyro_nf_freq.get(),
|
|
|
|
|
_param_imu_gyro_nf_bw.get());
|
|
|
|
|
_notch_filter_velocity[axis].reset(angular_velocity(axis));
|
|
|
|
|
for (int axis = 0; axis < 3; axis++) {
|
|
|
|
|
// angular velocity low pass
|
|
|
|
|
_lp_filter_velocity[axis].set_cutoff_frequency(_filter_sample_rate_hz, _param_imu_gyro_cutoff.get());
|
|
|
|
|
_lp_filter_velocity[axis].reset(angular_velocity(axis));
|
|
|
|
|
|
|
|
|
|
// angular acceleration low pass
|
|
|
|
|
_lp_filter_acceleration[axis].set_cutoff_frequency(_filter_sample_rate_hz, _param_imu_dgyro_cutoff.get());
|
|
|
|
|
_lp_filter_acceleration[axis].reset(angular_acceleration(axis));
|
|
|
|
|
// angular velocity notch
|
|
|
|
|
_notch_filter_velocity[axis].setParameters(_filter_sample_rate_hz, _param_imu_gyro_nf_freq.get(),
|
|
|
|
|
_param_imu_gyro_nf_bw.get());
|
|
|
|
|
_notch_filter_velocity[axis].reset(angular_velocity(axis));
|
|
|
|
|
|
|
|
|
|
// angular acceleration low pass
|
|
|
|
|
_lp_filter_acceleration[axis].set_cutoff_frequency(_filter_sample_rate_hz, _param_imu_dgyro_cutoff.get());
|
|
|
|
|
_lp_filter_acceleration[axis].reset(angular_acceleration(axis));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dynamic notch filters, first disable, then force update (if available)
|
|
|
|
|
DisableDynamicNotchEscRpm();
|
|
|
|
|
DisableDynamicNotchFFT();
|
|
|
|
|
|
|
|
|
|
UpdateDynamicNotchEscRpm(new_scale, true);
|
|
|
|
|
UpdateDynamicNotchFFT(new_scale, true);
|
|
|
|
|
|
|
|
|
|
_angular_velocity_prev = angular_velocity;
|
|
|
|
|
_last_scale = new_scale;
|
|
|
|
|
|
|
|
|
|
_reset_filters = false;
|
|
|
|
|
perf_count(_filter_reset_perf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dynamic notch filters, first disable, then force update (if available)
|
|
|
|
|
DisableDynamicNotchEscRpm();
|
|
|
|
|
DisableDynamicNotchFFT();
|
|
|
|
|
|
|
|
|
|
UpdateDynamicNotchEscRpm(true);
|
|
|
|
|
UpdateDynamicNotchFFT(true);
|
|
|
|
|
|
|
|
|
|
_angular_velocity_prev = angular_velocity;
|
|
|
|
|
|
|
|
|
|
_reset_filters = false;
|
|
|
|
|
perf_count(_filter_reset_perf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VehicleAngularVelocity::SensorBiasUpdate(bool force)
|
|
|
|
@@ -224,6 +226,8 @@ bool VehicleAngularVelocity::SensorSelectionUpdate(bool force)
|
|
|
|
|
_selected_sensor_device_id = sensor_selection.gyro_device_id;
|
|
|
|
|
_calibration.set_device_id(sensor_gyro_fifo_sub.get().device_id);
|
|
|
|
|
|
|
|
|
|
_timestamp_sample_last = 0;
|
|
|
|
|
_filter_sample_rate_hz = NAN;
|
|
|
|
|
_reset_filters = true;
|
|
|
|
|
_bias.zero();
|
|
|
|
|
_fifo_available = true;
|
|
|
|
@@ -231,6 +235,8 @@ bool VehicleAngularVelocity::SensorSelectionUpdate(bool force)
|
|
|
|
|
|
|
|
|
|
perf_count(_selection_changed_perf);
|
|
|
|
|
|
|
|
|
|
PX4_DEBUG("selecting gyro FIFO %d %d", i, _selected_sensor_device_id);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -249,7 +255,8 @@ bool VehicleAngularVelocity::SensorSelectionUpdate(bool force)
|
|
|
|
|
_calibration.set_device_id(sensor_gyro_sub.get().device_id);
|
|
|
|
|
_selected_sensor_device_id = sensor_selection.gyro_device_id;
|
|
|
|
|
|
|
|
|
|
// clear bias and corrections
|
|
|
|
|
_timestamp_sample_last = 0;
|
|
|
|
|
_filter_sample_rate_hz = NAN;
|
|
|
|
|
_reset_filters = true;
|
|
|
|
|
_bias.zero();
|
|
|
|
|
_fifo_available = false;
|
|
|
|
@@ -257,6 +264,8 @@ bool VehicleAngularVelocity::SensorSelectionUpdate(bool force)
|
|
|
|
|
|
|
|
|
|
perf_count(_selection_changed_perf);
|
|
|
|
|
|
|
|
|
|
PX4_DEBUG("selecting gyro %d %d", i, _selected_sensor_device_id);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -341,29 +350,37 @@ void VehicleAngularVelocity::ParametersUpdate(bool force)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Vector3f VehicleAngularVelocity::GetResetAngularVelocity() const
|
|
|
|
|
Vector3f VehicleAngularVelocity::GetResetAngularVelocity(float new_scale) const
|
|
|
|
|
{
|
|
|
|
|
if ((_last_publish != 0) && (_last_scale > 0.f)
|
|
|
|
|
&& PX4_ISFINITE(_angular_velocity(0))
|
|
|
|
|
&& PX4_ISFINITE(_angular_velocity(1))
|
|
|
|
|
&& PX4_ISFINITE(_angular_velocity(2))) {
|
|
|
|
|
if ((_last_publish != 0) && (new_scale > 0.f)) {
|
|
|
|
|
// angular velocity filtering is performed on raw unscaled data
|
|
|
|
|
// start with last valid vehicle body frame angular velocity and compute equivalent raw data (for current sensor selection)
|
|
|
|
|
return _calibration.Uncorrect(_angular_velocity + _bias) / _last_scale;
|
|
|
|
|
Vector3f angular_velocity{_calibration.Uncorrect(_angular_velocity + _bias) / new_scale};
|
|
|
|
|
|
|
|
|
|
if (PX4_ISFINITE(angular_velocity(0))
|
|
|
|
|
&& PX4_ISFINITE(angular_velocity(1))
|
|
|
|
|
&& PX4_ISFINITE(angular_velocity(2))) {
|
|
|
|
|
|
|
|
|
|
return angular_velocity;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Vector3f{0.f, 0.f, 0.f};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Vector3f VehicleAngularVelocity::GetResetAngularAcceleration() const
|
|
|
|
|
Vector3f VehicleAngularVelocity::GetResetAngularAcceleration(float new_scale) const
|
|
|
|
|
{
|
|
|
|
|
if ((_last_publish != 0) && (_last_scale > 0.f)
|
|
|
|
|
&& PX4_ISFINITE(_angular_acceleration(0))
|
|
|
|
|
&& PX4_ISFINITE(_angular_acceleration(1))
|
|
|
|
|
&& PX4_ISFINITE(_angular_acceleration(2))) {
|
|
|
|
|
// angular acceleration filtering is performed on raw unscaled data
|
|
|
|
|
if ((_last_publish != 0) && (new_scale > 0.f)) {
|
|
|
|
|
// angular acceleration filtering is performed on unscaled angular velocity data
|
|
|
|
|
// start with last valid vehicle body frame angular acceleration and compute equivalent raw data (for current sensor selection)
|
|
|
|
|
return _calibration.rotation().I() * _angular_acceleration / _last_scale;
|
|
|
|
|
Vector3f angular_acceleration{_calibration.rotation().I() *_angular_acceleration / new_scale};
|
|
|
|
|
|
|
|
|
|
if (PX4_ISFINITE(angular_acceleration(0))
|
|
|
|
|
&& PX4_ISFINITE(angular_acceleration(1))
|
|
|
|
|
&& PX4_ISFINITE(angular_acceleration(2))) {
|
|
|
|
|
|
|
|
|
|
return angular_acceleration;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Vector3f{0.f, 0.f, 0.f};
|
|
|
|
@@ -401,7 +418,7 @@ void VehicleAngularVelocity::DisableDynamicNotchFFT()
|
|
|
|
|
#endif // !CONSTRAINED_FLASH
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VehicleAngularVelocity::UpdateDynamicNotchEscRpm(bool force)
|
|
|
|
|
void VehicleAngularVelocity::UpdateDynamicNotchEscRpm(float new_scale, bool force)
|
|
|
|
|
{
|
|
|
|
|
#if !defined(CONSTRAINED_FLASH)
|
|
|
|
|
const bool enabled = _param_imu_gyro_dyn_nf.get() & DynamicNotch::EscRpm;
|
|
|
|
@@ -434,8 +451,8 @@ void VehicleAngularVelocity::UpdateDynamicNotchEscRpm(bool force)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// only reset if there's sufficient change (> 1%)
|
|
|
|
|
if (change_percent > 0.01f) {
|
|
|
|
|
const Vector3f reset_angular_velocity{GetResetAngularVelocity()};
|
|
|
|
|
if (force || (change_percent > 0.01f)) {
|
|
|
|
|
const Vector3f reset_angular_velocity{GetResetAngularVelocity(new_scale)};
|
|
|
|
|
|
|
|
|
|
for (int axis = 0; axis < 3; axis++) {
|
|
|
|
|
auto &dnf = _dynamic_notch_filter_esc_rpm[i][harmonic][axis];
|
|
|
|
@@ -464,7 +481,7 @@ void VehicleAngularVelocity::UpdateDynamicNotchEscRpm(bool force)
|
|
|
|
|
#endif // !CONSTRAINED_FLASH
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VehicleAngularVelocity::UpdateDynamicNotchFFT(bool force)
|
|
|
|
|
void VehicleAngularVelocity::UpdateDynamicNotchFFT(float new_scale, bool force)
|
|
|
|
|
{
|
|
|
|
|
#if !defined(CONSTRAINED_FLASH)
|
|
|
|
|
const bool enabled = _param_imu_gyro_dyn_nf.get() & DynamicNotch::FFT;
|
|
|
|
@@ -488,13 +505,13 @@ void VehicleAngularVelocity::UpdateDynamicNotchFFT(bool force)
|
|
|
|
|
const float peak_diff_abs = fabsf(dnf.getNotchFreq() - peak_freq);
|
|
|
|
|
const float change_percent = peak_diff_abs / peak_freq;
|
|
|
|
|
|
|
|
|
|
if (change_percent > 0.001f) {
|
|
|
|
|
if (force || (change_percent > 0.001f)) {
|
|
|
|
|
// peak frequency changed by at least 0.1%
|
|
|
|
|
dnf.setParameters(_filter_sample_rate_hz, peak_freq, sensor_gyro_fft.resolution_hz);
|
|
|
|
|
|
|
|
|
|
// only reset if there's sufficient change
|
|
|
|
|
if (peak_diff_abs > sensor_gyro_fft.resolution_hz) {
|
|
|
|
|
dnf.reset(GetResetAngularVelocity()(axis));
|
|
|
|
|
dnf.reset(GetResetAngularVelocity(new_scale)(axis));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
perf_count(_dynamic_notch_filter_fft_update_perf);
|
|
|
|
@@ -566,22 +583,18 @@ float VehicleAngularVelocity::FilterAngularVelocity(int axis, float data[], int
|
|
|
|
|
return data[N - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float VehicleAngularVelocity::FilterAngularAcceleration(int axis, float data[], int N, float dt_s)
|
|
|
|
|
float VehicleAngularVelocity::FilterAngularAcceleration(int axis, float dt_s, float data[], int N)
|
|
|
|
|
{
|
|
|
|
|
if (N > 0) {
|
|
|
|
|
// angular acceleration: Differentiate & apply specific angular acceleration (D-term) low-pass (IMU_DGYRO_CUTOFF)
|
|
|
|
|
float delta_velocity_filtered;
|
|
|
|
|
// angular acceleration: Differentiate & apply specific angular acceleration (D-term) low-pass (IMU_DGYRO_CUTOFF)
|
|
|
|
|
float angular_acceleration_filtered = 0.f;
|
|
|
|
|
|
|
|
|
|
for (int n = 0; n < N; n++) {
|
|
|
|
|
const float delta_velocity = (data[n] - _angular_velocity_prev(axis));
|
|
|
|
|
delta_velocity_filtered = _lp_filter_acceleration[axis].apply(delta_velocity);
|
|
|
|
|
_angular_velocity_prev(axis) = data[n];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return delta_velocity_filtered / dt_s;
|
|
|
|
|
for (int n = 0; n < N; n++) {
|
|
|
|
|
const float angular_acceleration = (data[n] - _angular_velocity_prev(axis)) / dt_s;
|
|
|
|
|
angular_acceleration_filtered = _lp_filter_acceleration[axis].apply(angular_acceleration);
|
|
|
|
|
_angular_velocity_prev(axis) = data[n];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0.f;
|
|
|
|
|
return angular_acceleration_filtered;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VehicleAngularVelocity::Run()
|
|
|
|
@@ -589,12 +602,20 @@ void VehicleAngularVelocity::Run()
|
|
|
|
|
// backup schedule
|
|
|
|
|
ScheduleDelayed(10_ms);
|
|
|
|
|
|
|
|
|
|
ParametersUpdate();
|
|
|
|
|
|
|
|
|
|
// update corrections first to set _selected_sensor
|
|
|
|
|
const bool selection_updated = SensorSelectionUpdate();
|
|
|
|
|
|
|
|
|
|
_calibration.SensorCorrectionsUpdate(selection_updated);
|
|
|
|
|
SensorBiasUpdate(selection_updated);
|
|
|
|
|
ParametersUpdate();
|
|
|
|
|
|
|
|
|
|
if (selection_updated || !PX4_ISFINITE(_filter_sample_rate_hz) || (_filter_sample_rate_hz <= FLT_EPSILON)) {
|
|
|
|
|
if (!UpdateSampleRate()) {
|
|
|
|
|
// sensor sample rate required to run
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_fifo_available) {
|
|
|
|
|
// process all outstanding fifo messages
|
|
|
|
@@ -604,13 +625,9 @@ void VehicleAngularVelocity::Run()
|
|
|
|
|
const float dt_s = sensor_fifo_data.dt * 1e-6f;
|
|
|
|
|
_timestamp_sample_last = sensor_fifo_data.timestamp_sample;
|
|
|
|
|
|
|
|
|
|
// in FIFO mode the unscaled raw data is filtered, reset filters on any scale change
|
|
|
|
|
if (_reset_filters || (fabsf(sensor_fifo_data.scale - _last_scale) > FLT_EPSILON)) {
|
|
|
|
|
if (UpdateSampleRate()) {
|
|
|
|
|
// in FIFO mode the unscaled raw data is filtered
|
|
|
|
|
_last_scale = sensor_fifo_data.scale;
|
|
|
|
|
|
|
|
|
|
ResetFilters();
|
|
|
|
|
}
|
|
|
|
|
ResetFilters(sensor_fifo_data.scale);
|
|
|
|
|
|
|
|
|
|
if (_reset_filters) {
|
|
|
|
|
continue; // not safe to run until filters configured
|
|
|
|
@@ -639,14 +656,12 @@ void VehicleAngularVelocity::Run()
|
|
|
|
|
|
|
|
|
|
// save last filtered sample
|
|
|
|
|
angular_velocity_unscaled(axis) = FilterAngularVelocity(axis, data, N);
|
|
|
|
|
angular_acceleration_unscaled(axis) = FilterAngularAcceleration(axis, data, N, dt_s);
|
|
|
|
|
angular_acceleration_unscaled(axis) = FilterAngularAcceleration(axis, dt_s, data, N);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Publish
|
|
|
|
|
if (!_sensor_fifo_sub.updated()) {
|
|
|
|
|
CalibrateAndPublish(sensor_fifo_data.timestamp_sample, angular_velocity_unscaled, angular_acceleration_unscaled,
|
|
|
|
|
sensor_fifo_data.scale);
|
|
|
|
|
}
|
|
|
|
|
CalibrateAndPublish(!_sensor_fifo_sub.updated(), sensor_fifo_data.timestamp_sample, angular_velocity_unscaled,
|
|
|
|
|
angular_acceleration_unscaled, sensor_fifo_data.scale);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -655,15 +670,15 @@ void VehicleAngularVelocity::Run()
|
|
|
|
|
sensor_gyro_s sensor_data;
|
|
|
|
|
|
|
|
|
|
while (_sensor_sub.update(&sensor_data)) {
|
|
|
|
|
if (_timestamp_sample_last == 0) {
|
|
|
|
|
_timestamp_sample_last = sensor_data.timestamp_sample - 1e6f / _filter_sample_rate_hz;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const float dt_s = math::constrain(((sensor_data.timestamp_sample - _timestamp_sample_last) / 1e6f), 0.0002f, 0.02f);
|
|
|
|
|
_timestamp_sample_last = sensor_data.timestamp_sample;
|
|
|
|
|
|
|
|
|
|
if (_reset_filters) {
|
|
|
|
|
if (UpdateSampleRate()) {
|
|
|
|
|
// non-FIFO sensor data is already scaled
|
|
|
|
|
_last_scale = 1.f;
|
|
|
|
|
ResetFilters();
|
|
|
|
|
}
|
|
|
|
|
ResetFilters();
|
|
|
|
|
|
|
|
|
|
if (_reset_filters) {
|
|
|
|
|
continue; // not safe to run until filters configured
|
|
|
|
@@ -673,8 +688,8 @@ void VehicleAngularVelocity::Run()
|
|
|
|
|
UpdateDynamicNotchEscRpm();
|
|
|
|
|
UpdateDynamicNotchFFT();
|
|
|
|
|
|
|
|
|
|
Vector3f angular_velocity_unscaled;
|
|
|
|
|
Vector3f angular_acceleration_unscaled;
|
|
|
|
|
Vector3f angular_velocity;
|
|
|
|
|
Vector3f angular_acceleration;
|
|
|
|
|
|
|
|
|
|
float raw_data_array[] {sensor_data.x, sensor_data.y, sensor_data.z};
|
|
|
|
|
|
|
|
|
@@ -683,19 +698,17 @@ void VehicleAngularVelocity::Run()
|
|
|
|
|
float data[1] {raw_data_array[axis]};
|
|
|
|
|
|
|
|
|
|
// save last filtered sample
|
|
|
|
|
angular_velocity_unscaled(axis) = FilterAngularVelocity(axis, data, 1);
|
|
|
|
|
angular_acceleration_unscaled(axis) = FilterAngularAcceleration(axis, data, 1, dt_s);
|
|
|
|
|
angular_velocity(axis) = FilterAngularVelocity(axis, data);
|
|
|
|
|
angular_acceleration(axis) = FilterAngularAcceleration(axis, dt_s, data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Publish
|
|
|
|
|
if (!_sensor_sub.updated()) {
|
|
|
|
|
CalibrateAndPublish(sensor_data.timestamp_sample, angular_velocity_unscaled, angular_acceleration_unscaled);
|
|
|
|
|
}
|
|
|
|
|
CalibrateAndPublish(!_sensor_sub.updated(), sensor_data.timestamp_sample, angular_velocity, angular_acceleration);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VehicleAngularVelocity::CalibrateAndPublish(const hrt_abstime ×tamp_sample,
|
|
|
|
|
void VehicleAngularVelocity::CalibrateAndPublish(bool publish, const hrt_abstime ×tamp_sample,
|
|
|
|
|
const Vector3f &angular_velocity_unscaled, const Vector3f &angular_acceleration_unscaled, float scale)
|
|
|
|
|
{
|
|
|
|
|
// Angular velocity: rotate sensor frame to board, scale raw data to SI, apply calibration, and remove in-run estimated bias
|
|
|
|
@@ -704,7 +717,7 @@ void VehicleAngularVelocity::CalibrateAndPublish(const hrt_abstime ×tamp_sa
|
|
|
|
|
// Angular acceleration: rotate sensor frame to board, scale raw data to SI, apply any additional configured rotation
|
|
|
|
|
_angular_acceleration = _calibration.rotation() * angular_acceleration_unscaled * scale;
|
|
|
|
|
|
|
|
|
|
if (timestamp_sample >= _last_publish + _publish_interval_min_us) {
|
|
|
|
|
if (publish && (timestamp_sample >= _last_publish + _publish_interval_min_us)) {
|
|
|
|
|
|
|
|
|
|
// Publish vehicle_angular_acceleration
|
|
|
|
|
vehicle_angular_acceleration_s v_angular_acceleration;
|
|
|
|
|