started performance plot

This commit is contained in:
2025-11-16 17:46:36 -08:00
parent e2d85ce6b9
commit 8dd1e012ad
13 changed files with 83 additions and 22 deletions

4
.gitignore vendored
View File

@@ -41,3 +41,7 @@ codegen/
# Sandbox contents # Sandbox contents
sandbox/* sandbox/*
# Videos
*.mp4
*.avi

View File

@@ -1,7 +1,4 @@
classdef agent classdef agent
properties (Access = public)
performance = NaN; % current individual sensor performance on partition
end
properties (SetAccess = private, GetAccess = public) properties (SetAccess = private, GetAccess = public)
% Identifiers % Identifiers
index = NaN; index = NaN;

View File

@@ -15,7 +15,7 @@ function obj = initialize(obj, domain, objective, agents, timestep, partitoningF
% Define simulation time parameters % Define simulation time parameters
obj.timestep = timestep; obj.timestep = timestep;
obj.maxIter = maxIter; obj.maxIter = maxIter - 1;
% Define domain % Define domain
obj.domain = domain; obj.domain = domain;
@@ -33,6 +33,14 @@ function obj = initialize(obj, domain, objective, agents, timestep, partitoningF
% Compute adjacency matrix % Compute adjacency matrix
obj = obj.updateAdjacency(); obj = obj.updateAdjacency();
% 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.fPerf = figure;
obj.perf = [zeros(size(obj.agents, 1) + 1, 1), NaN(size(obj.agents, 1) + 1, size(obj.partitioningTimes, 1) - 1)];
% Create initial partitioning % Create initial partitioning
obj = obj.partition(); obj = obj.partition();

View File

@@ -17,13 +17,19 @@ classdef miSim
end end
properties (Access = private) properties (Access = private)
% Sim
t = NaN; % current sim time
perf; % sensor performance timeseries array
times;
partitioningTimes;
% Plot objects % Plot objects
f = firstPlotSetup(); % main plotting tiled layout figure f = firstPlotSetup(); % main plotting tiled layout figure
connectionsPlot; % objects for lines connecting agents in spatial plots connectionsPlot; % objects for lines connecting agents in spatial plots
graphPlot; % objects for abstract network graph plot graphPlot; % objects for abstract network graph plot
partitionPlot; % objects for partition plot partitionPlot; % objects for partition plot
fPerf = figure; % performance plot figure fPerf; % performance plot figure
performancePlot; % objects for sensor performance plot performancePlot; % objects for sensor performance plot
% Indicies for various plot types in the main tiled layout figure % Indicies for various plot types in the main tiled layout figure

View File

@@ -22,15 +22,15 @@ function obj = partition(obj)
% Get highest performing agent's index % Get highest performing agent's index
[m,n,~] = size(agentInds); [m,n,~] = size(agentInds);
[i,j] = ndgrid(1:m, 1:n); [jj,kk] = ndgrid(1:m, 1:n);
obj.partitioning = agentInds(sub2ind(size(agentInds), i, j, idx)); obj.partitioning = agentInds(sub2ind(size(agentInds), jj, kk, idx));
% Get individual agent sensor performance % Get individual agent sensor performance
nowIdx = [0; obj.partitioningTimes] == obj.t;
for ii = 1:size(obj.agents, 1) for ii = 1:size(obj.agents, 1)
obj.agents{ii}.performance = sum(agentPerformances(sub2ind(size(agentInds), i, j, idx)), 'all'); obj.perf(ii, nowIdx) = sum(agentPerformances(sub2ind(size(agentInds), jj, kk, ii)), 'all');
end end
% Current total performance % Current total performance
sum(arrayfun(@(x) x.performance, [obj.agents{:}])) obj.perf(end, nowIdx) = sum(obj.perf(1:(end - 1), nowIdx));
obj.performance = sum(max(agentPerformances(:, :, 1:(end - 1)), [], 3), 'all'); % do not count final "non-assignment" layer in computing cumulative performance
end end

View File

@@ -37,4 +37,7 @@ function obj = plot(obj)
ylim(obj.f.Children(1).Children(obj.spatialPlotIndices(ii)), [obj.domain.minCorner(2), obj.domain.maxCorner(2)]); ylim(obj.f.Children(1).Children(obj.spatialPlotIndices(ii)), [obj.domain.minCorner(2), obj.domain.maxCorner(2)]);
zlim(obj.f.Children(1).Children(obj.spatialPlotIndices(ii)), [obj.domain.minCorner(3), obj.domain.maxCorner(3)]); zlim(obj.f.Children(1).Children(obj.spatialPlotIndices(ii)), [obj.domain.minCorner(3), obj.domain.maxCorner(3)]);
end end
% Plot performance
obj = obj.plotPerformance();
end end

28
@miSim/plotPerformance.m Normal file
View File

@@ -0,0 +1,28 @@
function obj = plotPerformance(obj)
arguments (Input)
obj (1, 1) {mustBeA(obj, 'miSim')};
end
arguments (Output)
obj (1, 1) {mustBeA(obj, 'miSim')};
end
axes(obj.fPerf);
title(obj.fPerf.Children(1), "Sensor Performance");
xlabel(obj.fPerf.Children(1), 'Time (s)');
ylabel(obj.fPerf.Children(1), 'Sensor Performance');
grid(obj.fPerf.Children(1), 'on');
% Plot current cumulative performance
hold(obj.fPerf.Children(1), 'on');
o = plot(obj.fPerf.Children(1), obj.perf(end, :));
hold(obj.fPerf.Children(1), 'off');
% Plot current agent performance
for ii = 1:(size(obj.perf, 1) - 1)
hold(obj.fPerf.Children(1), 'on');
o = [o; plot(obj.fPerf.Children(1), obj.perf(ii, :))];
hold(obj.fPerf.Children(1), 'off');
end
obj.performancePlot = o;
end

View File

@@ -6,22 +6,18 @@ function [obj] = run(obj)
obj (1, 1) {mustBeA(obj, 'miSim')}; obj (1, 1) {mustBeA(obj, 'miSim')};
end end
% Set up times to iterate over
times = linspace(0, obj.timestep * obj.maxIter, obj.maxIter+1)';
partitioningTimes = times(obj.partitioningFreq:obj.partitioningFreq:size(times, 1));
% Start video writer % Start video writer
v = obj.setupVideoWriter(); v = obj.setupVideoWriter();
v.open(); v.open();
for ii = 1:size(times, 1) for ii = 1:size(obj.times, 1)
% Display current sim time % Display current sim time
t = times(ii); obj.t = obj.times(ii);
fprintf("Sim Time: %4.2f (%d/%d)\n", t, ii, obj.maxIter) fprintf("Sim Time: %4.2f (%d/%d)\n", obj.t, ii, obj.maxIter + 1);
% Check if it's time for new partitions % Check if it's time for new partitions
updatePartitions = false; updatePartitions = false;
if ismember(t, partitioningTimes) if ismember(obj.t, obj.partitioningTimes)
updatePartitions = true; updatePartitions = true;
obj = obj.partition(); obj = obj.partition();
end end

View File

@@ -9,7 +9,7 @@ function v = setupVideoWriter(obj)
if ispc || ismac if ispc || ismac
v = VideoWriter(fullfile('sandbox', strcat(string(datetime('now'), 'yyyy_MM_dd_HH_mm_ss'), '_miSimHist')), 'MPEG-4'); v = VideoWriter(fullfile('sandbox', strcat(string(datetime('now'), 'yyyy_MM_dd_HH_mm_ss'), '_miSimHist')), 'MPEG-4');
elseif isunix elseif isunix
v = VideoWriter(fullfile('sandbox', strcat(string(datetime('now'), 'yyyy_MM_dd_HH_mm_ss'), '_miSimHist')), 'Motion JPEG AVI'); v = VideoWriter(fullfile('.', strcat(string(datetime('now'), 'yyyy_MM_dd_HH_mm_ss'), '_miSimHist')), 'Motion JPEG AVI');
end end
v.FrameRate = 1 / obj.timestep; v.FrameRate = 1 / obj.timestep;

View File

@@ -36,6 +36,17 @@ function [obj] = updatePlots(obj, updatePartitions)
ylim(obj.f.Children(1).Children(obj.spatialPlotIndices(ii)), [obj.domain.minCorner(2), obj.domain.maxCorner(2)]); ylim(obj.f.Children(1).Children(obj.spatialPlotIndices(ii)), [obj.domain.minCorner(2), obj.domain.maxCorner(2)]);
zlim(obj.f.Children(1).Children(obj.spatialPlotIndices(ii)), [obj.domain.minCorner(3), obj.domain.maxCorner(3)]); zlim(obj.f.Children(1).Children(obj.spatialPlotIndices(ii)), [obj.domain.minCorner(3), obj.domain.maxCorner(3)]);
end end
drawnow;
% Update performance plot
if updatePartitions
nowIdx = [0; obj.partitioningTimes] == obj.t;
% set(obj.performancePlot(1), 'YData', obj.perf(end, 1:find(nowIdx)));
obj.performancePlot(1).YData(nowIdx) = obj.perf(end, nowIdx);
for ii = 2:size(obj.performancePlot, 1)
obj.performancePlot(ii).YData(nowIdx) = obj.perf(ii, nowIdx);
end
drawnow; drawnow;
end end
end

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info>
<Category UUID="FileClassCategory">
<Label UUID="design"/>
</Category>
</Info>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<Info location="plotPerformance.m" type="File"/>

View File

@@ -333,7 +333,7 @@ classdef test_miSim < matlab.unittest.TestCase
tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.timestep, tc.partitoningFreq, tc.maxIter, tc.obstacles); tc.testClass = tc.testClass.initialize(tc.domain, tc.domain.objective, tc.agents, tc.timestep, tc.partitoningFreq, tc.maxIter, tc.obstacles);
% Run simulation loop % Run simulation loop
tc.testClass = tc.testClass.run(f); tc.testClass = tc.testClass.run();
end end
function test_basic_partitioning(tc) function test_basic_partitioning(tc)
% place agents a fixed distance +/- X from the domain's center % place agents a fixed distance +/- X from the domain's center