LCOV - code coverage report
Current view: top level - home/pbarker/rc/ardupilot/ArduPlane - mode_qstabilize.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 34 44 77.3 %
Date: 2026-09-09 11:02:08 Functions: 5 5 100.0 %

          Line data    Source code
       1             : #include "mode.h"
       2             : #include "Plane.h"
       3             : 
       4             : #if HAL_QUADPLANE_ENABLED
       5             : 
       6           3 : bool ModeQStabilize::_enter()
       7             : {
       8           3 :     quadplane.throttle_wait = false;
       9           3 :     return true;
      10             : }
      11             : 
      12     1616725 : void ModeQStabilize::update()
      13             : {
      14             :     // set nav_roll and nav_pitch using sticks
      15             :     // Beware that QuadPlane::tailsitter_check_input (called from Plane::read_radio)
      16             :     // may alter the control_in values for roll and yaw, but not the corresponding
      17             :     // radio_in values. This means that the results for norm_input would not necessarily
      18             :     // be correct for tailsitters, so get_control_in() must be used instead.
      19             :     // normalize control_input to [-1,1]
      20     1616725 :     const float roll_input = (float)plane.channel_roll->get_control_in() / plane.channel_roll->get_range();
      21     1616725 :     const float pitch_input = (float)plane.channel_pitch->get_control_in() / plane.channel_pitch->get_range();
      22             : 
      23             :     // then scale to target angles in centidegrees
      24     1616725 :     if (plane.quadplane.tailsitter.active()) {
      25             :         // tailsitters are different
      26       47327 :         set_tailsitter_roll_pitch(roll_input, pitch_input);
      27       47327 :         return;
      28             :     }
      29             : 
      30     1569398 :     if (!plane.quadplane.option_is_set(QuadPlane::Option::INGORE_FW_ANGLE_LIMITS_IN_Q_MODES)) {
      31             :         // by default angles are also constrained by forward flight limits
      32     1569398 :         set_limited_roll_pitch(roll_input, pitch_input);
      33             :     } else {
      34             :         // use angle max for both roll and pitch
      35           0 :         const int16_t angle_max_cd = plane.quadplane.attitude_control->lean_angle_max_cd();
      36           0 :         plane.nav_roll_cd = roll_input * angle_max_cd;
      37           0 :         plane.nav_pitch_cd = pitch_input * angle_max_cd;
      38             :     }
      39             : }
      40             : 
      41             : // quadplane stabilize mode
      42       15235 : void ModeQStabilize::run()
      43             : {
      44       15235 :     const uint32_t now = AP_HAL::millis();
      45       15235 :     if (quadplane.tailsitter.in_vtol_transition(now)) {
      46             :         // Tailsitters in FW pull up phase of VTOL transition run FW controllers
      47           0 :         Mode::run();
      48           0 :         return;
      49             :     }
      50             : 
      51       15235 :     plane.quadplane.assign_tilt_to_fwd_thr();
      52             : 
      53             :     // special check for ESC calibration in QSTABILIZE
      54       15235 :     if (quadplane.esc_calibration != 0) {
      55           0 :         quadplane.run_esc_calibration();
      56           0 :         plane.stabilize_roll();
      57           0 :         plane.stabilize_pitch();
      58           0 :         return;
      59             :     }
      60             : 
      61             :     // normal QSTABILIZE mode
      62       15235 :     float pilot_throttle_scaled = quadplane.get_pilot_throttle();
      63       15235 :     quadplane.hold_stabilize(pilot_throttle_scaled);
      64             : 
      65             :     // Stabilize with fixed wing surfaces
      66       15235 :     plane.stabilize_roll();
      67       15235 :     plane.stabilize_pitch();
      68             : 
      69             :     // Center rudder
      70       15235 :     output_rudder_and_steering(0.0);
      71             : }
      72             : 
      73             : // set the desired roll and pitch for a tailsitter
      74       47327 : void ModeQStabilize::set_tailsitter_roll_pitch(const float roll_input, const float pitch_input)
      75             : {
      76             :     // separate limit for roll, if set
      77       47327 :     if (plane.quadplane.tailsitter.max_roll_angle > 0) {
      78             :         // roll param is in degrees not centidegrees
      79           0 :         plane.nav_roll_cd = plane.quadplane.tailsitter.max_roll_angle * 100.0f * roll_input;
      80             :     } else {
      81       47327 :         plane.nav_roll_cd = roll_input * plane.quadplane.attitude_control->lean_angle_max_cd();
      82             :     }
      83             : 
      84             :     // angle max for tailsitter pitch
      85       47327 :     plane.nav_pitch_cd = pitch_input * plane.quadplane.attitude_control->lean_angle_max_cd();
      86       47327 :     plane.quadplane.transition->set_VTOL_roll_pitch_limit(plane.nav_roll_cd, plane.nav_pitch_cd);
      87       47327 : }
      88             : 
      89             : // set the desired roll and pitch for normal quadplanes, also limited by forward flight limits
      90     1569398 : void ModeQStabilize::set_limited_roll_pitch(const float roll_input, const float pitch_input)
      91             : {
      92     1569398 :     const int16_t angle_max_cd = plane.quadplane.attitude_control->lean_angle_max_cd();
      93     1569398 :     plane.nav_roll_cd = roll_input * MIN(plane.roll_limit_cd, angle_max_cd);
      94             :     // pitch is further constrained by PTCH_LIM_MIN/MAX which may impose
      95             :     // tighter (possibly asymmetrical) limits than Q_ANGLE_MAX
      96     1569398 :     if (pitch_input > 0) {
      97        1080 :         plane.nav_pitch_cd = pitch_input * MIN(plane.aparm.pitch_limit_max*100, angle_max_cd);
      98             :     } else {
      99     1568318 :         plane.nav_pitch_cd = pitch_input * MIN(-plane.pitch_limit_min*100, angle_max_cd);
     100             :     }
     101     1569398 : }
     102             : 
     103             : #endif

Generated by: LCOV version 1.14