diff --git a/classes/Bay.m b/classes/Bay.m index 180b279dc12e0ba8893ec5292ddcfd79c5743121..80cb8eaf85055b681583805539d0835d8bc0f16d 100644 --- a/classes/Bay.m +++ b/classes/Bay.m @@ -3,17 +3,17 @@ classdef Bay < Component & matlab.mixin.Heterogeneous % Arrays of bay subclasses will be represented as [mxn Bay] arrays properties(Abstract) - position % [m] Absolute position, relative to previous component + position % [m] OVERRIDE 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) + xCg % [m] Cg relative to bay upper side end methods (Static,Sealed,Access=protected) function default = getDefaultScalarElement - default = Boat; + default = Nose; end end end diff --git a/classes/Config.m b/classes/Config.m index 1a68e29b7b40c97dea3d3a44ae2f029279a1bacc..760e923ad404a4ddfde4d3233c016dab5b19d83c 100644 --- a/classes/Config.m +++ b/classes/Config.m @@ -5,7 +5,7 @@ classdef(Abstract) Config < handle properties(Abstract, Access = protected) - configName {mustBeTextScalar} + configName {mustBeTextScalar} variableName char end diff --git a/classes/Mission.m b/classes/Mission.m index 23eb161da9b5f35d48e730b21b12e83315af96fb..33601f41880bbf4966979528bde25b22193f22ce 100644 --- a/classes/Mission.m +++ b/classes/Mission.m @@ -12,10 +12,13 @@ classdef Mission < Config properties name % Mission name, used to access <mission> folder + end + + properties(SetAccess = protected) currentPath end - properties(Dependent) + properties(Dependent, SetAccess = protected) configPath dataPath end @@ -30,7 +33,6 @@ classdef Mission < Config arguments loadConfig {islogical} = false end - obj.currentPath = fullfile(fileparts(mfilename("fullpath")), '..', 'missions'); if loadConfig, obj.loadConfig; end end @@ -50,7 +52,7 @@ classdef Mission < Config methods(Access = protected) function loadConfig(obj) fileName = obj.configName; - filePath = obj.currentPath; + filePath = fullfile(fileparts(mfilename("fullpath")), '..', 'missions'); if ~isfile(fullfile(filePath, fileName)) error(strcat("File not found inside the config folder: ", filePath)); @@ -61,6 +63,7 @@ classdef Mission < Config configObj = eval(varName); fields = obj.getProperties('writable'); for j = 1:size(fields, 2), obj.(fields{j}) = configObj.(fields{j}); end + obj.currentPath = filePath; end end diff --git a/classes/Rocket.m b/classes/Rocket.m index d525dfd2114785db687fda5a0c5c292a6ce46995..ce84f3aea9f4352ff233b72b7bad67ba4c40d990 100644 --- a/classes/Rocket.m +++ b/classes/Rocket.m @@ -169,6 +169,80 @@ classdef Rocket < Component end end + methods % Updaters + function updateLength(obj) + % Do not consider Boat length, as motor bay already covers boat + obj.length = sum([obj.bays(1:end-1).length]); + end + + function updateDiameter(obj) + % Take payload diameter as reference + obj.diameter = obj.payload.diameter; + end + + function updateMasses(obj) + obj.updateMassNoMotor(); + obj.mass = obj.massNoMotor + obj.motor.mass; + end + + function updateAbsolutePositions(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 + obj.absolutePositions = out; + obj.absolutePositionsNoMotor = out([1:5, 7:end]); + end + + function updateXCgs(obj) + obj.updateXCgNoMotor(); + % Motor mass is 6th element of "bays" + obj.xCg = (obj.xCgNoMotor*obj.massNoMotor + ... + obj.motor.mass.*(obj.motor.xCg+obj.absolutePositions(6)))./ ... + obj.mass; + end + + function updateInertias(obj) + % [3x634] Ix, Iy, Iz + obj.updateInertiaNoMotor(); + temp = [obj.motor.inertia] + ... + (obj.absolutePositions(6) + [obj.xCg]).^2 .* obj.mass; + obj.inertia = temp + obj.inertiaNoMotor; + end + + function updateAll(obj) + obj.updateLength; + obj.updateDiameter; + obj.updateMasses; + obj.updateAbsolutePositions; + obj.updateXCgs; + obj.updateInertias; + end + end + + methods(Access = private) % Properties without motor + function updateMassNoMotor(obj) + obj.massNoMotor = sum([obj.baysNoMotor.mass]); + end + + function updateXCgNoMotor(obj) + obj.xCgNoMotor = (([obj.absolutePositionsNoMotor] + [obj.baysNoMotor.xCg])* ... + [obj.baysNoMotor.mass]')/obj.massNoMotor; + end + + function updateInertiaNoMotor(obj) + % [3x1] Ix, Iy, Iz + temp = [obj.baysNoMotor.inertia] + ... + ([obj.absolutePositionsNoMotor] + [obj.xCgNoMotor]).^2 .* obj.massNoMotor; + obj.inertiaNoMotor = sum(temp, 2); + end + end methods function obj = Rocket(mission, varIn) @@ -195,6 +269,7 @@ classdef Rocket < Component [~, obj.bays] = obj.getProperties(Superclass='Bay', Heterogeneous=1); obj.baysNoMotor = [obj.bays(1:5), obj.bays(7:end)]; % Take all bays except motor + obj.updateAll(); % add back overrides end end end diff --git a/classes/bays/Motor.m b/classes/bays/Motor.m index d58b4e135b0f90239dfd8eefb1e9d9a8623ff47b..39bb44213e7fb2651718a0563ba3e90b65d56673 100644 --- a/classes/bays/Motor.m +++ b/classes/bays/Motor.m @@ -11,7 +11,7 @@ classdef Motor < Bay properties name {mustBeTextScalar} = '' % [-] Motor name - position % [m] Absolute position, relative to nose base + 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) diff --git a/classes/components/WindCustom.m b/classes/components/WindCustom.m index a0159ed60ec5d14b108f207aa3183087d493fb0b..d2e12bc0c186bc1fc4b783ebf68d6b28b8eeb3a5 100644 --- a/classes/components/WindCustom.m +++ b/classes/components/WindCustom.m @@ -13,11 +13,11 @@ classdef WindCustom < Component altitudes (1, :) magnitudeDistribution (1, :) ... - {mustBeMember(magnitudeDistribution, {'u', 'g'})} = 'u' % [-] Magnitude distrubution: uniform, gaussian + {mustBeMember(magnitudeDistribution, {'u', 'g'})} = 'u' % [-] Magnitude distrubution: uniform, gaussian azimuthDistribution (1, :) ... - {mustBeMember(azimuthDistribution, {'u', 'g'})} = 'u' % [-] Azimuth distrubution: uniform, gaussian - magnitudeParameters (2, :) % [m/s] Distribution parameters: [min; max], [mu; sigma] - azimuthParameters (2, :) % [deg] Distribution parameters: [min; max], [mu; sigma] + {mustBeMember(azimuthDistribution, {'u', 'g'})} = 'u' % [-] Azimuth distrubution: uniform, gaussian + magnitudeParameters (2, :) % [m/s] Distribution parameters: [min; max], [mu; sigma] + azimuthParameters (2, :) % [deg] Distribution parameters: [min; max], [mu; sigma] end properties(SetAccess = private) diff --git a/missions/2024_Lyra_Roccaraso_September/config/environmentConfig.m b/missions/2024_Lyra_Roccaraso_September/config/environmentConfig.m index 91165eb0c3e129404492fcd01d841fb05ba05565..d994fbcadd6bd499bea3bca185d6915a8197b2b6 100644 --- a/missions/2024_Lyra_Roccaraso_September/config/environmentConfig.m +++ b/missions/2024_Lyra_Roccaraso_September/config/environmentConfig.m @@ -4,14 +4,13 @@ environment = Environment(); -environment.lat0 = 41.8084579; % [deg] Launchpad latitude -environment.lon0 = 14.0546408; % [deg] Launchpad longitude -environment.z0 = 1414; % [m] Launchpad Altitude -environment.pin1Length = 000; % [m] Distance from the upper pin to the upper tank cap -environment.pin2Length = 000; % [m] Distance from the lower pin to the lower tank cap -environment.rampLength = 000; % [m] Total launchpad length +environment.lat0 = 41.8084579; % [deg] Launchpad latitude +environment.lon0 = 14.0546408; % [deg] Launchpad longitude +environment.z0 = 1414; % [m] Launchpad Altitude +environment.pin1Length = 000; % [m] Distance from the upper pin to the upper tank cap +environment.pin2Length = 000; % [m] Distance from the lower pin to the lower tank cap +environment.rampLength = 000; % [m] Total launchpad length -% environment.altitude ? -environment.temperature = NaN; -environment.pressure = NaN; -environment.rho = NaN; \ No newline at end of file +environment.temperature = []; % [deg] Ground temperature correction +environment.pressure = []; % [Pa] Ground pressure correction +environment.rho = []; % [Kg/m^3] Gorund air density correction \ No newline at end of file diff --git a/missions/2024_Lyra_Roccaraso_September/config/rocketConfig.m b/missions/2024_Lyra_Roccaraso_September/config/rocketConfig.m index 86d37b24a120d3b91b271e146277fb76406068a1..ec2b05a34c3a6f9d11e78a4ea2c2b439b2a341f0 100644 --- a/missions/2024_Lyra_Roccaraso_September/config/rocketConfig.m +++ b/missions/2024_Lyra_Roccaraso_September/config/rocketConfig.m @@ -7,7 +7,7 @@ rocket.length = []; % [m] OVERRIDE total length rocket.diameter = []; % [m] OVERRIDE diameter rocket.mass = []; % [kg] OVERRIDE total mass rocket.massNoMotor = []; % [kg] OVERRIDE mass without motor -rocket.inertia = []; % [] OVERRIDE total inertia +rocket.inertia = []; % [] OVERRIDE total inertia - Axibody reference rocket.inertiaNoMotor = []; % [] OVERRIDE inertia without motor rocket.xCg = []; % [] OVERRIDE total xCg rocket.xCgNoMotor = []; % [] OVERRIDE xCg without motor @@ -17,40 +17,40 @@ nose = Nose(); nose.length = 0.3; % [m] Nosecone Length nose.diameter = 000; % [m] Nosecone Diameter -nose.mass = 1; % [m] Nosecone Inertia -nose.inertia = [1; 1; 0.1]; % [m] Nosecone Mass +nose.mass = 1; % [m] Nosecone Mass +nose.inertia = [1; 1; 0.1]; % [m] Nosecone Inertia - Axibody reference nose.ogiveType = 'MHAACK'; % [-] Nosecone shape -nose.power = 000; %3/4; % [-] Nosecone power type parameter -nose.pMod = 000; %1.250152e+00; % [-] P coefficient for modified nosecone shapes -nose.cMod = 000; %1.799127e-01; % [-] C coefficient for modified nosecone shapes +nose.power = 3/4; % [-] Nosecone power type parameter +nose.pMod = 1.250152e+00; % [-] P coefficient for modified nosecone shapes +nose.cMod = 1.799127e-01; % [-] C coefficient for modified nosecone shapes nose.xCg = 000; % [m] Nosecone xCg %% PLD payload = Payload(); -payload.length = 0.1; -payload.diameter = 0; -payload.mass = 2; -payload.inertia = [5; 4.5; 5]; -payload.xCg = 0; - +payload.length = 0.1; % [m] Total bay length +payload.diameter = 0; % [m] Diameter of the bay +payload.mass = 2; % [kg] Total bay mass +payload.inertia = [5; 4.5; 5]; % [kg*m^2] Total bay inertia (Body reference) +payload.xCg = 0; % [m] Cg relative to bay upper side + %% RCS recovery = Recovery(); -recovery.length = 0.3; -recovery.diameter = 0; -recovery.mass = 3; -recovery.inertia = [6; 12; 12]; -recovery.xCg = 0; +recovery.length = 0.3; % [m] Total bay length +recovery.diameter = 0; % [m] Diameter of the bay +recovery.mass = 3; % [kg] Total bay mass +recovery.inertia = [6; 12; 12]; % [kg*m^2] Total bay inertia (Body reference) +recovery.xCg = 0; % [m] Cg relative to bay upper side %% ELC electronics = Electronics(); -electronics.length = 0.2; -electronics.diameter = 000; -electronics.mass = 3; -electronics.inertia = [7.5; 7.5; 7.5]; -electronics.xCg = 0; +electronics.length = 0.2; % [m] Total bay length +electronics.diameter = 000; % [m] Diameter of the bay +electronics.mass = 3; % [kg] Total bay mass +electronics.inertia = [7.5; 7.5; 7.5]; % [kg*m^2] Total bay inertia (Body reference) +electronics.xCg = 0; % [m] Cg relative to bay upper side %% ARB airbrakes = Airbrakes(); @@ -65,47 +65,47 @@ airbrakes.width = 0.1002754821; % [m] brakes width (normal) airbrakes.thickness = 0.008; % [m] brakes thickness airbrakes.xDistance = 1.517; % [m] axial position from nosecone base -airbrakes.length = 0.05; -airbrakes.diameter = 000; -airbrakes.mass = 2.5; -airbrakes.inertia = [1.25; 0.05; 1.25]; +airbrakes.length = 0.05; % [m] Total bay length +airbrakes.diameter = 000; % [m] Diameter of the bay +airbrakes.mass = 2.5; % [kg] Total bay mass +airbrakes.inertia = [1.25; 0.05; 1.25]; % [kg*m^2] Total bay inertia (Body reference) +airbrakes.xCg = 0; % [m] Cg relative to bay upper side airbrakes.minTime = 0; % [s] time after which the airbrakes can be used airbrakes.maxMach = 0.8; % [-] Maximum Mach at which airbrakes can be used airbrakes.servoOmega = 150*pi/180; % [rad/s] Servo-motor angular velocity -airbrakes.xCg = 0; %% MOTOR motor = Motor(); -motor.name = 'HRE_FURIA-Rv2-T04T03'; -motor.cutoffTime = inf; +motor.name = 'HRE_FURIA-Rv2-T04T03'; % [-] Motor name +motor.cutoffTime = inf; % [s] Cutoff time motor.ignitionTransient = 0.4; % [s] Ignition transient motor.cutoffTransient = 0.3; % [s] Cut-off transient %% REAR - FICNAN + BOAT rear = Rear(); -rear.position = 1.3; -rear.length = 0.1; -rear.diameter = 0; -rear.mass = 0.25; -rear.xCg = 0.1254; -rear.inertia = [0.85; 0.85; 0.85]; - -rear.type = 'CONE'; -rear.boatLength = 0; -rear.finalDiameter = 0; - -rear.rootChord = 0.30; % [m] attached chord length -rear.freeChord = 0.14; % [m] free chord length -rear.height = 0.11; % [m] fin heigth -rear.deltaXFreeChord = 0.13; % [m] start of Chord 2 measured from start of Chord 1 -rear.nPanel = 3; % [m] number of fins -rear.leadingEdgeRadius = [0 0]; % [deg] Leading edge radius at each span station -rear.axialDistance = 0.012; % [m] distance between end of root chord and end of center body -rear.semiThickness = 0.00175; % [m] fin semi-thickness -rear.maxThicknessPosition = 0.00175; % [m] Fraction of chord from leading edge to max thickness +rear.position = 1.3; +rear.length = 0.1; % [m] Total bay length +rear.diameter = 0; % [m] Diameter of the bay +rear.mass = 0.25; % [kg] Total bay mass +rear.inertia = [0.85; 0.85; 0.85]; % [kg*m^2] Total bay inertia (Body reference) +rear.xCg = 0.1254; % [m] Cg relative to bay upper side + +rear.type = 'CONE'; % [-] Boat type +rear.boatLength = 0; % [m] Boat length +rear.finalDiameter = 0; % [m] Boat end diameter + +rear.rootChord = 0.30; % [m] attached chord length +rear.freeChord = 0.14; % [m] free chord length +rear.height = 0.11; % [m] fin heigth +rear.deltaXFreeChord = 0.13; % [m] start of Chord 2 measured from start of Chord 1 +rear.nPanel = 3; % [m] number of fins +rear.leadingEdgeRadius = [0 0]; % [deg] Leading edge radius at each span station +rear.axialDistance = 0.012; % [m] distance between end of root chord and end of center body +rear.semiThickness = 0.00175; % [m] fin semi-thickness +rear.maxThicknessPosition = 0.00175; % [m] Fraction of chord from leading edge to max thickness %% PITOT pitot = Pitot(); diff --git a/missions/2024_Lyra_Roccaraso_September/config/windConfig.m b/missions/2024_Lyra_Roccaraso_September/config/windConfig.m index e95aec56f381677dc3f7d7a0c9fba64627066f8d..332c74eea10b207f02afd7a9d0d019b509c8ceb1 100644 --- a/missions/2024_Lyra_Roccaraso_September/config/windConfig.m +++ b/missions/2024_Lyra_Roccaraso_September/config/windConfig.m @@ -1,7 +1,7 @@ % CONFIG - This script sets up wind direction and magnitude based on % altitudes % -% Wind azimuth angle indications (wind directed towards): !!! SABGLAITO +% Wind azimuth angle indications - Wind directed towards <angle> % 0 deg (use 360 instead of 0) -> North % 90 deg -> East % 180 deg -> South @@ -11,19 +11,19 @@ windCustom = WindCustom(); -windCustom.altitudes = [0 200 2000]; % [m] Altitudes at which a distribution change occurs -windCustom.magnitudeDistribution = ["g", "u", "u"]; % [] -windCustom.magnitudeParameters = [7 2 10; % [] +windCustom.altitudes = [0 200 2000]; % [m] Altitudes at which a distribution change occurs +windCustom.magnitudeDistribution = ["g", "u", "u"]; % [-] Distribution type: "u" - uniform, "g" - gaussian +windCustom.magnitudeParameters = [7 2 10; % [m/s] Distribution parameters: "u" - [min; max], "g" - [mu; sigma] 0.5 9 20]; -windCustom.azimuthDistribution = ["u", "u", "u"]; % [] -windCustom.azimuthParameters = 0*pi/180 * ones(2,3); % [] +windCustom.azimuthDistribution = ["u", "u", "u"]; % [-] Distribution type: "u" - uniform, "g" - gaussian +windCustom.azimuthParameters = 0*pi/180 * ones(2,3); % [deg] Distribution parameters: "u" - [min; max], "g" - [mu; sigma] %% MATLAB WIND MODEL windMatlab = WindMatlab(); -windMatlab.DayMin = 105; % [d] Minimum Day of the launch -windMatlab.DayMax = 105; % [d] Maximum Day of the launch -windMatlab.HourMin = 4; % [h] Minimum Hour of the day -windMatlab.HourMax = 4; % [h] Maximum Hour of the day -windMatlab.ww = 0; % [m/s] Vertical wind speed \ No newline at end of file +windMatlab.DayMin = 105; % [d] Minimum Day of the launch +windMatlab.DayMax = 105; % [d] Maximum Day of the launch +windMatlab.HourMin = 4; % [h] Minimum Hour of the day +windMatlab.HourMax = 4; % [h] Maximum Hour of the day +windMatlab.ww = 0; % [m/s] Vertical wind speed \ No newline at end of file diff --git a/missions/missionConfig.m b/missions/missionConfig.m index 3fdc59afb6850f090ae9de8b46034f5ddab4c9c7..ed0be403f2a37a384b0f96924bf71266b21ee141 100644 --- a/missions/missionConfig.m +++ b/missions/missionConfig.m @@ -3,5 +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 diff --git a/missions/settings/OLDsettingsConfig.m b/missions/settings/OLDsettingsConfig.m deleted file mode 100644 index 9adeba56c7fb66da4d4b179b512b74bb78b18bd5..0000000000000000000000000000000000000000 --- a/missions/settings/OLDsettingsConfig.m +++ /dev/null @@ -1,10 +0,0 @@ -% CONFIG - This script sets up which feature a mission uses -% -% Use this file to store information about the features implemented in a -% mission (e.g. whether a specific algorithm is used, the engine type, -% flags...) - -settings.motorType = 'hybrid'; % [-] choices are: solid, hybrid - -settings.flags.autoMatProt = false; -settings.flags.highAoA = true; \ No newline at end of file