Skip to content

Commit 816aa0f

Browse files
RomanBapstdagar
authored andcommitted
VTOL transitions: use FW attitude loop (PX4#11911)
* VTOL trans: changed that now in transition for both MC and FW the corresponding (correct) attitude controller is running * attitude setpoint for stabilized mode is generated by tailsitter.cpp * reset yaw setpoint during transition to avoid big yaw errors after transition back to hover * VT_TYPE parameter: added "reboot required" metadata
1 parent d4b7441 commit 816aa0f

File tree

8 files changed

+60
-39
lines changed

8 files changed

+60
-39
lines changed

Tools/uorb_graph/create.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ def __init__(self, module_whitelist=[], topic_blacklist=[]):
247247
('mc_pos_control', r'mc_pos_control_main\.cpp$', r'\b_attitude_setpoint_id=([^,)]+)', r'^_attitude_setpoint_id$'),
248248

249249
('mc_att_control', r'mc_att_control_main\.cpp$', r'\b_actuators_id=([^,)]+)', r'^_actuators_id$'),
250+
('mc_att_control', r'mc_att_control_main\.cpp$', r'\_attitude_sp_id=([^,)]+)', r'^_attitude_sp_id$'),
250251

251252
('fw_att_control', r'FixedwingAttitudeControl\.cpp$', r'\b_actuators_id=([^,)]+)', r'^_actuators_id$'),
252253
('fw_att_control', r'FixedwingAttitudeControl\.cpp$', r'\b_attitude_setpoint_id=([^,)]+)', r'^_attitude_setpoint_id$'),

src/modules/fw_att_control/FixedwingAttitudeControl.cpp

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
#include "FixedwingAttitudeControl.hpp"
3535

36+
#include <vtol_att_control/vtol_type.h>
37+
3638
using namespace time_literals;
3739

3840
/**
@@ -120,9 +122,6 @@ FixedwingAttitudeControl::FixedwingAttitudeControl() :
120122
_parameter_handles.bat_scale_en = param_find("FW_BAT_SCALE_EN");
121123
_parameter_handles.airspeed_mode = param_find("FW_ARSP_MODE");
122124

123-
// initialize to invalid VTOL type
124-
_parameters.vtol_type = -1;
125-
126125
/* fetch initial parameter values */
127126
parameters_update();
128127

@@ -242,10 +241,6 @@ FixedwingAttitudeControl::parameters_update()
242241

243242
param_get(_parameter_handles.rattitude_thres, &_parameters.rattitude_thres);
244243

245-
if (_vehicle_status.is_vtol) {
246-
param_get(_parameter_handles.vtol_type, &_parameters.vtol_type);
247-
}
248-
249244
param_get(_parameter_handles.bat_scale_en, &_parameters.bat_scale_en);
250245

251246
param_get(_parameter_handles.airspeed_mode, &tmp);
@@ -292,13 +287,25 @@ FixedwingAttitudeControl::vehicle_control_mode_poll()
292287
if (updated) {
293288
orb_copy(ORB_ID(vehicle_control_mode), _vcontrol_mode_sub, &_vcontrol_mode);
294289
}
290+
291+
if (_vehicle_status.is_vtol) {
292+
const bool is_hovering = _vehicle_status.is_rotary_wing && !_vehicle_status.in_transition_mode;
293+
const bool is_tailsitter_transition = _vehicle_status.in_transition_mode && _is_tailsitter;
294+
295+
if (is_hovering || is_tailsitter_transition) {
296+
_vcontrol_mode.flag_control_attitude_enabled = false;
297+
_vcontrol_mode.flag_control_manual_enabled = false;
298+
}
299+
}
295300
}
296301

