Skip to content

Commit 5ae4ca8

Browse files
sfuhrerbkueng
authored andcommitted
VTOL: Make pusher assist generic to enable also for tiltrotor
-move pusher assist functionality into vtol_type class and adapt it to also work for tiltrotor VTOLs (pitch rotors down to accelerate forward) -for tiltrotor: compensate for lost lift due to tilt by increasing the throttle -enable pusher / tiltassist also in altitude mode Signed-off-by: Silvan Fuhrer <[email protected]>
1 parent ca0b570 commit 5ae4ca8

8 files changed

+126
-85
lines changed

src/modules/vtol_att_control/standard.cpp

+2-78
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ Standard::Standard(VtolAttitudeControl *attc) :
6262

6363
_params_handles_standard.pusher_ramp_dt = param_find("VT_PSHER_RMP_DT");
6464
_params_handles_standard.back_trans_ramp = param_find("VT_B_TRANS_RAMP");
65-
_params_handles_standard.down_pitch_max = param_find("VT_DWN_PITCH_MAX");
66-
_params_handles_standard.forward_thrust_scale = param_find("VT_FWD_THRUST_SC");
6765
_params_handles_standard.pitch_setpoint_offset = param_find("FW_PSP_OFF");
6866
_params_handles_standard.reverse_output = param_find("VT_B_REV_OUT");
6967
_params_handles_standard.reverse_delay = param_find("VT_B_REV_DEL");
@@ -84,13 +82,6 @@ Standard::parameters_update()
8482

8583
_airspeed_trans_blend_margin = _params->transition_airspeed - _params->airspeed_blend;
8684

87-
/* maximum down pitch allowed */
88-
param_get(_params_handles_standard.down_pitch_max, &v);
89-
_params_standard.down_pitch_max = math::radians(v);
90-
91-
/* scale for fixed wing thrust used for forward acceleration in multirotor mode */
92-
param_get(_params_handles_standard.forward_thrust_scale, &_params_standard.forward_thrust_scale);
93-
9485
/* pitch setpoint offset */
9586
param_get(_params_handles_standard.pitch_setpoint_offset, &v);
9687
_params_standard.pitch_setpoint_offset = math::radians(v);
@@ -326,76 +317,9 @@ void Standard::update_mc_state()
326317
{
327318
VtolType::update_mc_state();
328319

329-
// if the thrust scale param is zero or the drone is on manual mode,
330-
// then the pusher-for-pitch strategy is disabled and we can return
331-
if (_params_standard.forward_thrust_scale < FLT_EPSILON ||
332-
!_v_control_mode->flag_control_position_enabled) {
333-
return;
334-
}
335-
336-
// Do not engage pusher assist during a failsafe event
337-
// There could be a problem with the fixed wing drive
338-
if (_attc->get_vtol_vehicle_status()->vtol_transition_failsafe) {
339-
return;
340-
}
341-
342-
// disable pusher assist during landing
343-
if (_attc->get_pos_sp_triplet()->current.valid
344-
&& _attc->get_pos_sp_triplet()->current.type == position_setpoint_s::SETPOINT_TYPE_LAND) {
345-
return;
346-
}
347-
348-
const Dcmf R(Quatf(_v_att->q));
349-
const Dcmf R_sp(Quatf(_v_att_sp->q_d));
350-
const Eulerf euler(R);
351-
const Eulerf euler_sp(R_sp);
352-
_pusher_throttle = 0.0f;
353-
354-
// direction of desired body z axis represented in earth frame
355-
Vector3f body_z_sp(R_sp(0, 2), R_sp(1, 2), R_sp(2, 2));
356-
357-
// rotate desired body z axis into new frame which is rotated in z by the current
358-
// heading of the vehicle. we refer to this as the heading frame.
359-
Dcmf R_yaw = Eulerf(0.0f, 0.0f, -euler(2));
360-
body_z_sp = R_yaw * body_z_sp;
361-
body_z_sp.normalize();
362-
363-
// calculate the desired pitch seen in the heading frame
364-
// this value corresponds to the amount the vehicle would try to pitch forward
365-
float pitch_forward = atan2f(body_z_sp(0), body_z_sp(2));
366-
367-
// only allow pitching forward up to threshold, the rest of the desired
368-
// forward acceleration will be compensated by the pusher
369-
if (pitch_forward < -_params_standard.down_pitch_max) {
370-
// desired roll angle in heading frame stays the same
371-
float roll_new = -asinf(body_z_sp(1));
372-
373-
_pusher_throttle = (sinf(-pitch_forward) - sinf(_params_standard.down_pitch_max))
374-
* _params_standard.forward_thrust_scale;
375-
376-
// return the vehicle to level position
377-
float pitch_new = 0.0f;
378-
379-
// create corrected desired body z axis in heading frame
380-
const Dcmf R_tmp = Eulerf(roll_new, pitch_new, 0.0f);
381-
Vector3f tilt_new(R_tmp(0, 2), R_tmp(1, 2), R_tmp(2, 2));
382-
383-
// rotate the vector into a new frame which is rotated in z by the desired heading
384-
// with respect to the earh frame.
385-
const float yaw_error = wrap_pi(euler_sp(2) - euler(2));
386-
const Dcmf R_yaw_correction = Eulerf(0.0f, 0.0f, -yaw_error);
387-
tilt_new = R_yaw_correction * tilt_new;
388-
389-
// now extract roll and pitch setpoints
390-
_v_att_sp->pitch_body = atan2f(tilt_new(0), tilt_new(2));
391-
_v_att_sp->roll_body = -asinf(tilt_new(1));
392-
393-
const Quatf q_sp(Eulerf(_v_att_sp->roll_body, _v_att_sp->pitch_body, euler_sp(2)));
394-
q_sp.copyTo(_v_att_sp->q_d);
395-
_v_att_sp->q_d_valid = true;
396-
}
320+
VtolType::pusher_assist();
397321

398-
_pusher_throttle = _pusher_throttle < 0.0f ? 0.0f : _pusher_throttle;
322+
_pusher_throttle = _forward_thrust;
399323
}
400324

