From c8301e3e4c0d66c05e175c399313e6e783e3af94 Mon Sep 17 00:00:00 2001 From: MatteoGotti <matteo.gotti@skywarder.eu> Date: Sun, 21 Apr 2024 22:36:01 +0200 Subject: [PATCH] [refactoring-ode] updates - Rocket and Motor classes - all the configs for Lyra Portugal - createDissileInput --- classes/Rocket.m | 134 ++++++++------- classes/bays/Motor.m | 8 +- functions/miscellaneous/createDissileInput.m | 153 +++++++++--------- .../config/environmentConfig.m | 4 +- .../config/parachuteConfig.m | 16 +- .../config/rocketConfig.m | 90 +++++------ missions/missionConfig.m | 2 +- 7 files changed, 212 insertions(+), 195 deletions(-) diff --git a/classes/Rocket.m b/classes/Rocket.m index b67d0b8..2ad97d1 100644 --- a/classes/Rocket.m +++ b/classes/Rocket.m @@ -1,14 +1,14 @@ classdef Rocket < Component -% Rocket: Contains and manages all bays -% -% Constructor: -% - Rocket: Creates an instance of the Rocket class. -% Loaded config: rocketConfig.m > rocket (for overrides) -% Loaded data: - -% Arguments: -% - mission: Mission, mission object -% - varIn: (optional) config source. Alternative to config.m -% file + % Rocket: Contains and manages all bays + % + % Constructor: + % - Rocket: Creates an instance of the Rocket class. + % Loaded config: rocketConfig.m > rocket (for overrides) + % Loaded data: - + % Arguments: + % - mission: Mission, mission object + % - varIn: (optional) config source. Alternative to config.m + % file properties payload Payload % [-] Payload bay @@ -22,6 +22,7 @@ classdef Rocket < Component parachutes Parachute % [-] Parachutes onboard length double % [m] Total length + lengthCenterNoMot double % [m] Center length - no nose, no motor diameter double % [m] Diameter mass double % [kg] Total mass massNoMotor double % [kg] Mass without motor @@ -29,7 +30,7 @@ classdef Rocket < Component inertiaNoMotor double % [kg*m^2] Inertia without motor xCg double % [m] Total xCg xCgNoMotor double % [m] xCg without motor - + descentStagesNum double % [-] Number of descent stages stagesMass double % [kg] Mass of stage 2, 3, .. without chutes end @@ -58,16 +59,21 @@ classdef Rocket < Component end methods % Updaters - function updateAbsolutePositions(obj) + function updateAbsolutePositions(obj) bDictionay = obj.bays; b = values(bDictionay); + if ~isempty(obj.lengthCenterNoMot) + obj.absolutePositions = dictionary(["motor", "rear"], ... + [obj.lengthCenterNoMot, obj.lengthCenterNoMot + obj.rear.position]); + return + end % Populate shift vectors (how much each bay shifts the next one back) % Shift overrides are applyed to the previous bay shift = zeros(size(b)); overrides = ~cellfun(@isempty, {b.position}); overridesShift = logical([overrides(2:end), 0]); - + shift(overridesShift) = b(overrides).position; shift(~overridesShift) = [b(~overridesShift).length]; @@ -75,12 +81,14 @@ classdef Rocket < Component absPositions = absPositions + ... (obj.payload.length - obj.payload.noseLength); obj.absolutePositions = dictionary(keys(bDictionay), absPositions); - end + end function updateGeometry(obj) - if isempty(obj.length) - % Measures rear - tip + if ~isempty(obj.lengthCenterNoMot) + obj.length = obj.lengthCenterNoMot + obj.motor.length + obj.payload.noseLength; + else obj.length = (obj.absolutePositions("rear") + obj.bays("rear").length) + obj.bays("payload").noseLength; + obj.lengthCenterNoMot = obj.absolutePositions("motor"); end if isempty(obj.crossSection) obj.crossSection = 0.25*pi*obj.diameter^2; @@ -119,7 +127,7 @@ classdef Rocket < Component end % Motor mass is 5th element of "bays" obj.xCg = (obj.xCgNoMotor*obj.massNoMotor + ... - obj.motor.mass.*(obj.motor.xCg+obj.absolutePositions('motor')'))./ ... + obj.motor.mass.*(obj.motor.xCg+obj.lengthCenterNoMot))./ ... obj.mass; end @@ -133,7 +141,7 @@ classdef Rocket < Component % Assumption: xCgs are close to rocket axis inertias = [bNoMotor.inertia]; temp = inertias(2:3, :) + ... - (obj.xCgNoMotor' - (aPosNoMotor + [bNoMotor.xCg])).^2 .* [bNoMotor.mass]; + (obj.xCgNoMotor' - (aPosNoMotor + [bNoMotor.xCg])).^2 .* [bNoMotor.mass]; obj.inertiaNoMotor = [inertias(1); sum(temp, 2)]; end @@ -141,19 +149,19 @@ classdef Rocket < Component if ~isempty(obj.inertia) return; end - % [3x634] Ix, Iy, Iz + % [3xN] Ix, Iy, Iz % Assumption: xCgs are close to rocket axis motorInertia = obj.motor.inertia(2:3, :) + ... (obj.xCg - (obj.absolutePositions('motor') + obj.motor.xCg)).^2 .* obj.motor.mass; baysInertia = obj.inertiaNoMotor(2:3, :) + ... (obj.xCg - obj.xCgNoMotor).^2 .* obj.massNoMotor; - obj.inertia = [obj.motor.inertia(1, :) + obj.inertiaNoMotor(1, :); + obj.inertia = [obj.motor.inertia(1, :) + obj.inertiaNoMotor(1, :); motorInertia + baysInertia]; obj.inertiaDot = diff(obj.inertia, 1, 2)./diff(obj.motor.time); obj.inertiaDot(:, end + 1) = obj.inertiaDot(:, end); - end + end function updateCutoff(obj) obj.cutoffInertia = interpLinear(obj.motor.time, obj.inertia, obj.motor.cutoffTime); @@ -177,21 +185,29 @@ classdef Rocket < Component methods(Access = protected) % Loaders function obj = loadData(obj) if isempty(obj.mission.name) - return; + return; + end + varNames = {'total', 'geometry', 'state', 'finsCN'}; + dataCoeffs = load(fullfile(obj.mission.dataPath, 'aeroCoefficients.mat'), ... + varNames{:}); + dataCoeffsHighAOA = load(fullfile(obj.mission.dataPath, 'aeroCoefficientsHighAOA.mat'), ... + varNames{:}); + + if isfield(dataCoeffs, "finsCN") && isfield(dataCoeffsHighAOA, "finsCN") + obj.coefficients.finsCN = dataCoeffs.finsCN; + obj.coefficientsHighAOA.finsCN = dataCoeffsHighAOA.finsCN; end - load(fullfile(obj.mission.dataPath, 'aeroCoefficients.mat'), ... - 'total', 'finsCN', 'geometry', 'state'); - obj.coefficients.total = total; - obj.coefficients.finsCN = finsCN; - obj.coefficients.geometry = geometry; - obj.coefficients.state = state; - - load(fullfile(obj.mission.dataPath, 'aeroCoefficientsHighAOA.mat'), ... - 'total', 'finsCN', 'geometry', 'state'); - obj.coefficientsHighAOA.total = total; - obj.coefficientsHighAOA.finsCN = finsCN; - obj.coefficientsHighAOA.geometry = geometry; - obj.coefficientsHighAOA.state = state; + + varNames = varNames{1:end - 1}; + if all(and(isfield(dataCoeffs, varNames), ... + isfield(dataCoeffsHighAOA, varNames))) + obj.coefficients.total = dataCoeffs.total; + obj.coefficientsHighAOA.total = dataCoeffsHighAOA.total; + obj.coefficients.geometry = dataCoeffs.geometry; + obj.coefficientsHighAOA.geometry = dataCoeffsHighAOA.geometry; + obj.coefficients.state = dataCoeffs.state; + obj.coefficientsHighAOA.state = dataCoeffsHighAOA.state; + end end end @@ -225,7 +241,7 @@ classdef Rocket < Component function [coeffsValues, angle0] = interpCoeffs(obj, t, alpha, mach, beta, alt, c) % interpCoeffs - interpolation of aerodynamic coefficients. - % + % % INPUTS: % - t, double [1,1], integration time, [s]; % - alpha, double[1,1], angle of attack, []; @@ -233,11 +249,11 @@ classdef Rocket < Component % - beta, double[1,1], sideslip angle, []; % - alt, double[1,1], altitude, [m]; % - c, double[1,1], aerobrakes control variable, []; - % + % % OUTPUTS: % - coeffsValues, array [16,1], aerodynamic coefficients; % - angle0, array [2,1], array of the reference aerodynamic angles. - + if mach > obj.airbrakes.maxMach c = 0; end @@ -248,22 +264,22 @@ classdef Rocket < Component [nearBeta, indexBeta] = nearestValSorted(obj.coefficients.state.betas*pi/180, beta); [~, indexAlt] = nearestValSorted(obj.coefficients.state.altitudes, alt); [~, indexControl] = nearestValSorted(obj.coefficients.state.hprot, h); - + angle0 = [nearAlpha; nearBeta]; - - if t >= obj.motor.cutoffTime + + if t >= obj.motor.cutoffTime % Interpolate on airbrake control % Uses end xCg, even if tCutOff < tBurnTime num = length(obj.coefficients.state.hprot); %#ok<CPROPLC> index1 = indexControl; index2 = indexControl + 1; - if index2 > num + if index2 > num if num == 1 coeffsValues = obj.coefficients(:, indexAlpha, indexMach, indexBeta, indexAlt, 1, end); return; else index2 = index2 - 1; - index1 = index1 - 1; + index1 = index1 - 1; end end @@ -272,27 +288,27 @@ classdef Rocket < Component deltaH = obj.coefficients.state.hprot(index2) - obj.coefficients.state.hprot(index1); coeffsValues = ( (h - obj.coefficients.state.hprot(index1))/deltaH)*(VE - VF) + VF; - else + else % Interpolate on xCg, close airbrakes num = 1:1:length(obj.coefficients.state.xcgTime)-1; %#ok<CPROPLC> indexXcg = t >= obj.coefficients.state.xcgTime(1:end-1) & t < obj.coefficients.state.xcgTime(2:end); index1 = num(indexXcg); index2 = index1 + 1; - + VF = obj.coefficients.total(:, indexAlpha, indexMach, indexBeta, indexAlt, indexControl, index1); VE = obj.coefficients.total(:, indexAlpha, indexMach, indexBeta, indexAlt, indexControl, index2); - + deltaT = obj.coefficients.state.xcgTime(index2) - obj.coefficients.state.xcgTime(index1); coeffsValues = ( (t - obj.coefficients.state.xcgTime(index1))/deltaT)*(VE - VF) + VF; end end function checks = checkGeometry(obj) - % checkGeometry - This methods checks if the rocket geometry + % checkGeometry - This methods checks if the rocket geometry % is consistent with the geometry of the % aerodynamic matrices % - % OUTPUTS: + % OUTPUTS: % - checks (n fields of geometry, 1): boolean value of the geometry checks xCgRocket = round([ ... @@ -321,18 +337,18 @@ classdef Rocket < Component ], 3); geometryTest = round([ - obj.coefficients.geometry.diameter; - obj.coefficients.geometry.lNose; - obj.coefficients.geometry.lCenter; - obj.coefficients.geometry.cMod; - obj.coefficients.geometry.pMod; - obj.coefficients.geometry.chord1; - obj.coefficients.geometry.chord2; - obj.coefficients.geometry.height; + obj.coefficients.geometry.diameter; + obj.coefficients.geometry.lNose; + obj.coefficients.geometry.lCenter; + obj.coefficients.geometry.cMod; + obj.coefficients.geometry.pMod; + obj.coefficients.geometry.chord1; + obj.coefficients.geometry.chord2; + obj.coefficients.geometry.height; obj.coefficients.geometry.deltaXLE; - obj.coefficients.geometry.nPanel; - obj.coefficients.geometry.boatL; - obj.coefficients.geometry.boatD; + obj.coefficients.geometry.nPanel; + obj.coefficients.geometry.boatL; + obj.coefficients.geometry.boatD; ], 3); checks = [ diff --git a/classes/bays/Motor.m b/classes/bays/Motor.m index 27b4c01..ec0572d 100644 --- a/classes/bays/Motor.m +++ b/classes/bays/Motor.m @@ -33,7 +33,7 @@ classdef Motor < Bay properties(Dependent) mass % [kg] Total Motor mass fuselageXCg double % [m] xcg of the engine fuselage only from tank tip - flagHRE logical % [-] Flag relateed to the type of motor: true if HRE + isHRE logical % [-] Flag relateed to the type of motor: true if HRE end properties(Access = protected) @@ -58,7 +58,7 @@ classdef Motor < Bay function mass = get.mass(obj) mass = obj.propellantMass + ... - obj.structureMass + obj.fuselageMass; + obj.structureMass; %+ obj.fuselageMass; end function fuselageXCg = get.fuselageXCg(obj) @@ -66,8 +66,8 @@ classdef Motor < Bay obj.tankLength)/2 + obj.tankLength; end - function flagHRE = get.flagHRE(obj) - flagHRE = contains(obj.name, 'HRE'); + function isHRE = get.isHRE(obj) + isHRE = contains(obj.name, 'HRE'); end end diff --git a/functions/miscellaneous/createDissileInput.m b/functions/miscellaneous/createDissileInput.m index 0802eac..a5216fe 100644 --- a/functions/miscellaneous/createDissileInput.m +++ b/functions/miscellaneous/createDissileInput.m @@ -1,10 +1,10 @@ -function [input] = createDissileInput(settings, vars) +function [input] = createDissileInput(rocket, vars) %{ createDissileInput - function to create the input file to run dissileMatcom INPUTS: - - settings, struct, containing the rocket's details + - rocket, Rocket object, containing the rocket's details - vars, struct, containing the simulation's details - Mach [1, NMACH] : contains the mach numbers to be computed (NMACH <= 20) - Alpha [1, NALPHA]: contains the alpha values to be computed [deg] @@ -30,26 +30,31 @@ REVISION: %} +arguments + rocket Rocket + vars +end + %% CHECK ERROR -if length(vars.Alpha) > 20 || length(vars.Mach) > 20 - error("dissileMatcom with alpha or mach > 20 cases is not yet compatible"); +if length(vars.alpha) > 20 || length(vars.mach) > 20 + error("dissileMatcom with alpha or mach > 20 cases is not yet compatible"); end -if not(any(vars.Alpha == 0)) - error('vars.Alpha does not contains 0'); +if not(any(vars.alpha == 0)) + error('vars.Alpha does not contains 0'); end -if not(any(vars.Alpha == 1)) - error('vars.Alpha does not contains 1'); +if not(any(vars.alpha == 1)) + error('vars.Alpha does not contains 1'); end -if not(any(vars.Alpha == -1)) - error('vars.Alpha does not contains -1'); +if not(any(vars.alpha == -1)) + error('vars.Alpha does not contains -1'); end -if not(isequal(vars.Alpha, -fliplr(vars.Alpha))) - error('vars.Alpha is not symmetric'); +if not(isequal(vars.alpha, -fliplr(vars.alpha))) + error('vars.Alpha is not symmetric'); end noses = {'CONICAL', 'OGIVE', 'POWER', 'HAACK', 'KARMAN', 'MHAACK'}; @@ -57,98 +62,100 @@ noses = {'CONICAL', 'OGIVE', 'POWER', 'HAACK', 'KARMAN', 'MHAACK'}; %% FLTCON % Flight conditions quantities input.fltcon.about = 'Flight conditions quantities'; -input.fltcon.MACH = vars.Mach; -input.fltcon.ALPHA = vars.Alpha; -input.fltcon.BETA = vars.Beta; -input.fltcon.ALT = vars.Alt; +input.fltcon.MACH = vars.mach; +input.fltcon.ALPHA = vars.alpha; +input.fltcon.BETA = vars.beta; +input.fltcon.ALT = vars.alt; %% REFQ % Reference quantities input.refq.about = 'Reference quantities'; -input.refq.XCG = vars.xcg; % [m] Longitudinal position of C.G. (distance between C.G. and the base of the nose cone, LNOSE will be added later in dissileMatcom/GEOM) -input.refq.SREF = round(pi*settings.C^2/4, 5); % [m^2] Reference area -input.refq.LREF = settings.C; % [m] Longitudinal reference length -input.refq.LATREF = settings.C; % [m] Lateral reference length +input.refq.XCG = vars.xcg; % [m] Longitudinal position of C.G. (distance between C.G. and the base of the nose cone, LNOSE will be added later in dissileMatcom/GEOM) +input.refq.SREF = rocket.crossSection; % [m^2] Reference area +input.refq.LREF = rocket.diameter; % [m] Longitudinal reference length +input.refq.LATREF = rocket.diameter; % [m] Lateral reference length %% AXIBOD % Axisymmetric bodies quantities input.axibod.about = 'Axisymmetric body quantities'; %%% nose -input.axibod.TNOSE = find(strcmp(noses, settings.OgType))-1; % [0=CONICAL, 1=OGIVE, 2=POWER, 3=HAACK, 4=KARMAN, 5=MHAACK] ogive type -if strcmp(settings.OgType, 'MHAACK') - input.axibod.MHAACKCP = [settings.cMod settings.pMod]; % [-] CMOD PMOD mhaack parameters, set CMOD = 1/3 and PMOD = 1 to get a haack -elseif strcmp(settings.OgType, 'POWER') - input.axibod.POWER = settings.NosePower; % [-] Exponent of the power series, set a value between 0 and 1 +input.axibod.TNOSE = find(strcmp(noses, rocket.payload.noseType))-1; % [0=CONICAL, 1=OGIVE, 2=POWER, 3=HAACK, 4=KARMAN, 5=MHAACK] ogive type +if strcmp(rocket.payload.noseType, 'MHAACK') + input.axibod.MHAACKCP = [rocket.payload.noseCMod rocket.payload.nosePMod]; % [-] CMOD PMOD mhaack parameters, set CMOD = 1/3 and PMOD = 1 to get a haack +elseif strcmp(rocket.OgType, 'POWER') + input.axibod.POWER = rocket.payload.nosePower; % [-] Exponent of the power series, set a value between 0 and 1 end -input.axibod.LNOSE = settings.Lnose; % [m] Nose length -input.axibod.DNOSE = settings.C; % [m] Nose diameter at base +input.axibod.LNOSE = rocket.payload.noseLength; % [m] Nose length +input.axibod.DNOSE = rocket.diameter; % [m] Nose diameter at base input.axibod.TRUNC = false; %%% pitot -if isfield(settings,'PITOTCLI') - input.axibod.PITOTCLI = settings.PITOTCLI; % [m] Pitot initial conic section length - input.axibod.PITOTCLB = settings.PITOTCLB; % [m] Pitot final conic section length - input.axibod.PITOTCDI = settings.PITOTCDI; % [m] Pitot initial conic section diameter - input.axibod.PITOTCDB = settings.PITOTCDB; % [m] Pitot final conic section diameter - input.axibod.PITOTL = settings.PITOTL; % [m] Pitot tube length - input.axibod.PITOTD = settings.PITOTD; % [m] Pitot tube diameter +if ~isempty(rocket.pitot.initialConeLength) + input.axibod.PITOTCLI = rocket.pitot.initialConeLength; % [m] Pitot initial conic section length + input.axibod.PITOTCLB = rocket.pitot.finalConeLength; % [m] Pitot final conic section length + input.axibod.PITOTCDI = rocket.pitot.initialConeDiameter; % [m] Pitot initial conic section diameter + input.axibod.PITOTCDB = rocket.pitot.finalConeDiameter; % [m] Pitot final conic section diameter + input.axibod.PITOTL = rocket.pitot.length; % [m] Pitot tube length + input.axibod.PITOTD = rocket.PITOTD; % [m] Pitot tube diameter end %%% centerbody -input.axibod.LCENTR = settings.Lcenter; % [m] Centerbody length -input.axibod.DCENTR = settings.C; % [m] Centerbody diameter at base +input.axibod.LCENTR = rocket.lengthCenter; % [m] Centerbody length +input.axibod.DCENTR = rocket.diameter; % [m] Centerbody diameter at base %%% boattail -input.axibod.LAFT = settings.boatL; % [m] Boattail length -input.axibod.DAFT = settings.boatD; % [m] Boattail base diameter -if (isfield(settings, 'boatType')) - input.axibod.TAFT = settings.boatType; % [-] Boattail type +if (~isempty(rocket.rear.boatType)) + boats = {'CONICAL', 'OGIVE'}; + input.axibod.LAFT = rocket.rear.boatLength; % [m] Boattail length + input.axibod.DAFT = rocket.rear.boatFinalDiameter; % [m] Boattail base diameter + input.axibod.TAFT = find(strcmp(boats, rocket.rear.boatType))-1; % [-] Boattail type end -input.axibod.DEXIT = 0; % [m] Nozzle diameter for base drag calculation -input.axibod.BASE = false; % [-] +input.axibod.DEXIT = 0; % [m] Nozzle diameter for base drag calculation +input.axibod.BASE = false; % [-] %%% protub -if isfield(vars, 'hprot') && any(vars.hprot) - input.axibod.PROTUB = true; % Flag if protub exist - input.axibod.NPROT = 1; % [-] N° set protub - input.axibod.PTYPE = 'BLOCK'; % Protub type (only block exist) - input.axibod.XPROT = settings.xprot; % [m] Longitudinal distance from missile nose cone base to the geometric centroid of the protuberance set (if there is a pitot tube LNOSE will be added later in dissileMatcom/GEOM) - input.axibod.NLOC = settings.nloc; % [-] N° protub in each set - input.axibod.LPROT = settings.lprot; % [m] Length of protuberance - input.axibod.WPROT = settings.wprot; % [m] Width of protuberance - input.axibod.HPROT = vars.hprot; % [m] Height of protuberance - input.axibod.OPROT = 0; % [m] Vertical offset of protuberance +if ~isempty(vars.hprot) + input.axibod.PROTUB = true; % Flag if protub exist + input.axibod.NPROT = 1; % [-] N° set protub + input.axibod.PTYPE = 'BLOCK'; % Protub type (only block exist) + input.axibod.XPROT = rocket.airbrakes.xDistance; % [m] Longitudinal distance from missile nose cone base to the geometric centroid of the protuberance set (if there is a pitot tube LNOSE will be added later in dissileMatcom/GEOM) + input.axibod.NLOC = rocket.airbrakes.n; % [-] N° protub in each set + input.axibod.LPROT = rocket.airbrakes.thickness; % [m] Thickness of protuberance + input.axibod.WPROT = rocket.airbrakes.width; % [m] Width of protuberance + input.axibod.HPROT = vars.hprot; % [m] Height of protuberance + input.axibod.OPROT = 0; % [m] Vertical offset of protuberance else input.axibod.PROTUB = false; end %% FINSET1 -% Fin set 1 properties +%%% Fin set 1 properties input.finset1.about = 'Finset 1 properties'; -input.finset1.XLE = [settings.Lcenter - settings.d - settings.Chord1, ... -settings.Lcenter - settings.d - settings.Chord1 + settings.deltaXLE]; % [m] Distance from missile nose cone base to chord leading edge at each span location (LNOSE will be added later in dissileMatcom/GEOM) -input.finset1.NPANEL = settings.Npanel; % [-] Number of panels in fin set +input.finset1.XLE = [rocket.lengthCenter - rocket.rear.finsAxialDistance - ... + rocket.rear.finsRootChord, rocket.lengthCenter - rocket.rear.finsAxialDistance - ... + rocket.rear.finsRootChord + rocket.rear.finsDeltaXFreeChord]; % [m] Distance from missile nose cone base to chord leading edge at each span location (LNOSE will be added later in dissileMatcom/GEOM) +input.finset1.NPANEL = rocket.rear.nPanel; % [-] Number of panels in fin set input.finset1.PHIF = ... -(0:1:(settings.Npanel - 1)) * 360/settings.Npanel; % [deg] Roll angle of each fin measured clockwise from top vertical center looking forward -input.finset1.LER = settings.Ler; % [m] Leading edge radius at each span station -input.finset1.SSPAN = [0, settings.Height]; % [m] Semi-span locations -input.finset1.CHORD = [settings.Chord1, settings.Chord2]; % [m] Panel chord at each semi-span location -input.finset1.SECTYP = 0; % [0=HEX, 1=NACA, 2=ARC, 3=USER] Airfoil section type -input.finset1.ZUPPER = [settings.zupRaw/settings.Chord1, ... -settings.zupRaw/settings.Chord2]; % [-] Thickness-to-chord ratio of upper surface -input.finset1.LMAXU = [settings.LmaxuRaw/settings.Chord1, ... -settings.LmaxuRaw/settings.Chord2]; % [-] Fraction of chord from leading edge to maximum thickness of upper surface -input.finset1.LFLATU = [(settings.Chord1 - 2*settings.LmaxuRaw)/settings.Chord1,... -(settings.Chord2 - 2*settings.LmaxuRaw)/settings.Chord2]; % [-] Fraction of chord of constant thickness section of upper surface + (0:1:(rocket.rear.nPanel - 1)) * 360/rocket.rear.nPanel; % [deg] Roll angle of each fin measured clockwise from top vertical center looking forward +input.finset1.LER = rocket.rear.finsLeadingEdgeRadius; % [m] Leading edge radius at each span station +input.finset1.SSPAN = [0, rocket.rear.finsHeight]; % [m] Semi-span locations +input.finset1.CHORD = [rocket.rear.finsRootChord, rocket.rear.finsFreeChord]; % [m] Panel chord at each semi-span location +input.finset1.SECTYP = 0; % [0=HEX, 1=NACA, 2=ARC, 3=USER] Airfoil section type +input.finset1.ZUPPER = [rocket.rear.finsSemiThickness/rocket.rear.finsRootChord, ... + rocket.rear.finsSemiThickness/rocket.rear.finsFreeChord]; % [-] Thickness-to-chord ratio of upper surface +input.finset1.LMAXU = [rocket.rear.finsMaxThicknessPosition/rocket.rear.finsRootChord, ... + rocket.rear.finsMaxThicknessPosition/rocket.rear.finsFreeChord]; % [-] Fraction of chord from leading edge to maximum thickness of upper surface +input.finset1.LFLATU = [(rocket.rear.finsRootChord - 2*rocket.rear.finsMaxThicknessPosition)/rocket.rear.finsRootChord,... + (rocket.rear.finsFreeChord - 2*rocket.rear.finsMaxThicknessPosition)/rocket.rear.finsFreeChord]; % [-] Fraction of chord of constant thickness section of upper surface %% DO NOT MODIFY -input.fltcon.NALPHA = length(input.fltcon.ALPHA); % [-] Number of alphas -input.fltcon.NMACH = length(input.fltcon.MACH); % [-] Number of Machs +input.fltcon.NALPHA = length(input.fltcon.ALPHA); % [-] Number of alphas +input.fltcon.NMACH = length(input.fltcon.MACH); % [-] Number of Machs %% OPTIONS -input.printTxt = false; % if you want the coefficients printed in the command window -input.draw = false; % if you want the shape of your rocket plotted -input.HREflag = true; -input.axibod.precision = 11; % [-] 1-1001, how many points to approximate nose cone shape, default is 11 (NOTE: POWER SHAPE REQUIRES <= 401) +input.printTxt = false; % if you want the coefficients printed in the command window +input.draw = false; % if you want the shape of your rocket plotted +input.HREflag = rocket.motor.isHRE; +input.axibod.precision = 11; % [-] 1-1001, how many points to approximate nose cone shape, default is 11 (NOTE: POWER SHAPE REQUIRES <= 401) end diff --git a/missions/2024_Lyra_Portugal_October/config/environmentConfig.m b/missions/2024_Lyra_Portugal_October/config/environmentConfig.m index c434edc..8f66bc9 100644 --- a/missions/2024_Lyra_Portugal_October/config/environmentConfig.m +++ b/missions/2024_Lyra_Portugal_October/config/environmentConfig.m @@ -7,8 +7,8 @@ environment = Environment(); environment.lat0 = 39.388727; % [deg] Launchpad latitude environment.lon0 = -8.287842; % [deg] Launchpad longitude environment.z0 = 160; % [m] Launchpad Altitude -environment.pin1Length = 0.560; % [m] Distance from the upper pin to the upper tank cap -environment.pin2Length = 0.205; % [m] Distance from the lower pin to the lower tank cap +environment.pin1Length = 0.5603; % [m] Distance from the upper pin to the upper tank cap +environment.pin2Length = 0.2055; % [m] Distance from the lower pin to the lower tank cap environment.rampLength = 12; % [m] Total launchpad length environment.temperature = []; % [deg] Ground temperature correction diff --git a/missions/2024_Lyra_Portugal_October/config/parachuteConfig.m b/missions/2024_Lyra_Portugal_October/config/parachuteConfig.m index 4934298..7fad54c 100644 --- a/missions/2024_Lyra_Portugal_October/config/parachuteConfig.m +++ b/missions/2024_Lyra_Portugal_October/config/parachuteConfig.m @@ -20,12 +20,12 @@ parachute(1,1).expulsionSpeed = 5; % [m/s] Expulsion Speed parachute(2, 1) = Parachute(); parachute(2, 1).name = 'MAIN chute'; -parachute(2, 1).surface = 7.34; % [m^2] Surface +parachute(2, 1).surface = 14; % [m^2] Surface parachute(2, 1).mass = 1.05; % [kg] Parachute Mass -parachute(2, 1).cd = 1.75; % [/] Parachute Drag Coefficient +parachute(2, 1).cd = 0.6; % [/] Parachute Drag Coefficient parachute(2, 1).cl = 0; % [/] Parachute Lift Coefficient parachute(2, 1).finalAltitude = 0; % [m] Final altitude of the parachute -parachute(2, 1).cx = 1.2; % [/] Parachute Longitudinal Drag Coefficient +parachute(2, 1).cx = 1.15; % [/] Parachute Longitudinal Drag Coefficient parachute(2, 1).chordLength = 6; % [m] Shock Chord Length parachute(2, 1).chordK = 3000; % [N/m^2] Shock Chord Elastic Constant parachute(2, 1).chordC = 0; % [Ns/m] Shock Chord Dynamic Coefficient @@ -37,13 +37,13 @@ parachute(2, 1).nf = 8.7; % [/] Adimensional Opening Time parachute(1, 2) = Parachute(); parachute(1, 2).name = "Payload DROGUE"; -parachute(1, 2).surface = 0.187; % [m^2] Surface +parachute(1, 2).surface = 0.11; % [m^2] Surface parachute(1, 2).mass = 0.15; % [kg] Parachute Mass -parachute(1, 2).cd = 0.8; % [/] Parachute Drag Coefficient +parachute(1, 2).cd = 1.2; % [/] Parachute Drag Coefficient parachute(1, 2).cl = 0; % [/] Parachute Lift Coefficient parachute(1, 2).openingDelay = 1; % [s] drogue opening delay -parachute(1, 2).finalAltitude = 300; % [m] Final altitude of the parachute -parachute(1, 2).cx = 1.5; % [/] Parachute Longitudinal Drag Coefficient +parachute(1, 2).finalAltitude = 450; % [m] Final altitude of the parachute +parachute(1, 2).cx = 1.4; % [/] Parachute Longitudinal Drag Coefficient parachute(1, 2).chordLength = 1.5; % [m] Shock Chord Length parachute(1, 2).chordK = 7200; % [N/m^2] Shock Chord Elastic Constant parachute(1, 2).chordC = 0; % [Ns/m] Shock Chord Dynamic Coefficient @@ -55,5 +55,5 @@ parachute(1, 2).expulsionSpeed = 10; % [m/s] Expulsion Speed parachute(2, 2) = Parachute(); parachute(2, 2).name = "Payload AIRFOIL"; -parachute(2, 2).mass = 0.42; % [kg] Parachute Mass +parachute(2, 2).mass = 0.50; % [kg] Parachute Mass parachute(2, 2).finalAltitude = 0; % [m] Final altitude of the parachute diff --git a/missions/2024_Lyra_Portugal_October/config/rocketConfig.m b/missions/2024_Lyra_Portugal_October/config/rocketConfig.m index ad5bbb5..c039bc4 100644 --- a/missions/2024_Lyra_Portugal_October/config/rocketConfig.m +++ b/missions/2024_Lyra_Portugal_October/config/rocketConfig.m @@ -3,60 +3,55 @@ %% ROCKET - OVERRIDES BAYS CONFIG rocket = Rocket(); -rocket.diameter = 0.15; % [m] Rocket diameter -rocket.length = []; % [m] OVERRIDE total length -rocket.mass = []; % [kg] OVERRIDE total mass -rocket.massNoMotor = []; % [kg] OVERRIDE mass without motor -rocket.inertia = []; % [kg*m^2] OVERRIDE total inertia - Axibody reference -rocket.inertiaNoMotor = []; % [kg*m^2] OVERRIDE inertia without motor -rocket.xCg = []; % [m] OVERRIDE total xCg -rocket.xCgNoMotor = []; % [m] OVERRIDE xCg without motor +rocket.diameter = 0.15; % [m] Rocket diameter +rocket.massNoMotor = 17.0; % [kg] OVERRIDE mass without motor +rocket.inertiaNoMotor = [0.06535397; + 17.21019828; + 17.21056483]; % [kg*m^2] OVERRIDE inertia without motor - body axes reference +rocket.xCgNoMotor = 1.28; % [m] OVERRIDE xCg without motor +rocket.lengthCenterNoMot = 1.778; % [m] OVERRIDE Center length - no nose, no motor %% PLD - Includes Payload + Nose payload = Payload(); payload.length = 0.32; % [m] Total bay length payload.mass = 3.38512; % [kg] Total bay mass -payload.inertia = ... - [1032892397; 5461775539; 5450863094]*1e-9; % [kg*m^2] Total bay inertia (Body reference) -payload.xCg = 0.22734; % [m] Cg relative to bay upper side +payload.inertia = []; % [kg*m^2] Total bay inertia (Body reference) +payload.xCg = []; % [m] Cg relative to bay upper side payload.noseLength = 0.32; % [m] Nosecone length payload.noseType = 'MHAACK'; % [-] Nosecone shape payload.nosePower = 3/4; % [-] Nosecone power type parameter -payload.nosePMod = 1.250152e+00; % [-] P coefficient for modified nosecone shapes -payload.noseCMod = 1.799127e-01; % [-] C coefficient for modified nosecone shapes +payload.nosePMod = 1.291586e+00; % [-] P coefficient for modified nosecone shapes +payload.noseCMod = 9.272342e-03; % [-] C coefficient for modified nosecone shapes %% RCS recovery = Recovery(); -recovery.length = 0.9469; % [m] Total bay length -recovery.mass = 4.05091; % [kg] Total bay mass -recovery.inertia = ... - [1335996937; 2133707079; 2133851442]*1e-9; % [kg*m^2] Total bay inertia (Body reference) -recovery.xCg = 0.56607; % [m] Cg relative to bay upper side +recovery.length = []; % [m] Total bay length +recovery.mass = []; % [kg] Total bay mass +recovery.inertia = []; % [kg*m^2] Total bay inertia (Body reference) +recovery.xCg = []; % [m] Cg relative to bay upper side %% ELC electronics = Electronics(); -electronics.length = 0.4305; % [m] Total bay length -electronics.mass = 2.56618; % [kg] Total bay mass -electronics.inertia = ... - [909714504; 4749092145; 4715845883]*1e-9; % [kg*m^2] Total bay inertia (Body reference) -electronics.xCg = 0.22968; % [m] Cg relative to bay upper side +electronics.length = []; % [m] Total bay length +electronics.mass = []; % [kg] Total bay mass +electronics.inertia = []; % [kg*m^2] Total bay inertia (Body reference) +electronics.xCg = []; % [m] Cg relative to bay upper side %% ARB airbrakes = Airbrakes(); -airbrakes.length = 0.0548; % [m] Total bay length -airbrakes.mass = 0.99429; % [kg] Total bay mass -airbrakes.inertia = ... - [78545425; 41163849; 41163849]*1e-9; % [kg*m^2] Total bay inertia (Body reference) -airbrakes.xCg = 0.03967; % [m] Cg relative to bay upper side +airbrakes.length = []; % [m] Total bay length +airbrakes.mass = []; % [kg] Total bay mass +airbrakes.inertia = []; % [kg*m^2] Total bay inertia (Body reference) +airbrakes.xCg = []; % [m] Cg relative to bay upper side -airbrakes.multipleAB = false; % If true, multiple and smooth airbrakes opening will be simulated -airbrakes.opening = [1 3]; % aerobrakes, 1-2-3 for 0%, 50% or 100% opened -airbrakes.deltaTime = [10]; % aerobrakes, configurations usage time +airbrakes.multipleAB = false; % If true, multiple and smooth airbrakes opening will be simulated +airbrakes.opening = [1]; % aerobrakes, 1-2-3 for 0%, 50% or 100% opened +airbrakes.deltaTime = []; % aerobrakes, configurations usage time airbrakes.n = 3; % [-] number of brakes airbrakes.height = linspace(0, 0.0363, 3); % [m] Block airbrakes opening coordinate ( First entry must be 0! ) @@ -71,40 +66,39 @@ airbrakes.servoOmega = 150*pi/180; % [rad/s] Servo-motor %% MOTOR motor = Motor(); -motor.name = 'HRE_FURIA-Rv2-T04T03'; % [-] Motor name +motor.name = 'HRE_ARM_30_inj-T03T03'; % [-] Motor name motor.cutoffTime = inf; % [s] Cutoff time -motor.ignitionTransient = 0.4; % [s] Ignition transient +motor.ignitionTransient = 0.3; % [s] Ignition transient motor.cutoffTransient = 0.3; % [s] Cut-off transient %% REAR - Includes Fincan + Boat rear = Rear(); -rear.position = 1.086; -rear.length = 0.5585; % [m] Total bay length -rear.mass = 1.61926; % [kg] Total bay mass -rear.inertia = ... - [13054773; 44192627; 44193468]*1e-9; % [kg*m^2] Total bay inertia (Body reference) -rear.xCg = 0.25358; % [m] Cg relative to bay upper side +rear.position = 1.086; % [m] offset from +rear.length = []; % [m] Total bay length +rear.mass = []; % [kg] Total bay mass +rear.inertia = []; % [kg*m^2] Total bay inertia (Body reference) +rear.xCg = []; % [m] Cg relative to bay upper side rear.boatType = 'OGIVE'; % [-] Boat type rear.boatLength = 0.114; % [m] Boat length rear.boatFinalDiameter = 0.125; % [m] Boat end diameter rear.finsRootChord = 0.3; % [m] attached chord length -rear.finsFreeChord = 0.14; % [m] free chord length -rear.finsHeight = 0.1; % [m] fin height -rear.finsDeltaXFreeChord = 0.13; % [m] start of Chord 2 measured from start of Chord 1 +rear.finsFreeChord = 0.12; % [m] free chord length +rear.finsHeight = 0.13; % [m] fin height +rear.finsDeltaXFreeChord = 0.12; % [m] start of Chord 2 measured from start of Chord 1 rear.nPanel = 3; % [m] number of fins rear.finsLeadingEdgeRadius = [0 0]; % [deg] Leading edge radius at each span station -rear.finsAxialDistance = 0.012; % [m] distance between end of root chord and end of center body +rear.finsAxialDistance = -0.044; % [m] distance between end of root chord and end of center body rear.finsSemiThickness = 0.00175; % [m] fin semi-thickness rear.finsMaxThicknessPosition = 0.00175; % [m] Fraction of chord from leading edge to max thickness %% PITOT pitot = Pitot(); -pitot.length = 0.04777; % [m] Pitot tube length -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 +pitot.length = []; % [m] Pitot tube length +pitot.initialConeLength = []; % [m] Pitot initial conic section length +pitot.finalConeLength = []; % [m] Pitot final conic section length +pitot.initialConeDiameter = []; % [m] Pitot initial conic section diameter +pitot.finalConeDiameter = []; % [m] Pitot final conic section diameter \ No newline at end of file diff --git a/missions/missionConfig.m b/missions/missionConfig.m index ed0be40..daf58c3 100644 --- a/missions/missionConfig.m +++ b/missions/missionConfig.m @@ -3,4 +3,4 @@ % Use this file to store relevant, universally true settings, % such as the current mission. The config "BIOS" mission = Mission(); -mission.name = '2024_Lyra_Roccaraso_September'; \ No newline at end of file +mission.name = '2024_Lyra_Portugal_October'; \ No newline at end of file -- GitLab