From b5f6699f2eb5e5a7b33de815f436cf5c8f3f2e56 Mon Sep 17 00:00:00 2001 From: Matthias Grob Date: Mon, 26 Feb 2024 12:04:54 +0100 Subject: [PATCH] mixer_module: send a last sample out after all outputs were disabled This matters for PWM when the last output gets disabled on either FMU or IO it would just keep on running. Also when rebooting with a parameters reset or new airframe with no mapped outputs it would previously keep outputting PWM with the disarmed value of the new airframe e.g. 1000us which is a safety hazard because servos could break the physical limit of the model or miscalibrated ESCs spinning motors. --- src/lib/mixer_module/mixer_module.cpp | 5 ++++- src/lib/mixer_module/mixer_module.hpp | 1 + src/lib/mixer_module/mixer_module_tests.cpp | 8 ++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/lib/mixer_module/mixer_module.cpp b/src/lib/mixer_module/mixer_module.cpp index dc5f791af2..ee75bcf9fa 100644 --- a/src/lib/mixer_module/mixer_module.cpp +++ b/src/lib/mixer_module/mixer_module.cpp @@ -455,7 +455,8 @@ bool MixingOutput::update() } } - if (!all_disabled) { + // Send output if any function mapped or one last disabling sample + if (!all_disabled || !_was_all_disabled) { if (!_armed.armed && !_armed.manual_lockdown) { _actuator_test.overrideValues(outputs, _max_num_outputs); } @@ -463,6 +464,8 @@ bool MixingOutput::update() limitAndUpdateOutputs(outputs, has_updates); } + _was_all_disabled = all_disabled; + return true; } diff --git a/src/lib/mixer_module/mixer_module.hpp b/src/lib/mixer_module/mixer_module.hpp index c791feb103..3deaa54aa4 100644 --- a/src/lib/mixer_module/mixer_module.hpp +++ b/src/lib/mixer_module/mixer_module.hpp @@ -288,6 +288,7 @@ private: hrt_abstime _lowrate_schedule_interval{300_ms}; ActuatorTest _actuator_test{_function_assignment}; uint32_t _reversible_mask{0}; ///< per-output bits. If set, the output is configured to be reversible (motors only) + bool _was_all_disabled{false}; uORB::SubscriptionCallbackWorkItem *_subscription_callback{nullptr}; ///< current scheduling callback diff --git a/src/lib/mixer_module/mixer_module_tests.cpp b/src/lib/mixer_module/mixer_module_tests.cpp index ef48f3e3f2..3901a1c85d 100644 --- a/src/lib/mixer_module/mixer_module_tests.cpp +++ b/src/lib/mixer_module/mixer_module_tests.cpp @@ -191,11 +191,15 @@ TEST_F(MixerModuleTest, basic) mixing_output.setAllMaxValues(MAX_VALUE); EXPECT_EQ(test_module.num_updates, 0); - // all functions disabled: not expected to get an update + // all functions disabled: expect to get one single update to process disabling the output signal mixing_output.update(); mixing_output.updateSubscriptions(false); mixing_output.update(); - EXPECT_EQ(test_module.num_updates, 0); + EXPECT_EQ(test_module.num_updates, 1); + mixing_output.update(); + mixing_output.updateSubscriptions(false); + mixing_output.update(); + EXPECT_EQ(test_module.num_updates, 1); test_module.reset(); // configure motor, ensure all still disarmed