diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 04a87756fbfae525f9000a5f62ea689c6097c6a6..6a0d01885f1c96343c137ae2d994535e1c5f9c53 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,3 @@ -# # # Copyright (c) 2023 Skyward Experimental Rocketry # # # Authors: Alberto Nidasio # # # # # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -27,49 +26,59 @@ # # Stage test -# simulator: -# stage: test -# tags: -# - matlab -# script: -# - cd . -# # - if (Test-Path ..\dissilematcom) { Remove-Item -Path ..\dissilematcom -Recurse -Force } -# # - git clone git@git.skywarder.eu:afd/msa/dissilematcom.git ../dissilematcom -# # - cd unitTests/tests -# # - matlab -batch "assertSuccess(runtests('simulatorUnitTests'))" +simulator: + stage: test + tags: + - matlab + script: + - cd . + - if (Test-Path ..\dissilematcom) { Remove-Item -Path ..\dissilematcom -Recurse -Force } + - git clone git@git.skywarder.eu:afd/msa/dissilematcom.git ../dissilematcom + - cd unitTests/tests + - matlab -batch "assertSuccess(runtests('TestSimulator'))" + # apogeeAnalysis: # stage: test # tags: # - matlab # script: -# - cd . -# # - cd unitTests/tests -# # - matlab -batch "assertSuccess(runtests('apogeeUnitTests'))" +# - cd . +# - cd unitTests/tests +# - matlab -batch "assertSuccess(runtests('apogeeUnitTests'))" # commonFuncitons: # stage: test # tags: # - matlab # script: -# - cd . -# # - cd unitTests/tests -# # - matlab -batch "assertSuccess(runtests('cmnFnctnUnitTests'))" +# - cd . +# - cd unitTests/tests +# - matlab -batch "assertSuccess(runtests('cmnFnctnUnitTests'))" # optimizator: # stage: test # tags: # - matlab # script: -# - cd . -# # - cd unitTests/tests -# # - matlab -batch "assertSuccess(runtests('optUnitTests'))" +# - cd . +# - cd unitTests/tests +# - matlab -batch "assertSuccess(runtests('optUnitTests'))" # sensitivity: # stage: test # tags: # - matlab # script: +# - cd . +# - cd unitTests/tests +# - matlab -batch "assertSuccess(runtests('sensitivityUnitTests'))" + +# allTests: +# stage: test +# tags: +# - matlab +# script: # - cd . -# # - cd unitTests/tests -# # - matlab -batch "assertSuccess(runtests('sensitivityUnitTests'))" +# - cd unitTests/tests +# - matlab -batch "assertSuccess(runtests)" \ No newline at end of file diff --git a/apogeeAnalysis/apogeeAnalysisConfig.m b/apogeeAnalysis/apogeeAnalysisConfig.m index 12d8efe927fc55bfc2bf9c8ded3109d61ec118e4..cf5fae029e336e38b63fa030fb4c4692c4548bfb 100644 --- a/apogeeAnalysis/apogeeAnalysisConfig.m +++ b/apogeeAnalysis/apogeeAnalysisConfig.m @@ -26,17 +26,18 @@ selection.motorName = {'HRE_ARM_EuRoC_2024'}; selection.transient = 1; %% PLOTS OPTIONS -plots.targetApogee = 3000; % [m] target apogee -plots.maxAcceleration = 15; % [g] imposed limit acceleration -plots.minVexit = 20; % [m/s] imposed limit on launchpad exit velocity +options.unitTest = false; % [-] true to disable prints and plots +options.targetApogee = 3000; % [m] target apogee +options.maxAcceleration = 15; % [g] imposed limit acceleration +options.minVexit = 20; % [m/s] imposed limit on launchpad exit velocity % Acceleration plot % set to false if you don't want the acceleration plot -plots.accelerationPlot = true; +options.accelerationPlot = true; % Launchpad exit velocity % set to false if you don't want the launchpad exit velocity plot -plots.launchpadVelPlot = true; +options.launchpadVelPlot = true; %% UNCERTAINTIES % Total impulse uncertaintie diff --git a/apogeeAnalysis/mainApogeeAnalysis.m b/apogeeAnalysis/mainApogeeAnalysis.m index 8fba160540d416378816865940e8c33984cdfbda..3227df2887fc8a88439a1bd3dab330d0decfe72a 100644 --- a/apogeeAnalysis/mainApogeeAnalysis.m +++ b/apogeeAnalysis/mainApogeeAnalysis.m @@ -1,12 +1,13 @@ -function [standardResults, engineCutResults] = mainApogeeAnalysis(rocket, settings, analysis, plots) +function [standardResults, engineCutResults] = mainApogeeAnalysis(rocket, settings, analysis, options) arguments rocket = [] % Rocket = Rocket.empty settings Settings = Settings.empty analysis.isStandard = [] analysis.isEngineCut = [] - plots.accelerationPlot = [] - plots.launchpadVelPlot = [] + options.accelerationPlot = [] + options.launchpadVelPlot = [] + options.unitTest = [] end % % @@ -38,7 +39,7 @@ if isempty(rocket), rocket = Rocket(mission); end if isempty(settings), settings = Settings('ode', 'apogeeAnalysis'); end Settings.read(settings, analysis, 'analysis'); -Settings.read(settings, plots, 'plots'); +Settings.read(settings, options, 'options'); if ~settings.analysis.isStandard && ~settings.analysis.isEngineCut error('Select at least one between standardAnalysis and engineCutAnalysis'); @@ -131,28 +132,42 @@ standardResults = []; engineCutResults = []; if settings.analysis.isStandard - fprintf('Standard apogee analysis started:\n'); + if ~settings.options.unitTest + fprintf('Standard apogee analysis started:\n'); + end + standardResults = standardApogee(settings, rocket, mission, selectedMotors, environments, winds, airbrakes); - fprintf('Elapsed time for standard apogee analysis: %4.2f [s]\n', standardResults.compTime); + + if ~settings.options.unitTest + fprintf('Elapsed time for standard apogee analysis: %4.2f [s]\n', standardResults.compTime); + end end if settings.analysis.isEngineCut - fprintf('Engine cut apogee analysis started:\n'); + if ~settings.options.unitTest + fprintf('Engine cut apogee analysis started:\n'); + end + if settings.uncert.percEngineCut < settings.uncert.percDeltaTime error('The selected cut-off time is smaller than deltaTime') end + if settings.uncert.percEngineCut + settings.uncert.percDeltaTime > 1 error('The sum of percEngineCut and percDeltaTime mus be <= 1') end + engineCutResults = engineCutApogee(settings, rocket, mission, selectedMotors, environments, winds, airbrakes); - fprintf('Elapsed time for engine cut apogee analysis: %4.2f [s]\n', engineCutResults.compTime); + + if ~settings.options.unitTest + fprintf('Elapsed time for engine cut apogee analysis: %4.2f [s]\n', engineCutResults.compTime); + end end %% PLOTS -if settings.analysis.isStandard +if settings.analysis.isStandard && ~settings.options.unitTest plotApogeeAnalysis(true, settings, selectedMotors, standardResults); end -if settings.analysis.isEngineCut +if settings.analysis.isEngineCut && ~settings.options.unitTest plotApogeeAnalysis(false, settings, selectedMotors, engineCutResults); end \ No newline at end of file diff --git a/apogeeAnalysis/src/engineCutApogee.m b/apogeeAnalysis/src/engineCutApogee.m index 5efb982e1830629292e17cf22ab95442758544ef..0c0ad49b8fd0018a43a09212e2a20def14d50554 100644 --- a/apogeeAnalysis/src/engineCutApogee.m +++ b/apogeeAnalysis/src/engineCutApogee.m @@ -71,9 +71,9 @@ for i = 1:2 % highest and lowest apogee cases nIT = nIT + 1; % if not(isfield(settings, 'unitTest')) || settings.unitTest == false - fprintf(repmat('\b',1,numel(msg))); + if ~settings.options.unitTest, fprintf(repmat('\b',1,numel(msg))); end msg = strcat('Simulation progress:',num2str(floor(nIT/iTOT*100)),'%%'); - fprintf(strcat(msg, '\n')); + if ~settings.options.unitTest, fprintf(strcat(msg, '\n')); end % end end end diff --git a/apogeeAnalysis/src/plotApogeeAnalysis.m b/apogeeAnalysis/src/plotApogeeAnalysis.m index be61a38653337b1dfcdb6ae54867f8432d9e1669..b65b405a424535afc3120db7f07eb1e64d24d69f 100644 --- a/apogeeAnalysis/src/plotApogeeAnalysis.m +++ b/apogeeAnalysis/src/plotApogeeAnalysis.m @@ -28,13 +28,13 @@ if isStdAnalysis xGrid = result.deltaStructuralMass; xLegend = 'Variation in structural mass ($kg$)'; figTitles = ["HIGHEST APOGEE CASE", "LOWEST APOGEE CASE"]; - nSubPlots = 2 + settings.plots.accelerationPlot + settings.plots.launchpadVelPlot; + nSubPlots = 2 + settings.options.accelerationPlot + settings.options.launchpadVelPlot; - if settings.plots.launchpadVelPlot + if settings.options.launchpadVelPlot maxAcc = result.maxAcc; end - if settings.plots.accelerationPlot + if settings.options.accelerationPlot vExit = result.vExit; end margin = 0.25; @@ -57,13 +57,13 @@ colorMap = turbo(nMotors+1); % plot highest/lowest apogee case for i = 1:2 - if i == 1 && min(min(apogee(:,:,i))) > settings.plots.targetApogee %% UPWIND - string = strcat("In the case the apogee is maximized, for each motor the final apogee is over ", num2str(settings.plots.targetApogee), "m."); + if i == 1 && min(min(apogee(:,:,i))) > settings.options.targetApogee %% UPWIND + string = strcat("In the case the apogee is maximized, for each motor the final apogee is over ", num2str(settings.options.targetApogee), "m."); string = strcat(string, " Decrease the minimum Itot in configApogee"); warning(string); end - if i == 2 && max(max(apogee(:,:,i))) < settings.plots.targetApogee %% DOWNWIND - string = strcat("In the case the apogee is minimized, for each motor the final apogee is above ", num2str(settings.plots.targetApogee), "m."); + if i == 2 && max(max(apogee(:,:,i))) < settings.options.targetApogee %% DOWNWIND + string = strcat("In the case the apogee is minimized, for each motor the final apogee is above ", num2str(settings.options.targetApogee), "m."); string = strcat(string, " Increase the maximum Itot in configApogee"); warning(string); end @@ -75,12 +75,12 @@ for i = 1:2 % ref plot quantities minApo = min(min(apogee(:,:,i))); maxApo = max(max(apogee(:,:,i))); - delta = [settings.plots.targetApogee - minApo; maxApo - settings.plots.targetApogee]; + delta = [settings.options.targetApogee - minApo; maxApo - settings.options.targetApogee]; delta(2) = delta(2)*(delta(2) > 0) + 100*(delta(2) <= 0); - yMax = settings.plots.targetApogee + delta(2) + 10; + yMax = settings.options.targetApogee + delta(2) + 10; yMin = minApo - 10; - if isStdAnalysis && (settings.plots.accelerationPlot || settings.plots.launchpadVelPlot) + if isStdAnalysis && (settings.options.accelerationPlot || settings.options.launchpadVelPlot) plotApogee = subplot(1, nSubPlots, 1:2); else plotApogee = fig.CurrentAxes; @@ -98,7 +98,7 @@ for i = 1:2 end leg = legend(labels, 'Interpreter', 'latex', 'Location', 'Best'); - yline(settings.plots.targetApogee,':', 'Color', [0.85 0 0], 'Linewidth', 2.5, ... + yline(settings.options.targetApogee,':', 'Color', [0.85 0 0], 'Linewidth', 2.5, ... 'Label', {'Target', 'Apogee'}, 'LabelHorizontalAlignment','left',... 'LabelVerticalAlignment', 'middle', 'Interpreter', 'latex'); % target apogee line @@ -124,7 +124,7 @@ for i = 1:2 end else % green rectangle over the target line - rectangle('Position', [xGridMin settings.plots.targetApogee (xGridMax-xGridMin) delta(2)], ... + rectangle('Position', [xGridMin settings.options.targetApogee (xGridMax-xGridMin) delta(2)], ... 'FaceColor', [0 1 0 0.1], 'Linestyle', 'none', 'FaceAlpha', 0.3); end @@ -144,7 +144,7 @@ for i = 1:2 if isStdAnalysis % Max acceleration plot - if settings.plots.accelerationPlot + if settings.options.accelerationPlot spA = subplot(1, nSubPlots, 3); hold on, grid on; @@ -163,7 +163,7 @@ for i = 1:2 spA.YLabel.String = '$max~|a|$ ($g$)'; spA.TickLabelInterpreter = 'latex'; % legend(labels, 'Interpreter', 'latex', 'Location', 'Best') - yline(settings.plots.maxAcceleration,':', 'Color', [0.85 0 0], 'Linewidth', 2.5, ... + yline(settings.options.maxAcceleration,':', 'Color', [0.85 0 0], 'Linewidth', 2.5, ... 'Label', {'Limit $max|a|$'}, 'LabelHorizontalAlignment','left',... 'LabelVerticalAlignment', 'bottom', 'Interpreter', 'latex'); % target apogee line xline(0,':', 'Interpreter', 'latex', ... @@ -172,8 +172,8 @@ for i = 1:2 end % Launchpad exit velocity plot - if settings.plots.launchpadVelPlot - spV = subplot(1, nSubPlots, 3 + settings.plots.accelerationPlot); + if settings.options.launchpadVelPlot + spV = subplot(1, nSubPlots, 3 + settings.options.accelerationPlot); hold on, grid on; % sorting for a better plot visualization @@ -184,7 +184,7 @@ for i = 1:2 plot(xGrid,vExit(:,k,i),'o-','color',colorMap(iCol(k),:),'LineWidth',1) end - yline(settings.plots.minVexit,':', 'Color', [0.85 0 0], 'Linewidth', 2.5, ... + yline(settings.options.minVexit,':', 'Color', [0.85 0 0], 'Linewidth', 2.5, ... 'Label', {'Minimum', 'Exit Velocity'}, 'LabelHorizontalAlignment','left',... 'LabelVerticalAlignment', 'top', 'Interpreter', 'latex'); % target apogee line xline(0,':', 'Interpreter', 'latex', ... @@ -192,7 +192,7 @@ for i = 1:2 'Color', [0.1 0.1 0.1], 'LineWidth', 2.5); % reference mass line spV.XLabel.String = xLegend; spV.YLabel.String = 'Launchpad exit velocity ($m/s$)'; - spV.YLim(1) = min(settings.plots.minVexit, min(vExit, [], 'all')) - 2; + spV.YLim(1) = min(settings.options.minVexit, min(vExit, [], 'all')) - 2; spV.TickLabelInterpreter = 'latex'; end % sorting for a better plot visualization diff --git a/apogeeAnalysis/src/standardApogee.m b/apogeeAnalysis/src/standardApogee.m index 3ff5b551be43708285d5d0e80e8d3c44a9a74630..14264cf19d849c07e57502d8027e0e581c409072 100644 --- a/apogeeAnalysis/src/standardApogee.m +++ b/apogeeAnalysis/src/standardApogee.m @@ -69,9 +69,9 @@ for i = 1:2 % highest and lowest apogee cases end nIT = nIT + 1; % if not(isfield(settings, 'unitTest')) || settings.unitTest == false - fprintf(repmat('\b',1,numel(msg))); + if ~settings.options.unitTest, fprintf(repmat('\b',1,numel(msg))); end msg = strcat('Simulation progress:',num2str(floor(nIT/iTOT*100)),'%%'); - fprintf(strcat(msg, '\n')); + if ~settings.options.unitTest, fprintf(strcat(msg, '\n')); end % end end end diff --git a/common b/common index 615eeea4668b5936cde62ab86c88809a8913fad2..52e9a50b3b7a6c88a0681fb5d38636ccd5f1d0f9 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 615eeea4668b5936cde62ab86c88809a8913fad2 +Subproject commit 52e9a50b3b7a6c88a0681fb5d38636ccd5f1d0f9 diff --git a/sensitivityAnalysis/mainSensitivity.m b/sensitivityAnalysis/mainSensitivity.m index 56ac7b8a3304468c95c98759afba48d32ca87a90..2d91b129b8eace7c914d8558d459a98555a6333d 100644 --- a/sensitivityAnalysis/mainSensitivity.m +++ b/sensitivityAnalysis/mainSensitivity.m @@ -1,5 +1,5 @@ function [postProcess, parameters] = ... - mainSensitivity(rocket, wind, environment, settings, plots) + mainSensitivity(rocket, wind, environment, settings, plots, options) arguments rocket = [] % Rocket = Rocket.empty wind = [] % Wind = Wind.empty @@ -13,6 +13,9 @@ arguments plots.offlineMap = []; + options.n = []; + options.type = []; + options.unitTest = []; end % mainSensitivity - main script for the sensitivity analysis. % @@ -51,6 +54,7 @@ if isempty(wind), wind = Wind(mission); end if isempty(settings), settings = Settings('ode', 'sensitivity'); end Settings.read(settings, plots, 'sensitivity', 'plots'); +Settings.read(settings, options, 'sensitivity'); parameters = initParameter(settings.sensitivity.parameters, rocket, environment, settings); gcp('nocreate'); % If pool exists, do not create new one. @@ -80,6 +84,11 @@ settings.simulator.parafoil = settings.sensitivity.parafoil; settings.simulator.stability = false; settings.simulator.launchMode = false; +if settings.sensitivity.unitTest + settings.sensitivity.plots.enabled = false; + settings.simulator.launchMode = false; +end + switch settings.sensitivity.type case 2 settings.simulator.ballistic = true; @@ -141,7 +150,9 @@ end postTime = toc; -fprintf('----COMPUTATION COMPLETE------\nComputational effort: %5.3f [s]\nPostprocess effort: %5.3f [s]\n', compTime, postTime); +if ~settings.sensitivity.unitTest + fprintf('----COMPUTATION COMPLETE------\nComputational effort: %5.3f [s]\nPostprocess effort: %5.3f [s]\n', compTime, postTime); +end postProcess = struct(); postProcess.ascent = postpAsc; diff --git a/sensitivityAnalysis/sensitivityConfig.m b/sensitivityAnalysis/sensitivityConfig.m index 7653b39f4939cadaad4678a8d377226a639ab065..f3a559a0ec4701b536fc90c628992fd8e8988e75 100644 --- a/sensitivityAnalysis/sensitivityConfig.m +++ b/sensitivityAnalysis/sensitivityConfig.m @@ -13,6 +13,7 @@ % SPDX-License-Identifier: GPL-3.0-or-later %% SIMULATION PARAMETERS +sensitivity.unitTest = false; sensitivity.n = 100; % Number of cases sensitivity.type = 4; % Simulation type: diff --git a/sensitivityAnalysis/src/postprocess/postprocessAscent.m b/sensitivityAnalysis/src/postprocess/postprocessAscent.m index 53eade5f05ff64acf8361e8ff1d8c6784c1ff248..b059d9dd41c9f6611479b4603887b8115c258e03 100644 --- a/sensitivityAnalysis/src/postprocess/postprocessAscent.m +++ b/sensitivityAnalysis/src/postprocess/postprocessAscent.m @@ -155,7 +155,11 @@ else end %% postprocessing the simulations -pwPost = PoolWaitbar(N, strcat('Postprocessing', {' '}, num2str(N), ' ASCENT simulations...')); +barEnabled = ~settings.sensitivity.unitTest; + +if barEnabled + pwPost = PoolWaitbar(N, strcat('Postprocessing', {' '}, num2str(N), ' ASCENT simulations...')); +end for i = 1:N sim = ascent(i); @@ -269,7 +273,9 @@ for i = 1:N end end - pwPost.increment(); + if barEnabled + pwPost.increment(); + end end %% Saving data diff --git a/sensitivityAnalysis/src/postprocess/postprocessDescentBall.m b/sensitivityAnalysis/src/postprocess/postprocessDescentBall.m index fb5a4900087a167597b5078889cc4ca3d103168d..92725b7e8f1470f69f34aceefd7fd139f5845505 100644 --- a/sensitivityAnalysis/src/postprocess/postprocessDescentBall.m +++ b/sensitivityAnalysis/src/postprocess/postprocessDescentBall.m @@ -78,7 +78,11 @@ velFun = @(dat) [dat(4); dat(5); -dat(6); sqrt(dat(4)^2 + dat(5)^2) + dat(6)^2]; descVelZFun = @(dat) [min(dat); max(dat); mean(dat)]; %% postprocessing the simulations -pwPost = PoolWaitbar(N, strcat('Postprocessing', {' '}, num2str(N), ' BALLISTIC simulations...')); +barEnabled = ~settings.sensitivity.unitTest; + +if barEnabled + pwPost = PoolWaitbar(N, strcat('Postprocessing', {' '}, num2str(N), ' BALLISTIC simulations...')); +end for i = 1:N sim = descent(i); @@ -111,7 +115,9 @@ for i = 1:N varPar(:, i) = aux; end - pwPost.increment(); + if barEnabled + pwPost.increment(); + end end %% Saving data diff --git a/sensitivityAnalysis/src/postprocess/postprocessDescentPara.m b/sensitivityAnalysis/src/postprocess/postprocessDescentPara.m index b9d1b17a043beeddf7c021de3488f5b73a9ffb91..385a717700e2472f77d1597a484d4b98913f52cc 100644 --- a/sensitivityAnalysis/src/postprocess/postprocessDescentPara.m +++ b/sensitivityAnalysis/src/postprocess/postprocessDescentPara.m @@ -187,7 +187,11 @@ else end %% postprocessing the simulations -pwPost = PoolWaitbar(N, strcat('Postprocessing', {' '}, num2str(N), ' PARA simulations...')); +barEnabled = ~settings.sensitivity.unitTest; + +if barEnabled + pwPost = PoolWaitbar(N, strcat('Postprocessing', {' '}, num2str(N), ' PARA simulations...')); +end for i = 1:N desc = descent(:, :, i); @@ -274,7 +278,10 @@ for i = 1:N bendingTorqueMainOpening(j, i)=forceMainOpening(3); end end - pwPost.increment(); + + if barEnabled + pwPost.increment(); + end end %% Saving data diff --git a/sensitivityAnalysis/src/postprocess/postprocessLaunchMode.m b/sensitivityAnalysis/src/postprocess/postprocessLaunchMode.m index 1806e776946317c6d852cca71957fdb0144deea3..914796169415e21bf7fa262e214ee04c42d52056 100644 --- a/sensitivityAnalysis/src/postprocess/postprocessLaunchMode.m +++ b/sensitivityAnalysis/src/postprocess/postprocessLaunchMode.m @@ -10,9 +10,12 @@ function postp = postprocessLaunchMode(ascent, descentPara, descentBall, setting pointFun = @(dat) [dat(1); dat(2); -dat(3); sqrt(dat(1)^2 + dat(2)^2)]; - %% postprocessing the simulations - pwPost = PoolWaitbar(N, strcat('Postprocessing', {' '}, num2str(N), ' PARA simulations...')); - + %% postprocessing the simulationsbarEnabled = ~settings.sensitivity.unitTest; + + if barEnabled + pwPost = PoolWaitbar(N, strcat('Postprocessing', {' '}, num2str(N), ' PARA simulations...')); + end + for i = 1:N desc = descentPara(:, :, i); ball = descentBall(i); @@ -25,8 +28,10 @@ function postp = postprocessLaunchMode(ascent, descentPara, descentBall, setting mainLandingPoint(:, i) = pointFun(main.state.Y(1:3, end)); ballLandingPoint(:, i) = pointFun(ball.state.Y(1:3, end)); apogee(i) = -asc.state.Y(3, end); - - increment(pwPost); + + if barEnabled + increment(pwPost); + end end %% Saving data diff --git a/sensitivityAnalysis/src/postprocess/postprocessStability.m b/sensitivityAnalysis/src/postprocess/postprocessStability.m index a6122238946d42c78adebd1e7f62358ccc44c9f6..34187d8a12145f630347279c08d58bb352e4ac4e 100644 --- a/sensitivityAnalysis/src/postprocess/postprocessStability.m +++ b/sensitivityAnalysis/src/postprocess/postprocessStability.m @@ -62,7 +62,11 @@ windAz = zeros(1, N); alphaTot = zeros(1, N); %% postprocessing the simulations -pwPost = PoolWaitbar(N, strcat('Postprocessing', {' '}, num2str(N), ' STABILITY simulations...')); +barEnabled = ~settings.sensitivity.unitTest; + +if barEnabled + pwPost = PoolWaitbar(N, strcat('Postprocessing', {' '}, num2str(N), ' STABILITY simulations...')); +end for i = 1:N sim = stability(i); @@ -90,7 +94,9 @@ for i = 1:N varPar(:, i) = aux; end - pwPost.increment(); + if barEnabled + pwPost.increment(); + end end %% Saving data diff --git a/sensitivityAnalysis/src/sensitivityStochRun.m b/sensitivityAnalysis/src/sensitivityStochRun.m index b8921df049fc11386ebaa28c61c26c3757974998..c24b63c39716ce42c0e54153edbae136ebdfe779 100644 --- a/sensitivityAnalysis/src/sensitivityStochRun.m +++ b/sensitivityAnalysis/src/sensitivityStochRun.m @@ -78,7 +78,13 @@ descentBall = struct.empty(); stability = struct.empty(); %% EXECUTING SIMULATIONS -waitBar = PoolWaitbar(n, strcat('Computing', {' '}, num2str(n), ' simulations...')); +barEnabled = ~settings.sensitivity.unitTest; + +if barEnabled + waitBar = PoolWaitbar(n, strcat('Computing', {' '}, num2str(n), ' simulations...')); +else + waitBar = PoolWaitbar.empty(); +end if ascentFlag ascent = wrapper.dummy; @@ -143,6 +149,8 @@ parfor i = 1:n end end - waitBar.increment(); %#ok<PFBNS> + if barEnabled + waitBar.increment(); %#ok<PFBNS> + end end end \ No newline at end of file diff --git a/simulator/mainSimulator.m b/simulator/mainSimulator.m index 5a14012e66984dad38c24bb25730d63e960fc6df..fec14574cc185be8b2965778181290104c9f1f14 100644 --- a/simulator/mainSimulator.m +++ b/simulator/mainSimulator.m @@ -13,6 +13,7 @@ arguments options.landingMap logical = []; % True to run geoplots options.satellite3D logical = []; % True to plot trajectory on 3D map options.SMonly logical = []; % True to plot only SM, useful during design + options.unitTest logical = []; % True to disable all plots and prints end % MAIN SIMULATOR - Runs the simulation that has been chosen in config files % @@ -62,6 +63,12 @@ end % Needed for compatibility with sensitivity settings.simulator.parachute = ~settings.simulator.ballistic; +if settings.simulator.unitTest + settings.simulator.prints = false; + settings.simulator.plots = false; + settings.simulator.SMonly = false; +end + %% DATA PREPARATION % Pre-allocating wrapper Y0 = zeros(1, 14); Y0(10) = 1; @@ -74,15 +81,24 @@ wrapper = DataWrapper(dataDummy, 1000, 1); tStart = tic; -fprintf('- Standard Ascent Simulation Started...\n'); +if ~settings.simulator.unitTest + fprintf('- Standard Ascent Simulation Started...\n'); +end + [solution, ascent] = stdAscent(rocket, environment, wind, settings, wrapper); wrapper.reset(); if settings.simulator.ballistic - fprintf('- Standard Ballistic Descent Started...\n\n'); + if ~settings.simulator.unitTest + fprintf('- Standard Ballistic Descent Started...\n\n'); + end + descent = stdDescentBal(solution, settings); else - fprintf('- Standard Descent Started...\n\n'); + if ~settings.simulator.unitTest + fprintf('- Standard Descent Started...\n\n'); + end + descent = stdDescent(solution, settings); end diff --git a/simulator/simulatorConfig.m b/simulator/simulatorConfig.m index bd5af2b6618bad17ca67f77e40eb1fadbd8c6e62..66d00f6f94e75a785944abdc047c678c8bdc31d8 100644 --- a/simulator/simulatorConfig.m +++ b/simulator/simulatorConfig.m @@ -16,6 +16,8 @@ simulator.ballistic = false; % True to run a ballistic (without parachut % NOTE: airbrakes flag is set in rocketConfig %% PLOTS +simulator.unitTest = false; % True to disable all plots and prints + simulator.prints = false; % True to print data after simulation simulator.plots = false; % True to plot data after simulation simulator.landingMap = true; % True to run geoplots diff --git a/stabilityAnalysis/mainStabilityAnalysis.m b/stabilityAnalysis/mainStabilityAnalysis.m index b4ae30af6a95f30fadbbf521c5563478ce473d63..b63fc8c81e12c12fc3a4bb9adec2f55f6bd8ce1e 100644 --- a/stabilityAnalysis/mainStabilityAnalysis.m +++ b/stabilityAnalysis/mainStabilityAnalysis.m @@ -14,6 +14,7 @@ arguments options.plotXCPlonATOT = []; options.plotQINDEX = []; options.plotCoeffs = []; + options.unitTest = []; end % mainStabilityAnalysis - Main script to compute the rocket stability at % launchpad exit given a set of wind intensity and @@ -47,11 +48,18 @@ if isempty(environment), environment = Environment(mission, rocket.motor); end if isempty(wind), wind = Wind(mission); end if isempty(settings), settings = Settings('stabilityAnalysis', 'ode'); end -% Settings.read(settings, options, 'stability'); +Settings.read(settings, options, 'stability'); settings.stability.dissile.alt = environment.z0; settings.stability.dissile.xcg = rocket.xcg(1); +%% FLAGS + +if options.unitTest + settings.stability.plots = false; + settings.stability.prints = false; +end + %% LAUNCHPAD DYNAMICS % states to compute the exit pad velocity T = (288.15 - 0.0065*environment.z0); % temperature @@ -94,7 +102,7 @@ stabilityData.XCPmat(indexNan) = nan; XCPlonATOT = squeeze(stabilityData.XCPmat(5, :, :)); % XCPlatATOT = squeeze(stabilityData.XCPmat(6, :, :)); -%% +flag = false; if settings.stability.prints || settings.stability.plots flag = true; if isscalar(settings.stability.windMag) @@ -125,7 +133,9 @@ if flag stabilityPrints(settings.stability, stabilityData, const, nameConst, refVec, nameVec, computeStabilityTime, vExit, a) end %% PLOTS -stabilityPlots(flag, settings.stability, stabilityData, const, nameConst, refVec, nameVec) +if settings.stability.plots + stabilityPlots(flag, settings.stability, stabilityData, const, nameConst, refVec, nameVec) +end %% SAVING if settings.stability.saveRes diff --git a/stabilityAnalysis/src/computeStability.m b/stabilityAnalysis/src/computeStability.m index 976090cd5e6d73017c7d1c569c8c9467f9b0b8e5..c452a896c01406c031b6be8d0fdb0032be632d03 100644 --- a/stabilityAnalysis/src/computeStability.m +++ b/stabilityAnalysis/src/computeStability.m @@ -102,7 +102,10 @@ windMesh = [row1; row2]; %% computation nCall = ceil(meshCol/nFC); -barStab = PoolWaitbar(nCall, strcat('Calculating...')); + +if ~stability.unitTest + barStab = PoolWaitbar(nCall, strcat('Calculating...')); +end for i = 1:nCall if i~=nCall @@ -185,7 +188,10 @@ for i = 1:nCall [XCPmat(:, index), qIndexMat(:, index), stabilityCoeffs(:, index)] = getXCP(coeff, iAlpha, iBeta, dissileInput, stability); end - increment(barStab) + + if ~stability.unitTest + increment(barStab) + end end %% reshape to increase readibility diff --git a/stabilityAnalysis/src/stabilityPlots.m b/stabilityAnalysis/src/stabilityPlots.m index 2b3be312d6141407cdc4cab64d9b930e8bd986a1..05f4a1d742a4d18c245cc5b4e45ec1ebb3ea6169 100644 --- a/stabilityAnalysis/src/stabilityPlots.m +++ b/stabilityAnalysis/src/stabilityPlots.m @@ -16,119 +16,117 @@ function [] = stabilityPlots(flag, settings, stabilityData, const, nameConst, re XCPlonATOT = squeeze(stabilityData.XCPmat(5, :, :)); %% PLOTS -if settings.plots - if flag - figure('Name','Stability margin'); - hold on; - % if (settings.vars.plotXCPlon), plot(refVec, XCPlon, '-o', 'DisplayName','XCPlon'); end - % if (settings.vars.plotXCPlat), plot(refVec, XCPlat, '-o', 'DisplayName','XCPlat'); end - % if (settings.vars.plotXCPtotSTD), plot(refVec, XCPtotSTD, '-o', 'DisplayName', 'XCPtot - STD'); end - % if (settings.vars.plotXCPtotMOD), plot(refVec, XCPtotMOD, '-o', 'DisplayName', 'XCPtot - MOD'); end - if (settings.plotXCPlonATOT), plot(refVec, XCPlonATOT, '-o', 'DisplayName', 'XCPlon - ATOT'); end - % if (settings.vars.plotXCPlatATOT), plot(refVec, XCPlatATOT, '-o', 'DisplayName', 'XCPlat - ATOT'); end +if flag + figure('Name','Stability margin'); + hold on; + % if (settings.vars.plotXCPlon), plot(refVec, XCPlon, '-o', 'DisplayName','XCPlon'); end + % if (settings.vars.plotXCPlat), plot(refVec, XCPlat, '-o', 'DisplayName','XCPlat'); end + % if (settings.vars.plotXCPtotSTD), plot(refVec, XCPtotSTD, '-o', 'DisplayName', 'XCPtot - STD'); end + % if (settings.vars.plotXCPtotMOD), plot(refVec, XCPtotMOD, '-o', 'DisplayName', 'XCPtot - MOD'); end + if (settings.plotXCPlonATOT), plot(refVec, XCPlonATOT, '-o', 'DisplayName', 'XCPlon - ATOT'); end + % if (settings.vars.plotXCPlatATOT), plot(refVec, XCPlatATOT, '-o', 'DisplayName', 'XCPlat - ATOT'); end + + grid on; + xlabel(strcat(nameVec{1},{' '}, nameVec{2})); + ylabel('SM (-)'); + title('STABILITY MARGIN'); + subtitle(strcat(nameConst{1},':',{' '},num2str(const), {' '}, nameConst{2})); + legend; + if settings.plotQINDEX + figure('Name','Quality indices (angular)') + names = {'Angle between Faero and Maero', 'Angle between Fyz and Myz', 'Angle between Fyz and vRyz'}; + hold on; + for i = 1:3 + plot(refVec, stabilityData.qIndexMat(i, :).*180/pi,'-o','DisplayName',names{i}); + end grid on; xlabel(strcat(nameVec{1},{' '}, nameVec{2})); - ylabel('SM (-)'); - title('STABILITY MARGIN'); + ylabel('Angle (deg)'); + title('Angular indices'); subtitle(strcat(nameConst{1},':',{' '},num2str(const), {' '}, nameConst{2})); legend; - if settings.plotQINDEX - figure('Name','Quality indices (angular)') - names = {'Angle between Faero and Maero', 'Angle between Fyz and Myz', 'Angle between Fyz and vRyz'}; - hold on; - for i = 1:3 - plot(refVec, stabilityData.qIndexMat(i, :).*180/pi,'-o','DisplayName',names{i}); - end - grid on; - xlabel(strcat(nameVec{1},{' '}, nameVec{2})); - ylabel('Angle (deg)'); - title('Angular indices'); - subtitle(strcat(nameConst{1},':',{' '},num2str(const), {' '}, nameConst{2})); - legend; - - figure('Name','Tindex') - plot(refVec, stabilityData.qIndexMat(4, :),'-o', 'DisplayName','T - index'); - grid on; - xlabel(strcat(nameVec{1},{' '}, nameVec{2})); - ylabel('(-)'); - title('T - index') - subtitle(strcat(nameConst{1},':',{' '},num2str(const), {' '}, nameConst{2})); - legend; + figure('Name','Tindex') + plot(refVec, stabilityData.qIndexMat(4, :),'-o', 'DisplayName','T - index'); + grid on; + xlabel(strcat(nameVec{1},{' '}, nameVec{2})); + ylabel('(-)'); + title('T - index') + subtitle(strcat(nameConst{1},':',{' '},num2str(const), {' '}, nameConst{2})); + legend; - figure('Name','Quality index (force)') - plot(refVec, stabilityData.qIndexMat(5, :),'-o', 'DisplayName','Norm of Fpar'); - grid on; - xlabel(strcat(nameVec{1},{' '}, nameVec{2})); - ylabel('(-)'); - title('Force index'); - end + figure('Name','Quality index (force)') + plot(refVec, stabilityData.qIndexMat(5, :),'-o', 'DisplayName','Norm of Fpar'); + grid on; + xlabel(strcat(nameVec{1},{' '}, nameVec{2})); + ylabel('(-)'); + title('Force index'); + end - if settings.plotCoeffs - names = {'Cl', 'Cm', 'Cn', 'CA', 'CY', 'CN'}; - ind = [9 3 7 10 8 4]; + if settings.plotCoeffs + names = {'Cl', 'Cm', 'Cn', 'CA', 'CY', 'CN'}; + ind = [9 3 7 10 8 4]; - figure('Name','Coefficients'); - hold on; - for j = 1:6 - coeff = stabilityData.stabilityCoeffs(ind(j), :); - coeff = coeff./max(abs(coeff)); - if j <=3 - mk = '-o'; - else - mk = '-^'; - end - plot(refVec, coeff, mk , 'DisplayName', names{j}); + figure('Name','Coefficients'); + hold on; + for j = 1:6 + coeff = stabilityData.stabilityCoeffs(ind(j), :); + coeff = coeff./max(abs(coeff)); + if j <=3 + mk = '-o'; + else + mk = '-^'; end - - grid on - legend - ylabel('(-)'); - xlabel(strcat(nameVec{1},{' '}, nameVec{2})); - title('Normalized Coefficients'); + plot(refVec, coeff, mk , 'DisplayName', names{j}); end + + grid on + legend + ylabel('(-)'); + xlabel(strcat(nameVec{1},{' '}, nameVec{2})); + title('Normalized Coefficients'); + end +else + if settings.plotXCPlonATOT + tit = strcat('Stability margin (XCPlonATOT)'); + figure('Name',tit); + SM = XCPlonATOT; + surf(settings.windMag, settings.windAz*180/pi,SM','FaceColor','Interp', 'EdgeColor','none'); + colormap jet; + cb = colorbar; + cb.Label.String = 'SM (-)'; + xlabel('Wind Magnitude (m/s)'); + ylabel('Wind Azimuth (deg)'); + zlabel('SM (-)'); + title('XCP tot'); else - if settings.plotXCPlonATOT - tit = strcat('Stability margin (XCPlonATOT)'); + warning('plotXCPlonATOT set to false') + end + + if settings.plotQINDEX + names = {'Angle between Faero and Maero', 'Angle between Fyz and Myz', 'Angle between Fyz and vRyz', 'T - index', 'Norm of Fpar'}; + for i = 1:5 + tit = strcat('Quality index num:', num2str(i)); figure('Name',tit); - SM = XCPlonATOT; - surf(settings.windMag, settings.windAz*180/pi,SM','FaceColor','Interp', 'EdgeColor','none'); + qInd = squeeze(stabilityData.qIndexMat(i, :, :)); + if i <= 3 + qInd = qInd.*180/pi; + end + surf(settings.windMag, settings.windAz*180/pi, qInd', 'FaceColor', 'Interp'); colormap jet; cb = colorbar; - cb.Label.String = 'SM (-)'; xlabel('Wind Magnitude (m/s)'); ylabel('Wind Azimuth (deg)'); - zlabel('SM (-)'); - title('XCP tot'); - else - warning('plotXCPlonATOT set to false') - end - - if settings.plotQINDEX - names = {'Angle between Faero and Maero', 'Angle between Fyz and Myz', 'Angle between Fyz and vRyz', 'T - index', 'Norm of Fpar'}; - for i = 1:5 - tit = strcat('Quality index num:', num2str(i)); - figure('Name',tit); - qInd = squeeze(stabilityData.qIndexMat(i, :, :)); - if i <= 3 - qInd = qInd.*180/pi; - end - surf(settings.windMag, settings.windAz*180/pi, qInd', 'FaceColor', 'Interp'); - colormap jet; - cb = colorbar; - xlabel('Wind Magnitude (m/s)'); - ylabel('Wind Azimuth (deg)'); - - if i <= 4 - cb.Label.String = 'qIndex (deg)'; - zlabel('qIndex (deg)'); - else - cb.Label.String = 'qIndex (-)'; - zlabel('qIndex (-)'); - end - title(names{i}) + + if i <= 4 + cb.Label.String = 'qIndex (deg)'; + zlabel('qIndex (deg)'); + else + cb.Label.String = 'qIndex (-)'; + zlabel('qIndex (-)'); end + title(names{i}) end end end diff --git a/stabilityAnalysis/stabilityAnalysisConfig.m b/stabilityAnalysis/stabilityAnalysisConfig.m index 8eb9c27698330a729f9bee561bc2136f7f7139d3..9e192e7c048854a2f0f9e913a6ecc73c23ad66b9 100644 --- a/stabilityAnalysis/stabilityAnalysisConfig.m +++ b/stabilityAnalysis/stabilityAnalysisConfig.m @@ -10,6 +10,8 @@ % % SPDX-License-Identifier: GPL-3.0-or-later +stability.unitTest = false; + %% SIMULATION SETUP stability.windAz = (0:359)*pi/180; stability.windMag = 9; diff --git a/unitTests/configUnitTest.m b/unitTests/configUnitTest.m deleted file mode 100644 index 4303d2db19986306bfbc1025ee04267fed672743..0000000000000000000000000000000000000000 --- a/unitTests/configUnitTest.m +++ /dev/null @@ -1,21 +0,0 @@ -% config unit-test - -% choose the mission -mission = Mission(true); - -%% UNIT TESTS TO RUN -% choose which folders to test -opt.testSimulator = true; -% opt.testCommonFunction = true; -opt.testApogeeAnalysis = true; -opt.testOptimization = false; -opt.testSensitivity = false; - - -%% UNIT TEST TO CREATE -% choose which folders to create data for -opt.createTestSimulator = true; -% opt.createTestCommonFunction = true; -opt.createTestApogeeAnalysis = true; -opt.createTestOptimization = false; -opt.createTestSensitivity = false; diff --git a/unitTests/data/testSimulator/HRE/referenceState_HRE.mat b/unitTests/data/testSimulator/HRE/referenceState_HRE.mat index de39f3f056767f120f0f111e925821b6aef54c73..df6749b4bb37585ea3c3021724cb5c40b927fbd6 100644 --- a/unitTests/data/testSimulator/HRE/referenceState_HRE.mat +++ b/unitTests/data/testSimulator/HRE/referenceState_HRE.mat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94213b354af235446bfe76f6d7914d2c8905f3d6cec4bfb2f543322d4b5736e1 -size 81189519 +oid sha256:9ff07ce27d01bf23c29c98a7dd1c758b21bf3bc65a62dae0004cee6e382bee55 +size 80968214 diff --git a/unitTests/data/testSimulator/ballistic/referenceState_ballistic.mat b/unitTests/data/testSimulator/ballistic/referenceState_ballistic.mat index 2ec9624f4f3444ad203801955e6f5af6b7c02750..eeab8cc558f787ecc588cb40bf628a27de3d8d36 100644 --- a/unitTests/data/testSimulator/ballistic/referenceState_ballistic.mat +++ b/unitTests/data/testSimulator/ballistic/referenceState_ballistic.mat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fa6a60fb79d87e78807a383d3f631ae33962d3aac96d79b324f9141f1651d093 -size 80572522 +oid sha256:3e0cb11e661873efb0afedd3f0a1a9b4db1e6a2b231cac731e7dc0c4858d329f +size 80257863 diff --git a/unitTests/data/testSimulator/engineCut/referenceState_engineCut.mat b/unitTests/data/testSimulator/engineCut/referenceState_engineCut.mat index fbc21a9e670de87964b7e7a832a3aeda1e3dff0a..79548f48bc854a264b69fc43034dab65c1358d6f 100644 --- a/unitTests/data/testSimulator/engineCut/referenceState_engineCut.mat +++ b/unitTests/data/testSimulator/engineCut/referenceState_engineCut.mat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b26f24f1967c13154953c43e1b703af995f113eb2c5f294a2a4129073b03b831 -size 81203214 +oid sha256:7351319f1601e60ed22da5672aa76cfa44705c5f61791110c0b96e3cb42dd029 +size 80821062 diff --git a/unitTests/data/testSimulator/multipleAB/referenceState_multipleAB.mat b/unitTests/data/testSimulator/multipleAB/referenceState_multipleAB.mat index 742bc0e34fcd336faf96da4847eb9ca3f6c5bf5e..109f8c24d61086ff50d1a1d69fe978e66d5aa0b9 100644 --- a/unitTests/data/testSimulator/multipleAB/referenceState_multipleAB.mat +++ b/unitTests/data/testSimulator/multipleAB/referenceState_multipleAB.mat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d6010f5e911e3bd2a99a941dce7daa7373d7856596c9b6e5dea203489865bd3 -size 81167424 +oid sha256:d70bf97397bd031aaca2318234955e01df09c79b5810217d88f8234138aea97e +size 80909109 diff --git a/unitTests/data/testSimulator/solid/referenceState_solid.mat b/unitTests/data/testSimulator/solid/referenceState_solid.mat index d01fcc829019f971d3b665d34f0d1ffebff629a1..d61250310e631f0f401fb9c25850ce0eb09f8ba9 100644 --- a/unitTests/data/testSimulator/solid/referenceState_solid.mat +++ b/unitTests/data/testSimulator/solid/referenceState_solid.mat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9752252923f523ca283d55092109d99a3ca7ce9bde96335988c49fd7c3d496a -size 81192294 +oid sha256:2b0c9958bc51b0a045785bc572f3948a7d79285979d520cc0916d5139b2552ed +size 80968216 diff --git a/unitTests/mainUnitTest.m b/unitTests/mainUnitTest.m index d8cbd73c7256f93ca06367cc8209855e0d320d25..d546408cf5501325bc7fca283a564526c35a77dc 100644 --- a/unitTests/mainUnitTest.m +++ b/unitTests/mainUnitTest.m @@ -1,41 +1,45 @@ -% main unit-test - +function [apoResults, optResults, sensResults, simResults] = mainUnitTest(options) +arguments + options.testApogeeAnalysis logical = []; + options.testOptimization logical = []; + options.testSensitivity logical = []; + options.testSimulator logical = []; +end +%% PATH currentPath = fileparts(mfilename('fullpath')); addpath(genpath(fullfile(currentPath, '..'))); -configUnitTest; +%% LOAD OPTIONS +settings = Settings('unitTest'); +Settings.read(settings, options, 'unitTest'); %% TESTS beginTest = tic; -% if opt.testCommonFunction -% test = TestCommonFunctions(); -% testcmnfnctResults = run(test); -% disp(testcmnfnctResults); -% end - -if opt.testApogeeAnalysis +if settings.unitTest.testApogeeAnalysis test = TestApogeeAnalysis(); apoResults = run(test); disp(apoResults); end -if opt.testOptimization - test = TestOptimization(); - optResults = run(test); - disp(optResults); -end +% if settings.unitTest.testOptimization +% test = TestOptimization(); +% optResults = run(test); +% disp(optResults); +% end -if opt.testSensitivity +if settings.unitTest.testSensitivity test = TestSensitivity(); sensResults = run(test); disp(sensResults); end -if opt.testSimulator - test = TestSimulator(); +if settings.unitTest.testSimulator + test = TestSimulator(); simResults = run(test); - disp(simResults); + disp(simResults); end -toc(beginTest) \ No newline at end of file +toc(beginTest) + +end \ No newline at end of file diff --git a/unitTests/saveTests.m b/unitTests/saveTests.m index c14e556f80fa49a6b28cc983c82111caaf0826ad..2b6aede16b236e16aa74041b7294407e51754bc7 100644 --- a/unitTests/saveTests.m +++ b/unitTests/saveTests.m @@ -1,55 +1,51 @@ -% save tests - +function saveTests(rocket, wind, environment, settings , options) +arguments + rocket = [] % Rocket = Rocket.empty + wind = [] % Wind = Wind.empty + environment = [] % Environment = Environment.empty + settings = [] % Settings = Settings.empty + options.saveTestApogeeAnalysis logical = []; + options.saveTestOptimization logical = []; + options.saveTestSensitivity logical = []; + options.saveTestSimulator cell = {}; +end +%% PATH currentPath = fileparts(mfilename('fullpath')); addpath(genpath(currentPath)); +totTime = tic; -configUnitTest; - +%% LOAD DATA / SETTINGS mission = Mission(true); - -totTime = tic; +if isempty(rocket), rocket = Rocket(mission); end +if isempty(environment), environment = Environment(mission, rocket.motor); end +if isempty(wind), wind = Wind(mission); end +if isempty(settings), settings = Settings('unitTest'); end +Settings.read(settings, options, 'unitTest'); %% CREATING SIMULATOR TESTS -if opt.createTestSimulator - verifiable = {'HRE', 'solid', 'multipleAB', 'engineCut', 'ballistic'}; - for k = 1:length(verifiable) - TestSimulator.saveTest(verifiable{k}, mission); +if ~isempty(settings.unitTest.saveTestSimulator) + for k = 1:length(settings.unitTest.saveTestSimulator) + TestSimulator.saveTest(settings.unitTest.saveTestSimulator{k}, rocket, wind, environment); end end - -% %% TEST COMMONFUNCTIONS -% if opt.createTestCommonFunction -% vars.mach = 0.05:0.05:1; -% vars.alpha = [-10 -7.5 -5 -2.5 -1 -0.5 -0.1 0 0.1 0.5 1 2.5 5 7.5 10]; -% vars.beta = [-2.5 -0.1 0 0.1 2.5]; -% vars.alt = (0:400:4000); -% vars.hprot = []; -% t = 1.3; -% alpha = 5; -% mach = 0.4; -% beta = 2; -% alt = 1145; -% c = 2; -% TestCommonFunctions.saveTest(mission, vars, t, alpha, mach, beta, alt, c); -% end - %% TEST APOGEE ANALYSIS -if opt.createTestApogeeAnalysis +if settings.unitTest.saveTestApogeeAnalysis TestApogeeAnalysis.saveTest(mission); end -% %% SENSITIVITY ANALYSIS -% if opt.createTestSensitivity -% TestSensitivity.saveTest(mission); -% end - -%% OPTIMIZATION -if opt.createTestOptimization - TestOptimization.saveTest(mission); +%% SENSITIVITY ANALYSIS +if settings.unitTest.saveTestSensitivity + TestSensitivity.saveTest(mission); end +% %% OPTIMIZATION +% if settings.unitTest.saveTestOptimization +% TestOptimization.saveTest(mission); +% end totTimeF = toc(totTime); fprintf('\n\n All unit tests created in: %2.2f seconds\n\n', totTimeF) - +end +% clear all +% clc diff --git a/unitTests/tests/TestApogeeAnalysis.m b/unitTests/tests/TestApogeeAnalysis.m index 3c7a9b977ae6395ae5b6d56df580d35724455f08..cc30caa312a9a47719aa248475a6cbc17eed0a50 100644 --- a/unitTests/tests/TestApogeeAnalysis.m +++ b/unitTests/tests/TestApogeeAnalysis.m @@ -1,4 +1,4 @@ -classdef TestApogeeAnalysis < UnitTest +classdef TestApogeeAnalysis < matlab.unittest.TestCase properties refStandardResults diff --git a/unitTests/tests/TestCommonFunctions.m b/unitTests/tests/TestCommonFunctions.m index 86cff7310799346134e9c23d21916b6a9694a1ea..a259a354380bf8efe042f8cf769d0c2ff5ba22cb 100644 --- a/unitTests/tests/TestCommonFunctions.m +++ b/unitTests/tests/TestCommonFunctions.m @@ -1,4 +1,4 @@ -classdef TestCommonFunctions < UnitTest +classdef TestCommonFunctions < matlab.unittest.TestCase % This class contains the common functions unit-test. % To run the test you have to create the istance of this class in the % mainUnitTests script. diff --git a/unitTests/tests/TestSensitivity.m b/unitTests/tests/TestSensitivity.m index 71d03dc71d696e35829ff65eccff830dd8e0ed4e..c6cd08f2b71f2f7d7c1dc4259c91caad7cff39f6 100644 --- a/unitTests/tests/TestSensitivity.m +++ b/unitTests/tests/TestSensitivity.m @@ -1,4 +1,4 @@ -classdef TestSensitivity < UnitTest +classdef TestSensitivity < matlab.unittest.TestCase % NON FUNZIONANTE, testCase.sensitivitySettings must be of type Settings or be convertible to Settings. diff --git a/unitTests/tests/TestSimulator.m b/unitTests/tests/TestSimulator.m index d630437d4fc0294fac6ec3a5afef8aecf5abb3da..3216246c0d52097cd67ceff9f27687f0ea7ad156 100644 --- a/unitTests/tests/TestSimulator.m +++ b/unitTests/tests/TestSimulator.m @@ -1,20 +1,20 @@ -classdef TestSimulator < UnitTest - - % TEST FUNZIONANTE, DA RISOLVERE PATH PER simulatorConfig.m in saveTest +classdef TestSimulator < matlab.unittest.TestCase properties - simulatorSettings + settings refSimulator + rocket + wind + environment end - properties (TestParameter) + properties (MethodSetupParameter) verifiable = {'multipleAB', 'ballistic', 'engineCut', 'solid', 'HRE'}; end - - methods - function createTest(testCase, verifiable) + + methods (TestMethodSetup) + function setup(testCase, verifiable) currentPath = fileparts(mfilename('fullpath')); - addpath(genpath(currentPath)); fileName = sprintf("referenceState_%s.mat", verifiable); filePath = fullfile(currentPath, '..', 'data', 'testSimulator', verifiable, fileName); @@ -28,81 +28,70 @@ classdef TestSimulator < UnitTest testCase.refSimulator.stateA = load(filePath).stateA; testCase.refSimulator.stateF = load(filePath).stateF; - testCase.simulatorSettings = load(filePath).simulatorSettings; + testCase.settings = load(filePath).settings; % Construct the file path dynamically based on the test parameter end end + methods (TestMethodTeardown) + function teardown(testCase) + mainSimPath = fullfile('..', '..', 'simulator'); + rmpath(genpath(mainSimPath)); + end + end + + methods (Test) + function mainSimulatorTest(testCase) + mainSimPath = fullfile('..', '..', 'simulator'); + addpath(genpath(mainSimPath)); + % Run main simulator + [postp.stateA, postp.stateF] = mainSimulator(testCase.rocket, testCase.wind, testCase.environment, testCase.settings); + + % Verify results + testCase.verifyEqual(postp, testCase.refSimulator); + end + end methods (Static) - function saveTest(verifiable, mission) + function saveTest(verifiable, rocket, wind, environment) Time = tic; + currentPath = fileparts(mfilename('fullpath')); disp('Started saving simulator tests') - currentPath = fileparts(mfilename('fullpath')); - addpath(genpath(currentPath)); - mainSimPath = fullfile(currentPath, '..', '..', 'simulator', 'simulatorConfig.m'); - mainOdePath = fullfile(currentPath, '..', '..', 'common', 'settings', 'odeConfig.m'); - - rocket = Rocket(mission); - environment = Environment(mission, rocket.motor); - wind = Wind(mission); - - simulatorSettings = Settings(mainSimPath, mainOdePath); - simulatorSettings.simulator.SMonly = 0; - if strcmp(verifiable, 'ballistic') - simulatorSettings.simulator.ballistic = 1; - simulatorSettings.simulator.parafoil = 0; + simPath = fullfile(fileparts(mfilename('fullpath')), '..', '..', 'simulator', 'simulatorConfig.m'); + settings = Settings('ode', simPath); + + if verifiable == "ballistic" + settings.simulator.ballistic = 1; + settings.simulator.parafoil = 0; + elseif verifiable == "multipleAB" + rocket.airbrakes.enabled = 1; + elseif verifiable == "engineCut" + rocket.motor.cutoffTime = 3; + elseif verifiable == "HRE" + rocket.motor = Motor(Mission("2024_Lyra_Portugal_October")); + % elseif verifiable == "solid" + % rocket.motor = Motor(Mission("2022_Pyxis_Portugal_October")); end % simulator - [stateA, stateF] = mainSimulator(rocket, wind, environment, simulatorSettings); - - % mainSimPath = fullfile('..', '..', 'simulator', 'simulatorConfig.m'); - % mainOdePath = fullfile('..', '..', 'common', 'settings', 'odeConfig.m'); - % simulatorSettings = Settings(mainSimPath, mainOdePath); - % simulatorSettings.simulator.SMonly = 0; - % if strcmp(verifiable, 'ballistic') - % simulatorSettings.simulator.ballistic = 1; - % simulatorSettings.simulator.parafoil = 0; - % end + [stateA, stateF] = mainSimulator(rocket, wind, environment, settings, 'unitTest', true); % Save final state fileName = sprintf("referenceState_%s.mat", verifiable); - folderPath = fullfile(currentPath,'..', 'data', 'testSimulator', verifiable); + folderPath = fullfile(currentPath, '..', 'data', 'testSimulator', verifiable); filePath = fullfile(folderPath, fileName); - if ~exist(folderPath, "dir") - mkdir(folderPath) - end - save(filePath,'stateA','stateF', 'simulatorSettings',... - 'mission', 'rocket', 'environment', 'wind'); + if ~exist(folderPath, "dir"), mkdir(folderPath); end - close all; + save(filePath,'stateA','stateF', 'settings',... + 'rocket', 'environment', 'wind'); Time = toc(Time); fprintf('\t %s test created in: %2.2f seconds\n',verifiable, Time) end end - - methods (Test) - function mainSimulatorTest(testCase, verifiable) - - testCase.createTest(verifiable); - - mainSimPath = fullfile('..', '..', 'simulator'); - addpath(genpath(mainSimPath)); - - % Run main simulator - [postp.stateA, postp.stateF] = mainSimulator(testCase.rocket, testCase.wind, testCase.environment, testCase.simulatorSettings); - - close all; - - % Verify results - testCase.verifyEqual(postp, testCase.refSimulator, 'AbsTol', testCase.absToll, 'RelTol', testCase.relToll); - end - end end diff --git a/unitTests/tests/UnitTest.m b/unitTests/tests/UnitTest.m deleted file mode 100644 index ec4039be254896e846d45c4b9a64bb559d81d3a2..0000000000000000000000000000000000000000 --- a/unitTests/tests/UnitTest.m +++ /dev/null @@ -1,22 +0,0 @@ -classdef (Abstract) UnitTest < matlab.unittest.TestCase - properties - mission Mission % [-] mission object - rocket Rocket % [-] rocket object - environment Environment % [-] environment component - wind Wind % [-] wind component - absToll % [-] absolute tolerance - relToll % [-] relative tolerance - end - - methods - function obj = UnitTest() - obj.mission = Mission(true); - obj.rocket = Rocket(obj.mission); - obj.environment = Environment(obj.mission, obj.rocket.motor); - obj.wind = Wind(obj.mission); - obj.absToll = 0.001; - obj.relToll = 0.001; - end - - end -end \ No newline at end of file diff --git a/unitTests/unitTestConfig.m b/unitTests/unitTestConfig.m new file mode 100644 index 0000000000000000000000000000000000000000..31da7208df18d02bbe9ee5d8cee602d1d89a80fc --- /dev/null +++ b/unitTests/unitTestConfig.m @@ -0,0 +1,15 @@ +% CONFIG - This script sets up rocket's parameters + +%% UNIT TESTS TO RUN +% choose which folders to test +unitTest.testSimulator = true; +unitTest.testApogeeAnalysis = false; +% unitTest.testOptimization = false; +unitTest.testSensitivity = false; + +%% UNIT TEST TO CREATE +% choose which folders to create data for +unitTest.saveTestSimulator = {'multipleAB', 'ballistic', 'engineCut', 'solid', 'HRE'}; % Select the simulator tests to perform +unitTest.saveTestApogeeAnalysis = false; +% unitTest.saveTestOptimization = false; +unitTest.saveTestSensitivity = false; \ No newline at end of file