297302
void
298303
FixedwingAttitudeControl::vehicle_manual_poll()
299304
{
305+
const bool is_tailsitter_transition = _is_tailsitter && _vehicle_status.in_transition_mode;
306+
const bool is_fixed_wing = !_vehicle_status.is_rotary_wing;
300307

301-
if (_vcontrol_mode.flag_control_manual_enabled && !_vehicle_status.is_rotary_wing) {
308+
if (_vcontrol_mode.flag_control_manual_enabled && (!is_tailsitter_transition || is_fixed_wing)) {
302309

303310
// Always copy the new manual setpoint, even if it wasn't updated, to fill the _actuators with valid values
304311
if (orb_copy(ORB_ID(manual_control_setpoint), _manual_sub, &_manual) == PX4_OK) {
@@ -394,7 +401,7 @@ FixedwingAttitudeControl::vehicle_rates_setpoint_poll()
394401
if (updated) {
395402
orb_copy(ORB_ID(vehicle_rates_setpoint), _rates_sp_sub, &_rates_sp);
396403

397-
if (_parameters.vtol_type == vtol_type::TAILSITTER) {
404+
if (_is_tailsitter) {
398405
float tmp = _rates_sp.roll;
399406
_rates_sp.roll = -_rates_sp.yaw;
400407
_rates_sp.yaw = tmp;
@@ -424,25 +431,17 @@ FixedwingAttitudeControl::vehicle_status_poll()
424431
if (vehicle_status_updated) {
425432
orb_copy(ORB_ID(vehicle_status), _vehicle_status_sub, &_vehicle_status);
426433

427-
// if VTOL and not in fixed wing mode we should only control body-rates which are published
428-
// by the multicoper attitude controller. Therefore, modify the control mode to achieve rate
429-
// control only
430-
if (_vehicle_status.is_vtol) {
431-
if (_vehicle_status.is_rotary_wing) {
432-
_vcontrol_mode.flag_control_attitude_enabled = false;
433-
_vcontrol_mode.flag_control_manual_enabled = false;
434-
}
435-
}
436-
437434
/* set correct uORB ID, depending on if vehicle is VTOL or not */
438435
if (!_actuators_id) {
439436
if (_vehicle_status.is_vtol) {
440437
_actuators_id = ORB_ID(actuator_controls_virtual_fw);
441438
_attitude_setpoint_id = ORB_ID(fw_virtual_attitude_setpoint);
442439

443-
_parameter_handles.vtol_type = param_find("VT_TYPE");
440+
int32_t vt_type = -1;
444441

445-
parameters_update();
442+
if (param_get(param_find("VT_TYPE"), &vt_type) == PX4_OK) {
443+
_is_tailsitter = (vt_type == vtol_type::TAILSITTER);
444+
}
446445

447446
} else {
448447
_actuators_id = ORB_ID(actuator_controls_0);
@@ -566,7 +565,7 @@ void FixedwingAttitudeControl::run()
566565
/* get current rotation matrix and euler angles from control state quaternions */
567566
matrix::Dcmf R = matrix::Quatf(_att.q);
568567

569-
if (_vehicle_status.is_vtol && _parameters.vtol_type == vtol_type::TAILSITTER) {
568+
if (_is_tailsitter) {
570569
/* vehicle is a tailsitter, we need to modify the estimated attitude for fw mode
571570
*
572571
* Since the VTOL airframe is initialized as a multicopter we need to
@@ -609,7 +608,7 @@ void FixedwingAttitudeControl::run()
609608
_att.yawspeed = helper;
610609
}
611610

612-
matrix::Eulerf euler_angles(R);
611+
const matrix::Eulerf euler_angles(R);
613612

614613
vehicle_attitude_setpoint_poll();
615614
vehicle_control_mode_poll();
@@ -623,7 +622,7 @@ void FixedwingAttitudeControl::run()
623622
_att_sp.fw_control_yaw = _att_sp.fw_control_yaw && _vcontrol_mode.flag_control_auto_enabled;
624623

625624
/* lock integrator until control is started */
626-
bool lock_integrator = !(_vcontrol_mode.flag_control_rates_enabled && !_vehicle_status.is_rotary_wing);
625+
bool lock_integrator = !_vcontrol_mode.flag_control_rates_enabled || _vehicle_status.is_rotary_wing;
627626

628627
/* Simple handling of failsafe: deploy parachute if failsafe is on */
629628
if (_vcontrol_mode.flag_control_termination_enabled) {

src/modules/fw_att_control/FixedwingAttitudeControl.hpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
#include <uORB/topics/vehicle_land_detected.h>
6161
#include <uORB/topics/vehicle_rates_setpoint.h>
6262
#include <uORB/topics/vehicle_status.h>
63-
#include <vtol_att_control/vtol_type.h>
6463

6564
using matrix::Eulerf;
6665
using matrix::Quatf;
@@ -140,6 +139,8 @@ class FixedwingAttitudeControl final : public ModuleBase<FixedwingAttitudeContro
140139

141140
bool _flag_control_attitude_enabled_last{false};
142141

142+
bool _is_tailsitter{false};
143+
143144
struct {
144145
float p_tc;
145146
float p_p;
@@ -204,8 +205,6 @@ class FixedwingAttitudeControl final : public ModuleBase<FixedwingAttitudeContro
204205

205206
float rattitude_thres;
206207

207-
int32_t vtol_type; /**< VTOL type: 0 = tailsitter, 1 = tiltrotor */
208-
209208
int32_t bat_scale_en; /**< Battery scaling enabled */
210209
bool airspeed_disabled;
211210

@@ -274,8 +273,6 @@ class FixedwingAttitudeControl final : public ModuleBase<FixedwingAttitudeContro
274273

275274
param_t rattitude_thres;
276275

277-
param_t vtol_type;
278-
279276
param_t bat_scale_en;
280277
param_t airspeed_mode;
281278

src/modules/mc_att_control/mc_att_control.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include <uORB/topics/vehicle_status.h>
5858
#include <uORB/topics/vehicle_land_detected.h>
5959
#include <uORB/topics/landing_gear.h>
60+
#include <vtol_att_control/vtol_type.h>
6061

6162
#include <AttitudeControl.hpp>
6263

@@ -174,6 +175,7 @@ class MulticopterAttitudeControl : public ModuleBase<MulticopterAttitudeControl>
174175
orb_advert_t _landing_gear_pub{nullptr};
175176

176177
orb_id_t _actuators_id{nullptr}; /**< pointer to correct actuator controls0 uORB metadata structure */
178+
orb_id_t _attitude_sp_id{nullptr}; /**< pointer to correct attitude setpoint uORB metadata structure */
177179

178180
bool _actuators_0_circuit_breaker_enabled{false}; /**< circuit breaker to suppress output */
179181

@@ -277,6 +279,8 @@ class MulticopterAttitudeControl : public ModuleBase<MulticopterAttitudeControl>
277279
(ParamInt<px4::params::MC_AIRMODE>) _param_mc_airmode
278280
)
279281

282+
bool _is_tailsitter{false};
283+
280284
matrix::Vector3f _rate_p; /**< P gain for angular rate error */
281285
matrix::Vector3f _rate_i; /**< I gain for angular rate error */
282286
matrix::Vector3f _rate_int_lim; /**< integrator state limit for rate loop */

src/modules/mc_att_control/mc_att_control_main.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,16 @@ MulticopterAttitudeControl::vehicle_status_poll()
252252
if (_actuators_id == nullptr) {
253253
if (_vehicle_status.is_vtol) {
254254
_actuators_id = ORB_ID(actuator_controls_virtual_mc);
255+
_attitude_sp_id = ORB_ID(mc_virtual_attitude_setpoint);
256+
257+
int32_t vt_type = -1;
258+
if (param_get(param_find("VT_TYPE"), &vt_type) == PX4_OK) {
259+
_is_tailsitter = (vt_type == vtol_type::TAILSITTER);
260+
}
255261

256262
} else {
257263
_actuators_id = ORB_ID(actuator_controls_0);
264+
_attitude_sp_id = ORB_ID(vehicle_attitude_setpoint);
258265
}
259266
}
260267
}
@@ -407,7 +414,6 @@ void
407414
MulticopterAttitudeControl::generate_attitude_setpoint(float dt, bool reset_yaw_sp)
408415
{
409416
vehicle_attitude_setpoint_s attitude_setpoint{};
410-
landing_gear_s landing_gear{};
411417
const float yaw = Eulerf(Quatf(_v_att.q)).psi();
412418

413419
/* reset yaw setpoint to current position if needed */
@@ -495,12 +501,12 @@ MulticopterAttitudeControl::generate_attitude_setpoint(float dt, bool reset_yaw_
495501
attitude_setpoint.q_d_valid = true;
496502

497503
attitude_setpoint.thrust_body[2] = -throttle_curve(_manual_control_sp.z);
504+
attitude_setpoint.timestamp = hrt_absolute_time();
505+
if (_attitude_sp_id != nullptr) {
506+
orb_publish_auto(_attitude_sp_id, &_vehicle_attitude_setpoint_pub, &attitude_setpoint, nullptr, ORB_PRIO_DEFAULT);
507+
}
498508

499509
_landing_gear.landing_gear = get_landing_gear_state();
500-
501-
attitude_setpoint.timestamp = landing_gear.timestamp = hrt_absolute_time();
502-
orb_publish_auto(ORB_ID(vehicle_attitude_setpoint), &_vehicle_attitude_setpoint_pub, &attitude_setpoint, nullptr, ORB_PRIO_DEFAULT);
503-
504510
_landing_gear.timestamp = hrt_absolute_time();
505511
orb_publish_auto(ORB_ID(landing_gear), &_landing_gear_pub, &_landing_gear, nullptr, ORB_PRIO_DEFAULT);
506512
}
@@ -805,7 +811,15 @@ MulticopterAttitudeControl::run()
805811

806812
bool attitude_setpoint_generated = false;
807813

808-
if (_v_control_mode.flag_control_attitude_enabled && _vehicle_status.is_rotary_wing) {
814+
const bool is_hovering = _vehicle_status.is_rotary_wing && !_vehicle_status.in_transition_mode;
815+
816+
// vehicle is a tailsitter in transition mode
817+
const bool is_tailsitter_transition = _vehicle_status.in_transition_mode && _is_tailsitter;
818+
819+
bool run_att_ctrl = _v_control_mode.flag_control_attitude_enabled && (is_hovering || is_tailsitter_transition);
820+
821+
822+
if (run_att_ctrl) {
809823
if (attitude_updated) {
810824
// Generate the attitude setpoint from stick inputs if we are in Manual/Stabilized mode
811825
if (_v_control_mode.flag_control_manual_enabled &&
@@ -822,7 +836,7 @@ MulticopterAttitudeControl::run()
822836

823837
} else {
824838
/* attitude controller disabled, poll rates setpoint topic */
825-
if (_v_control_mode.flag_control_manual_enabled && _vehicle_status.is_rotary_wing) {
839+
if (_v_control_mode.flag_control_manual_enabled && is_hovering) {
826840
if (manual_control_updated) {
827841
/* manual rates control - ACRO mode */
828842
Vector3f man_rate_sp(
@@ -856,9 +870,12 @@ MulticopterAttitudeControl::run()
856870
}
857871

858872
if (attitude_updated) {
873+
// reset yaw setpoint during transitions, tailsitter.cpp generates
874+
// attitude setpoint for the transition
859875
reset_yaw_sp = (!attitude_setpoint_generated && !_v_control_mode.flag_control_rattitude_enabled) ||
860876
_vehicle_land_detected.landed ||
861-
(_vehicle_status.is_vtol && !_vehicle_status.is_rotary_wing); // VTOL in FW mode
877+
(_vehicle_status.is_vtol && _vehicle_status.in_transition_mode);
878+
862879
attitude_dt = 0.f;
863880
}
864881

src/modules/vtol_att_control/vtol_att_control_main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ VtolAttitudeControl::start()
752752
_control_task = px4_task_spawn_cmd("vtol_att_control",
753753
SCHED_DEFAULT,
754754
SCHED_PRIORITY_ATTITUDE_CONTROL + 1,
755-
1230,
755+
1320,
756756
(px4_main_t)&VtolAttitudeControl::task_main_trampoline,
757757
nullptr);
758758

src/modules/vtol_att_control/vtol_att_control_params.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ PARAM_DEFINE_INT32(VT_FW_PERM_STAB, 0);
8282
* @min 0
8383
* @max 2
8484
* @decimal 0
85+
* @reboot_required true
8586
* @group VTOL Attitude Control
8687
*/
8788
PARAM_DEFINE_INT32(VT_TYPE, 0);

src/modules/vtol_att_control/vtol_type.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,9 @@ bool VtolType::is_motor_off_channel(const int channel)
370370
int tmp;
371371
int channels = _params->fw_motors_off;
372372

373-
for (int i = 0; i < _params->vtol_motor_count; ++i) {
373+
static constexpr int num_outputs_max = 8;
374+
375+
for (int i = 0; i < num_outputs_max; ++i) {
374376
tmp = channels % 10;
375377

376378
if (tmp == 0) {

0 commit comments

Comments
 (0)