diff --git a/@miSim/initializeFromCsv.m b/@miSim/initializeFromCsv.m index 350a630..38ef7c4 100644 --- a/@miSim/initializeFromCsv.m +++ b/@miSim/initializeFromCsv.m @@ -14,9 +14,12 @@ function obj = initializeFromCsv(obj, csvPath) % % Expected CSV columns (see scenario.csv): % timestep, maxIter, minAlt, discretizationStep, protectedRange, -% initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, -% alphaDist, betaDist, alphaTilt, betaTilt, +% initialStepSize, barrierGain, barrierExponent, +% collisionRadius (per-UAV), comRange (per-UAV), +% alphaDist (per-UAV), betaDist (per-UAV), +% alphaTilt (per-UAV), betaTilt (per-UAV), % domainMin ("x,y,z"), domainMax ("x,y,z"), objectivePos ("x,y"), +% objectiveVar ("v11,v12,v21,v22"), sensorPerformanceMinimum, % initialPositions (flat "x1,y1,z1, x2,y2,z2,..."), % numObstacles, obstacleMin (flat), obstacleMax (flat) @@ -39,12 +42,13 @@ PROTECTED_RANGE = scenario.protectedRange; INITIAL_STEP_SIZE = scenario.initialStepSize; BARRIER_GAIN = scenario.barrierGain; BARRIER_EXPONENT = scenario.barrierExponent; -COLLISION_RADIUS = scenario.collisionRadius; -COMMS_RANGE = scenario.comRange; -ALPHA_DIST = scenario.alphaDist; -BETA_DIST = scenario.betaDist; -ALPHA_TILT = scenario.alphaTilt; -BETA_TILT = scenario.betaTilt; +% Per-UAV parameters (vectors with one element per UAV) +COLLISION_RADIUS_VEC = scenario.collisionRadius; % 1×N +COMMS_RANGE_VEC = scenario.comRange; % 1×N +ALPHA_DIST_VEC = scenario.alphaDist; % 1×N +BETA_DIST_VEC = scenario.betaDist; % 1×N +ALPHA_TILT_VEC = scenario.alphaTilt; % 1×N +BETA_TILT_VEC = scenario.betaTilt; % 1×N DOMAIN_MIN = scenario.domainMin; % 1×3 DOMAIN_MAX = scenario.domainMax; % 1×3 @@ -59,6 +63,20 @@ assert(mod(numel(flatPos), 3) == 0, ... positions = reshape(flatPos, 3, [])'; % N×3 numAgents = size(positions, 1); +% Validate per-UAV parameter lengths match numAgents +assert(numel(COLLISION_RADIUS_VEC) == numAgents, ... + "collisionRadius has %d values but expected %d (one per UAV)", numel(COLLISION_RADIUS_VEC), numAgents); +assert(numel(COMMS_RANGE_VEC) == numAgents, ... + "comRange has %d values but expected %d (one per UAV)", numel(COMMS_RANGE_VEC), numAgents); +assert(numel(ALPHA_DIST_VEC) == numAgents, ... + "alphaDist has %d values but expected %d (one per UAV)", numel(ALPHA_DIST_VEC), numAgents); +assert(numel(BETA_DIST_VEC) == numAgents, ... + "betaDist has %d values but expected %d (one per UAV)", numel(BETA_DIST_VEC), numAgents); +assert(numel(ALPHA_TILT_VEC) == numAgents, ... + "alphaTilt has %d values but expected %d (one per UAV)", numel(ALPHA_TILT_VEC), numAgents); +assert(numel(BETA_TILT_VEC) == numAgents, ... + "betaTilt has %d values but expected %d (one per UAV)", numel(BETA_TILT_VEC), numAgents); + numObstacles = scenario.numObstacles; % ---- Build domain -------------------------------------------------------- @@ -70,19 +88,23 @@ dom.objective = sensingObjective; objFcn = objectiveFunctionWrapper(OBJECTIVE_GROUND_POS, OBJECTIVE_VAR); dom.objective = dom.objective.initialize(objFcn, dom, DISCRETIZATION_STEP, PROTECTED_RANGE, SENSOR_PERFORMANCE_MINIMUM); -% ---- Build shared sensor model ------------------------------------------- -sensor = sigmoidSensor; -sensor = sensor.initialize(ALPHA_DIST, BETA_DIST, ALPHA_TILT, BETA_TILT); - % ---- Initialise agents from scenario positions --------------------------- +% Each agent gets its own sensor model and collision/comms radii from the +% per-UAV parameter vectors. agentList = cell(numAgents, 1); for ii = 1:numAgents pos = positions(ii, :); + + % Per-UAV sensor model + sensor = sigmoidSensor; + sensor = sensor.initialize(ALPHA_DIST_VEC(ii), BETA_DIST_VEC(ii), ... + ALPHA_TILT_VEC(ii), BETA_TILT_VEC(ii)); + geom = spherical; - geom = geom.initialize(pos, COLLISION_RADIUS, REGION_TYPE.COLLISION, ... + geom = geom.initialize(pos, COLLISION_RADIUS_VEC(ii), REGION_TYPE.COLLISION, ... sprintf("UAV %d Collision", ii)); ag = agent; - ag = ag.initialize(pos, geom, sensor, COMMS_RANGE, MAX_ITER, ... + ag = ag.initialize(pos, geom, sensor, COMMS_RANGE_VEC(ii), MAX_ITER, ... INITIAL_STEP_SIZE, sprintf("UAV %d", ii)); agentList{ii} = ag; end diff --git a/aerpaw/config/scenario.csv b/aerpaw/config/scenario.csv index fdd0cca..0189c67 100644 --- a/aerpaw/config/scenario.csv +++ b/aerpaw/config/scenario.csv @@ -1,2 +1,2 @@ timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax -5, 100, 30.0, 0.1, 1.0, 2.0, 100, 3, 3.0, 30.0, 80.0, 0.25, 5.0, 0.1, "0.0, 0.0, 0.0", "50.0, 50.0, 80.0", "35.0, 35.0", "10, 5, 5, 10", 2e-1, "5.0, 10.0, 45.0, 15.0, 10.0, 35.0", 0, "", "" \ No newline at end of file +5, 100, 30.0, 0.1, 1.0, 2.0, 100, 3, "3.0, 3.0", "30.0, 30.0", "80.0, 80.0", "0.25, 0.25", "5.0, 5.0", "0.1, 0.1", "0.0, 0.0, 0.0", "50.0, 50.0, 80.0", "35.0, 35.0", "10, 5, 5, 10", 0.15, "5.0, 10.0, 45.0, 15.0, 10.0, 35.0", 0, "", "" \ No newline at end of file diff --git a/aerpaw/controller.coderprj b/aerpaw/controller.coderprj index 3089563..f0b9274 100644 --- a/aerpaw/controller.coderprj +++ b/aerpaw/controller.coderprj @@ -1095,7 +1095,7 @@ true - 2026-03-03T15:32:50 + 2026-03-03T15:54:20 diff --git a/aerpaw/controller.m b/aerpaw/controller.m index 957e5c5..f71fa14 100644 --- a/aerpaw/controller.m +++ b/aerpaw/controller.m @@ -34,7 +34,7 @@ else end % Load guidance scenario from CSV (parameters for guidance_step) -NUM_SCENARIO_PARAMS = 27; +NUM_SCENARIO_PARAMS = 45; MAX_OBSTACLES_CTRL = int32(8); scenarioParams = zeros(1, NUM_SCENARIO_PARAMS); obstacleMin = zeros(MAX_OBSTACLES_CTRL, 3); diff --git a/aerpaw/guidance_step.m b/aerpaw/guidance_step.m index eb26834..c01a794 100644 --- a/aerpaw/guidance_step.m +++ b/aerpaw/guidance_step.m @@ -18,17 +18,17 @@ function nextPositions = guidance_step(currentPositions, isInit, ... % On MATLAB path this is ignored; parameters are loaded % from scenario.csv via initializeFromCsv instead. % Index mapping (1-based): -% 1 timestep 9 collisionRadius -% 2 maxIter 10 comRange -% 3 minAlt 11 alphaDist -% 4 discretizationStep 12 betaDist -% 5 protectedRange 13 alphaTilt -% 6 initialStepSize 14 betaTilt -% 7 barrierGain 15-17 domainMin -% 8 barrierExponent 18-20 domainMax -% 21-22 objectivePos -% 23-26 objectiveVar (2x2, col-major) -% 27 sensorPerformanceMinimum +% 1 timestep 9-12 collisionRadius[1:4] +% 2 maxIter 13-16 comRange[1:4] +% 3 minAlt 17-20 alphaDist[1:4] +% 4 discretizationStep 21-24 betaDist[1:4] +% 5 protectedRange 25-28 alphaTilt[1:4] +% 6 initialStepSize 29-32 betaTilt[1:4] +% 7 barrierGain 33-35 domainMin +% 8 barrierExponent 36-38 domainMax +% 39-40 objectivePos +% 41-44 objectiveVar (2x2, col-major) +% 45 sensorPerformanceMinimum % obstacleMin (MAX_OBSTACLES × 3) double column-major obstacle corners (compiled path) % obstacleMax (MAX_OBSTACLES × 3) double % numObstacles (1,1) int32 actual obstacle count @@ -72,6 +72,8 @@ if isInit else % ================================================================ % Compiled path: unpack scenarioParams array and obstacle arrays. + % Per-UAV parameters are stored as MAX_CLIENTS-wide blocks; only + % the first numAgents entries of each block are used. % ================================================================ TIMESTEP = scenarioParams(1); MAX_ITER = int32(scenarioParams(2)); @@ -81,17 +83,17 @@ if isInit INITIAL_STEP_SIZE = scenarioParams(6); BARRIER_GAIN = scenarioParams(7); BARRIER_EXPONENT = scenarioParams(8); - COLLISION_RADIUS = scenarioParams(9); - COMMS_RANGE = scenarioParams(10); - ALPHA_DIST = scenarioParams(11); - BETA_DIST = scenarioParams(12); - ALPHA_TILT = scenarioParams(13); - BETA_TILT = scenarioParams(14); - DOMAIN_MIN = scenarioParams(15:17); - DOMAIN_MAX = scenarioParams(18:20); - OBJECTIVE_GROUND_POS = scenarioParams(21:22); - OBJECTIVE_VAR = reshape(scenarioParams(23:26), 2, 2); - SENSOR_PERFORMANCE_MINIMUM = scenarioParams(27); + COLLISION_RADIUS_VEC = scenarioParams(9:12); % per-UAV [1:MAX_CLIENTS] + COMMS_RANGE_VEC = scenarioParams(13:16); + ALPHA_DIST_VEC = scenarioParams(17:20); + BETA_DIST_VEC = scenarioParams(21:24); + ALPHA_TILT_VEC = scenarioParams(25:28); + BETA_TILT_VEC = scenarioParams(29:32); + DOMAIN_MIN = scenarioParams(33:35); + DOMAIN_MAX = scenarioParams(36:38); + OBJECTIVE_GROUND_POS = scenarioParams(39:40); + OBJECTIVE_VAR = reshape(scenarioParams(41:44), 2, 2); + SENSOR_PERFORMANCE_MINIMUM = scenarioParams(45); % --- Build domain geometry --- dom = rectangularPrism; @@ -112,19 +114,21 @@ if isInit dom.objective = dom.objective.initializeWithValues(objValues, dom, ... DISCRETIZATION_STEP, PROTECTED_RANGE, SENSOR_PERFORMANCE_MINIMUM); - % --- Build shared sensor model --- - sensor = sigmoidSensor; - sensor = sensor.initialize(ALPHA_DIST, BETA_DIST, ALPHA_TILT, BETA_TILT); - - % --- Initialise agents from GPS positions --- + % --- Initialise agents from GPS positions (per-UAV parameters) ---- agentList = cell(numAgents, 1); for ii = 1:numAgents pos = currentPositions(ii, :); + + % Per-UAV sensor model + sensor = sigmoidSensor; + sensor = sensor.initialize(ALPHA_DIST_VEC(ii), BETA_DIST_VEC(ii), ... + ALPHA_TILT_VEC(ii), BETA_TILT_VEC(ii)); + geom = spherical; - geom = geom.initialize(pos, COLLISION_RADIUS, REGION_TYPE.COLLISION, ... + geom = geom.initialize(pos, COLLISION_RADIUS_VEC(ii), REGION_TYPE.COLLISION, ... sprintf("UAV %d Collision", ii)); ag = agent; - ag = ag.initialize(pos, geom, sensor, COMMS_RANGE, MAX_ITER, ... + ag = ag.initialize(pos, geom, sensor, COMMS_RANGE_VEC(ii), MAX_ITER, ... INITIAL_STEP_SIZE, sprintf("UAV %d", ii)); agentList{ii} = ag; end diff --git a/aerpaw/impl/controller_impl.cpp b/aerpaw/impl/controller_impl.cpp index 2cb5b9f..91c627f 100644 --- a/aerpaw/impl/controller_impl.cpp +++ b/aerpaw/impl/controller_impl.cpp @@ -174,14 +174,19 @@ static int readScenarioDataRow(const char* filename, char* line, int lineSize) { // Load guidance parameters from scenario.csv into flat params[NUM_SCENARIO_PARAMS]. // Index mapping (0-based): -// 0-13 : timestep, maxIter, minAlt, discretizationStep, protectedRange, -// initialStepSize, barrierGain, barrierExponent, collisionRadius, -// comRange, alphaDist, betaDist, alphaTilt, betaTilt -// 14-16: domainMin (east, north, up) -// 17-19: domainMax (east, north, up) -// 20-21: objectivePos (east, north) -// 22-25: objectiveVar (2x2 col-major: v11, v12, v21, v22) -// 26 : sensorPerformanceMinimum +// 0-7 : timestep, maxIter, minAlt, discretizationStep, protectedRange, +// initialStepSize, barrierGain, barrierExponent +// 8-11 : collisionRadius[1:4] (per-UAV, MAX_CLIENTS_PER_PARAM slots) +// 12-15: comRange[1:4] +// 16-19: alphaDist[1:4] +// 20-23: betaDist[1:4] +// 24-27: alphaTilt[1:4] +// 28-31: betaTilt[1:4] +// 32-34: domainMin (east, north, up) +// 35-37: domainMax (east, north, up) +// 38-39: objectivePos (east, north) +// 40-43: objectiveVar (2x2 col-major: v11, v12, v21, v22) +// 44 : sensorPerformanceMinimum // Returns 1 on success, 0 on failure. int loadScenario(const char* filename, double* params) { char line[4096]; @@ -198,16 +203,52 @@ int loadScenario(const char* filename, double* params) { return 0; } - // Scalar fields (columns 0–13) - for (int i = 0; i < 14; i++) { + // Zero-initialise all params so unused per-UAV slots default to 0 + for (int i = 0; i < NUM_SCENARIO_PARAMS; i++) params[i] = 0.0; + + // Scalar fields (columns 0–7): timestep..barrierExponent + for (int i = 0; i < 8; i++) { params[i] = atof(trimField(fields[i])); } + // Per-UAV fields (columns 8–13): collisionRadius, comRange, + // alphaDist, betaDist, alphaTilt, betaTilt. + // Each is a quoted comma-separated list with up to MAX_CLIENTS_PER_PARAM values. + // Stored in params as consecutive blocks of MAX_CLIENTS_PER_PARAM (4) slots. + { + const int perUavCols[] = {8, 9, 10, 11, 12, 13}; + const int perUavOffsets[] = {8, 12, 16, 20, 24, 28}; // 0-based param indices + const char* perUavNames[] = {"collisionRadius", "comRange", + "alphaDist", "betaDist", + "alphaTilt", "betaTilt"}; + for (int p = 0; p < 6; p++) { + char tmp[256]; + strncpy(tmp, fields[perUavCols[p]], sizeof(tmp) - 1); + tmp[sizeof(tmp) - 1] = '\0'; + char* t = trimField(tmp); + // Parse comma-separated values + double vals[4] = {0, 0, 0, 0}; + int count = 0; + char* tok = strtok(t, ","); + while (tok && count < MAX_CLIENTS_PER_PARAM) { + vals[count++] = atof(tok); + tok = strtok(nullptr, ","); + } + if (count == 0) { + fprintf(stderr, "loadScenario: failed to parse %s\n", perUavNames[p]); + return 0; + } + for (int k = 0; k < MAX_CLIENTS_PER_PARAM; k++) { + params[perUavOffsets[p] + k] = vals[k]; + } + } + } + // domainMin: column 14, format "east, north, up" { char tmp[256]; strncpy(tmp, fields[14], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0'; char* t = trimField(tmp); - if (sscanf(t, "%lf , %lf , %lf", ¶ms[14], ¶ms[15], ¶ms[16]) != 3) { + if (sscanf(t, "%lf , %lf , %lf", ¶ms[32], ¶ms[33], ¶ms[34]) != 3) { fprintf(stderr, "loadScenario: failed to parse domainMin: %s\n", t); return 0; } @@ -217,7 +258,7 @@ int loadScenario(const char* filename, double* params) { { char tmp[256]; strncpy(tmp, fields[15], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0'; char* t = trimField(tmp); - if (sscanf(t, "%lf , %lf , %lf", ¶ms[17], ¶ms[18], ¶ms[19]) != 3) { + if (sscanf(t, "%lf , %lf , %lf", ¶ms[35], ¶ms[36], ¶ms[37]) != 3) { fprintf(stderr, "loadScenario: failed to parse domainMax: %s\n", t); return 0; } @@ -227,7 +268,7 @@ int loadScenario(const char* filename, double* params) { { char tmp[256]; strncpy(tmp, fields[16], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0'; char* t = trimField(tmp); - if (sscanf(t, "%lf , %lf", ¶ms[20], ¶ms[21]) != 2) { + if (sscanf(t, "%lf , %lf", ¶ms[38], ¶ms[39]) != 2) { fprintf(stderr, "loadScenario: failed to parse objectivePos: %s\n", t); return 0; } @@ -237,7 +278,7 @@ int loadScenario(const char* filename, double* params) { { char tmp[256]; strncpy(tmp, fields[17], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0'; char* t = trimField(tmp); - if (sscanf(t, "%lf , %lf , %lf , %lf", ¶ms[22], ¶ms[23], ¶ms[24], ¶ms[25]) != 4) { + if (sscanf(t, "%lf , %lf , %lf , %lf", ¶ms[40], ¶ms[41], ¶ms[42], ¶ms[43]) != 4) { fprintf(stderr, "loadScenario: failed to parse objectiveVar: %s\n", t); return 0; } @@ -246,11 +287,11 @@ int loadScenario(const char* filename, double* params) { // sensorPerformanceMinimum: column 18 { char tmp[64]; strncpy(tmp, fields[18], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0'; - params[26] = atof(trimField(tmp)); + params[44] = atof(trimField(tmp)); } printf("Loaded scenario: domain [%g,%g,%g] to [%g,%g,%g]\n", - params[14], params[15], params[16], params[17], params[18], params[19]); + params[32], params[33], params[34], params[35], params[36], params[37]); return 1; } diff --git a/aerpaw/impl/controller_impl.h b/aerpaw/impl/controller_impl.h index 7edf018..948ea20 100644 --- a/aerpaw/impl/controller_impl.h +++ b/aerpaw/impl/controller_impl.h @@ -17,9 +17,21 @@ int loadTargets(const char* filename, double* targets, int maxClients); // Scenario loading (scenario.csv) // Number of elements in the flat params array passed to guidance_step. -// Indices: 0-13 scalars, 14-16 domainMin, 17-19 domainMax, 20-21 objectivePos, -// 22-25 objectiveVar (2x2 col-major: [v11,v12,v21,v22]), 26 sensorPerformanceMinimum. -#define NUM_SCENARIO_PARAMS 27 +// Indices (0-based): +// 0-7 scalars (timestep..barrierExponent) +// 8-11 collisionRadius[1:4] (per-UAV, MAX_CLIENTS slots) +// 12-15 comRange[1:4] +// 16-19 alphaDist[1:4] +// 20-23 betaDist[1:4] +// 24-27 alphaTilt[1:4] +// 28-31 betaTilt[1:4] +// 32-34 domainMin +// 35-37 domainMax +// 38-39 objectivePos +// 40-43 objectiveVar (2x2 col-major) +// 44 sensorPerformanceMinimum +#define NUM_SCENARIO_PARAMS 45 +#define MAX_CLIENTS_PER_PARAM 4 // Maximum number of obstacles (upper bound for pre-allocated arrays). #define MAX_OBSTACLES 8 diff --git a/aerpaw/results/plotGpsCsvs.m b/aerpaw/results/plotGpsCsvs.m index 5a72727..d040570 100644 --- a/aerpaw/results/plotGpsCsvs.m +++ b/aerpaw/results/plotGpsCsvs.m @@ -20,7 +20,7 @@ fclose(fID); lla0 = [str2double(yaml((strfind(yaml, 'lat:') + 4):(strfind(yaml, 'lon:') - 1))), str2double(yaml((strfind(yaml, 'lon:') + 4):(strfind(yaml, 'alt:') - 1))), seaToGroundLevel]; % Paths to logs -gpsCsvs = dir(fullfile("sandbox", "test9", "*.csv")); +gpsCsvs = dir(fullfile("sandbox", "test10", "*.csv")); G = cell(size(gpsCsvs)); for ii = 1:size(gpsCsvs, 1) @@ -38,18 +38,13 @@ for ii = 1:size(gpsCsvs, 1) stopIdx = find(verticalSpeed <= prctile(verticalSpeed, pctThreshold), 1, 'last'); % % Plot whole flight, including setup/cleanup - % startIdx = 1; - % stopIdx = length(verticalSpeed); + startIdx = 1; + stopIdx = length(verticalSpeed); % Plot recorded trajectory over specified range of indices geoplot3(gf, G{ii}.Latitude(startIdx:stopIdx), G{ii}.Longitude(startIdx:stopIdx), G{ii}.Altitude(startIdx:stopIdx) + seaToGroundLevel, c(mod(ii, length(c))), 'LineWidth', 2, "MarkerSize", 5); end -% Plot objective -objectivePos = [params.objectivePos, 0]; -llaObj = enu2lla(objectivePos, lla0, 'flat'); -geoplot3(gf, [llaObj(1), llaObj(1)], [llaObj(2), llaObj(2)], [llaObj(3), llaObj(3) + 50], 'LineWidth', 3, "Color", 'y'); - % Plot domain altOffset = 1; % to avoid clipping into the ground when displayed domain = [lla0; enu2lla(params.domainMax, lla0, 'flat')]; @@ -64,5 +59,10 @@ geoplot3(gf, [domain(2, 1), domain(2, 1)], [domain(2, 2), domain(2, 2)], domain( floorAlt = params.minAlt; geoplot3(gf, [domain(1, 1), domain(2, 1), domain(2, 1), domain(1, 1), domain(1, 1)], [domain(1, 2), domain(1, 2), domain(2, 2), domain(2, 2), domain(1, 2)], repmat(domain(1, 3) + altOffset + floorAlt, 1, 5), 'LineWidth', 3, 'Color', 'r'); +% Plot objective +objectivePos = [params.objectivePos, 0]; +llaObj = enu2lla(objectivePos, lla0, 'flat'); +geoplot3(gf, [llaObj(1), llaObj(1)], [llaObj(2), llaObj(2)], [llaObj(3), domain(2, 3)], 'LineWidth', 3, "Color", 'y'); + % finish hold(gf, "off"); \ No newline at end of file diff --git a/resources/project/q138eJA8Ym4eSfM3RFMVvg63QtU/soCFsvL91lhqvUw-h8HkHCtfsiwd.xml b/resources/project/q138eJA8Ym4eSfM3RFMVvg63QtU/soCFsvL91lhqvUw-h8HkHCtfsiwd.xml new file mode 100644 index 0000000..4356a6a --- /dev/null +++ b/resources/project/q138eJA8Ym4eSfM3RFMVvg63QtU/soCFsvL91lhqvUw-h8HkHCtfsiwd.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/project/q138eJA8Ym4eSfM3RFMVvg63QtU/soCFsvL91lhqvUw-h8HkHCtfsiwp.xml b/resources/project/q138eJA8Ym4eSfM3RFMVvg63QtU/soCFsvL91lhqvUw-h8HkHCtfsiwp.xml new file mode 100644 index 0000000..09a956f --- /dev/null +++ b/resources/project/q138eJA8Ym4eSfM3RFMVvg63QtU/soCFsvL91lhqvUw-h8HkHCtfsiwp.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/project/soCFsvL91lhqvUw-h8HkHCtfsiw/1fQ44ZBWSpGWUWzrR6iBNoEkvh4d.xml b/resources/project/soCFsvL91lhqvUw-h8HkHCtfsiw/1fQ44ZBWSpGWUWzrR6iBNoEkvh4d.xml new file mode 100644 index 0000000..4356a6a --- /dev/null +++ b/resources/project/soCFsvL91lhqvUw-h8HkHCtfsiw/1fQ44ZBWSpGWUWzrR6iBNoEkvh4d.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/project/soCFsvL91lhqvUw-h8HkHCtfsiw/1fQ44ZBWSpGWUWzrR6iBNoEkvh4p.xml b/resources/project/soCFsvL91lhqvUw-h8HkHCtfsiw/1fQ44ZBWSpGWUWzrR6iBNoEkvh4p.xml new file mode 100644 index 0000000..01cb34e --- /dev/null +++ b/resources/project/soCFsvL91lhqvUw-h8HkHCtfsiw/1fQ44ZBWSpGWUWzrR6iBNoEkvh4p.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/test/parametricTestSuite.m b/test/parametricTestSuite.m index b1f1728..9fc185c 100644 --- a/test/parametricTestSuite.m +++ b/test/parametricTestSuite.m @@ -30,7 +30,7 @@ classdef parametricTestSuite < matlab.unittest.TestCase function test_AERPAW_scenario(tc) % Load scenario definition tc.csvPath = fullfile(matlab.project.rootProject().RootFolder, "aerpaw", "config", "scenario.csv"); - params = tc.testClass.readScenarioCsv(tc.csvPath); + params = readScenarioCsv(tc.csvPath); % Define scenario according to CSV specification tc.domain = tc.domain.initialize([params.domainMin; params.domainMax], REGION_TYPE.DOMAIN, "Domain"); @@ -41,16 +41,20 @@ classdef parametricTestSuite < matlab.unittest.TestCase agents{ii} = agent; sensorModel = sigmoidSensor; - sensorModel = sensorModel.initialize(params.alphaDist, params.betaDist, params.alphaTilt, params.betaTilt); + sensorModel = sensorModel.initialize(params.alphaDist(ii), params.betaDist(ii), params.alphaTilt(ii), params.betaTilt(ii)); collisionGeometry = spherical; - collisionGeometry = collisionGeometry.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), params.collisionRadius, REGION_TYPE.COLLISION, sprintf("Agent %d collision geometry", ii)); + collisionGeometry = collisionGeometry.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), params.collisionRadius(ii), REGION_TYPE.COLLISION, sprintf("Agent %d collision geometry", ii)); - agents{ii} = agents{ii}.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), collisionGeometry, sensorModel, params.comRange, params.maxIter, params.initialStepSize, sprintf("Agent %d", ii), tc.plotCommsGeometry); + agents{ii} = agents{ii}.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), collisionGeometry, sensorModel, params.comRange(ii), params.maxIter, params.initialStepSize, sprintf("Agent %d", ii), tc.plotCommsGeometry); end - % TODO - obstacles = {}; + % Create obstacles + obstacles = cell(params.numObstacles, 1); + for ii = 1:size(obstacles, 1) + obstacles{ii} = rectangularPrism; + obstacles{ii} = obstacles{ii}.initialize([params.obstacleMin((((ii - 1) * 3) + 1):(ii * 3)); params.obstacleMax((((ii - 1) * 3) + 1):(ii * 3))], "OBSTACLE", sprintf("Obstacle %d", ii)); + end % Set up simulation tc.testClass = tc.testClass.initialize(tc.domain, agents, params.barrierGain, params.barrierExponent, params.minAlt, params.timestep, params.maxIter, obstacles, tc.makePlots, tc.makeVideo); @@ -60,13 +64,10 @@ classdef parametricTestSuite < matlab.unittest.TestCase % Run tc.testClass = tc.testClass.run(); - - % Cleanup - tc.testClass = tc.testClass.teardown(); end function csv_parametric_tests_random_agents(tc) % Read in parameters to iterate over - params = tc.testClass.readScenarioCsv(tc.csvPath); + params = readScenarioCsv(tc.csvPath); % Test case setup l = 10; % domain size