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