fixed issues in sigmoid sensor model causing inverted response (annular partitions)
This commit is contained in:
1 parent
66bbfe52ca
commit
f7b28cdf4f
55 files changed
+44
-31
No files matched your search
+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;
|
||||
+17
-12
@@ -42,8 +42,8 @@ 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 = 8; % Maximum range between agents that forms a communications link
|
||||
@@ -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