From 8b7a7564854d8a356cd037ea1a7df61ca2d55dc3 Mon Sep 17 00:00:00 2001 From: Kevin D Date: Tue, 20 Jan 2026 23:49:12 -0800 Subject: [PATCH] CSV parametric testing --- @miSim/miSim.m | 2 +- @miSim/teardown.m | 12 ++++- @miSim/writeParams.m | 8 +++- test/parametricTestSuite.m | 97 ++++++++++++++++++++------------------ test/testIterations.csv | 3 ++ 5 files changed, 71 insertions(+), 51 deletions(-) create mode 100644 test/testIterations.csv diff --git a/@miSim/miSim.m b/@miSim/miSim.m index 577a0b8..d1d3f6c 100644 --- a/@miSim/miSim.m +++ b/@miSim/miSim.m @@ -67,8 +67,8 @@ classdef miSim [obj] = plotTrails(obj); [obj] = plotH(obj); [obj] = updatePlots(obj); + [obj] = teardown(obj); validate(obj); - teardown(obj); end methods (Access = private) [v] = setupVideoWriter(obj); diff --git a/@miSim/teardown.m b/@miSim/teardown.m index 4563b45..ae83145 100644 --- a/@miSim/teardown.m +++ b/@miSim/teardown.m @@ -1,8 +1,9 @@ -function teardown(obj) +function obj = teardown(obj) arguments (Input) obj (1, 1) {mustBeA(obj, 'miSim')}; end arguments (Output) + obj (1, 1) {mustBeA(obj, 'miSim')}; end % Close plots @@ -10,4 +11,13 @@ function teardown(obj) close(obj.fPerf); close(obj.f); + % Reset accumulators + obj.performance = 0; + + % Reset agents + for ii = 1:size(obj.agents, 1) + obj.agents{ii} = agent; + end + + end \ No newline at end of file diff --git a/@miSim/writeParams.m b/@miSim/writeParams.m index 8530bbf..7816faf 100644 --- a/@miSim/writeParams.m +++ b/@miSim/writeParams.m @@ -12,11 +12,15 @@ function writeParams(obj) alphaTilt = cellfun(@(x) x.sensorModel.alphaTilt, obj.agents); betaTilt = cellfun(@(x) x.sensorModel.alphaDist, obj.agents); comRange = cellfun(@(x) x.commsGeometry.radius, obj.agents); + initialStepSize = cellfun(@(x) x.initialStepSize, obj.agents); % Combine with simulation parameters params = struct('timestep', obj.timestep, 'maxIter', obj.maxIter, 'minAlt', obj.obstacles{end}.maxCorner(3), 'discretizationStep', obj.domain.objective.discretizationStep, ... - 'collisionRadius', collisionRadii, 'alphaDist', alphaDist, 'betaDist', betaDist, ... - 'alphaTilt', alphaTilt, 'betaTilt', betaTilt, 'comRange', comRange); + 'sensorPerformanceMinimum', obj.domain.objective.sensorPerformanceMinimum, 'collisionRadius', collisionRadii, 'alphaDist', alphaDist, 'betaDist', betaDist, ... + 'alphaTilt', alphaTilt, 'betaTilt', betaTilt, 'comRange', comRange, 'initialStepSize', initialStepSize, 'barrierGain', obj.barrierGain, 'barrierExponent', obj.barrierExponent ... + ); + + % TODO add sensorPerformanceMinimum % Save all parameters to output file paramsFile = strcat(obj.artifactName, "_miSimParams"); diff --git a/test/parametricTestSuite.m b/test/parametricTestSuite.m index 118cf6c..4e0e768 100644 --- a/test/parametricTestSuite.m +++ b/test/parametricTestSuite.m @@ -11,67 +11,70 @@ classdef parametricTestSuite < matlab.unittest.TestCase makePlots = true; % disable plotting for big performance increase (also disables video) plotCommsGeometry = false; % disable plotting communications geometries protectedRange = 0; + + %% Test iterations + csvPath = fullfile(matlab.project.rootProject().RootFolder, 'test', 'testIterations.csv'); end - properties (TestParameter) - %% Simulation Parameters - timestep = num2cell([1]); % duration of one simulation timestep - maxIter = num2cell([25]); % number of timesteps to run - % Domain parameters - minAlt = num2cell([1]); % minimum allowed agent altitude, make sure test cases don't conflict with this + methods (Static) + function params = readIterationsCsv(csvPath) + arguments (Input) + csvPath (1, 1) string; + end + arguments (Output) + params (1, 1) struct; + end - % Constraint parameters - barrierGain = num2cell([100]); - barrierExponent = num2cell([3]); + % File input validation + assert(isfile(csvPath), "%s is not a valid filepath."); + assert(endsWith(csvPath, '.csv'), "%s is not a CSV file."); - % Sensing Objective Parameters - sensorPerformanceMinimum = num2cell([1e-6]); % sensor performance threshhold for partition assignment - discretizationStep = num2cell([0.01]); % sensing objective discretization step size - % this value goes on to determine central differences used in - % gradient ascent and partitioning element sizes - - % Agent Parameters - collisionRadius = num2cell([0.1]); - initialStepSize = num2cell([0.2]); % gradient ascent step size at the first iteration. Decreases linearly to 0 based on maxIter. - - % Sensor Model Parameters - alphaDist = num2cell([2.5, 5]); - betaDist = num2cell([3, 15]); - alphaTilt = num2cell([15, 30]); % (degrees)methods - betaTilt = num2cell([3, 15]); - - % Communications Parameters - comRange = num2cell([3]); + % Read file + csv = readtable(csvPath); + + % Put params into standard structure + params = struct('timestep', csv.timestep, 'maxIter', csv.maxIter, 'minAlt', csv.minAlt, 'discretizationStep', csv.discretizationStep, ... + 'sensorPerformanceMinimum', csv.sensorPerformanceMinimum, 'collisionRadius', csv.collisionRadius, 'alphaDist', csv.alphaDist, 'betaDist', csv.betaDist, ... + 'alphaTilt', csv.alphaTilt, 'betaTilt', csv.betaTilt, 'comRange', csv.comRange, 'initialStepSize', csv.initialStepSize, 'barrierGain', csv.barrierGain, 'barrierExponent', csv.barrierExponent); + end end methods (Test, ParameterCombination = "exhaustive") % Test cases - function single_agent_gradient_ascent(tc, timestep, maxIter, barrierGain, barrierExponent, minAlt, sensorPerformanceMinimum, discretizationStep, collisionRadius, initialStepSize, alphaDist, betaDist, alphaTilt, betaTilt, comRange) - % Set up square domain + function single_agent_gradient_ascent(tc) + % Read in parameters to iterate over + params = tc.readIterationsCsv(tc.csvPath); + + % Test case setup l = 10; - tc.domain = tc.domain.initialize([zeros(1, 3); l * ones(1, 3)], REGION_TYPE.DOMAIN, "Domain"); - tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([.75 * l, 0.75 * l]), tc.domain, discretizationStep, tc.protectedRange, sensorPerformanceMinimum); - - % Set up agent sensorModel = sigmoidSensor; - sensorModel = sensorModel.initialize(alphaDist, betaDist, alphaTilt, betaTilt); agentPos = [l/4, l/4, l/4]; collisionGeometry = spherical; - collisionGeometry = collisionGeometry.initialize(agentPos, collisionRadius, REGION_TYPE.COLLISION, "Agent 1 Collision Region"); agents = {agent}; - agents{1} = agents{1}.initialize(agentPos, collisionGeometry, sensorModel, comRange, maxIter, initialStepSize, "Agent 1", tc.plotCommsGeometry); - % Set up simulation - tc.testClass = tc.testClass.initialize(tc.domain, agents, barrierGain, barrierExponent, minAlt, timestep, maxIter, tc.obstacles, tc.makePlots, tc.makeVideo); - - % Save simulation parameters to output file - tc.testClass.writeParams(); - - % Run - tc.testClass = tc.testClass.run(); - - % Cleanup - tc.testClass.teardown(); + for ii = 1:size(params.timestep, 1) + % Set up square domain + tc.domain = tc.domain.initialize([zeros(1, 3); l * ones(1, 3)], REGION_TYPE.DOMAIN, "Domain"); + tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([.75 * l, 0.75 * l]), tc.domain, params.discretizationStep(ii), tc.protectedRange, params.sensorPerformanceMinimum(ii)); + + % Set up agent + sensorModel = sensorModel.initialize(params.alphaDist(ii), params.betaDist(ii), params.alphaTilt(ii), params.betaTilt(ii)); + collisionGeometry = collisionGeometry.initialize(agentPos, params.collisionRadius(ii), REGION_TYPE.COLLISION, "Agent 1 Collision Region"); + agents{1} = agents{1}.initialize(agentPos, collisionGeometry, sensorModel, params.comRange(ii), params.maxIter(ii), params.initialStepSize(ii), "Agent 1", tc.plotCommsGeometry); + + % Set up simulation + tc.testClass = tc.testClass.initialize(tc.domain, agents, params.barrierGain(ii), params.barrierExponent(ii), params.minAlt(ii), params.timestep(ii), params.maxIter(ii), tc.obstacles, tc.makePlots, tc.makeVideo); + + % Save simulation parameters to output file + tc.testClass.writeParams(); + + % Run + tc.testClass = tc.testClass.run(); + + % Cleanup + tc.testClass = tc.testClass.teardown(); + end + end end end \ No newline at end of file diff --git a/test/testIterations.csv b/test/testIterations.csv new file mode 100644 index 0000000..e5f1942 --- /dev/null +++ b/test/testIterations.csv @@ -0,0 +1,3 @@ +timestep, maxIter, minAlt, barrierGain, barrierExponent, sensorPerformanceMinimum, discretizationStep, collisionRadius, initialStepSize, alphaDist, betaDist, alphaTilt, betaTilt, comRange +1, 25, 1, 100, 3, 1e-6, 0.01, 0.1, 0.2, 2.5, 3, 15, 3, 3 +1, 25, 1, 100, 3, 1e-6, 0.01, 0.1, 0.2, 5, 15, 30, 15, 3