LCOV - code coverage report
Current view: top level - AP_Motors - AP_Motors_Class.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 42 54 77.8 %
Date: 2026-09-09 11:02:08 Functions: 42 54 77.8 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "AP_Motors_config.h"
       4             : 
       5             : #include <AP_Common/AP_Common.h>
       6             : #include <AP_Math/AP_Math.h>
       7             : #include <Filter/Filter.h>         // filter library
       8             : #include <Filter/DerivativeFilter.h>
       9             : #include <GCS_MAVLink/GCS_MAVLink.h>
      10             : #include <AP_Logger/AP_Logger_config.h>
      11             : #include <SRV_Channel/SRV_Channel_config.h>
      12             : 
      13             : #ifndef AP_MOTORS_MAX_NUM_MOTORS
      14             : #if AP_SCRIPTING_ENABLED
      15             : #define AP_MOTORS_MAX_NUM_MOTORS 32
      16             : #else
      17             : #define AP_MOTORS_MAX_NUM_MOTORS 12
      18             : #endif
      19             : 
      20             : // doesn't make sense to have more motors than servo channels, so clamp:
      21             : #if NUM_SERVO_CHANNELS < AP_MOTORS_MAX_NUM_MOTORS
      22             : #undef AP_MOTORS_MAX_NUM_MOTORS
      23             : #define AP_MOTORS_MAX_NUM_MOTORS NUM_SERVO_CHANNELS
      24             : #endif
      25             : 
      26             : // various Motors backends will not compile if we don't have 16 motors
      27             : // available (eg. AP_Motors6DOF).  Until we stop compiling those
      28             : // backends in when there aren't enough motors to support those
      29             : // backends we will support a minimum of 12 motors, the limit before
      30             : // we moved to 32 motor support:
      31             : #if AP_MOTORS_MAX_NUM_MOTORS < 12
      32             : #undef AP_MOTORS_MAX_NUM_MOTORS
      33             : #define AP_MOTORS_MAX_NUM_MOTORS 12
      34             : #endif
      35             : 
      36             : #endif  // defined (AP_MOTORS_MAX_NUM_MOTORS)
      37             : 
      38             : // scale factor for top layer to prevent beat frequency between top and bottom
      39             : // layers of co-rotating motors. Must be less than 1.0
      40             : #ifndef AP_MOTORS_FRAME_OCTAQUAD_COROTATING_SCALE_FACTOR
      41             : #define AP_MOTORS_FRAME_OCTAQUAD_COROTATING_SCALE_FACTOR 0.9
      42             : #endif
      43             : 
      44             : // offsets for motors in motor_out and _motor_filtered arrays
      45             : #define AP_MOTORS_MOT_1 0U
      46             : #define AP_MOTORS_MOT_2 1U
      47             : #define AP_MOTORS_MOT_3 2U
      48             : #define AP_MOTORS_MOT_4 3U
      49             : #define AP_MOTORS_MOT_5 4U
      50             : #define AP_MOTORS_MOT_6 5U
      51             : #define AP_MOTORS_MOT_7 6U
      52             : #define AP_MOTORS_MOT_8 7U
      53             : #define AP_MOTORS_MOT_9 8U
      54             : #define AP_MOTORS_MOT_10 9U
      55             : #define AP_MOTORS_MOT_11 10U
      56             : #define AP_MOTORS_MOT_12 11U
      57             : #define AP_MOTORS_MOT_13 12U
      58             : #define AP_MOTORS_MOT_14 13U
      59             : #define AP_MOTORS_MOT_15 14U
      60             : #define AP_MOTORS_MOT_16 15U
      61             : #define AP_MOTORS_MOT_17 16U
      62             : #define AP_MOTORS_MOT_18 17U
      63             : #define AP_MOTORS_MOT_19 18U
      64             : #define AP_MOTORS_MOT_20 19U
      65             : #define AP_MOTORS_MOT_21 20U
      66             : #define AP_MOTORS_MOT_22 21U
      67             : #define AP_MOTORS_MOT_23 22U
      68             : #define AP_MOTORS_MOT_24 23U
      69             : #define AP_MOTORS_MOT_25 24U
      70             : #define AP_MOTORS_MOT_26 25U
      71             : #define AP_MOTORS_MOT_27 26U
      72             : #define AP_MOTORS_MOT_28 27U
      73             : #define AP_MOTORS_MOT_29 28U
      74             : #define AP_MOTORS_MOT_30 29U
      75             : #define AP_MOTORS_MOT_31 30U
      76             : #define AP_MOTORS_MOT_32 31U
      77             : 
      78             : // motor update rate
      79             : #define AP_MOTORS_SPEED_DEFAULT     490 // default output rate to the motors
      80             : 
      81             : /// @class      AP_Motors
      82             : class AP_Motors {
      83             : public:
      84             : 
      85             :     enum motor_frame_class {
      86             :         MOTOR_FRAME_UNDEFINED = 0,
      87             :         MOTOR_FRAME_QUAD = 1,
      88             :         MOTOR_FRAME_HEXA = 2,
      89             :         MOTOR_FRAME_OCTA = 3,
      90             :         MOTOR_FRAME_OCTAQUAD = 4,
      91             :         MOTOR_FRAME_Y6 = 5,
      92             :         MOTOR_FRAME_HELI = 6,
      93             :         MOTOR_FRAME_TRI = 7,
      94             :         MOTOR_FRAME_SINGLE = 8,
      95             :         MOTOR_FRAME_COAX = 9,
      96             :         MOTOR_FRAME_TAILSITTER = 10,
      97             :         MOTOR_FRAME_HELI_DUAL = 11,
      98             :         MOTOR_FRAME_DODECAHEXA = 12,
      99             :         MOTOR_FRAME_HELI_QUAD = 13,
     100             :         MOTOR_FRAME_DECA = 14,
     101             :         MOTOR_FRAME_SCRIPTING_MATRIX = 15,
     102             :         MOTOR_FRAME_6DOF_SCRIPTING = 16,
     103             :         MOTOR_FRAME_DYNAMIC_SCRIPTING_MATRIX = 17,
     104             :     };
     105             : 
     106             :     // return string corresponding to frame_class
     107             :     const char* get_frame_string() const;
     108             : 
     109             :     enum motor_frame_type {
     110             :         MOTOR_FRAME_TYPE_PLUS = 0,
     111             :         MOTOR_FRAME_TYPE_X = 1,
     112             :         MOTOR_FRAME_TYPE_V = 2,
     113             :         MOTOR_FRAME_TYPE_H = 3,
     114             :         MOTOR_FRAME_TYPE_VTAIL = 4,
     115             :         MOTOR_FRAME_TYPE_ATAIL = 5,
     116             :         MOTOR_FRAME_TYPE_PLUSREV = 6, // plus with reversed motor direction
     117             :         MOTOR_FRAME_TYPE_Y6B = 10,
     118             :         MOTOR_FRAME_TYPE_Y6F = 11, // for FireFlyY6
     119             :         MOTOR_FRAME_TYPE_BF_X = 12, // X frame, betaflight ordering
     120             :         MOTOR_FRAME_TYPE_DJI_X = 13, // X frame, DJI ordering
     121             :         MOTOR_FRAME_TYPE_CW_X = 14, // X frame, clockwise ordering
     122             :         MOTOR_FRAME_TYPE_I = 15, // (sideways H) octo only
     123             :         MOTOR_FRAME_TYPE_NYT_PLUS = 16, // plus frame, no differential torque for yaw
     124             :         MOTOR_FRAME_TYPE_NYT_X = 17, // X frame, no differential torque for yaw
     125             :         MOTOR_FRAME_TYPE_BF_X_REV = 18, // X frame, betaflight ordering, reversed motors
     126             :         MOTOR_FRAME_TYPE_Y4 = 19, //Y4 Quadrotor frame
     127             :         MOTOR_FRAME_TYPE_X_COR = 20, // X8 co-rotating, old motor ordering
     128             :         MOTOR_FRAME_TYPE_CW_X_COR = 21, // X8 co-rotating, clockwise motor ordering
     129             :     };
     130             : 
     131             : 
     132             :     // returns a formatted string into buffer, e.g. "QUAD/X"
     133             :     void get_frame_and_type_string(char *buffer, uint8_t buflen) const;
     134             : 
     135             :     // Constructor
     136             :     AP_Motors(uint16_t speed_hz = AP_MOTORS_SPEED_DEFAULT);
     137             : 
     138             :     // singleton support
     139      436505 :     static AP_Motors    *get_singleton(void) { return _singleton; }
     140             : 
     141             :     // check initialisation succeeded
     142             :     virtual bool        arming_checks(size_t buflen, char *buffer) const;
     143             :     virtual bool        motor_test_checks(size_t buflen, char *buffer) const;
     144     4367695 :     bool                initialised_ok() const { return _initialised_ok; }
     145      862148 :     void                set_initialised_ok(bool val) { _initialised_ok = val; }
     146             : 
     147             :     // arm, disarm or check status status of motors
     148   410973116 :     bool                armed() const { return _armed; }
     149             :     void                armed(bool arm);
     150             : 
     151             :     // set motor interlock status
     152     8685725 :     void                set_interlock(bool set) { _interlock = set;}
     153             : 
     154             :     // get motor interlock status.  true means motors run, false motors don't run
     155   113143608 :     bool                get_interlock() const { return _interlock; }
     156             : 
     157             :     // get/set spoolup block
     158     3400667 :     bool                get_spoolup_block() const { return _spoolup_block; }
     159     5443750 :     void                set_spoolup_block(bool set) { _spoolup_block = set; }
     160             : 
     161             :     // set_roll, set_pitch, set_yaw, set_throttle
     162    34595905 :     void                set_roll(float roll_in) { _roll_in = roll_in; };        // range -1 ~ +1
     163    30013508 :     void                set_roll_ff(float roll_in) { _roll_in_ff = roll_in; };    // range -1 ~ +1
     164    34595905 :     void                set_pitch(float pitch_in) { _pitch_in = pitch_in; };    // range -1 ~ +1
     165    30013508 :     void                set_pitch_ff(float pitch_in) { _pitch_in_ff = pitch_in; };  // range -1 ~ +1
     166    34595905 :     void                set_yaw(float yaw_in) { _yaw_in = yaw_in; };            // range -1 ~ +1
     167    30013508 :     void                set_yaw_ff(float yaw_in) { _yaw_in_ff = yaw_in; };      // range -1 ~ +1
     168    35187951 :     void                set_throttle(float throttle_in) { _throttle_in = throttle_in; };   // range 0 ~ 1
     169    31750600 :     void                set_throttle_avg_max(float throttle_avg_max) { _throttle_avg_max = constrain_float(throttle_avg_max, 0.0f, 1.0f); };   // range 0 ~ 1
     170    34964062 :     void                set_throttle_filter_cutoff(float filt_hz) { _throttle_filter.set_cutoff_frequency(filt_hz); }
     171             :     void                set_slew_filter_cutoff(float filt_hz) { _throttle_slew_filter.set_cutoff_frequency(filt_hz); }
     172     1356799 :     void                set_forward(float forward_in) { _forward_in = forward_in; }; // range -1 ~ +1
     173     1356799 :     void                set_lateral(float lateral_in) { _lateral_in = lateral_in; };     // range -1 ~ +1
     174             : 
     175             :     // for 6DoF vehicles, sets the roll and pitch offset, this rotates the thrust vector in body frame
     176           0 :     virtual void        set_roll_pitch(float roll_deg, float pitch_deg) {};
     177             : 
     178             :     // accessors for roll, pitch, yaw and throttle inputs to motors
     179     5116771 :     float               get_roll() const { return _roll_in; }
     180     5013122 :     float               get_roll_ff() const { return _roll_in_ff; }
     181     4982733 :     float               get_pitch() const { return _pitch_in; }
     182     4822499 :     float               get_pitch_ff() const { return _pitch_in_ff; }
     183     6139145 :     float               get_yaw() const { return _yaw_in; }
     184     5852324 :     float               get_yaw_ff() const { return _yaw_in_ff; }
     185     2577813 :     float               get_throttle_out() const { return _throttle_out; }
     186           0 :     virtual bool        get_thrust(uint8_t motor_num, float& thr_out) const { return false; }
     187           0 :     virtual bool        get_raw_motor_throttle(uint8_t motor_num, float& thr_out) const { return false; }
     188           0 :     float               get_throttle_in() const { return _throttle_in; }
     189    99802341 :     float               get_throttle() const { return constrain_float(_throttle_filter.get(), 0.0f, 1.0f); }
     190     2180683 :     float               get_throttle_bidirectional() const { return constrain_float(2 * (_throttle_filter.get() - 0.5f), -1.0f, 1.0f); }
     191    34737650 :     float               get_throttle_slew_rate() const { return _throttle_slew_rate; }
     192       49960 :     float               get_forward() const { return _forward_in; }
     193       49960 :     float               get_lateral() const { return _lateral_in; }
     194             :     virtual float       get_throttle_hover() const = 0;
     195             : 
     196             :     // motor failure handling
     197           9 :     void                set_thrust_boost(bool enable) { _thrust_boost = enable; }
     198    64023096 :     bool                get_thrust_boost() const { return _thrust_boost; }
     199       17501 :     virtual uint8_t     get_lost_motor() const { return 0; }
     200             : 
     201             :     // desired spool states
     202             :     enum class DesiredSpoolState : uint8_t {
     203             :         SHUT_DOWN = 0,              // all motors should move to stop
     204             :         GROUND_IDLE = 1,            // all motors should move to ground idle
     205             :         THROTTLE_UNLIMITED = 2,     // motors should move to being a state where throttle is unconstrained (e.g. by start up procedure)
     206             :     };
     207             : 
     208             :     // set_desired_spool_state - apply safety constraints and set desired spool state
     209             :     // Pure virtual - each vehicle type must implement appropriate safety logic
     210             :     virtual void set_desired_spool_state(enum DesiredSpoolState spool) = 0;
     211             : 
     212    27420439 :     enum DesiredSpoolState get_desired_spool_state(void) const { return _spool_desired; }
     213             : 
     214             :     // spool states
     215             :     enum class SpoolState : uint8_t {
     216             :         SHUT_DOWN = 0,                      // all motors stop
     217             :         GROUND_IDLE = 1,                    // all motors at ground idle
     218             :         SPOOLING_UP = 2,                       // increasing maximum throttle while stabilizing
     219             :         THROTTLE_UNLIMITED = 3,             // throttle is no longer constrained by start up procedure
     220             :         SPOOLING_DOWN = 4,                     // decreasing maximum throttle while stabilizing
     221             :     };
     222             : 
     223             :     // get_spool_state - get current spool state
     224    33360718 :     enum SpoolState  get_spool_state(void) const { return _spool_state; }
     225             : 
     226             :     // set_dt_s / get_dt_s - dt is the time since the last time (in seconds) the motor mixers were updated
     227             :     //   _dt should be set based on the time of the last IMU read used by these controllers
     228             :     //   the motor mixers should run on each loop to ensure normal operation
     229    35139957 :     void set_dt_s(float dt_s) { _dt_s = dt_s; }
     230    26225997 :     float get_dt_s() const { return _dt_s; }
     231             : 
     232             :     // structure for holding motor limit flags
     233             :     struct AP_Motors_limit {
     234             :         bool roll;                    // we have reached roll or pitch limit
     235             :         bool pitch;                   // we have reached roll or pitch limit
     236             :         bool yaw;                     // we have reached yaw limit
     237             :         bool throttle_lower;          // we have reached throttle's lower limit
     238             :         bool throttle_upper;          // we have reached throttle's upper limit
     239             :         void set_all(bool flag);      // set all limits
     240             :         void set_rpy(bool flag);      // set limits for roll pitch yaw
     241             :         void set_throttle(bool flag); // set limits for throttle upper and lower
     242             :     } limit;
     243             : 
     244             : #if AP_SCRIPTING_ENABLED
     245             :     // set limit flag for pitch, roll and yaw
     246             :     void set_external_limits(bool roll, bool pitch, bool yaw, bool throttle_lower, bool throttle_upper);
     247             : #endif
     248             : 
     249             :     //
     250             :     // virtual functions that should be implemented by child classes
     251             :     //
     252             : 
     253             :     // set update rate to motors - a value in hertz
     254           0 :     virtual void        set_update_rate( uint16_t speed_hz ) { _speed_hz = speed_hz; }
     255             : 
     256             :     // init
     257             :     virtual void        init(motor_frame_class frame_class, motor_frame_type frame_type) = 0;
     258             : 
     259             :     // set frame class (i.e. quad, hexa, heli) and type (i.e. x, plus)
     260             :     virtual void        set_frame_class_and_type(motor_frame_class frame_class, motor_frame_type frame_type) = 0;
     261             : 
     262             :     // output - sends commands to the motors
     263             :     virtual void        output() = 0;
     264             : 
     265             :     // output_min - sends minimum values out to the motors
     266             :     virtual void        output_min() = 0;
     267             : 
     268             :     // output_test_seq - spin a motor at the pwm value specified
     269             :     //  motor_seq is the motor's sequence number from 1 to the number of motors on the frame
     270             :     //  pwm value is an actual pwm value that will be output, normally in the range of 1000 ~ 2000
     271             :     //  return true if output was successful, false if not possible
     272             :     bool                output_test_seq(uint8_t motor_seq, int16_t pwm);
     273             : 
     274             :     // get_motor_mask - returns a bitmask of which outputs are being used for motors (1 means being used)
     275             :     //  this can be used to ensure other pwm outputs (i.e. for servos) do not conflict
     276             :     virtual uint32_t    get_motor_mask() = 0;
     277             : 
     278             :     // pilot input in the -1 ~ +1 range for roll, pitch and yaw. 0~1 range for throttle
     279             :     void                set_radio_passthrough(float roll_input, float pitch_input, float throttle_input, float yaw_input);
     280             : 
     281             :     // return the roll factor of any motor, this is used for tilt rotors and tail sitters
     282             :     // using copter motors for forward flight
     283           0 :     virtual float       get_roll_factor(uint8_t i) { return 0.0f; }
     284             : 
     285             :     // return the pitch factor of any motor
     286           0 :     virtual float       get_pitch_factor(uint8_t i) { return 0.0f; }
     287             : 
     288             :     // return whether a motor is enabled or not
     289           0 :     virtual bool        is_motor_enabled(uint8_t i) { return false; }
     290             : 
     291             :     // This function required for tradheli. Tradheli initializes targets when going from unarmed to armed state.
     292             :     // This function is overriden in motors_heli class.   Always true for multicopters.
     293           0 :     virtual bool init_targets_on_arming() const { return true; }
     294             : 
     295             :     // returns true if the configured PWM type is digital and should have fixed endpoints
     296             :     bool is_digital_pwm_type() const;
     297             : 
     298             :     // returns true is pwm type is brushed
     299        2002 :     bool is_brushed_pwm_type() const { return _pwm_type == PWMType::BRUSHED; }
     300             : 
     301             :     // returns true is pwm type is normal
     302           0 :     bool is_normal_pwm_type() const { return (_pwm_type == PWMType::NORMAL) || (_pwm_type == PWMType::PWM_RANGE) || (_pwm_type == PWMType::PWM_ANGLE); }
     303             : 
     304       87346 :     MAV_TYPE get_frame_mav_type() const { return _mav_type; }
     305             : 
     306             :     // direct motor write
     307             :     virtual void        rc_write(uint8_t chan, uint16_t pwm);
     308             : 
     309             : #if AP_SCRIPTING_ENABLED
     310             :     void set_frame_string(const char * str);
     311             : #endif
     312             : 
     313             : #if HAL_LOGGING_ENABLED
     314             :     // write log, to be called at 10hz
     315           0 :     virtual void Log_Write() {};
     316             :     
     317             :     // log the spool rate, writes upon change
     318             :     void Log_Write_SPOL();
     319             : #endif
     320             : 
     321             :     enum MotorOptions : uint8_t {
     322             :         BATT_RAW_VOLTAGE = (1 << 0U)
     323             :     };
     324    62479662 :     bool has_option(MotorOptions option) { return _options.get() & uint8_t(option); }
     325             : 
     326             : protected:
     327             :     // output functions that should be overloaded by child classes
     328             :     virtual void        output_armed_stabilizing() = 0;
     329             :     virtual void        rc_write_angle(uint8_t chan, int16_t angle_cd);
     330             :     virtual void        rc_set_freq(uint32_t mask, uint16_t freq_hz);
     331             : 
     332             : 
     333             :     /*
     334             :       map an internal motor mask to real motor mask, accounting for
     335             :       SERVOn_FUNCTION mappings, and allowing for multiple outputs per
     336             :       motor number
     337             :     */
     338             :     uint32_t    motor_mask_to_srv_channel_mask(uint32_t mask) const;
     339             : 
     340             :     // add a motor to the motor map
     341             :     void add_motor_num(int8_t motor_num);
     342             :     
     343             :     // update the throttle input filter
     344             :     virtual void update_throttle_filter() = 0;
     345             : 
     346             :     // save parameters as part of disarming
     347           0 :     virtual void save_params_on_disarm() {}
     348             : 
     349             :     // internal variables
     350             :     float               _dt_s;                      // time difference (in seconds) since the last loop time
     351             :     uint16_t            _speed_hz;                  // speed in hz to send updates to motors
     352             :     float               _roll_in;                   // desired roll control from attitude controllers, -1 ~ +1
     353             :     float               _roll_in_ff;                // desired roll feed forward control from attitude controllers, -1 ~ +1
     354             :     float               _pitch_in;                  // desired pitch control from attitude controller, -1 ~ +1
     355             :     float               _pitch_in_ff;               // desired pitch feed forward control from attitude controller, -1 ~ +1
     356             :     float               _yaw_in;                    // desired yaw control from attitude controller, -1 ~ +1
     357             :     float               _yaw_in_ff;                 // desired yaw feed forward control from attitude controller, -1 ~ +1
     358             :     float               _throttle_in;               // last throttle input from set_throttle caller
     359             :     float               _throttle_out;              // throttle after mixing is complete
     360             :     float               _throttle_slew_rate;        // throttle slew rate from input
     361             :     float               _forward_in;                // last forward input from set_forward caller
     362             :     float               _lateral_in;                // last lateral input from set_lateral caller
     363             :     float               _throttle_avg_max;          // last throttle input from set_throttle_avg_max
     364             :     LowPassFilterFloat  _throttle_filter;           // pilot throttle input filter
     365             :     DerivativeFilterFloat_Size7  _throttle_slew;    // throttle output slew detector
     366             :     LowPassFilterFloat  _throttle_slew_filter;      // filter for the output of the throttle slew
     367             :     DesiredSpoolState   _spool_desired;             // desired spool state
     368             :     SpoolState          _spool_state;               // current spool mode
     369             :     DesiredSpoolState   _logged_spool_desired;      // last logged spool state
     370             :     SpoolState          _logged_spool_state;        // last logged spool mode
     371             : 
     372             :     // mask of what channels need fast output
     373             :     uint32_t            _motor_fast_mask;
     374             : 
     375             :     // Used with PWMType::PWM_RANGE and PWMType::PWM_ANGLE
     376             :     struct {
     377             :         // Mask of motors using scaled output
     378             :         uint32_t mask;
     379             : 
     380             :         // Offset used to convert from PWM to scaled value
     381             :         float offset;
     382             :     } _motor_pwm_scaled;
     383             : 
     384             :     
     385             :     // pass through variables
     386             :     float _roll_radio_passthrough;     // roll input from pilot in -1 ~ +1 range.  used for setup and providing servo feedback while landed
     387             :     float _pitch_radio_passthrough;    // pitch input from pilot in -1 ~ +1 range.  used for setup and providing servo feedback while landed
     388             :     float _throttle_radio_passthrough; // throttle/collective input from pilot in 0 ~ 1 range.  used for setup and providing servo feedback while landed
     389             :     float _yaw_radio_passthrough;      // yaw input from pilot in -1 ~ +1 range.  used for setup and providing servo feedback while landed
     390             : 
     391             :     enum class PWMType : uint8_t {
     392             :         NORMAL     = 0,
     393             :         ONESHOT    = 1,
     394             :         ONESHOT125 = 2,
     395             :         BRUSHED    = 3,
     396             :         DSHOT150   = 4,
     397             :         DSHOT300   = 5,
     398             :         DSHOT600   = 6,
     399             :         DSHOT1200  = 7,
     400             :         PWM_RANGE  = 8,
     401             :         PWM_ANGLE  = 9,
     402             :     };
     403             : 
     404             :     AP_Enum<PWMType>             _pwm_type;            // PWM output type
     405             : 
     406             :     // motor failure handling
     407             :     bool                _thrust_boost;          // true if thrust boost is enabled to handle motor failure
     408             :     bool                _thrust_balanced;       // true when output thrust is well balanced
     409             :     float               _thrust_boost_ratio;    // choice between highest and second highest motor output for output mixing (0 ~ 1). Zero is normal operation
     410             : 
     411             :     // motor options
     412             :     AP_Int16            _options;
     413             : 
     414             :     MAV_TYPE _mav_type; // MAV_TYPE_GENERIC = 0;
     415             : 
     416             :     // return string corresponding to frame_class
     417             :     virtual const char* _get_frame_string() const = 0;
     418             : 
     419             :     // return string corresponding to frame_type
     420         247 :     virtual const char* get_type_string() const { return ""; }
     421             : 
     422             :     // output_test_seq - spin a motor at the pwm value specified
     423             :     //  motor_seq is the motor's sequence number from 1 to the number of motors on the frame
     424             :     //  pwm value is an actual pwm value that will be output, normally in the range of 1000 ~ 2000
     425             :     virtual void _output_test_seq(uint8_t motor_seq, int16_t pwm) = 0;
     426             : 
     427             : #if AP_SCRIPTING_ENABLED
     428             :     // Custom frame string set from scripting
     429             :     char* custom_frame_string;
     430             : 
     431             :     // external limits from scripting
     432             :     AP_Motors_limit external_limits;
     433             : #endif
     434             : 
     435             : private:
     436             : 
     437             :     bool _armed;             // 0 if disarmed, 1 if armed
     438             :     bool _interlock;         // 1 if the motor interlock is enabled (i.e. motors run), 0 if disabled (motors don't run)
     439             :     bool _initialised_ok;    // 1 if initialisation was successful
     440             :     bool _spoolup_block;     // true if spoolup is blocked
     441             : 
     442             :     static AP_Motors *_singleton;
     443             : };
     444             : 
     445             : namespace AP {
     446             :     AP_Motors *motors();
     447             : };

Generated by: LCOV version 1.14