401325
void Standard::update_fw_state()

src/modules/vtol_att_control/standard.h

-4
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@ class Standard : public VtolType
6969
struct {
7070
float pusher_ramp_dt;
7171
float back_trans_ramp;
72-
float down_pitch_max;
73-
float forward_thrust_scale;
7472
float pitch_setpoint_offset;
7573
float reverse_output;
7674
float reverse_delay;
@@ -79,8 +77,6 @@ class Standard : public VtolType
7977
struct {
8078
param_t pusher_ramp_dt;
8179
param_t back_trans_ramp;
82-
param_t down_pitch_max;
83-
param_t forward_thrust_scale;
8480
param_t pitch_setpoint_offset;
8581
param_t reverse_output;
8682
param_t reverse_delay;

src/modules/vtol_att_control/tiltrotor.cpp

+22-2
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,11 @@ void Tiltrotor::update_mc_state()
207207
{
208208
VtolType::update_mc_state();
209209

210-
// make sure motors are not tilted
211-
_tilt_control = _params_tiltrotor.tilt_mc;
210+
VtolType::pusher_assist();
211+
212+
_tilt_control = _forward_thrust;
213+
214+
Tiltrotor::thrust_compensation_for_tilt();
212215
}
213216

214217
void Tiltrotor::update_fw_state()
@@ -387,3 +390,20 @@ void Tiltrotor::fill_actuator_outputs()
387390
_actuators_fw_in->control[actuator_controls_s::INDEX_YAW];
388391
}
389392
}
393+
394+
/*
395+
* Increase combined thrust of MC propellers if motors are tilted. Assumes that all MC motors are tilted equally.
396+
*/
397+
398+
void Tiltrotor::thrust_compensation_for_tilt()
399+
{
400+
401+
// only compensate for tilt angle up to 0.5 * max tilt
402+
float compensated_tilt = _tilt_control;
403+
compensated_tilt = compensated_tilt < 0.0f ? 0.0f : compensated_tilt;
404+
compensated_tilt = compensated_tilt > 0.5f ? 0.5f : compensated_tilt;
405+
406+
float thrust_new = _v_att_sp->thrust_body[2] / cosf(compensated_tilt * M_PI_2_F);
407+
408+
_v_att_sp->thrust_body[2] = thrust_new;
409+
}

src/modules/vtol_att_control/tiltrotor.h

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class Tiltrotor : public VtolType
5858
void update_mc_state() override;
5959
void update_fw_state() override;
6060
void waiting_on_tecs() override;
61+
void thrust_compensation_for_tilt();
6162

6263
private:
6364

src/modules/vtol_att_control/vtol_att_control_main.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ VtolAttitudeControl::VtolAttitudeControl() :
8686
_params_handles.diff_thrust = param_find("VT_FW_DIFTHR_EN");
8787
_params_handles.diff_thrust_scale = param_find("VT_FW_DIFTHR_SC");
8888

89+
_params_handles.down_pitch_max = param_find("VT_DWN_PITCH_MAX");
90+
_params_handles.forward_thrust_scale = param_find("VT_FWD_THRUST_SC");
91+
8992
/* fetch initial parameter values */
9093
parameters_update();
9194

@@ -272,6 +275,13 @@ VtolAttitudeControl::parameters_update()
272275
param_get(_params_handles.diff_thrust_scale, &v);
273276
_params.diff_thrust_scale = math::constrain(v, -1.0f, 1.0f);
274277

278+
/* maximum down pitch allowed */
279+
param_get(_params_handles.down_pitch_max, &v);
280+
_params.down_pitch_max = math::radians(v);
281+
282+
/* scale for fixed wing thrust used for forward acceleration in multirotor mode */
283+
param_get(_params_handles.forward_thrust_scale, &_params.forward_thrust_scale);
284+
275285
// make sure parameters are feasible, require at least 1 m/s difference between transition and blend airspeed
276286
_params.airspeed_blend = math::min(_params.airspeed_blend, _params.transition_airspeed - 1.0f);
277287

src/modules/vtol_att_control/vtol_att_control_main.h

+2
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ class VtolAttitudeControl : public ModuleBase<VtolAttitudeControl>, public px4::
201201
param_t fw_motors_off;
202202
param_t diff_thrust;
203203
param_t diff_thrust_scale;
204+
param_t down_pitch_max;
205+
param_t forward_thrust_scale;
204206
} _params_handles{};
205207

206208
/* for multicopters it is usual to have a non-zero idle speed of the engines

src/modules/vtol_att_control/vtol_type.cpp

+81-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
#include <px4_platform_common/defines.h>
4747
#include <matrix/math.hpp>
4848

49+
using namespace matrix;
50+
4951

5052
VtolType::VtolType(VtolAttitudeControl *att_controller) :
5153
_attc(att_controller),
@@ -187,7 +189,7 @@ void VtolType::check_quadchute_condition()
187189
{
188190

189191
if (_v_control_mode->flag_armed && !_land_detected->landed) {
190-
matrix::Eulerf euler = matrix::Quatf(_v_att->q);
192+
Eulerf euler = Quatf(_v_att->q);
191193

192194
// fixed-wing minimum altitude
193195
if (_params->fw_min_alt > FLT_EPSILON) {
@@ -381,3 +383,81 @@ bool VtolType::is_channel_set(const int channel, const int target)
381383

382384
return (channel_bitmap >> channel) & 1;
383385
}
386+
387+
388+
void VtolType::pusher_assist()
389+
{
390+
391+
// normalized pusher support throttle (standard VTOL) or tilt (tiltrotor), initialize to 0
392+
_forward_thrust = 0.0f;
393+
394+
// if the thrust scale param is zero or the drone is not in some position or altitude control mode,
395+
// then the pusher-for-pitch strategy is disabled and we can return
396+
if (_params->forward_thrust_scale < FLT_EPSILON || !(_v_control_mode->flag_control_position_enabled
397+
|| _v_control_mode->flag_control_altitude_enabled)) {
398+
return;
399+
}
400+
401+
// Do not engage pusher assist during a failsafe event (could be a problem with the fixed wing drive)
402+
if (_attc->get_vtol_vehicle_status()->vtol_transition_failsafe) {
403+
return;
404+
}
405+
406+
// disable pusher assist during landing
407+
if (_attc->get_pos_sp_triplet()->current.valid
408+
&& _attc->get_pos_sp_triplet()->current.type == position_setpoint_s::SETPOINT_TYPE_LAND) {
409+
return;
410+
}
411+
412+
const Dcmf R(Quatf(_v_att->q));
413+
const Dcmf R_sp(Quatf(_v_att_sp->q_d));
414+
const Eulerf euler(R);
415+
const Eulerf euler_sp(R_sp);
416+
417+
// direction of desired body z axis represented in earth frame
418+
Vector3f body_z_sp(R_sp(0, 2), R_sp(1, 2), R_sp(2, 2));
419+
420+
// rotate desired body z axis into new frame which is rotated in z by the current
421+
// heading of the vehicle. we refer to this as the heading frame.
422+
Dcmf R_yaw = Eulerf(0.0f, 0.0f, -euler(2));
423+
body_z_sp = R_yaw * body_z_sp;
424+
body_z_sp.normalize();
425+
426+
// calculate the desired pitch seen in the heading frame
427+
// this value corresponds to the amount the vehicle would try to pitch down
428+
float pitch_down = atan2f(body_z_sp(0), body_z_sp(2));
429+
430+
// only allow pitching down up to threshold, the rest of the desired
431+
// forward acceleration will be compensated by the pusher/tilt
432+
if (pitch_down < -_params->down_pitch_max) {
433+
// desired roll angle in heading frame stays the same
434+
float roll_new = -asinf(body_z_sp(1));
435+
436+
_forward_thrust = (sinf(-pitch_down) - sinf(_params->down_pitch_max)) * _params->forward_thrust_scale;
437+
// limit forward actuation to [0, 0.9]
438+
_forward_thrust = _forward_thrust < 0.0f ? 0.0f : _forward_thrust;
439+
_forward_thrust = _forward_thrust > 0.9f ? 0.9f : _forward_thrust;
440+
441+
// return the vehicle to level position
442+
float pitch_new = 0.0f;
443+
444+
// create corrected desired body z axis in heading frame
445+
const Dcmf R_tmp = Eulerf(roll_new, pitch_new, 0.0f);
446+
Vector3f tilt_new(R_tmp(0, 2), R_tmp(1, 2), R_tmp(2, 2));
447+
448+
// rotate the vector into a new frame which is rotated in z by the desired heading
449+
// with respect to the earh frame.
450+
const float yaw_error = wrap_pi(euler_sp(2) - euler(2));
451+
const Dcmf R_yaw_correction = Eulerf(0.0f, 0.0f, -yaw_error);
452+
tilt_new = R_yaw_correction * tilt_new;
453+
454+
// now extract roll and pitch setpoints
455+
_v_att_sp->pitch_body = atan2f(tilt_new(0), tilt_new(2));
456+
_v_att_sp->roll_body = -asinf(tilt_new(1));
457+
458+
const Quatf q_sp(Eulerf(_v_att_sp->roll_body, _v_att_sp->pitch_body, euler_sp(2)));
459+
q_sp.copyTo(_v_att_sp->q_d);
460+
_v_att_sp->q_d_valid = true;
461+
}
462+
463+
}

src/modules/vtol_att_control/vtol_type.h

+8
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ struct Params {
7070
int32_t fw_motors_off; /**< bitmask of all motors that should be off in fixed wing mode */
7171
int32_t diff_thrust;
7272
float diff_thrust_scale;
73+
float down_pitch_max;
74+
float forward_thrust_scale;
7375
};
7476

7577
// Has to match 1:1 msg/vtol_vehicle_status.msg
@@ -163,6 +165,10 @@ class VtolType
163165
*/
164166
bool can_transition_on_ground();
165167

168+
/**
169+
* Pusher assist in hover (pusher/pull for standard VTOL, motor tilt for tiltrotor)
170+
*/
171+
void pusher_assist();
166172

167173

168174
mode get_mode() {return _vtol_mode;}
@@ -216,6 +222,8 @@ class VtolType
216222

217223
motor_state _motor_state = motor_state::DISABLED;
218224

225+
float _forward_thrust = 0.0f; // normalized pusher throttle (standard VTOL) or tilt (tiltrotor)
226+
219227

220228

221229
/**

0 commit comments

Comments
 (0)