Files
miSim/@miSim/initializeFromCsv.m
2026-03-09 21:23:31 -07:00

130 lines
5.8 KiB
Matlab
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
function obj = initializeFromCsv(obj, csvPath)
% INITIALIZEFROMCSV Initialize miSim from an AERPAW scenario CSV file.
%
% Reads all guidance parameters, domain geometry, initial UAV positions,
% and obstacle definitions from the CSV, then builds and initialises the
% simulation. Ends by calling the standard obj.initialize(...) method.
%
% This is the MATLAB-path counterpart to the compiled path that unpacks a
% flat scenarioParams array in guidance_step.m. It is only ever called
% from within a coder.target('MATLAB') guard and is never compiled.
%
% Usage (inside guidance_step.m on MATLAB path):
% sim = sim.initializeFromCsv('aerpaw/config/scenario.csv');
%
% Expected CSV columns (see scenario.csv):
% timestep, maxIter, minAlt, discretizationStep, protectedRange,
% 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)
arguments (Input)
obj (1, 1) {mustBeA(obj, 'miSim')};
csvPath (1, 1) string;
end
arguments (Output)
obj (1, 1) {mustBeA(obj, 'miSim')};
end
% ---- Parse CSV via readScenarioCsv ---------------------------------------
scenario = obj.readScenarioCsv(csvPath);
TIMESTEP = scenario.timestep;
MAX_ITER = scenario.maxIter;
MIN_ALT = scenario.minAlt;
DISCRETIZATION_STEP = scenario.discretizationStep;
PROTECTED_RANGE = scenario.protectedRange;
INITIAL_STEP_SIZE = scenario.initialStepSize;
BARRIER_GAIN = scenario.barrierGain;
BARRIER_EXPONENT = scenario.barrierExponent;
% 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
OBJECTIVE_GROUND_POS = scenario.objectivePos; % 1×2
OBJECTIVE_VAR = reshape(scenario.objectiveVar, 2, 2); % 2×2 covariance matrix
SENSOR_PERFORMANCE_MINIMUM = scenario.sensorPerformanceMinimum; % scalar
% Initial UAV positions: flat vector reshaped to N×3
flatPos = scenario.initialPositions; % 1×(3*N)
assert(mod(numel(flatPos), 3) == 0, ...
"initialPositions must have a multiple of 3 values; got %d", numel(flatPos));
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 --------------------------------------------------------
dom = rectangularPrism;
dom = dom.initialize([DOMAIN_MIN; DOMAIN_MAX], REGION_TYPE.DOMAIN, "Guidance Domain");
% ---- Build sensing objective (MATLAB path: objectiveFunctionWrapper) -----
dom.objective = sensingObjective;
objFcn = objectiveFunctionWrapper(OBJECTIVE_GROUND_POS, OBJECTIVE_VAR);
dom.objective = dom.objective.initialize(objFcn, dom, DISCRETIZATION_STEP, PROTECTED_RANGE, SENSOR_PERFORMANCE_MINIMUM);
% ---- 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_VEC(ii), REGION_TYPE.COLLISION, ...
sprintf("UAV %d Collision", ii));
ag = agent;
ag = ag.initialize(pos, geom, sensor, COMMS_RANGE_VEC(ii), MAX_ITER, ...
INITIAL_STEP_SIZE, sprintf("UAV %d", ii));
agentList{ii} = ag;
end
% ---- Build obstacles from CSV --------------------------------------------
obstacleList = cell(numObstacles, 1);
if numObstacles > 0
obsMin = reshape(scenario.obstacleMin, 3, numObstacles)'; % N×3
obsMax = reshape(scenario.obstacleMax, 3, numObstacles)';
for ii = 1:numObstacles
obs = rectangularPrism;
obs = obs.initialize([obsMin(ii, :); obsMax(ii, :)], ...
REGION_TYPE.OBSTACLE, sprintf("Obstacle %d", ii));
obstacleList{ii} = obs;
end
end
% ---- Initialise simulation (plots and video disabled) --------------------
obj = obj.initialize(dom, agentList, BARRIER_GAIN, BARRIER_EXPONENT, ...
MIN_ALT, TIMESTEP, MAX_ITER, obstacleList, false, false);
end