lots of cleanup and simplification in test case construction
This commit is contained in:
@@ -9,14 +9,9 @@ classdef agent
|
||||
% State
|
||||
lastPos = NaN(1, 3); % position from previous timestep
|
||||
pos = NaN(1, 3); % current position
|
||||
vel = NaN(1, 3); % current velocity
|
||||
pan = NaN; % pan angle
|
||||
tilt = NaN; % tilt angle
|
||||
|
||||
% Collision
|
||||
collisionGeometry;
|
||||
barrierFunction;
|
||||
dBarrierFunction;
|
||||
|
||||
% FOV cone
|
||||
fovGeometry;
|
||||
@@ -39,7 +34,7 @@ classdef agent
|
||||
end
|
||||
|
||||
methods (Access = public)
|
||||
[obj] = initialize(obj, pos, vel, pan, tilt, collisionGeometry, sensorModel, guidanceModel, comRange, index, label);
|
||||
[obj] = initialize(obj, pos, pan, tilt, collisionGeometry, sensorModel, guidanceModel, comRange, index, label);
|
||||
[obj] = run(obj, domain, partitioning, t, index, agents);
|
||||
[partitioning] = partition(obj, agents, objective)
|
||||
[obj, f] = plot(obj, ind, f);
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
function obj = initialize(obj, pos, vel, pan, tilt, collisionGeometry, sensorModel, comRange, maxIter, label, plotCommsGeometry)
|
||||
function obj = initialize(obj, pos, collisionGeometry, sensorModel, comRange, maxIter, label, plotCommsGeometry)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'agent')};
|
||||
pos (1, 3) double;
|
||||
vel (1, 3) double;
|
||||
pan (1, 1) double;
|
||||
tilt (1, 1) double;
|
||||
collisionGeometry (1, 1) {mustBeGeometry};
|
||||
sensorModel (1, 1) {mustBeSensor};
|
||||
comRange (1, 1) double;
|
||||
@@ -17,9 +14,6 @@ function obj = initialize(obj, pos, vel, pan, tilt, collisionGeometry, sensorMod
|
||||
end
|
||||
|
||||
obj.pos = pos;
|
||||
obj.vel = vel;
|
||||
obj.pan = pan;
|
||||
obj.tilt = tilt;
|
||||
obj.collisionGeometry = collisionGeometry;
|
||||
obj.sensorModel = sensorModel;
|
||||
obj.label = label;
|
||||
|
||||
@@ -10,7 +10,7 @@ function [partitioning] = partition(obj, agents, objective)
|
||||
|
||||
% Assess sensing performance of each agent at each sample point
|
||||
% in the domain
|
||||
agentPerformances = cellfun(@(x) reshape(x.sensorModel.sensorPerformance(x.pos, x.pan, x.tilt, [objective.X(:), objective.Y(:), zeros(size(objective.X(:)))]), size(objective.X)), agents, 'UniformOutput', false);
|
||||
agentPerformances = cellfun(@(x) reshape(x.sensorModel.sensorPerformance(x.pos, [objective.X(:), objective.Y(:), zeros(size(objective.X(:)))]), size(objective.X)), agents, 'UniformOutput', false);
|
||||
agentPerformances{end + 1} = objective.sensorPerformanceMinimum * ones(size(agentPerformances{end})); % add additional layer to represent the threshold that has to be cleared for assignment to any partiton
|
||||
agentPerformances = cat(3, agentPerformances{:});
|
||||
|
||||
|
||||
@@ -13,6 +13,10 @@ function obj = run(obj, domain, partitioning, timestepIndex, index, agents)
|
||||
|
||||
% Collect objective function values across partition
|
||||
partitionMask = partitioning == index;
|
||||
if ~unique(partitionMask)
|
||||
% This agent has no partition, maintain current state
|
||||
return;
|
||||
end
|
||||
objectiveValues = domain.objective.values(partitionMask); % f(omega) on W_n
|
||||
|
||||
% Compute sensor performance on partition
|
||||
@@ -30,7 +34,7 @@ function obj = run(obj, domain, partitioning, timestepIndex, index, agents)
|
||||
% Compute performance values on partition
|
||||
if ii < 5
|
||||
% Compute sensing performance
|
||||
sensorValues = obj.sensorModel.sensorPerformance(pos, obj.pan, obj.tilt, [maskedX, maskedY, zeros(size(maskedX))]); % S_n(omega, P_n) on W_n
|
||||
sensorValues = obj.sensorModel.sensorPerformance(pos, [maskedX, maskedY, zeros(size(maskedX))]); % S_n(omega, P_n) on W_n
|
||||
% Objective performance does not change for 0, +/- X, Y steps.
|
||||
% Those values are computed once before the loop and are only
|
||||
% recomputed when +/- Z steps are applied
|
||||
@@ -45,7 +49,7 @@ function obj = run(obj, domain, partitioning, timestepIndex, index, agents)
|
||||
% Recompute partiton-derived performance values for sensing
|
||||
maskedX = domain.objective.X(partitionMask);
|
||||
maskedY = domain.objective.Y(partitionMask);
|
||||
sensorValues = obj.sensorModel.sensorPerformance(pos, obj.pan, obj.tilt, [maskedX, maskedY, zeros(size(maskedX))]); % S_n(omega, P_n) on W_n
|
||||
sensorValues = obj.sensorModel.sensorPerformance(pos, [maskedX, maskedY, zeros(size(maskedX))]); % S_n(omega, P_n) on W_n
|
||||
end
|
||||
|
||||
% Rearrange data into image arrays
|
||||
|
||||
@@ -5,6 +5,13 @@ function updatePlots(obj)
|
||||
arguments (Output)
|
||||
end
|
||||
|
||||
% Find change in agent position since last timestep
|
||||
deltaPos = obj.pos - obj.lastPos;
|
||||
if all(isnan(deltaPos)) || all(deltaPos == zeros(1, 3))
|
||||
% Agent did not move, so nothing has to move on the plots
|
||||
return;
|
||||
end
|
||||
|
||||
% Scatterplot point positions
|
||||
for ii = 1:size(obj.scatterPoints, 1)
|
||||
obj.scatterPoints(ii).XData = obj.pos(1);
|
||||
@@ -12,9 +19,6 @@ function updatePlots(obj)
|
||||
obj.scatterPoints(ii).ZData = obj.pos(3);
|
||||
end
|
||||
|
||||
% Find change in agent position since last timestep
|
||||
deltaPos = obj.pos - obj.lastPos;
|
||||
|
||||
% Collision geometry edges
|
||||
for jj = 1:size(obj.collisionGeometry.lines, 2)
|
||||
% Update plotting
|
||||
|
||||
@@ -14,6 +14,11 @@ function [obj] = constrainMotion(obj)
|
||||
|
||||
agents = [obj.agents{:}];
|
||||
v = reshape(([agents.pos] - [agents.lastPos])./obj.timestep, 3, size(obj.agents, 1))';
|
||||
if all(isnan(v)) || all(v == zeros(1, 3))
|
||||
% Agents are not attempting to move, so there is no motion to be
|
||||
% constrained
|
||||
return;
|
||||
end
|
||||
|
||||
% Initialize QP based on number of agents and obstacles
|
||||
nAOPairs = size(obj.agents, 1) * size(obj.obstacles, 1); % unique agent/obstacle pairs
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
function obj = initialize(obj, domain, objective, agents, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo)
|
||||
function obj = initialize(obj, domain, agents, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'miSim')};
|
||||
domain (1, 1) {mustBeGeometry};
|
||||
objective (1, 1) {mustBeA(objective, 'sensingObjective')};
|
||||
agents (:, 1) cell;
|
||||
minAlt (1, 1) double = 1;
|
||||
timestep (:, 1) double = 0.05;
|
||||
@@ -44,9 +43,6 @@ function obj = initialize(obj, domain, objective, agents, minAlt, timestep, maxI
|
||||
obj.obstacles{end, 1} = obj.obstacles{end, 1}.initialize([obj.domain.minCorner; obj.domain.maxCorner(1:2), obj.minAlt], "OBSTACLE", "Minimum Altitude Domain Constraint");
|
||||
end
|
||||
|
||||
% Define objective
|
||||
obj.objective = objective;
|
||||
|
||||
% Define agents
|
||||
obj.agents = agents;
|
||||
obj.constraintAdjacencyMatrix = logical(eye(size(agents, 1)));
|
||||
@@ -76,7 +72,7 @@ function obj = initialize(obj, domain, objective, agents, minAlt, timestep, maxI
|
||||
obj.perf = [zeros(size(obj.agents, 1) + 1, 1), NaN(size(obj.agents, 1) + 1, size(obj.partitioningTimes, 1) - 1)];
|
||||
|
||||
% Prepare h function data store
|
||||
obj.h = NaN(size(obj.agents, 1) * (size(obj.agents, 1) - 1) / 2 + size(obj.agents, 1) * size(obj.obstacles, 1) + 6, size(obj.times, 1) - 1);
|
||||
obj.h = NaN(size(obj.agents, 1) * (size(obj.agents, 1) - 1) / 2 + size(obj.agents, 1) * size(obj.obstacles, 1) + 6, size(obj.times, 1));
|
||||
|
||||
% Create initial partitioning
|
||||
obj.partitioning = obj.agents{1}.partition(obj.agents, obj.domain.objective);
|
||||
|
||||
@@ -55,7 +55,7 @@ classdef miSim
|
||||
end
|
||||
|
||||
methods (Access = public)
|
||||
[obj] = initialize(obj, domain, objective, agents, timestep, partitoningFreq, maxIter, obstacles);
|
||||
[obj] = initialize(obj, domain, agents, timestep, partitoningFreq, maxIter, obstacles);
|
||||
[obj] = run(obj);
|
||||
[obj] = lesserNeighbor(obj);
|
||||
[obj] = constrainMotion(obj);
|
||||
@@ -69,6 +69,7 @@ classdef miSim
|
||||
[obj] = plotH(obj);
|
||||
[obj] = updatePlots(obj);
|
||||
validate(obj);
|
||||
teardown(obj);
|
||||
end
|
||||
methods (Access = private)
|
||||
[v] = setupVideoWriter(obj);
|
||||
|
||||
13
@miSim/teardown.m
Normal file
13
@miSim/teardown.m
Normal file
@@ -0,0 +1,13 @@
|
||||
function teardown(obj)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'miSim')};
|
||||
end
|
||||
arguments (Output)
|
||||
end
|
||||
|
||||
% Close plots
|
||||
close(obj.hf);
|
||||
close(obj.fPerf);
|
||||
close(obj.f);
|
||||
|
||||
end
|
||||
@@ -1,10 +1,8 @@
|
||||
function obj = initialize(obj, alphaDist, betaDist, alphaPan, betaPan, alphaTilt, betaTilt)
|
||||
function obj = initialize(obj, alphaDist, betaDist, alphaTilt, betaTilt)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'sigmoidSensor')}
|
||||
alphaDist (1, 1) double;
|
||||
betaDist (1, 1) double;
|
||||
alphaPan (1, 1) double;
|
||||
betaPan (1, 1) double;
|
||||
alphaTilt (1, 1) double;
|
||||
betaTilt (1, 1) double;
|
||||
end
|
||||
@@ -14,8 +12,6 @@ function obj = initialize(obj, alphaDist, betaDist, alphaPan, betaPan, alphaTilt
|
||||
|
||||
obj.alphaDist = alphaDist;
|
||||
obj.betaDist = betaDist;
|
||||
obj.alphaPan = alphaPan;
|
||||
obj.betaPan = betaPan;
|
||||
obj.alphaTilt = alphaTilt;
|
||||
obj.betaTilt = betaTilt;
|
||||
end
|
||||
@@ -1,9 +1,7 @@
|
||||
function value = sensorPerformance(obj, agentPos, agentPan, agentTilt, targetPos)
|
||||
function value = sensorPerformance(obj, agentPos, targetPos)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'sigmoidSensor')};
|
||||
agentPos (1, 3) double;
|
||||
agentPan (1, 1) double;
|
||||
agentTilt (1, 1) double;
|
||||
targetPos (:, 3) double;
|
||||
end
|
||||
arguments (Output)
|
||||
@@ -15,7 +13,7 @@ function value = sensorPerformance(obj, agentPos, agentPan, agentTilt, targetPos
|
||||
x = vecnorm(agentPos(1:2) - targetPos(:, 1:2), 2, 2); % distance from sensor nadir to target nadir (i.e. distance ignoring height difference)
|
||||
|
||||
% compute tilt angle
|
||||
tiltAngle = (180 - atan2d(x, targetPos(:, 3) - agentPos(3))) - agentTilt; % degrees
|
||||
tiltAngle = (180 - atan2d(x, targetPos(:, 3) - agentPos(3))); % degrees
|
||||
|
||||
% Membership functions
|
||||
mu_d = obj.distanceMembership(d);
|
||||
@@ -3,15 +3,12 @@ classdef sigmoidSensor
|
||||
% Sensor parameters
|
||||
alphaDist = NaN;
|
||||
betaDist = NaN;
|
||||
alphaPan = NaN;
|
||||
betaPan = NaN;
|
||||
alphaTilt = NaN; % degrees
|
||||
betaTilt = NaN;
|
||||
end
|
||||
|
||||
methods (Access = public)
|
||||
[obj] = initialize(obj, alphaDist, betaDist, alphaPan, betaPan, alphaTilt, betaTilt);
|
||||
[values, positions] = sense(obj, agent, sensingObjective, domain, partitioning);
|
||||
[obj] = initialize(obj, alphaDist, betaDist, alphaTilt, betaTilt);
|
||||
[value] = sensorPerformance(obj, agentPos, agentPan, agentTilt, targetPos);
|
||||
[f] = plotParameters(obj);
|
||||
end
|
||||
@@ -48,13 +48,4 @@ function obj = initialize(obj, bounds, tag, label, objectiveFunction, discretiza
|
||||
if tag == REGION_TYPE.DOMAIN
|
||||
obj.objective = sensingObjective;
|
||||
end
|
||||
|
||||
% Initialize CBF
|
||||
% first part evaluates to +/-1 if the point is outside/inside the collision geometry
|
||||
% Second part determines the distance from the point to the boundary of the collision geometry
|
||||
obj.barrierFunction = @(x) (1 - 2 * obj.collisionGeometry.contains(x)) * obj.collisionGeometry.distance(x); % x is 1x3
|
||||
% gradient of barrier function
|
||||
obj.dBarrierFunction = @(x) obj.collisionGeometry.distanceGradient(x); % x is 1x3
|
||||
% as long as the collisionGeometry object is updated during runtime,
|
||||
% these functions never have to be updated again
|
||||
end
|
||||
@@ -20,10 +20,6 @@ classdef rectangularPrism
|
||||
|
||||
% Plotting
|
||||
lines;
|
||||
|
||||
% collision
|
||||
barrierFunction;
|
||||
dBarrierFunction;
|
||||
end
|
||||
properties (SetAccess = public, GetAccess = public)
|
||||
label = "";
|
||||
|
||||
@@ -18,11 +18,6 @@ function obj = initialize(obj, center, radius, tag, label)
|
||||
obj.radius = radius;
|
||||
obj.diameter = 2 * obj.radius;
|
||||
|
||||
% Initialize CBF
|
||||
obj.barrierFunction = @(x) NaN;
|
||||
% gradient of barrier function
|
||||
obj.dBarrierFunction = @(x) NaN;
|
||||
|
||||
% fake vertices in a cross pattern
|
||||
obj.vertices = [obj.center + [obj.radius, 0, 0]; ...
|
||||
obj.center - [obj.radius, 0, 0]; ...
|
||||
|
||||
@@ -11,10 +11,6 @@ classdef spherical
|
||||
|
||||
% Plotting
|
||||
lines;
|
||||
|
||||
% collision
|
||||
barrierFunction;
|
||||
dBarrierFunction;
|
||||
end
|
||||
properties (SetAccess = public, GetAccess = public)
|
||||
% Meta
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="@fixedCardinalSensor" type="File"/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info/>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="objectiveFunctionWrapper.m" type="File"/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info Ref="sensorModels" Type="Relative"/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="d143c27d-6824-4569-9093-8150b60976cb" type="Reference"/>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="teardown.m" type="File"/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="partition.m" type="File"/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="sensorModels" type="File"/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="fixedCardinalSensor.m" type="File"/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="sense.m" type="File"/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="1" type="DIR_SIGNIFIER"/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="1" type="DIR_SIGNIFIER"/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="sensorPerformance.m" type="File"/>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info>
|
||||
<Category UUID="FileClassCategory">
|
||||
<Label UUID="design"/>
|
||||
</Category>
|
||||
</Info>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info>
|
||||
<Category UUID="FileClassCategory">
|
||||
<Label UUID="design"/>
|
||||
</Category>
|
||||
</Info>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info>
|
||||
<Category UUID="FileClassCategory">
|
||||
<Label UUID="design"/>
|
||||
</Category>
|
||||
</Info>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="initialize.m" type="File"/>
|
||||
@@ -1,13 +0,0 @@
|
||||
classdef fixedCardinalSensor
|
||||
% Senses in the +/-x, +/- y directions at some specified fixed length
|
||||
properties
|
||||
alphaTilt = NaN;
|
||||
r = 0.1; % fixed sensing length
|
||||
end
|
||||
|
||||
methods (Access = public)
|
||||
[obj] = initialize(obj, r);
|
||||
[neighborValues, neighborPos] = sense(obj, agent, sensingObjective, domain, partitioning);
|
||||
[value] = sensorPerformance(obj, agentPos, agentPan, agentTilt, targetPos);
|
||||
end
|
||||
end
|
||||
@@ -1,10 +0,0 @@
|
||||
function obj = initialize(obj, r)
|
||||
arguments(Input)
|
||||
obj (1, 1) {mustBeA(obj, 'fixedCardinalSensor')};
|
||||
r (1, 1) double;
|
||||
end
|
||||
arguments(Output)
|
||||
obj (1, 1) {mustBeA(obj, 'fixedCardinalSensor')};
|
||||
end
|
||||
obj.r = r;
|
||||
end
|
||||
@@ -1,45 +0,0 @@
|
||||
function [neighborValues, neighborPos] = sense(obj, agent, sensingObjective, domain, partitioning)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'fixedCardinalSensor')};
|
||||
agent (1, 1) {mustBeA(agent, 'agent')};
|
||||
sensingObjective (1, 1) {mustBeA(sensingObjective, 'sensingObjective')};
|
||||
domain (1, 1) {mustBeGeometry};
|
||||
partitioning (:, :) double = NaN;
|
||||
end
|
||||
arguments (Output)
|
||||
neighborValues (4, 1) double;
|
||||
neighborPos (4, 3) double;
|
||||
end
|
||||
|
||||
% Set alphaTilt to produce an FOV cone with radius 'r' on the ground
|
||||
obj.alphaTilt = atan2(obj.r, agent.pos(3));
|
||||
|
||||
% Evaluate objective at position offsets +/-[r, 0, 0] and +/-[0, r, 0]
|
||||
currentPos = agent.pos(1:2);
|
||||
neighborPos = [currentPos(1) + obj.r, currentPos(2); ... % (+x)
|
||||
currentPos(1), currentPos(2) + obj.r; ... % (+y)
|
||||
currentPos(1) - obj.r, currentPos(2); ... % (-x)
|
||||
currentPos(1), currentPos(2) - obj.r; ... % (-y)
|
||||
];
|
||||
|
||||
% Check for neighbor positions that fall outside of the domain
|
||||
outOfBounds = false(size(neighborPos, 1), 1);
|
||||
for ii = 1:size(neighborPos, 1)
|
||||
if ~domain.contains([neighborPos(ii, :), 0])
|
||||
outOfBounds(ii) = true;
|
||||
end
|
||||
end
|
||||
|
||||
% Replace out of bounds positions with inoffensive in-bounds positions
|
||||
neighborPos(outOfBounds, 1:3) = repmat(agent.pos, sum(outOfBounds), 1);
|
||||
|
||||
% Sense values at selected positions
|
||||
neighborValues = [sensingObjective.objectiveFunction(neighborPos(1, 1), neighborPos(1, 2)), ... % (+x)
|
||||
sensingObjective.objectiveFunction(neighborPos(2, 1), neighborPos(2, 2)), ... % (+y)
|
||||
sensingObjective.objectiveFunction(neighborPos(3, 1), neighborPos(3, 2)), ... % (-x)
|
||||
sensingObjective.objectiveFunction(neighborPos(4, 1), neighborPos(4, 2)), ... % (-y)
|
||||
];
|
||||
|
||||
% Prevent out of bounds locations from ever possibly being selected
|
||||
neighborValues(outOfBounds) = 0;
|
||||
end
|
||||
@@ -1,14 +0,0 @@
|
||||
function value = sensorPerformance(obj, agentPos, agentPan, agentTilt, targetPos)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'fixedCardinalSensor')};
|
||||
agentPos (1, 3) double;
|
||||
agentPan (1, 1) double;
|
||||
agentTilt (1, 1) double;
|
||||
targetPos (:, 3) double;
|
||||
end
|
||||
arguments (Output)
|
||||
value (:, 1) double;
|
||||
end
|
||||
|
||||
value = 0.5 * ones(size(targetPos, 1), 1);
|
||||
end
|
||||
@@ -3,7 +3,6 @@ classdef parametricTestSuite < matlab.unittest.TestCase
|
||||
% System under test
|
||||
testClass = miSim;
|
||||
domain = rectangularPrism;
|
||||
objective = sensingObjective;
|
||||
obstacles = cell(1, 0);
|
||||
|
||||
%% Diagnostic Parameters
|
||||
@@ -16,33 +15,52 @@ classdef parametricTestSuite < matlab.unittest.TestCase
|
||||
end
|
||||
properties (TestParameter)
|
||||
%% Simulation Parameters
|
||||
maxIter = num2cell([200, 400]); % number of timesteps to run
|
||||
maxIter = num2cell([25]); % number of timesteps to run
|
||||
|
||||
% Domain parameters
|
||||
minAlt = num2cell([1, 3]); % minimum allowed agent altitude, make sure test cases don't conflict with this
|
||||
minAlt = num2cell([1]); % minimum allowed agent altitude, make sure test cases don't conflict with this
|
||||
|
||||
% Sensing Objective Parameters
|
||||
discretizationStep = num2cell([0.01, 0.05]);
|
||||
discretizationStep = num2cell([0.01]);
|
||||
|
||||
% Agent Parameters
|
||||
collisionRange = num2cell([0.1, 0.5]);
|
||||
collisionRadius = num2cell([0.1]);
|
||||
|
||||
% Sensor Model Parameters
|
||||
betaDist = num2cell(3:6:15);
|
||||
betaTilt = num2cell(3:6:15);
|
||||
alphaDist = num2cell([2.5, 5]);
|
||||
alphaTilt = num2cell([15, 30]); % (degrees)
|
||||
betaDist = num2cell([3, 15]);
|
||||
alphaTilt = num2cell([15, 30]); % (degrees)methods
|
||||
betaTilt = num2cell([3, 15]);
|
||||
|
||||
% Communications Parameters
|
||||
comRange = num2cell(1:2:5);
|
||||
comRange = num2cell([3]);
|
||||
end
|
||||
|
||||
methods (Test, ParameterCombination = "exhaustive")
|
||||
% Test methods
|
||||
% Test cases
|
||||
function single_agent_gradient_ascent(tc, maxIter, minAlt, discretizationStep, collisionRadius, alphaDist, betaDist, alphaTilt, betaTilt, comRange)
|
||||
% Set up square domain
|
||||
l = 10;
|
||||
tc.domain = tc.domain.initialize([zeros(1, 3); l * ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([.75 * l, 0.75 * l]), tc.domain, discretizationStep, tc.protectedRange);
|
||||
|
||||
function single_agent_gradient_ascent(tc, maxIter, minAlt, discretizationStep, collisionRange, alphaDist, alphaTilt, betaDist, betaTilt, comRange)
|
||||
1;
|
||||
% Set up agent
|
||||
sensorModel = sigmoidSensor;
|
||||
sensorModel = sensorModel.initialize(alphaDist, betaDist, alphaTilt, betaTilt);
|
||||
agentPos = [l/4, l/4, 3*l/4];
|
||||
collisionGeometry = spherical;
|
||||
collisionGeometry = collisionGeometry.initialize(agentPos, collisionRadius, REGION_TYPE.COLLISION, "Agent 1 Collision Region");
|
||||
agents = {agent};
|
||||
agents{1} = agents{1}.initialize(agentPos, collisionGeometry, sensorModel, comRange, maxIter, "Agent 1", tc.plotCommsGeometry);
|
||||
|
||||
% Set up simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, agents, minAlt, tc.timestep, maxIter, tc.obstacles, tc.makePlots, tc.makeVideo);
|
||||
|
||||
% Run
|
||||
tc.testClass = tc.testClass.run();
|
||||
|
||||
% Cleanup
|
||||
tc.testClass.teardown();
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -157,10 +157,10 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
|
||||
% Initialize candidate agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
sensor = sensor.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), NaN, NaN, tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
||||
sensor = sensor.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
||||
|
||||
% Initialize candidate agent
|
||||
newAgent = tc.agents{ii}.initialize(candidatePos, zeros(1,3), 0, 0, candidateGeometry, sensor, tc.comRange, tc.maxIter);
|
||||
newAgent = tc.agents{ii}.initialize(candidatePos, candidateGeometry, sensor, tc.comRange, tc.maxIter);
|
||||
|
||||
% Make sure candidate agent doesn't collide with
|
||||
% domain
|
||||
@@ -208,7 +208,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
end
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makeVideo);
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makeVideo);
|
||||
end
|
||||
function misim_run(tc)
|
||||
% randomly create obstacles
|
||||
@@ -291,10 +291,10 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
|
||||
% Initialize candidate agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
sensor = sensor.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), NaN, NaN, tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
||||
sensor = sensor.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
||||
|
||||
% Initialize candidate agent
|
||||
newAgent = tc.agents{ii}.initialize(candidatePos, zeros(1,3), 0, 0, candidateGeometry, sensor, tc.comRange, tc.maxIter);
|
||||
newAgent = tc.agents{ii}.initialize(candidatePos, candidateGeometry, sensor, tc.comRange, tc.maxIter);
|
||||
|
||||
% Make sure candidate agent doesn't collide with
|
||||
% domain
|
||||
@@ -342,7 +342,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
end
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makeVideo);
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makeVideo);
|
||||
|
||||
% Run simulation loop
|
||||
tc.testClass = tc.testClass.run();
|
||||
@@ -367,26 +367,26 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
% Initialize agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
% Homogeneous sensor model parameters
|
||||
sensor = sensor.initialize(2.75, 9, NaN, NaN, 22.5, 9);
|
||||
sensor = sensor.initialize(2.75, 9, 22.5, 9);
|
||||
% Heterogeneous sensor model parameters
|
||||
% sensor = sensor.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), NaN, NaN, tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
||||
% sensor = sensor.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
||||
|
||||
% Plot sensor parameters (optional)
|
||||
% f = sensor.plotParameters();
|
||||
|
||||
% Initialize agents
|
||||
tc.agents = {agent; agent};
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + dh + [d, 0, 0], zeros(1,3), 0, 0, geometry1, sensor, 3*d, tc.maxIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center + dh - [d, 0, 0], zeros(1,3), 0, 0, geometry2, sensor, 3*d, tc.maxIter);
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + dh + [d, 0, 0], geometry1, sensor, 3*d, tc.maxIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center + dh - [d, 0, 0], geometry2, sensor, 3*d, tc.maxIter);
|
||||
|
||||
% Optional third agent along the +Y axis
|
||||
geometry3 = rectangularPrism;
|
||||
geometry3 = geometry3.initialize([tc.domain.center + dh - [0, d, 0] - tc.collisionRanges(1) * ones(1, 3); tc.domain.center + dh - [0, d, 0] + tc.collisionRanges(1) * ones(1, 3)], REGION_TYPE.COLLISION);
|
||||
tc.agents{3} = agent;
|
||||
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center + dh - [0, d, 0], zeros(1, 3), 0, 0, geometry3, sensor, 3*d, tc.maxIter);
|
||||
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center + dh - [0, d, 0], geometry3, sensor, 3*d, tc.maxIter);
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.minAlt, tc.timestep, tc.maxIter, cell(0, 1), false, false);
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.minAlt, tc.timestep, tc.maxIter, cell(0, 1), false, false);
|
||||
|
||||
tc.verifyEqual(tc.testClass.partitioning(500, 500:502), [2, 3, 1]); % all three near center
|
||||
tc.verifyLessThan(sum(tc.testClass.partitioning == 1, 'all'), sum(tc.testClass.partitioning == 0, 'all')); % more non-assignments than partition 1 assignments
|
||||
@@ -409,19 +409,19 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
% Initialize agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
% Homogeneous sensor model parameters
|
||||
% sensor = sensor.initialize(2.5666, 5.0807, NaN, NaN, 20.8614, 13); % 13
|
||||
% sensor = sensor.initialize(2.5666, 5.0807, 20.8614, 13); % 13
|
||||
alphaDist = l/2; % half of domain length/width
|
||||
sensor = sensor.initialize(alphaDist, 3, NaN, NaN, 20, 3);
|
||||
sensor = sensor.initialize(alphaDist, 3, 20, 3);
|
||||
|
||||
% Plot sensor parameters (optional)
|
||||
% f = sensor.plotParameters();
|
||||
|
||||
% Initialize agents
|
||||
tc.agents = {agent};
|
||||
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2), 3], zeros(1,3), 0, 0, geometry1, sensor, 3, tc.maxIter);
|
||||
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2), 3], geometry1, sensor, 3, tc.maxIter);
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.minAlt, tc.timestep, tc.maxIter, cell(0, 1), false, false);
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.minAlt, tc.timestep, tc.maxIter, cell(0, 1), false, false);
|
||||
close(tc.testClass.fPerf);
|
||||
|
||||
tc.verifyEqual(unique(tc.testClass.partitioning), [0; 1]);
|
||||
@@ -442,9 +442,9 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
% Initialize agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
% Homogeneous sensor model parameters
|
||||
% sensor = sensor.initialize(2.5666, 5.0807, NaN, NaN, 20.8614, 13); % 13
|
||||
% sensor = sensor.initialize(2.5666, 5.0807, 20.8614, 13); % 13
|
||||
alphaDist = l/2; % half of domain length/width
|
||||
sensor = sensor.initialize(alphaDist, 3, NaN, NaN, 20, 3);
|
||||
sensor = sensor.initialize(alphaDist, 3, 20, 3);
|
||||
|
||||
% Plot sensor parameters (optional)
|
||||
% f = sensor.plotParameters();
|
||||
@@ -452,10 +452,10 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
% Initialize agents
|
||||
nIter = 100;
|
||||
tc.agents = {agent};
|
||||
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], zeros(1,3), 0, 0, geometry1, sensor, 3, nIter);
|
||||
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], geometry1, sensor, 3, nIter);
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.minAlt, tc.timestep, nIter, cell(0, 1));
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.minAlt, tc.timestep, nIter, cell(0, 1));
|
||||
|
||||
% Run the simulation
|
||||
tc.testClass = tc.testClass.run();
|
||||
@@ -484,18 +484,18 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
% Initialize agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
% Homogeneous sensor model parameters
|
||||
% sensor = sensor.initialize(2.5666, 5.0807, NaN, NaN, 20.8614, 13); % 13
|
||||
% sensor = sensor.initialize(2.5666, 5.0807, 20.8614, 13); % 13
|
||||
alphaDist = l/2; % half of domain length/width
|
||||
sensor = sensor.initialize(alphaDist, 3, NaN, NaN, 15, 3);
|
||||
sensor = sensor.initialize(alphaDist, 3, 15, 3);
|
||||
|
||||
% Initialize agents
|
||||
nIter = 50;
|
||||
tc.agents = {agent; agent};
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + d, zeros(1,3), 0, 0, geometry1, sensor, 5, nIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - d, zeros(1,3), 0, 0, geometry2, sensor, 5, nIter);
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + d, geometry1, sensor, 5, nIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - d, geometry2, sensor, 5, nIter);
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.minAlt, tc.timestep, nIter, cell(0, 1), tc.makeVideo, tc.makePlots);
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.minAlt, tc.timestep, nIter, cell(0, 1), tc.makeVideo, tc.makePlots);
|
||||
|
||||
% Run the simulation
|
||||
tc.testClass.run();
|
||||
@@ -529,7 +529,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
% Initialize agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
alphaDist = l/2; % half of domain length/width
|
||||
sensor = sensor.initialize(alphaDist, 3, NaN, NaN, 15, 3);
|
||||
sensor = sensor.initialize(alphaDist, 3, 15, 3);
|
||||
|
||||
% Initialize obstacles
|
||||
obstacleLength = 1;
|
||||
@@ -539,11 +539,10 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
% Initialize agents
|
||||
commsRadius = (2*radius + obstacleLength) * 0.9; % defined such that they cannot go around the obstacle on both sides
|
||||
tc.agents = {agent; agent;};
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center - d + [0, radius * 1.1 - yOffset, 0], zeros(1,3), 0, 0, geometry1, sensor, commsRadius, tc.maxIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - d - [0, radius *1.1 + yOffset, 0], zeros(1,3), 0, 0, geometry2, sensor, commsRadius, tc.maxIter);
|
||||
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center - d + [0, radius * 1.1 - yOffset, 0], geometry1, sensor, commsRadius, tc.maxIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - d - [0, radius *1.1 + yOffset, 0], geometry2, sensor, commsRadius, tc.maxIter);
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makeVideo);
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makeVideo);
|
||||
|
||||
% Run the simulation
|
||||
tc.testClass.run();
|
||||
@@ -571,7 +570,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
% Initialize agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
alphaDist = l/2; % half of domain length/width
|
||||
sensor = sensor.initialize(alphaDist, 3, NaN, NaN, 15, 3);
|
||||
sensor = sensor.initialize(alphaDist, 3, 15, 3);
|
||||
|
||||
% Initialize obstacles
|
||||
tc.obstacles = {};
|
||||
@@ -580,11 +579,11 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
nIter = 75;
|
||||
commsRadius = 4; % defined such that they cannot reach their objective without breaking connectivity
|
||||
tc.agents = {agent; agent;};
|
||||
tc.agents{1} = tc.agents{1}.initialize(dom.center + d, zeros(1,3), 0, 0, geometry1, sensor, commsRadius, nIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(dom.center - d, zeros(1,3), 0, 0, geometry2, sensor, commsRadius, nIter);
|
||||
tc.agents{1} = tc.agents{1}.initialize(dom.center + d, geometry1, sensor, commsRadius, nIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(dom.center - d, geometry2, sensor, commsRadius, nIter);
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(dom, dom.objective, tc.agents, tc.minAlt, tc.timestep, nIter, tc.obstacles, true, false);
|
||||
tc.testClass = tc.testClass.initialize(dom, tc.agents, tc.minAlt, tc.timestep, nIter, tc.obstacles, true, false);
|
||||
|
||||
% Run the simulation
|
||||
tc.testClass = tc.testClass.run();
|
||||
@@ -611,14 +610,14 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
% Initialize agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
alphaDist = l/2; % half of domain length/width
|
||||
sensor = sensor.initialize(alphaDist, 3, NaN, NaN, 15, 3);
|
||||
sensor = sensor.initialize(alphaDist, 3, 15, 3);
|
||||
|
||||
% Initialize agents
|
||||
nIter = 125;
|
||||
commsRadius = 5;
|
||||
tc.agents = {agent; agent;};
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center - [d, 0, 0], zeros(1,3), 0, 0, geometry1, sensor, commsRadius, nIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - [0, d, 0], zeros(1,3), 0, 0, geometry2, sensor, commsRadius, nIter);
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center - [d, 0, 0], geometry1, sensor, commsRadius, nIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - [0, d, 0], geometry2, sensor, commsRadius, nIter);
|
||||
|
||||
% Initialize obstacles
|
||||
obstacleLength = 1.5;
|
||||
@@ -626,7 +625,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
tc.obstacles{1} = tc.obstacles{1}.initialize([tc.domain.center(1:2) - obstacleLength, 0; tc.domain.center(1:2) + obstacleLength, tc.domain.maxCorner(3)], REGION_TYPE.OBSTACLE, "Obstacle 1");
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, 0, tc.timestep, nIter, tc.obstacles, false, false);
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, 0, tc.timestep, nIter, tc.obstacles, false, false);
|
||||
|
||||
% No communications link should be established
|
||||
tc.assertEqual(tc.testClass.adjacency, logical(true(2)));
|
||||
@@ -657,20 +656,20 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
% Initialize agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
alphaDist = l/2; % half of domain length/width
|
||||
sensor = sensor.initialize(alphaDist, 3, NaN, NaN, 15, 3);
|
||||
sensor = sensor.initialize(alphaDist, 3, 15, 3);
|
||||
|
||||
% Initialize agents
|
||||
nIter = 125;
|
||||
commsRadius = d;
|
||||
tc.agents = {agent; agent; agent; agent; agent;};
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + [d, 0, 0], zeros(1,3), 0, 0, geometry1, sensor, commsRadius, nIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center, zeros(1,3), 0, 0, geometry2, sensor, commsRadius, nIter);
|
||||
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center + [-d, d, 0], zeros(1,3), 0, 0, geometry3, sensor, commsRadius, nIter);
|
||||
tc.agents{4} = tc.agents{4}.initialize(tc.domain.center + [-2*d, d, 0], zeros(1,3), 0, 0, geometry4, sensor, commsRadius, nIter);
|
||||
tc.agents{5} = tc.agents{5}.initialize(tc.domain.center + [0, d, 0], zeros(1,3), 0, 0, geometry5, sensor, commsRadius, nIter);
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + [d, 0, 0], geometry1, sensor, commsRadius, nIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center, 0, 0, geometry2, sensor, commsRadius, nIter);
|
||||
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center + [-d, d, 0], geometry3, sensor, commsRadius, nIter);
|
||||
tc.agents{4} = tc.agents{4}.initialize(tc.domain.center + [-2*d, d, 0], geometry4, sensor, commsRadius, nIter);
|
||||
tc.agents{5} = tc.agents{5}.initialize(tc.domain.center + [0, d, 0], geometry5, sensor, commsRadius, nIter);
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, 0, tc.timestep, nIter, tc.obstacles, false, false);
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, 0, tc.timestep, nIter, tc.obstacles, false, false);
|
||||
|
||||
% Constraint adjacency matrix defined by LNA should be as follows
|
||||
tc.assertEqual(tc.testClass.constraintAdjacencyMatrix, logical( ...
|
||||
@@ -708,22 +707,22 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
% Initialize agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
alphaDist = l/2; % half of domain length/width
|
||||
sensor = sensor.initialize(alphaDist, 3, NaN, NaN, 15, 3);
|
||||
sensor = sensor.initialize(alphaDist, 3, 15, 3);
|
||||
|
||||
% Initialize agents
|
||||
nIter = 125;
|
||||
commsRadius = d;
|
||||
tc.agents = {agent; agent; agent; agent; agent; agent; agent;};
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + [-0.9 * d/sqrt(2), 0.9 * d/sqrt(2), 0], zeros(1,3), 0, 0, geometry1, sensor, commsRadius, nIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center + [-0.5 * d, 0.25 * d, 0], zeros(1,3), 0, 0, geometry2, sensor, commsRadius, nIter);
|
||||
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center + [0.9 * d, 0, 0], zeros(1,3), 0, 0, geometry3, sensor, commsRadius, nIter);
|
||||
tc.agents{4} = tc.agents{4}.initialize(tc.domain.center + [0.9 * d/sqrt(2), -0.9 * d/sqrt(2), 0], zeros(1,3), 0, 0, geometry4, sensor, commsRadius, nIter);
|
||||
tc.agents{5} = tc.agents{5}.initialize(tc.domain.center + [0, 0.9 * d, 0], zeros(1,3), 0, 0, geometry5, sensor, commsRadius, nIter);
|
||||
tc.agents{6} = tc.agents{6}.initialize(tc.domain.center, zeros(1,3), 0, 0, geometry6, sensor, commsRadius, nIter);
|
||||
tc.agents{7} = tc.agents{7}.initialize(tc.domain.center + [d/2, d/2, 0], zeros(1,3), 0, 0, geometry7, sensor, commsRadius, nIter);
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + [-0.9 * d/sqrt(2), 0.9 * d/sqrt(2), 0], geometry1, sensor, commsRadius, nIter);
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center + [-0.5 * d, 0.25 * d, 0], geometry2, sensor, commsRadius, nIter);
|
||||
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center + [0.9 * d, 0, 0], geometry3, sensor, commsRadius, nIter);
|
||||
tc.agents{4} = tc.agents{4}.initialize(tc.domain.center + [0.9 * d/sqrt(2), -0.9 * d/sqrt(2), 0], geometry4, sensor, commsRadius, nIter);
|
||||
tc.agents{5} = tc.agents{5}.initialize(tc.domain.center + [0, 0.9 * d, 0], geometry5, sensor, commsRadius, nIter);
|
||||
tc.agents{6} = tc.agents{6}.initialize(tc.domain.center, geometry6, sensor, commsRadius, nIter);
|
||||
tc.agents{7} = tc.agents{7}.initialize(tc.domain.center + [d/2, d/2, 0], geometry7, sensor, commsRadius, nIter);
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, 0, tc.timestep, nIter, tc.obstacles, false, false);
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, 0, tc.timestep, nIter, tc.obstacles, false, false);
|
||||
|
||||
% Constraint adjacency matrix defined by LNA should be as follows
|
||||
tc.assertEqual(tc.testClass.constraintAdjacencyMatrix, logical( ...
|
||||
|
||||
@@ -21,7 +21,7 @@ classdef test_sigmoidSensor < matlab.unittest.TestCase
|
||||
function tc = setup(tc)
|
||||
% Reinitialize sensor with random parameters
|
||||
tc.testClass = sigmoidSensor;
|
||||
tc.testClass = tc.testClass.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), NaN, NaN, tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
||||
tc.testClass = tc.testClass.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
||||
end
|
||||
end
|
||||
|
||||
@@ -34,28 +34,28 @@ classdef test_sigmoidSensor < matlab.unittest.TestCase
|
||||
alphaTilt = 15; % degrees
|
||||
betaTilt = 3;
|
||||
h = 1e-6;
|
||||
tc.testClass = tc.testClass.initialize(alphaDist, betaDist, NaN, NaN, alphaTilt, betaTilt);
|
||||
tc.testClass = tc.testClass.initialize(alphaDist, betaDist, alphaTilt, betaTilt);
|
||||
|
||||
% Plot (optional)
|
||||
% tc.testClass.plotParameters();
|
||||
|
||||
% Anticipate perfect performance for a point directly below and
|
||||
% extremely close
|
||||
tc.verifyEqual(tc.testClass.sensorPerformance([0, 0, h], NaN, 0, [0, 0, 0]), 1, 'RelTol', 1e-3);
|
||||
tc.verifyEqual(tc.testClass.sensorPerformance([0, 0, h], 0, [0, 0, 0]), 1, 'RelTol', 1e-3);
|
||||
% It looks like mu_t can max out at really low values like 0.37
|
||||
% when alphaTilt and betaTilt are small, which seems wrong
|
||||
|
||||
% Performance at nadir point, distance alphaDist should be 1/2 exactly
|
||||
tc.verifyEqual(tc.testClass.sensorPerformance([0, 0, alphaDist], NaN, 0, [0, 0, 0]), 1/2);
|
||||
tc.verifyEqual(tc.testClass.sensorPerformance([0, 0, alphaDist], 0, [0, 0, 0]), 1/2);
|
||||
|
||||
% Performance at (almost) 0 distance, alphaTilt should be 1/2
|
||||
tc.verifyEqual(tc.testClass.sensorPerformance([0, 0, h], NaN, 0, [tand(alphaTilt)*h, 0, 0]), 1/2, 'RelTol', 1e-3);
|
||||
tc.verifyEqual(tc.testClass.sensorPerformance([0, 0, h], 0, [tand(alphaTilt)*h, 0, 0]), 1/2, 'RelTol', 1e-3);
|
||||
|
||||
% Performance at great distance should be 0
|
||||
tc.verifyEqual(tc.testClass.sensorPerformance([0, 0, 10], NaN, 0, [0, 0, 0]), 0, 'AbsTol', 1e-9);
|
||||
tc.verifyEqual(tc.testClass.sensorPerformance([0, 0, 10], 0, [0, 0, 0]), 0, 'AbsTol', 1e-9);
|
||||
|
||||
% Performance at great tilt should be 0
|
||||
tc.verifyEqual(tc.testClass.sensorPerformance([0, 0, h], NaN, 0, [5, 5, 0]), 0, 'AbsTol', 1e-9);
|
||||
tc.verifyEqual(tc.testClass.sensorPerformance([0, 0, h], 0, [5, 5, 0]), 0, 'AbsTol', 1e-9);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
13
util/objectiveFunctionWrapper.m
Normal file
13
util/objectiveFunctionWrapper.m
Normal file
@@ -0,0 +1,13 @@
|
||||
function f = objectiveFunctionWrapper(center)
|
||||
% Convenience function to generate MVNPDFs at a point
|
||||
% Makes it look a lot neater to instantiate and sum these to make
|
||||
% composite objectives in particular
|
||||
arguments (Input)
|
||||
center (1, 2) double;
|
||||
end
|
||||
arguments (Output)
|
||||
f (1, 1) {mustBeA(f, 'function_handle')};
|
||||
end
|
||||
|
||||
f = @(x, y) mvnpdf([x(:), y(:)], center);
|
||||
end
|
||||
Reference in New Issue
Block a user