Compare commits
2
Commits
main
...
f7b28cdf4f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7b28cdf4f | ||
|
|
66bbfe52ca |
No files matched your search
@@ -45,3 +45,6 @@ sandbox/*
|
||||
# Videos
|
||||
*.mp4
|
||||
*.avi
|
||||
|
||||
# Figures
|
||||
*.fig
|
||||
+1
-1
@@ -29,5 +29,5 @@ function obj = initialize(obj, pos, vel, pan, tilt, collisionGeometry, sensorMod
|
||||
|
||||
% Initialize FOV cone
|
||||
obj.fovGeometry = cone;
|
||||
obj.fovGeometry = obj.fovGeometry.initialize([obj.pos(1:2), 0], tan(obj.sensorModel.alphaTilt) * obj.pos(3), obj.pos(3), REGION_TYPE.FOV, sprintf("%s FOV", obj.label));
|
||||
obj.fovGeometry = obj.fovGeometry.initialize([obj.pos(1:2), 0], tand(obj.sensorModel.alphaTilt) * obj.pos(3), obj.pos(3), REGION_TYPE.FOV, sprintf("%s FOV", obj.label));
|
||||
end
|
||||
+9
-4
@@ -20,15 +20,20 @@ function obj = partition(obj)
|
||||
agentInds{end + 1} = zeros(size(agentInds{end})); % index for no assignment
|
||||
agentInds = cat(3, agentInds{:});
|
||||
|
||||
% Get highest performing agent's index
|
||||
[m,n,~] = size(agentInds);
|
||||
[jj,kk] = ndgrid(1:m, 1:n);
|
||||
% Use highest performing agent's index to form partitions
|
||||
[m, n, ~] = size(agentInds);
|
||||
[jj, kk] = ndgrid(1:m, 1:n);
|
||||
obj.partitioning = agentInds(sub2ind(size(agentInds), jj, kk, idx));
|
||||
|
||||
% Get individual agent sensor performance
|
||||
nowIdx = [0; obj.partitioningTimes] == obj.t;
|
||||
if isnan(obj.t)
|
||||
nowIdx = 1;
|
||||
end
|
||||
for ii = 1:size(obj.agents, 1)
|
||||
obj.perf(ii, nowIdx) = sum(agentPerformances(sub2ind(size(agentInds), jj, kk, ii)), 'all');
|
||||
idx = obj.partitioning == ii;
|
||||
agentPerformance = squeeze(agentPerformances(:, :, ii));
|
||||
obj.perf(ii, nowIdx) = sum(agentPerformance(idx) .* obj.objective.values(idx));
|
||||
end
|
||||
|
||||
% Current total performance
|
||||
|
||||
@@ -29,8 +29,11 @@ function obj = initialize(obj, objectiveFunction, domain, discretizationStep, pr
|
||||
obj.objectiveFunction = objectiveFunction;
|
||||
obj.values = reshape(obj.objectiveFunction(obj.X, obj.Y), size(obj.X));
|
||||
|
||||
% Normalize
|
||||
obj.values = obj.values ./ max(obj.values, [], "all");
|
||||
|
||||
% store ground position
|
||||
idx = obj.values == max(obj.values, [], "all");
|
||||
idx = obj.values == 1;
|
||||
obj.groundPos = [obj.X(idx), obj.Y(idx)];
|
||||
|
||||
assert(domain.distance([obj.groundPos, domain.center(3)]) > protectedRange, "Domain is crowding the sensing objective")
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info Ref="sensingModels" Type="Relative"/>
|
||||
@@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="420d04e4-3880-4a45-8609-11cb30d87302" type="Reference"/>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info Ref="sensorModels" Type="Relative"/>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Info location="d143c27d-6824-4569-9093-8150b60976cb" type="Reference"/>
|
||||
File renamed without changes.
@@ -0,0 +1,2 @@
|
||||
<?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="sensingModels" type="File"/>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-1
@@ -12,7 +12,7 @@ function f = plotParameters(obj)
|
||||
|
||||
% Sample membership functions
|
||||
d_x = obj.distanceMembership(d);
|
||||
t_x = obj.tiltMembership(deg2rad(t));
|
||||
t_x = obj.tiltMembership(t);
|
||||
|
||||
% Plot resultant sigmoid curves
|
||||
f = figure;
|
||||
File renamed without changes.
+1
-1
@@ -12,7 +12,7 @@ function value = sensorPerformance(obj, agentPos, agentPan, agentTilt, targetPos
|
||||
|
||||
d = vecnorm(agentPos - targetPos, 2, 2); % distance from sensor to target
|
||||
x = vecnorm(agentPos(1:2) - targetPos(:, 1:2), 2, 2); % distance from sensor nadir to target nadir (i.e. distance ignoring height difference)
|
||||
tiltAngle = atan2(targetPos(:, 3) - agentPos(3), x) - agentTilt;
|
||||
tiltAngle = (180 - atan2d(x, targetPos(:, 3) - agentPos(3))) - agentTilt; % degrees
|
||||
|
||||
% Membership functions
|
||||
mu_d = obj.distanceMembership(d);
|
||||
+1
-1
@@ -5,7 +5,7 @@ classdef sigmoidSensor
|
||||
betaDist = NaN;
|
||||
alphaPan = NaN;
|
||||
betaPan = NaN;
|
||||
alphaTilt = NaN;
|
||||
alphaTilt = NaN; % degrees
|
||||
betaTilt = NaN;
|
||||
end
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
function x = tiltMembership(obj, t)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'sigmoidSensor')};
|
||||
t (:, 1) double;
|
||||
t (:, 1) double; % degrees
|
||||
end
|
||||
arguments (Output)
|
||||
x (:, 1) double;
|
||||
+21
-16
@@ -25,8 +25,8 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
objective = sensingObjective;
|
||||
|
||||
% Agents
|
||||
minAgents = 3; % Minimum number of agents to be randomly generated
|
||||
maxAgents = 6; % Maximum number of agents to be randomly generated
|
||||
minAgents = 2; % Minimum number of agents to be randomly generated
|
||||
maxAgents = 4; % Maximum number of agents to be randomly generated
|
||||
sensingLength = 0.05; % length parameter used by sensing function
|
||||
agents = cell(0, 1);
|
||||
|
||||
@@ -42,11 +42,11 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
betaTiltMax = 15;
|
||||
alphaDistMin = 2.5;
|
||||
alphaDistMax = 3;
|
||||
alphaTiltMin = deg2rad(15);
|
||||
alphaTiltMax = deg2rad(30);
|
||||
alphaTiltMin = 15; % degrees
|
||||
alphaTiltMax = 30; % degrees
|
||||
|
||||
% Communications
|
||||
comRange = 5; % Maximum range between agents that forms a communications link
|
||||
comRange = 8; % Maximum range between agents that forms a communications link
|
||||
end
|
||||
|
||||
% Setup for each test
|
||||
@@ -104,7 +104,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
if ii == 1
|
||||
while agentsCrowdObjective(tc.domain.objective, candidatePos, mean(tc.domain.dimensions) / 2)
|
||||
candidatePos = tc.domain.random();
|
||||
candidatePos(3) = min([tc.domain.maxCorner(3) * 0.95, 0.5 + rand * (tc.alphaDistMax * (1.1) - 0.5)]); % place agents at decent altitudes for sensing
|
||||
candidatePos(3) = 2 + rand * 2; % place agents at decent altitudes for sensing
|
||||
end
|
||||
else
|
||||
candidatePos = tc.agents{randi(ii - 1)}.pos + sign(randn([1, 3])) .* (rand(1, 3) .* tc.comRange/sqrt(2));
|
||||
@@ -349,36 +349,38 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
tc.domain.objective = tc.domain.objective.initialize(@(x, y) mvnpdf([x(:), y(:)], tc.domain.center(1:2)), tc.domain, tc.discretizationStep, tc.protectedRange);
|
||||
|
||||
% Initialize agent collision geometry
|
||||
dh = [0,0,-1]; % bias agent altitude from domain center
|
||||
geometry1 = rectangularPrism;
|
||||
geometry2 = geometry1;
|
||||
geometry1 = geometry1.initialize([tc.domain.center + [d, 0, 0] - tc.collisionRanges(1) * ones(1, 3); tc.domain.center + [d, 0, 0] + tc.collisionRanges(1) * ones(1, 3)], REGION_TYPE.COLLISION, sprintf("Agent %d collision volume", 1));
|
||||
geometry2 = geometry2.initialize([tc.domain.center - [d, 0, 0] - tc.collisionRanges(1) * ones(1, 3); tc.domain.center - [d, 0, 0] + tc.collisionRanges(1) * ones(1, 3)], REGION_TYPE.COLLISION, sprintf("Agent %d collision volume", 2));
|
||||
geometry1 = geometry1.initialize([tc.domain.center + dh + [d, 0, 0] - tc.collisionRanges(1) * ones(1, 3); tc.domain.center + dh + [d, 0, 0] + tc.collisionRanges(1) * ones(1, 3)], REGION_TYPE.COLLISION, sprintf("Agent %d collision volume", 1));
|
||||
geometry2 = geometry2.initialize([tc.domain.center + dh - [d, 0, 0] - tc.collisionRanges(1) * ones(1, 3); tc.domain.center + dh - [d, 0, 0] + tc.collisionRanges(1) * ones(1, 3)], REGION_TYPE.COLLISION, sprintf("Agent %d collision volume", 2));
|
||||
|
||||
% Initialize agent sensor model
|
||||
sensor = sigmoidSensor;
|
||||
% Homogeneous sensor model parameters
|
||||
sensor = sensor.initialize(2.5, 3, NaN, NaN, deg2rad(15), 3);
|
||||
sensor = sensor.initialize(2.75, 9, NaN, NaN, 22.5, 9);
|
||||
f = sensor.plotParameters();
|
||||
% 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));
|
||||
|
||||
% Initialize agents
|
||||
tc.agents = {agent; agent};
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + [d, 0, 0], zeros(1,3), 0, 0, geometry1, sensor, @gradientAscent, 3*d, 1, sprintf("Agent %d", 1));
|
||||
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));
|
||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + dh + [d, 0, 0], zeros(1,3), 0, 0, geometry1, sensor, @gradientAscent, 3*d, 1, sprintf("Agent %d", 1));
|
||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center + dh - [d, 0, 0], zeros(1,3), 0, 0, geometry2, sensor, @gradientAscent, 3*d, 2, sprintf("Agent %d", 2));
|
||||
|
||||
% Optional third agent along the +Y axis
|
||||
geometry3 = rectangularPrism;
|
||||
geometry3 = geometry3.initialize([tc.domain.center - [0, d, 0] - tc.collisionRanges(1) * ones(1, 3); tc.domain.center - [0, d, 0] + tc.collisionRanges(1) * ones(1, 3)], REGION_TYPE.COLLISION, sprintf("Agent %d collision volume", 3));
|
||||
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, sprintf("Agent %d collision volume", 3));
|
||||
tc.agents{3} = agent;
|
||||
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center - [0, d, 0], zeros(1, 3), 0, 0, geometry3, sensor, @gradientAscent, 3*d, 3, sprintf("Agent %d", 3));
|
||||
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center + dh - [0, d, 0], zeros(1, 3), 0, 0, geometry3, sensor, @gradientAscent, 3*d, 3, sprintf("Agent %d", 3));
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.timestep, tc.partitoningFreq, tc.maxIter);
|
||||
end
|
||||
function test_annular_partition(tc)
|
||||
function test_single_partition(tc)
|
||||
% make basic domain
|
||||
tc.domain = tc.domain.initialize([zeros(1, 3); 10 * ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||
l = 10; % domain size
|
||||
tc.domain = tc.domain.initialize([zeros(1, 3); l * ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||
|
||||
% make basic sensing objective
|
||||
tc.domain.objective = tc.domain.objective.initialize(@(x, y) mvnpdf([x(:), y(:)], tc.domain.center(1:2)), tc.domain, tc.discretizationStep, tc.protectedRange);
|
||||
@@ -390,7 +392,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, 0.3641, 13);
|
||||
% sensor = sensor.initialize(2.5666, 5.0807, NaN, NaN, 20.8614, 13); % 13
|
||||
alphaDist = l/2; % half of domain length/width
|
||||
sensor = sensor.initialize(alphaDist, 3, NaN, NaN, 20, 3);
|
||||
f = sensor.plotParameters();
|
||||
|
||||
% Initialize agents
|
||||
@@ -399,6 +403,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
||||
|
||||
% Initialize the simulation
|
||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.timestep, tc.partitoningFreq, tc.maxIter);
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ classdef test_sigmoidSensor < matlab.unittest.TestCase
|
||||
betaTiltMax = 15;
|
||||
alphaDistMin = 2.5;
|
||||
alphaDistMax = 3;
|
||||
alphaTiltMin = deg2rad(15);
|
||||
alphaTiltMax = deg2rad(30);
|
||||
alphaTiltMin = 15; % degrees
|
||||
alphaTiltMax = 30; % degrees
|
||||
end
|
||||
|
||||
methods (TestMethodSetup)
|
||||
@@ -31,7 +31,7 @@ classdef test_sigmoidSensor < matlab.unittest.TestCase
|
||||
tc.testClass = sigmoidSensor;
|
||||
alphaDist = 2.5;
|
||||
betaDist = 3;
|
||||
alphaTilt = deg2rad(15);
|
||||
alphaTilt = 15; % degrees
|
||||
betaTilt = 3;
|
||||
tc.testClass = tc.testClass.initialize(alphaDist, betaDist, NaN, NaN, alphaTilt, betaTilt);
|
||||
|
||||
|
||||
Reference in new issue
Block a user