From 3b3cab2089ce1ff80624c348c07e4c124f73a793 Mon Sep 17 00:00:00 2001 From: Kevin D Date: Wed, 1 Apr 2026 09:48:06 -0700 Subject: [PATCH] added full plotting from logged outputs --- @miSim/miSim.m | 1 + @miSim/plotFromSimHist.m | 93 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 @miSim/plotFromSimHist.m diff --git a/@miSim/miSim.m b/@miSim/miSim.m index 55f3545..5ca5056 100644 --- a/@miSim/miSim.m +++ b/@miSim/miSim.m @@ -72,6 +72,7 @@ classdef miSim [obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo); [obj] = initializeFromCsv(obj, csvPath); [obj] = initializeFromInits(obj, initsPath); + [obj] = plotFromSimHist(obj, initsPath, histPath); [obj] = run(obj); [obj] = lesserNeighbor(obj); [obj] = constrainMotion(obj); diff --git a/@miSim/plotFromSimHist.m b/@miSim/plotFromSimHist.m new file mode 100644 index 0000000..8eee9c7 --- /dev/null +++ b/@miSim/plotFromSimHist.m @@ -0,0 +1,93 @@ +function obj = plotFromSimHist(obj, initsPath, histPath) +% PLOTFROMSIMHIST Reconstruct all three miSim plots from saved matfiles. +% +% Loads the simInits matfile to rebuild domain/obstacle/objective/agent +% geometry, then loads the simHist matfile to restore the full time-history +% arrays. Produces the same three figures that a live run would generate: +% 1. Sensor performance vs. time (obj.fPerf) +% 2. Barrier function values vs. time (obj.hf) +% 3. 3-D spatial figure with domain, obstacles, objective, agent trails, +% and final-timestep communications topology (obj.f) +% +% Usage: +% sim = miSim; +% sim = sim.plotFromSimHist( ... +% 'sandbox/2025_01_01_12_00_00_miSimHist.mat', ... +% 'sandbox/2025_01_01_12_00_00_miSimInits.mat'); + +arguments (Input) + obj (1, 1) {mustBeA(obj, 'miSim')}; + initsPath (1, 1) string; + histPath (1, 1) string; +end +arguments (Output) + obj (1, 1) {mustBeA(obj, 'miSim')}; +end + +% ---- Reconstruct geometry from inits (plots disabled) -------------------- +obj = obj.initializeFromInits(initsPath); +nAgents = size(obj.agents, 1); + +% ---- Load history data --------------------------------------------------- +data = load(histPath); +out = data.out; + +nHistTimesteps = size(out.barriers, 2); +nPosTimesteps = size(out.agent(1).pos, 1); + +% ---- Populate barrier history -------------------------------------------- +% out.barriers may be narrower than the pre-allocated obj.barriers if the +% run was shorter than maxIter; fill what we have and leave the rest NaN. +obj.barriers(:, 1:nHistTimesteps) = out.barriers; + +% ---- Populate position history and advance agents to final positions ----- +for ii = 1:nAgents + agentPos = out.agent(ii).pos; % (nPosTimesteps × 3) + nPts = size(agentPos, 1); + obj.posHist(ii, 1:nPts, :) = reshape(agentPos, [1, nPts, 3]); + obj.agents{ii}.pos = agentPos(end, :); % show final position in spatial plot +end + +% ---- Set final constraint topology --------------------------------------- +obj.constraintAdjacencyMatrix = out.constraintAdjacency(:, :, end); + +% ---- Recompute partitioning at final agent positions --------------------- +obj.partitioning = obj.agents{1}.partition(obj.agents, obj.domain.objective); + +% ---- Enable plotting and produce spatial + barrier figures --------------- +obj.makePlots = true; +obj = obj.plot(); + +% ---- Performance figure (built directly — live machinery is incremental) - +nPerfTimesteps = numel(out.perf); +times = (0:nPerfTimesteps - 1) * obj.timestep; +normFactor = 1 / max(out.perf); + +obj.fPerf = figure; +ax = axes(obj.fPerf); +hold(ax, "on"); +title(ax, "Sensor Performance"); +xlabel(ax, "Time (s)"); +ylabel(ax, "Sensor Performance"); +grid(ax, "on"); + +legendStrings = strings(nAgents + 1, 1); +legendStrings(1) = "Total"; +plot(ax, times, out.perf * normFactor, "LineWidth", 1.5); +for ii = 1:nAgents + agentPerf = out.agent(ii).perf; + agentTimes = times(1:numel(agentPerf)); + plot(ax, agentTimes, agentPerf * normFactor); + if isfield(out.agent(ii), 'label') + legendStrings(ii + 1) = string(out.agent(ii).label); + else + legendStrings(ii + 1) = sprintf("Agent %d", ii); + end +end +legend(ax, legendStrings, "Location", "northwest"); +hold(ax, "off"); + +% Bring spatial figure to the front +figure(obj.f); + +end