refactored sensing objective into domain, random inits
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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]);
|
||||
|
||||
27
@sensingObjective/initializeRandomMvnpdf.m
Normal file
27
@sensingObjective/initializeRandomMvnpdf.m
Normal file
@@ -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
|
||||
@@ -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');
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
18
geometries/@rectangularPrism/initializeRandom.m
Normal file
18
geometries/@rectangularPrism/initializeRandom.m
Normal file
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info>
|
||||
<Category UUID="FileClassCategory">
|
||||
<Label UUID="design"/>
|
||||
</Category>
|
||||
</Info>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="initializeRandomMvnpdf.m" type="File"/>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info>
|
||||
<Category UUID="FileClassCategory">
|
||||
<Label UUID="design"/>
|
||||
</Category>
|
||||
</Info>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="initializeRandom.m" type="File"/>
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user