Skip to content

Commit 028bf97

Browse files
committed
In hover mode, change the tailsitter's angular velocity control from the FW controller to the MC controller,
add a parameter to disable a specified control surface, and support switching the control effect matrix during flight mode transitions.
1 parent c0c265c commit 028bf97

File tree

4 files changed

+76
-4
lines changed

4 files changed

+76
-4
lines changed

src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessTailsitterVTOL.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,24 @@ using namespace matrix;
4444
ActuatorEffectivenessTailsitterVTOL::ActuatorEffectivenessTailsitterVTOL(ModuleParams *parent)
4545
: ModuleParams(parent), _mc_rotors(this), _control_surfaces(this)
4646
{
47+
_param_handles.vt_elev_mc_lock = param_find("VT_ELEV_MC_LOCK");
48+
_param_handles.vt_ts_cs_hvr_dis = param_find("VT_TS_CS_HVR_DIS");
49+
updateParams();
4750
setFlightPhase(FlightPhase::HOVER_FLIGHT);
4851
}
52+
53+
void ActuatorEffectivenessTailsitterVTOL::updateParams()
54+
{
55+
ModuleParams::updateParams();
56+
param_get(_param_handles.vt_elev_mc_lock, &_param_vt_elev_mc_lock);
57+
param_get(_param_handles.vt_ts_cs_hvr_dis, &_param_vt_ts_cs_hvr_dis);
58+
}
59+
4960
bool
5061
ActuatorEffectivenessTailsitterVTOL::getEffectivenessMatrix(Configuration &configuration,
5162
EffectivenessUpdateReason external_update)
5263
{
53-
if (external_update == EffectivenessUpdateReason::NO_EXTERNAL_UPDATE) {
64+
if (!_control_surfaces_updated && external_update == EffectivenessUpdateReason::NO_EXTERNAL_UPDATE) {
5465
return false;
5566
}
5667

@@ -65,6 +76,23 @@ ActuatorEffectivenessTailsitterVTOL::getEffectivenessMatrix(Configuration &confi
6576
_first_control_surface_idx = configuration.num_actuators_matrix[configuration.selected_matrix];
6677
const bool surfaces_added_successfully = _control_surfaces.addActuators(configuration);
6778

79+
// In HOVER_FLIGHT, selectively disable control surfaces based on VT_TS_CS_HVR_DIS bitmask.
80+
// This only takes effect when VT_ELEV_MC_LOCK=0 (control surfaces unlocked in hover).
81+
if (surfaces_added_successfully && _flight_phase == FlightPhase::HOVER_FLIGHT && _param_vt_elev_mc_lock == 0) {
82+
// VT_TS_CS_HVR_DIS: bit=1 means disabled in hover, bit=0 means enabled (default)
83+
for (int i = 0; i < _control_surfaces.count(); i++) {
84+
if ((_param_vt_ts_cs_hvr_dis & (1 << i)) != 0) {
85+
// Set the corresponding column in effectiveness matrix to zero
86+
for (int row = 0; row < NUM_AXES; row++) {
87+
configuration.effectiveness_matrices[1](row, _first_control_surface_idx + i) = 0.f;
88+
}
89+
}
90+
}
91+
}
92+
93+
// Reset flag after update
94+
_control_surfaces_updated = false;
95+
6896
return (mc_rotors_added_successfully && surfaces_added_successfully);
6997
}
7098

@@ -104,6 +132,9 @@ void ActuatorEffectivenessTailsitterVTOL::setFlightPhase(const FlightPhase &flig
104132

105133
ActuatorEffectiveness::setFlightPhase(flight_phase);
106134

135+
// Trigger control surfaces matrix update when transitioning between HOVER_FLIGHT and other flight phases.
136+
_control_surfaces_updated = true;
137+
107138
// update stopped motors
108139
switch (flight_phase) {
109140
case FlightPhase::FORWARD_FLIGHT:

src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessTailsitterVTOL.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class ActuatorEffectivenessTailsitterVTOL : public ModuleParams, public Actuator
7575
void updateSetpoint(const matrix::Vector<float, NUM_AXES> &control_sp, int matrix_index, ActuatorVector &actuator_sp,
7676
const ActuatorVector &actuator_min, const ActuatorVector &actuator_max) override;
7777

78+
void updateParams() override;
7879

7980
void setFlightPhase(const FlightPhase &flight_phase) override;
8081

@@ -88,6 +89,16 @@ class ActuatorEffectivenessTailsitterVTOL : public ModuleParams, public Actuator
8889

8990
int _first_control_surface_idx{0}; ///< applies to matrix 1
9091

92+
struct ParamHandles {
93+
param_t vt_elev_mc_lock;
94+
param_t vt_ts_cs_hvr_dis;
95+
} _param_handles{};
96+
97+
int32_t _param_vt_elev_mc_lock{1}; ///< Lock control surfaces in hover (default: locked)
98+
int32_t _param_vt_ts_cs_hvr_dis{0}; ///< Bitmask to disable specific surfaces in hover (only effective when VT_ELEV_MC_LOCK=0)
99+
100+
bool _control_surfaces_updated{false}; ///< flag to trigger matrix update when flight phase changes
101+
91102
uORB::Subscription _flaps_setpoint_sub{ORB_ID(flaps_setpoint)};
92103
uORB::Subscription _spoilers_setpoint_sub{ORB_ID(spoilers_setpoint)};
93104
};

src/modules/vtol_att_control/tailsitter.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ void Tailsitter::fill_actuator_outputs()
284284
_thrust_setpoint_1->xyz[1] = 0.f;
285285
_thrust_setpoint_1->xyz[2] = 0.f;
286286

287-
// Motors
287+
// Motors: Generating force and torque (optional for FW_MODE)
288288
if (_vtol_mode == vtol_mode::FW_MODE) {
289289

290290
_thrust_setpoint_0->xyz[2] = -_vehicle_thrust_setpoint_virtual_fw->xyz[0];
@@ -325,8 +325,15 @@ void Tailsitter::fill_actuator_outputs()
325325
_torque_setpoint_0->xyz[2] = _vehicle_torque_setpoint_virtual_mc->xyz[2];
326326
}
327327

328-
// Control surfaces
329-
if (!_param_vt_elev_mc_lock.get() || _vtol_mode != vtol_mode::MC_MODE) {
328+
// Control surfaces: Generating torque (optional for MC_MODE)
329+
// VT_ELEV_MC_LOCK=0 enables control surfaces in hover, VT_TS_CS_HVR_DIS can still
330+
// selectively disable individual surfaces (e.g., those outside propeller slipstream).
331+
if (!_param_vt_elev_mc_lock.get() && _vtol_mode == vtol_mode::MC_MODE) {
332+
// Specific surface masking handled in ActuatorEffectivenessTailsitterVTOL.
333+
_torque_setpoint_1->xyz[0] = _vehicle_torque_setpoint_virtual_mc->xyz[0];
334+
_torque_setpoint_1->xyz[1] = _vehicle_torque_setpoint_virtual_mc->xyz[1];
335+
_torque_setpoint_1->xyz[2] = _vehicle_torque_setpoint_virtual_mc->xyz[2];
336+
} else {
330337
_torque_setpoint_1->xyz[0] = _vehicle_torque_setpoint_virtual_fw->xyz[0];
331338
_torque_setpoint_1->xyz[1] = _vehicle_torque_setpoint_virtual_fw->xyz[1];
332339
_torque_setpoint_1->xyz[2] = _vehicle_torque_setpoint_virtual_fw->xyz[2];

src/modules/vtol_att_control/vtol_att_control_params.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,3 +393,26 @@ PARAM_DEFINE_FLOAT(VT_LND_PITCH_MIN, 0.0f);
393393
* @group VTOL Attitude Control
394394
*/
395395
PARAM_DEFINE_FLOAT(VT_SPOILER_MC_LD, 0.f);
396+
397+
/**
398+
* Tailsitter: Disable control surfaces in hover mode
399+
*
400+
* Bitmask to disable specific control surfaces for attitude control in hover.
401+
* Set the bit to 1 to disable the corresponding surface (e.g., surfaces outside
402+
* propeller slipstream). Default 0 means all surfaces enabled.
403+
*
404+
* Only takes effect when VT_ELEV_MC_LOCK=0.
405+
*
406+
* @min 0
407+
* @max 255
408+
* @bit 0 Surface 0 (CA_SV_CS0)
409+
* @bit 1 Surface 1 (CA_SV_CS1)
410+
* @bit 2 Surface 2 (CA_SV_CS2)
411+
* @bit 3 Surface 3 (CA_SV_CS3)
412+
* @bit 4 Surface 4 (CA_SV_CS4)
413+
* @bit 5 Surface 5 (CA_SV_CS5)
414+
* @bit 6 Surface 6 (CA_SV_CS6)
415+
* @bit 7 Surface 7 (CA_SV_CS7)
416+
* @group VTOL Attitude Control
417+
*/
418+
PARAM_DEFINE_INT32(VT_TS_CS_HVR_DIS, 0);

0 commit comments

Comments
 (0)