reorganized code into separate files

This commit is contained in:
2025-11-15 14:36:10 -08:00
parent e7127365bd
commit 8dd24bdba6
203 changed files with 1413 additions and 1101 deletions

78
util/firstPlotSetup.m Normal file
View File

@@ -0,0 +1,78 @@
function f = firstPlotSetup(f)
arguments (Input)
f (1, 1) {mustBeA(f, 'matlab.ui.Figure')} = figure;
end
arguments (Output)
f (1, 1) {mustBeA(f, 'matlab.ui.Figure')};
end
if isempty(f.CurrentAxes)
tiledlayout(f, 5, 5, "TileSpacing", "tight", "Padding", "compact");
% 3D view
nexttile(1, [4, 5]);
axes(f.Children(1).Children(1));
axis(f.Children(1).Children(1), "image");
grid(f.Children(1).Children(1), "on");
view(f.Children(1).Children(1), 3);
xlabel(f.Children(1).Children(1), "X"); ylabel(f.Children(1).Children(1), "Y"); zlabel(f.Children(1).Children(1), "Z");
title(f.Children(1).Children(1), "3D View");
% Communications graph
nexttile(21, [1, 1]);
axes(f.Children(1).Children(1));
axis(f.Children(1).Children(1), "image");
grid(f.Children(1).Children(1), "off");
view(f.Children(1).Children(1), 0, 90);
title(f.Children(1).Children(1), "Network Graph");
set(f.Children(1).Children(1), 'XTickLabelMode', 'manual');
set(f.Children(1).Children(1), 'YTickLabelMode', 'manual');
set(f.Children(1).Children(1), 'XTickLabel', {});
set(f.Children(1).Children(1), 'YTickLabel', {});
set(f.Children(1).Children(1), 'XTick', []);
set(f.Children(1).Children(1), 'YTick', []);
set(f.Children(1).Children(1), 'XColor', 'none');
set(f.Children(1).Children(1), 'YColor', 'none');
% Top-down view
nexttile(22, [1, 1]);
axes(f.Children(1).Children(1));
axis(f.Children(1).Children(1), "image");
grid(f.Children(1).Children(1), "on");
view(f.Children(1).Children(1), 0, 90);
xlabel(f.Children(1).Children(1), "X"); ylabel(f.Children(1).Children(1), "Y");
title(f.Children(1).Children(1), "Top-down View");
% Side-on view
nexttile(23, [1, 1]);
axes(f.Children(1).Children(1));
axis(f.Children(1).Children(1), "image");
grid(f.Children(1).Children(1), "on");
view(f.Children(1).Children(1), 90, 0);
ylabel(f.Children(1).Children(1), "Y"); zlabel(f.Children(1).Children(1), "Z");
title(f.Children(1).Children(1), "Side-on View");
% Front-on view
nexttile(24, [1, 1]);
axes(f.Children(1).Children(1));
axis(f.Children(1).Children(1), "image");
grid(f.Children(1).Children(1), "on");
view(f.Children(1).Children(1), 0, 0);
xlabel(f.Children(1).Children(1), "X"); zlabel(f.Children(1).Children(1), "Z");
title(f.Children(1).Children(1), "Front-on View");
% Partitioning
nexttile(25, [1, 1]);
axes(f.Children(1).Children(1));
axis(f.Children(1).Children(1), "image");
grid(f.Children(1).Children(1), "on");
view(f.Children(1).Children(1), 0, 90);
xlabel(f.Children(1).Children(1), "X"); ylabel(f.Children(1).Children(1), "Y");
title(f.Children(1).Children(1), "Domain Partitioning");
set(f.Children(1).Children(1), 'XTickLabelMode', 'manual');
set(f.Children(1).Children(1), 'YTickLabelMode', 'manual');
set(f.Children(1).Children(1), 'XTickLabel', {});
set(f.Children(1).Children(1), 'YTickLabel', {});
set(f.Children(1).Children(1), 'XTick', []);
set(f.Children(1).Children(1), 'YTick', []);
end
end

