classdef multirotor < robotics.core.internal.NavigationModel
    %MULTIROTOR Guidance model for multirotor UAVs
    %   The MULTIROTOR class represents a reduced-order
    %   guidance model for a UAV (unmanned aerial vehicle). The model
    %   approximates the behavior of a closed-loop system consisting of an
    %   autopilot controller and a multirotor kinematic model for 3-D
    %   motion.
    %
    %   model = MULTIROTOR creates a multirotor
    %   motion model with double precision values used in
    %   input/output/configuration.
    %
    %   model = MULTIROTOR(DATATYPE) creates a
    %   multirotor motion model, with input/output/configuration value
    %   typed according to DATATYPE. Supported DATATYPE includes "double"
    %   and "single".
    %
    %   MULTIROTOR properties:
    %      Configuration - Multirotor autopilot control gains and mass in
    %                      kilograms
    %      DataType      - Interface and configuration value data type
    %      ModelType     - Motion model definition type
    %      Name          - Motion model name
    %
    %   MULTIROTOR methods:
    %      control       - Control commands for UAV
    %      copy          - Create a copy of motion model instance
    %      derivative    - Compute time derivative of Multirotor UAV states
    %      environment   - Environment inputs for Multirotor UAV
    %      state         - Multirotor UAV states
    %
    %   NOTE: The autopilot operates using Euler-angle control inputs near
    %   the neutral roll/pitch angle. Therefore, this model is susceptible
    %   to singularity of Euler angles when the pitch angle reaches +/-
    %   pi/2.
    %
    %   Example:
    %
    %      % Construct a multirotor motion model with double precision
    %      % interface and computation type.
    %      model = multirotor;
    %
    %      % Set state world XYZ coordinates.
    %      s = state(model);
    %      s(1:3) = [3;2;1];
    %
    %      % Set control command Roll and Thrust.
    %      u = control(model);
    %      u.Roll = 1;
    %      u.Thrust = 1;
    %
    %      % Create environment setting.
    %      e = environment(model);
    %
    %      % Compute time derivative of the state given current state,
    %      % control and environment.
    %      sdot = derivative(model, s, u, e);
    %
    %      % Perform simulation using ODE45 integration
    %      simOut = ode45(@(~,x)derivative(model,x,u,e), [0 1], s);

    %   Copyright 2018-2020 The MathWorks, Inc.

    %#codegen

    methods
        function obj = multirotor(varargin)
            %multirotor Construct multirotor guidance model
            
            obj@robotics.core.internal.NavigationModel('MultirotorGuidance', varargin{:});
        end
    end

    methods
        function stateDerivative = derivative(model, stateVector, controlStruct, environmentStruct)
            %DERIVATIVE Compute time derivative of the state based on multirotor model's equation of motion
            %
            %   STATEDERIVATIVE = DERIVATIVE(MODEL, STATEVECTOR,
            %   CONTROLSTRUCT, ENVIRONMENTSTRUCT). The STATEVECTOR,
            %   CONTROLSTRUCT, and ENVIRONMENTSTRUCT inputs are generated
            %   by calling the functions: state(MODEL), control(MODEL), and
            %   environment(MODEL), respectively. These inputs are used to
            %   calculate the time derivative of the UAV states.

            stateDerivative = derivative@robotics.core.internal.NavigationModel(model, stateVector, controlStruct, environmentStruct);
        end

        function u = control(model)
            %CONTROL Control commands for UAV
            %
            %   U = CONTROL(MODEL) returns a struct with the following
            %   fields: Roll, Pitch, YawRate, and Thrust. Each is a scalar
            %   of same type as MODEL.DataType.
            u = control@robotics.core.internal.NavigationModel(model);
        end

        function s = state(model)
            %STATE Multirotor UAV states
            %
            %   S = STATE(MODEL) returns a 13-element vector of a UAV state:
            %      - 3x1 position ([X Y Z])
            %      - 3x1 velocity in north-east-down flat earth coordinates
            %      - 3x1 euler angles of multirotor attitude (flat earth ZYX sequence)
            %      - 3x1 Angular velocity along body frame axis
            %      - scalar for Thrust
            %   Default: zeros(13,1,model.DataType)
            
            s = state@robotics.core.internal.NavigationModel(model);
        end

        function e = environment(model)
            %ENVIRONMENT Environment inputs for Multirotor UAV
            %
            %   E = ENVIRONMENT(MODEL) returns a struct with field 'Gravity',
            %   E.Gravity is a scalar of same type as MODEL.DataType.
            e = environment@robotics.core.internal.NavigationModel(model);
        end
        
        function copyObj = copy(model)
            %COPY Create deep copy of model
            %
            %   COPYOBJ = COPY(MODEL) returns a deep copy of the model
            
            copyObj = copy@robotics.core.internal.NavigationModel(model);
        end
    end
    
    methods (Access = protected)
        function model = getModelWithDefaultConfiguration(obj)
            %getModelWithDefaultConfiguration create a multirotor model of
            %the same data type as input
            
            model = multirotor(obj.DataType);
        end
    end
end
