[control allocator] Enhance Tailsitter control allocation to support more complex drone configurations#26320
Conversation
64ecee2 to
2024ea1
Compare
2024ea1 to
5b86eb2
Compare
|
Could you please help me find a reviewer? @farhangnaderi |
8009edc to
028bf97
Compare
028bf97 to
f55e314
Compare
8594814 to
fd252be
Compare
|
@mengchaoheng How can I test this? |
… hover, add parameter to disable specified control surfaces, and update control effectiveness matrix during flight mode transitions
fd252be to
d5db2d9
Compare
There was a problem hiding this comment.
Pull request overview
This pull request enhances tailsitter control allocation to support more complex drone configurations, specifically addressing the need to use different control effectiveness matrices for different flight modes and to selectively disable control surfaces in hover mode.
Changes:
- Switches tailsitter angular velocity control in hover mode from the fixed-wing (FW) controller to the multicopter (MC) controller when VT_ELEV_MC_LOCK=0
- Adds a new parameter VT_TS_CS_HVR_DIS to selectively disable specific control surfaces in hover mode (e.g., surfaces outside propeller slipstream)
- Implements dynamic control effectiveness matrix updates based on flight phase transitions
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/modules/vtol_att_control/vtol_att_control_params.c | Defines new bitmask parameter VT_TS_CS_HVR_DIS to disable specific control surfaces in hover mode |
| src/modules/vtol_att_control/tailsitter.cpp | Modifies control surface torque assignment logic to use MC controller in hover when surfaces are unlocked |
| src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessTailsitterVTOL.hpp | Adds parameter handles, cached parameter values, and update flag for dynamic matrix updates |
| src/modules/control_allocator/VehicleActuatorEffectiveness/ActuatorEffectivenessTailsitterVTOL.cpp | Implements parameter handling, effectiveness matrix modification based on flight phase, and matrix update triggering |
Comments suppressed due to low confidence (1)
src/modules/vtol_att_control/tailsitter.cpp:341
- The logic change here introduces a behavior change for the case when VT_ELEV_MC_LOCK=1 (locked) and the vehicle is in MC_MODE (hover).
Original behavior: When VT_ELEV_MC_LOCK=1 in MC_MODE, the condition (!_param_vt_elev_mc_lock.get() || _vtol_mode != vtol_mode::MC_MODE) evaluated to FALSE, so torque_setpoint_1 remained at zero (initialized at line 271-273), effectively locking the control surfaces.
New behavior: When VT_ELEV_MC_LOCK=1 in MC_MODE, the condition (!_param_vt_elev_mc_lock.get() && _vtol_mode == vtol_mode::MC_MODE) evaluates to FALSE, so the else branch executes and assigns FW torque to the control surfaces.
This means control surfaces are now driven by the FW controller output even in hover mode when they should be locked. This contradicts the VT_ELEV_MC_LOCK parameter documentation which states "If set to 1 the control surfaces are locked at the disarmed value in multicopter mode."
The correct logic should explicitly handle the locked case in MC_MODE by setting torque to zero or not updating it from the initialized zero value.
if (!_param_vt_elev_mc_lock.get() && _vtol_mode == vtol_mode::MC_MODE) {
// In MC_MODE apply torque from multirotor controller
_torque_setpoint_1->xyz[0] = _vehicle_torque_setpoint_virtual_mc->xyz[0];
_torque_setpoint_1->xyz[1] = _vehicle_torque_setpoint_virtual_mc->xyz[1];
_torque_setpoint_1->xyz[2] = _vehicle_torque_setpoint_virtual_mc->xyz[2];
} else {
_torque_setpoint_1->xyz[0] = _vehicle_torque_setpoint_virtual_fw->xyz[0];
_torque_setpoint_1->xyz[1] = _vehicle_torque_setpoint_virtual_fw->xyz[1];
_torque_setpoint_1->xyz[2] = _vehicle_torque_setpoint_virtual_fw->xyz[2];
}
I can briefly summarize this PR:
There are two methods to check the actual effect:
When VT_TS_CS_HVR_DIS = 0: pxh> control_allocator status
...
INFO [control_allocator] Instance: 1
INFO [control_allocator] Effectiveness =
| 0 | 1
Mx| 0 0
My| 0.50000 0.50000
Mz|-0.50000 0.50000
Fx| 0 0
Fy| 0 0
Fz| 0 0
...When VT_TS_CS_HVR_DIS = 1, we can see that the control effect (moment) of the first control surface (first column) is set to 0: pxh> control_allocator status
...
INFO [control_allocator] Instance: 1
INFO [control_allocator] Effectiveness =
| 0 | 1
Mx| 0 0
My| 0 0.50000
Mz| 0 0.50000
Fx| 0 0
Fy| 0 0
Fz| 0 0
...
This model has been extensively validated, with real-world flight videos available on YouTube, and a SITL simulation video demonstrating the specific tests related to this PR is also available for review. |
|
FWIW tailsitter seems to be getting some interest at the moment - #26394 |
This entirely depends on the reviewers. My opinion is that the tailsitter is an existing aircraft type and doesn't need to be added as a new model. Only some details need to be refined, and so far my pull request seems to be working well. Of course, whether this work is meaningful depends entirely on the reviewers. If another pull request can solve my needs, I would be happy to use their method. Update: I have confirmed that another PR(#26394) is related to the effect of the rotor in the control effect matrix. However, this PR is related to the control surface. |
Features
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.
Solved Problem
Fixes #25404
Solution
In the original code logic, all control surfaces are used in fixed-wing mode or during the transition phase, while control surfaces are not used in hover mode (unless the parameter VT_ELEV_MC_LOCK = 0), and the control torque comes from the FW controller.
Now, the MC controller is used when VT_ELEV_MC_LOCK = 0 in hover mode, and a new parameter VT_TS_CS_HVR_DIS is added to disable specific control surfaces, such as disabling control surfaces that are not affected by the propeller wash. The other modes (fixed-wing mode or transition phase) remain unchanged.
I disable some control surfaces by setting certain columns of the control effect matrix to 0, rather than masking to set the actuator output to 0 (by
ActuatorEffectivenessTailsitterVTOL::updateSetpoint). The logic behind this is that if the control effect matrix contains columns corresponding to disabled control surfaces, the pseudo-inverse method for solving the control allocation problem will introduce coupling. This is proven by the calculation results of a simple example in Matlab: