diff --git a/@miSim/plot.m b/@miSim/plot.m
index 243b67f..4fea9fa 100644
--- a/@miSim/plot.m
+++ b/@miSim/plot.m
@@ -16,7 +16,7 @@ function [obj, f] = plot(obj)
end
% Plot objective gradient
- f = obj.objective.plot(obj.objectivePlotIndices, f);
+ f = obj.domain.objective.plot(obj.objectivePlotIndices, f);
% Plot agents and their collision geometries
for ii = 1:size(obj.agents, 1)
diff --git a/@sensingObjective/initialize.m b/@sensingObjective/initialize.m
index 1d51fb0..69c00eb 100644
--- a/@sensingObjective/initialize.m
+++ b/@sensingObjective/initialize.m
@@ -1,22 +1,21 @@
-function obj = initialize(obj, objectiveFunction, footprint, groundAlt, discretizationStep)
+function obj = initialize(obj, objectiveFunction, domain, discretizationStep)
arguments (Input)
obj (1,1) {mustBeA(obj, 'sensingObjective')};
objectiveFunction (1, 1) {mustBeA(objectiveFunction, 'function_handle')};
- footprint (:, 2) double;
- groundAlt (1, 1) double = 0;
+ domain (1, 1) {mustBeGeometry};
discretizationStep (1, 1) double = 1;
end
arguments (Output)
obj (1,1) {mustBeA(obj, 'sensingObjective')};
end
- obj.groundAlt = groundAlt;
+ obj.groundAlt = domain.minCorner(3);
% Extract footprint limits
- xMin = min(footprint(:, 1));
- xMax = max(footprint(:, 1));
- yMin = min(footprint(:, 2));
- yMax = max(footprint(:, 2));
+ xMin = min(domain.footprint(:, 1));
+ xMax = max(domain.footprint(:, 1));
+ yMin = min(domain.footprint(:, 2));
+ yMax = max(domain.footprint(:, 2));
xGrid = unique([xMin:discretizationStep:xMax, xMax]);
yGrid = unique([yMin:discretizationStep:yMax, yMax]);
diff --git a/@sensingObjective/initializeRandomMvnpdf.m b/@sensingObjective/initializeRandomMvnpdf.m
new file mode 100644
index 0000000..b421acb
--- /dev/null
+++ b/@sensingObjective/initializeRandomMvnpdf.m
@@ -0,0 +1,27 @@
+function obj = initializeRandomMvnpdf(obj, domain, protectedRange, discretizationStep)
+ arguments (Input)
+ obj (1, 1) {mustBeA(obj, 'sensingObjective')};
+ domain (1, 1) {mustBeGeometry};
+ protectedRange (1, 1) double = 1;
+ discretizationStep (1, 1) double = 1;
+ end
+ arguments (Output)
+ obj (1, 1) {mustBeA(obj, 'sensingObjective')};
+ end
+
+ % Set random objective position
+ mu = domain.minCorner;
+ while domain.distance(mu) < protectedRange
+ mu = domain.random();
+ end
+ mu = mu(1:2);
+
+ % Set random distribution parameters
+ sig = [2 + rand * 2, 1; 1, 2 + rand * 2];
+
+ % Set up random bivariate normal distribution function
+ objectiveFunction = @(x, y) mvnpdf([x(:), y(:)], mu, sig);
+
+ % Regular initialization
+ obj = obj.initialize(objectiveFunction, domain, discretizationStep);
+end
\ No newline at end of file
diff --git a/@sensingObjective/plot.m b/@sensingObjective/plot.m
index b9adbc0..9e48eeb 100644
--- a/@sensingObjective/plot.m
+++ b/@sensingObjective/plot.m
@@ -18,7 +18,6 @@ function f = plot(obj, ind, f)
o.HitTest = 'off';
o.PickableParts = 'none';
hold(f.CurrentAxes, "off");
-
else
hold(f.Children(1).Children(ind(1)), "on");
o = surf(f.Children(1).Children(ind(1)), obj.X, obj.Y, repmat(obj.groundAlt, size(obj.X)), obj.values ./ max(obj.values, [], "all"), 'EdgeColor', 'none');
diff --git a/@sensingObjective/sensingObjective.m b/@sensingObjective/sensingObjective.m
index fbe865a..f24eefa 100644
--- a/@sensingObjective/sensingObjective.m
+++ b/@sensingObjective/sensingObjective.m
@@ -12,7 +12,8 @@ classdef sensingObjective
end
methods (Access = public)
- [obj] = initialize(obj, objectiveFunction, footprint, groundAlt, discretizationStep);
+ [obj] = initialize(obj, objectiveFunction, domain, discretizationStep);
+ [obj] = initializeRandomMvnpdf(obj, domain, protectedRange, discretizationStep);
[f ] = plot(obj, ind, f);
end
end
\ No newline at end of file
diff --git a/geometries/@rectangularPrism/initialize.m b/geometries/@rectangularPrism/initialize.m
index a09d510..66df445 100644
--- a/geometries/@rectangularPrism/initialize.m
+++ b/geometries/@rectangularPrism/initialize.m
@@ -1,9 +1,11 @@
-function obj = initialize(obj, bounds, tag, label)
+function obj = initialize(obj, bounds, tag, label, objectiveFunction, discretizationStep)
arguments (Input)
obj (1, 1) {mustBeA(obj, 'rectangularPrism')};
bounds (2, 3) double;
tag (1, 1) REGION_TYPE = REGION_TYPE.INVALID;
label (1, 1) string = "";
+ objectiveFunction (1, 1) function_handle = @(x, y) 1;
+ discretizationStep (1, 1) double = 1;
end
arguments (Output)
obj (1, 1) {mustBeA(obj, 'rectangularPrism')};
@@ -12,7 +14,7 @@ function obj = initialize(obj, bounds, tag, label)
obj.tag = tag;
obj.label = label;
- %% Define geometry bounds by LL corner and UR corner
+ % Define geometry bounds by LL corner and UR corner
obj.minCorner = bounds(1, 1:3);
obj.maxCorner = bounds(2, 1:3);
@@ -37,4 +39,9 @@ function obj = initialize(obj, bounds, tag, label)
[obj.minCorner(1), obj.maxCorner(2)]; ...
[obj.maxCorner(1), obj.minCorner(2)]; ...
obj.maxCorner(1:2)];
+
+ % Instantiate sensingObjective only for DOMAIN-type regions
+ if tag == REGION_TYPE.DOMAIN
+ obj.objective = sensingObjective;
+ end
end
\ No newline at end of file
diff --git a/geometries/@rectangularPrism/initializeRandom.m b/geometries/@rectangularPrism/initializeRandom.m
new file mode 100644
index 0000000..b57330f
--- /dev/null
+++ b/geometries/@rectangularPrism/initializeRandom.m
@@ -0,0 +1,18 @@
+function [obj] = initializeRandom(obj, minDimension, tag, label)
+ arguments (Input)
+ obj (1, 1) {mustBeA(obj, 'rectangularPrism')};
+ minDimension (1, 1) double = 10;
+ tag (1, 1) REGION_TYPE = REGION_TYPE.INVALID;
+ label (1, 1) string = "";
+ end
+ arguments (Output)
+ obj (1, 1) {mustBeA(obj, 'rectangularPrism')};
+ end
+
+ % Produce random bounds
+ L = ceil(minDimension + rand * minDimension);
+ bounds = [zeros(1, 3); L * ones(1, 3)];
+
+ % Regular initialization
+ obj = obj.initialize(bounds, tag, label);
+end
\ No newline at end of file
diff --git a/geometries/@rectangularPrism/rectangularPrism.m b/geometries/@rectangularPrism/rectangularPrism.m
index f0928e1..59cc217 100644
--- a/geometries/@rectangularPrism/rectangularPrism.m
+++ b/geometries/@rectangularPrism/rectangularPrism.m
@@ -21,9 +21,14 @@ classdef rectangularPrism
% Plotting
lines;
end
+ properties (SetAccess = public, GetAccess = public)
+ % Sensing objective (for DOMAIN region type only)
+ objective;
+ end
methods (Access = public)
- [obj ] = initialize(obj, bounds, tag, label);
+ [obj ] = initialize(obj, bounds, tag, label, objectiveFunction, discretizationStep);
+ [obj ] = initializeRandom(obj, tag, label);
[r ] = random(obj);
[c ] = contains(obj, pos);
[d ] = distance(obj, pos);
diff --git a/resources/project/qFRcMsci5bTUnTBevgtb2pITyQU/MwRvCS7aBsmP7sDYhggreAErsO8d.xml b/resources/project/qFRcMsci5bTUnTBevgtb2pITyQU/MwRvCS7aBsmP7sDYhggreAErsO8d.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/resources/project/qFRcMsci5bTUnTBevgtb2pITyQU/MwRvCS7aBsmP7sDYhggreAErsO8d.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/project/qFRcMsci5bTUnTBevgtb2pITyQU/MwRvCS7aBsmP7sDYhggreAErsO8p.xml b/resources/project/qFRcMsci5bTUnTBevgtb2pITyQU/MwRvCS7aBsmP7sDYhggreAErsO8p.xml
new file mode 100644
index 0000000..1599b93
--- /dev/null
+++ b/resources/project/qFRcMsci5bTUnTBevgtb2pITyQU/MwRvCS7aBsmP7sDYhggreAErsO8p.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/resources/project/tBBDcBPWdBTCTMSBG9IGJ_TsICk/qyT5ovOLTSj0PEK6QQG5cW9EeTAd.xml b/resources/project/tBBDcBPWdBTCTMSBG9IGJ_TsICk/qyT5ovOLTSj0PEK6QQG5cW9EeTAd.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/resources/project/tBBDcBPWdBTCTMSBG9IGJ_TsICk/qyT5ovOLTSj0PEK6QQG5cW9EeTAd.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/project/tBBDcBPWdBTCTMSBG9IGJ_TsICk/qyT5ovOLTSj0PEK6QQG5cW9EeTAp.xml b/resources/project/tBBDcBPWdBTCTMSBG9IGJ_TsICk/qyT5ovOLTSj0PEK6QQG5cW9EeTAp.xml
new file mode 100644
index 0000000..3727ae7
--- /dev/null
+++ b/resources/project/tBBDcBPWdBTCTMSBG9IGJ_TsICk/qyT5ovOLTSj0PEK6QQG5cW9EeTAp.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/test/test_miSim.m b/test/test_miSim.m
index 5952af9..fd26fe2 100644
--- a/test/test_miSim.m
+++ b/test/test_miSim.m
@@ -2,12 +2,15 @@ classdef test_miSim < matlab.unittest.TestCase
properties (Access = private)
testClass = miSim;
- % Domain
- domain = rectangularPrism; % domain geometry
+ % Sim
maxIter = 250;
timestep = 0.05
partitoningFreq = 5;
+ % Domain
+ domain = rectangularPrism; % domain geometry
+ minDimension = 10;
+
% Obstacles
minNumObstacles = 1; % Minimum number of obstacles to be randomly generated
maxNumObstacles = 3; % Maximum number of obstacles to be randomly generated
@@ -16,7 +19,7 @@ classdef test_miSim < matlab.unittest.TestCase
obstacles = cell(1, 0);
% Objective
- objectiveDiscretizationStep = 0.01; % Step at which the objective function is solved in X and Y space
+ discretizationStep = 0.01; % Step at which the objective function is solved in X and Y space
protectedRange = 1; % Minimum distance between the sensing objective and the edge of the domain
objective = sensingObjective;
@@ -39,26 +42,10 @@ classdef test_miSim < matlab.unittest.TestCase
methods (TestMethodSetup)
% Generate a random domain
function tc = setDomain(tc)
- % random integer-sized cube domain ranging from [0, 5 -> 25]
- % in all dimensions
- L = ceil(5 + rand * 10 + rand * 10);
- tc.domain = tc.domain.initialize([zeros(1, 3); L * ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
- end
- % Generate a random sensing objective within that domain
- function tc = setSensingObjective(tc)
- % Using a bivariate normal distribution
- % Set peak position (mean)
- mu = tc.domain.minCorner;
- while tc.domain.distance(mu) < tc.protectedRange
- mu = tc.domain.random();
- end
- mu(3) = 0;
-
- % Set standard deviations of bivariate distribution
- sig = [2 + rand * 2, 1; 1, 2 + rand * 2];
-
- % Define objective
- tc.objective = tc.objective.initialize(@(x, y) mvnpdf([x(:), y(:)], mu(1:2), sig), tc.domain.footprint, tc.domain.minCorner(3), tc.objectiveDiscretizationStep);
+ % random integer-dimensioned cubic domain
+ tc.domain = tc.domain.initializeRandom(tc.minDimension, REGION_TYPE.DOMAIN, "Domain");
+ % Random bivariate normal PDF objective
+ tc.domain.objective = tc.domain.objective.initializeRandomMvnpdf(tc.domain, tc.protectedRange, tc.discretizationStep);
end
% Instantiate agents
function tc = setAgents(tc)
@@ -121,13 +108,13 @@ classdef test_miSim < matlab.unittest.TestCase
% Make sure that the obstacles don't cover the sensing
% objective
- if obstacleCoversObjective(tc.objective, tc.obstacles{ii})
+ if obstacleCoversObjective(tc.domain.objective, tc.obstacles{ii})
continue;
end
% Make sure that the obstacles aren't too close to the
% sensing objective
- if obstacleCrowdsObjective(tc.objective, tc.obstacles{ii}, tc.protectedRange)
+ if obstacleCrowdsObjective(tc.domain.objective, tc.obstacles{ii}, tc.protectedRange)
continue;
end
@@ -140,11 +127,11 @@ classdef test_miSim < matlab.unittest.TestCase
for ii = 1:size(tc.agents, 1)
initInvalid = true;
while initInvalid
- candidatePos = [tc.objective.groundPos, 0];
+ candidatePos = [tc.domain.objective.groundPos, 0];
% Generate a random position for the agent based on
% existing agent positions
if ii == 1
- while agentsCrowdObjective(tc.objective, candidatePos, mean(tc.domain.dimensions) / 2)
+ while agentsCrowdObjective(tc.domain.objective, candidatePos, mean(tc.domain.dimensions) / 2)
candidatePos = tc.domain.random();
end
else
@@ -159,7 +146,7 @@ classdef test_miSim < matlab.unittest.TestCase
% Make sure that the candidate position does not crowd
% the sensing objective and create boring scenarios
- if agentsCrowdObjective(tc.objective, candidatePos, mean(tc.domain.dimensions) / 2)
+ if agentsCrowdObjective(tc.domain.objective, candidatePos, mean(tc.domain.dimensions) / 2)
continue;
end
@@ -243,7 +230,7 @@ classdef test_miSim < matlab.unittest.TestCase
end
% Initialize the simulation
- [tc.testClass, f] = tc.testClass.initialize(tc.domain, tc.objective, tc.agents, tc.timestep, tc.partitoningFreq, tc.maxIter, tc.obstacles);
+ [tc.testClass, f] = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.timestep, tc.partitoningFreq, tc.maxIter, tc.obstacles);
end
function misim_run(tc)
% randomly create obstacles
@@ -289,13 +276,13 @@ classdef test_miSim < matlab.unittest.TestCase
% Make sure that the obstacles don't cover the sensing
% objective
- if obstacleCoversObjective(tc.objective, tc.obstacles{ii})
+ if obstacleCoversObjective(tc.domain.objective, tc.obstacles{ii})
continue;
end
% Make sure that the obstacles aren't too close to the
% sensing objective
- if obstacleCrowdsObjective(tc.objective, tc.obstacles{ii}, tc.protectedRange)
+ if obstacleCrowdsObjective(tc.domain.objective, tc.obstacles{ii}, tc.protectedRange)
continue;
end
@@ -308,11 +295,11 @@ classdef test_miSim < matlab.unittest.TestCase
for ii = 1:size(tc.agents, 1)
initInvalid = true;
while initInvalid
- candidatePos = [tc.objective.groundPos, 0];
+ candidatePos = [tc.domain.objective.groundPos, 0];
% Generate a random position for the agent based on
% existing agent positions
if ii == 1
- while agentsCrowdObjective(tc.objective, candidatePos, mean(tc.domain.dimensions) / 2)
+ while agentsCrowdObjective(tc.domain.objective, candidatePos, mean(tc.domain.dimensions) / 2)
candidatePos = tc.domain.random();
end
else
@@ -327,7 +314,7 @@ classdef test_miSim < matlab.unittest.TestCase
% Make sure that the candidate position does not crowd
% the sensing objective and create boring scenarios
- if agentsCrowdObjective(tc.objective, candidatePos, mean(tc.domain.dimensions) / 2)
+ if agentsCrowdObjective(tc.domain.objective, candidatePos, mean(tc.domain.dimensions) / 2)
continue;
end
@@ -411,7 +398,7 @@ classdef test_miSim < matlab.unittest.TestCase
end
% Initialize the simulation
- [tc.testClass, f] = tc.testClass.initialize(tc.domain, tc.objective, tc.agents, tc.timestep, tc.partitoningFreq, tc.maxIter, tc.obstacles);
+ [tc.testClass, f] = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.timestep, tc.partitoningFreq, tc.maxIter, tc.obstacles);
% Run simulation loop
[tc.testClass, f] = tc.testClass.run(f);
@@ -424,7 +411,7 @@ classdef test_miSim < matlab.unittest.TestCase
tc.domain = tc.domain.initialize([zeros(1, 3); 10 * ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
% make basic sensing objective
- tc.objective = tc.objective.initialize(@(x, y) mvnpdf([x(:), y(:)], tc.domain.center(1:2), eye(2)), tc.domain.footprint, tc.domain.minCorner(3), tc.objectiveDiscretizationStep);
+ tc.domain.objective = tc.domain.objective.initialize(@(x, y) mvnpdf([x(:), y(:)], tc.domain.center(1:2), eye(2)), tc.domain.footprint, tc.domain.minCorner(3), tc.discretizationStep);
% Initialize agent collision geometry
geometry1 = rectangularPrism;
@@ -442,7 +429,7 @@ classdef test_miSim < matlab.unittest.TestCase
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - [d, 0, 0], zeros(1,3), 0, 0, geometry2, sensor, @gradientAscent, 3*d, 2, sprintf("Agent %d", 2));
% Initialize the simulation
- [tc.testClass, f] = tc.testClass.initialize(tc.domain, tc.objective, tc.agents, tc.timestep, tc.partitoningFreq, tc.maxIter);
+ [tc.testClass, f] = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.timestep, tc.partitoningFreq, tc.maxIter);
end
end
end
\ No newline at end of file