View File

@@ -0,0 +1,11 @@
function c = agentsCrowdObjective(objective, positions, protectedRange)
arguments (Input)
objective (1, 1) {mustBeA(objective, 'sensingObjective')};
positions (:, 3) double; % this could be expanded to handle n obstacles in 1 call
protectedRange (1, 1) double;
end
arguments (Output)
c (:, 1) logical;
end
c = vecnorm(positions(:, 1:2) - objective.groundPos, 2, 2) <= protectedRange;
end

View File

@@ -0,0 +1,10 @@
function mustBeGeometry(geometry)
validGeometries = ["rectangularPrism";];
if isa(geometry, 'cell')
for ii = 1:size(geometry, 1)
assert(any(arrayfun(@(x) isa(geometry{ii}, x), validGeometries)), "Geometry in index %d is not a valid geometry class", ii);
end
else
assert(any(arrayfun(@(x) isa(geometry, x), validGeometries)), "Geometry is not a valid geometry class");
end
end

View File

@@ -0,0 +1,10 @@
function mustBeSensor(sensorModel)
validSensorModels = ["fixedCardinalSensor"; "sigmoidSensor";];
if isa(sensorModel, 'cell')
for ii = 1:size(sensorModel, 1)
assert(any(arrayfun(@(x) isa(sensorModel{ii}, x), validSensorModels)), "Sensor in index %d is not a valid sensor class", ii);
end
else
assert(any(arrayfun(@(x) isa(sensorModel, x), validSensorModels)), "Sensor is not a valid sensor class");
end
end

View File

@@ -0,0 +1,21 @@
function c = domainContainsObstacle(domain, obstacle)
arguments (Input)
domain (1, 1) {mustBeGeometry};
obstacle (1, 1) {mustBeGeometry}; % this could be expanded to handle n obstacles in 1 call
end
arguments (Output)
c (1, 1) logical;
end
switch class(domain)
case 'rectangularPrism'
switch class(obstacle)
case 'rectangularPrism'
c = all(domain.minCorner <= obstacle.minCorner) && all(domain.maxCorner >= obstacle.maxCorner);
otherwise
error("%s not implemented for obstacles of class %s", coder.mfunctionname, class(domain));
end
otherwise
error("%s not implemented for domains of class %s", coder.mfunctionname, class(domain));
end
end

View File

@@ -0,0 +1,17 @@
function c = geometryIntersects(g1, g2)
c = false;
% Check if g2 contains g1
for jj = 1:size(g1.edges, 1)
if g2.containsLine(g1.vertices(g1.edges(jj, 1), 1:3), g1.vertices(g1.edges(jj, 2), 1:3))
c = true;
return;
end
end
% Check if g1 contains g2
for jj = 1:size(g2.edges, 1)
if g1.containsLine(g2.vertices(g2.edges(jj, 1), 1:3), g2.vertices(g2.edges(jj, 2), 1:3))
c = true;
return;
end
end
end

View File

@@ -0,0 +1,13 @@
function c = obstacleCoversObjective(objective, obstacle)
arguments (Input)
objective (1, 1) {mustBeA(objective, 'sensingObjective')};
obstacle (1, 1) {mustBeGeometry}; % this could be expanded to handle n obstacles in 1 call
end
arguments (Output)
c (1, 1) logical;
end
% Check if the obstacle contains the objective's ground position if the
% ground position were raised to the obstacle's center's height
c = obstacle.contains([objective.groundPos, obstacle.center(3)]);
end

View File

@@ -0,0 +1,11 @@
function c = obstacleCrowdsObjective(objective, obstacle, protectedRange)
arguments (Input)
objective (1, 1) {mustBeA(objective, 'sensingObjective')};
obstacle (1, 1) {mustBeGeometry}; % this could be expanded to handle n obstacles in 1 call
protectedRange (1, 1) double;
end
arguments (Output)
c (1, 1) logical;
end
c = norm(obstacle.distance([objective.groundPos, obstacle.center(3)])) <= protectedRange;
end