codegen fixes, bug fixes, gets running on testbed environment
This commit is contained in:
@@ -17,8 +17,8 @@ classdef agent
|
||||
fovGeometry;
|
||||
|
||||
% Communication
|
||||
commsGeometry = spherical;
|
||||
lesserNeighbors = [];
|
||||
commsGeometry;
|
||||
lesserNeighbors = zeros(1, 0);
|
||||
|
||||
% Performance
|
||||
performance = 0;
|
||||
@@ -34,6 +34,17 @@ classdef agent
|
||||
end
|
||||
|
||||
methods (Access = public)
|
||||
function obj = agent()
|
||||
arguments (Input)
|
||||
end
|
||||
arguments (Output)
|
||||
obj (1, 1) agent
|
||||
end
|
||||
obj.collisionGeometry = spherical;
|
||||
obj.sensorModel = sigmoidSensor;
|
||||
obj.fovGeometry = cone;
|
||||
obj.commsGeometry = spherical;
|
||||
end
|
||||
[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)
|
||||
|
||||
@@ -23,7 +23,9 @@ function obj = initialize(obj, pos, collisionGeometry, sensorModel, comRange, ma
|
||||
obj.stepDecayRate = obj.initialStepSize / maxIter;
|
||||
|
||||
% Initialize performance vector
|
||||
obj.performance = [0, NaN(1, maxIter), 0];
|
||||
if coder.target('MATLAB')
|
||||
obj.performance = [0, NaN(1, maxIter), 0];
|
||||
end
|
||||
|
||||
% Add spherical geometry based on com range
|
||||
obj.commsGeometry = obj.commsGeometry.initialize(obj.pos, comRange, REGION_TYPE.COMMS, sprintf("%s Comms Geometry", obj.label));
|
||||
|
||||
@@ -7,29 +7,33 @@ function [partitioning] = partition(obj, agents, objective)
|
||||
arguments (Output)
|
||||
partitioning (:, :) double;
|
||||
end
|
||||
|
||||
% Assess sensing performance of each agent at each sample point
|
||||
% in the domain
|
||||
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{:});
|
||||
|
||||
% Get highest performance value at each point
|
||||
[~, idx] = max(agentPerformances, [], 3);
|
||||
nAgents = size(agents, 1);
|
||||
gridM = size(objective.X, 1);
|
||||
gridN = size(objective.X, 2);
|
||||
nPoints = gridM * gridN;
|
||||
|
||||
% Collect agent indices in the same way as performance
|
||||
indices = 1:size(agents, 1);
|
||||
agentInds = squeeze(tensorprod(indices, ones(size(objective.X))));
|
||||
if size(agentInds, 1) ~= size(agents, 1)
|
||||
agentInds = reshape(agentInds, [size(agents, 1), size(agentInds)]); % needed for cases with 1 agent where prior squeeze is too agressive
|
||||
% Assess sensing performance of each agent at each sample point.
|
||||
% agentPerf is (nPoints x nAgents+1): the extra column is the
|
||||
% minimum threshold that must be exceeded for any assignment.
|
||||
agentPerf = zeros(nPoints, nAgents + 1);
|
||||
for aa = 1:nAgents
|
||||
p = agents{aa}.sensorModel.sensorPerformance(agents{aa}.pos, ...
|
||||
[objective.X(:), objective.Y(:), zeros(nPoints, 1)]);
|
||||
agentPerf(:, aa) = p(:);
|
||||
end
|
||||
agentInds = num2cell(agentInds, 2:3);
|
||||
agentInds = cellfun(@(x) squeeze(x), agentInds, "UniformOutput", false);
|
||||
agentInds{end + 1} = zeros(size(agentInds{end})); % index for no assignment
|
||||
agentInds = cat(3, agentInds{:});
|
||||
agentPerf(:, nAgents + 1) = objective.sensorPerformanceMinimum;
|
||||
|
||||
% Use highest performing agent's index to form partitions
|
||||
[m, n, ~] = size(agentInds);
|
||||
[jj, kk] = ndgrid(1:m, 1:n);
|
||||
partitioning = agentInds(sub2ind(size(agentInds), jj, kk, idx));
|
||||
end
|
||||
% Find which agent has highest performance at each point.
|
||||
% If the threshold column wins (idx == nAgents+1) the point is unassigned (0).
|
||||
[~, idx] = max(agentPerf, [], 2);
|
||||
|
||||
assignedAgent = zeros(nPoints, 1);
|
||||
for pp = 1:nPoints
|
||||
if idx(pp) <= nAgents
|
||||
assignedAgent(pp) = idx(pp);
|
||||
end
|
||||
end
|
||||
|
||||
partitioning = reshape(assignedAgent, gridM, gridN);
|
||||
end
|
||||
|
||||
23
@agent/run.m
23
@agent/run.m
@@ -13,7 +13,7 @@ function obj = run(obj, domain, partitioning, timestepIndex, index, agents)
|
||||
|
||||
% Collect objective function values across partition
|
||||
partitionMask = partitioning == index;
|
||||
if ~unique(partitionMask)
|
||||
if ~any(partitionMask(:))
|
||||
% This agent has no partition, maintain current state
|
||||
return;
|
||||
end
|
||||
@@ -32,10 +32,10 @@ function obj = run(obj, domain, partitioning, timestepIndex, index, agents)
|
||||
pos = obj.pos + delta * deltaApplicator(ii, 1:3);
|
||||
|
||||
% Compute performance values on partition
|
||||
if ii < 5
|
||||
if ii < 6
|
||||
% Compute sensing performance
|
||||
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.
|
||||
% 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
|
||||
else
|
||||
@@ -64,17 +64,26 @@ function obj = run(obj, domain, partitioning, timestepIndex, index, agents)
|
||||
end
|
||||
|
||||
% Store agent performance at current time and place
|
||||
obj.performance(timestepIndex + 1) = C_delta(1);
|
||||
if coder.target('MATLAB')
|
||||
obj.performance(timestepIndex + 1) = C_delta(1);
|
||||
end
|
||||
|
||||
% Compute gradient by finite central differences
|
||||
gradC = [(C_delta(2)-C_delta(3))/(2*delta), (C_delta(4)-C_delta(5))/(2*delta), (C_delta(6)-C_delta(7))/(2*delta)];
|
||||
|
||||
% Compute scaling factor
|
||||
targetRate = obj.initialStepSize - obj.stepDecayRate * timestepIndex; % slow down as you get closer
|
||||
rateFactor = targetRate / norm(gradC);
|
||||
gradNorm = norm(gradC);
|
||||
|
||||
% Compute unconstrained next position
|
||||
pNext = obj.pos + rateFactor * gradC;
|
||||
% Compute unconstrained next position.
|
||||
% Guard against near-zero gradient: when sensor performance is saturated
|
||||
% or near-zero across the whole partition, rateFactor -> Inf and pNext
|
||||
% explodes. Stay put instead.
|
||||
if gradNorm < 1e-10
|
||||
pNext = obj.pos;
|
||||
else
|
||||
pNext = obj.pos + (targetRate / gradNorm) * gradC;
|
||||
end
|
||||
|
||||
% Move to next position
|
||||
obj.lastPos = obj.pos;
|
||||
|
||||
Reference in New Issue
Block a user