/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #pragma once #include #include "transition.h" #include #include class QuadPlane; class AP_MotorsMulticopter; class Tailsitter_Transition; class Tailsitter { friend class QuadPlane; friend class Plane; public: Tailsitter(QuadPlane& _quadplane, AP_MotorsMulticopter*& _motors); bool enabled() const { return (enable > 0) && setup_complete;} void setup(); // return true when flying a control surface only tailsitter bool is_control_surface_tailsitter(void) const; // return true when flying a tailsitter in VTOL bool active(void); // create outputs for tailsitters void output(void); // handle different tailsitter input types void check_input(void); // check if we have completed transition to fixed wing bool transition_fw_complete(void); // return true if we are a tailsitter in FW flight bool is_in_fw_flight(void) const; // check if we have completed transition to vtol bool transition_vtol_complete(void) const; // return true if transition to VTOL flight bool in_vtol_transition(uint32_t now = 0) const; // account for control surface speed scaling in VTOL modes void speed_scaling(void); // return the transition_angle_vtol value int8_t get_transition_angle_vtol() const; // return true if pitch control should be relaxed bool relax_pitch(); // Write tailsitter specific log void write_log(); // tailsitter speed scaler float last_spd_scaler = 1.0f; // used to slew rate limiting with TAILSITTER_GSCL_ATT_THR option static const struct AP_Param::GroupInfo var_info[]; // bit 0 enables plane mode and bit 1 enables body-frame roll mode enum input { TAILSITTER_INPUT_PLANE = (1U<<0), TAILSITTER_INPUT_BF_ROLL = (1U<<1) }; enum gscl_mask { TAILSITTER_GSCL_THROTTLE = (1U<<0), TAILSITTER_GSCL_ATT_THR = (1U<<1), TAILSITTER_GSCL_DISK_THEORY = (1U<<2), TAILSITTER_GSCL_ALTITUDE = (1U<<3), }; AP_Int8 enable; AP_Int8 transition_angle_fw; AP_Float transition_rate_fw; AP_Int8 transition_angle_vtol; AP_Float transition_rate_vtol; AP_Float transition_throttle_vtol; AP_Int8 input_type; AP_Float vectored_forward_gain; AP_Float vectored_hover_gain; AP_Float vectored_hover_power; AP_Float throttle_scale_max; AP_Float gain_scaling_min; AP_Float max_roll_angle; AP_Int16 motor_mask; AP_Float scaling_speed_min; AP_Float scaling_speed_max; AP_Int16 gain_scaling_mask; AP_Float disk_loading; AP_Float VTOL_roll_scale; AP_Float VTOL_pitch_scale; AP_Float VTOL_yaw_scale; AP_Float disk_loading_min_outflow; AP_MotorsTailsitter* tailsitter_motors; private: // Tailsitter specific log message struct PACKED log_tailsitter { LOG_PACKET_HEADER; uint64_t time_us; float throttle_scaler; float speed_scaler; float min_throttle; }; // Data to be logged struct { float throttle_scaler; float speed_scaler; float min_throttle; } log_data; bool setup_complete; // true when flying a tilt-vectored tailsitter bool _is_vectored; // true is outputs are configured bool _have_elevator; bool _have_aileron; bool _have_rudder; bool _have_elevon; bool _have_v_tail; // refences for convenience QuadPlane& quadplane; AP_MotorsMulticopter*& motors; // transition logic Tailsitter_Transition* transition; }; // Transition for tailsitters class Tailsitter_Transition : public Transition { friend class Tailsitter; public: Tailsitter_Transition(QuadPlane& _quadplane, AP_MotorsMulticopter*& _motors, Tailsitter& _tailsitter):Transition(_quadplane, _motors), tailsitter(_tailsitter) {}; void update() override; void VTOL_update() override; void force_transition_complete() override; bool complete() const override { return transition_state == TRANSITION_DONE; } // setup for the transition back to fixed wing void restart() override; uint8_t get_log_transition_state() const override { return static_cast(transition_state); } bool active_frwd() const override { return transition_state == TRANSITION_ANGLE_WAIT_FW; } bool show_vtol_view() const override; void set_FW_roll_pitch(int32_t& nav_pitch_cd, int32_t& nav_roll_cd) override; bool allow_stick_mixing() const override; MAV_VTOL_STATE get_mav_vtol_state() const override; bool set_VTOL_roll_pitch_limit(int32_t& nav_roll_cd, int32_t& nav_pitch_cd) override; bool allow_weathervane() override; private: enum { TRANSITION_ANGLE_WAIT_FW, TRANSITION_ANGLE_WAIT_VTOL, TRANSITION_DONE } transition_state; // for transition to VTOL flight uint32_t vtol_transition_start_ms; float vtol_transition_initial_pitch; // for rate limit of VTOL flight uint32_t vtol_limit_start_ms; float vtol_limit_initial_pitch; // for rate limit of FW flight uint32_t fw_limit_start_ms; float fw_limit_initial_pitch; // for transition to FW flight uint32_t fw_transition_start_ms; float fw_transition_initial_pitch; // time when we were last in a vtol control mode uint32_t last_vtol_mode_ms; Tailsitter& tailsitter; };