From 3a1546e14297c53abf1d50724e80709e533cea7b Mon Sep 17 00:00:00 2001 From: Mauco03 <marco.gaibotti@skywarder.eu> Date: Mon, 24 Mar 2025 22:56:07 +0100 Subject: [PATCH] [handle-value-conversion] Fixed wind model --- classes/misc/Wind.m | 146 +++++++++++++++++++++++++++++++++----------- 1 file changed, 111 insertions(+), 35 deletions(-) diff --git a/classes/misc/Wind.m b/classes/misc/Wind.m index 3adff25..e8aa811 100644 --- a/classes/misc/Wind.m +++ b/classes/misc/Wind.m @@ -9,31 +9,111 @@ classdef Wind < Config % - mission: Mission, mission object % - varIn: (optional) config source. Alternative to config.m % file - properties + properties(Dependent) altitudes (1, :) magnitudeDistribution (1, :) ... - {mustBeMember(magnitudeDistribution, {'u', 'g'})} = 'u' % [-] Magnitude distrubution: uniform, gaussian + {mustBeMember(magnitudeDistribution, {'u', 'g'})} % [-] Magnitude distrubution: uniform (default), gaussian azimuthDistribution (1, :) ... - {mustBeMember(azimuthDistribution, {'u', 'g'})} = 'u' % [-] Azimuth distrubution: uniform, gaussian + {mustBeMember(azimuthDistribution, {'u', 'g'})} % [-] Azimuth distrubution: uniform (default), gaussian elevationDistribution (1, :) ... - {mustBeMember(elevationDistribution, {'u', 'g'})} = 'u' % [-] Elevation distrubution: uniform, gaussian - magnitudeParameters (2, :) % [m/s] Distribution parameters: [min; max], [mu; sigma] - azimuthParameters (2, :) % [deg] Distribution parameters: [min; max], [mu; sigma] - elevationParameters (2, :) % [deg] Distribution parameters: [min; max], [mu; sigma] + {mustBeMember(elevationDistribution, {'u', 'g'})} % [-] Elevation distrubution: uniform (default), gaussian + + magnitudeParameters (2, :) % [m/s] Distribution parameters: [min; max], [mu; sigma] + azimuthParameters (2, :) % [deg] Distribution parameters: [min; max], [mu; sigma] + elevationParameters (2, :) % [deg] Distribution parameters: [min; max], [mu; sigma] end + properties(Access = private) + ALTITUDES + + MAGNITUDE_DISTRIBUTION = '' + AZIMUTH_DISTRIBUTION = '' + ELEVATION_DISTRIBUTION = '' + + MAGNITUDE_PARAMETERS = [] + AZIMUTH_PARAMETERS = [] + ELEVATION_PARAMETERS = [] + end + properties(SetAccess = private) azimuth elevation magnitude end + properties(Access = private) + checks (1, 3) logical % true if #[magnitude, azimuth, elevation] == #altitudes + end + properties(Constant, Access = protected) configName = 'windConfig.m' variableName = 'windCustom' end + methods % Getters / Setters + function obj = set.altitudes(obj, value) + if length(value) ~= length(obj.ALTITUDES) + obj.ALTITUDES = value; + obj.magnitude = obj.updateDistribution(obj.MAGNITUDE_DISTRIBUTION, obj.MAGNITUDE_PARAMETERS); + obj.azimuth = obj.updateDistribution(obj.AZIMUTH_DISTRIBUTION, obj.AZIMUTH_PARAMETERS); + obj.elevation = obj.updateDistribution(obj.ELEVATION_DISTRIBUTION, obj.ELEVATION_PARAMETERS); + else + obj.ALTITUDES = value; + end + + obj.checks(1) = length(obj.magnitude) == length(obj.ALTITUDES); + obj.checks(2) = length(obj.azimuth) == length(obj.ALTITUDES); + obj.checks(3) = length(obj.elevation) == length(obj.ALTITUDES); + end + + function obj = set.magnitudeDistribution(obj, value) + obj.MAGNITUDE_DISTRIBUTION = value; + obj.magnitude = obj.updateDistribution(value, obj.MAGNITUDE_PARAMETERS); + obj.checks(1) = length(obj.magnitude) == length(obj.ALTITUDES); + end + + function obj = set.magnitudeParameters(obj, value) + obj.MAGNITUDE_PARAMETERS = value; + obj.magnitude = obj.updateDistribution(obj.MAGNITUDE_DISTRIBUTION, value); + obj.checks(1) = length(obj.magnitude) == length(obj.ALTITUDES); + end + + function obj = set.azimuthDistribution(obj, value) + obj.AZIMUTH_DISTRIBUTION = value; + obj.azimuth = obj.updateDistribution(value, obj.AZIMUTH_PARAMETERS); + obj.checks(2) = length(obj.azimuth) == length(obj.ALTITUDES); + end + + function obj = set.azimuthParameters(obj, value) + obj.AZIMUTH_PARAMETERS = value; + obj.azimuth = obj.updateDistribution(obj.AZIMUTH_DISTRIBUTION, value); + obj.checks(2) = length(obj.azimuth) == length(obj.ALTITUDES); + end + + function obj = set.elevationDistribution(obj, value) + obj.ELEVATION_DISTRIBUTION = value; + obj.elevation = obj.updateDistribution(value, obj.ELEVATION_PARAMETERS); + obj.checks(3) = length(obj.elevation) == length(obj.ALTITUDES); + end + + function obj = set.elevationParameters(obj, value) + obj.ELEVATION_PARAMETERS = value; + obj.elevation = obj.updateDistribution(obj.ELEVATION_DISTRIBUTION, value); + obj.checks(3) = length(obj.elevation) == length(obj.ALTITUDES); + end + + function value = get.altitudes(obj), value = obj.ALTITUDES; end + + function value = get.magnitudeDistribution(obj), value = obj.MAGNITUDE_DISTRIBUTION; end + function value = get.azimuthDistribution(obj), value = obj.AZIMUTH_DISTRIBUTION; end + function value = get.elevationDistribution(obj), value = obj.ELEVATION_DISTRIBUTION; end + + function value = get.magnitudeParameters(obj), value = obj.MAGNITUDE_PARAMETERS; end + function value = get.azimuthParameters(obj), value = obj.AZIMUTH_PARAMETERS; end + function value = get.elevationParameters(obj), value = obj.ELEVATION_PARAMETERS; end + end + methods function obj = Wind(mission, varIn) arguments(Input) @@ -41,10 +121,14 @@ classdef Wind < Config varIn = [] end obj@Config(mission, varIn); - obj = obj.updateAll(); end function [uw, vw, ww] = getVels(obj, z) + if ~all(obj.checks) + error(['Parameters and distributions must be the same ' ... + 'size as altitudes or scalar']); + end + if isscalar(obj.altitudes) uw = round( - obj.magnitude * cos(obj.azimuth) * cos(obj.elevation), 6); vw = round( - obj.magnitude * sin(obj.azimuth) * cos(obj.elevation), 6); @@ -53,36 +137,38 @@ classdef Wind < Config mag = interpLinear(obj.altitudes, obj.magnitude, z, true); az = interpLinear(obj.altitudes, obj.azimuth, z, true); el = interpLinear(obj.altitudes, obj.elevation, z, true); - + uw = round( - mag * cos(az) * cos(el), 6); vw = round( - mag * sin(az) * cos(el), 6); ww = round( - mag * (-sin(el)), 6); end end - - function obj = updateAll(obj) - obj = obj.updateElevation(); - - obj.magnitude = obj.updateDistribution(obj.magnitudeDistribution, ... - obj.magnitudeParameters); - - obj.azimuth = obj.updateDistribution(obj.azimuthDistribution, ... - obj.azimuthParameters); - - obj.elevation = obj.updateDistribution(obj.elevationDistribution, ... - obj.elevationParameters); - end end methods(Access = private) function vec = updateDistribution(obj, dist, parameters) - s = length(obj.altitudes); - vec = nan(1,s); + s = length(obj.ALTITUDES); + vec = []; + + dist = string(dist); + lDist = length(dist); + lPara = width(parameters); + + if lDist == 0, dist = "u"; lDist = 1; end + if lPara == 0, parameters = [0; 0]; lPara = 1; end + + if lDist == 1, dist = repmat(dist, 1, s); lDist = s; end + if lPara == 1, parameters = repmat(parameters, 1, s); lPara = s; end + + if lDist ~= s, return; end + if lPara ~= s, return; end + isUniform = strcmp(dist, "u"); uniformDist = @(val1, val2) rand(1)*(val2 - val1) + val1; gaussianDist = @(mean, sigma) normrnd(mean, sigma, 1); + vec = nan(1,s); for i = 1:s if isUniform(i) vec(i) = uniformDist(parameters(1,i), parameters(2,i)); @@ -91,15 +177,5 @@ classdef Wind < Config end end end - - function obj = updateElevation(obj) - if any(size(obj.elevationDistribution) ~= size(obj.azimuthDistribution)) - obj.elevationDistribution = repmat("u", size(obj.azimuthDistribution)); - end - - if isempty(obj.elevationParameters) && ~isempty(obj.azimuthParameters) - obj.elevationParameters = zeros(size(obj.azimuthParameters)); - end - end end -end +end \ No newline at end of file -- GitLab