now doing partitioning on every timestep, looks super smooth
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
function obj = initialize(obj, domain, objective, agents, minAlt, timestep, partitoningFreq, maxIter, obstacles, makePlots, makeVideo)
|
||||
function obj = initialize(obj, domain, objective, agents, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'miSim')};
|
||||
domain (1, 1) {mustBeGeometry};
|
||||
@@ -6,7 +6,6 @@ function obj = initialize(obj, domain, objective, agents, minAlt, timestep, part
|
||||
agents (:, 1) cell;
|
||||
minAlt (1, 1) double = 1;
|
||||
timestep (:, 1) double = 0.05;
|
||||
partitoningFreq (:, 1) double = 0.25
|
||||
maxIter (:, 1) double = 1000;
|
||||
obstacles (:, 1) cell {mustBeGeometry} = cell(0, 1);
|
||||
makePlots(1, 1) logical = true;
|
||||
@@ -33,7 +32,6 @@ function obj = initialize(obj, domain, objective, agents, minAlt, timestep, part
|
||||
|
||||
% Define domain
|
||||
obj.domain = domain;
|
||||
obj.partitioningFreq = partitoningFreq;
|
||||
|
||||
% Add geometries representing obstacles within the domain
|
||||
obj.obstacles = obstacles;
|
||||
@@ -73,7 +71,6 @@ function obj = initialize(obj, domain, objective, agents, minAlt, timestep, part
|
||||
|
||||
% Set up times to iterate over
|
||||
obj.times = linspace(0, obj.timestep * obj.maxIter, obj.maxIter+1)';
|
||||
obj.partitioningTimes = obj.times(obj.partitioningFreq:obj.partitioningFreq:size(obj.times, 1));
|
||||
|
||||
% Prepare performance data store (at t = 0, all have 0 performance)
|
||||
obj.perf = [zeros(size(obj.agents, 1) + 1, 1), NaN(size(obj.agents, 1) + 1, size(obj.partitioningTimes, 1) - 1)];
|
||||
@@ -82,7 +79,7 @@ function obj = initialize(obj, domain, objective, agents, minAlt, timestep, part
|
||||
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);
|
||||
|
||||
% Create initial partitioning
|
||||
obj = obj.partition();
|
||||
obj.partitioning = obj.agents{1}.partition(obj.agents, obj.domain.objective);
|
||||
|
||||
% Initialize variable that will store agent positions for trail plots
|
||||
obj.posHist = NaN(size(obj.agents, 1), obj.maxIter + 1, 3);
|
||||
|
||||
@@ -67,7 +67,7 @@ classdef miSim
|
||||
[obj] = plotGraph(obj);
|
||||
[obj] = plotTrails(obj);
|
||||
[obj] = plotH(obj);
|
||||
[obj] = updatePlots(obj, updatePartitions);
|
||||
[obj] = updatePlots(obj);
|
||||
validate(obj);
|
||||
end
|
||||
methods (Access = private)
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
function obj = partition(obj)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'miSim')};
|
||||
end
|
||||
arguments (Output)
|
||||
obj (1, 1) {mustBeA(obj, 'miSim')};
|
||||
end
|
||||
|
||||
% 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, [obj.objective.X(:), obj.objective.Y(:), zeros(size(obj.objective.X(:)))]), size(obj.objective.X)), obj.agents, 'UniformOutput', false);
|
||||
agentPerformances{end + 1} = obj.domain.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);
|
||||
|
||||
% Collect agent indices in the same way as performance
|
||||
indices = 1:size(obj.agents, 1);
|
||||
agentInds = squeeze(tensorprod(indices, ones(size(obj.objective.X))));
|
||||
if size(agentInds, 1) ~= size(obj.agents, 1)
|
||||
agentInds = reshape(agentInds, [size(obj.agents, 1), size(agentInds)]); % needed for cases with 1 agent where prior squeeze is too agressive
|
||||
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{:});
|
||||
|
||||
% 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));
|
||||
end
|
||||
16
@miSim/run.m
16
@miSim/run.m
@@ -18,19 +18,18 @@ function [obj] = run(obj)
|
||||
obj.timestepIndex = ii;
|
||||
fprintf("Sim Time: %4.2f (%d/%d)\n", obj.t, ii, obj.maxIter + 1);
|
||||
|
||||
% Before moving
|
||||
% Validate current simulation configuration
|
||||
obj.validate();
|
||||
|
||||
% Check if it's time for new partitions
|
||||
updatePartitions = false;
|
||||
if ismember(obj.t, obj.partitioningTimes)
|
||||
updatePartitions = true;
|
||||
obj = obj.partition();
|
||||
end
|
||||
% Update partitioning before moving (this one is strictly for
|
||||
% plotting purposes, the real partitioning is done by the agents)
|
||||
obj.partitioning = obj.agents{1}.partition(obj.agents, obj.domain.objective);
|
||||
|
||||
% Determine desired communications links
|
||||
obj = obj.lesserNeighbor();
|
||||
|
||||
% Moving
|
||||
% Iterate over agents to simulate their unconstrained motion
|
||||
for jj = 1:size(obj.agents, 1)
|
||||
obj.agents{jj} = obj.agents{jj}.run(obj.domain, obj.partitioning, obj.timestepIndex, jj, obj.agents);
|
||||
@@ -40,8 +39,7 @@ function [obj] = run(obj)
|
||||
% CBF constraints solved by QP
|
||||
obj = constrainMotion(obj);
|
||||
|
||||
% Finished simulation for this timestep, do accounting
|
||||
|
||||
% After moving
|
||||
% Update agent position history array
|
||||
obj.posHist(1:size(obj.agents, 1), obj.timestepIndex + 1, 1:3) = reshape(cell2mat(cellfun(@(x) x.pos, obj.agents, 'UniformOutput', false)), size(obj.agents, 1), 1, 3);
|
||||
|
||||
@@ -52,7 +50,7 @@ function [obj] = run(obj)
|
||||
obj = obj.updateAdjacency();
|
||||
|
||||
% Update plots
|
||||
obj = obj.updatePlots(updatePartitions);
|
||||
obj = obj.updatePlots();
|
||||
|
||||
% Write frame in to video
|
||||
if obj.makeVideo
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
function [obj] = updatePlots(obj, updatePartitions)
|
||||
function [obj] = updatePlots(obj)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'miSim')};
|
||||
updatePartitions (1, 1) logical = false;
|
||||
end
|
||||
arguments (Output)
|
||||
obj (1, 1) {mustBeA(obj, 'miSim')};
|
||||
@@ -30,10 +29,8 @@ function [obj] = updatePlots(obj, updatePartitions)
|
||||
obj = obj.plotGraph();
|
||||
|
||||
% Update partitioning plot
|
||||
if updatePartitions
|
||||
delete(obj.partitionPlot);
|
||||
obj = obj.plotPartitions();
|
||||
end
|
||||
delete(obj.partitionPlot);
|
||||
obj = obj.plotPartitions();
|
||||
|
||||
% reset plot limits to fit domain
|
||||
for ii = 1:size(obj.spatialPlotIndices, 2)
|
||||
|
||||
Reference in New Issue
Block a user