refactor(rate_control): replace gain compression template with setters (#28910)

Templating GainCompression3d on its parameter IDs made the compiler emit
every method twice on boards that build both the fixed-wing and the
multicopter rate controller, as each instantiation is a separate class.
Inlining does not remove the duplicate because update() is too large to
be inlined.

Make GainCompression3d a plain class configured through setters and let
each rate controller own its FW_GC_* or MC_GC_* parameters. This saves
1040 bytes of flash on px4_fmu-v6x_default with no change in behaviour.

Assisted-by: Claude:claude-opus-5-5

Signed-off-by: Andrea Bernasconi <andrea.bernasconi@auterion.com>
This commit is contained in:
Andrea Bernasconi
2026-09-29 19:09:12 +02:00
committed by GitHub
parent e40501eba0
commit 80e494bb79
6 changed files with 30 additions and 40 deletions
+6 -16
View File
@@ -36,15 +36,12 @@
using matrix::Vector3f;
using namespace time_literals;
template<px4::params ParamEnable, px4::params ParamGainMin>
GainCompression3dT<ParamEnable, ParamGainMin>::GainCompression3dT(ModuleParams *parent) : ModuleParams(parent)
GainCompression3d::GainCompression3d()
{
updateParams();
_gain_compression_pub.advertise();
}
template<px4::params ParamEnable, px4::params ParamGainMin>
void GainCompression3dT<ParamEnable, ParamGainMin>::reset()
void GainCompression3d::reset()
{
for (unsigned i = 0; i < 3; i++) {
_compression_gains[i].reset();
@@ -53,20 +50,16 @@ void GainCompression3dT<ParamEnable, ParamGainMin>::reset()
_gains.setOne();
}
template<px4::params ParamEnable, px4::params ParamGainMin>
void GainCompression3dT<ParamEnable, ParamGainMin>::updateParams()
void GainCompression3d::setCompressionGainMin(const float gain_min)
{
ModuleParams::updateParams();
for (unsigned i = 0; i < 3; i++) {
_compression_gains[i].setCompressionGainMin(_param_gc_gain_min.get());
_compression_gains[i].setCompressionGainMin(gain_min);
}
}
template<px4::params ParamEnable, px4::params ParamGainMin>
void GainCompression3dT<ParamEnable, ParamGainMin>::update(const Vector3f &input, const float dt)
void GainCompression3d::update(const Vector3f &input, const float dt)
{
if (!_param_gc_en.get()) {
if (!_enabled) {
reset();
return;
}
@@ -99,9 +92,6 @@ void GainCompression3dT<ParamEnable, ParamGainMin>::update(const Vector3f &input
}
}
template class GainCompression3dT<px4::params::FW_GC_EN, px4::params::FW_GC_GAIN_MIN>;
template class GainCompression3dT<px4::params::MC_GC_EN, px4::params::MC_GC_GAIN_MIN>;
float GainCompression::update(const float input, const float dt)
{
if (!PX4_ISFINITE(input)) {
+9 -21
View File
@@ -44,11 +44,12 @@
#pragma once
// PX4 includes
#include <px4_platform_common/module_params.h>
#include <drivers/drv_hrt.h>
// Libraries
#include <math.h>
#include <lib/mathlib/math/filter/AlphaFilter.hpp>
#include <matrix/matrix/math.hpp>
// uORB includes
#include <uORB/Publication.hpp>
@@ -93,25 +94,18 @@ private:
};
/*
* Templated on the enable and minimum gain parameter IDs so that the same
* implementation can be used by the fixed-wing and multicopter rate controllers
* with their own set of parameters.
*/
template<px4::params ParamEnable, px4::params ParamGainMin>
class GainCompression3dT : public ModuleParams
class GainCompression3d
{
public:
GainCompression3dT(ModuleParams *parent);
~GainCompression3dT() = default;
GainCompression3d();
~GainCompression3d() = default;
void reset();
void update(const matrix::Vector3f &input, float dt);
const matrix::Vector3f &getGains() const { return _gains; };
protected:
void updateParams() override;
void setEnabled(bool enabled) { _enabled = enabled; }
void setCompressionGainMin(float gain_min);
private:
// uORB publications
@@ -120,16 +114,10 @@ private:
GainCompression _compression_gains[3];
matrix::Vector3f _gains{1.f, 1.f, 1.f};
bool _enabled{false};
hrt_abstime _time_last_publication{0};
static constexpr float _kLpfCutoffFrequency{5.f}; // Just above the control bandwidth of most UAVs
static constexpr float _kHpfCutoffFrequency{2.f * _kLpfCutoffFrequency}; // 1 Octave above LPF cutoff, as recommended by the reference paper
DEFINE_PARAMETERS(
(ParamBool<ParamEnable>) _param_gc_en,
(ParamFloat<ParamGainMin>) _param_gc_gain_min
)
};
using GainCompression3d = GainCompression3dT<px4::params::FW_GC_EN, px4::params::FW_GC_GAIN_MIN>;
using GainCompression3dMc = GainCompression3dT<px4::params::MC_GC_EN, px4::params::MC_GC_GAIN_MIN>;
@@ -85,6 +85,9 @@ FixedwingRateControl::parameters_update()
_rate_control.setIntegratorLimit(
Vector3f(_param_fw_rr_imax.get(), _param_fw_pr_imax.get(), _param_fw_yr_imax.get()));
_gain_compression.setEnabled(_param_fw_gc_en.get());
_gain_compression.setCompressionGainMin(_param_fw_gc_gain_min.get());
if (_handle_param_vt_fw_difthr_en != PARAM_INVALID) {
param_get(_handle_param_vt_fw_difthr_en, &_param_vt_fw_difthr_en);
}
@@ -186,6 +186,9 @@ private:
(ParamFloat<px4::params::FW_DTRIM_Y_VMAX>) _param_fw_dtrim_y_vmax,
(ParamFloat<px4::params::FW_DTRIM_Y_VMIN>) _param_fw_dtrim_y_vmin,
(ParamBool<px4::params::FW_GC_EN>) _param_fw_gc_en,
(ParamFloat<px4::params::FW_GC_GAIN_MIN>) _param_fw_gc_gain_min,
(ParamFloat<px4::params::FW_MAN_P_SC>) _param_fw_man_p_sc,
(ParamFloat<px4::params::FW_MAN_R_SC>) _param_fw_man_r_sc,
(ParamFloat<px4::params::FW_MAN_Y_SC>) _param_fw_man_y_sc,
@@ -218,7 +221,7 @@ private:
)
RateControl _rate_control; ///< class for rate control calculations
GainCompression3d _gain_compression{this};
GainCompression3d _gain_compression;
void updateActuatorControlsStatus(float dt);
@@ -93,6 +93,9 @@ MulticopterRateControl::parameters_updated()
_rate_control.setFeedForwardGain(
Vector3f(_param_mc_rollrate_ff.get(), _param_mc_pitchrate_ff.get(), _param_mc_yawrate_ff.get()));
_gain_compression.setEnabled(_param_mc_gc_en.get());
_gain_compression.setCompressionGainMin(_param_mc_gc_gain_min.get());
// manual rate control acro mode rate limits
_acro_rate_max = Vector3f(radians(_param_mc_acro_r_max.get()), radians(_param_mc_acro_p_max.get()),
@@ -94,7 +94,7 @@ private:
void updateActuatorControlsStatus(const vehicle_torque_setpoint_s &vehicle_torque_setpoint, float dt);
RateControl _rate_control; ///< class for rate control calculations
GainCompression3dMc _gain_compression{this}; ///< reduces the loop gain when an oscillation is detected
GainCompression3d _gain_compression; ///< reduces the loop gain when an oscillation is detected
uORB::Subscription _battery_status_sub{ORB_ID(battery_status)};
uORB::Subscription _control_allocator_status_sub{ORB_ID(control_allocator_status)};
@@ -167,6 +167,9 @@ private:
(ParamFloat<px4::params::MC_ACRO_SUPEXPO>) _param_mc_acro_supexpo, /**< superexpo stick curve shape (roll & pitch) */
(ParamFloat<px4::params::MC_ACRO_SUPEXPOY>) _param_mc_acro_supexpoy, /**< superexpo stick curve shape (yaw) */
(ParamBool<px4::params::MC_BAT_SCALE_EN>) _param_mc_bat_scale_en
(ParamBool<px4::params::MC_BAT_SCALE_EN>) _param_mc_bat_scale_en,
(ParamBool<px4::params::MC_GC_EN>) _param_mc_gc_en,
(ParamFloat<px4::params::MC_GC_GAIN_MIN>) _param_mc_gc_gain_min
)
};