Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tailsitter: remove thrust spikes around entering/leaving transition modes #23033

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
42 changes: 39 additions & 3 deletions src/modules/vtol_att_control/tailsitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ void Tailsitter::update_vtol_state()

if (_vtol_vehicle_status->fixed_wing_system_failure) {
// Failsafe event, switch to MC mode immediately
if (_vtol_mode != vtol_mode::MC_MODE) {
_transition_start_timestamp = hrt_absolute_time();
}

_vtol_mode = vtol_mode::MC_MODE;

} else if (!_attc->is_fixed_wing_requested()) {
Expand Down Expand Up @@ -121,6 +125,7 @@ void Tailsitter::update_vtol_state()
case vtol_mode::TRANSITION_BACK:
// failsafe into fixed wing mode
_vtol_mode = vtol_mode::FW_MODE;
_trans_finished_ts = hrt_absolute_time();
break;
}
}
Expand Down Expand Up @@ -225,6 +230,11 @@ void Tailsitter::update_transition_state()

_v_att_sp->thrust_body[2] = _mc_virtual_att_sp->thrust_body[2];

if (_vtol_mode == vtol_mode::TRANSITION_BACK) {
const float progress = math::constrain(_time_since_trans_start / B_TRANS_THRUST_BLENDING_DURATION, 0.f, 1.f);
blendThrottleBeginningBackTransition(progress);
}

_v_att_sp->timestamp = hrt_absolute_time();

const Eulerf euler_sp(_q_trans_sp);
Expand All @@ -238,7 +248,7 @@ void Tailsitter::update_transition_state()
void Tailsitter::waiting_on_tecs()
{
// copy the last trust value from the front transition
_v_att_sp->thrust_body[0] = _thrust_transition;
_v_att_sp->thrust_body[0] = -_last_thr_in_mc;
}

void Tailsitter::update_fw_state()
Expand Down Expand Up @@ -294,12 +304,27 @@ void Tailsitter::fill_actuator_outputs()
_torque_setpoint_0->xyz[2] = _vehicle_torque_setpoint_virtual_fw->xyz[2] * _param_vt_fw_difthr_s_r.get();
}

// for the short period after switching to FW where there is no thrust published yet from the FW controller,
// keep publishing the last MC thrust to keep the motors running
if (hrt_elapsed_time(&_trans_finished_ts) < 50_ms) {
Copy link
Member

@dagar dagar Apr 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of hard coding these little magic timeouts everywhere what about checking against the actual FW controller publication (_fw_virtual_att_sp)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't find a good way without the hard coded timeout.

  • _fw_virtual_att_sp is constantly being published in the transition phase (with thrust=0), so barely looking at the timestamp doesn't help. We would need to do some isNone() checks.
  • We would need to be careful between the _fw_virtual_att_sp publication and the torque/thrust handling we do here, as one comes from the position controller while the other is the output from the FW rate controller.

_thrust_setpoint_0->xyz[2] = _last_thr_in_mc;
_torque_setpoint_0->xyz[0] = 0.f;
_torque_setpoint_0->xyz[1] = 0.f;
_torque_setpoint_0->xyz[2] = 0.f;
}

} else {
_thrust_setpoint_0->xyz[2] = _vehicle_thrust_setpoint_virtual_mc->xyz[2];

// for the short period after starting the backtransition where there is no thrust published yet from the MC controller,
// keep publishing the last FW thrust to keep the motors running
if (_vtol_mode != vtol_mode::TRANSITION_FRONT_P1 && hrt_elapsed_time(&_transition_start_timestamp) < 50_ms) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (_vtol_mode != vtol_mode::TRANSITION_FRONT_P1 && hrt_elapsed_time(&_transition_start_timestamp) < 50_ms) {
if (_vtol_mode == vtol_mode::TRANSITION_BACK && hrt_elapsed_time(&_transition_start_timestamp) < 50_ms) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I did that on purpose, to also catch the quad-chute case (where the state goes directly from FW to MC, skipping transition).

_thrust_setpoint_0->xyz[2] = -_last_thr_in_fw_mode;
}

_torque_setpoint_0->xyz[0] = _vehicle_torque_setpoint_virtual_mc->xyz[0];
_torque_setpoint_0->xyz[1] = _vehicle_torque_setpoint_virtual_mc->xyz[1];
_torque_setpoint_0->xyz[2] = _vehicle_torque_setpoint_virtual_mc->xyz[2];

_thrust_setpoint_0->xyz[2] = _vehicle_thrust_setpoint_virtual_mc->xyz[2];
}

// Control surfaces
Expand Down Expand Up @@ -330,3 +355,14 @@ bool Tailsitter::isFrontTransitionCompletedBase()

return transition_to_fw;
}

void Tailsitter::blendThrottleAfterFrontTransition(float scale)
{
// note: MC throttle is negative (as in negative z), while FW throttle is positive (positive x)
_v_att_sp->thrust_body[0] = scale * _v_att_sp->thrust_body[0] + (1.f - scale) * (-_last_thr_in_mc);
sfuhrer marked this conversation as resolved.
Show resolved Hide resolved
}

void Tailsitter::blendThrottleBeginningBackTransition(float scale)
{
_v_att_sp->thrust_body[2] = scale * _v_att_sp->thrust_body[2] + (1.f - scale) * (-_last_thr_in_fw_mode);
}
5 changes: 5 additions & 0 deletions src/modules/vtol_att_control/tailsitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ static constexpr float PITCH_THRESHOLD_AUTO_TRANSITION_TO_FW = -1.05f; // -60°
// [rad] Pitch threshold required for completing transition to hover in automatic transitions
static constexpr float PITCH_THRESHOLD_AUTO_TRANSITION_TO_MC = -0.26f; // -15°

// [s] Thrust blending duration from fixed-wing to back transition throttle
static constexpr float B_TRANS_THRUST_BLENDING_DURATION = 0.5f;

class Tailsitter : public VtolType
{

Expand All @@ -66,6 +69,8 @@ class Tailsitter : public VtolType
void update_fw_state() override;
void fill_actuator_outputs() override;
void waiting_on_tecs() override;
void blendThrottleAfterFrontTransition(float scale) override;
void blendThrottleBeginningBackTransition(float scale);

private:
enum class vtol_mode {
Expand Down
2 changes: 2 additions & 0 deletions src/modules/vtol_att_control/vtol_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ void VtolType::update_transition_state()
_time_since_trans_start = (float)(t_now - _transition_start_timestamp) * 1e-6f;

check_quadchute_condition();

_last_thr_in_mc = _vehicle_thrust_setpoint_virtual_mc->xyz[2];
}

float VtolType::update_and_get_backtransition_pitch_sp()
Expand Down
1 change: 1 addition & 0 deletions src/modules/vtol_att_control/vtol_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ class VtolType : public ModuleParams
// motors spinning up or cutting too fast when doing transitions.
float _thrust_transition = 0.0f; // thrust value applied during a front transition (tailsitter & tiltrotor only)
float _last_thr_in_fw_mode = 0.0f;
float _last_thr_in_mc = 0.f;

hrt_abstime _trans_finished_ts = 0;
hrt_abstime _transition_start_timestamp{0};
Expand Down