classdef Motor < Bay
% Motor: Represents the motor configuration for a rocket.
%
%   Constructor:
%       - Motor: Creates an instance of the Motor class.
%           Loaded config: rocketConfig.m > motor
%           Loaded data: motors.mat
%           Arguments:
%               - mission: Mission, mission object
%               - varIn: (optional) config source. Alternative to config.m file
  
    properties
        name                {mustBeTextScalar} = '' % [-]  Motor name
        position                                    % [m] Absolute position, relative to nose base
        length                                      % [m]  Total length (motor + tank)
        inertia                                     % [kg*m^2] Total Motor inertia (Body reference)
        cutoffTime          double                  % [s]  Shutdown time
        tankLength          double                  % [m]  Tank length
        ignitionTransient   double                  % [s]  Ignition transient duration
        cutoffTransient     double                  % [s]  Cutoff transient duration
        time                double                  % [s]  Engine time vector
        thrust              double                  % [N]  Engine thrust vector
        fuelMass            double                  % [kg] Fuel (grain) initial mass
        oxidizerMass        double                  % [kg] Oxidizer initial mass
        propellantMass      double                  % [Kg] Propellant Mass (in time)
        structureMass       double                  % [kg] Engine Structural Mass
        fuselageMass        double                  % [kg] Fuselage of the engine only
        xCg                                         % [m]  Engine xcg from tank tip
        pe                  double                  % [Pa] Eflux pressure
        ae                  double                  % [Pa] Eflux Area
    end

    properties(Dependent)
        mass                                        % [kg] Total Motor mass
        fuselageXCg         double                  % [m]  xcg of the engine fuselage only from tank tip
        isHRE             logical                   % [-] Flag relateed to the type of motor: true if HRE
    end

    properties(Access = protected)        
        configName = 'rocketConfig.m'
        variableName = 'motor'
        mission Mission = Mission()
    end

    methods
        function obj = Motor(mission, varIn)
            arguments(Input)
                mission Mission = Mission()
                varIn = []
            end
            obj@Bay(mission, varIn);
        end

        function set.name(obj, name)
            obj.name = name;
            obj.loadData();
        end

        function mass = get.mass(obj)
            mass = obj.propellantMass + ... 
                obj.structureMass; %+ obj.fuselageMass;
        end

        function fuselageXCg = get.fuselageXCg(obj)
            fuselageXCg = (obj.length - ...
                obj.tankLength)/2 + obj.tankLength;   
        end

        function isHRE = get.isHRE(obj)
            isHRE = contains(obj.name, 'HRE');
        end
    end

    methods (Access = protected)
        function obj = loadData(obj)
            if isempty(obj.mission.name) || isempty(obj.name)
                return; 
            end
            load(fullfile(obj.mission.dataPath, 'motors.mat'), 'motors');
            chosenMotor = motors(strcmp({motors.MotorName}, obj.name));
            if isempty(chosenMotor)
                error(strcat('Unable to find engine: ', obj.name));
            end
            
            obj.length         = chosenMotor.L;    
            obj.tankLength     = chosenMotor.Ltank;
            obj.time           = chosenMotor.t;    
            obj.thrust         = chosenMotor.T;    
            obj.fuelMass       = chosenMotor.mFu;  
            obj.oxidizerMass   = chosenMotor.mOx;  
            obj.structureMass  = chosenMotor.mc;   
            obj.propellantMass = chosenMotor.m;
            obj.xCg            = chosenMotor.xcg; 
            obj.inertia        = [chosenMotor.Ixx; chosenMotor.Iyy; chosenMotor.Izz];
            obj.pe             = chosenMotor.Pe;   
            obj.ae             = chosenMotor.Ae;   
            obj.fuselageMass   = chosenMotor.mFus; 

            if isempty(obj.cutoffTime) || obj.cutoffTime > obj.time(end)
                obj.cutoffTime = obj.time(end);
            end
        end
    end
end