fix(mixer_module): change MixingOutput to use float outputs (#26724)

* refactor(mixer_module): change MixingOutput to use float outputs

MixingOutput now passes float values to output drivers instead of
uint16_t. This removes the need for the 8192 offset encoding and
allows reversible motors to receive negative values directly.

* fix(mixer_module): fix float safety issues

-EscClient and voxl2_io: replace outputs[i] with fabs(outputs[i]) > 0.fto fix compilation issues
-GZMixingInterface: add explicit double cast to prevent compilation error
-PWMSim: replaced unit16 cast with lroundf given that now motors outputs can be negative and casting a negative float to unit16 is undefinder behaviour
-mixer_module: same fix of PWM (unit126 cast on negative float is undefined behaviour)

* refactor(mixer_module): float rounding suggestions

* fix(pwm_sim): fix inverted disarmed condition

* fix(mixer_module): more float rounding improvements

* fix(mixer_module_tests): use casting method which are now in drivers for rounding tests

---------

Co-authored-by: Matthias Grob <maetugr@gmail.com>
This commit is contained in:
Gennaro Guidone
2026-03-16 14:59:53 -08:00
committed by GitHub
co-authored by Matthias Grob
parent 26c9ca115f
commit 00b27c56a8
39 changed files with 142 additions and 176 deletions
+8 -6
View File
@@ -155,8 +155,7 @@ public:
uint16_t system_status() const { return _status; }
bool updateOutputs(uint16_t outputs[MAX_ACTUATORS], unsigned num_outputs,
unsigned num_control_groups_updated) override;
bool updateOutputs(float outputs[MAX_ACTUATORS], unsigned num_outputs, unsigned num_control_groups_updated) override;
private:
void Run() override;
@@ -364,19 +363,22 @@ PX4IO::~PX4IO()
perf_free(_interface_write_perf);
}
bool PX4IO::updateOutputs(uint16_t outputs[MAX_ACTUATORS],
unsigned num_outputs, unsigned num_control_groups_updated)
bool PX4IO::updateOutputs(float outputs[MAX_ACTUATORS], unsigned num_outputs, unsigned num_control_groups_updated)
{
uint16_t hw_outputs[MAX_ACTUATORS] {};
for (size_t i = 0; i < num_outputs; i++) {
if (!_mixing_output.isFunctionSet(i)) {
// do not run any signal on disabled channels
outputs[i] = 0;
}
hw_outputs[i] = static_cast<uint16_t>(lroundf(outputs[i]));
}
if (!_test_fmu_fail) {
/* output to the servos */
io_reg_set(PX4IO_PAGE_DIRECT_PWM, 0, outputs, num_outputs);
io_reg_set(PX4IO_PAGE_DIRECT_PWM, 0, hw_outputs, num_outputs);
}
return true;
@@ -504,7 +506,7 @@ void PX4IO::updateFailsafe()
uint16_t values[PX4IO_MAX_ACTUATORS] {};
for (unsigned i = 0; i < _max_actuators; i++) {
values[i] = _mixing_output.actualFailsafeValue(i);
values[i] = static_cast<uint16_t>(lroundf(_mixing_output.actualFailsafeValue(i)));
}
io_reg_set(PX4IO_PAGE_FAILSAFE_PWM, 0, values, _max_actuators);