Hover attitude control in FBW-A

If I am in FBW-A mode and the throttle at zero, I will be hovering still - can anyone point me to where the gains are gotten from to control this mode of flight? In my current project, there is a huge difference between hover stability in Stabilize or Hover mode compared to FBW-A at zero throttle and I need to address this to make the transition work.

Any pointers would be appreciated as I’ve been around and around the code base several times and my head is spinning!

PS: why is quadplane code so fragmented…?

Assuming that you are referring to the situation where Q_ASSIST is turned on, the first place you would look at is in quadplane.cpp to find out where Q_ASSIST is being activated.

(I will use Ardupilot’s Master branch as an example, but the basic flow shouldn’t change much across Plane 3.9 - 4.0. Also, I hope I didn’t misinterpret your question :slight_smile:)

Line 1425 (Quadplane::assistance_needed) is called to check if Q_ASSIST needs to be activated.

Searching within the same file to find where the above function is called, we see that it is called in Line 1553 of Quadplane::update_transition:

if (have_airspeed &&
    assistance_needed(aspeed) &&
    !is_tailsitter() &&
    hal.util->get_soft_armed() &&
    ((plane.auto_throttle_mode && !plane.throttle_suppressed) ||
     plane.get_throttle_input()>0 ||
     plane.is_flying())) {
    // the quad should provide some assistance to the plane
    if (transition_state != TRANSITION_AIRSPEED_WAIT) {
        gcs().send_text(MAV_SEVERITY_INFO, "Transition started airspeed %.1f", (double)aspeed);
    }
    transition_state = TRANSITION_AIRSPEED_WAIT;

This block of code tells us that when Q_ASSIST is activated, the aircraft switches into TRANSITION_AIRSPEED_WAIT, which is handled in the same function at Line 1610.

The function then calls hold_hover at Line 1632. The function itself is given at Line 1007:

/*
  hold hover with target climb rate
 */
void QuadPlane::hold_hover(float target_climb_rate)
{
    // motors use full range
    motors->set_desired_spool_state(AP_Motors::DesiredSpoolState::THROTTLE_UNLIMITED);

    // initialize vertical speeds and acceleration
    pos_control->set_max_speed_z(-pilot_velocity_z_max, pilot_velocity_z_max);
    pos_control->set_max_accel_z(pilot_accel_z);

    // call attitude controller
    multicopter_attitude_rate_update(get_desired_yaw_rate_cds());

    // call position controller
    pos_control->set_alt_target_from_climb_rate_ff(target_climb_rate, plane.G_Dt, false);
    run_z_controller();
}

From here, we should be able to get a sensing that during Q_ASSIST, the autopilot is updating the attitude controller with rate inputs (in fact, if you look deeper, you will be able to find the rate inputs for roll and pitch), and only updates the position Z controller and not the XY controller. Which makes sense, because in FBWA mode + Q_ASSIST, you aren’t focused on holding position and more about maintaining altitude.

If you want to go deeper to find out where the gains are taken from, look into each function in hold_hover, it will take you to the Arducopter Attitude and Position control libraries.

Quadplane inherits a lot of code from Arducopter, so it jumps a lot between the Plane and Copter libraries. But quadplane.cpp should usually be the first place you’ll want to look at :slight_smile:

Hope this helps

1 Like

Thank you @disgruntled-patzer! I’ve spotted a few things I need to go investigate. One thing I am looking for is where Quadplane::update(void) is called - I’m feeling especially thick asking this one but I can’t spot it.

Perhaps this may help: Block Diagram For Learning

@disgruntled-patzer thanks!

1 Like