diff --git a/classes/Bay.m b/classes/Bay.m index 9e35314776a008f3ff0a205a600d58a4eaefb9b3..a364fa039a1d2e0b6f973afe495df7e12d087eb9 100644 --- a/classes/Bay.m +++ b/classes/Bay.m @@ -1,14 +1,21 @@ -classdef Bay < Component +classdef Bay < Component & matlab.mixin.Heterogeneous % An abstraction class that enables a standardized management of data % Properties and methods implemented in the Component class will % impact every physical component of the rocket (e.g. motor, elc ...) - properties (Abstract) + properties(Abstract) + position % [m] Absolute position, relative to previous component length % [m] Total bay length diameter % [m] Diameter of the bay mass % [kg] Total bay mass xCg % [m] Cg relative to bay upper side inertia % [kg*m^2] Total bay inertia (Body reference) end + + methods (Static,Sealed,Access=protected) + function default = getDefaultScalarElement + default = Boat; + end + end end diff --git a/classes/Config.m b/classes/Config.m index 16976061a8b169089b0f10987c94a88989db40e0..0042af3dc0e9111361e7ad3b691a94062a824a69 100644 --- a/classes/Config.m +++ b/classes/Config.m @@ -38,6 +38,7 @@ classdef(Abstract) Config < handle obj preset char {mustBeMember(preset, {'readable', 'writable', ''})} = '' options.Superclass char = '' + options.Heterogeneous logical = 0 attributes.GetAccess char {mustBeMember(attributes.GetAccess, {'public', 'private', ''})} = '' attributes.SetAccess char {mustBeMember(attributes.SetAccess, {'public', 'private', ''})} = '' attributes.Dependent logical {mustBeMember(attributes.Dependent, [0, 1])} = [] @@ -88,10 +89,15 @@ classdef(Abstract) Config < handle end end propertiesOut = properties(1:ii); - valuesOut = cell(1, ii); if nargout == 2 - for i = 1:ii, valuesOut{i} = obj.(propertiesOut{i}); end + if isempty(options.Superclass) || ~options.Heterogeneous + valuesOut = cell(1, ii); + for i = 1:ii, valuesOut{i} = obj.(propertiesOut{i}); end + else + valuesOut(ii) = obj.(propertiesOut{1}); + for i = 1:ii, valuesOut(i) = obj.(propertiesOut{i}); end + end end end end diff --git a/classes/Rocket.m b/classes/Rocket.m index 66ed69cd44302657b7d0377e62da64b827ec8ed8..1eebb1bd0517f883c4091ba7c75dca922c5acf04 100644 --- a/classes/Rocket.m +++ b/classes/Rocket.m @@ -1,4 +1,4 @@ -classdef Rocket < Bay +classdef Rocket < Component %ROCKET Summary of this class goes here % Detailed explanation goes here @@ -9,9 +9,9 @@ classdef Rocket < Bay electronics Electronics = Electronics() airbrakes Airbrakes = Airbrakes() motor Motor = Motor() + fincan Fincan = Fincan() boat Boat = Boat() - fins Fins = Fins() pitot Pitot = Pitot() length @@ -30,20 +30,18 @@ classdef Rocket < Bay mission Mission end - properties(Access = private) - bays cell + properties(SetAccess = private) + absolutePositions % [m] Cg positions - 0 is set at nose base + bays (1, :) = Boat() % [Bay] All bays + baysNoMotor (1, :) = Boat() % [Bay] All non time-dependent Bays end methods % Getters / Setters function out = get.length(obj) if ~isempty(obj.length), out = obj.length; return; end - out.sum = obj.nose.length + obj.payload.length + obj.recovery.length + ... - obj.electronics.length + obj.airbrakes.length + obj.motor.length + ... - obj.boat.length; - - out.vect = [obj.nose.length, obj.payload.length, obj.recovery.length, ... - obj.electronics.length, obj.airbrakes.length, obj.motor.length, ... - obj.boat.length]; % [1 x nBays] + % Do not consider Boat length, as motor bay already covers boat + out = sum([obj.bays(1:end-1).length]); + if out == 0, out = []; end end function out = get.diameter(obj) @@ -53,23 +51,40 @@ classdef Rocket < Bay function out = get.mass(obj) if ~isempty(obj.mass), out = obj.mass; return; end - out = obj.nose.mass + obj.payload.mass + obj.recovery.mass + ... - obj.electronics.mass + obj.airbrakes.mass + obj.motor.mass + ... - obj.boat.mass + obj.fins.mass; + if size(obj.bays, 2) == 1, out = []; return; end + out = obj.massNoMotor + obj.motor.mass; + if out == 0, out = []; end end function out = get.massNoMotor(obj) if ~isempty(obj.massNoMotor), out = obj.massNoMotor; return; end - out = obj.nose.mass + obj.payload.mass + obj.recovery.mass + ... - obj.electronics.mass + obj.airbrakes.mass + obj.motor.fuselageMass + ... - obj.boat.mass + obj.fins.mass; + if size(obj.baysNoMotor, 2) == 1, out = []; return; end + out = sum([obj.baysNoMotor.mass]); end function out = get.xCg(obj) if ~isempty(obj.xCg), out = obj.xCg; return; end - out = [obj.nose.xCg, obj.payload.xCg, obj.recovery.xCg, ... - obj.electronics.xCg, obj.airbrakes.xCg, obj.motor.xCg, ... - obj.boat.xCg, obj.fins.xCg]; % [nTspan x nBays] + %massWeighted = obj.bays + out = 0; + % fun = @(bay) out + bay.mass*2; + % out = cellfun(fun, obj.bays); + % out = out/obj.mass; + % out = [obj.nose.xCg, obj.payload.xCg, obj.recovery.xCg, ... + % obj.electronics.xCg, obj.airbrakes.xCg, obj.motor.xCg, ... + % obj.boat.xCg, obj.fincan.xCg]; % [nTspan x nBays] + end + + function out = get.absolutePositions(obj) + out = zeros(1, size(obj.bays, 2)); + out(1) = -obj.bays(1).length; + for i = 2:size(obj.bays, 2) + bay = obj.bays(i); + if ~isempty(bay.position) + out(i) = sum([obj.bays(2:i-2).length, bay.position]); + continue; + end + out(i) = sum([obj.bays(2:i-1).length]); + end end function out = get.xCp(obj) @@ -83,14 +98,12 @@ classdef Rocket < Bay % initialized as a matrix [nTspan x nBays] or [nTspan x 1]. % Otherwise we could compute inertia without motor first and % then add the motor as a vector - if ~isempty(obj.inertia) && ~isempty(obj.nose.inertia) ... - && ~isempty(obj.payload.inertia) && ~isempty(obj.recovery.inertia) ... - && ~isempty(obj.electronics.inertia) && ~isempty(obj.airbrakes.inertia) ... - && ~isempty(obj.motor.inertia) && ~isempty(obj.boat.inertia) && ~isempty(obj.fins.inertia) + if ~isempty(obj.xCp), out = obj.inertia; return; end + % && ~isempty(obj.nose.inertia) ... + % && ~isempty(obj.payload.inertia) && ~isempty(obj.recovery.inertia) ... + % && ~isempty(obj.electronics.inertia) && ~isempty(obj.airbrakes.inertia) ... + % && ~isempty(obj.motor.inertia) && ~isempty(obj.boat.inertia) && ~isempty(obj.fins.inertia) - out = obj.inertia; - return; - end % Ixx = [obj.nose.inertia(:,1), obj.payload.inertia(:,1), obj.recovery.inertia(:,1), ... % obj.electronics.inertia(:,1), obj.airbrakes.inertia(:,1), obj.motor.inertia(:,1), ... % obj.boat.inertia(:,1), obj.fins.inertia(:,1)]; % [nTspan x nBays] @@ -134,7 +147,7 @@ classdef Rocket < Bay mission Mission = Mission() varIn = [] end - obj@Bay(mission, varIn); + obj@Component(mission, varIn); obj.mission = mission; %% Loading data @@ -147,10 +160,11 @@ classdef Rocket < Bay obj.airbrakes = Airbrakes(mission, vars); obj.motor = Motor(mission, vars); obj.boat = Boat(mission, vars); - obj.fins = Fins(mission, vars); + obj.fincan = Fincan(mission, vars); obj.pitot = Pitot(mission, vars); - - [~, obj.bays] = obj.getProperties(Superclass='Bay'); + + [~, obj.bays] = obj.getProperties(Superclass='Bay', Heterogeneous=1); + obj.baysNoMotor = [obj.bays(1:5), obj.bays(7:end)]; % Take all bays except motor end end end diff --git a/classes/bays/Airbrakes.m b/classes/bays/Airbrakes.m index d6969016f5c1f3a3a58ad211e5eafd5dbef1db02..c4d67b5ca8a8766a60976ef8d1572df3a2bdf803 100644 --- a/classes/bays/Airbrakes.m +++ b/classes/bays/Airbrakes.m @@ -14,6 +14,7 @@ classdef Airbrakes < Bay maxMach double % [-] Maximum Mach at which airbrakes can be used servoOmega double % [rad/s] Servo-motor angular velocity height double % [m] Block airbrakes opening coordinate ( First entry must be 0! ) + position % [m] Offset with respect to other bays (negative -> shift forward) length % [m] Total bay length diameter % [m] Diameter of the bay mass % [kg] Total bay mass diff --git a/classes/bays/Boat.m b/classes/bays/Boat.m index 6749151deb5e73563c644ad622d454bc6fff81b5..068eff1933677704dbbfd29321fb2f3512d09ca7 100644 --- a/classes/bays/Boat.m +++ b/classes/bays/Boat.m @@ -3,6 +3,7 @@ classdef Boat < Bay % Detailed explanation goes here properties type {mustBeMember(type, {'', 'CONE', 'OGIVE'})} = '' % [] Boat type + position % [m] Absolute position, relative to nose base length % [m] Total bay length diameter % [m] Final diameter of the bay mass % [kg] Total bay mass diff --git a/classes/bays/Electronics.m b/classes/bays/Electronics.m index 6a02f418ee02a1dad3e3cb8c55461b2be7079e44..3da511198d51ad5214082d982712d382c883fa9b 100644 --- a/classes/bays/Electronics.m +++ b/classes/bays/Electronics.m @@ -3,6 +3,8 @@ classdef Electronics < Bay % Properties and methods implemented in the Component class will % impact every physical component of the rocket (e.g. motor, elc ...) properties + offset = 0 + position % [m] Absolute position, relative to nose base length % [m] Total bay length diameter % [m] Diameter of the bay mass % [kg] Total bay mass diff --git a/classes/components/Fins.m b/classes/bays/Fincan.m similarity index 73% rename from classes/components/Fins.m rename to classes/bays/Fincan.m index 4987e4f5bcaa5e0ee3a0c9cdfb833318029973f5..fba4ea2c371793b6fea071ec0636576ff0e621eb 100644 --- a/classes/components/Fins.m +++ b/classes/bays/Fincan.m @@ -1,10 +1,14 @@ -classdef Fins < Component +classdef Fincan < Bay %FINS Summary of this class goes here % Detailed explanation goes here properties - mass double % [kg] Fins mass - xCg double % [m] Cg from fins root chord tip + mass % [kg] Fins mass + position % [m] Absolute position, relative to nose base + length + diameter + inertia + xCg % [m] Cg from fins root chord tip rootChord double % [m] attached chord length freeChord double % [m] free chord length height double % [m] fin heigth @@ -18,17 +22,17 @@ classdef Fins < Component properties(Access = protected) configName = 'rocketConfig.m' - variableName = 'fins' + variableName = 'fincan' mission Mission = Mission() end methods - function obj = Fins(mission, varIn) + function obj = Fincan(mission, varIn) arguments(Input) mission Mission = Mission() varIn = [] end - obj@Component(mission, varIn); + obj@Bay(mission, varIn); end end end \ No newline at end of file diff --git a/classes/bays/Motor.m b/classes/bays/Motor.m index 26602e4ef28e9032e990912bda044f2be6b63e74..42e401966bce9b7eaf5d4daa8357657ecbd842c8 100644 --- a/classes/bays/Motor.m +++ b/classes/bays/Motor.m @@ -4,6 +4,7 @@ classdef Motor < Bay properties name {mustBeTextScalar} = '' % [-] Motor name + position % [m] Absolute position, relative to nose base length % [m] Total length (motor + tank) diameter % [m] Diameter of the Motor inertia % [kg*m^2] Total Motor inertia (Body reference) @@ -15,6 +16,7 @@ classdef Motor < Bay 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 @@ -24,7 +26,6 @@ classdef Motor < Bay properties(Dependent) mass % [kg] Total Motor mass - propellantMass double % [Kg] Propellant Mass (in time) fuselageXCg double % [m] xcg of the engine fuselage only from tank tip end @@ -48,13 +49,9 @@ classdef Motor < Bay obj.loadData(); end - function propellantMass = get.propellantMass(obj) - propellantMass = obj.fuelMass + obj.oxidizerMass; - end - function mass = get.mass(obj) mass = obj.propellantMass + ... - obj.structureMass + obj.fuselageMass; + obj.structureMass; %+ obj.fuselageMass; end function fuselageXCg = get.fuselageXCg(obj) @@ -78,6 +75,7 @@ classdef Motor < Bay 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; diff --git a/classes/bays/Nose.m b/classes/bays/Nose.m index aa69463b564be3cf0263e86dceb851dbd12234fe..8906d68f53beef1dc904aa47bcfe918e018268a6 100644 --- a/classes/bays/Nose.m +++ b/classes/bays/Nose.m @@ -8,6 +8,7 @@ classdef Nose < Bay power double % [-] Nosecone power type parameter pMod double % [-] P coefficient for modified nosecone shapes cMod double % [-] C coefficient for modified nosecone shapes + position % [m] Absolute position, relative to nose base length % [m] Total bay length diameter % [m] Diameter of the bay mass % [kg] Total bay mass diff --git a/classes/bays/Payload.m b/classes/bays/Payload.m index 4af058455066f0af49e796af74bd4b0073d8beef..3db6c22d3f7ea066a821ff49dde1e2553b644c2d 100644 --- a/classes/bays/Payload.m +++ b/classes/bays/Payload.m @@ -2,6 +2,7 @@ classdef Payload < Bay %GEOMETRY Summary of this class goes here % Detailed explanation goes here properties + position % [m] Absolute position, relative to nose base length % [m] Total bay length diameter % [m] Diameter of the bay mass % [kg] Total bay mass diff --git a/classes/bays/Recovery.m b/classes/bays/Recovery.m index ce78221e1262718dc329ca79a7c81fc67f3b4f12..2c34c587a52d9c87df7713923c5c598acfa1a45a 100644 --- a/classes/bays/Recovery.m +++ b/classes/bays/Recovery.m @@ -2,6 +2,7 @@ classdef Recovery < Bay %GEOMETRY Summary of this class goes here % Detailed explanation goes here properties + position % [m] Absolute position, relative to nose base length % [m] Total bay length diameter % [m] Diameter of the bay mass % [kg] Total bay mass diff --git a/missions/2024_Lyra_Roccaraso_September/config/rocketConfig.m b/missions/2024_Lyra_Roccaraso_September/config/rocketConfig.m index 8b312179cecb9e11d0fe7739618c469fe9b57344..bcdcd72d95bfa1c00a1bd992eecdea38e978f158 100644 --- a/missions/2024_Lyra_Roccaraso_September/config/rocketConfig.m +++ b/missions/2024_Lyra_Roccaraso_September/config/rocketConfig.m @@ -15,7 +15,7 @@ rocket.xCp = []; %% NOSE nose = Nose(); -nose.length = 000; % [m] Nosecone Length +nose.length = 0.3; % [m] Nosecone Length nose.diameter = 000; % [m] Nosecone Diameter nose.mass = 000; % [m] Nosecone Inertia nose.inertia = 000; % [m] Nosecone Mass @@ -27,27 +27,27 @@ nose.cMod = 000; %1.799127e-01; % [-] C coefficient %% PLD payload = Payload(); -payload.length = 0; +payload.length = 0.1; payload.diameter = 0; payload.mass = 0; payload.inertia = 0; -%% ELC -electronics = Electronics(); - -electronics.length = 000; -electronics.diameter = 000; -electronics.mass = 000; -electronics.inertia = 000; - %% RCS recovery = Recovery(); -recovery.length = 0; +recovery.length = 0.2; recovery.diameter = 0; recovery.mass = 0; recovery.inertia = 0; +%% ELC +electronics = Electronics(); + +electronics.length = 0.1; +electronics.diameter = 000; +electronics.mass = 000; +electronics.inertia = 000; + %% ARB airbrakes = Airbrakes(); @@ -87,24 +87,27 @@ boat.mass = 0; boat.inertia = 0; %% FINS -fins = Fins(); - -fins.mass = 0; -fins.xCg = 0; -fins.rootChord = 0.30; % [m] attached chord length -fins.freeChord = 0.14; % [m] free chord length -fins.height = 0.11; % [m] fin heigth -fins.deltaXFreeChord = 0.13; % [m] start of Chord 2 measured from start of Chord 1 -fins.nPanel = 3; % [m] number of fins -fins.leadingEdgeRadius = [0 0]; % [deg] Leading edge radius at each span station -fins.axialDistance = 0.012; % [m] distance between end of root chord and end of center body -fins.semiThickness = 0.00175; % [m] fin semi-thickness -fins.maxThicknessPosition = 0.00175; % [m] Fraction of chord from leading edge to max thickness +fincan = Fincan(); + +fincan.position = 1.5; +fincan.mass = 0; +fincan.xCg = 0; +fincan.rootChord = 0.30; % [m] attached chord length +fincan.freeChord = 0.14; % [m] free chord length +fincan.height = 0.11; % [m] fin heigth +fincan.deltaXFreeChord = 0.13; % [m] start of Chord 2 measured from start of Chord 1 +fincan.nPanel = 3; % [m] number of fins +fincan.leadingEdgeRadius = [0 0]; % [deg] Leading edge radius at each span station +fincan.axialDistance = 0.012; % [m] distance between end of root chord and end of center body +fincan.semiThickness = 0.00175; % [m] fin semi-thickness +fincan.maxThicknessPosition = 0.00175; % [m] Fraction of chord from leading edge to max thickness %% PITOT pitot = Pitot(); -protuberances.xDistance = 1.517; % [m] axial position from nosecone base -protuberances.n = 3; % [-] number of brakes -protuberances.length = 0.008; % [m] brakes thickness -protuberances.width = 0.1002754821; % [m] brakes width (normal) \ No newline at end of file +pitot.length = 0; % [m] Pitot tube length +pitot.diameter = 0; % [m] Pitot tube diameter +pitot.initialConeLength = 0; % [m] Pitot initial conic section length +pitot.finalConeLength = 0; % [m] Pitot final conic section length +pitot.initialConeDiameter = 0; % [m] Pitot initial conic section diameter +pitot.finalConeDiameter = 0; % [m] Pitot final conic section diameter \ No newline at end of file