LCOV - code coverage report
Current view: top level - AP_Motors - AP_MotorsHeli.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 26 27 96.3 %
Date: 2026-09-09 11:02:08 Functions: 20 21 95.2 %

          Line data    Source code
       1             : /// @file       AP_MotorsHeli.h
       2             : /// @brief      Motor control class for Traditional Heli
       3             : #pragma once
       4             : 
       5             : #include <inttypes.h>
       6             : 
       7             : #include <AP_Common/AP_Common.h>
       8             : #include <AP_Math/AP_Math.h>            // ArduPilot Mega Vector/Matrix math Library
       9             : #include <RC_Channel/RC_Channel.h>
      10             : #include <SRV_Channel/SRV_Channel.h>
      11             : #include "AP_Motors_Class.h"
      12             : #include "AP_MotorsHeli_RSC.h"
      13             : 
      14             : // servo output rates
      15             : #define AP_MOTORS_HELI_SPEED_DEFAULT            125     // default servo update rate for helicopters
      16             : 
      17             : // default swash min and max angles and positions
      18             : #define AP_MOTORS_HELI_SWASH_CYCLIC_MAX         2500
      19             : #define AP_MOTORS_HELI_COLLECTIVE_MIN           1250
      20             : #define AP_MOTORS_HELI_COLLECTIVE_MAX           1750
      21             : #define AP_MOTORS_HELI_COLLECTIVE_HOVER_DEFAULT 0.5f  // the estimated hover throttle, 0 ~ 1
      22             : #define AP_MOTORS_HELI_COLLECTIVE_HOVER_TC      10.0f // time constant used to update estimated hover throttle, 0 ~ 1
      23             : #define AP_MOTORS_HELI_COLLECTIVE_HOVER_MIN     0.3f  // minimum possible hover throttle
      24             : #define AP_MOTORS_HELI_COLLECTIVE_HOVER_MAX     0.8f // maximum possible hover throttle
      25             : #define AP_MOTORS_HELI_COLLECTIVE_MIN_DEG      -90.0f // minimum collective blade pitch angle in deg
      26             : #define AP_MOTORS_HELI_COLLECTIVE_MAX_DEG       90.0f // maximum collective blade pitch angle in deg
      27             : #define AP_MOTORS_HELI_COLLECTIVE_LAND_MIN      -2.0f // minimum landed collective blade pitch angle in deg for modes using althold
      28             : 
      29             : 
      30             : // rsc function output channels.
      31             : #define AP_MOTORS_HELI_RSC                      CH_8
      32             : 
      33             : class AP_HeliControls;
      34             : 
      35             : /// @class      AP_MotorsHeli
      36             : class AP_MotorsHeli : public AP_Motors {
      37             : public:
      38             : 
      39             :     /// Constructor
      40          83 :     AP_MotorsHeli( uint16_t speed_hz = AP_MOTORS_HELI_SPEED_DEFAULT) :
      41             :         AP_Motors(speed_hz),
      42          83 :         _main_rotor(SRV_Channel::k_heli_rsc, AP_MOTORS_HELI_RSC, 0U)
      43             :     {
      44          83 :         AP_Param::setup_object_defaults(this, var_info);
      45          83 :     };
      46             : 
      47             :     // init
      48             :     void init(motor_frame_class frame_class, motor_frame_type frame_type) override;
      49             : 
      50             :     // set frame class (i.e. quad, hexa, heli) and type (i.e. x, plus)
      51        2260 :     void set_frame_class_and_type(motor_frame_class frame_class, motor_frame_type frame_type) override {
      52        2260 :         _frame_class = frame_class;
      53        2260 :         _frame_type = frame_type;
      54        2260 :     }
      55             : 
      56             :     // set update rate to motors - a value in hertz
      57             :     virtual void set_update_rate( uint16_t speed_hz ) override = 0;
      58             : 
      59             :     // output_min - sets servos to neutral point with motors stopped
      60             :     void output_min() override;
      61             : 
      62             :     // set_desired_spool_state - set desired spool state with safety constraints
      63             :     void set_desired_spool_state(DesiredSpoolState spool) override;
      64             : 
      65             :     //
      66             :     // heli specific methods
      67             :     //
      68             : 
      69             :     //set turbine start flag on to initiaize starting sequence
      70          10 :     void set_turb_start(bool turb_start) { _heliflags.start_engine = turb_start; }
      71             : 
      72             :     // set_collective_for_landing - limits collective from going too low if we know we are landed
      73      404223 :     void set_collective_for_landing(bool landing) { _heliflags.landing_collective = landing; }
      74             : 
      75             :     // get_rsc_mode - gets the current rotor speed control method
      76      404475 :     uint8_t get_rsc_mode() const { return _main_rotor.get_rsc_control_mode(); }
      77             : 
      78             :     // get_rsc_setpoint - gets contents of _rsc_setpoint parameter (0~1)
      79             :     float get_rsc_setpoint() const { return _main_rotor._rsc_setpoint.get() * 0.01f; }
      80             : 
      81             :     // set_desired_rotor_speed - sets target rotor speed as a number from 0 ~ 1
      82             :     virtual void set_desired_rotor_speed(float desired_speed);
      83             : 
      84             :     // get_desired_rotor_speed - gets target rotor speed as a number from 0 ~ 1
      85     1813914 :     float get_desired_rotor_speed() const { return _main_rotor.get_desired_rotor_speed(); }
      86             : 
      87             :     // get_motor_mask - returns a bitmask of which outputs are being used for motors or servos (1 means being used)
      88             :     //  this can be used to ensure other pwm outputs (i.e. for servos) do not conflict
      89             :     virtual uint32_t get_motor_mask() override;
      90             : 
      91             :     // output - sends commands to the motors
      92             :     void output() override;
      93             : 
      94             :     // update estimated throttle required to hover
      95             :     void update_throttle_hover(float dt);
      96     5274951 :     float get_throttle_hover() const override { return constrain_float(_collective_hover, AP_MOTORS_HELI_COLLECTIVE_HOVER_MIN, AP_MOTORS_HELI_COLLECTIVE_HOVER_MAX); }
      97             : 
      98             :     // accessor to get the takeoff collective flag signifying that current collective is greater than collective required to indicate takeoff
      99      485907 :     bool get_takeoff_collective() const { return _heliflags.takeoff_collective; }
     100             : 
     101             :     // accessor to get the land min collective flag signifying that current collective is lower than collective required for landing
     102      168158 :     bool get_below_land_min_coll() const { return _heliflags.below_land_min_coll; }
     103             : 
     104             :     // support passing init_targets_on_arming flag to greater code
     105       67407 :     bool init_targets_on_arming() const override { return _heliflags.init_targets_on_arming; }
     106             : 
     107             :     // helper for vehicle code to request autorotation states in the RSC.
     108     1803521 :     void set_autorotation_active(bool tf) { _main_rotor.autorotation.set_active(tf, false); }
     109             : 
     110             :     // true if we are using a manual collective flight mode
     111     3233979 :     void set_using_manual_collective_mode(bool using_manual_collective_mode) { _main_rotor.set_using_manual_collective_mode(using_manual_collective_mode); }
     112             : 
     113             :     // helper to force the RSC autorotation state to deactivated
     114     1430458 :     void force_deactivate_autorotation(void) { _main_rotor.autorotation.set_active(false, true); }
     115             : 
     116             :     // true if RSC is actively autorotating or bailing out
     117     3366425 :     bool in_autorotation(void) const { return _main_rotor.in_autorotation(); }
     118             : 
     119             :     // true if bailing out autorotation
     120       14401 :     bool autorotation_bailout(void) const { return _main_rotor.autorotation.bailing_out(); }
     121             : 
     122             :     // true if the autorotation functionality within the rsc has been enabled
     123          80 :     bool rsc_autorotation_enabled(void) const { return _main_rotor.autorotation.enabled(); }
     124             : 
     125             :     // set land complete flag
     126     3233979 :     void set_land_complete(bool landed) { _heliflags.land_complete = landed; }
     127             : 
     128             :     // function to calculate and set the normalised collective position given a desired blade pitch angle (deg)
     129             :     void set_coll_from_ang(float col_ang_deg);
     130             : 
     131             :     //return zero lift collective position
     132     3181156 :     float get_coll_mid() const { return _collective_zero_thrust_pct; }
     133             : 
     134             :     // enum for heli optional features
     135             :     enum class HeliOption {
     136             :         USE_LEAKY_I                     = (1<<0),   // 1
     137             :     };
     138             : 
     139             :     // use leaking integrator management scheme
     140     4258859 :     bool using_leaky_integrator() const { return heli_option(HeliOption::USE_LEAKY_I); }
     141             : 
     142             :     // Run arming checks
     143             :     bool arming_checks(size_t buflen, char *buffer) const override;
     144             : 
     145             :     // Tell user motor test is disabled on heli
     146             :     bool motor_test_checks(size_t buflen, char *buffer) const override;
     147             : 
     148             :     // output_test_seq - disabled on heli, do nothing
     149           0 :     void _output_test_seq(uint8_t motor_seq, int16_t pwm) override {};
     150             : 
     151             :     // Helper function for param conversions to be done in motors class
     152             :     virtual void heli_motors_param_conversions(void);
     153             : 
     154             :     // var_info for holding Parameter information
     155             :     static const struct AP_Param::GroupInfo var_info[];
     156             : 
     157             : protected:
     158             : 
     159             :     // manual servo modes (used for setup)
     160             :     enum ServoControlModes {
     161             :         SERVO_CONTROL_MODE_AUTOMATED = 0,
     162             :         SERVO_CONTROL_MODE_MANUAL_PASSTHROUGH,
     163             :         SERVO_CONTROL_MODE_MANUAL_MAX,
     164             :         SERVO_CONTROL_MODE_MANUAL_CENTER,
     165             :         SERVO_CONTROL_MODE_MANUAL_MIN,
     166             :         SERVO_CONTROL_MODE_MANUAL_OSCILLATE,
     167             :     };
     168             : 
     169             :     // output - sends commands to the motors
     170             :     void output_armed_stabilizing() override;
     171             :     void output_disarmed();
     172             : 
     173             :     // external objects we depend upon
     174             :     AP_MotorsHeli_RSC   _main_rotor;            // main rotor
     175             : 
     176             :     // update_motor_controls - sends commands to motor controllers
     177             :     virtual void update_motor_control(AP_MotorsHeli_RSC::DesiredRSCSpoolState state) = 0;
     178             : 
     179             :     // update_spool_state - updates the spool state based on the desired state
     180             :     virtual AP_Motors::SpoolState update_spool_state(AP_MotorsHeli_RSC::DesiredRSCSpoolState state) = 0;
     181             : 
     182             :     // run spool logic
     183             :     void                output_logic();
     184             : 
     185             :     // output_to_motors - sends commands to the motors
     186             :     virtual void        output_to_motors() = 0;
     187             : 
     188             :     // reset_flight_controls - resets all controls and scalars to flight status
     189             :     void reset_flight_controls();
     190             : 
     191             :     // update the throttle input filter
     192             :     void update_throttle_filter() override;
     193             : 
     194             :     // move_actuators - moves swash plate and tail rotor
     195             :     virtual void move_actuators(float roll_out, float pitch_out, float coll_in, float yaw_out) = 0;
     196             : 
     197             :     // init_outputs - initialise Servo/PWM ranges and endpoints.  This
     198             :     // method also updates the initialised flag.
     199             :     virtual void init_outputs() = 0;
     200             : 
     201             :     // calculate_armed_scalars - recalculates scalars that can change while armed
     202             :     virtual void calculate_armed_scalars();
     203             : 
     204             :     // calculate_scalars - must be implemented by child classes
     205             :     virtual void calculate_scalars() = 0;
     206             : 
     207             :     // servo_test - move servos through full range of movement
     208             :     // to be overloaded by child classes, different vehicle types would have different movement patterns
     209             :     virtual void servo_test() = 0;
     210             : 
     211             :     // save parameters as part of disarming
     212             :     void save_params_on_disarm() override;
     213             : 
     214             :     // Determines if _heli_options bit is set
     215             :     bool heli_option(HeliOption opt) const;
     216             : 
     217             :     // updates the takeoff collective flag indicating that current collective is greater than collective required to indicate takeoff.
     218             :     void update_takeoff_collective_flag(float coll_out);
     219             : 
     220         240 :     const char* _get_frame_string() const override { return "HELI"; }
     221             : 
     222             :     // update turbine start flag
     223             :     void update_turbine_start();
     224             : 
     225             :     // Update _heliflags.rotor_runup_complete value writing log event on state change
     226             :     void set_rotor_runup_complete(bool new_value);
     227             : 
     228             : #if HAL_LOGGING_ENABLED
     229             :     // Returns the scaling value required to convert the collective angle parameters into the cyclic-output-to-angle conversion for blade angle logging
     230             :     float get_cyclic_angle_scaler(void) const;
     231             : #endif
     232             : 
     233             :     // enum values for HOVER_LEARN parameter
     234             :     enum HoverLearn {
     235             :         HOVER_LEARN_DISABLED = 0,
     236             :         HOVER_LEARN_ONLY = 1,
     237             :         HOVER_LEARN_AND_SAVE = 2
     238             :     };
     239             : 
     240             :     // flags bitmask
     241             :     struct heliflags_type {
     242             :         uint8_t landing_collective      : 1;    // true if collective is setup for landing which has much higher minimum
     243             :         uint8_t rotor_runup_complete    : 1;    // true if the rotors have had enough time to wind up
     244             :         uint8_t init_targets_on_arming  : 1;    // 0 if targets were initialized, 1 if targets were not initialized after arming
     245             :         uint8_t save_rsc_mode           : 1;    // used to determine the rsc mode needs to be saved while disarmed
     246             :         uint8_t servo_test_running      : 1;    // true if servo_test is running
     247             :         uint8_t land_complete           : 1;    // true if aircraft is landed
     248             :         uint8_t takeoff_collective      : 1;    // true if collective is above 30% between H_COL_MID and H_COL_MAX
     249             :         uint8_t below_land_min_coll     : 1;    // true if collective is below H_COL_LAND_MIN
     250             :         uint8_t start_engine            : 1;    // true if turbine start RC option is initiated
     251             :     } _heliflags;
     252             : 
     253             :     // parameters
     254             :     AP_Int16        _cyclic_max;                // Maximum cyclic angle of the swash plate in centi-degrees
     255             :     AP_Int16        _collective_min;            // Lowest possible servo position for the swashplate
     256             :     AP_Int16        _collective_max;            // Highest possible servo position for the swashplate
     257             :     AP_Int8         _servo_mode;                // Pass radio inputs directly to servos during set-up through mission planner
     258             :     AP_Int8         _servo_test;                // sets number of cycles to test servo movement on bootup
     259             :     AP_Float        _collective_hover;          // estimated collective required to hover throttle in the range 0 ~ 1
     260             :     AP_Int8         _collective_hover_learn;    // enable/disabled hover collective learning
     261             :     AP_Int8         _heli_options;              // bitmask for optional features
     262             :     AP_Float        _collective_zero_thrust_deg;// Zero thrust blade collective pitch in degrees
     263             :     AP_Float        _collective_land_min_deg;   // Minimum Landed collective blade pitch in degrees for non-manual collective modes (i.e. modes that use altitude hold)
     264             :     AP_Float        _collective_max_deg;        // Maximum collective blade pitch angle in deg that corresponds to the PWM set for maximum collective pitch (H_COL_MAX)
     265             :     AP_Float        _collective_min_deg;        // Minimum collective blade pitch angle in deg that corresponds to the PWM set for minimum collective pitch (H_COL_MIN)
     266             : 
     267             :     // internal variables
     268             :     float           _collective_zero_thrust_pct;      // collective zero thrutst parameter value converted to 0 ~ 1 range
     269             :     float           _collective_land_min_pct;      // collective land min parameter value converted to 0 ~ 1 range
     270             :     uint8_t         _servo_test_cycle_counter = 0;   // number of test cycles left to run after bootup
     271             : 
     272             :     motor_frame_type _frame_type;
     273             :     motor_frame_class _frame_class;
     274             : };

Generated by: LCOV version 1.14