diff --git a/classes/Config.m b/classes/Config.m index e1ca9fc571cacf092734e3ff620b69f2605e4b4d..16976061a8b169089b0f10987c94a88989db40e0 100644 --- a/classes/Config.m +++ b/classes/Config.m @@ -22,7 +22,7 @@ classdef(Abstract) Config < handle end methods - function propertiesOut = getProperties(obj, preset, options) + function [propertiesOut, valuesOut] = getProperties(obj, preset, options, attributes) % This function returns properties that match specific attributes % You can specify presets to include combinations of properties: % - 'readable': GetAccess = 'public', Abstract = false, @@ -31,50 +31,68 @@ classdef(Abstract) Config < handle % Constant = false, Abstract = false, Hidden = false % % Presets have the priority over options, in case of conflicts + % + % WARNING: If second output is used, only values with public + % getAccess will be read arguments obj - preset char {mustBeMember(preset, {'readable', 'writable', ''})} = '' - options.GetAccess char {mustBeMember(options.GetAccess, {'public', 'private', ''})} = '' - options.SetAccess char {mustBeMember(options.SetAccess, {'public', 'private', ''})} = '' - options.Dependent logical {mustBeMember(options.Dependent, [0, 1])} = [] - options.Constant logical {mustBeMember(options.Constant, [0, 1])} = [] - options.Abstract logical {mustBeMember(options.Abstract, [0, 1])} = [] - options.Transient logical {mustBeMember(options.Transient, [0, 1])} = [] - options.Hidden logical {mustBeMember(options.Hidden, [0, 1])} = [] - options.AbortSet logical {mustBeMember(options.AbortSet, [0, 1])} = [] + preset char {mustBeMember(preset, {'readable', 'writable', ''})} = '' + options.Superclass char = '' + attributes.GetAccess char {mustBeMember(attributes.GetAccess, {'public', 'private', ''})} = '' + attributes.SetAccess char {mustBeMember(attributes.SetAccess, {'public', 'private', ''})} = '' + attributes.Dependent logical {mustBeMember(attributes.Dependent, [0, 1])} = [] + attributes.Constant logical {mustBeMember(attributes.Constant, [0, 1])} = [] + attributes.Abstract logical {mustBeMember(attributes.Abstract, [0, 1])} = [] + attributes.Transient logical {mustBeMember(attributes.Transient, [0, 1])} = [] + attributes.Hidden logical {mustBeMember(attributes.Hidden, [0, 1])} = [] + attributes.AbortSet logical {mustBeMember(attributes.AbortSet, [0, 1])} = [] end if ~isempty(preset) switch preset case 'readable' - options.GetAccess = 'public'; - options.Abstract = 0; - options.Hidden = 0; + attributes.GetAccess = 'public'; + attributes.Abstract = 0; + attributes.Hidden = 0; case 'writable' - options.SetAccess = 'public'; - options.Dependent = 0; - options.Constant = 0; - options.Abstract = 0; - options.Hidden = 0; + attributes.SetAccess = 'public'; + attributes.Dependent = 0; + attributes.Constant = 0; + attributes.Abstract = 0; + attributes.Hidden = 0; end end + if nargout == 2, attributes.GetAccess = 'public'; end - fields = fieldnames(options); - check = @(field, prop) isempty(options.(field)) || isequal(prop.(field), options.(field)); + fields = fieldnames(attributes); + attributeCheck = @(field, prop) isempty(attributes.(field)) ... + || isequal(prop.(field), attributes.(field)); + optionCheck = @(prop) isempty(options.Superclass) ... + || ~isempty(prop.Validation) ... + && ~isempty(prop.Validation.Class) ... + && ~isempty(prop.Validation.Class.SuperclassList) ... + && any(strcmp(prop.Validation.Class.SuperclassList.Name, options.Superclass)); + mc = metaclass(obj); ii = 0; nProperties = length(mc.PropertyList); properties = cell(1,nProperties); - for c = 1:nProperties + for c = 1:nProperties mp = mc.PropertyList(c); - checks = cellfun(@(field) check(field, mp), fields); + checks = [cellfun(@(field) attributeCheck(field, mp), fields); + optionCheck(mp)]; if all(checks) ii = ii + 1; properties(ii) = {mp.Name}; end end propertiesOut = properties(1:ii); + valuesOut = cell(1, ii); + + if nargout == 2 + for i = 1:ii, valuesOut{i} = obj.(propertiesOut{i}); end + end end end diff --git a/classes/Rocket.m b/classes/Rocket.m index aca4e1b9641b6d131e15acdf0f85badb5420c589..797a5ef680434699691446e6dac80e8f280e66ea 100644 --- a/classes/Rocket.m +++ b/classes/Rocket.m @@ -28,6 +28,10 @@ classdef Rocket < Bay variableName = '' mission Mission end + + properties(Access = private) + bays cell + end methods % Getters / Setters function out = get.length(obj) @@ -36,22 +40,31 @@ classdef Rocket < Bay obj.electronics.length + obj.airbrakes.length + obj.motor.length + ... obj.boat.length; end + function out = get.diameter(obj) if ~isempty(obj.diameter), out = obj.diameter; return; end out = obj.payload.diameter; end + 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; 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; end + + function out = get.xCg(obj) + if ~isempty(obj.xCg), out = obj.xCg; return; end + out = 0; + end + function out = get.inertia(obj) % WIP % Here I'm assuming that inertias, xCg and mass change with time (because % the motor lose propellant), thus all the variable should be @@ -87,10 +100,6 @@ classdef Rocket < Bay % out(:,3) = out(:,3) + baysIzz(:,i) + obj.mass.*(obj.xCg - xCgAbsolute(i)).^2; % end end - function out = get.xCg(obj) - if ~isempty(obj.xCg), out = obj.xCg; return; end - out = 0; - end end methods @@ -114,6 +123,8 @@ classdef Rocket < Bay obj.boat = Boat(mission, vars); obj.fins = Fins(mission, vars); obj.pitot = Pitot(mission, vars); + + [~, obj.bays] = obj.getProperties(Superclass='Bay'); end end end diff --git a/classes/Settings.m b/classes/Settings.m index dd6516a501cb126510cff84e1f6f63c31fb1788d..52c32050f686882f36a8840beff5c520b4b3adab 100644 --- a/classes/Settings.m +++ b/classes/Settings.m @@ -16,6 +16,25 @@ classdef Settings < Config & dynamicprops end methods + function obj = Settings() + obj.currentPath = fullfile(fileparts(mfilename("fullpath")), '..', 'missions'); + + % ODE settings + obj.ode.finalTime = 2000; % [s] Final integration time + obj.ode.optAscent = odeset('Events', @eventApogee, 'InitialStep', 1); % ODE options for ascend + obj.ode.optAscentDelayPara= odeset('InitialStep', 1); % ODE options for due to the opening delay of the parachute + obj.ode.optAscentMultipleAB = odeset('Events', @eventAB, 'InitialStep', 1); % ODE options for opening of the airbrakes + obj.ode.optParachute = odeset('Events', @eventParaCut); % ODE options for the parachutes + obj.ode.optDescent = odeset('Events', @eventLanding,... + 'RelTol', 1e-3, 'AbsTol', 1e-3); % ODE options for ballistic descent + obj.ode.optLaunchpad = odeset('Events', @eventPad); % ODE options for the launchpad phase + + % Settings for descent 6dof simulation + obj.ode.optDrogue6DOF = odeset('Events', @eventParaCut, 'AbsTol', 1e-6,'RelTol', 1e-6); %ODE options for due to cutting of the drogue chute + obj.ode.optMainExt6DOF = odeset('Events', @eventMainExit, 'AbsTol', 1e-6,'RelTol', 1e-6); %ODE options for due to the extraction of the main chute + obj.ode.optMain6DOF = odeset('Events', @eventLanding, 'AbsTol', 1e-6,'RelTol', 1e-6); %ODE options to terminate descent phase + end + function outputVariables = getConfig(obj) fileName = obj.configName; filePath = obj.mission.configPath; @@ -37,25 +56,6 @@ classdef Settings < Config & dynamicprops end end - function obj = Settings() - obj.currentPath = fullfile(fileparts(mfilename("fullpath")), '..', 'missions'); - - % ODE settings - obj.ode.finalTime = 2000; % [s] Final integration time - obj.ode.optAscent = odeset('Events', @eventApogee, 'InitialStep', 1); % ODE options for ascend - obj.ode.optAscentDelayPara= odeset('InitialStep', 1); % ODE options for due to the opening delay of the parachute - obj.ode.optAscentMultipleAB = odeset('Events', @eventAB, 'InitialStep', 1); % ODE options for opening of the airbrakes - obj.ode.optParachute = odeset('Events', @eventParaCut); % ODE options for the parachutes - obj.ode.optDescent = odeset('Events', @eventLanding,... - 'RelTol', 1e-3, 'AbsTol', 1e-3); % ODE options for ballistic descent - obj.ode.optLaunchpad = odeset('Events', @eventPad); % ODE options for the launchpad phase - - % Settings for descent 6dof simulation - obj.ode.optDrogue6DOF = odeset('Events', @eventParaCut, 'AbsTol', 1e-6,'RelTol', 1e-6); %ODE options for due to cutting of the drogue chute - obj.ode.optMainExt6DOF = odeset('Events', @eventMainExit, 'AbsTol', 1e-6,'RelTol', 1e-6); %ODE options for due to the extraction of the main chute - obj.ode.optMain6DOF = odeset('Events', @eventLanding, 'AbsTol', 1e-6,'RelTol', 1e-6); %ODE options to terminate descent phase - end - function path = get.configPath(obj) if (obj.name), path = fullfile(obj.currentPath, obj.name, 'config'); else, path = ''; diff --git a/classes/bays/Airbrakes.m b/classes/bays/Airbrakes.m index 146d9e6ef2d2edfa31a275be814ef07b18be5c91..d6969016f5c1f3a3a58ad211e5eafd5dbef1db02 100644 --- a/classes/bays/Airbrakes.m +++ b/classes/bays/Airbrakes.m @@ -26,4 +26,14 @@ classdef Airbrakes < Bay variableName = 'airbrakes' mission Mission = Mission() end + + methods + function obj = Airbrakes(mission, varIn) + arguments(Input) + mission Mission = Mission() + varIn = [] + end + obj@Bay(mission, varIn); + end + end end \ No newline at end of file diff --git a/classes/bays/Boat.m b/classes/bays/Boat.m index af20baad44d87203d48df8cc86785338429dff0e..6749151deb5e73563c644ad622d454bc6fff81b5 100644 --- a/classes/bays/Boat.m +++ b/classes/bays/Boat.m @@ -15,4 +15,14 @@ classdef Boat < Bay variableName = 'boat' mission Mission = Mission() end + + methods + function obj = Boat(mission, varIn) + arguments(Input) + mission Mission = Mission() + varIn = [] + end + obj@Bay(mission, varIn); + end + end end \ No newline at end of file diff --git a/classes/bays/Electronics.m b/classes/bays/Electronics.m index a0e1a7a5b2e589a3d19365831bef5116e78d3295..6a02f418ee02a1dad3e3cb8c55461b2be7079e44 100644 --- a/classes/bays/Electronics.m +++ b/classes/bays/Electronics.m @@ -15,4 +15,14 @@ classdef Electronics < Bay variableName = 'electronics' mission Mission = Mission() end + + methods + function obj = Electronics(mission, varIn) + arguments(Input) + mission Mission = Mission() + varIn = [] + end + 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 2e63309966d447685264332424319cdaac5a20aa..26602e4ef28e9032e990912bda044f2be6b63e74 100644 --- a/classes/bays/Motor.m +++ b/classes/bays/Motor.m @@ -35,6 +35,14 @@ classdef Motor < Bay 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(); diff --git a/classes/bays/Nose.m b/classes/bays/Nose.m index bbeee1b45067c43d00b079483c41836b718dcee7..aa69463b564be3cf0263e86dceb851dbd12234fe 100644 --- a/classes/bays/Nose.m +++ b/classes/bays/Nose.m @@ -20,4 +20,14 @@ classdef Nose < Bay variableName = 'nose' mission Mission = Mission() end + + methods + function obj = Nose(mission, varIn) + arguments(Input) + mission Mission = Mission() + varIn = [] + end + obj@Bay(mission, varIn); + end + end end \ No newline at end of file diff --git a/classes/bays/Payload.m b/classes/bays/Payload.m index 0b76fe7076655cf50796589adff5b1db32401547..4af058455066f0af49e796af74bd4b0073d8beef 100644 --- a/classes/bays/Payload.m +++ b/classes/bays/Payload.m @@ -14,4 +14,14 @@ classdef Payload < Bay variableName = 'payload' mission Mission = Mission() end + + methods + function obj = Payload(mission, varIn) + arguments(Input) + mission Mission = Mission() + varIn = [] + end + obj@Bay(mission, varIn); + end + end end \ No newline at end of file diff --git a/classes/bays/Recovery.m b/classes/bays/Recovery.m index 09b56aee9fe71efb16aa582bf9687d9715b172c1..ce78221e1262718dc329ca79a7c81fc67f3b4f12 100644 --- a/classes/bays/Recovery.m +++ b/classes/bays/Recovery.m @@ -14,4 +14,14 @@ classdef Recovery < Bay variableName = 'recovery' mission Mission = Mission() end + + methods + function obj = Recovery(mission, varIn) + arguments(Input) + mission Mission = Mission() + varIn = [] + end + obj@Bay(mission, varIn); + end + end end \ No newline at end of file diff --git a/classes/components/Environment.m b/classes/components/Environment.m index 47ec3e002446ff1258637e62427c993075b0a644..85dbeb175c2077eef42df55382ed1ded00d45c1e 100644 --- a/classes/components/Environment.m +++ b/classes/components/Environment.m @@ -34,8 +34,6 @@ classdef Environment < Component motor Motor = Motor() varIn = [] end - if nargin > 0 && nargin < 2, error('Too few arguments. Type help for more info'); end - if nargin > 3, error('Too many arguments.'); end obj@Component(mission, varIn); obj.motor = motor; end diff --git a/classes/components/Fins.m b/classes/components/Fins.m index c5b214d51619ad3908e80ba14979d72b7a8923bf..4987e4f5bcaa5e0ee3a0c9cdfb833318029973f5 100644 --- a/classes/components/Fins.m +++ b/classes/components/Fins.m @@ -21,4 +21,14 @@ classdef Fins < Component variableName = 'fins' mission Mission = Mission() end + + methods + function obj = Fins(mission, varIn) + arguments(Input) + mission Mission = Mission() + varIn = [] + end + obj@Component(mission, varIn); + end + end end \ No newline at end of file diff --git a/classes/components/Pitot.m b/classes/components/Pitot.m index eca6f94d4eb434ee2dda0d682a1a2ac9a1df167e..b5467542bfcd95980313a380830c348374c39049 100644 --- a/classes/components/Pitot.m +++ b/classes/components/Pitot.m @@ -16,4 +16,14 @@ classdef Pitot < Component variableName = 'pitot' mission Mission = Mission() end + + methods + function obj = Pitot(mission, varIn) + arguments(Input) + mission Mission = Mission() + varIn = [] + end + obj@Component(mission, varIn); + end + end end \ No newline at end of file diff --git a/classes/components/Wind.m b/classes/components/Wind.m deleted file mode 100644 index c785b8880b616bb94b2b5265d30b550b09ae5c0b..0000000000000000000000000000000000000000 --- a/classes/components/Wind.m +++ /dev/null @@ -1,141 +0,0 @@ -classdef Wind < Component - %UNTITLED Summary of this class goes here - % Detailed explanation goes here - - properties - model {mustBeMember(model, {'','custom', 'matlab'})} = '' % [] Chosen wind model: 'custom' or 'matlab' - - altitudes - magnitudeMin % [m/s] Minimum Magnitude - magnitudeMax % [m/s] Maximum Magnitude - elevationMin % [rad] Minimum Elevation, user input in degrees (ex. 0) - elevationMax % [rad] Maximum Elevation, user input in degrees (ex. 0) (Max == 90 Deg) - azimuthMin % [rad] Minimum Azimuth, user input in degrees (ex. 90) - azimuthMax % [rad] Maximum Azimuth, user input in degrees (ex. 90) - - magnitudeDistribution % - azimuthDistribution % - magnitudeParameters % - azimuthParameters % - - DayMin % [d] Minimum Day of the launch - DayMax % [d] Maximum Day of the launch - HourMin % [h] Minimum Hour of the day - HourMax % [h] Maximum Hour of the day - ww % [m/s] Vertical wind speed - end - - properties(SetAccess = private) - azimuth - magnitude - end - - properties(Access = protected) - configName = 'windConfig.m' - variableName = '' - mission Mission - environment Environment - end - - methods - function obj = Wind(mission, environment, varIn) - arguments(Input) - mission Mission = Mission() - environment Environment = Environment() - varIn = [] - end - if nargin > 0 && nargin < 2, error('Too few arguments. Type help for more info'); end - if nargin > 3, error('Too many arguments.'); end - obj@Component(mission, varIn); - obj.environment = environment; - end - end - - - methods - function [uw, vw, ww] = computeWindVels(obj, z) - s = length(obj.altitudes); % reference vectors length - if s==1 - uw = round( - obj.magVec * cos(obj.azVec), 6); - vw = round( - obj.magVec * sin(obj.azVec), 6); - ww = 0; - else - mag = interpLinear(obj.altitudes, obj.magVec, z, true); - az = interpLinear(obj.altitudes, obj.azVec, z, true); - - uw = round( - mag * cos(az), 6); - vw = round( - mag * sin(az), 6); - ww = 0; - end - end - - function obj = setData(obj) - s = length(obj.altitudes); - if s<=1 - obj.constantWind = true; - if strcmp(settings.magDistribution(1), "u") - mag = rand(1)*(obj.mag(2,1) - obj.mag(1,1)) + obj.mag(1,1); - else - mag = normrnd(obj.mag(1,1), obj.mag(2,1), 1); - end - - if strcmp(settings.azDistribution(1), "u") - az = rand(1)*(obj.az(2,1) - obj.az(1,1)) + obj.az(1,1); - else - az = normrnd(obj.az(1,1), obj.az(2,1), 1); - end - - obj.magVec = mag; - obj.azVec = az; - else - obj.constantWind = false; - - magVector = nan(1,s); - azVector = nan(1,s); - isUniformMag = strcmp(obj.magDistribution, "u"); - isUniformAz = strcmp(obj.azDistribution, "u"); - - uniformDis = @(val1, val2) rand(1)*(val2 - val1) + val1; - gaussianDis = @(mean, sigma) normrnd(mean, sigma, 1); - - for i = 1:s - if isUniformMag(i) - magVector(i) = uniformDis(obj.mag(1,i), obj.mag(2,i)); - else - magVector(i) = gaussianDis(obj.mag(1,i), obj.mag(2,i)); - end - - if isUniformAz(i) - azVector(i) = uniformDis(obj.az(1,i), obj.az(2,i)); - else - azVector(i) = gaussianDis(obj.az(1,i), obj.az(2,i)); - end - end - - obj.magVec = magVector; - obj.azVec = azVector; - end - end - - function [uw, vw, ww] = windMatlabGenerator(obj, z, t, Hour, Day) - h = -z + obj.z0; - if h < 0 - h = 0; - end - - if nargin == 3 - if obj.HourMin == obj.HourMax - Day = obj.DayMin; - Hour = obj.HourMin; - end - end - - Seconds = Hour*3600; - % horizontal wind - [uw,vw] = atmoshwm(obj.lat0,obj.lon0,h,'day',Day,... - 'seconds',Seconds+t,'model','quiet','version','14'); % NED reference - ww = obj.ww; - - end - end -end diff --git a/classes/components/WindCustom.m b/classes/components/WindCustom.m new file mode 100644 index 0000000000000000000000000000000000000000..58547c2f788f0bd5125623d95b81c021f39ed6d6 --- /dev/null +++ b/classes/components/WindCustom.m @@ -0,0 +1,87 @@ +classdef WindCustom < Component + %UNTITLED Summary of this class goes here + % Detailed explanation goes here + + properties + altitudes (1, :) + + magnitudeDistribution (1, :) ... + {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] + end + + properties(SetAccess = private) + azimuth + magnitude + end + + properties(Access = protected) + configName = 'windConfig.m' + variableName = 'windCustom' + mission Mission + end + + methods + function obj = WindCustom(mission, varIn) + arguments(Input) + mission Mission = Mission() + varIn = [] + end + obj@Component(mission, varIn); + obj.setData(); + end + + function [uw, vw, ww] = getVels(obj, z) + s = length(obj.altitudes); % reference vectors length + if s==1 + uw = round( - obj.magnitude * cos(obj.azimuth), 6); + vw = round( - obj.magnitude * sin(obj.azimuth), 6); + ww = 0; + else + mag = interpLinear(obj.altitudes, obj.magnitude, z, true); + az = interpLinear(obj.altitudes, obj.azimuth, z, true); + + uw = round( - mag * cos(az), 6); + vw = round( - mag * sin(az), 6); + ww = 0; + end + end + end + + methods(Access = private) + function obj = setData(obj) + s = length(obj.altitudes); + magVector = nan(1,s); + azVector = nan(1,s); + isUniformMag = strcmp(obj.magnitudeDistribution, "u"); + isUniformAz = strcmp(obj.azimuthDistribution, "u"); + + uniformDist = @(val1, val2) rand(1)*(val2 - val1) + val1; + gaussianDist = @(mean, sigma) normrnd(mean, sigma, 1); + + for i = 1:s + if isUniformMag(i) + magVector(i) = uniformDist(obj.magnitudeParameters(1,i), ... + obj.magnitudeParameters(2,i)); + else + magVector(i) = gaussianDist(obj.magnitudeParameters(1,i), ... + obj.magnitudeParameters(2,i)); + end + + if isUniformAz(i) + azVector(i) = uniformDist(obj.azimuthParameters(1,i), ... + obj.azimuthParameters(2,i)); + else + azVector(i) = gaussianDist(obj.azimuthParameters(1,i), ... + obj.azimuthParameters(2,i)); + end + end + + obj.magnitude = magVector; + obj.azimuth = azVector; + end + end +end diff --git a/classes/components/WindMatlab.m b/classes/components/WindMatlab.m new file mode 100644 index 0000000000000000000000000000000000000000..d1ef4b559a03a84a3c068617263807c63c6dcc3a --- /dev/null +++ b/classes/components/WindMatlab.m @@ -0,0 +1,53 @@ +classdef WindMatlab < Component + %UNTITLED Summary of this class goes here + % Detailed explanation goes here + + properties + DayMin % [d] Minimum Day of the launch + DayMax % [d] Maximum Day of the launch + HourMin % [h] Minimum Hour of the day + HourMax % [h] Maximum Hour of the day + ww % [m/s] Vertical wind speed + end + + properties(Access = protected) + configName = 'windConfig.m' + variableName = 'windMatlab' + mission Mission + environment Environment + end + + methods + function obj = WindMatlab(mission, environment, varIn) + arguments(Input) + mission Mission = Mission() + environment Environment = Environment() + varIn = [] + end + if nargin > 0 && nargin < 2, error('MATLAB:narginchk:notEnoughInputs', ... + 'Not enough input arguments.'); end + obj@Component(mission, varIn); + obj.environment = environment; + end + + function [uw, vw, ww] = getVels(obj, z, t, Hour, Day) + h = -z + obj.environment.z0; + if h < 0 + h = 0; + end + + if nargin == 3 + if obj.HourMin == obj.HourMax + Day = obj.DayMin; + Hour = obj.HourMin; + end + end + + Seconds = Hour*3600; + % horizontal wind + [uw,vw] = atmoshwm(obj.environment.lat0, obj.environment.lon0,h,'day',Day,... + 'seconds',Seconds+t,'model','quiet','version','14'); % NED reference + ww = obj.ww; + end + end +end diff --git a/functions/configManagement/OLDaddParameter.m b/functions/configManagement/OLDaddParameter.m deleted file mode 100644 index cfef9cff735a57e44b4f11ffce4a3806c0675657..0000000000000000000000000000000000000000 --- a/functions/configManagement/OLDaddParameter.m +++ /dev/null @@ -1,260 +0,0 @@ -function parameters = addParameter(name, distr, type, A, B, varargin) -% createParameter - create the struct containing the attributes to compute -% the uncertanties in a given parameter -% -% Data is read from the common folder -% -% INPUTS: -% name, string: parameter name -% distr, int: input format and distribution type -% - 1: uniform, A [min]; B [max] -% val > A; val < B -% -% - 2: uniform, A [% min]; B [% max] -% val > A*v0 ; val < B*v0 (v0: nominal value) -% -% - 3: uniform, A [delta Min]; B [delta Max] -% val > v0 + A; val < v0 + B -% -% - 4: uniform, A [delta% min]; B [delta% max] -% val > (1 + A)*v0; val < (1 + B)*v0 -% -% - 5: gaussian, A [average]; B [standard deviation] -% mu = A; STD = B; -% val = randn -% -% - 6: gaussian, A [delta% avg]; B [standard deviation] -% mu = A; STD = B; -% val = (1 + randn)*v0 -% -% type, int: uncertanty type (meaningfull only if the uncertanty is -% applied to and array like the Thrust or the CA) -% - 1: the same uncertanty value is applied to each element -% - 2: the uncertanty is computed independently for each -% element -% -% A, double: A-parameter -% -% B, double: B-parameter -% -% parameters (optional), cell array: previous parameters -% (if present, the new parameter will be appended to the given cell array) -% -% OUTPUTS: -% par: struct, parameter struct - -if (nargin < 5 || nargin > 6), error('Wrong input arguments count: requires 5 or 6 arguments'), end -if mod(distr, 1) ~= 0, error('distr shall be integer'); end -if mod(type, 1) ~= 0, error('type shall be integer'); end -if distr < 1 || distr > 6, error('distr shall be an integer value between 1 and 6'); end -if type < 1 || type > 2, error('B shall be an integer value between 1 and 2'); end - -%% Loading data -switch name - case {'CA', 'CYB', 'CY0', 'CNA', 'CN0', 'Cl', 'Clp', 'Cma', 'Cm0', 'Cmad', 'Cmq', 'Cnb', 'Cn0', 'Cnr', 'Cnp'} - % load aerodynamics from data - case {'omega', 'phi'} - data = loadConfig('environmentConfig.m'); - case {'structMass', 'expMass'} - data = loadConfig('massConfig.m'); - case {'thrust'} - data = loadConfig('engineConfig.m'); - case {'Ixx', 'Iyy', 'Izz'} - data = loadConfig('inertiaConfig.m'); - case {'drogueS', 'drogueMass', 'drogueCL', 'drogueCD', 'paramainS', 'paramainMass', 'paramainCL', 'paramainCD'} - data = loadConfig('parachuteConfig.m'); - case {'rocketDiameter', 'rocketLCenter', 'centerOfMass', 'finRootChord', 'finFreeChord', 'finHeigth', 'finSemiThickness', 'ogiveLength', 'ogivePMod', 'ogiveCMod'} - data = loadConfig('geometryConfig.m'); - otherwise - error(strcat('Parameter: <', name,'> not known')); -end - -%% Creating parameters -if nargin == 5, len = 0; else - parameters = varargin{1}; - len = length(parameters); -end - -parameter = struct; -parameter.name = name; -parameter.distribution = distr; -parameter.type = type; -parameter.A = A; -parameter.B = B; -parameter.code = nan; - -switch name - % Aerodynamic coefficients ---- - case 'CA' - parameter.value = data.Coeffs(1, :, :, :, :, :, :); - parameter.code = 1; - parameter.UDM = '-'; - case 'CYB' - parameter.value = data.Coeffs(2, :, :, :, :, :, :); - parameter.code = 2; - parameter.UDM = '-'; - case 'CY0' - parameter.value = data.Coeffs(3, :, :, :, :, :, :); - parameter.code = 3; - parameter.UDM = '-'; - case 'CNA' - parameter.value = data.Coeffs(4, :, :, :, :, :, :); - parameter.code = 4; - parameter.UDM = '-'; - case 'CN0' - parameter.value = data.Coeffs(5, :, :, :, :, :, :); - parameter.code = 5; - parameter.UDM = '-'; - case 'Cl' - parameter.value = data.Coeffs(6, :, :, :, :, :, :); - parameter.code = 6; - parameter.UDM = '-'; - case 'Clp' - parameter.value = data.Coeffs(7, :, :, :, :, :, :); - parameter.code = 7; - parameter.UDM = '-'; - case 'Cma' - parameter.value = data.Coeffs(8, :, :, :, :, :, :); - parameter.code = 8; - parameter.UDM = '-'; - case 'Cm0' - parameter.value = data.Coeffs(9, :, :, :, :, :, :); - parameter.code = 9; - parameter.UDM = '-'; - case 'Cmad' - parameter.value = data.Coeffs(10, :, :, :, :, :, :); - parameter.code = 10; - parameter.UDM = '-'; - case 'Cmq' - parameter.value = data.Coeffs(11, :, :, :, :, :, :); - parameter.code = 11; - parameter.UDM = '-'; - case 'Cnb' - parameter.value = data.Coeffs(12, :, :, :, :, :, :); - parameter.code = 12; - parameter.UDM = '-'; - case 'Cn0' - parameter.value = data.Coeffs(13, :, :, :, :, :, :); - parameter.code = 13; - parameter.UDM = '-'; - case 'Cnr' - parameter.value = data.Coeffs(14, :, :, :, :, :, :); - parameter.code = 14; - parameter.UDM = '-'; - case 'Cnp' - parameter.value = data.Coeffs(15, :, :, :, :, :, :); - parameter.code = 15; - parameter.UDM = '-'; - % rocket/launch high level parameters ---- - case 'omega' - parameter.value = data.OMEGA; - parameter.code = 16; - parameter.UDM = 'rad'; - case 'phi' - parameter.value = data.PHI; - parameter.code = 17; - parameter.UDM = 'rad'; - case 'structMass' - parameter.value = data.structure; - parameter.code = 18; - parameter.UDM = 'kg'; - case 'expMass' - parameter.value = data.motor.expM; - parameter.code = 19; - parameter.UDM = 'kg'; - case 'thrust' - parameter.value = data.motor.expThrust; - parameter.code = 20; - parameter.UDM = 'N'; - case 'Ixx' - parameter.value = data.Ixx; - parameter.code = 21; - parameter.UDM = 'kg*m^4'; - case 'Iyy' - parameter.value = data.Iyy; - parameter.code = 22; - parameter.UDM = 'kg*m^4'; - case 'Izz' - parameter.value = data.Izz; - parameter.code = 23; - parameter.UDM = 'kg*m^4'; - case 'drogueS' - parameter.value = data.para(1, 1).S; - parameter.code = 24; - parameter.UDM = 'm2'; - case 'drogueMass' - parameter.value = data.para(1, 1).mass; - parameter.code = 25; - parameter.UDM = 'kg'; - case 'drogueCL' - parameter.value = data.para(1, 1).CL; - parameter.code = 26; - parameter.UDM = '-'; - case 'drogueCD' - parameter.value = data.para(1, 1).CD; - parameter.code = 27; - parameter.UDM = '-'; - case 'paramainS' - parameter.value = data.para(2, 1).S; - parameter.code = 28; - parameter.UDM = 'm2'; - case 'paramainMass' - parameter.value = data.para(2, 1).mass; - parameter.code = 29; - parameter.UDM = 'kg'; - case 'paramainCL' - parameter.value = data.para(2, 1).CL; - parameter.code = 30; - parameter.UDM = '-'; - case 'paramainCD' - parameter.value = data.para(2, 1).CD; - parameter.code = 31; - parameter.UDM = '-'; - % rocket geometry --- available with the stability run only - case 'rocketDiameter' - parameter.value = data.C; - parameter.code = 32; - parameter.UDM = 'm'; - case 'rocketLCenter' - parameter.value = data.Lcenter; - parameter.code = 33; - parameter.UDM = 'm'; - case 'centerOfMass' - parameter.value = data.xcg; - parameter.code = 34; - parameter.UDM = 'm'; - case 'finRootChord' - parameter.value = data.Chord1; - parameter.code = 35; - parameter.UDM = 'm'; - case 'finFreeChord' - parameter.value = data.Chord2; - parameter.code = 36; - parameter.UDM = 'm'; - case 'finHeigth' - parameter.value = data.Height; - parameter.code = 37; - parameter.UDM = 'm'; - case 'finSemiThickness' - parameter.value = data.zupRaw; - parameter.code = 38; - parameter.UDM = 'm'; - case 'ogiveLength' - parameter.value = data.Lnose; - parameter.code = 39; - parameter.UDM = 'm'; - case 'ogivePMod' - parameter.value = data.pMod; - parameter.code = 40; - parameter.UDM = '-'; - case 'ogiveCMod' - parameter.value = data.cMod; - parameter.code = 41; - parameter.UDM = '-'; - otherwise - error(strcat('Parameter: <', name,'> not known')); -end - -parameters{len+1} = parameter; -end - diff --git a/functions/configManagement/OLDloadConfig.m b/functions/configManagement/OLDloadConfig.m deleted file mode 100644 index ab06845c9c500b883f4adca2b7654885075c2ba4..0000000000000000000000000000000000000000 --- a/functions/configManagement/OLDloadConfig.m +++ /dev/null @@ -1,24 +0,0 @@ -function varargout = loadConfig(varargin) -% launchProb - This function reads and outputs data structures from .m -% files present in the config folder -% -% INPUTS: - fileNames -% -% OUTPUTS: -% - stucts, ordered based on input - -varargout = cell(1, nargin); -mission = varargin{end}; - -%% LOAD desired configs - for i = 1:nargin-1 - fileName = char(varargin{i}); - if ~isfile(fullfile(mission.configPath, fileName)) - error(strcat("File not found inside the config folder: ", varargin{i})); - end - - varName = strtok(fileName,'C'); - run(fileName); - varargout{i} = eval(varName); - end -end \ No newline at end of file diff --git a/functions/configManagement/OLDpreProcess.m b/functions/configManagement/OLDpreProcess.m deleted file mode 100644 index 9e6fe8a55ddd024fdd1cc14874f99ff06f9dea78..0000000000000000000000000000000000000000 --- a/functions/configManagement/OLDpreProcess.m +++ /dev/null @@ -1,6 +0,0 @@ -function [outputArg1,outputArg2] = preProcess(inputArg1,inputArg2) -%PREPROCESS Summary of this function goes here -% Detailed explanation goes here -outputArg1 = inputArg1; -outputArg2 = inputArg2; -end \ No newline at end of file diff --git a/functions/configManagement/functionSignatures.json b/functions/configManagement/functionSignatures.json deleted file mode 100644 index e995e02fcb83035ee103f43982ac4567d3ee45ce..0000000000000000000000000000000000000000 --- a/functions/configManagement/functionSignatures.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "addParameter": - { - "inputs": - [ - {"name":"parameter", "kind":"required", "type": - [ - "choices={'CA', 'CYB', 'CY0', 'CNA', 'CN0', 'Cl', 'Clp', 'Cma', 'Cm0', 'Cmad', 'Cmq', 'Cnb', 'Cn0', 'Cnr', 'Cnp', 'omega', 'phi', 'structMass', 'expMass', 'thrust', 'Ixx', 'Iyy', 'Izz', 'drogueS', 'drogueMass', 'drogueCL', 'drogueCD', 'paramainS', 'paramainMass', 'paramainCL', 'paramainCD', 'rocketDiameter', 'rocketLCenter', 'centerOfMass', 'finRootChord', 'finFreeChord', 'finHeigth', 'finSemiThickness', 'ogiveLength', 'ogivePMod', 'ogiveCMod'}" - ], - "purpose":"The parameter you wish to change"}, - {"name":"distribution", "kind":"required", "type":["integer", ">0", "<7"], "purpose":"Distribution type. See help for more info."}, - {"name":"type", "kind":"required", "type":["integer", ">0", "<3"], "purpose":"How to apply distribution. See help for more info."}, - {"name":"A", "kind":"required", "type":["numeric"], "purpose":"Parameter used for distribution"}, - {"name":"B", "kind":"required", "type":["numeric"], "purpose":"Parameter used for distribution"}, - {"name":"parameters", "kind":"ordered"} - ], - "outputs": - [ - {"name":"parameter", "type":["nrows=1"]} - ] - } -} \ No newline at end of file diff --git a/functions/datcom/createFor006.m b/functions/datcom/createFor006.m deleted file mode 100644 index 43a325a86920bf7b97f2af9b67e11394e723f132..0000000000000000000000000000000000000000 --- a/functions/datcom/createFor006.m +++ /dev/null @@ -1,336 +0,0 @@ -function createFor006(datcom, settings, datcomPath) -%{ - -CREATEFOR006 - function to create the 'for006.dat' file. - -INPUTS: - - datcom, struct, data of the rocket and the simulation; - - settings, struct, data of the rocket and the simulation; - - datcomPath, path, relative path from where this function is called - to the location of this function. - -OUTPUTS: -/ - -CALLED FUNCTION: - - -REVISION: -- #0 21/10/2019, Release, Giulio Pacifici - -- #1 Revision, Adriano Filippo Inno -- #2 04/11/2023 Update, Marco Luigi Gaibotti -%} - -oldFolder = cd; % save the older current directory -cd(datcomPath) % redirect the new directory in 'commonFunctions/Datcom' - -%% recalling the variables -MachOriginal = datcom.Mach; -Alpha = datcom.Alpha; -Beta = datcom.Beta; -Alt = datcom.Alt; - -Mach = round(MachOriginal, 2); % Every number of the Mach vector rounded up to the second decimal digit -if max(Mach - MachOriginal) < 1e-2 && max(Mach - MachOriginal) > 1e-10 % Warning if the Mach numbers have more than 2 decimal digits - warning("Too many decimal digits of Mach. Reduce to 2 digits after the decimal point." ... - +"Mach vector has been automatically rounded up."); -end -if length(Mach) > 20 % Warning if the length of the Mach vector is bigger than 20 - Mach = Mach(1:20); % Mach vector reduced to the first 20 numbers. - warning("Too many Mach numbers." ... - +"The Mach vector has been automatically reduced to first 20 Mach numbers.") -end -C1 = datcom.Chord1; -C2 = datcom.Chord2; - -C = settings.C; -r = C/2; -S = pi*C^2/4; -if isfield(datcom,'Lnose') - Lnose = datcom.Lnose; -else - Lnose = settings.Lnose; -end -OgType = datcom.OgType; -deltaXLE = datcom.deltaXLE; -xcg = datcom.xcg + Lnose; - -Lcenter = settings.Lcenter + settings.boatL - datcom.Laft; -Npanel = settings.Npanel; -Ler = settings.Ler(1); -d = settings.d; -zup_raw = settings.zupRaw; -Lmaxu_raw = settings.LmaxuRaw; -H = datcom.Height; -Taft = datcom.Taft; -Laft = datcom.Laft; -Daft = datcom.Daft; - -if Npanel == 3 - Phif = [0, 120, 240]; -elseif Npanel == 4 - Phif = [0, 90, 180, 270]; -end - -Nm = length(Mach); -Na = length(Alpha); -Nb = length(Beta); -Nalt = length(Alt); - -%% protuberance data -if isfield(datcom, 'hprot') && datcom.hprot ~= 0 - protub_flag = 1; - % constants - xprot = settings.xprot + Lnose; - nloc = settings.nloc; - lprot = settings.lprot; - wprot = settings.wprot; - % variables - hprot = datcom.hprot; -else - protub_flag = 0; -end - -%% datcom -Xle1 = Lcenter + Lnose - d - C1; -Xle2 = Xle1 + deltaXLE; - -%%% Defining Fin Section -Zup = [zup_raw/C1, zup_raw/C2]; -Lmaxu = [Lmaxu_raw/C1, Lmaxu_raw/C2]; -Lflatu = [(C1 - 2*Lmaxu_raw)/C1, (C2 - 2*Lmaxu_raw)/C2]; - -%%% Creating for005.dat file from previous data -if isunix % unix procedure - fid = fopen(strcat(pwd, '/for005.dat'),'w+'); -else - fid = fopen(strcat(pwd, '\for005.dat'),'w+'); -end - -%%%%%%%%%%%% Flight Conditions -%%%% Beta -fprintf(fid, ' $FLTCON\r\n'); -fprintf(fid, ' BETA = '); -fprintf(fid, '%.2f,\r\n', Beta(1)); -%%%% Alt -fprintf(fid, ' ALT = '); -fprintf(fid, '%d', Nm); -fprintf(fid, '*'); -fprintf(fid, '%d.,\r\n', Alt(1)); -%%%% Nmach -fprintf(fid, ' NMACH = '); -fprintf(fid, '%d., \r\n', Nm); -%%%% Mach -fprintf(fid, ' MACH = '); -if Nm > 11 - for M = 1:11 - fprintf(fid, '%.2f,',Mach(M)); - end - fprintf(fid, ' \r\n MACH(12) = '); - for M = 12:Nm - fprintf(fid, '%.2f',Mach(M)); - fprintf(fid, ','); - end -else - for M = 1:Nm - fprintf(fid, '%.2f,',Mach(M)); - end -end - -fprintf(fid, '\r\n'); -%%%% Nalpha -fprintf(fid, ' NALPHA = '); -fprintf(fid, '%d., \r\n', Na); -%%%% Alpha -fprintf(fid, ' ALPHA = '); -if Na > 9 - for a = 1:9 - fprintf(fid, '%.1f,', Alpha(a)); - end - fprintf(fid, ' \r\n ALPHA(10) = '); - for a = 10:Na - fprintf(fid, '%.1f,', Alpha(a)); - end -else - for a = 1:Na - fprintf(fid, '%.1f,', Alpha(a)); - end -end - -fprintf(fid, '$'); - -%%%%%%%%%%%% Reference Quantities -fprintf(fid, '\r\n $REFQ\r\n'); -%%%% XCG -fprintf(fid, ' XCG = '); -fprintf(fid, '%.4f,\r\n', xcg); -%%%% SREF -fprintf(fid, ' SREF = '); -fprintf(fid, '%.5f,\r\n', S); -%%%% LREF -fprintf(fid, ' LREF = '); -fprintf(fid, '%.3f,\r\n', C); -%%%% LATREF -fprintf(fid, ' LATREF = '); -fprintf(fid, '%.3f,$', C); -%%%% TNOSE -%%%%%%%%%%%% Axisymmetric Body Geometry -fprintf(fid, '\r\n $AXIBOD\r\n'); -%%%% TNOSE -fprintf(fid, ' TNOSE = %s, \r\n', OgType); -if strcmp(OgType, 'POWER') - if isfield(settings,'autoMatProt_flag') - fprintf(fid, ' POWER = %.3f, \r\n', settings.NosePower); - else - fprintf(fid, ' POWER = %.3f, \r\n', datcom.NosePower); - end -end - -%%%% LNOSE -fprintf(fid, ' LNOSE = '); -fprintf(fid, '%.3f, \r\n', Lnose); -%%%% DNOSE -fprintf(fid, ' DNOSE = '); -fprintf(fid, '%.3f, \r\n', C); -%%%% LCENTR -fprintf(fid, ' LCENTR = '); -fprintf(fid, '%.3f, \r\n', Lcenter); -%%%% DCENTR -fprintf(fid, ' DCENTR = '); -fprintf(fid, '%.3f, \r\n', C); -%%% BOAT-TAIL -if Laft ~= 0 - %%%% TAFT - fprintf(fid, ' TAFT = '); - fprintf(fid, '%.1f, \r\n', Taft); - %%%% LAFT - fprintf(fid, ' LAFT = '); - fprintf(fid, '%.3f, \r\n', Laft); - %%%% DAFT - fprintf(fid, ' DAFT = '); - fprintf(fid, '%.3f, \r\n', Daft); -end -if isfield(settings, 'pMod') - %%%% PMOD - fprintf(fid, ' PMOD = '); - fprintf(fid, '%.4f, \r\n', settings.pMod); -end -if isfield(settings, 'cMod') - %%%% CMOD - fprintf(fid, ' CMOD = '); - fprintf(fid, '%.4f, \r\n', settings.cMod); -end -%%%% DEXIT -fprintf(fid, ' DEXIT = 0.,'); -fprintf(fid, '\r\n'); -%%%% BASE -fprintf(fid, ' BASE = .FALSE.,$'); - -% add protuberance if configuration is empty and if current -% % protuberance area is different from zero -if protub_flag - fprintf(fid, '\r\n $PROTUB \r\n'); - fprintf(fid, ' NPROT = 1., \r\n'); - fprintf(fid, ' PTYPE = BLOCK, \r\n'); - fprintf(fid, ' XPROT = '); - fprintf(fid, '%.3f, \r\n', xprot); - fprintf(fid, ' NLOC = '); - fprintf(fid, '%.3f, \r\n', nloc); - fprintf(fid, ' LPROT = '); - fprintf(fid, '%.3f, \r\n', lprot); - fprintf(fid, ' WPROT = '); - fprintf(fid, '%.4f, \r\n', wprot); - fprintf(fid, ' HPROT = '); - fprintf(fid, '%.4f, \r\n', hprot); - fprintf(fid, ' OPROT = 0.,$'); -end - -%%%%%%%%%%%% Finset -fprintf(fid, '\r\n $FINSET1 \r\n'); -%%%% XLE -fprintf(fid, ' XLE = '); -fprintf(fid, '%.3f,', Xle1); -fprintf(fid, '%.3f, \r\n', Xle2); -%%%% NPANEL -fprintf(fid, ' NPANEL = '); -fprintf(fid, '%.1f,\r\n', Npanel); -%%%% PHIF -fprintf(fid, ' PHIF = '); -for P = 1:length(Phif) - fprintf(fid, '%.1f', Phif(P)); - fprintf(fid, ','); -end -fprintf(fid, '\r\n'); -%%%% LER -fprintf(fid, ' LER = 2*'); -fprintf(fid, '%.4f,\r\n', Ler); -%%%% SSPAN -fprintf(fid, ' SSPAN = '); -fprintf(fid, '%.3f,', r); -fprintf(fid, '%.3f,\r\n', r + H); -%%%% CHORD -fprintf(fid, ' CHORD = '); -fprintf(fid, '%.3f,', C1); -fprintf(fid, '%.3f,\r\n', C2); -%%%% SECTYP -fprintf(fid, ' SECTYP = HEX, \r\n'); -%%%% ZUPPER -fprintf(fid, ' ZUPPER = '); -fprintf(fid, '%.4f,', Zup(1)); -fprintf(fid, '%.4f,\r\n', Zup(2)); -%%%% LMAXU -fprintf(fid, ' LMAXU = '); -fprintf(fid, '%.4f,', Lmaxu(1)); -fprintf(fid, '%.4f,\r\n', Lmaxu(2)); -%%%% LFLATU -fprintf(fid, ' LFLATU = '); -fprintf(fid, '%.4f,', Lflatu(1)); -fprintf(fid, '%.4f,$ \r\n', Lflatu(2)); - -%%%%%%%%%%%% Options -fprintf(fid, 'DERIV RAD \r\n'); -fprintf(fid, 'DIM M \r\n'); -fprintf(fid, 'DAMP \r\n'); -fprintf(fid, 'SAVE \r\n'); -fprintf(fid, 'NEXT CASE \r\n'); - -%%%%%%%%%%%% Cases -for A = 1:Nalt - for B = 1:Nb - if not(A == 1 && B == 1) - fprintf(fid,' $FLTCON \r\n'); - fprintf(fid,' BETA = '); - fprintf(fid, '%.1f, \r\n', Beta(B)); - fprintf(fid, ' ALT = '); - fprintf(fid, '%d', Nm); - fprintf(fid, '*'); - fprintf(fid, '%d.,$ \r\n', Alt(A)); - fprintf(fid, 'DERIV RAD\r\n'); - fprintf(fid, 'DIM M\r\n'); - fprintf(fid, 'DAMP\r\n'); - fprintf(fid, 'SAVE\r\n'); - fprintf(fid, 'NEXT CASE\r\n'); - end - end -end -fclose(fid); - -if isunix - [~, ~] = system('./datcom for005.dat'); -else - [~, ~] = system('datcom.exe for005.dat'); -end - -value = 0; -didItRun = 0; -while value == 0 && didItRun < 5000 - value = exist('for006.dat', 'file'); - pause(0.001); - didItRun = didItRun + 1; -end - -if didItRun >= 5000 - error('datcom did not run'); -end - -cd(oldFolder); % redirect back the current directory to the old folder diff --git a/functions/datcom/datcomParser.m b/functions/datcom/datcomParser.m deleted file mode 100644 index 50ed85de72e0cc49d405b69bbfd9d9c0f4ad5dfa..0000000000000000000000000000000000000000 --- a/functions/datcom/datcomParser.m +++ /dev/null @@ -1,259 +0,0 @@ -function [Coeffs, State] = datcomParser(varargin) -%{ - datcomParser - function to parse the 'for006.dat' file and to generate the - matrices of the aerodynamic coefficients. - -INPUTS: - - varargin, it can be either a string that contains the name of .mat file - that is saved in the Current Folder or it can be an empty field - and the .mat file is not saved. - (Read NOTES for more informations.) - -OUTPUTS: - - Coeffs, struct, struct in which the fields are the matrices of the aerodynamic - coefficients. (e.g. Coeffs.CA) - - State:, struct, struct in which the fields are the arrays of the aerodynamic states - (Alpha, Mach, Beta, Altitude) used to compute the aerodynamic - coefficients. - -NOTES: If the function is used with the syntax -'[Coeffs, State] = datcomParser()' the file .mat is not saved in the -Current Folder. If the function is used with the syntax -'[Coeffs, State] = datcomParser('name')' a file called 'name.mat' is saved -in the settings.mission Folder. This file contains the two structs Coeffs and -State that can be loaded into the workspace in any future moment using the -command MATLAB function 'load'. Note that the file 'for006.dat' that has to -be parsed must be in the Current Folder. -!! ATTENTION !! Coefficients matrices contains only 15 coefficients, to add -coefficients check parsedNames variable. - -CALLED FUNCTIONS: - - -REVISIONS: -- #0 14/10/2019, Release, Giulio Pacifici - -- #1 10/11/2020, Revision, Adriano Filippo Inno - str2num and str2double removed - -- #2 10/11/2020, Revision, Adriano Filippo Inno - improved speed avoiding to parse each aerodynamic state - -- #3 10/11/2020, Revision, Adriano Filippo Inno - improved speed avoiding to parse each line of the block - -- #4 15/11/2020, Revision, Adriano Filippo Inno - improved speed passing from line parsing to matrix parsing - -- #5 27/04/2021, Revision, Adriano Filippo Inno - check to prevent failure added -%} - -if not(isempty(varargin)) - mat_name = varargin{1}; - savemat = true; -else - savemat = false; -end - -linestring = fileread('for006.dat'); - -%% check for computational errors in XCP -pattern = '(\d)\*+([\n\s\-])'; -newPattern = '$2 NaN $2'; -linestring = regexprep(linestring, pattern, newPattern); - -%% blocksplit -pattern = '\*+ \<FLIGHT CONDITIONS AND REFERENCE QUANTITIES \*+'; -blocks = regexp(linestring, pattern, 'split'); -block1 = blocks(1); -blocks = blocks(2:end); - -%% error check -error_check = regexp(block1, '(** ERROR **)', 'tokens'); -if not(isempty(error_check{1})) - error('Attention: Error in the ''for006.dat'' file.'); -end - -%% length check -pattern = '*** END OF JOB ***'; -if not(contains(linestring, pattern)) - error('Datcom didn''t complete the computations, probably the for005 contains too many cases') -end - -%% get coefficient names -pattern = ' *\<ALPHA\> *([\w -/]*)'; -pattern1 = '[\./-]'; -names = cell(26, 1); -index = 1; - -for i = 1:4 - block = blocks{i}; - token = regexp(block, pattern, 'tokens'); - - % convert cells inside token into strings - for k = 1:length(token) - token{k} = char(token{k}); - end - - dummy = split(join(token(:))); - correct = dummy; - - for j = 1:length(dummy) - name = dummy{j}; - a = regexprep(name(1:end-1), pattern1, '_'); - b = regexprep(name(end), pattern1, ''); - correct{j} = [a, b]; - end - names(index:index+length(correct)-1) = correct; - index = index+length(correct); -end -NL = length(names); - -%% get the aerodynamic states -pattern1 = ' *\<MACH NO\> *= * (-*[\d]+.[\d]*)'; -pattern2 = ' *\<ALTITUDE\> *= * (-*[\d]+.[\d]*)'; -pattern3 = ' *\<SIDESLIP\> *= * (-*[\d]+.[\d]*)'; - -%%% Mach -Nb = length(blocks); -NM = min([21, Nb/4]); % initial guess -M = zeros(1, NM); -for i = 1:NM - jj = (i - 1)*4 + 1; - block = blocks{jj}; - mach = regexp(block, pattern1, 'tokens'); - M(i) = sscanf(char(mach{1}), '%f'); - if i > 1 && M(i) == M(1) - M = M(1:i-1); - break; - end -end -NM = length(M); - -%%% Beta -NB = min([97, Nb/4/NM]); % initial guess -B = zeros(1, NB); -for i = 1:NB - jj = (i - 1)*4*NM + 1; - block = blocks{jj}; - sslip = regexp(block, pattern3, 'tokens'); - B(i) = sscanf(char(sslip{1}), '%f'); - if i > 1 && B(i) == B(1) - B = B(1:i-1); - break; - end -end -NB = length(B); - -%%% Altitude -NA = Nb/4/NM/NB; -A = zeros(1, NA); -for i = 1:NA - jj = (i - 1)*4*NM*NB + 1; - block = blocks{jj}; - alt = regexp(block, pattern2, 'tokens'); - A(i) = sscanf(char(alt{1}), '%f'); -end -A = A(1:i); - -Mrep = repmat(M, 1, NB*NA); -Brep = repmat(repelem(B, 1, NM), 1, NA); -Arep = repelem(A, 1, NM*NB); - -%%% Alpha -pattern = '^[-\d](?=[\d\.])'; - -block = blocks{2}; -lines = splitlines(block); -index = 0; -new_1 = cell(200, 1); - -for j = 1:length(lines) - line = lines{j}; - line = strtrim(line); - - if regexp(line, pattern, 'once') - index = index + 1; - new_1{index} = sscanf(line, '%f'); - end - -end - -alpha = zeros(1, index); - -for j = 1:index - row = new_1{j}; - alpha(j) = row(1); -end -Na = length(alpha); - -%% get the aerodynamic data -raw_data = zeros(Na, Nb*NL/4); -ll = 1; -for i = 1:Nb - block = blocks{i}; - lines = splitlines(block); - - j = 1; - line = "a"; - while not( contains(line, 'NaN') || all(not(isletter(line))) ) || isempty(line) - line = strtrim(lines{j}); - j = j + 1; - end - - lineScan = sscanf(line, '%f'); - Nls = length(lineScan) - 1; - raw_data(1, ll:ll+Nls-1) = lineScan(2:end)'; - charMatr = join(lines(j:j+Na-1)); - Matr = sscanf(charMatr{1}, '%f', [Nls+1, Na-1]); - raw_data(2:end, ll:ll+Nls-1) = Matr(2:end, :)'; - j = j + Na - 1; - - if not(all(not(contains(lines(j:end), 'ALPHA')))) - line = "a"; - while not( contains(line, 'NaN') || all(not(isletter(line))) ) || isempty(line) - line = strtrim(lines{j}); - j = j + 1; - end - - lineScan = sscanf(line, '%f'); - Nls2 = length(lineScan) - 1; - raw_data(1, ll+Nls:ll+Nls+Nls2-1) = lineScan(2:end)'; - - charMatr = join(lines(j:j+Na-1)); - Matr = sscanf(charMatr{1}, '%f', [Nls2+1, Na-1]); - raw_data(2:end, ll+Nls:ll+Nls+Nls2-1) = Matr(2:end, :)'; - else - Nls2 = 0; - end - ll = ll + Nls + Nls2; - -end - -%% savemat -Coeffs = zeros(NL, Na, NM, NB, NA); - -for i = 1:Nb/4 - iA = A==Arep(i); - iB = B==Brep(i); - iM = M==Mrep(i); - - for j = 1:NL - Coeffs(j, :, iM, iB, iA) = raw_data(:, NL*(i-1)+j); - end -end - -State.Machs = M; -State.Alphas = alpha; -State.Betas = B; -State.Altitudes = A; - -%parsedNames = [3, 13, 4, 11, 1, 6, 26, 12, 2, 20, 17, 14, 5, 22, 25, 10, 15]; -parsedNames = [3, 13, 4, 11, 1, 6, 26, 12, 2, 20, 17, 14, 5, 22, 25, 10]; - -Coeffs = Coeffs(parsedNames, :, :, :, :); - -if savemat - Geometry = varargin{2}; - save(mat_name, 'State', 'Coeffs', 'Geometry'); -end diff --git a/functions/roccarasoTerrainData/funZGen.m b/functions/roccarasoTerrainData/funZGen.m deleted file mode 100644 index 92b8703bd1c3a9021123f092d5d618559e9197ec..0000000000000000000000000000000000000000 --- a/functions/roccarasoTerrainData/funZGen.m +++ /dev/null @@ -1,43 +0,0 @@ -function funZ = funZGen(fn_map, lat0, lon0) -%{ - funZ - This function tells the altitude of landing point at Roccaraso - INPUTS: - -fn_map, filename of the map - -lat0, double [1, 1], latitude of the origin - -lon0, double [1, 1], longitude of the origin - - OUTPUTS - -z, double [1, 1], altitude of the landing point: - -if mode=='xy' --> z=funZ(x,y) in a NED system - -if mode=='LL' --> z=funZ(lat,lon) in a wgs84 based LLA system - CALLED FUNCTIONS: / -Copyright © 2021, Skyward Experimental Rocketry, AFD department -All rights reserved - -SPDX-License-Identifier: GPL-3.0-or-later - -%} -load(fn_map, 'RA', 'ZA', 'latlim', 'lonlim') -if lat0 < latlim(1) || lat0 > latlim(2) || lon0 < lonlim(1) || lon0 > lonlim(2) - error('the initial coordinates are outside the range of the zData.map coordinates, check the config') -end - - -lat = RA.LatitudeLimits(2) - (RA.YIntrinsicLimits(1):(RA.YIntrinsicLimits(2)-1))*RA.CellExtentInLatitude; -lon = RA.LongitudeLimits(1) + (RA.XIntrinsicLimits(1):(RA.XIntrinsicLimits(2)-1))*RA.CellExtentInLongitude; -jmax = length(lon); -imax = length(lat); -LON = zeros(imax*jmax, 1); -LAT = zeros(imax*jmax, 1); -ZOO = zeros(imax*jmax, 1); - -for j = 1:jmax - LON((imax*(j - 1) + 1):(imax*j)) = ones(imax, 1)*lon(j); - LAT((imax*(j - 1) + 1):(imax*j)) = lat; - ZOO((imax*(j - 1) + 1):(imax*j)) = ZA(:,j); -end - -h0 = relative*geointerp(ZA, RA, lat0, lon0); -[xNorth, yEast, zDown] = geodetic2ned(LAT, LON, ZOO, lat0, lon0, h0, wgs84Ellipsoid); -funZ = scatteredInterpolant(xNorth, yEast, zDown); - diff --git a/functions/roccarasoTerrainData/zdata.mat b/functions/roccarasoTerrainData/zdata.mat deleted file mode 100644 index 2c148ef7fe9ed43f473f54fc7ef2c8e5cdad7e46..0000000000000000000000000000000000000000 --- a/functions/roccarasoTerrainData/zdata.mat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c95b9364010ce84d32cb202e266e1a83bef03c78ba9fa3a315f5ce3d270324d3 -size 3441807 diff --git a/missions/2024_Lyra_Roccaraso_September/config/windConfig.m b/missions/2024_Lyra_Roccaraso_September/config/windConfig.m index 25eaee3a231d6894f27113d19f85c878c893ab57..e95aec56f381677dc3f7d7a0c9fba64627066f8d 100644 --- a/missions/2024_Lyra_Roccaraso_September/config/windConfig.m +++ b/missions/2024_Lyra_Roccaraso_September/config/windConfig.m @@ -6,29 +6,24 @@ % 90 deg -> East % 180 deg -> South % 270 deg -> West -wind = Wind(); -wind.model = 'matlab'; % [] Chosen wind model: 'custom' or 'matlab' %% CUSTOM WIND MODEL -wind.magnitudeMin = 1; % [m/s] Minimum Magnitude -wind.magnitudeMax = 5; % [m/s] Maximum Magnitude -wind.elevationMin = 0*pi/180; % [rad] Minimum Elevation, user input in degrees (ex. 0) -wind.elevationMax = 0*pi/180; % [rad] Maximum Elevation, user input in degrees (ex. 0) (Max == 90 Deg) -wind.azimuthMin = wrapTo360(180)*pi/180; % [rad] Minimum Azimuth, user input in degrees (ex. 90) -wind.azimuthMax = wrapTo360(180)*pi/180; % [rad] Maximum Azimuth, user input in degrees (ex. 90) +windCustom = WindCustom(); -wind.altitudes = [0 200 2000]; % [m] Altitudes at which a distribution change occurs -wind.magnitudeDistribution = ["g", "u", "u"]; % [] -wind.magnitudeParameters = [7 2 10; % [] +windCustom.altitudes = [0 200 2000]; % [m] Altitudes at which a distribution change occurs +windCustom.magnitudeDistribution = ["g", "u", "u"]; % [] +windCustom.magnitudeParameters = [7 2 10; % [] 0.5 9 20]; -wind.azimuthDistribution = ["u", "u", "u"]; % [] -wind.azimuthParameters = 0*pi/180 * ones(2,3); % [] +windCustom.azimuthDistribution = ["u", "u", "u"]; % [] +windCustom.azimuthParameters = 0*pi/180 * ones(2,3); % [] %% MATLAB WIND MODEL -wind.DayMin = 105; % [d] Minimum Day of the launch -wind.DayMax = 105; % [d] Maximum Day of the launch -wind.HourMin = 4; % [h] Minimum Hour of the day -wind.HourMax = 4; % [h] Maximum Hour of the day -wind.ww = 0; % [m/s] Vertical wind speed \ No newline at end of file +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