added agent position trail to plot
This commit is contained in:
@@ -28,6 +28,7 @@ function obj = initialize(obj, domain, objective, agents, minAlt, timestep, part
|
||||
|
||||
% Define simulation time parameters
|
||||
obj.timestep = timestep;
|
||||
obj.timestepIndex = 0;
|
||||
obj.maxIter = maxIter - 1;
|
||||
|
||||
% Define domain
|
||||
@@ -66,6 +67,10 @@ function obj = initialize(obj, domain, objective, agents, minAlt, timestep, part
|
||||
% Create initial partitioning
|
||||
obj = obj.partition();
|
||||
|
||||
% Initialize variable that will store agent positions for trail plots
|
||||
obj.posHist = NaN(size(obj.agents, 1), obj.maxIter + 1, 3);
|
||||
obj.posHist(1:size(obj.agents, 1), 1, 1:3) = reshape(cell2mat(cellfun(@(x) x.pos, obj.agents, 'UniformOutput', false)), size(obj.agents, 1), 1, 3);
|
||||
|
||||
% Set up plots showing initialized state
|
||||
obj = obj.plot();
|
||||
end
|
||||
@@ -4,6 +4,7 @@ classdef miSim
|
||||
% Simulation parameters
|
||||
properties (SetAccess = private, GetAccess = public)
|
||||
timestep = NaN; % delta time interval for simulation iterations
|
||||
timestepIndex = NaN; % index of the current timestep (useful for time-indexed arrays)
|
||||
partitioningFreq = NaN; % number of simulation timesteps at which the partitioning routine is re-run
|
||||
maxIter = NaN; % maximum number of simulation iterations
|
||||
domain = rectangularPrism;
|
||||
@@ -35,9 +36,11 @@ classdef miSim
|
||||
connectionsPlot; % objects for lines connecting agents in spatial plots
|
||||
graphPlot; % objects for abstract network graph plot
|
||||
partitionPlot; % objects for partition plot
|
||||
|
||||
performancePlot; % objects for sensor performance plot
|
||||
|
||||
posHist; % data for trail plot
|
||||
trailPlot; % objects for agent trail plot
|
||||
|
||||
% Indicies for various plot types in the main tiled layout figure
|
||||
spatialPlotIndices = [6, 4, 3, 2];
|
||||
objectivePlotIndices = [6, 4];
|
||||
@@ -56,6 +59,7 @@ classdef miSim
|
||||
[obj] = plotConnections(obj);
|
||||
[obj] = plotPartitions(obj);
|
||||
[obj] = plotGraph(obj);
|
||||
[obj] = plotTrails(obj);
|
||||
[obj] = updatePlots(obj, updatePartitions);
|
||||
end
|
||||
methods (Access = private)
|
||||
|
||||
@@ -36,6 +36,9 @@ function obj = plot(obj)
|
||||
% Plot domain partitioning
|
||||
obj = obj.plotPartitions();
|
||||
|
||||
% Plot agent trails
|
||||
obj = obj.plotTrails();
|
||||
|
||||
% Enforce plot limits
|
||||
for ii = 1:size(obj.spatialPlotIndices, 2)
|
||||
xlim(obj.f.Children(1).Children(obj.spatialPlotIndices(ii)), [obj.domain.minCorner(1), obj.domain.maxCorner(1)]);
|
||||
|
||||
@@ -37,10 +37,7 @@ function obj = plotPerformance(obj)
|
||||
end
|
||||
|
||||
% Add legend
|
||||
agentStrings = repmat("Agent %d", size(obj.perf, 1) - 1, 1);
|
||||
for ii = 1:size(agentStrings, 1)
|
||||
agentStrings(ii) = sprintf(agentStrings(ii), ii);
|
||||
end
|
||||
agentStrings = string(cellfun(@(x) x.label, obj.agents, 'UniformOutput', false));
|
||||
agentStrings = ["Total"; agentStrings];
|
||||
legend(obj.fPerf.Children(1), agentStrings, 'Location', 'northwest');
|
||||
|
||||
|
||||
31
@miSim/plotTrails.m
Normal file
31
@miSim/plotTrails.m
Normal file
@@ -0,0 +1,31 @@
|
||||
function obj = plotTrails(obj)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, 'miSim')}
|
||||
end
|
||||
arguments (Output)
|
||||
obj (1, 1) {mustBeA(obj, 'miSim')}
|
||||
end
|
||||
|
||||
% fast exit when plotting is disabled
|
||||
if ~obj.makePlots
|
||||
return;
|
||||
end
|
||||
|
||||
% Plot full range of position history on each spatial plot axes
|
||||
o = [];
|
||||
for ii = 1:(size(obj.posHist, 1))
|
||||
hold(obj.f.Children(1).Children(obj.spatialPlotIndices(1)), 'on');
|
||||
o = [o; plot3(obj.f.Children(1).Children(obj.spatialPlotIndices(1)), obj.posHist(ii, 1:obj.maxIter, 1), obj.posHist(ii, 1:obj.maxIter, 2), obj.posHist(ii, 1:obj.maxIter, 3), 'Color', 'k', 'LineWidth', 1)];
|
||||
hold(obj.f.Children(1).Children(obj.spatialPlotIndices(1)), 'off');
|
||||
end
|
||||
|
||||
% Copy trails to other figures?
|
||||
obj.trailPlot = o;
|
||||
|
||||
% Add legend?
|
||||
% TODO legend?
|
||||
% TODO unique colors for agent trails (same as performance plot?)
|
||||
% Could be agent-specific colors (stored as agent property)
|
||||
keyboard
|
||||
|
||||
end
|
||||
@@ -15,6 +15,7 @@ function [obj] = run(obj)
|
||||
for ii = 1:size(obj.times, 1)
|
||||
% Display current sim time
|
||||
obj.t = obj.times(ii);
|
||||
obj.timestepIndex = ii;
|
||||
fprintf("Sim Time: %4.2f (%d/%d)\n", obj.t, ii, obj.maxIter + 1);
|
||||
|
||||
% Check if it's time for new partitions
|
||||
@@ -38,6 +39,9 @@ function [obj] = run(obj)
|
||||
|
||||
% Finished simulation for this timestep, do accounting
|
||||
|
||||
% 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);
|
||||
|
||||
% Update total performance
|
||||
obj.performance = [obj.performance, sum(cellfun(@(x) x.performance(end), obj.agents))];
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ function [obj] = updatePlots(obj, updatePartitions)
|
||||
obj.agents{ii}.updatePlots();
|
||||
end
|
||||
|
||||
% The remaining updates might be possible to do in a clever way
|
||||
% that moves existing lines instead of clearing and
|
||||
% The remaining updates might should all be possible to do in a clever
|
||||
% way that moves existing lines instead of clearing and
|
||||
% re-plotting, which is much better for performance boost
|
||||
|
||||
% Update agent connections plot
|
||||
@@ -41,15 +41,23 @@ function [obj] = updatePlots(obj, updatePartitions)
|
||||
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)]);
|
||||
end
|
||||
|
||||
% Update agent trails
|
||||
for ii = 1:size(obj.agents, 1)
|
||||
obj.trailPlot(ii).XData(obj.timestepIndex) = obj.posHist(ii, obj.timestepIndex, 1);
|
||||
obj.trailPlot(ii).YData(obj.timestepIndex) = obj.posHist(ii, obj.timestepIndex, 2);
|
||||
obj.trailPlot(ii).ZData(obj.timestepIndex) = obj.posHist(ii, obj.timestepIndex, 3);
|
||||
end
|
||||
|
||||
drawnow;
|
||||
|
||||
% Update performance plot
|
||||
% Re-normalize performance plot
|
||||
normalizingFactor = 1/max(obj.performance(end));
|
||||
obj.performancePlot(1).YData(1:length(obj.performance)) = obj.performance * normalizingFactor;
|
||||
obj.performancePlot(1).XData(find(isnan(obj.performancePlot(1).XData), 1, 'first')) = obj.t;
|
||||
obj.performancePlot(1).XData(obj.timestepIndex) = obj.t;
|
||||
for ii = 2:(size(obj.agents, 1) + 1)
|
||||
obj.performancePlot(ii).YData(1:length(obj.performance)) = obj.agents{ii - 1}.performance * normalizingFactor;
|
||||
obj.performancePlot(ii).XData(find(isnan(obj.performancePlot(ii).XData), 1, 'first')) = obj.t;
|
||||
obj.performancePlot(ii).XData(obj.timestepIndex) = obj.t;
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user