Compare commits
40 Commits
789aecc560
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| c73559cd69 | |||
| 0b63cb4874 | |||
| cb9debf976 | |||
| ac56d3fcd2 | |||
| db6bcbb151 | |||
| 78f9dcd579 | |||
| 030dd30c7d | |||
| b44df40c7e | |||
| 740b42eba4 | |||
| 7433310390 | |||
| bc26cbc706 | |||
| ea111e56f8 | |||
| 8200dab499 | |||
| 0e39e0037d | |||
| e950d43fc8 | |||
| 0490dd656d | |||
| 4159a3a5cb | |||
| 81fe1b67c5 | |||
| 6349212dd5 | |||
| 35702a6ce2 | |||
| a202164875 | |||
| 57a89d93d5 | |||
| e19e9870d7 | |||
| 5cbb395684 | |||
| d07df25528 | |||
| 6cb6dabcb5 | |||
| 69e11549b2 | |||
| c467ca35be | |||
| fbc7fe18f4 | |||
| adac72dbc8 | |||
| 275123d0fc | |||
| dd0861d11c | |||
| fbcaa32abd | |||
| 09a10abfd5 | |||
| 87060ca123 | |||
| f7902ee220 | |||
| 5c90219322 | |||
| d3bdc80e64 | |||
| f3f9ec3db2 | |||
| 9564a5707f |
+4
-2
@@ -32,7 +32,9 @@ classdef agent
|
|||||||
|
|
||||||
properties (SetAccess = private, GetAccess = public)
|
properties (SetAccess = private, GetAccess = public)
|
||||||
initialStepSize = NaN;
|
initialStepSize = NaN;
|
||||||
|
initialMaxAngleStepSize = NaN;
|
||||||
stepDecayRate = NaN;
|
stepDecayRate = NaN;
|
||||||
|
angleStepDecayRate = NaN;
|
||||||
end
|
end
|
||||||
|
|
||||||
methods (Access = public)
|
methods (Access = public)
|
||||||
@@ -48,8 +50,8 @@ classdef agent
|
|||||||
obj.commsGeometry = spherical;
|
obj.commsGeometry = spherical;
|
||||||
end
|
end
|
||||||
[obj] = initialize(obj, pos, pan, tilt, collisionGeometry, sensorModel, guidanceModel, comRange, index, label);
|
[obj] = initialize(obj, pos, pan, tilt, collisionGeometry, sensorModel, guidanceModel, comRange, index, label);
|
||||||
[obj] = run(obj, domain, partitioning, t, index, agents);
|
[obj] = run(obj, domain, partitioning, t, index, useDoubleIntegrator, dampingCoeff, dt, optimizeSensorPointing, otherAgents);
|
||||||
[partitioning] = partition(obj, agents, objective)
|
[partitioning, agents] = partition(obj, agents, objective)
|
||||||
[obj, f] = plot(obj, ind, f);
|
[obj, f] = plot(obj, ind, f);
|
||||||
updatePlots(obj);
|
updatePlots(obj);
|
||||||
end
|
end
|
||||||
|
|||||||
+5
-2
@@ -1,4 +1,4 @@
|
|||||||
function obj = initialize(obj, pos, collisionGeometry, sensorModel, comRange, maxIter, initialStepSize, label, plotCommsGeometry)
|
function obj = initialize(obj, pos, collisionGeometry, sensorModel, comRange, maxIter, initialStepSize, initialMaxAngleStepSize, label, plotCommsGeometry)
|
||||||
arguments (Input)
|
arguments (Input)
|
||||||
obj (1, 1) {mustBeA(obj, "agent")};
|
obj (1, 1) {mustBeA(obj, "agent")};
|
||||||
pos (1, 3) double;
|
pos (1, 3) double;
|
||||||
@@ -7,6 +7,7 @@ function obj = initialize(obj, pos, collisionGeometry, sensorModel, comRange, ma
|
|||||||
comRange (1, 1) double;
|
comRange (1, 1) double;
|
||||||
maxIter (1, 1) double;
|
maxIter (1, 1) double;
|
||||||
initialStepSize (1, 1) double = 0.2;
|
initialStepSize (1, 1) double = 0.2;
|
||||||
|
initialMaxAngleStepSize (1, 1) double = 5.0;
|
||||||
label (1, 1) string = "";
|
label (1, 1) string = "";
|
||||||
plotCommsGeometry (1, 1) logical = false;
|
plotCommsGeometry (1, 1) logical = false;
|
||||||
end
|
end
|
||||||
@@ -23,7 +24,9 @@ function obj = initialize(obj, pos, collisionGeometry, sensorModel, comRange, ma
|
|||||||
obj.label = label;
|
obj.label = label;
|
||||||
obj.plotCommsGeometry = plotCommsGeometry;
|
obj.plotCommsGeometry = plotCommsGeometry;
|
||||||
obj.initialStepSize = initialStepSize;
|
obj.initialStepSize = initialStepSize;
|
||||||
|
obj.initialMaxAngleStepSize = initialMaxAngleStepSize;
|
||||||
obj.stepDecayRate = obj.initialStepSize / maxIter;
|
obj.stepDecayRate = obj.initialStepSize / maxIter;
|
||||||
|
obj.angleStepDecayRate = obj.initialMaxAngleStepSize / maxIter;
|
||||||
|
|
||||||
% Initialize performance vector
|
% Initialize performance vector
|
||||||
if coder.target('MATLAB')
|
if coder.target('MATLAB')
|
||||||
@@ -35,5 +38,5 @@ function obj = initialize(obj, pos, collisionGeometry, sensorModel, comRange, ma
|
|||||||
|
|
||||||
% Initialize FOV cone
|
% Initialize FOV cone
|
||||||
obj.fovGeometry = cone;
|
obj.fovGeometry = cone;
|
||||||
obj.fovGeometry = obj.fovGeometry.initialize([obj.pos(1:3)], tand(obj.sensorModel.alphaTilt) * obj.pos(3), obj.pos(3), REGION_TYPE.FOV, sprintf("%s FOV", obj.label));
|
obj.fovGeometry = obj.fovGeometry.initialize([obj.pos(1:3)], tand(obj.sensorModel.halfAngle()) * obj.pos(3), obj.pos(3), REGION_TYPE.FOV, sprintf("%s FOV", obj.label), obj.sensorModel.tilt, obj.sensorModel.azimuth);
|
||||||
end
|
end
|
||||||
|
|||||||
+18
-3
@@ -1,4 +1,4 @@
|
|||||||
function [partitioning] = partition(obj, agents, objective)
|
function [partitioning, agents] = partition(obj, agents, objective)
|
||||||
arguments (Input)
|
arguments (Input)
|
||||||
obj (1, 1) {mustBeA(obj, "agent")};
|
obj (1, 1) {mustBeA(obj, "agent")};
|
||||||
agents (:, 1) {mustBeA(agents, "cell")};
|
agents (:, 1) {mustBeA(agents, "cell")};
|
||||||
@@ -6,6 +6,7 @@ function [partitioning] = partition(obj, agents, objective)
|
|||||||
end
|
end
|
||||||
arguments (Output)
|
arguments (Output)
|
||||||
partitioning (:, :) double;
|
partitioning (:, :) double;
|
||||||
|
agents (:, 1) cell;
|
||||||
end
|
end
|
||||||
|
|
||||||
nAgents = size(agents, 1);
|
nAgents = size(agents, 1);
|
||||||
@@ -18,8 +19,22 @@ function [partitioning] = partition(obj, agents, objective)
|
|||||||
% minimum threshold that must be exceeded for any assignment.
|
% minimum threshold that must be exceeded for any assignment.
|
||||||
agentPerf = zeros(nPoints, nAgents + 1);
|
agentPerf = zeros(nPoints, nAgents + 1);
|
||||||
for aa = 1:nAgents
|
for aa = 1:nAgents
|
||||||
p = agents{aa}.sensorModel.sensorPerformance(agents{aa}.pos, ...
|
if isa(agents{aa}.sensorModel, "sigmoidSensor")
|
||||||
[objective.X(:), objective.Y(:), zeros(nPoints, 1)]);
|
p = agents{aa}.sensorModel.sensorPerformance(agents{aa}.pos, ...
|
||||||
|
[objective.X(:), objective.Y(:), zeros(nPoints, 1)]);
|
||||||
|
elseif isa(agents{aa}.sensorModel, "rfSensor")
|
||||||
|
otherSensorsIdx = [1:(aa - 1), (aa + 1):size(agents, 1)];
|
||||||
|
otherSensors = agents(otherSensorsIdx);
|
||||||
|
otherSensorsPos = cell2mat(cellfun(@(x) x.pos, otherSensors, "UniformOutput", false));
|
||||||
|
otherSensors = cellfun(@(x) x.sensorModel, otherSensors, "UniformOutput", false);
|
||||||
|
[p, ~, agents{aa}.sensorModel, otherSensors] = agents{aa}.sensorModel.sensorPerformance(agents{aa}.pos, ...
|
||||||
|
[objective.X(:), objective.Y(:), zeros(nPoints, 1)], otherSensorsPos, otherSensors);
|
||||||
|
for k = 1:numel(otherSensorsIdx)
|
||||||
|
agents{otherSensorsIdx(k)}.sensorModel = otherSensors{k};
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("?");
|
||||||
|
end
|
||||||
agentPerf(:, aa) = p(:);
|
agentPerf(:, aa) = p(:);
|
||||||
end
|
end
|
||||||
agentPerf(:, nAgents + 1) = objective.sensorPerformanceMinimum;
|
agentPerf(:, nAgents + 1) = objective.sensorPerformanceMinimum;
|
||||||
|
|||||||
+80
-33
@@ -1,14 +1,15 @@
|
|||||||
function obj = run(obj, domain, partitioning, timestepIndex, index, agents, useDoubleIntegrator, dampingCoeff, dt)
|
function obj = run(obj, domain, partitioning, timestepIndex, index, useDoubleIntegrator, dampingCoeff, dt, optimizeSensorPointing, otherAgents)
|
||||||
arguments (Input)
|
arguments (Input)
|
||||||
obj (1, 1) {mustBeA(obj, "agent")};
|
obj (1, 1) {mustBeA(obj, "agent")};
|
||||||
domain (1, 1) {mustBeGeometry};
|
domain (1, 1) {mustBeGeometry};
|
||||||
partitioning (:, :) double;
|
partitioning (:, :) double;
|
||||||
timestepIndex (1, 1) double;
|
timestepIndex (1, 1) double;
|
||||||
index (1, 1) double;
|
index (1, 1) double;
|
||||||
agents (:, 1) {mustBeA(agents, "cell")};
|
|
||||||
useDoubleIntegrator (1, 1) logical = false;
|
useDoubleIntegrator (1, 1) logical = false;
|
||||||
dampingCoeff (1, 1) double = 2.0;
|
dampingCoeff (1, 1) double = 2.0;
|
||||||
dt (1, 1) double = 1.0;
|
dt (1, 1) double = 1.0;
|
||||||
|
optimizeSensorPointing (1, 1) logical = false;
|
||||||
|
otherAgents (:, 1) cell = cell();
|
||||||
end
|
end
|
||||||
arguments (Output)
|
arguments (Output)
|
||||||
obj (1, 1) {mustBeA(obj, "agent")};
|
obj (1, 1) {mustBeA(obj, "agent")};
|
||||||
@@ -33,33 +34,62 @@ function obj = run(obj, domain, partitioning, timestepIndex, index, agents, useD
|
|||||||
maskedX = domain.objective.X(partitionMask);
|
maskedX = domain.objective.X(partitionMask);
|
||||||
maskedY = domain.objective.Y(partitionMask);
|
maskedY = domain.objective.Y(partitionMask);
|
||||||
|
|
||||||
% Compute agent performance at the current position and each delta position +/- X, Y, Z
|
if isa(obj.sensorModel, "rfSensor")
|
||||||
delta = domain.objective.discretizationStep; % smallest possible step size that gets different results
|
% Extract other agents' sensor models and positions once, outside the delta loop.
|
||||||
deltaApplicator = [0, 0, 0; 1, 0, 0; -1, 0, 0; 0, 1, 0; 0, -1, 0; 0, 0, 1; 0, 0, -1]; % none, +X, -X, +Y, -Y, +Z, -Z
|
% Mask the full-grid RSS caches (filled by partition()) down to this agent's
|
||||||
C_delta = NaN(7, 1); % agent performance at delta steps in each direction
|
% partition subset so sensorPerformance can reuse them for all perturbations.
|
||||||
for ii = 1:7
|
otherSensorsPos = cell2mat(cellfun(@(x) x.pos, otherAgents, "UniformOutput", false));
|
||||||
|
otherSensors = cellfun(@(x) x.sensorModel, otherAgents, "UniformOutput", false);
|
||||||
|
partitionIndices = find(partitionMask);
|
||||||
|
for kk = 1:numel(otherSensors)
|
||||||
|
if ~isempty(otherSensors{kk}.rssCache)
|
||||||
|
otherSensors{kk}.rssCache = otherSensors{kk}.rssCache(partitionIndices);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
% Pre-mask this agent's own full-grid cache to the partition subset.
|
||||||
|
% Used for ii==1 (current position, no perturbation) to avoid recomputing.
|
||||||
|
baseSensorModel = obj.sensorModel;
|
||||||
|
if ~isempty(obj.sensorModel.rssCache)
|
||||||
|
baseSensorModel.rssCache = obj.sensorModel.rssCache(partitionIndices);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if optimizeSensorPointing
|
||||||
|
% Stash actual current sensor model tilt/azimuth before messing with it
|
||||||
|
% in these following hypotheticals
|
||||||
|
tilt = obj.sensorModel.tilt;
|
||||||
|
azimuth = obj.sensorModel.azimuth;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Compute agent performance at the current position and each delta position +/- X, Y, Z, tilt, azimuth
|
||||||
|
deltaPos = domain.objective.discretizationStep; % smallest possible step size that gets different results
|
||||||
|
if optimizeSensorPointing
|
||||||
|
deltaAngle = atan2d(domain.objective.discretizationStep, obj.pos(3)); % smallest possible angle derived from smallest possible step size and current height
|
||||||
|
end
|
||||||
|
deltaApplicator = [0, 0, 0, 0, 0; 1, 0, 0, 0, 0; -1, 0, 0, 0, 0; 0, 1, 0, 0, 0; 0, -1, 0, 0, 0; 0, 0, 1, 0, 0; 0, 0, -1, 0, 0; 0, 0, 0, 1, 0; 0, 0, 0, -1, 0; 0, 0, 0, 0, 1; 0, 0, 0, 0, -1;]; % none, +X, -X, +Y, -Y, +Z, -Z, +tilt, -tilt, +azimuth, -azimuth
|
||||||
|
C_delta = NaN(size(deltaApplicator, 1), 1); % agent performance at delta steps in each direction
|
||||||
|
for ii = 1:size(deltaApplicator, 1)
|
||||||
|
if ~optimizeSensorPointing && ii > 7; break; end
|
||||||
% Apply delta to position
|
% Apply delta to position
|
||||||
pos = obj.pos + delta * deltaApplicator(ii, 1:3);
|
pos = obj.pos + deltaPos * deltaApplicator(ii, 1:3);
|
||||||
|
if optimizeSensorPointing
|
||||||
|
% Apply delta to tilt and azimuth
|
||||||
|
obj.sensorModel.tilt = tilt + deltaAngle * deltaApplicator(ii, 4);
|
||||||
|
obj.sensorModel.azimuth = azimuth + deltaAngle * deltaApplicator(ii, 5);
|
||||||
|
end
|
||||||
|
|
||||||
% Compute performance values on partition
|
% Compute performance values on partition
|
||||||
if ii < 6
|
if isa(obj.sensorModel, "sigmoidSensor")
|
||||||
% Compute sensing performance
|
|
||||||
sensorValues = obj.sensorModel.sensorPerformance(pos, [maskedX, maskedY, zeros(size(maskedX))]); % S_n(omega, P_n) on W_n
|
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.
|
elseif isa(obj.sensorModel, "rfSensor")
|
||||||
% Those values are computed once before the loop and are only
|
if ii == 1
|
||||||
% recomputed when +/- Z steps are applied
|
sensorModelForDelta = baseSensorModel; % reuse partition-step cache; no recompute needed
|
||||||
|
else
|
||||||
|
sensorModelForDelta = obj.sensorModel.clearRssCache;
|
||||||
|
end
|
||||||
|
[sensorValues, ~, ~, ~] = sensorModelForDelta.sensorPerformance(pos, [maskedX, maskedY, zeros(size(maskedX))], otherSensorsPos, otherSensors);
|
||||||
else
|
else
|
||||||
% Redo partitioning for Z stepping only
|
error("?");
|
||||||
partitioning = obj.partition(agents, domain.objective);
|
|
||||||
|
|
||||||
% Recompute partiton-derived performance values for objective
|
|
||||||
partitionMask = partitioning == index;
|
|
||||||
objectiveValues = domain.objective.values(partitionMask); % f(omega) on W_n
|
|
||||||
|
|
||||||
% Recompute partiton-derived performance values for sensing
|
|
||||||
maskedX = domain.objective.X(partitionMask);
|
|
||||||
maskedY = domain.objective.Y(partitionMask);
|
|
||||||
sensorValues = obj.sensorModel.sensorPerformance(pos, [maskedX, maskedY, zeros(size(maskedX))]); % S_n(omega, P_n) on W_n
|
|
||||||
end
|
end
|
||||||
|
|
||||||
% Rearrange data into image arrays
|
% Rearrange data into image arrays
|
||||||
@@ -73,37 +103,54 @@ function obj = run(obj, domain, partitioning, timestepIndex, index, agents, useD
|
|||||||
C_delta(ii) = sum(C(~isnan(C)));
|
C_delta(ii) = sum(C(~isnan(C)));
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if optimizeSensorPointing
|
||||||
|
% Reset sensor model to actual tilt and azimuth angles
|
||||||
|
obj.sensorModel.tilt = tilt;
|
||||||
|
obj.sensorModel.azimuth = azimuth;
|
||||||
|
end
|
||||||
|
|
||||||
% Store agent performance at current time and place
|
% Store agent performance at current time and place
|
||||||
if coder.target('MATLAB')
|
if coder.target('MATLAB')
|
||||||
obj.performance(timestepIndex + 1) = C_delta(1);
|
obj.performance(timestepIndex + 1) = C_delta(1);
|
||||||
end
|
end
|
||||||
|
|
||||||
% Compute gradient by finite central differences
|
% 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)];
|
gradC = [(C_delta(2)-C_delta(3))/(2*deltaPos), (C_delta(4)-C_delta(5))/(2*deltaPos), (C_delta(6)-C_delta(7))/(2*deltaPos)];
|
||||||
|
if optimizeSensorPointing
|
||||||
|
gradC(4) = (C_delta(8) -C_delta(9)) /(2*deltaAngle);
|
||||||
|
gradC(5) = (C_delta(10)-C_delta(11))/(2*deltaAngle);
|
||||||
|
end
|
||||||
|
|
||||||
% Compute scaling factor
|
% Compute scaling factor
|
||||||
targetRate = obj.initialStepSize - obj.stepDecayRate * timestepIndex; % slow down as you get closer
|
targetPosRate = obj.initialStepSize - obj.stepDecayRate * timestepIndex; % slow down as you get closer
|
||||||
gradNorm = norm(gradC);
|
gradPosNorm = norm(gradC(1:3));
|
||||||
|
|
||||||
% Compute unconstrained next state
|
% Compute unconstrained next state
|
||||||
if useDoubleIntegrator
|
if useDoubleIntegrator
|
||||||
% Double-integrator: gradient produces desired acceleration with damping
|
% Double-integrator: gradient produces desired acceleration with damping
|
||||||
if gradNorm < 1e-100
|
if gradPosNorm < 1e-100
|
||||||
a_gradient = zeros(1, 3);
|
a_gradient = zeros(1, 5);
|
||||||
else
|
else
|
||||||
% Scale so steady-state step ≈ targetRate (matching SI behavior)
|
% Scale so steady-state step ≈ targetRate (matching SI behavior)
|
||||||
a_gradient = (targetRate * dampingCoeff / (gradNorm * dt)) * gradC;
|
a_gradient = (targetPosRate * dampingCoeff / (gradPosNorm * dt)) * gradC;
|
||||||
end
|
end
|
||||||
% Semi-implicit Euler: unconditionally stable for any dampingCoeff and dt
|
% Semi-implicit Euler: unconditionally stable for any dampingCoeff and dt
|
||||||
obj.vel = (obj.vel + a_gradient * dt) / (1 + dampingCoeff * dt);
|
obj.vel = (obj.vel + a_gradient(1:3) * dt) / (1 + dampingCoeff * dt);
|
||||||
obj.pos = obj.lastPos + obj.vel * dt;
|
obj.pos = obj.lastPos + obj.vel * dt;
|
||||||
else
|
else
|
||||||
% Single-integrator: gradient directly sets position step
|
% Single-integrator: gradient directly sets position step
|
||||||
if gradNorm >= 1e-100
|
if gradPosNorm >= 1e-100
|
||||||
obj.pos = obj.pos + (targetRate / gradNorm) * gradC;
|
obj.pos = obj.pos + (targetPosRate / gradPosNorm) * gradC(1:3);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
% Update tilt and azimuth, saturating at the decaying maximum allowed step size
|
||||||
|
if optimizeSensorPointing
|
||||||
|
maxAngleStep = obj.initialMaxAngleStepSize - obj.angleStepDecayRate * timestepIndex;
|
||||||
|
obj.sensorModel.tilt = obj.sensorModel.tilt + sign(gradC(4)) * min(abs(gradC(4)), maxAngleStep);
|
||||||
|
obj.sensorModel.azimuth = obj.sensorModel.azimuth + sign(gradC(5)) * min(abs(gradC(5)), maxAngleStep);
|
||||||
|
end
|
||||||
|
|
||||||
% Reinitialize collision geometry in the new position
|
% Reinitialize collision geometry in the new position
|
||||||
d = obj.pos - obj.collisionGeometry.center;
|
d = obj.pos - obj.collisionGeometry.center;
|
||||||
if isa(obj.collisionGeometry, "rectangularPrism")
|
if isa(obj.collisionGeometry, "rectangularPrism")
|
||||||
|
|||||||
+50
-27
@@ -7,45 +7,68 @@ function updatePlots(obj)
|
|||||||
|
|
||||||
% Find change in agent position since last timestep
|
% Find change in agent position since last timestep
|
||||||
deltaPos = obj.pos - obj.lastPos;
|
deltaPos = obj.pos - obj.lastPos;
|
||||||
if all(isnan(deltaPos)) || all(deltaPos == zeros(1, 3))
|
posChanged = ~(all(isnan(deltaPos)) || all(deltaPos == zeros(1, 3)));
|
||||||
% Agent did not move, so nothing has to move on the plots
|
orientChanged = obj.sensorModel.tilt ~= obj.fovGeometry.tilt || ...
|
||||||
|
obj.sensorModel.azimuth ~= obj.fovGeometry.azimuth;
|
||||||
|
|
||||||
|
if ~posChanged && ~orientChanged
|
||||||
return;
|
return;
|
||||||
end
|
end
|
||||||
|
|
||||||
% Scatterplot point positions
|
if posChanged
|
||||||
for ii = 1:size(obj.scatterPoints, 1)
|
% Scatterplot point positions
|
||||||
obj.scatterPoints(ii).XData = obj.pos(1);
|
for ii = 1:size(obj.scatterPoints, 1)
|
||||||
obj.scatterPoints(ii).YData = obj.pos(2);
|
obj.scatterPoints(ii).XData = obj.pos(1);
|
||||||
obj.scatterPoints(ii).ZData = obj.pos(3);
|
obj.scatterPoints(ii).YData = obj.pos(2);
|
||||||
end
|
obj.scatterPoints(ii).ZData = obj.pos(3);
|
||||||
|
|
||||||
% Collision geometry edges
|
|
||||||
for jj = 1:size(obj.collisionGeometry.lines, 2)
|
|
||||||
% Update plotting
|
|
||||||
for ii = 1:size(obj.collisionGeometry.lines(:, jj), 1)
|
|
||||||
obj.collisionGeometry.lines(ii, jj).XData = obj.collisionGeometry.lines(ii, jj).XData + deltaPos(1);
|
|
||||||
obj.collisionGeometry.lines(ii, jj).YData = obj.collisionGeometry.lines(ii, jj).YData + deltaPos(2);
|
|
||||||
obj.collisionGeometry.lines(ii, jj).ZData = obj.collisionGeometry.lines(ii, jj).ZData + deltaPos(3);
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
% Communications geometry edges
|
% Collision geometry edges
|
||||||
if obj.plotCommsGeometry
|
for jj = 1:size(obj.collisionGeometry.lines, 2)
|
||||||
for jj = 1:size(obj.commsGeometry.lines, 2)
|
|
||||||
for ii = 1:size(obj.collisionGeometry.lines(:, jj), 1)
|
for ii = 1:size(obj.collisionGeometry.lines(:, jj), 1)
|
||||||
obj.collisionGeometry.lines(ii, jj).XData = obj.collisionGeometry.lines(ii, jj).XData + deltaPos(1);
|
obj.collisionGeometry.lines(ii, jj).XData = obj.collisionGeometry.lines(ii, jj).XData + deltaPos(1);
|
||||||
obj.collisionGeometry.lines(ii, jj).YData = obj.collisionGeometry.lines(ii, jj).YData + deltaPos(2);
|
obj.collisionGeometry.lines(ii, jj).YData = obj.collisionGeometry.lines(ii, jj).YData + deltaPos(2);
|
||||||
obj.collisionGeometry.lines(ii, jj).ZData = obj.collisionGeometry.lines(ii, jj).ZData + deltaPos(3);
|
obj.collisionGeometry.lines(ii, jj).ZData = obj.collisionGeometry.lines(ii, jj).ZData + deltaPos(3);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
% Communications geometry edges
|
||||||
|
if obj.plotCommsGeometry
|
||||||
|
for jj = 1:size(obj.commsGeometry.lines, 2)
|
||||||
|
for ii = 1:size(obj.collisionGeometry.lines(:, jj), 1)
|
||||||
|
obj.collisionGeometry.lines(ii, jj).XData = obj.collisionGeometry.lines(ii, jj).XData + deltaPos(1);
|
||||||
|
obj.collisionGeometry.lines(ii, jj).YData = obj.collisionGeometry.lines(ii, jj).YData + deltaPos(2);
|
||||||
|
obj.collisionGeometry.lines(ii, jj).ZData = obj.collisionGeometry.lines(ii, jj).ZData + deltaPos(3);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
% Update FOV geometry surfaces
|
% FOV cone: recompute full mesh whenever position or orientation changes
|
||||||
for jj = 1:size(obj.fovGeometry.surface, 2)
|
if ~isempty(obj.fovGeometry.surface)
|
||||||
% Update each plot
|
% Sync fovGeometry state to current agent position and sensor orientation
|
||||||
% obj.fovGeometry = obj.fovGeometry.plot(obj.spatialPlotIndices)
|
obj.fovGeometry = obj.fovGeometry.initialize( ...
|
||||||
obj.fovGeometry.surface(jj).XData = obj.fovGeometry.surface(jj).XData + deltaPos(1);
|
obj.pos, obj.fovGeometry.radius, obj.fovGeometry.height, ...
|
||||||
obj.fovGeometry.surface(jj).YData = obj.fovGeometry.surface(jj).YData + deltaPos(2);
|
obj.fovGeometry.tag, obj.fovGeometry.label, ...
|
||||||
obj.fovGeometry.surface(jj).ZData = obj.fovGeometry.surface(jj).ZData + deltaPos(3);
|
obj.sensorModel.tilt, obj.sensorModel.azimuth);
|
||||||
|
|
||||||
|
% Recompute cone mesh (mirrors cone.plot logic)
|
||||||
|
maxAlt = obj.fovGeometry.surface(1).Parent.ZLim(2);
|
||||||
|
scalingFactor = maxAlt / obj.fovGeometry.height;
|
||||||
|
[X, Y, Z] = cylinder([scalingFactor * obj.fovGeometry.radius, 0], obj.fovGeometry.n);
|
||||||
|
Z = Z * maxAlt;
|
||||||
|
Ry = [cosd(obj.fovGeometry.tilt), 0, -sind(obj.fovGeometry.tilt); 0, 1, 0; sind(obj.fovGeometry.tilt), 0, cosd(obj.fovGeometry.tilt)];
|
||||||
|
Rz = [sind(obj.fovGeometry.azimuth), -cosd(obj.fovGeometry.azimuth), 0; cosd(obj.fovGeometry.azimuth), sind(obj.fovGeometry.azimuth), 0; 0, 0, 1];
|
||||||
|
R = Rz * Ry;
|
||||||
|
pts = R * [X(:)'; Y(:)'; Z(:)' - maxAlt];
|
||||||
|
X = reshape(pts(1, :), size(X)) + obj.pos(1);
|
||||||
|
Y = reshape(pts(2, :), size(Y)) + obj.pos(2);
|
||||||
|
Z = reshape(pts(3, :) + maxAlt, size(Z)) + obj.pos(3) - maxAlt;
|
||||||
|
|
||||||
|
for jj = 1:size(obj.fovGeometry.surface, 2)
|
||||||
|
obj.fovGeometry.surface(jj).XData = X;
|
||||||
|
obj.fovGeometry.surface(jj).YData = Y;
|
||||||
|
obj.fovGeometry.surface(jj).ZData = Z;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
+3
-1
@@ -1,4 +1,4 @@
|
|||||||
function [obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo, useDoubleIntegrator, dampingCoeff, useFixedTopology)
|
function [obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo, useDoubleIntegrator, dampingCoeff, useFixedTopology, optimizeSensorPointing)
|
||||||
arguments (Input)
|
arguments (Input)
|
||||||
obj (1, 1) {mustBeA(obj, "miSim")};
|
obj (1, 1) {mustBeA(obj, "miSim")};
|
||||||
domain (1, 1) {mustBeGeometry};
|
domain (1, 1) {mustBeGeometry};
|
||||||
@@ -14,6 +14,7 @@ function [obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, m
|
|||||||
useDoubleIntegrator (1, 1) logical = false;
|
useDoubleIntegrator (1, 1) logical = false;
|
||||||
dampingCoeff (1, 1) double = 2.0;
|
dampingCoeff (1, 1) double = 2.0;
|
||||||
useFixedTopology (1, 1) logical = false;
|
useFixedTopology (1, 1) logical = false;
|
||||||
|
optimizeSensorPointing (1, 1) logical = false;
|
||||||
end
|
end
|
||||||
arguments (Output)
|
arguments (Output)
|
||||||
obj (1, 1) {mustBeA(obj, "miSim")};
|
obj (1, 1) {mustBeA(obj, "miSim")};
|
||||||
@@ -93,6 +94,7 @@ function [obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, m
|
|||||||
obj.useDoubleIntegrator = useDoubleIntegrator;
|
obj.useDoubleIntegrator = useDoubleIntegrator;
|
||||||
obj.dampingCoeff = dampingCoeff;
|
obj.dampingCoeff = dampingCoeff;
|
||||||
obj.useFixedTopology = useFixedTopology;
|
obj.useFixedTopology = useFixedTopology;
|
||||||
|
obj.optimizeSensorPointing = optimizeSensorPointing;
|
||||||
|
|
||||||
% Compute adjacency matrix and network topology
|
% Compute adjacency matrix and network topology
|
||||||
obj = obj.updateAdjacency();
|
obj = obj.updateAdjacency();
|
||||||
|
|||||||
@@ -52,8 +52,19 @@ BETA_TILT_VEC = scenario.betaTilt; % 1×N
|
|||||||
|
|
||||||
DOMAIN_MIN = scenario.domainMin; % 1×3
|
DOMAIN_MIN = scenario.domainMin; % 1×3
|
||||||
DOMAIN_MAX = scenario.domainMax; % 1×3
|
DOMAIN_MAX = scenario.domainMax; % 1×3
|
||||||
OBJECTIVE_GROUND_POS = scenario.objectivePos; % 1×2
|
|
||||||
OBJECTIVE_VAR = reshape(scenario.objectiveVar, 2, 2); % 2×2 covariance matrix
|
% objectivePos: 2 values per Gaussian component (1 or 2 components supported)
|
||||||
|
nObjComponents = numel(scenario.objectivePos) / 2;
|
||||||
|
assert(mod(numel(scenario.objectivePos), 2) == 0, ...
|
||||||
|
'objectivePos must have an even number of values (2 per Gaussian component)');
|
||||||
|
assert(nObjComponents >= 1 && nObjComponents <= 2, ...
|
||||||
|
'At most 2 objective Gaussian components supported; got %d', nObjComponents);
|
||||||
|
assert(numel(scenario.objectiveVar) == nObjComponents * 4, ...
|
||||||
|
'objectiveVar must have %d values for %d component(s); got %d', ...
|
||||||
|
nObjComponents * 4, nObjComponents, numel(scenario.objectiveVar));
|
||||||
|
OBJECTIVE_GROUND_POS = reshape(scenario.objectivePos, 2, nObjComponents)'; % nObj×2
|
||||||
|
OBJECTIVE_VAR = permute(reshape(scenario.objectiveVar, 2, 2, nObjComponents), [3, 1, 2]); % nObj×2×2
|
||||||
|
|
||||||
SENSOR_PERFORMANCE_MINIMUM = scenario.sensorPerformanceMinimum; % scalar
|
SENSOR_PERFORMANCE_MINIMUM = scenario.sensorPerformanceMinimum; % scalar
|
||||||
|
|
||||||
% Initial UAV positions: flat vector reshaped to N×3
|
% Initial UAV positions: flat vector reshaped to N×3
|
||||||
|
|||||||
+2
-1
@@ -20,6 +20,7 @@ classdef miSim
|
|||||||
useDoubleIntegrator = false; % false = single-integrator, true = double-integrator dynamics
|
useDoubleIntegrator = false; % false = single-integrator, true = double-integrator dynamics
|
||||||
dampingCoeff = 2.0; % velocity-proportional damping for double-integrator mode
|
dampingCoeff = 2.0; % velocity-proportional damping for double-integrator mode
|
||||||
useFixedTopology = false; % false = lesser neighbor (dynamic), true = fixed initial topology
|
useFixedTopology = false; % false = lesser neighbor (dynamic), true = fixed initial topology
|
||||||
|
optimizeSensorPointing = false; % false = fixed sensor tilt/azimuth, true = optimize tilt/azimuth via gradient ascent
|
||||||
artifactName = "";
|
artifactName = "";
|
||||||
f; % main plotting tiled layout figure
|
f; % main plotting tiled layout figure
|
||||||
fPerf; % performance plot figure
|
fPerf; % performance plot figure
|
||||||
@@ -69,7 +70,7 @@ classdef miSim
|
|||||||
obj.obstacles = {rectangularPrism};
|
obj.obstacles = {rectangularPrism};
|
||||||
obj.agents = {agent};
|
obj.agents = {agent};
|
||||||
end
|
end
|
||||||
[obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo);
|
[obj] = initialize(obj, domain, agents, barrierGain, barrierExponent, minAlt, timestep, maxIter, obstacles, makePlots, makeVideo, useDoubleIntegrator, dampingCoeff, useFixedTopology);
|
||||||
[obj] = initializeFromCsv(obj, csvPath);
|
[obj] = initializeFromCsv(obj, csvPath);
|
||||||
[obj] = initializeFromInits(obj, initsPath);
|
[obj] = initializeFromInits(obj, initsPath);
|
||||||
[obj] = plotFromSimHist(obj, initsPath, histPath);
|
[obj] = plotFromSimHist(obj, initsPath, histPath);
|
||||||
|
|||||||
+18
-2
@@ -10,7 +10,13 @@ function [obj] = run(obj)
|
|||||||
% Start video writer
|
% Start video writer
|
||||||
if obj.makeVideo
|
if obj.makeVideo
|
||||||
v = obj.setupVideoWriter();
|
v = obj.setupVideoWriter();
|
||||||
|
drawnow;
|
||||||
v.open();
|
v.open();
|
||||||
|
% Capture reference frame size; used to resize frames that deviate
|
||||||
|
% due to figure reflow during plot updates (e.g. in headless mode).
|
||||||
|
I_ref = getframe(obj.f);
|
||||||
|
v.writeVideo(I_ref);
|
||||||
|
videoFrameSize = [size(I_ref.cdata, 2), size(I_ref.cdata, 1)];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -25,9 +31,16 @@ function [obj] = run(obj)
|
|||||||
obj.validate();
|
obj.validate();
|
||||||
end
|
end
|
||||||
|
|
||||||
|
% Clear RF sensor caches
|
||||||
|
if isa(obj.agents{1}.sensorModel, "rfSensor")
|
||||||
|
for ss = 1:size(obj.agents, 1)
|
||||||
|
obj.agents{ss}.sensorModel = obj.agents{ss}.sensorModel.clearRssCache;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
% Update partitioning before moving (this one is strictly for
|
% Update partitioning before moving (this one is strictly for
|
||||||
% plotting purposes, the real partitioning is done by the agents)
|
% plotting purposes, the real partitioning is done by the agents)
|
||||||
obj.partitioning = obj.agents{1}.partition(obj.agents, obj.domain.objective);
|
[obj.partitioning, obj.agents] = obj.agents{1}.partition(obj.agents, obj.domain.objective);
|
||||||
|
|
||||||
% Determine desired communications links
|
% Determine desired communications links
|
||||||
if ~obj.useFixedTopology
|
if ~obj.useFixedTopology
|
||||||
@@ -42,7 +55,7 @@ function [obj] = run(obj)
|
|||||||
% Moving
|
% Moving
|
||||||
% Iterate over agents to simulate their unconstrained motion
|
% Iterate over agents to simulate their unconstrained motion
|
||||||
for jj = 1:size(obj.agents, 1)
|
for jj = 1:size(obj.agents, 1)
|
||||||
obj.agents{jj} = obj.agents{jj}.run(obj.domain, obj.partitioning, obj.timestepIndex, jj, obj.agents, obj.useDoubleIntegrator, obj.dampingCoeff, obj.timestep);
|
obj.agents{jj} = obj.agents{jj}.run(obj.domain, obj.partitioning, obj.timestepIndex, jj, obj.useDoubleIntegrator, obj.dampingCoeff, obj.timestep, obj.optimizeSensorPointing, obj.agents([1:(jj - 1), (jj + 1):size(obj.agents, 1)]));
|
||||||
end
|
end
|
||||||
|
|
||||||
% Adjust motion determined by unconstrained gradient ascent using
|
% Adjust motion determined by unconstrained gradient ascent using
|
||||||
@@ -66,6 +79,9 @@ function [obj] = run(obj)
|
|||||||
% Write frame in to video
|
% Write frame in to video
|
||||||
if obj.makeVideo
|
if obj.makeVideo
|
||||||
I = getframe(obj.f);
|
I = getframe(obj.f);
|
||||||
|
if size(I.cdata, 2) ~= videoFrameSize(1) || size(I.cdata, 1) ~= videoFrameSize(2)
|
||||||
|
I.cdata = imresize(I.cdata, [videoFrameSize(2), videoFrameSize(1)]);
|
||||||
|
end
|
||||||
v.writeVideo(I);
|
v.writeVideo(I);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+36
-5
@@ -13,10 +13,39 @@ function writeInits(obj)
|
|||||||
|
|
||||||
% Collect agent parameters
|
% Collect agent parameters
|
||||||
collisionRadii = cellfun(@(x) x.collisionGeometry.radius, obj.agents);
|
collisionRadii = cellfun(@(x) x.collisionGeometry.radius, obj.agents);
|
||||||
alphaDist = cellfun(@(x) x.sensorModel.alphaDist, obj.agents);
|
if isprop(obj.agents{1}.sensorModel, "alphaDist")
|
||||||
betaDist = cellfun(@(x) x.sensorModel.betaDist, obj.agents);
|
% sigmoidSensor parameters
|
||||||
alphaTilt = cellfun(@(x) x.sensorModel.alphaTilt, obj.agents);
|
alphaDist = cellfun(@(x) x.sensorModel.alphaDist, obj.agents);
|
||||||
betaTilt = cellfun(@(x) x.sensorModel.betaTilt, obj.agents);
|
betaDist = cellfun(@(x) x.sensorModel.betaDist, obj.agents);
|
||||||
|
alphaTilt = cellfun(@(x) x.sensorModel.alphaTilt, obj.agents);
|
||||||
|
betaTilt = cellfun(@(x) x.sensorModel.betaTilt, obj.agents);
|
||||||
|
|
||||||
|
% others to zero
|
||||||
|
lossExponent = zeros(size(obj.agents));
|
||||||
|
P_TX = zeros(size(obj.agents));
|
||||||
|
BW = zeros(size(obj.agents));
|
||||||
|
f_c = zeros(size(obj.agents));
|
||||||
|
G_RX_dBi = zeros(size(obj.agents));
|
||||||
|
beamwidthExponent = zeros(size(obj.agents));
|
||||||
|
|
||||||
|
elseif isprop(obj.agents{1}.sensorModel, "P_TX")
|
||||||
|
% rfSensor parameters
|
||||||
|
lossExponent = cellfun(@(x) x.sensorModel.lossExponent, obj.agents);
|
||||||
|
P_TX = cellfun(@(x) x.sensorModel.P_TX, obj.agents);
|
||||||
|
BW = cellfun(@(x) x.sensorModel.BW, obj.agents);
|
||||||
|
f_c = cellfun(@(x) x.sensorModel.f_c, obj.agents);
|
||||||
|
G_RX_dBi = cellfun(@(x) x.sensorModel.G_RX_dBi, obj.agents);
|
||||||
|
beamwidthExponent = cellfun(@(x) x.sensorModel.beamwidthExponent, obj.agents);
|
||||||
|
|
||||||
|
% others to zero
|
||||||
|
alphaDist = zeros(size(obj.agents));
|
||||||
|
betaDist = zeros(size(obj.agents));
|
||||||
|
alphaTilt = zeros(size(obj.agents));
|
||||||
|
betaTilt = zeros(size(obj.agents));
|
||||||
|
end
|
||||||
|
% joint parameters
|
||||||
|
tilt = cellfun(@(x) x.sensorModel.tilt, obj.agents);
|
||||||
|
azimuth = cellfun(@(x) x.sensorModel.azimuth, obj.agents);
|
||||||
comRanges = cellfun(@(x) x.commsGeometry.radius, obj.agents);
|
comRanges = cellfun(@(x) x.commsGeometry.radius, obj.agents);
|
||||||
initialStepSize = cellfun(@(x) x.initialStepSize, obj.agents);
|
initialStepSize = cellfun(@(x) x.initialStepSize, obj.agents);
|
||||||
pos = cell2mat(cellfun(@(x) x.pos, obj.agents, 'UniformOutput', false));
|
pos = cell2mat(cellfun(@(x) x.pos, obj.agents, 'UniformOutput', false));
|
||||||
@@ -30,7 +59,9 @@ function writeInits(obj)
|
|||||||
"barrierGain", obj.barrierGain, "barrierExponent", obj.barrierExponent, "numObstacles", numInputObs, ...
|
"barrierGain", obj.barrierGain, "barrierExponent", obj.barrierExponent, "numObstacles", numInputObs, ...
|
||||||
"numAgents", size(obj.agents, 1), "collisionRadius", collisionRadii, "comRange", comRanges, ...
|
"numAgents", size(obj.agents, 1), "collisionRadius", collisionRadii, "comRange", comRanges, ...
|
||||||
"useDoubleIntegrator", obj.useDoubleIntegrator, "dampingCoeff", obj.dampingCoeff, "useFixedTopology", obj.useFixedTopology, ...
|
"useDoubleIntegrator", obj.useDoubleIntegrator, "dampingCoeff", obj.dampingCoeff, "useFixedTopology", obj.useFixedTopology, ...
|
||||||
"alphaDist", alphaDist, "betaDist", betaDist, "alphaTilt", alphaTilt, "betaTilt", betaTilt, ...
|
"tilt", tilt, "azimuth", azimuth, ... % joint sensor parameters
|
||||||
|
"alphaDist", alphaDist, "betaDist", betaDist, "alphaTilt", alphaTilt, "betaTilt", betaTilt, ... % sigmoid sensor parameters
|
||||||
|
"lossExponent", lossExponent, "P_TX", P_TX, "BW", BW, "f_c", f_c, "G_RX_dBi", G_RX_dBi, "beamwidthExponent", beamwidthExponent, ... % RF sensor parameters
|
||||||
... % ^^^ PARAMETERS ^^^ | vvv STATES vvv
|
... % ^^^ PARAMETERS ^^^ | vvv STATES vvv
|
||||||
"pos", pos, "objectivePos", obj.domain.objective.groundPos, "objectiveSigma", obj.domain.objective.objectiveSigma, ...
|
"pos", pos, "objectivePos", obj.domain.objective.groundPos, "objectiveSigma", obj.domain.objective.objectiveSigma, ...
|
||||||
"domainMin", obj.domain.minCorner, "domainMax", obj.domain.maxCorner, ...
|
"domainMin", obj.domain.minCorner, "domainMax", obj.domain.maxCorner, ...
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
function value = RSS(obj, d, dx, dy, dz)
|
||||||
|
arguments (Input)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||||
|
d (:, 1) double;
|
||||||
|
dx (:, 1) double;
|
||||||
|
dy (:, 1) double;
|
||||||
|
dz (:, 1) double;
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
value (:, 1) double
|
||||||
|
end
|
||||||
|
% Boresight unit vector: [st*sa, st*ca, -ct]
|
||||||
|
% Target direction unit vector: [dx, dy, dz] / d
|
||||||
|
% cos_theta = dot product of the two, computed without per-point trig.
|
||||||
|
st = sind(obj.tilt);
|
||||||
|
ct = cosd(obj.tilt);
|
||||||
|
sa = sind(obj.azimuth);
|
||||||
|
ca = cosd(obj.azimuth);
|
||||||
|
cos_theta = (st .* (dx .* sa + dy .* ca) - ct .* dz) ./ max(d, eps);
|
||||||
|
cos_theta = max(-1, min(1, cos_theta));
|
||||||
|
theta = acosd(cos_theta);
|
||||||
|
gain = 10 .* obj.beamwidthExponent .* log10((1 + cosd(theta)) ./ 2);
|
||||||
|
value = obj.P_TX_dBm + gain + obj.G_RX_dBi - obj.pathLoss(d);
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
function obj = clearRssCache(obj)
|
||||||
|
arguments (Input)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||||
|
end
|
||||||
|
|
||||||
|
obj.rssCache = double.empty(0, 1);
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
function [d, dx, dy, dz] = computePointToPoints(~, agentPos, targetPos)
|
||||||
|
dx = targetPos(:,1) - agentPos(1);
|
||||||
|
dy = targetPos(:,2) - agentPos(2);
|
||||||
|
dz = targetPos(:,3) - agentPos(3);
|
||||||
|
d = sqrt(dx.^2 + dy.^2 + dz.^2);
|
||||||
|
end
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
function value = halfAngle(obj)
|
||||||
|
arguments (Input)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
value (1, 1) double;
|
||||||
|
end
|
||||||
|
% Sweep angular offset from boresight by evaluating transmitterGain at
|
||||||
|
% (obj.tilt + dtheta, obj.azimuth). The cosine difference identity guarantees
|
||||||
|
% the resulting angular offset from boresight equals dtheta exactly,
|
||||||
|
% independent of the actual pointing direction.
|
||||||
|
dtheta = (0:0.1:179.9)';
|
||||||
|
gain = obj.transmitterGain(obj.tilt + dtheta, obj.azimuth * ones(size(dtheta)));
|
||||||
|
target = gain(1) - 3;
|
||||||
|
idx = find(gain <= target, 1);
|
||||||
|
if isempty(idx) || idx == 1
|
||||||
|
value = dtheta(end);
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
% Linear interpolation between bracketing samples
|
||||||
|
value = dtheta(idx-1) + (target - gain(idx-1)) * ...
|
||||||
|
(dtheta(idx) - dtheta(idx-1)) / (gain(idx) - gain(idx-1));
|
||||||
|
end
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
function obj = initialize(obj, txPower, bandwidth, centerFreq, rxGain_dBi, beamwidthExponent, tilt, azimuth, lossExponent)
|
||||||
|
arguments (Input)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")}
|
||||||
|
txPower (1, 1) double;
|
||||||
|
bandwidth (1, 1) double;
|
||||||
|
centerFreq (1, 1) double;
|
||||||
|
rxGain_dBi (1, 1) double;
|
||||||
|
beamwidthExponent (1, 1) double;
|
||||||
|
tilt (1, 1) double = 0;
|
||||||
|
azimuth (1, 1) double = 0;
|
||||||
|
lossExponent (1, 1) double = NaN;
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")}
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Provided values
|
||||||
|
obj.P_TX = txPower; % Transmit power (W)
|
||||||
|
obj.BW = bandwidth; % Bandwidth (Hz)
|
||||||
|
obj.f_c = centerFreq; % Center frequency (Hz)
|
||||||
|
obj.G_RX_dBi = rxGain_dBi; % Receiving Antenna Gain (dBi)
|
||||||
|
obj.beamwidthExponent = beamwidthExponent; % Defines how focused the antenna beam is
|
||||||
|
obj.lossExponent = lossExponent;
|
||||||
|
|
||||||
|
% Define initial antenna pointing
|
||||||
|
obj.tilt = tilt;
|
||||||
|
obj.azimuth = azimuth;
|
||||||
|
|
||||||
|
%% Computed values
|
||||||
|
obj.P_TX_dBm = 10*log10(obj.P_TX/1e-3); % Transmit power in dBm
|
||||||
|
obj.N = obj.k_B * obj.T_0 * obj.BW; % Thermal noise
|
||||||
|
end
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
function L_FSPL_dB = pathLoss(obj, d)
|
||||||
|
arguments (Input)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||||
|
d (:, 1) double; % distance from TX to RX
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
L_FSPL_dB (:, 1) double
|
||||||
|
end
|
||||||
|
|
||||||
|
% Free Space Path Loss (dB); d clamped away from zero (log undefined at d=0)
|
||||||
|
L_FSPL_dB = obj.lossExponent * 10 * log10(max(d, eps)) + 20 * log10(obj.f_c) + 20 * log10((4*pi)/obj.c);
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
function f = plot(obj, altitude, otherSensorsPos, otherSensors)
|
||||||
|
arguments (Input)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||||
|
altitude (1, 1) double;
|
||||||
|
otherSensorsPos (:, 3) double = NaN(0, 3);
|
||||||
|
otherSensors (:, 1) cell = cell(0, 1);
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
f (1, 1) {mustBeA(f, "matlab.ui.Figure")};
|
||||||
|
end
|
||||||
|
|
||||||
|
% Clear local caches so this visualization always uses its own grid
|
||||||
|
obj.rssCache = [];
|
||||||
|
for ii = 1:numel(otherSensors)
|
||||||
|
otherSensors{ii}.rssCache = [];
|
||||||
|
end
|
||||||
|
|
||||||
|
% bias other sensors altitudes appropriately
|
||||||
|
otherSensorsPos = otherSensorsPos + [0, 0, altitude];
|
||||||
|
|
||||||
|
% Create grid on which to evalute SINR, SNR
|
||||||
|
agentPos = [0, 0, altitude];
|
||||||
|
d = 10;
|
||||||
|
if ~isempty(otherSensorsPos)
|
||||||
|
d = max(otherSensorsPos(:, 3) * 0.55);
|
||||||
|
d = max(d, max(vecnorm(otherSensorsPos(:, 1:2), 2, 2)) * 1.25);
|
||||||
|
end
|
||||||
|
c = 0.1;
|
||||||
|
d = ceil(d / c) * c;
|
||||||
|
distances = -d:c:d;
|
||||||
|
[targetPosX, targetPosY] = meshgrid(distances, distances);
|
||||||
|
|
||||||
|
% Compute SINR, SNR
|
||||||
|
[SINR, ~] = obj.sensorPerformance(agentPos, [targetPosX(:), targetPosY(:), zeros(size(targetPosX(:)))], otherSensorsPos, otherSensors);
|
||||||
|
SINR = reshape(SINR, size(targetPosX));
|
||||||
|
|
||||||
|
% normalize in linear scale
|
||||||
|
% SINR = 10.^(SINR/10); SINR = SINR ./ max(SINR(:)); SINR = 10 * log10(SINR);
|
||||||
|
|
||||||
|
% Collect sensor positions and boresight parameters for overlay
|
||||||
|
sensorTilts = [obj.tilt; cellfun(@(s) s.tilt, otherSensors)];
|
||||||
|
sensorAzimuths = [obj.azimuth; cellfun(@(s) s.azimuth, otherSensors)];
|
||||||
|
tailScale = 0.5 * d;
|
||||||
|
|
||||||
|
f = figure;
|
||||||
|
surf(targetPosX, targetPosY, zeros(size(targetPosX)), SINR, "EdgeColor", "none");
|
||||||
|
axis(f.Children(1), "image");
|
||||||
|
colormap(f.Children(1), "hot");
|
||||||
|
title("Ground User SINR and -3 dB antenna gain regions");
|
||||||
|
subtitle(sprintf("%d interfering source(s)", size(otherSensorsPos, 1)));
|
||||||
|
c = colorbar;
|
||||||
|
ylabel(c, "SINR (dB)");
|
||||||
|
xlabel("X (m)");
|
||||||
|
ylabel("Y (m)");
|
||||||
|
hold(f.Children(2), "on");
|
||||||
|
scatter3(0, 0, altitude, 100, 'ko', "LineWidth", 2);
|
||||||
|
scatter3(otherSensorsPos(:, 1), otherSensorsPos(:, 2), otherSensorsPos(:, 3), 100, "bx", "LineWidth", 2);
|
||||||
|
qSelf = quiver3(0, 0, altitude, ...
|
||||||
|
tailScale * sind(obj.tilt) * sind(obj.azimuth), ...
|
||||||
|
tailScale * sind(obj.tilt) * cosd(obj.azimuth), ...
|
||||||
|
-tailScale * cosd(obj.tilt), ...
|
||||||
|
0, 'k', 'LineWidth', 1.5);
|
||||||
|
qSelf.MaxHeadSize = 0.75;
|
||||||
|
if ~isempty(otherSensors)
|
||||||
|
qOthers = quiver3(otherSensorsPos(:,1), otherSensorsPos(:,2), otherSensorsPos(:,3), ...
|
||||||
|
tailScale .* sind(sensorTilts(2:end)) .* sind(sensorAzimuths(2:end)), ...
|
||||||
|
tailScale .* sind(sensorTilts(2:end)) .* cosd(sensorAzimuths(2:end)), ...
|
||||||
|
-tailScale .* cosd(sensorTilts(2:end)), ...
|
||||||
|
0, 'b', 'LineWidth', 1.5);
|
||||||
|
qOthers.MaxHeadSize = 0.75;
|
||||||
|
end
|
||||||
|
% Draw half-angle cones co-boresighted with each quiver arrow
|
||||||
|
N = 48;
|
||||||
|
phi = linspace(0, 2*pi, N);
|
||||||
|
[PHI, S] = meshgrid(phi, [0; 1]); % row 1 = apex (s=0), row 2 = base (s=1)
|
||||||
|
allSensors = [{obj}; otherSensors];
|
||||||
|
allPos = [[0, 0, altitude]; otherSensorsPos];
|
||||||
|
for ii = 1:numel(allSensors)
|
||||||
|
ha = allSensors{ii}.halfAngle();
|
||||||
|
tlt = sensorTilts(ii);
|
||||||
|
az = sensorAzimuths(ii);
|
||||||
|
pos = allPos(ii, :);
|
||||||
|
% Cone length: enough that the axis tip is guaranteed below z=0
|
||||||
|
coneLength = 1.1 * pos(3) / max(cosd(tlt), 0.1);
|
||||||
|
% Nadir cone mesh: apex at origin, base at z = -coneLength
|
||||||
|
cX = S .* coneLength .* tand(ha) .* cos(PHI);
|
||||||
|
cY = S .* coneLength .* tand(ha) .* sin(PHI);
|
||||||
|
cZ = -S .* coneLength;
|
||||||
|
% Rotate nadir → boresight (same convention as quiver arrows)
|
||||||
|
Ry = [cosd(tlt), 0, -sind(tlt); 0, 1, 0; sind(tlt), 0, cosd(tlt)];
|
||||||
|
Rz = [sind(az), -cosd(az), 0; cosd(az), sind(az), 0; 0, 0, 1];
|
||||||
|
R = Rz * Ry;
|
||||||
|
pts = R * [cX(:)'; cY(:)'; cZ(:)'];
|
||||||
|
cX = reshape(pts(1,:), size(cX)) + pos(1);
|
||||||
|
cY = reshape(pts(2,:), size(cY)) + pos(2);
|
||||||
|
cZ = reshape(pts(3,:), size(cZ)) + pos(3);
|
||||||
|
if ii == 1
|
||||||
|
fc = [0, 0, 0];
|
||||||
|
else
|
||||||
|
fc = [0, 0, 1];
|
||||||
|
end
|
||||||
|
surf(cX, cY, cZ, "FaceColor", fc, "FaceAlpha", 0.15, "EdgeColor", "none");
|
||||||
|
|
||||||
|
% Conic section: intersect each cone generator with z=0
|
||||||
|
b_vec = R * [0; 0; -1];
|
||||||
|
u_vec = R * [1; 0; 0];
|
||||||
|
v_vec = R * [0; 1; 0];
|
||||||
|
phi_sec = linspace(0, 2*pi, 720)';
|
||||||
|
dirs = cosd(ha) .* b_vec' + sind(ha) .* (cos(phi_sec) .* u_vec' + sin(phi_sec) .* v_vec');
|
||||||
|
t_sec = -pos(3) ./ dirs(:, 3);
|
||||||
|
t_sec(t_sec <= 0) = NaN;
|
||||||
|
sx = pos(1) + t_sec .* dirs(:, 1);
|
||||||
|
sy = pos(2) + t_sec .* dirs(:, 2);
|
||||||
|
plot3(sx, sy, zeros(size(sx)), "Color", fc, "LineWidth", 2);
|
||||||
|
end
|
||||||
|
clim(f.Children(2), [min(SINR(:)), max(SINR(:))]);
|
||||||
|
xlim(f.Children(2), [-d, d]);
|
||||||
|
ylim(f.Children(2), [-d, d]);
|
||||||
|
hold(f.Children(2), "off");
|
||||||
|
zlim([0, Inf]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
function f = plotParameters(obj)
|
||||||
|
arguments (Input)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
f (1, 1) {mustBeA(f, "matlab.ui.Figure")};
|
||||||
|
end
|
||||||
|
|
||||||
|
% Agent altitude layers and angle sample points
|
||||||
|
alt_values = 10.^[1, 2, 3, 4];
|
||||||
|
t_values = 0:2.5:87.5; % 0=nadir (center), <90=near horizon (edge)
|
||||||
|
a_values = 0:2.5:360;
|
||||||
|
|
||||||
|
[T, A] = meshgrid(t_values, a_values); % Naz x Nel
|
||||||
|
Ar = deg2rad(A);
|
||||||
|
|
||||||
|
f = figure;
|
||||||
|
hold("on");
|
||||||
|
|
||||||
|
for ii = 1:numel(alt_values)
|
||||||
|
alt = alt_values(ii);
|
||||||
|
|
||||||
|
% For agent at altitude alt, ground target at tilt T has slant distance:
|
||||||
|
D = alt ./ cosd(T);
|
||||||
|
|
||||||
|
% Compute RSS for each (d, t, a) triple
|
||||||
|
rss = obj.RSS(D(:), T(:), A(:));
|
||||||
|
Fslice = reshape(rss, size(D));
|
||||||
|
|
||||||
|
% Disc geometry: t=0 (nadir) -> center, t~90 (horizon) -> edge
|
||||||
|
r = log10(alt) .* T ./ 90;
|
||||||
|
X = r .* cos(Ar);
|
||||||
|
Y = r .* sin(Ar);
|
||||||
|
Z = log10(alt) * ones(size(X));
|
||||||
|
|
||||||
|
hs = surf(X, Y, Z, Fslice);
|
||||||
|
hs.EdgeColor = 'none';
|
||||||
|
hs.FaceColor = 'interp';
|
||||||
|
hs.FaceAlpha = 0.25;
|
||||||
|
end
|
||||||
|
|
||||||
|
colormap(turbo);
|
||||||
|
c = colorbar; c.Label.String = "Received Signal Strength (dB)";
|
||||||
|
daspect([1 1 0.2]);
|
||||||
|
xlabel('X (log_{10} units)'); ylabel('Y (log_{10} units)'); zlabel('log_{10} Altitude (m)');
|
||||||
|
set(gca, 'ZDir', 'reverse');
|
||||||
|
view(3);
|
||||||
|
axis("vis3d");
|
||||||
|
grid("on");
|
||||||
|
scatter3(0, 0, 0, 'rx');
|
||||||
|
hold("off");
|
||||||
|
end
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
function f = plotPerformance(obj, altitude, otherSensorsPos, otherSensors)
|
||||||
|
arguments (Input)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||||
|
altitude (1, 1) double;
|
||||||
|
otherSensorsPos (:, 3) double = NaN(0, 3);
|
||||||
|
otherSensors (:, 1) cell = cell(0, 1);
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
f (1, 1) {mustBeA(f, "matlab.ui.Figure")};
|
||||||
|
end
|
||||||
|
|
||||||
|
% Clear local caches so this visualization always uses its own grid
|
||||||
|
obj.rssCache = [];
|
||||||
|
for ii = 1:numel(otherSensors)
|
||||||
|
otherSensors{ii}.rssCache = [];
|
||||||
|
end
|
||||||
|
|
||||||
|
% bias other sensors altitudes appropriately
|
||||||
|
otherSensorsPos = otherSensorsPos + [0, 0, altitude];
|
||||||
|
|
||||||
|
% Create grid on which to evalute SINR, SNR
|
||||||
|
agentPos = [0, 0, altitude];
|
||||||
|
d = 10;
|
||||||
|
if ~isempty(otherSensorsPos)
|
||||||
|
d = max(d, max(vecnorm(otherSensorsPos(:, 1:2), 2, 2)) * 1.25);
|
||||||
|
end
|
||||||
|
c = 0.1;
|
||||||
|
d = ceil(d / c) * c;
|
||||||
|
distances = -d:c:d;
|
||||||
|
[targetPosX, targetPosY] = meshgrid(distances, distances);
|
||||||
|
|
||||||
|
% Compute SINR, SNR
|
||||||
|
[SINR, SNR] = obj.sensorPerformance(agentPos, [targetPosX(:), targetPosY(:), zeros(size(targetPosX(:)))], otherSensorsPos, otherSensors);
|
||||||
|
SINR = reshape(SINR, size(targetPosX));
|
||||||
|
SNR = reshape(SNR, size(targetPosX));
|
||||||
|
|
||||||
|
% normalize in linear scale
|
||||||
|
SINR = 10.^(SINR/10); SINR = SINR ./ max(SINR(:)); SINR = 10 * log10(SINR);
|
||||||
|
SNR = 10.^(SNR/10); SNR = SNR ./ max(SNR(:)); SNR = 10 * log10(SNR);
|
||||||
|
|
||||||
|
% Collect sensor positions and boresight parameters for overlay
|
||||||
|
sensorXY = [0, 0; otherSensorsPos(:, 1:2)];
|
||||||
|
sensorTilts = [obj.tilt; cellfun(@(s) s.tilt, otherSensors)];
|
||||||
|
sensorAzimuths = [obj.azimuth; cellfun(@(s) s.azimuth, otherSensors)];
|
||||||
|
tailScale = 0.5 * d;
|
||||||
|
|
||||||
|
f = figure;
|
||||||
|
tiledlayout(1, 2, TileSpacing="compact", Padding="compact");
|
||||||
|
|
||||||
|
nexttile;
|
||||||
|
imagesc(distances, distances, SNR);
|
||||||
|
axis("image"); set(gca, 'YDir', 'normal');
|
||||||
|
colorbar; xlabel("X (m)"); ylabel("Y (m)");
|
||||||
|
title("Linearly Normalized SNR (dB)");
|
||||||
|
subtitle("No interfering sources");
|
||||||
|
addSensorOverlay(gca, sensorXY(1, 1:2), sensorTilts(1, 1), sensorAzimuths(1, 1), tailScale);
|
||||||
|
|
||||||
|
nexttile;
|
||||||
|
imagesc(distances, distances, SINR);
|
||||||
|
axis("image"); set(gca, 'YDir', 'normal');
|
||||||
|
colorbar; xlabel("X (m)"); ylabel("Y (m)");
|
||||||
|
title("Linearly Normalized SINR (dB)");
|
||||||
|
subtitle(sprintf("%d interfering source(s)", size(otherSensorsPos, 1)));
|
||||||
|
addSensorOverlay(gca, sensorXY, sensorTilts, sensorAzimuths, tailScale);
|
||||||
|
end
|
||||||
|
|
||||||
|
function addSensorOverlay(ax, sensorXY, tilts, azimuths, tailScale)
|
||||||
|
% Draw a marker + boresight arrow for each sensor.
|
||||||
|
% Tail direction follows azimuth convention (0=+Y, 90=+X, clockwise).
|
||||||
|
% Tail length = tailScale * sind(tilt), so nadir (0°) has no tail and
|
||||||
|
% horizon (90°) has the full tailScale length.
|
||||||
|
hold(ax, 'on');
|
||||||
|
for ii = 1:size(sensorXY, 1)
|
||||||
|
x = sensorXY(ii, 1);
|
||||||
|
y = sensorXY(ii, 2);
|
||||||
|
if ii == 1
|
||||||
|
c = [0, 0, 0];
|
||||||
|
mk = 'o';
|
||||||
|
else
|
||||||
|
c = [0.9, 0.2, 0.2];
|
||||||
|
mk = 'x';
|
||||||
|
end
|
||||||
|
scatter(ax, x, y, 80, c, mk, LineWidth=2);
|
||||||
|
if tilts(ii) > 0
|
||||||
|
u = tailScale * sind(tilts(ii)) * sind(azimuths(ii));
|
||||||
|
v = tailScale * sind(tilts(ii)) * cosd(azimuths(ii));
|
||||||
|
quiver(ax, x, y, u, v, 0, Color=c, LineWidth=2, MaxHeadSize=1.0);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
hold(ax, 'off');
|
||||||
|
end
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
classdef rfSensor
|
||||||
|
properties (SetAccess = private, GetAccess = public)
|
||||||
|
% Physical parameters
|
||||||
|
c = 3e8; % Speed of light (m/s)
|
||||||
|
k_B = 1.38e-23 % Boltzmann constant (W/Hz/K) for thermal noise model
|
||||||
|
T_0 = 300; % Ambient temperature (Kelvin) for thermal noise model
|
||||||
|
lossExponent = NaN; % Path loss exponent (2 for free space, up to 6 for the lossiest environments)
|
||||||
|
% Sensor parameters
|
||||||
|
P_TX = NaN; % Transmit power (Watts)
|
||||||
|
BW = NaN; % Bandwidth (Hz)
|
||||||
|
f_c = NaN; % Center frequency (Hz)
|
||||||
|
G_RX_dBi = NaN; % Receiver antenna gain
|
||||||
|
beamwidthExponent = NaN; % Antenna beamwidth exponent for cosine radiation pattern, larger exponent -> narrower beam
|
||||||
|
% Values computed at initialization
|
||||||
|
P_TX_dBm = NaN; % Transmit power (dBm)
|
||||||
|
N = NaN; % Thermal noise
|
||||||
|
% Cached state (per timestep)
|
||||||
|
end
|
||||||
|
properties (Access = public)
|
||||||
|
tilt = NaN; % Antenna boresight tilt (deg): 0=nadir, 90=horizon
|
||||||
|
azimuth = NaN; % Antenna boresight azimuth (deg): 0=+y, 90=+x, 180=-y, 270=-x
|
||||||
|
rssCache (:,1) double = double.empty(0,1); % linear-scale RSS to last ground targets grid
|
||||||
|
end
|
||||||
|
|
||||||
|
methods (Access = public)
|
||||||
|
[obj] = initialize(obj, txPower, bandwidth, centerFreq, rxGain, beamwidthExponent, tilt, azimuth); % initialize sensor, define parameters
|
||||||
|
[SINR, SNR, obj, otherSensors] = sensorPerformance(obj, agentPos, targetPos, otherSensorsPos, otherSensors); % determine sensor performance for a given single sensor and target geometry
|
||||||
|
[d, dx, dy, dz] = computePointToPoints(obj, agentPos, targetPos);
|
||||||
|
[value] = halfAngle(obj); % tilt angle (deg) at which sensor performance is halved
|
||||||
|
[f] = plotParameters(obj); % debug, plot sensor response as a function of distance and tilt angle
|
||||||
|
[f] = plotPerformance(obj, altitude, otherSensorsPos, otherSensors); % debug, plot SNR or SINR ground heatmap for a given geometry
|
||||||
|
[f] = plot(obj, altitude, otherSensorsPos, otherSensors);
|
||||||
|
obj = clearRssCache(obj);
|
||||||
|
end
|
||||||
|
methods (Access = private)
|
||||||
|
x = RSS(obj, d, dx, dy, dz); % Received signal strength (function of distance and tilt angle)
|
||||||
|
G_TX_dB = transmitterGain(obj, t, a); % Antenna gain for a given TX/RX pair
|
||||||
|
L_FSPL_dB = pathLoss(obj, d); % Free space path loss for a given TX/RX pair
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
function [SINR, SNR, obj, otherSensors] = sensorPerformance(obj, agentPos, targetPos, otherSensorsPos, otherSensors)
|
||||||
|
arguments (Input)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||||
|
agentPos (1, 3) double;
|
||||||
|
targetPos (:, 3) double;
|
||||||
|
otherSensorsPos (:, 3) double = [];
|
||||||
|
otherSensors (:, 1) cell = {};
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
SINR (:, 1) double;
|
||||||
|
SNR (:, 1) double;
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||||
|
otherSensors (:, 1) cell;
|
||||||
|
end
|
||||||
|
assert(size(otherSensorsPos, 1) == size(otherSensors, 1), "Mismatch in number of other sensor positions (%d) and number of other sensors (%d) provided", size(otherSensorsPos, 1), size(otherSensors, 1));
|
||||||
|
|
||||||
|
if isempty(obj.rssCache)
|
||||||
|
[d, dx, dy, dz] = obj.computePointToPoints(agentPos, targetPos);
|
||||||
|
obj.rssCache = 1e-3 .* 10 .^ (0.1 .* obj.RSS(d, dx, dy, dz)); % dBm → W
|
||||||
|
end
|
||||||
|
S = obj.rssCache;
|
||||||
|
|
||||||
|
I = zeros(size(S));
|
||||||
|
for ii = 1:size(otherSensors, 1)
|
||||||
|
if isempty(otherSensors{ii}.rssCache)
|
||||||
|
[d_o, dx_o, dy_o, dz_o] = otherSensors{ii}.computePointToPoints(otherSensorsPos(ii, 1:3), targetPos);
|
||||||
|
otherSensors{ii}.rssCache = 1e-3 .* 10 .^ (0.1 .* otherSensors{ii}.RSS(d_o, dx_o, dy_o, dz_o)); % dBm → W
|
||||||
|
end
|
||||||
|
I = I + otherSensors{ii}.rssCache;
|
||||||
|
end
|
||||||
|
|
||||||
|
SINR = 10*log10(S ./ (I + obj.N));
|
||||||
|
SNR = 10*log10(S ./ obj.N);
|
||||||
|
end
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
function value = transmitterGain(obj, t, a)
|
||||||
|
arguments (Input)
|
||||||
|
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||||
|
t (:, 1) double; % LOS tilt angle
|
||||||
|
a (:, 1) double; % LOS azimuth angle
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
value (:, 1) double
|
||||||
|
end
|
||||||
|
if ~isequal(size(t), size(a))
|
||||||
|
error("t and a must be the same size");
|
||||||
|
end
|
||||||
|
|
||||||
|
% Angular offset from boresight via spherical law of cosines
|
||||||
|
% Convention: t=0° nadir, t=90° horizon; a=0° +y, a=90° +x
|
||||||
|
cos_theta = sind(obj.tilt) .* sind(t) .* cosd(a - obj.azimuth) + ...
|
||||||
|
cosd(obj.tilt) .* cosd(t);
|
||||||
|
cos_theta = max(-1, min(1, cos_theta)); % clamp for numerical safety
|
||||||
|
theta = acosd(cos_theta);
|
||||||
|
|
||||||
|
% Cardioid family: peak at boresight (theta=0), null opposite (theta=180°)
|
||||||
|
value = 10 .* obj.beamwidthExponent .* log10((1 + cosd(theta)) ./ 2);
|
||||||
|
end
|
||||||
@@ -11,19 +11,26 @@ function f = plot(obj, ind, f)
|
|||||||
% Create axes if they don't already exist
|
% Create axes if they don't already exist
|
||||||
f = firstPlotSetup(f);
|
f = firstPlotSetup(f);
|
||||||
|
|
||||||
|
normalized = obj.values ./ sum(obj.values, "all");
|
||||||
|
cRange = [min(normalized, [], "all"), max(normalized, [], "all")];
|
||||||
|
|
||||||
% Plot gradient on the "floor" of the domain
|
% Plot gradient on the "floor" of the domain
|
||||||
if isnan(ind)
|
if isnan(ind)
|
||||||
hold(f.CurrentAxes, "on");
|
ax = f.CurrentAxes;
|
||||||
o = surf(f.CurrentAxes, obj.X, obj.Y, zeros(size(obj.X)), obj.values ./ max(obj.values, [], "all"), "EdgeColor", "none");
|
hold(ax, "on");
|
||||||
|
o = surf(ax, obj.X, obj.Y, zeros(size(obj.X)), normalized, "EdgeColor", "none");
|
||||||
o.HitTest = "off";
|
o.HitTest = "off";
|
||||||
o.PickableParts = "none";
|
o.PickableParts = "none";
|
||||||
hold(f.CurrentAxes, "off");
|
clim(ax, cRange);
|
||||||
|
hold(ax, "off");
|
||||||
else
|
else
|
||||||
hold(f.Children(1).Children(ind(1)), "on");
|
ax = f.Children(1).Children(ind(1));
|
||||||
o = surf(f.Children(1).Children(ind(1)), obj.X, obj.Y, zeros(size(obj.X)), obj.values ./ max(obj.values, [], "all"), "EdgeColor", "none");
|
hold(ax, "on");
|
||||||
|
o = surf(ax, obj.X, obj.Y, zeros(size(obj.X)), normalized, "EdgeColor", "none");
|
||||||
o.HitTest = "off";
|
o.HitTest = "off";
|
||||||
o.PickableParts = "none";
|
o.PickableParts = "none";
|
||||||
hold(f.Children(1).Children(ind(1)), "off");
|
clim(ax, cRange);
|
||||||
|
hold(ax, "off");
|
||||||
end
|
end
|
||||||
|
|
||||||
% Add to other perspectives
|
% Add to other perspectives
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
function value = halfAngle(obj)
|
||||||
|
arguments (Input)
|
||||||
|
obj (1, 1) {mustBeA(obj, "sigmoidSensor")};
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
value (1, 1) double;
|
||||||
|
end
|
||||||
|
value = obj.alphaTilt;
|
||||||
|
end
|
||||||
@@ -1,17 +1,24 @@
|
|||||||
function obj = initialize(obj, alphaDist, betaDist, alphaTilt, betaTilt)
|
function obj = initialize(obj, alphaDist, betaDist, alphaTilt, betaTilt, tilt, azimuth)
|
||||||
arguments (Input)
|
arguments (Input)
|
||||||
obj (1, 1) {mustBeA(obj, "sigmoidSensor")}
|
obj (1, 1) {mustBeA(obj, "sigmoidSensor")}
|
||||||
alphaDist (1, 1) double;
|
alphaDist (1, 1) double;
|
||||||
betaDist (1, 1) double;
|
betaDist (1, 1) double;
|
||||||
alphaTilt (1, 1) double;
|
alphaTilt (1, 1) double;
|
||||||
betaTilt (1, 1) double;
|
betaTilt (1, 1) double;
|
||||||
|
tilt (1, 1) double = 0;
|
||||||
|
azimuth (1, 1) double = 0;
|
||||||
end
|
end
|
||||||
arguments (Output)
|
arguments (Output)
|
||||||
obj (1, 1) {mustBeA(obj, "sigmoidSensor")}
|
obj (1, 1) {mustBeA(obj, "sigmoidSensor")}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
% Sensor performance parameters
|
||||||
obj.alphaDist = alphaDist;
|
obj.alphaDist = alphaDist;
|
||||||
obj.betaDist = betaDist;
|
obj.betaDist = betaDist;
|
||||||
obj.alphaTilt = alphaTilt;
|
obj.alphaTilt = alphaTilt;
|
||||||
obj.betaTilt = betaTilt;
|
obj.betaTilt = betaTilt;
|
||||||
|
|
||||||
|
% Sensor pointing parameters
|
||||||
|
obj.tilt = tilt;
|
||||||
|
obj.azimuth = azimuth;
|
||||||
end
|
end
|
||||||
@@ -8,16 +8,20 @@ function value = sensorPerformance(obj, agentPos, targetPos)
|
|||||||
value (:, 1) double;
|
value (:, 1) double;
|
||||||
end
|
end
|
||||||
|
|
||||||
% compute direct distance and distance projected onto the ground
|
% Unit vectors from agent to each target
|
||||||
d = vecnorm(agentPos - targetPos, 2, 2); % distance from sensor to target
|
diffs = targetPos - agentPos;
|
||||||
x = vecnorm(agentPos(1:2) - targetPos(:, 1:2), 2, 2); % distance from sensor nadir to target nadir (i.e. distance ignoring height difference)
|
d = vecnorm(diffs, 2, 2);
|
||||||
|
dirs = diffs ./ d;
|
||||||
|
|
||||||
% compute tilt angle
|
% Boresight unit vector: tilt=0 → nadir [0,0,-1]; azimuth 0=+Y, 90=+X clockwise
|
||||||
tiltAngle = (180 - atan2d(x, targetPos(:, 3) - agentPos(3))); % degrees
|
boresight = [sind(obj.tilt)*sind(obj.azimuth), sind(obj.tilt)*cosd(obj.azimuth), -cosd(obj.tilt)];
|
||||||
|
|
||||||
|
% Angular offset from boresight to each target direction
|
||||||
|
angularOffset = acosd(dirs * boresight');
|
||||||
|
|
||||||
% Membership functions
|
% Membership functions
|
||||||
mu_d = obj.distanceMembership(d);
|
mu_d = obj.distanceMembership(d);
|
||||||
mu_t = obj.tiltMembership(tiltAngle);
|
mu_t = obj.tiltMembership(angularOffset);
|
||||||
|
|
||||||
value = mu_d .* mu_t; % assume pan membership is always 1
|
value = mu_d .* mu_t; % assume pan membership is always 1
|
||||||
end
|
end
|
||||||
@@ -6,14 +6,20 @@ classdef sigmoidSensor
|
|||||||
alphaTilt = NaN; % degrees
|
alphaTilt = NaN; % degrees
|
||||||
betaTilt = NaN;
|
betaTilt = NaN;
|
||||||
end
|
end
|
||||||
|
properties (Access = public)
|
||||||
|
% pointing states
|
||||||
|
tilt = 0;
|
||||||
|
azimuth = 0;
|
||||||
|
end
|
||||||
|
|
||||||
methods (Access = public)
|
methods (Access = public)
|
||||||
[obj] = initialize(obj, alphaDist, betaDist, alphaTilt, betaTilt);
|
[obj] = initialize(obj, alphaDist, betaDist, alphaTilt, betaTilt, tilt, azimuth); % initialize sensor, define parameters
|
||||||
[value] = sensorPerformance(obj, agentPos, agentPan, agentTilt, targetPos);
|
[value] = sensorPerformance(obj, agentPos, targetPos); % determine sensor performance for a given single sensor and target geometry
|
||||||
[f] = plotParameters(obj);
|
[value] = halfAngle(obj); % tilt angle (deg) at which sensor performance is halved
|
||||||
|
[f] = plotParameters(obj); % debug, plot sensor response as a function of distance and tilt angle
|
||||||
end
|
end
|
||||||
methods (Access = private)
|
methods (Access = private)
|
||||||
x = distanceMembership(obj, d);
|
x = distanceMembership(obj, d); % used in computing distance factor of sensor performance
|
||||||
x = tiltMembership(obj, t);
|
x = tiltMembership(obj, t); % used in computing tilt factor of sensor performance
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology
|
timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology
|
||||||
1, 100, 30.0, 0.1, 2.0, 5, 1, 1, "6.0, 6.0", "25.0, 25.0", "80.0, 80.0", "0.25, 0.25", "5.0, 5.0", "0.1, 0.1", "0.0, 0.0, 0.0", "80.0, 80.0, 80.0", "55.0, 55.0", "40, 25, 25, 40", 0.15, "15.0, 10.0, 40.0, 5.0, 10.0, 45.0", 1, "1.0, 25.0, 0.0", "30.0, 30.0, 50.0", 1, 2.0, 1
|
1, 100, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 80.0", "0.25, 0.25", "8.0, 8.0", "0.1, 0.1", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "66.6, 66.6", "55, 35, 35, 55", 0.15, "15.0, 15.0, 50.0, 40.0, 15.0, 50.0", 1, "0.0, 35.0, 0.0", "50, 40.0, 60", 1, 2.0, 1
|
||||||
|
@@ -0,0 +1,2 @@
|
|||||||
|
timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology
|
||||||
|
1, 50, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 50.0", "0.25, 1.0", "8.0, 25.0", "0.1, 0.02", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "60.0, 80.0, 45.0, 70.0", "70, 15, 15, 20, 20, 15, 15, 70", 0.15, "10.0, 10.0, 50.0, 40.0, 15.0, 45.0", 8, "0.0, 30.0, 0.0, 42.0, 30.0, 0.0, 84.0, 30.0, 0.0, 13.0, 60.0, 0.0, 55.0, 60.0, 0.0, 0.0, 90, 0.0, 42.0, 90.0, 0.0, 84.0, 90.0, 0.0", "16.0, 40.0, 100.0, 58.0, 40.0, 100.0, 100.0, 40.0, 100.0, 29.0, 70.0, 100.0, 71.0, 70.0, 100.0, 16.0, 100.0, 100.0, 58.0, 100.0, 100.0, 100.0, 100.0, 100.0", 0, 2.0, 1
|
||||||
|
@@ -0,0 +1,2 @@
|
|||||||
|
timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology
|
||||||
|
1, 65, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 50.0", "0.25, 1.0", "8.0, 25.0", "0.1, 0.02", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "30.0, 80.0", "60, 20, 20, 30", 0.15, "65.0, 15.0, 65.0, 65.0, 15.0, 45.0", 3, "0.0, 25.0, 55.0, 40.0, 10.0, 0.0, 40.0, 45.0, 60.0", "100.0, 70.0, 60.0, 45.0, 80.0, 55.0, 100.0, 50.0, 100.0", 0, 2.0, 1
|
||||||
|
@@ -0,0 +1,2 @@
|
|||||||
|
timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology
|
||||||
|
1, 100, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 80.0", "0.25, 0.25", "8.0, 8.0", "0.1, 0.1", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "66.6, 66.6", "55, 35, 35, 55", 0.15, "15.0, 15.0, 50.0, 40.0, 15.0, 50.0", 1, "0.0, 35.0, 0.0", "50, 40.0, 60", 1, 2.0, 1
|
||||||
|
@@ -0,0 +1,2 @@
|
|||||||
|
timestep, maxIter, minAlt, discretizationStep, protectedRange, initialStepSize, barrierGain, barrierExponent, collisionRadius, comRange, alphaDist, betaDist, alphaTilt, betaTilt, domainMin, domainMax, objectivePos, objectiveVar, sensorPerformanceMinimum, initialPositions, numObstacles, obstacleMin, obstacleMax, useDoubleIntegrator, dampingCoeff, useFixedTopology
|
||||||
|
1, 65, 35.0, 0.1, 2.0, 6, 1, 1, "8.0, 8.0", "35.0, 35.0", "80.0, 50.0", "0.25, 1.0", "8.0, 25.0", "0.1, 0.02", "0.0, 0.0, 0.0", "100.0, 100.0, 100.0", "30.0, 80.0", "60, 20, 20, 30", 0.15, "90.0, 10.0, 50.0, 65.0, 15.0, 45.0", 4, "0.0, 30.0, 0.0, 70.0, 30.0, 0.0, 0.0, 60.0, 0.0, 55.0, 60.0, 0.0", "50.0, 40.0, 100.0, 100.0, 40.0, 100.0, 35.0, 70.0, 100.0, 100.0, 70.0, 100.0", 0, 2.0, 1
|
||||||
|
+152
-125
@@ -158,6 +158,21 @@
|
|||||||
<Size type="coderapp.internal.codertype.Dimension"/>
|
<Size type="coderapp.internal.codertype.Dimension"/>
|
||||||
<Size type="coderapp.internal.codertype.Dimension"/>
|
<Size type="coderapp.internal.codertype.Dimension"/>
|
||||||
</Types>
|
</Types>
|
||||||
|
<Types id="32" type="coderapp.internal.codertype.PrimitiveType">
|
||||||
|
<ClassName>int32</ClassName>
|
||||||
|
<Size type="coderapp.internal.codertype.Dimension"/>
|
||||||
|
<Size type="coderapp.internal.codertype.Dimension"/>
|
||||||
|
</Types>
|
||||||
|
<Types id="33" type="coderapp.internal.codertype.PrimitiveType">
|
||||||
|
<ClassName>int32</ClassName>
|
||||||
|
<Size type="coderapp.internal.codertype.Dimension"/>
|
||||||
|
<Size type="coderapp.internal.codertype.Dimension"/>
|
||||||
|
</Types>
|
||||||
|
<Types id="34" type="coderapp.internal.codertype.PrimitiveType">
|
||||||
|
<ClassName>int32</ClassName>
|
||||||
|
<Size type="coderapp.internal.codertype.Dimension"/>
|
||||||
|
<Size type="coderapp.internal.codertype.Dimension"/>
|
||||||
|
</Types>
|
||||||
</Types>
|
</Types>
|
||||||
</coderapp.internal.interface.project.Interface>
|
</coderapp.internal.interface.project.Interface>
|
||||||
</MF0>
|
</MF0>
|
||||||
@@ -411,749 +426,761 @@
|
|||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="42" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="42" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/constrainMotion.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="43" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="43" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/constrainMotion.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="44" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="44" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_data.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="45" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="45" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_data.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="46" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="46" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_initialize.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_data.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="47" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="47" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_initialize.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_data.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="48" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="48" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_internal_types.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_initialize.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="49" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="49" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_terminate.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_initialize.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="50" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="50" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_terminate.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_internal_types.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="51" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="51" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_types.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_terminate.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="52" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="52" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/countsort.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_terminate.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="53" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="53" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/countsort.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/controller_types.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="54" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="54" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/deleteColMoveEnd.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/countsort.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="55" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="55" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/deleteColMoveEnd.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/countsort.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="56" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="56" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/dot.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/deleteColMoveEnd.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="57" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="57" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/dot.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/deleteColMoveEnd.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="58" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="58" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/driver.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/dot.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="59" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="59" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/driver.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/dot.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="60" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="60" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/exp.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/driver.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="61" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="61" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/exp.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/driver.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="62" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="62" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/eye.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/exp.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="63" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="63" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/eye.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/exp.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="64" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="64" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/factorQR.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/eye.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="65" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="65" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/factorQR.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/eye.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="66" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="66" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/feasibleX0ForWorkingSet.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/factorQR.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="67" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="67" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/feasibleX0ForWorkingSet.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/factorQR.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="68" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="68" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/feasibleratiotest.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/feasibleX0ForWorkingSet.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="69" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="69" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/feasibleratiotest.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/feasibleX0ForWorkingSet.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="70" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="70" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/find.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/feasibleratiotest.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="71" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="71" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/find.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/feasibleratiotest.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="72" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="72" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/fullColLDL2_.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/find.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="73" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="73" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/fullColLDL2_.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/find.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="74" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="74" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/guidance_step.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/fullColLDL2_.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="75" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="75" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/guidance_step.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/fullColLDL2_.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="76" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="76" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/iterate.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/guidance_step.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="77" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="77" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/iterate.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/guidance_step.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="78" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="78" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ixamax.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/iterate.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="79" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="79" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ixamax.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/iterate.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="80" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="80" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ixfun.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ixamax.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="81" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="81" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ixfun.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ixamax.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="82" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="82" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lesserNeighbor.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ixfun.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="83" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="83" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lesserNeighbor.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ixfun.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="84" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="84" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/linearForm_.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lesserNeighbor.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="85" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="85" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/linearForm_.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/lesserNeighbor.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="86" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="86" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/maxConstraintViolation.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/linearForm_.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="87" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="87" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/maxConstraintViolation.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/linearForm_.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="88" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="88" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/meshgrid.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/maxConstraintViolation.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="89" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="89" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/meshgrid.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/maxConstraintViolation.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="90" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="90" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/miSim.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/meshgrid.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="91" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="91" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/miSim.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/meshgrid.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="92" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="92" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/minOrMax.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/miSim.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="93" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="93" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/minOrMax.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/miSim.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="94" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="94" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/mpower.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/minOrMax.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="95" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="95" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/mpower.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/minOrMax.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="96" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="96" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/nchoosek.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/mpower.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="97" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="97" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/nchoosek.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/mpower.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="98" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="98" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/norm.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/nchoosek.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="99" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="99" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/norm.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/nchoosek.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="100" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="100" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/partition.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/norm.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="101" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="101" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/partition.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/norm.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="102" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="102" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/phaseone.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/partition.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="103" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="103" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/phaseone.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/partition.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="104" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="104" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/quadprog.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/phaseone.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="105" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="105" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/quadprog.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/phaseone.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="106" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="106" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ratiotest.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/quadprog.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="107" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="107" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ratiotest.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/quadprog.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="108" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="108" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rectangularPrism.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ratiotest.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="109" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="109" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rectangularPrism.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/ratiotest.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="110" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="110" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/removeConstr.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rectangularPrism.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="111" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="111" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/removeConstr.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rectangularPrism.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="112" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="112" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/repmat.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/removeConstr.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="113" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="113" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/repmat.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/removeConstr.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="114" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="114" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rtGetInf.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/repmat.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="115" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="115" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rtGetInf.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/repmat.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="116" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="116" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rtGetNaN.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rtGetInf.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="117" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="117" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rtGetNaN.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rtGetInf.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="118" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="118" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rt_defines.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rtGetNaN.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="119" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="119" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rt_nonfinite.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rtGetNaN.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="120" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="120" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rt_nonfinite.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rt_defines.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="121" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="121" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rtwtypes.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rt_nonfinite.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="122" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="122" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/run.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rt_nonfinite.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="123" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="123" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/run.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/rtwtypes.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="124" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="124" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sensingObjective.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/run.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="125" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="125" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sensingObjective.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/run.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="126" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="126" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sensorPerformance.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sensingObjective.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="127" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="127" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sensorPerformance.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sensingObjective.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="128" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="128" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/setProblemType.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sensorPerformance.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="129" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="129" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/setProblemType.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sensorPerformance.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="130" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="130" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sigmoidSensor.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/setProblemType.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="131" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="131" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sigmoidSensor.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/setProblemType.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="132" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="132" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sort.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sigmoidSensor.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="133" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="133" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sort.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sigmoidSensor.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="134" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="134" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/spherical.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sort.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="135" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="135" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/spherical.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sort.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="136" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="136" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sprintf.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/spherical.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="137" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="137" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sprintf.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/spherical.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="138" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="138" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/squareQ_appendCol.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sprintf.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="139" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="139" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/squareQ_appendCol.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sprintf.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="140" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="140" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/string1.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/squareQ_appendCol.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="141" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="141" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/string1.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/squareQ_appendCol.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="142" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="142" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sum.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/string1.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="143" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="143" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sum.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/string1.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="144" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="144" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/triu.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sum.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="145" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="145" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/triu.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/sum.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="146" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="146" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/unique.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/triu.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="147" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="147" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/unique.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/triu.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="148" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="148" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/vecnorm.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/unique.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="149" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="149" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/vecnorm.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/unique.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="150" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="150" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xgemv.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/vecnorm.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="151" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="151" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xgemv.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/vecnorm.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="152" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="152" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xgeqp3.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xgemv.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="153" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="153" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xgeqp3.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xgemv.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="154" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="154" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xnrm2.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xgeqp3.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="155" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="155" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xnrm2.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xgeqp3.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="156" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="156" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xrotg.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xnrm2.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="157" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="157" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xrotg.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xnrm2.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="158" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="158" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzgeqp3.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xrotg.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="159" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="159" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzgeqp3.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xrotg.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="160" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="160" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzlarf.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzgeqp3.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="161" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="161" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzlarf.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzgeqp3.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="162" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="162" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzlarfg.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzlarf.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="163" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="163" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzlarfg.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzlarf.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="164" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="164" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/matlab/R2025a/extern/include/tmwtypes.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzlarfg.cpp</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="165" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="165" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/examples/main.cpp</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/xzlarfg.h</Path>
|
||||||
</File>
|
</File>
|
||||||
<Type>GENERATED_SOURCE</Type>
|
<Type>GENERATED_SOURCE</Type>
|
||||||
</Artifacts>
|
</Artifacts>
|
||||||
<Artifacts id="166" type="coderapp.internal.build.mfz.CodegenArtifact">
|
<Artifacts id="166" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
|
<Path>/home/kdee/matlab/R2025a/extern/include/tmwtypes.h</Path>
|
||||||
|
</File>
|
||||||
|
<Type>GENERATED_SOURCE</Type>
|
||||||
|
</Artifacts>
|
||||||
|
<Artifacts id="167" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/examples/main.cpp</Path>
|
||||||
|
</File>
|
||||||
|
<Type>GENERATED_SOURCE</Type>
|
||||||
|
</Artifacts>
|
||||||
|
<Artifacts id="168" type="coderapp.internal.build.mfz.CodegenArtifact">
|
||||||
<File type="coderapp.internal.util.mfz.FileSpec">
|
<File type="coderapp.internal.util.mfz.FileSpec">
|
||||||
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/examples/main.h</Path>
|
<Path>/home/kdee/Desktop/miSim/aerpaw/codegen/examples/main.h</Path>
|
||||||
</File>
|
</File>
|
||||||
@@ -1161,7 +1188,7 @@
|
|||||||
</Artifacts>
|
</Artifacts>
|
||||||
<BuildFolder type="coderapp.internal.util.mfz.FileSpec"/>
|
<BuildFolder type="coderapp.internal.util.mfz.FileSpec"/>
|
||||||
<Success>true</Success>
|
<Success>true</Success>
|
||||||
<Timestamp>2026-04-05T13:43:54</Timestamp>
|
<Timestamp>2026-04-07T22:43:01</Timestamp>
|
||||||
</MainBuildResult>
|
</MainBuildResult>
|
||||||
</coderapp.internal.mlc.mfz.MatlabCoderProjectState>
|
</coderapp.internal.mlc.mfz.MatlabCoderProjectState>
|
||||||
</MF0>
|
</MF0>
|
||||||
|
|||||||
+27
-5
@@ -42,9 +42,10 @@ end
|
|||||||
% TRANSIT_ALT_STEP must exceed 2 * max(collisionRadius).
|
% TRANSIT_ALT_STEP must exceed 2 * max(collisionRadius).
|
||||||
% Waypoint 1: each UAV flies to (finalX, finalY) at its unique transit altitude.
|
% Waypoint 1: each UAV flies to (finalX, finalY) at its unique transit altitude.
|
||||||
% Waypoint 2: each UAV adjusts to its actual target altitude.
|
% Waypoint 2: each UAV adjusts to its actual target altitude.
|
||||||
|
% These constants are also used for the altitude-staggered return before RTL.
|
||||||
|
TRANSIT_ALT_BASE = 25.0; % must match drone.takeoff() altitude in uav_runner.py
|
||||||
|
TRANSIT_ALT_STEP = 25; % vertical separation per UAV (m); must exceed 2*collisionRadius
|
||||||
if ~coder.target('MATLAB')
|
if ~coder.target('MATLAB')
|
||||||
TRANSIT_ALT_BASE = 25.0; % must match drone.takeoff() altitude in uav_runner.py
|
|
||||||
TRANSIT_ALT_STEP = 12.1; % vertical separation per UAV (m); must exceed 2*collisionRadius
|
|
||||||
for ii = double(totalLoaded):-1:1
|
for ii = double(totalLoaded):-1:1
|
||||||
transitRow = (ii - 1) * 2 + 1;
|
transitRow = (ii - 1) * 2 + 1;
|
||||||
finalRow = (ii - 1) * 2 + 2;
|
finalRow = (ii - 1) * 2 + 2;
|
||||||
@@ -57,7 +58,7 @@ if ~coder.target('MATLAB')
|
|||||||
end
|
end
|
||||||
|
|
||||||
% Load guidance scenario from CSV (parameters for guidance_step)
|
% Load guidance scenario from CSV (parameters for guidance_step)
|
||||||
NUM_SCENARIO_PARAMS = 45;
|
NUM_SCENARIO_PARAMS = 55;
|
||||||
MAX_OBSTACLES_CTRL = int32(8);
|
MAX_OBSTACLES_CTRL = int32(8);
|
||||||
scenarioParams = zeros(1, NUM_SCENARIO_PARAMS);
|
scenarioParams = zeros(1, NUM_SCENARIO_PARAMS);
|
||||||
obstacleMin = zeros(MAX_OBSTACLES_CTRL, 3);
|
obstacleMin = zeros(MAX_OBSTACLES_CTRL, 3);
|
||||||
@@ -101,7 +102,7 @@ for w = 1:numWaypoints
|
|||||||
target = targets(targetIdx, :);
|
target = targets(targetIdx, :);
|
||||||
|
|
||||||
if coder.target('MATLAB')
|
if coder.target('MATLAB')
|
||||||
disp([datestr(now, 'HH:MM:SS'), ' Sending TARGET to client ', num2str(i), ' (waypoint ', num2str(w), '): ', ...
|
disp(['Sending TARGET to client ', num2str(i), ' (waypoint ', num2str(w), '): ', ...
|
||||||
num2str(target(1)), ',', num2str(target(2)), ',', num2str(target(3))]);
|
num2str(target(1)), ',', num2str(target(2)), ',', num2str(target(3))]);
|
||||||
else
|
else
|
||||||
coder.ceval('sendTarget', int32(i), coder.ref(target));
|
coder.ceval('sendTarget', int32(i), coder.ref(target));
|
||||||
@@ -148,6 +149,10 @@ guidance_step(positions(1:numClients, :), true, ...
|
|||||||
|
|
||||||
% Main guidance loop (event-triggered)
|
% Main guidance loop (event-triggered)
|
||||||
for step = 1:MAX_GUIDANCE_STEPS
|
for step = 1:MAX_GUIDANCE_STEPS
|
||||||
|
if ~coder.target('MATLAB')
|
||||||
|
coder.ceval('setGuidanceStep', int32(step), int32(MAX_GUIDANCE_STEPS));
|
||||||
|
end
|
||||||
|
|
||||||
% Run one guidance step: feed current GPS positions in, get targets out
|
% Run one guidance step: feed current GPS positions in, get targets out
|
||||||
nextPositions = guidance_step(positions(1:numClients, :), false, ...
|
nextPositions = guidance_step(positions(1:numClients, :), false, ...
|
||||||
scenarioParams, obstacleMin, obstacleMax, numObstacles);
|
scenarioParams, obstacleMin, obstacleMax, numObstacles);
|
||||||
@@ -158,7 +163,7 @@ for step = 1:MAX_GUIDANCE_STEPS
|
|||||||
if ~coder.target('MATLAB')
|
if ~coder.target('MATLAB')
|
||||||
coder.ceval('sendTarget', int32(i), coder.ref(target));
|
coder.ceval('sendTarget', int32(i), coder.ref(target));
|
||||||
else
|
else
|
||||||
disp([datestr(now, 'HH:MM:SS'), ' [guidance] target UAV ', num2str(i), ': ', num2str(target)]);
|
disp(['[step ', num2str(step), '] target UAV ', num2str(i), ': ', num2str(target)]);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -187,9 +192,26 @@ if ~coder.target('MATLAB')
|
|||||||
% last guidance navigation and is back in sequential (ACK/READY) mode.
|
% last guidance navigation and is back in sequential (ACK/READY) mode.
|
||||||
coder.ceval('waitForAllMessageType', int32(numClients), ...
|
coder.ceval('waitForAllMessageType', int32(numClients), ...
|
||||||
int32(MESSAGE_TYPE.ACK));
|
int32(MESSAGE_TYPE.ACK));
|
||||||
|
% Reset step counter so post-guidance logging carries no step prefix.
|
||||||
|
coder.ceval('setGuidanceStep', int32(0), int32(MAX_GUIDANCE_STEPS));
|
||||||
end
|
end
|
||||||
% --------------------------------------------------------------------------
|
% --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
% Altitude-staggered return: separate UAVs vertically before issuing RTL,
|
||||||
|
% mirroring the initial positioning stagger so UAVs transit laterally at
|
||||||
|
% unique altitudes and cannot collide during the return flight.
|
||||||
|
if ~coder.target('MATLAB')
|
||||||
|
for i = 1:numClients
|
||||||
|
transitAlt = TRANSIT_ALT_BASE + (double(i) - 1) * TRANSIT_ALT_STEP;
|
||||||
|
target = [positions(i, 1), positions(i, 2), transitAlt];
|
||||||
|
coder.ceval('sendTarget', int32(i), coder.ref(target));
|
||||||
|
end
|
||||||
|
coder.ceval('waitForAllMessageType', int32(numClients), int32(MESSAGE_TYPE.ACK));
|
||||||
|
coder.ceval('waitForAllMessageType', int32(numClients), int32(MESSAGE_TYPE.READY));
|
||||||
|
else
|
||||||
|
disp('Altitude-staggered return (simulation): UAVs commanded to transit altitudes.');
|
||||||
|
end
|
||||||
|
|
||||||
% Send RTL command to all clients
|
% Send RTL command to all clients
|
||||||
for i = 1:numClients
|
for i = 1:numClients
|
||||||
if coder.target('MATLAB')
|
if coder.target('MATLAB')
|
||||||
|
|||||||
+29
-14
@@ -29,6 +29,9 @@ function nextPositions = guidance_step(currentPositions, isInit, ...
|
|||||||
% 39-40 objectivePos
|
% 39-40 objectivePos
|
||||||
% 41-44 objectiveVar (2x2, col-major)
|
% 41-44 objectiveVar (2x2, col-major)
|
||||||
% 45 sensorPerformanceMinimum
|
% 45 sensorPerformanceMinimum
|
||||||
|
% 46 useDoubleIntegrator
|
||||||
|
% 47 dampingCoeff
|
||||||
|
% 48 useFixedTopology
|
||||||
% obstacleMin (MAX_OBSTACLES × 3) double column-major obstacle corners (compiled path)
|
% obstacleMin (MAX_OBSTACLES × 3) double column-major obstacle corners (compiled path)
|
||||||
% obstacleMax (MAX_OBSTACLES × 3) double
|
% obstacleMax (MAX_OBSTACLES × 3) double
|
||||||
% numObstacles (1,1) int32 actual obstacle count
|
% numObstacles (1,1) int32 actual obstacle count
|
||||||
@@ -91,26 +94,34 @@ if isInit
|
|||||||
BETA_TILT_VEC = scenarioParams(29:32);
|
BETA_TILT_VEC = scenarioParams(29:32);
|
||||||
DOMAIN_MIN = scenarioParams(33:35);
|
DOMAIN_MIN = scenarioParams(33:35);
|
||||||
DOMAIN_MAX = scenarioParams(36:38);
|
DOMAIN_MAX = scenarioParams(36:38);
|
||||||
OBJECTIVE_GROUND_POS = scenarioParams(39:40);
|
NUM_OBJ_COMPONENTS = int32(scenarioParams(39));
|
||||||
OBJECTIVE_VAR = reshape(scenarioParams(41:44), 2, 2);
|
OBJECTIVE_POS_FLAT = scenarioParams(40:43); % [x1,y1,x2,y2]; zero-padded if N=1
|
||||||
SENSOR_PERFORMANCE_MINIMUM = scenarioParams(45);
|
OBJECTIVE_VAR_FLAT = scenarioParams(44:51); % [v11,v12,v21,v22 per component]
|
||||||
|
SENSOR_PERFORMANCE_MINIMUM = scenarioParams(52);
|
||||||
|
USE_DOUBLE_INTEGRATOR = logical(scenarioParams(53));
|
||||||
|
DAMPING_COEFF = scenarioParams(54);
|
||||||
|
USE_FIXED_TOPOLOGY = logical(scenarioParams(55));
|
||||||
|
|
||||||
% --- Build domain geometry ---
|
% --- Build domain geometry ---
|
||||||
dom = rectangularPrism;
|
dom = rectangularPrism;
|
||||||
dom = dom.initialize([DOMAIN_MIN; DOMAIN_MAX], REGION_TYPE.DOMAIN, "Guidance Domain");
|
dom = dom.initialize([DOMAIN_MIN; DOMAIN_MAX], REGION_TYPE.DOMAIN, "Guidance Domain");
|
||||||
|
|
||||||
% --- Build sensing objective (inline Gaussian; codegen-compatible) ---
|
% --- Build sensing objective: sum of N bivariate Gaussians (codegen-compatible) ---
|
||||||
dom.objective = sensingObjective;
|
dom.objective = sensingObjective;
|
||||||
xGrid = unique([DOMAIN_MIN(1):DISCRETIZATION_STEP:DOMAIN_MAX(1), DOMAIN_MAX(1)]);
|
xGrid = unique([DOMAIN_MIN(1):DISCRETIZATION_STEP:DOMAIN_MAX(1), DOMAIN_MAX(1)]);
|
||||||
yGrid = unique([DOMAIN_MIN(2):DISCRETIZATION_STEP:DOMAIN_MAX(2), DOMAIN_MAX(2)]);
|
yGrid = unique([DOMAIN_MIN(2):DISCRETIZATION_STEP:DOMAIN_MAX(2), DOMAIN_MAX(2)]);
|
||||||
[gridX, gridY] = meshgrid(xGrid, yGrid);
|
[gridX, gridY] = meshgrid(xGrid, yGrid);
|
||||||
dx = gridX - OBJECTIVE_GROUND_POS(1);
|
objValues = zeros(size(gridX));
|
||||||
dy = gridY - OBJECTIVE_GROUND_POS(2);
|
for kk = 1:NUM_OBJ_COMPONENTS
|
||||||
% Bivariate Gaussian using objectiveVar covariance matrix (avoids inv())
|
pos_k = OBJECTIVE_POS_FLAT((kk-1)*2+1 : (kk-1)*2+2);
|
||||||
ov_a = OBJECTIVE_VAR(1,1); ov_b = OBJECTIVE_VAR(1,2);
|
var_k = reshape(OBJECTIVE_VAR_FLAT((kk-1)*4+1 : (kk-1)*4+4), 2, 2);
|
||||||
ov_c = OBJECTIVE_VAR(2,1); ov_d = OBJECTIVE_VAR(2,2);
|
dx = gridX - pos_k(1);
|
||||||
ov_det = ov_a * ov_d - ov_b * ov_c;
|
dy = gridY - pos_k(2);
|
||||||
objValues = exp((-0.5 / ov_det) .* (ov_d .* dx.*dx - (ov_b + ov_c) .* dx.*dy + ov_a .* dy.*dy));
|
ov_a = var_k(1,1); ov_b = var_k(1,2);
|
||||||
|
ov_c = var_k(2,1); ov_d = var_k(2,2);
|
||||||
|
ov_det = ov_a * ov_d - ov_b * ov_c;
|
||||||
|
objValues = objValues + exp((-0.5 / ov_det) .* (ov_d .* dx.*dx - (ov_b + ov_c) .* dx.*dy + ov_a .* dy.*dy));
|
||||||
|
end
|
||||||
dom.objective = dom.objective.initializeWithValues(objValues, dom, ...
|
dom.objective = dom.objective.initializeWithValues(objValues, dom, ...
|
||||||
DISCRETIZATION_STEP, PROTECTED_RANGE, SENSOR_PERFORMANCE_MINIMUM);
|
DISCRETIZATION_STEP, PROTECTED_RANGE, SENSOR_PERFORMANCE_MINIMUM);
|
||||||
|
|
||||||
@@ -146,7 +157,8 @@ if isInit
|
|||||||
% --- Initialise simulation (plots and video disabled) ---
|
% --- Initialise simulation (plots and video disabled) ---
|
||||||
sim = miSim;
|
sim = miSim;
|
||||||
sim = sim.initialize(dom, agentList, BARRIER_GAIN, BARRIER_EXPONENT, ...
|
sim = sim.initialize(dom, agentList, BARRIER_GAIN, BARRIER_EXPONENT, ...
|
||||||
MIN_ALT, TIMESTEP, MAX_ITER, obstacleList, false, false);
|
MIN_ALT, TIMESTEP, MAX_ITER, obstacleList, false, false, ...
|
||||||
|
USE_DOUBLE_INTEGRATOR, DAMPING_COEFF, USE_FIXED_TOPOLOGY);
|
||||||
end
|
end
|
||||||
|
|
||||||
% On the init call return current positions unchanged
|
% On the init call return current positions unchanged
|
||||||
@@ -176,7 +188,9 @@ else
|
|||||||
sim.timestepIndex = sim.timestepIndex + 1;
|
sim.timestepIndex = sim.timestepIndex + 1;
|
||||||
|
|
||||||
% 3. Update communications topology (Lesser Neighbour Assignment)
|
% 3. Update communications topology (Lesser Neighbour Assignment)
|
||||||
sim = sim.lesserNeighbor();
|
if ~sim.useFixedTopology
|
||||||
|
sim = sim.lesserNeighbor();
|
||||||
|
end
|
||||||
|
|
||||||
% 4. Compute Voronoi partitioning
|
% 4. Compute Voronoi partitioning
|
||||||
sim.partitioning = sim.agents{1}.partition(sim.agents, sim.domain.objective);
|
sim.partitioning = sim.agents{1}.partition(sim.agents, sim.domain.objective);
|
||||||
@@ -184,7 +198,8 @@ else
|
|||||||
% 5. Unconstrained gradient-ascent step for each agent
|
% 5. Unconstrained gradient-ascent step for each agent
|
||||||
for ii = 1:size(sim.agents, 1)
|
for ii = 1:size(sim.agents, 1)
|
||||||
sim.agents{ii} = sim.agents{ii}.run(sim.domain, sim.partitioning, ...
|
sim.agents{ii} = sim.agents{ii}.run(sim.domain, sim.partitioning, ...
|
||||||
sim.timestepIndex, ii, sim.agents);
|
sim.timestepIndex, ii, ...
|
||||||
|
sim.useDoubleIntegrator, sim.dampingCoeff, sim.timestep, sim.optimizeSensorPointing);
|
||||||
end
|
end
|
||||||
|
|
||||||
% 6. Apply CBF safety filter (collision / comms / domain constraints via QP)
|
% 6. Apply CBF safety filter (collision / comms / domain constraints via QP)
|
||||||
|
|||||||
+120
-31
@@ -16,6 +16,44 @@
|
|||||||
|
|
||||||
static int serverSocket = -1;
|
static int serverSocket = -1;
|
||||||
static std::vector<int> clientSockets;
|
static std::vector<int> clientSockets;
|
||||||
|
static int guidanceStep = 0;
|
||||||
|
static int guidanceTotalSteps = 0;
|
||||||
|
static struct timespec lastStepTime = {0, 0};
|
||||||
|
|
||||||
|
// During guidance returns "(%d/%d) "; outside guidance returns "HH:MM:SS ".
|
||||||
|
static std::string logPrefix() {
|
||||||
|
if (guidanceStep > 0) {
|
||||||
|
char buf[32];
|
||||||
|
snprintf(buf, sizeof(buf), "(%d/%d) ", guidanceStep, guidanceTotalSteps);
|
||||||
|
return std::string(buf);
|
||||||
|
}
|
||||||
|
time_t now = time(nullptr);
|
||||||
|
struct tm* lt = localtime(&now);
|
||||||
|
char ts[16];
|
||||||
|
strftime(ts, sizeof(ts), "%H:%M:%S", lt);
|
||||||
|
return std::string(ts) + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
void setGuidanceStep(int step, int totalSteps) {
|
||||||
|
struct timespec now;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
||||||
|
// From step 2 onward, elapsed = setGuidanceStep(N-1) → setGuidanceStep(N),
|
||||||
|
// which spans the full prior iteration: guidance computation + target send
|
||||||
|
// + flight + position request/receive.
|
||||||
|
if (step > 1 && lastStepTime.tv_sec != 0) {
|
||||||
|
double elapsed = (now.tv_sec - lastStepTime.tv_sec)
|
||||||
|
+ (now.tv_nsec - lastStepTime.tv_nsec) * 1e-9;
|
||||||
|
guidanceStep = step;
|
||||||
|
guidanceTotalSteps = totalSteps;
|
||||||
|
std::cout << logPrefix() << "Iteration duration: " << elapsed << " s\n";
|
||||||
|
} else {
|
||||||
|
guidanceStep = step;
|
||||||
|
guidanceTotalSteps = totalSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastStepTime = now;
|
||||||
|
}
|
||||||
|
|
||||||
void initSockets() {}
|
void initSockets() {}
|
||||||
void cleanupSockets() {}
|
void cleanupSockets() {}
|
||||||
@@ -184,9 +222,13 @@ static int readScenarioDataRow(const char* filename, char* line, int lineSize) {
|
|||||||
// 28-31: betaTilt[1:4]
|
// 28-31: betaTilt[1:4]
|
||||||
// 32-34: domainMin (east, north, up)
|
// 32-34: domainMin (east, north, up)
|
||||||
// 35-37: domainMax (east, north, up)
|
// 35-37: domainMax (east, north, up)
|
||||||
// 38-39: objectivePos (east, north)
|
// 38 : numObjectiveComponents (1 or 2; inferred from objectivePos field length)
|
||||||
// 40-43: objectiveVar (2x2 col-major: v11, v12, v21, v22)
|
// 39-42: objectivePos flat [x1,y1,x2,y2] (4 slots; zero-padded if N=1)
|
||||||
// 44 : sensorPerformanceMinimum
|
// 43-50: objectiveVar flat [v11,v12,v21,v22 per component] (8 slots; zero-padded if N=1)
|
||||||
|
// 51 : sensorPerformanceMinimum (CSV column 18)
|
||||||
|
// 52 : useDoubleIntegrator (CSV column 23)
|
||||||
|
// 53 : dampingCoeff (CSV column 24)
|
||||||
|
// 54 : useFixedTopology (CSV column 25)
|
||||||
// Returns 1 on success, 0 on failure.
|
// Returns 1 on success, 0 on failure.
|
||||||
int loadScenario(const char* filename, double* params) {
|
int loadScenario(const char* filename, double* params) {
|
||||||
char line[4096];
|
char line[4096];
|
||||||
@@ -198,8 +240,8 @@ int loadScenario(const char* filename, double* params) {
|
|||||||
|
|
||||||
char* fields[32];
|
char* fields[32];
|
||||||
int nf = splitCSVRow(copy, fields, 32);
|
int nf = splitCSVRow(copy, fields, 32);
|
||||||
if (nf < 19) {
|
if (nf < 26) {
|
||||||
fprintf(stderr, "loadScenario: expected >=19 columns, got %d\n", nf);
|
fprintf(stderr, "loadScenario: expected >=26 columns, got %d\n", nf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,34 +306,78 @@ int loadScenario(const char* filename, double* params) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// objectivePos: column 16
|
// objectivePos: column 16 — 2 values per component (up to 2 components).
|
||||||
|
// Infer numObjectiveComponents from the number of values parsed.
|
||||||
{
|
{
|
||||||
char tmp[256]; strncpy(tmp, fields[16], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0';
|
char tmp[256]; strncpy(tmp, fields[16], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0';
|
||||||
char* t = trimField(tmp);
|
char* t = trimField(tmp);
|
||||||
if (sscanf(t, "%lf , %lf", ¶ms[38], ¶ms[39]) != 2) {
|
double posVals[4] = {0, 0, 0, 0};
|
||||||
fprintf(stderr, "loadScenario: failed to parse objectivePos: %s\n", t);
|
int posCount = 0;
|
||||||
|
char* tok = strtok(t, ",");
|
||||||
|
while (tok && posCount < 4) {
|
||||||
|
posVals[posCount++] = atof(tok);
|
||||||
|
tok = strtok(nullptr, ",");
|
||||||
|
}
|
||||||
|
// Check for a 5th token — would mean > 2 components
|
||||||
|
if (tok) {
|
||||||
|
fprintf(stderr, "loadScenario: at most 2 objective Gaussian components supported (objectivePos has >4 values)\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (posCount == 0 || posCount % 2 != 0) {
|
||||||
|
fprintf(stderr, "loadScenario: objectivePos must have 2 or 4 values, got %d\n", posCount);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int nObj = posCount / 2;
|
||||||
|
params[38] = (double)nObj;
|
||||||
|
for (int k = 0; k < 4; k++) params[39 + k] = posVals[k]; // zero-padded for nObj=1
|
||||||
}
|
}
|
||||||
|
|
||||||
// objectiveVar: column 17, format "v11, v12, v21, v22"
|
// objectiveVar: column 17 — 4 values per component (v11,v12,v21,v22).
|
||||||
{
|
{
|
||||||
char tmp[256]; strncpy(tmp, fields[17], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0';
|
char tmp[512]; strncpy(tmp, fields[17], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0';
|
||||||
char* t = trimField(tmp);
|
char* t = trimField(tmp);
|
||||||
if (sscanf(t, "%lf , %lf , %lf , %lf", ¶ms[40], ¶ms[41], ¶ms[42], ¶ms[43]) != 4) {
|
int nObj = (int)params[38];
|
||||||
fprintf(stderr, "loadScenario: failed to parse objectiveVar: %s\n", t);
|
double varVals[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
int varCount = 0;
|
||||||
|
char* tok = strtok(t, ",");
|
||||||
|
while (tok && varCount < 8) {
|
||||||
|
varVals[varCount++] = atof(tok);
|
||||||
|
tok = strtok(nullptr, ",");
|
||||||
|
}
|
||||||
|
if (varCount != nObj * 4) {
|
||||||
|
fprintf(stderr, "loadScenario: objectiveVar has %d values but expected %d (4 per component)\n",
|
||||||
|
varCount, nObj * 4);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
for (int k = 0; k < 8; k++) params[43 + k] = varVals[k]; // zero-padded for nObj=1
|
||||||
}
|
}
|
||||||
|
|
||||||
// sensorPerformanceMinimum: column 18
|
// sensorPerformanceMinimum: column 18
|
||||||
{
|
{
|
||||||
char tmp[64]; strncpy(tmp, fields[18], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0';
|
char tmp[64]; strncpy(tmp, fields[18], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0';
|
||||||
params[44] = atof(trimField(tmp));
|
params[51] = atof(trimField(tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Loaded scenario: domain [%g,%g,%g] to [%g,%g,%g]\n",
|
// useDoubleIntegrator: column 23
|
||||||
params[32], params[33], params[34], params[35], params[36], params[37]);
|
{
|
||||||
|
char tmp[64]; strncpy(tmp, fields[23], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0';
|
||||||
|
params[52] = atof(trimField(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
// dampingCoeff: column 24
|
||||||
|
{
|
||||||
|
char tmp[64]; strncpy(tmp, fields[24], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0';
|
||||||
|
params[53] = atof(trimField(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
// useFixedTopology: column 25
|
||||||
|
{
|
||||||
|
char tmp[64]; strncpy(tmp, fields[25], sizeof(tmp) - 1); tmp[sizeof(tmp)-1] = '\0';
|
||||||
|
params[54] = atof(trimField(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Loaded scenario: domain [%g,%g,%g] to [%g,%g,%g], %d objective component(s)\n",
|
||||||
|
params[32], params[33], params[34], params[35], params[36], params[37], (int)params[38]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,18 +516,22 @@ static const char* messageTypeName(uint8_t msgType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a single-byte message type to a client
|
// Send a single-byte message type to a client (no logging)
|
||||||
int sendMessageType(int clientId, int msgType) {
|
static int sendMessageTypeRaw(int clientId, int msgType) {
|
||||||
if (clientId <= 0 || clientId > (int)clientSockets.size()) return 0;
|
if (clientId <= 0 || clientId > (int)clientSockets.size()) return 0;
|
||||||
|
|
||||||
uint8_t msg = (uint8_t)msgType;
|
uint8_t msg = (uint8_t)msgType;
|
||||||
ssize_t sent = send(clientSockets[clientId - 1], &msg, 1, 0);
|
ssize_t sent = send(clientSockets[clientId - 1], &msg, 1, 0);
|
||||||
if (sent != 1) {
|
if (sent != 1) {
|
||||||
std::cerr << "Send failed for client " << clientId << "\n";
|
std::cerr << "Send failed for client " << clientId << "\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << "Sent " << messageTypeName(msg) << " to client " << clientId << "\n";
|
// Send a single-byte message type to a client
|
||||||
|
int sendMessageType(int clientId, int msgType) {
|
||||||
|
if (!sendMessageTypeRaw(clientId, msgType)) return 0;
|
||||||
|
std::cout << logPrefix() << "Sent " << messageTypeName((uint8_t)msgType) << " to client " << clientId << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,13 +550,7 @@ int sendTarget(int clientId, const double* coords) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timestamp
|
std::cout << logPrefix() << "Sent TARGET to client " << clientId << ": "
|
||||||
time_t now = time(nullptr);
|
|
||||||
struct tm* lt = localtime(&now);
|
|
||||||
char ts[16];
|
|
||||||
strftime(ts, sizeof(ts), "%H:%M:%S", lt);
|
|
||||||
|
|
||||||
std::cout << ts << " Sent TARGET to client " << clientId << ": "
|
|
||||||
<< coords[0] << "," << coords[1] << "," << coords[2] << "\n";
|
<< coords[0] << "," << coords[1] << "," << coords[2] << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -514,31 +598,36 @@ int waitForAllMessageType(int numClients, int expectedType) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Received " << messageTypeName(msgType) << " from client " << (i + 1) << "\n";
|
|
||||||
|
|
||||||
if (msgType == expected) {
|
if (msgType == expected) {
|
||||||
completed[i] = true;
|
completed[i] = true;
|
||||||
completedCount++;
|
completedCount++;
|
||||||
|
} else {
|
||||||
|
std::cerr << logPrefix() << "Unexpected " << messageTypeName(msgType)
|
||||||
|
<< " from client " << (i + 1)
|
||||||
|
<< " (expected " << messageTypeName(expected) << ")\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::cout << logPrefix() << "Received " << messageTypeName(expected) << " from all clients\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Broadcast GUIDANCE_TOGGLE to all clients
|
// Broadcast GUIDANCE_TOGGLE to all clients
|
||||||
void sendGuidanceToggle(int numClients) {
|
void sendGuidanceToggle(int numClients) {
|
||||||
for (int i = 1; i <= numClients; i++) {
|
for (int i = 1; i <= numClients; i++) {
|
||||||
sendMessageType(i, 6); // GUIDANCE_TOGGLE = 6
|
sendMessageTypeRaw(i, 6); // GUIDANCE_TOGGLE = 6
|
||||||
}
|
}
|
||||||
|
std::cout << logPrefix() << "Sent GUIDANCE_TOGGLE to clients\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send REQUEST_POSITION to all clients
|
// Send REQUEST_POSITION to all clients
|
||||||
int sendRequestPositions(int numClients) {
|
int sendRequestPositions(int numClients) {
|
||||||
for (int i = 1; i <= numClients; i++) {
|
for (int i = 1; i <= numClients; i++) {
|
||||||
if (!sendMessageType(i, 7)) return 0; // REQUEST_POSITION = 7
|
if (!sendMessageTypeRaw(i, 7)) return 0; // REQUEST_POSITION = 7
|
||||||
}
|
}
|
||||||
|
std::cout << logPrefix() << "Sent REQUEST_POSITION to clients\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,7 +662,7 @@ int recvPositions(int numClients, double* positions, int maxClients) {
|
|||||||
positions[i + 1 * maxClients] = coords[1]; // north (y)
|
positions[i + 1 * maxClients] = coords[1]; // north (y)
|
||||||
positions[i + 2 * maxClients] = coords[2]; // up (z)
|
positions[i + 2 * maxClients] = coords[2]; // up (z)
|
||||||
|
|
||||||
std::cout << "Position from client " << (i + 1) << ": "
|
std::cout << logPrefix() << "Position from client " << (i + 1) << ": "
|
||||||
<< coords[0] << "," << coords[1] << "," << coords[2] << "\n";
|
<< coords[0] << "," << coords[1] << "," << coords[2] << "\n";
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -27,10 +27,14 @@ int loadTargets(const char* filename, double* targets, int maxClients);
|
|||||||
// 28-31 betaTilt[1:4]
|
// 28-31 betaTilt[1:4]
|
||||||
// 32-34 domainMin
|
// 32-34 domainMin
|
||||||
// 35-37 domainMax
|
// 35-37 domainMax
|
||||||
// 38-39 objectivePos
|
// 38 numObjectiveComponents (1 or 2; inferred from objectivePos field length)
|
||||||
// 40-43 objectiveVar (2x2 col-major)
|
// 39-42 objectivePos flat [x1,y1,x2,y2] (4 slots; zero-padded if N=1)
|
||||||
// 44 sensorPerformanceMinimum
|
// 43-50 objectiveVar flat [v11,v12,v21,v22 per component] (8 slots; zero-padded if N=1)
|
||||||
#define NUM_SCENARIO_PARAMS 45
|
// 51 sensorPerformanceMinimum
|
||||||
|
// 52 useDoubleIntegrator (0=single-integrator, 1=double-integrator)
|
||||||
|
// 53 dampingCoeff
|
||||||
|
// 54 useFixedTopology (0=dynamic lesser-neighbor, 1=fixed)
|
||||||
|
#define NUM_SCENARIO_PARAMS 55
|
||||||
#define MAX_CLIENTS_PER_PARAM 4
|
#define MAX_CLIENTS_PER_PARAM 4
|
||||||
// Maximum number of obstacles (upper bound for pre-allocated arrays).
|
// Maximum number of obstacles (upper bound for pre-allocated arrays).
|
||||||
#define MAX_OBSTACLES 8
|
#define MAX_OBSTACLES 8
|
||||||
@@ -59,6 +63,7 @@ int sendTarget(int clientId, const double* coords);
|
|||||||
int waitForAllMessageType(int numClients, int expectedType);
|
int waitForAllMessageType(int numClients, int expectedType);
|
||||||
|
|
||||||
// Guidance loop operations
|
// Guidance loop operations
|
||||||
|
void setGuidanceStep(int step, int totalSteps); // call at the top of each guidance iteration
|
||||||
void sendGuidanceToggle(int numClients);
|
void sendGuidanceToggle(int numClients);
|
||||||
int sendRequestPositions(int numClients);
|
int sendRequestPositions(int numClients);
|
||||||
int recvPositions(int numClients, double* positions, int maxClients); // column-major maxClients x 3
|
int recvPositions(int numClients, double* positions, int maxClients); // column-major maxClients x 3
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
function controller = controllerAnalysis(resultsPath)
|
||||||
|
arguments (Input)
|
||||||
|
resultsPath (1, 1) string;
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
controller table;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Measure intervals between issuing commands from the controller
|
||||||
|
% (make sure this is ~4-5 seconds at minimum to avoid overwhelming the UAV autopilot)
|
||||||
|
r = dir(resultsPath);
|
||||||
|
controllerPath = fullfile(r(startsWith({r.name}, 'controller_')).folder, r(startsWith({r.name}, 'controller_')).name);
|
||||||
|
controllerPath = dir(controllerPath);
|
||||||
|
controllerPath = fullfile(controllerPath(endsWith({controllerPath.name}, '_controller_log.txt')).folder, controllerPath(endsWith({controllerPath.name}, '_controller_log.txt')).name);
|
||||||
|
controller = readControllerLogs(controllerPath);
|
||||||
|
rpIdx = startsWith(controller.message, "Iteration duration: ");
|
||||||
|
s = split(controller.message(rpIdx), "Iteration duration: ");
|
||||||
|
s = split(s(:, 2), ' s');
|
||||||
|
s = duration(strcat("00:", s(:, 1)), "InputFormat", "mm:ss.SSS");
|
||||||
|
s.Format = "mm:ss.SSS";
|
||||||
|
fprintf("Minimum command spacing: %2.3f seconds\n", seconds(min(s)));
|
||||||
|
fprintf("Maximum command spacing: %2.3f seconds\n", seconds(max(s)));
|
||||||
|
fprintf("Mean command spacing: %2.3f seconds\n", seconds(mean(s)));
|
||||||
|
fprintf("Median command spacing: %2.3f seconds\n", seconds(median(s)));
|
||||||
|
if seconds(min(s)) < 4
|
||||||
|
warning("Minimum command spacing %2.3f questionably short for AERPAW", seconds(min(s)));
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -29,6 +29,7 @@ function [f, G] = plotGpsLogs(logDirs, seaToGroundLevel, plotWholeFlight)
|
|||||||
logDirs = dir(logDirs);
|
logDirs = dir(logDirs);
|
||||||
logDirs = logDirs(3:end);
|
logDirs = logDirs(3:end);
|
||||||
logDirs = logDirs([logDirs.isdir] == 1);
|
logDirs = logDirs([logDirs.isdir] == 1);
|
||||||
|
logDirs = logDirs(~startsWith({logDirs.name}, "controller_"));
|
||||||
|
|
||||||
G = cell(size(logDirs));
|
G = cell(size(logDirs));
|
||||||
for ii = 1:size(logDirs, 1)
|
for ii = 1:size(logDirs, 1)
|
||||||
@@ -61,6 +62,27 @@ function [f, G] = plotGpsLogs(logDirs, seaToGroundLevel, plotWholeFlight)
|
|||||||
enu = array2table(enu, 'VariableNames', ["East", "North", "Up"]);
|
enu = array2table(enu, 'VariableNames', ["East", "North", "Up"]);
|
||||||
G{ii} = [G{ii}, enu];
|
G{ii} = [G{ii}, enu];
|
||||||
|
|
||||||
|
% Do crude comparison of pairwise distances between this UAV and
|
||||||
|
% all previous UAVs
|
||||||
|
for jj = 1:(ii - 1)
|
||||||
|
Ai = G{ii}(:, [1, end-2:end]);
|
||||||
|
Aj = G{jj}(:, [1, end-2:end]);
|
||||||
|
|
||||||
|
% Trim data to match sizes
|
||||||
|
idx = min([size(Ai, 1), size(Aj, 1)]);
|
||||||
|
Ai = Ai(1:idx, :); Aj = Aj(1:idx, :);
|
||||||
|
|
||||||
|
pos_i = [Ai.East, Ai.North, Ai.Up];
|
||||||
|
pos_j = [Aj.East, Aj.North, Aj.Up];
|
||||||
|
d = vecnorm(pos_i - pos_j, 2, 2);
|
||||||
|
d = d(~isnan(d));
|
||||||
|
|
||||||
|
fprintf("Minimum distance between agents %d and %d is %2.3f\n", ii, jj, min(d));
|
||||||
|
if min(d) < 6
|
||||||
|
warning("Minimum distance between agents %d and %d of %2.3f is questionable for AERPAW", ii, jj, min(d));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
% Plot recorded trajectory over specified range of indices
|
% Plot recorded trajectory over specified range of indices
|
||||||
geoplot3(gf, G{ii}.Latitude(startIdx:stopIdx), G{ii}.Longitude(startIdx:stopIdx), G{ii}.Altitude(startIdx:stopIdx) + seaToGroundLevel, c(mod(ii, length(c))), 'LineWidth', 2, "MarkerSize", 5);
|
geoplot3(gf, G{ii}.Latitude(startIdx:stopIdx), G{ii}.Longitude(startIdx:stopIdx), G{ii}.Altitude(startIdx:stopIdx) + seaToGroundLevel, c(mod(ii, length(c))), 'LineWidth', 2, "MarkerSize", 5);
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
function [f, R] = plotRadioLogs(resultsPath)
|
function [f, fDist, R] = plotRadioLogs(resultsPath, G, tLim)
|
||||||
arguments (Input)
|
arguments (Input)
|
||||||
resultsPath (1, 1) string;
|
resultsPath (1, 1) string;
|
||||||
|
G cell = {};
|
||||||
|
tLim (1, 2) datetime = [datetime(-Inf, 'ConvertFrom', 'datenum'), datetime(Inf, 'ConvertFrom', 'datenum')];
|
||||||
end
|
end
|
||||||
arguments (Output)
|
arguments (Output)
|
||||||
f (1, 1) matlab.ui.Figure;
|
f (1, 1) matlab.ui.Figure;
|
||||||
|
fDist (1, 1) matlab.ui.Figure;
|
||||||
R cell;
|
R cell;
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -40,11 +43,44 @@ function [f, R] = plotRadioLogs(resultsPath)
|
|||||||
|
|
||||||
metricNames = ["SNR", "Power", "Quality", "PathLoss", "NoiseFloor", "FreqOffset"];
|
metricNames = ["SNR", "Power", "Quality", "PathLoss", "NoiseFloor", "FreqOffset"];
|
||||||
yLabels = ["SNR (dB)", "Power (dB)", "Quality", "Path Loss (dB)", "Noise Floor (dB)", "Freq Offset (MHz)"];
|
yLabels = ["SNR (dB)", "Power (dB)", "Quality", "Path Loss (dB)", "Noise Floor (dB)", "Freq Offset (MHz)"];
|
||||||
|
nMetrics = numel(metricNames);
|
||||||
|
|
||||||
|
% --- Time-based figure ---
|
||||||
f = figure;
|
f = figure;
|
||||||
tl = tiledlayout(numel(metricNames), 1, 'TileSpacing', 'compact', 'Padding', 'compact');
|
tl = tiledlayout(nMetrics + 1, 1, 'TileSpacing', 'compact', 'Padding', 'compact');
|
||||||
|
|
||||||
for mi = 1:numel(metricNames)
|
% Distance vs time tile (first)
|
||||||
|
ax = nexttile(tl);
|
||||||
|
hold(ax, 'on'); grid(ax, 'on');
|
||||||
|
legendEntries = string.empty;
|
||||||
|
ci = 1;
|
||||||
|
if ~isempty(G)
|
||||||
|
for rxIdx = 1:nUAV
|
||||||
|
tbl = R{rxIdx};
|
||||||
|
txIDs = unique(tbl.TxUAVID);
|
||||||
|
for ti = 1:numel(txIDs)
|
||||||
|
txID = txIDs(ti);
|
||||||
|
rows = tbl(tbl.TxUAVID == txID, :);
|
||||||
|
rows = rows(rows.Timestamp >= tLim(1) & rows.Timestamp <= tLim(2), :);
|
||||||
|
if isempty(rows), continue; end
|
||||||
|
[~, ia] = unique(rows.Timestamp);
|
||||||
|
[radioPt, dist] = pairDist(rows(ia, :), G);
|
||||||
|
if isempty(dist) || all(isnan(dist)), continue; end
|
||||||
|
valid = ~isnan(dist);
|
||||||
|
si = mod(ci - 1, numel(styles)) + 1;
|
||||||
|
plot(ax, datetime(radioPt(valid), 'ConvertFrom', 'posixtime'), dist(valid), ...
|
||||||
|
styles(si), 'Color', colors(ci, :), 'MarkerSize', 3, 'LineWidth', 0.5);
|
||||||
|
legendEntries(end+1) = sprintf("TX %d → RX %d", txID, rows.RxUAVID(1)); %#ok<AGROW>
|
||||||
|
ci = ci + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ylabel(ax, 'Distance (m)');
|
||||||
|
xlabel(ax, 'Time');
|
||||||
|
legend(ax, legendEntries, 'Location', 'best');
|
||||||
|
hold(ax, 'off');
|
||||||
|
|
||||||
|
for mi = 1:nMetrics
|
||||||
ax = nexttile(tl);
|
ax = nexttile(tl);
|
||||||
hold(ax, 'on');
|
hold(ax, 'on');
|
||||||
grid(ax, 'on');
|
grid(ax, 'on');
|
||||||
@@ -57,23 +93,32 @@ function [f, R] = plotRadioLogs(resultsPath)
|
|||||||
for ti = 1:numel(txIDs)
|
for ti = 1:numel(txIDs)
|
||||||
txID = txIDs(ti);
|
txID = txIDs(ti);
|
||||||
rows = tbl(tbl.TxUAVID == txID, :);
|
rows = tbl(tbl.TxUAVID == txID, :);
|
||||||
|
rows = rows(rows.Timestamp >= tLim(1) & rows.Timestamp <= tLim(2), :);
|
||||||
vals = rows.(metricNames(mi));
|
vals = rows.(metricNames(mi));
|
||||||
|
valid = ~isnan(vals);
|
||||||
|
rows = rows(valid, :);
|
||||||
|
vals = vals(valid);
|
||||||
|
|
||||||
% Skip if all NaN for this metric
|
if isempty(rows)
|
||||||
if all(isnan(vals))
|
|
||||||
continue;
|
continue;
|
||||||
end
|
end
|
||||||
|
|
||||||
si = mod(ci - 1, numel(styles)) + 1;
|
si = mod(ci - 1, numel(styles)) + 1;
|
||||||
plot(ax, rows.Timestamp, vals, styles(si), ...
|
plot(ax, rows.Timestamp, vals, styles(si), ...
|
||||||
'Color', colors(ci, :), 'MarkerSize', 3, 'LineWidth', 1);
|
'Color', colors(ci, :), 'MarkerSize', 3, 'LineWidth', 0.5);
|
||||||
legendEntries(end+1) = sprintf("TX %d → RX %d", txID, tbl.RxUAVID(1)); %#ok<AGROW>
|
legendEntries(end+1) = sprintf("TX %d → RX %d", txID, tbl.RxUAVID(1)); %#ok<AGROW>
|
||||||
|
|
||||||
|
% Median per 1/3-second time bin
|
||||||
|
[t_med, v_med] = timeBinMedian(posixtime(rows.Timestamp), vals, 1/3);
|
||||||
|
plot(ax, datetime(t_med, 'ConvertFrom', 'posixtime'), v_med, '-', ...
|
||||||
|
'Color', 'r', 'LineWidth', 2);
|
||||||
|
legendEntries(end+1) = sprintf("TX %d → RX %d (median)", txID, tbl.RxUAVID(1)); %#ok<AGROW>
|
||||||
ci = ci + 1;
|
ci = ci + 1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
ylabel(ax, yLabels(mi));
|
ylabel(ax, yLabels(mi));
|
||||||
if mi == numel(metricNames)
|
if mi == nMetrics
|
||||||
xlabel(ax, 'Time');
|
xlabel(ax, 'Time');
|
||||||
end
|
end
|
||||||
legend(ax, legendEntries, 'Location', 'best');
|
legend(ax, legendEntries, 'Location', 'best');
|
||||||
@@ -81,4 +126,134 @@ function [f, R] = plotRadioLogs(resultsPath)
|
|||||||
end
|
end
|
||||||
|
|
||||||
title(tl, 'Radio Channel Metrics');
|
title(tl, 'Radio Channel Metrics');
|
||||||
|
|
||||||
|
% --- Distance-based figure ---
|
||||||
|
fDist = figure;
|
||||||
|
|
||||||
|
if isempty(G)
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
tl2 = tiledlayout(nMetrics + 1, 1, 'TileSpacing', 'compact', 'Padding', 'compact');
|
||||||
|
|
||||||
|
% Distance vs time tile (first)
|
||||||
|
ax = nexttile(tl2);
|
||||||
|
hold(ax, 'on'); grid(ax, 'on');
|
||||||
|
legendEntries = string.empty;
|
||||||
|
ci = 1;
|
||||||
|
for rxIdx = 1:nUAV
|
||||||
|
tbl = R{rxIdx};
|
||||||
|
txIDs = unique(tbl.TxUAVID);
|
||||||
|
for ti = 1:numel(txIDs)
|
||||||
|
txID = txIDs(ti);
|
||||||
|
rows = tbl(tbl.TxUAVID == txID, :);
|
||||||
|
rows = rows(rows.Timestamp >= tLim(1) & rows.Timestamp <= tLim(2), :);
|
||||||
|
if isempty(rows), continue; end
|
||||||
|
[~, ia] = unique(rows.Timestamp);
|
||||||
|
[radioPt, dist] = pairDist(rows(ia, :), G);
|
||||||
|
if isempty(dist) || all(isnan(dist)), continue; end
|
||||||
|
valid = ~isnan(dist);
|
||||||
|
si = mod(ci - 1, numel(styles)) + 1;
|
||||||
|
plot(ax, datetime(radioPt(valid), 'ConvertFrom', 'posixtime'), dist(valid), ...
|
||||||
|
styles(si), 'Color', colors(ci, :), 'MarkerSize', 3, 'LineWidth', 0.5);
|
||||||
|
legendEntries(end+1) = sprintf("TX %d → RX %d", txID, rows.RxUAVID(1)); %#ok<AGROW>
|
||||||
|
ci = ci + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ylabel(ax, 'Distance (m)');
|
||||||
|
xlabel(ax, 'Time');
|
||||||
|
legend(ax, legendEntries, 'Location', 'best');
|
||||||
|
hold(ax, 'off');
|
||||||
|
|
||||||
|
for mi = 1:nMetrics
|
||||||
|
ax = nexttile(tl2);
|
||||||
|
hold(ax, 'on');
|
||||||
|
grid(ax, 'on');
|
||||||
|
|
||||||
|
legendEntries = string.empty;
|
||||||
|
ci = 1;
|
||||||
|
for rxIdx = 1:nUAV
|
||||||
|
tbl = R{rxIdx};
|
||||||
|
txIDs = unique(tbl.TxUAVID);
|
||||||
|
for ti = 1:numel(txIDs)
|
||||||
|
txID = txIDs(ti);
|
||||||
|
rows = tbl(tbl.TxUAVID == txID, :);
|
||||||
|
|
||||||
|
if isempty(rows)
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
|
||||||
|
rows = rows(rows.Timestamp >= tLim(1) & rows.Timestamp <= tLim(2), :);
|
||||||
|
if isempty(rows)
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
|
||||||
|
vals = rows.(metricNames(mi));
|
||||||
|
valid = ~isnan(vals);
|
||||||
|
rows = rows(valid, :);
|
||||||
|
vals = vals(valid);
|
||||||
|
|
||||||
|
if isempty(rows)
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
|
||||||
|
[radioPt, dist] = pairDist(rows, G);
|
||||||
|
if isempty(dist) || all(isnan(dist)), continue; end
|
||||||
|
|
||||||
|
% Drop points where GPS interpolation returned NaN
|
||||||
|
validDist = ~isnan(dist);
|
||||||
|
rowTs = radioPt(validDist);
|
||||||
|
dist = dist(validDist);
|
||||||
|
vals = vals(validDist);
|
||||||
|
|
||||||
|
si = mod(ci - 1, numel(styles)) + 1;
|
||||||
|
scatter(ax, dist, vals, 9, colors(ci, :), strrep(styles(si), "-", ""), 'filled');
|
||||||
|
legendEntries(end+1) = sprintf("TX %d → RX %d", txID, rows.RxUAVID(1)); %#ok<AGROW>
|
||||||
|
|
||||||
|
% Median per 1/3-second time bin, plotted against median distance
|
||||||
|
[~, dv_med] = timeBinMedian(rowTs, [dist, vals], 1/3);
|
||||||
|
[d_med, si_sort] = sort(dv_med(:, 1));
|
||||||
|
v_med = dv_med(si_sort, 2);
|
||||||
|
plot(ax, d_med, v_med, '-', 'Color', 'r', 'LineWidth', 2);
|
||||||
|
legendEntries(end+1) = sprintf("TX %d → RX %d (median)", txID, rows.RxUAVID(1)); %#ok<AGROW>
|
||||||
|
ci = ci + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ylabel(ax, yLabels(mi));
|
||||||
|
if mi == nMetrics
|
||||||
|
xlabel(ax, 'Distance (m)');
|
||||||
|
end
|
||||||
|
legend(ax, legendEntries, 'Location', 'best');
|
||||||
|
hold(ax, 'off');
|
||||||
|
end
|
||||||
|
|
||||||
|
title(tl2, 'Radio Channel Metrics vs Distance');
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function [radioPt, dist] = pairDist(rows, G)
|
||||||
|
% Interpolate GPS-based inter-UAV distance at each row's timestamp.
|
||||||
|
radioPt = []; dist = [];
|
||||||
|
txGpsIdx = double(rows.TxUAVID(1)) + 1;
|
||||||
|
rxGpsIdx = double(rows.RxUAVID(1)) + 1;
|
||||||
|
if txGpsIdx > numel(G) || rxGpsIdx > numel(G), return; end
|
||||||
|
Gtx = G{txGpsIdx};
|
||||||
|
Grx = G{rxGpsIdx};
|
||||||
|
if ~ismember('East', Gtx.Properties.VariableNames) || ...
|
||||||
|
~ismember('East', Grx.Properties.VariableNames), return; end
|
||||||
|
txTs = Gtx.Timestamp; txTs.TimeZone = '';
|
||||||
|
rxTs = Grx.Timestamp; rxTs.TimeZone = '';
|
||||||
|
txPt = posixtime(txTs);
|
||||||
|
rxPt = posixtime(rxTs);
|
||||||
|
radioPt = posixtime(rows.Timestamp);
|
||||||
|
validTx = ~isnan(Gtx.East);
|
||||||
|
validRx = ~isnan(Grx.East);
|
||||||
|
txE = interp1(txPt(validTx), Gtx.East(validTx), radioPt, 'linear', NaN);
|
||||||
|
txN = interp1(txPt(validTx), Gtx.North(validTx), radioPt, 'linear', NaN);
|
||||||
|
txU = interp1(txPt(validTx), Gtx.Up(validTx), radioPt, 'linear', NaN);
|
||||||
|
rxE = interp1(rxPt(validRx), Grx.East(validRx), radioPt, 'linear', NaN);
|
||||||
|
rxN = interp1(rxPt(validRx), Grx.North(validRx), radioPt, 'linear', NaN);
|
||||||
|
rxU = interp1(rxPt(validRx), Grx.Up(validRx), radioPt, 'linear', NaN);
|
||||||
|
dist = vecnorm([txE - rxE, txN - rxN, txU - rxU], 2, 2);
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
function T2 = readControllerLogs(filepath)
|
||||||
|
arguments (Input)
|
||||||
|
filepath (1, 1) string;
|
||||||
|
end
|
||||||
|
arguments (Output)
|
||||||
|
T2 table;
|
||||||
|
end
|
||||||
|
assert(isfile(filepath), "File not found at %s", filepath);
|
||||||
|
|
||||||
|
T = readtable(filepath, 'VariableNamingRule', 'preserve');
|
||||||
|
s = split(T.(T.Properties.VariableNames{1}), ']');
|
||||||
|
s2 = strip(s(startsWith(s(:, 2), " ("), 1), 'left', '[');
|
||||||
|
d = datetime(s2, "InputFormat", "yyyy-MM-dd HH:mm:ss.SSSSSS")';
|
||||||
|
it = s(startsWith(s(:, 2), " ("), 2);
|
||||||
|
it = str2double(strip(strip(it, 'left'), 'left', '('));
|
||||||
|
T.Var3 = strip(append(T.Var3, " ", T.Var4, " ", T.Var5, " ", T.Var6, " ", T.Var7));
|
||||||
|
T.Var4 = []; T.Var5 = []; T.Var6 = []; T.Var7 = [];
|
||||||
|
msg = T.(T.Properties.VariableNames{2});
|
||||||
|
msg = msg(startsWith(s(:, 2), " ("), :);
|
||||||
|
s3 = split(msg, ') ');
|
||||||
|
s3 = s3(:, 2);
|
||||||
|
msg = append(s3, T.Var3(startsWith(s(:, 2), " (")));
|
||||||
|
T2 = table(it, d', msg, 'VariableNames', ["iteration", "timestamp", "message"]);
|
||||||
|
% T.Var1 = datetime(strip(strip(append(T.Var1, " ", T.Var2), 'left', '['), 'right', ']'), "InputFormat", "yyyy-MM-dd HH:mm:ss.SSSSSS");
|
||||||
|
% T.Var2 = [];
|
||||||
|
% T.Var3 = strip(append(T.Var3, " ", T.Var4, " ", T.Var5, " ", T.Var6, " ", string(T.Var7), " ", T.Var8, " ", T.Var9));
|
||||||
|
% T.Var4 = []; T.Var5 = []; T.Var6 = []; T.Var7 = []; T.Var8 = []; T.Var9 = [];
|
||||||
|
% T.Properties.VariableNames{1} = 'timestamp';
|
||||||
|
% T.Properties.VariableNames{2} = 'message';
|
||||||
|
|
||||||
|
% T(ismissing(T.message), :) = [];
|
||||||
|
end
|
||||||
@@ -2,7 +2,6 @@ function R = readRadioLogs(logPath)
|
|||||||
arguments (Input)
|
arguments (Input)
|
||||||
logPath (1, 1) string {isfolder(logPath)};
|
logPath (1, 1) string {isfolder(logPath)};
|
||||||
end
|
end
|
||||||
|
|
||||||
arguments (Output)
|
arguments (Output)
|
||||||
R (:, 8) table;
|
R (:, 8) table;
|
||||||
end
|
end
|
||||||
@@ -71,6 +70,40 @@ function R = readRadioLogs(logPath)
|
|||||||
|
|
||||||
R = sortrows(R, "Timestamp");
|
R = sortrows(R, "Timestamp");
|
||||||
|
|
||||||
|
% Reconstruct per-measurement timestamps within GNURadio processing batches.
|
||||||
|
% The flowgraph accumulates one full PN sequence (4095 chips at samp_rate/sps)
|
||||||
|
% per measurement, but outputs the whole batch simultaneously with a single
|
||||||
|
% wall-clock timestamp. We reassign timestamps by counting backward from the
|
||||||
|
% batch processing time at the known PN period interval.
|
||||||
|
pn_period = 4095 / (2e6 / 16); % 32.76 ms per PN correlation period
|
||||||
|
|
||||||
|
for txId = unique(R.TxUAVID)'
|
||||||
|
rows = find(R.TxUAVID == txId);
|
||||||
|
if numel(rows) < 2, continue; end
|
||||||
|
|
||||||
|
dt = seconds(diff(R.Timestamp(rows)));
|
||||||
|
break_pos = [1; find(dt > 0.5) + 1];
|
||||||
|
end_pos = [break_pos(2:end) - 1; numel(rows)];
|
||||||
|
|
||||||
|
for b = 1:numel(break_pos)
|
||||||
|
idx = rows(break_pos(b) : end_pos(b));
|
||||||
|
batch_ts = posixtime(R.Timestamp(idx));
|
||||||
|
t_ref = max(batch_ts);
|
||||||
|
|
||||||
|
% Multiple metric files share the same processing timestamp for
|
||||||
|
% each PN period, so group by unique original timestamp rather
|
||||||
|
% than treating every row as a separate PN period.
|
||||||
|
[~, ~, group_id] = unique(batch_ts);
|
||||||
|
n_groups = max(group_id);
|
||||||
|
new_ts = t_ref - (n_groups - 1 : -1 : 0)' * pn_period;
|
||||||
|
|
||||||
|
for g = 1:n_groups
|
||||||
|
R.Timestamp(idx(group_id == g)) = ...
|
||||||
|
datetime(new_ts(g), 'ConvertFrom', 'posixtime');
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
% Remove rows during defined guard period between TDM shifts
|
% Remove rows during defined guard period between TDM shifts
|
||||||
R(R.TxUAVID == -1, :) = [];
|
R(R.TxUAVID == -1, :) = [];
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
%% Plot AERPAW logs (trajectory, radio)
|
%% Plot AERPAW logs (trajectory, radio)
|
||||||
resultsPath = fullfile(matlab.project.rootProject().RootFolder, "sandbox", "two_around_wall"); % Define path to results copied from AERPAW platform
|
resultsPath = fullfile(matlab.project.rootProject().RootFolder, "sandbox", "two_around_wall"); % Define path to results copied from AERPAW platform
|
||||||
|
|
||||||
|
% Check timeline in controller logs
|
||||||
|
controller = controllerAnalysis(resultsPath);
|
||||||
|
|
||||||
% Plot GPS logged data and scenario information (domain, objective, obstacles)
|
% Plot GPS logged data and scenario information (domain, objective, obstacles)
|
||||||
seaToGroundLevel = 110; % measured approximately from USGS national map viewer
|
seaToGroundLevel = 110; % measured approximately from USGS national map viewer
|
||||||
plotWholeFlight = true; % do not attempt to automatically trim initial and final positioning and landing from flight plot (buggy)
|
plotWholeFlight = true; % do not attempt to automatically trim initial and final positioning and landing from flight plot (buggy)
|
||||||
% [fGlobe, G] = plotGpsLogs(resultsPath, seaToGroundLevel, true);
|
[fGlobe, G] = plotGpsLogs(resultsPath, seaToGroundLevel, true);
|
||||||
|
|
||||||
% Plot radio statistics
|
% Plot radio statistics (time-based and distance-based)
|
||||||
[fRadio, R] = plotRadioLogs(resultsPath);
|
[fRadio, fRadioDist, R] = plotRadioLogs(resultsPath, G, controller.timestamp([1, end]));
|
||||||
|
|
||||||
%% Run simulation
|
%% Run simulation
|
||||||
% Run miSim using same AERPAW scenario definition CSV
|
% Run miSim using same AERPAW scenario definition CSV
|
||||||
@@ -34,7 +37,7 @@ for ii = 1:size(agents, 1)
|
|||||||
collisionGeometry = spherical;
|
collisionGeometry = spherical;
|
||||||
collisionGeometry = collisionGeometry.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), params.collisionRadius(ii), REGION_TYPE.COLLISION, sprintf("Agent %d collision geometry", ii));
|
collisionGeometry = collisionGeometry.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), params.collisionRadius(ii), REGION_TYPE.COLLISION, sprintf("Agent %d collision geometry", ii));
|
||||||
|
|
||||||
agents{ii} = agents{ii}.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), collisionGeometry, sensorModel, params.comRange(ii), params.maxIter, params.initialStepSize, sprintf("Agent %d", ii), plotCommsGeometry);
|
agents{ii} = agents{ii}.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), collisionGeometry, sensorModel, params.comRange(ii), params.maxIter, params.initialStepSize, 5.0, sprintf("Agent %d", ii), plotCommsGeometry);
|
||||||
end
|
end
|
||||||
|
|
||||||
% Create obstacles
|
% Create obstacles
|
||||||
@@ -61,9 +64,12 @@ copyobj(sim.f.Children, comparison);
|
|||||||
|
|
||||||
% Plot trajectories on top
|
% Plot trajectories on top
|
||||||
for ii = 1:size(G, 1)
|
for ii = 1:size(G, 1)
|
||||||
|
gpsTimes = G{ii}.Timestamp;
|
||||||
|
gpsTimes.TimeZone = '';
|
||||||
|
inRange = gpsTimes >= controller.timestamp(1) & gpsTimes <= controller.timestamp(end);
|
||||||
for jj = 1:size(sim.spatialPlotIndices, 2)
|
for jj = 1:size(sim.spatialPlotIndices, 2)
|
||||||
hold(comparison.Children.Children(sim.spatialPlotIndices(jj)), "on");
|
hold(comparison.Children.Children(sim.spatialPlotIndices(jj)), "on");
|
||||||
plot3(comparison.Children(1).Children(sim.spatialPlotIndices(jj)), G{ii}.East, G{ii}.North, G{ii}.Up + seaToGroundLevel, 'Color', 'r', 'LineWidth', 1);
|
plot3(comparison.Children(1).Children(sim.spatialPlotIndices(jj)), G{ii}.East(inRange), G{ii}.North(inRange), G{ii}.Up(inRange) + seaToGroundLevel, 'Color', 'r', 'LineWidth', 1);
|
||||||
hold(comparison.Children.Children(sim.spatialPlotIndices(jj)), "off");
|
hold(comparison.Children.Children(sim.spatialPlotIndices(jj)), "off");
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
function [t_med, v_med] = timeBinMedian(t, v, binWidth)
|
||||||
|
% Compute median of each column of v within fixed-width time bins.
|
||||||
|
%
|
||||||
|
% t - (N,1) posixtime values
|
||||||
|
% v - (N,K) data matrix; one column per quantity
|
||||||
|
% binWidth - scalar bin width in seconds
|
||||||
|
%
|
||||||
|
% t_med - (B,1) median time of each non-empty bin
|
||||||
|
% v_med - (B,K) median of each column per non-empty bin
|
||||||
|
|
||||||
|
edges = (floor(min(t) / binWidth) * binWidth) : binWidth : ...
|
||||||
|
(floor(max(t) / binWidth) * binWidth + binWidth);
|
||||||
|
bins = discretize(t, edges);
|
||||||
|
nBins = numel(edges) - 1;
|
||||||
|
K = size(v, 2);
|
||||||
|
|
||||||
|
t_all = NaN(nBins, 1);
|
||||||
|
v_all = NaN(nBins, K);
|
||||||
|
for bi = 1:nBins
|
||||||
|
mask = bins == bi;
|
||||||
|
if ~any(mask), continue; end
|
||||||
|
t_all(bi) = median(t(mask));
|
||||||
|
v_all(bi,:) = median(v(mask,:), 1);
|
||||||
|
end
|
||||||
|
|
||||||
|
ok = ~isnan(t_all);
|
||||||
|
t_med = t_all(ok);
|
||||||
|
v_med = v_all(ok, :);
|
||||||
|
end
|
||||||
@@ -6,9 +6,11 @@ classdef cone
|
|||||||
label = "";
|
label = "";
|
||||||
|
|
||||||
% Spatial
|
% Spatial
|
||||||
center = NaN;
|
center = NaN;
|
||||||
radius = NaN;
|
radius = NaN;
|
||||||
height = NaN;
|
height = NaN;
|
||||||
|
tilt = 0; % degrees, 0=nadir 90=horizon
|
||||||
|
azimuth = 0; % degrees, 0=+Y 90=+X clockwise
|
||||||
|
|
||||||
% Plotting
|
% Plotting
|
||||||
surface;
|
surface;
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
function obj = initialize(obj, center, radius, height, tag, label)
|
function obj = initialize(obj, center, radius, height, tag, label, tilt, azimuth)
|
||||||
arguments (Input)
|
arguments (Input)
|
||||||
obj (1, 1) {mustBeA(obj, "cone")};
|
obj (1, 1) {mustBeA(obj, "cone")};
|
||||||
center (1, 3) double;
|
center (1, 3) double;
|
||||||
radius (1, 1) double;
|
radius (1, 1) double;
|
||||||
height (1, 1) double;
|
height (1, 1) double;
|
||||||
tag (1, 1) REGION_TYPE = REGION_TYPE.INVALID;
|
tag (1, 1) REGION_TYPE = REGION_TYPE.INVALID;
|
||||||
label (1, 1) string = "";
|
label (1, 1) string = "";
|
||||||
|
tilt (1, 1) double = 0;
|
||||||
|
azimuth (1, 1) double = 0;
|
||||||
end
|
end
|
||||||
arguments (Output)
|
arguments (Output)
|
||||||
obj (1, 1) {mustBeA(obj, "cone")};
|
obj (1, 1) {mustBeA(obj, "cone")};
|
||||||
end
|
end
|
||||||
|
|
||||||
obj.center = center;
|
obj.center = center;
|
||||||
obj.radius = radius;
|
obj.radius = radius;
|
||||||
obj.height = height;
|
obj.height = height;
|
||||||
obj.tag = tag;
|
obj.tag = tag;
|
||||||
obj.label = label;
|
obj.label = label;
|
||||||
|
obj.tilt = tilt;
|
||||||
|
obj.azimuth = azimuth;
|
||||||
end
|
end
|
||||||
@@ -21,6 +21,17 @@ function [obj, f] = plot(obj, ind, f, maxAlt)
|
|||||||
% Scale to match height
|
% Scale to match height
|
||||||
Z = Z * maxAlt;
|
Z = Z * maxAlt;
|
||||||
|
|
||||||
|
% Rotate mesh around apex to match boresight tilt and azimuth.
|
||||||
|
% Apex sits at [0, 0, maxAlt] before center translation.
|
||||||
|
% Convention: tilt 0=nadir, 90=horizon; azimuth 0=+Y, 90=+X, clockwise.
|
||||||
|
Ry = [cosd(obj.tilt), 0, -sind(obj.tilt); 0, 1, 0; sind(obj.tilt), 0, cosd(obj.tilt)];
|
||||||
|
Rz = [sind(obj.azimuth), -cosd(obj.azimuth), 0; cosd(obj.azimuth), sind(obj.azimuth), 0; 0, 0, 1];
|
||||||
|
R = Rz * Ry;
|
||||||
|
pts = R * [X(:)'; Y(:)'; Z(:)' - maxAlt];
|
||||||
|
X = reshape(pts(1, :), size(X));
|
||||||
|
Y = reshape(pts(2, :), size(Y));
|
||||||
|
Z = reshape(pts(3, :) + maxAlt, size(Z));
|
||||||
|
|
||||||
% Move to center location
|
% Move to center location
|
||||||
X = X + obj.center(1);
|
X = X + obj.center(1);
|
||||||
Y = Y + obj.center(2);
|
Y = Y + obj.center(2);
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="test"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="test_rfSensor.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="plot.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="clearRssCache.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="rfSensor.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="plotParameters.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="plotPerformance.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="halfAngle.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="computePointToPoints.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="sensorPerformance.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="transmitterGain.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="initialize.m" type="File"/>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info/>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="1" type="DIR_SIGNIFIER"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="RSS.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="pathLoss.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="readControllerLogs.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="controllerAnalysis.m" type="File"/>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info>
|
||||||
|
<Category UUID="FileClassCategory">
|
||||||
|
<Label UUID="design"/>
|
||||||
|
</Category>
|
||||||
|
</Info>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="halfAngle.m" type="File"/>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info/>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Info location="@rfSensor" type="File"/>
|
||||||
@@ -34,8 +34,14 @@ classdef parametricTestSuite < matlab.unittest.TestCase
|
|||||||
|
|
||||||
% Define scenario according to CSV specification
|
% Define scenario according to CSV specification
|
||||||
tc.domain = tc.domain.initialize([params.domainMin; params.domainMax], REGION_TYPE.DOMAIN, "Domain");
|
tc.domain = tc.domain.initialize([params.domainMin; params.domainMax], REGION_TYPE.DOMAIN, "Domain");
|
||||||
objectiveSigma = reshape(params.objectiveVar, [1 2 2]);
|
if length(params.objectiveVar) > 4 && length(params.objectivePos) > 2
|
||||||
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper(params.objectivePos, objectiveSigma), tc.domain, params.discretizationStep, params.protectedRange, params.sensorPerformanceMinimum, params.objectivePos, objectiveSigma);
|
objectiveSigma = permute(reshape(params.objectiveVar, [length(params.objectiveVar)/4 2 2]), [3 1 2]);
|
||||||
|
objectivePos = reshape(params.objectivePos, [length(params.objectivePos)/2, 2])';
|
||||||
|
else
|
||||||
|
objectiveSigma = reshape(params.objectiveVar, [1, 2, 2]);
|
||||||
|
objectivePos = params.objectivePos;
|
||||||
|
end
|
||||||
|
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper(objectivePos, objectiveSigma), tc.domain, params.discretizationStep, params.protectedRange, params.sensorPerformanceMinimum, objectivePos, objectiveSigma);
|
||||||
|
|
||||||
agents = cell(size(params.initialPositions, 2) / 3, 1);
|
agents = cell(size(params.initialPositions, 2) / 3, 1);
|
||||||
for ii = 1:size(agents, 1)
|
for ii = 1:size(agents, 1)
|
||||||
@@ -47,7 +53,7 @@ classdef parametricTestSuite < matlab.unittest.TestCase
|
|||||||
collisionGeometry = spherical;
|
collisionGeometry = spherical;
|
||||||
collisionGeometry = collisionGeometry.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), params.collisionRadius(ii), REGION_TYPE.COLLISION, sprintf("Agent %d collision geometry", ii));
|
collisionGeometry = collisionGeometry.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), params.collisionRadius(ii), REGION_TYPE.COLLISION, sprintf("Agent %d collision geometry", ii));
|
||||||
|
|
||||||
agents{ii} = agents{ii}.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), collisionGeometry, sensorModel, params.comRange(ii), params.maxIter, params.initialStepSize, sprintf("Agent %d", ii), tc.plotCommsGeometry);
|
agents{ii} = agents{ii}.initialize(params.initialPositions((((ii - 1) * 3) + 1):(ii * 3)), collisionGeometry, sensorModel, params.comRange(ii), params.maxIter, params.initialStepSize, 5.0, sprintf("Agent %d", ii), tc.plotCommsGeometry);
|
||||||
end
|
end
|
||||||
|
|
||||||
% Create obstacles
|
% Create obstacles
|
||||||
@@ -106,7 +112,7 @@ classdef parametricTestSuite < matlab.unittest.TestCase
|
|||||||
|
|
||||||
% Initialize agent
|
% Initialize agent
|
||||||
collisionGeometry = collisionGeometry.initialize(agentPos, params.collisionRadius(ii, 1), REGION_TYPE.COLLISION, "Agent 1 Collision Region");
|
collisionGeometry = collisionGeometry.initialize(agentPos, params.collisionRadius(ii, 1), REGION_TYPE.COLLISION, "Agent 1 Collision Region");
|
||||||
agents{1} = agents{1}.initialize(agentPos, collisionGeometry, sensorModel, params.comRange(ii, 1), params.maxIter(ii), params.initialStepSize(ii), "Agent 1", tc.plotCommsGeometry);
|
agents{1} = agents{1}.initialize(agentPos, collisionGeometry, sensorModel, params.comRange(ii, 1), params.maxIter(ii), params.initialStepSize(ii), 5.0, "Agent 1", tc.plotCommsGeometry);
|
||||||
|
|
||||||
% Set up remaining agents in random (valid) locations
|
% Set up remaining agents in random (valid) locations
|
||||||
for jj = 2:size(agents, 1)
|
for jj = 2:size(agents, 1)
|
||||||
@@ -148,7 +154,7 @@ classdef parametricTestSuite < matlab.unittest.TestCase
|
|||||||
|
|
||||||
% Initialize agent
|
% Initialize agent
|
||||||
collisionGeometry = collisionGeometry.initialize(agentPos, params.collisionRadius(ii, jj), REGION_TYPE.COLLISION, sprintf("Agent %d Collision Region", jj));
|
collisionGeometry = collisionGeometry.initialize(agentPos, params.collisionRadius(ii, jj), REGION_TYPE.COLLISION, sprintf("Agent %d Collision Region", jj));
|
||||||
agents{jj} = agents{jj}.initialize(agentPos, collisionGeometry, sensorModel, params.comRange(ii, jj), params.maxIter(ii), params.initialStepSize(ii), sprintf("Agent %d", jj), tc.plotCommsGeometry);
|
agents{jj} = agents{jj}.initialize(agentPos, collisionGeometry, sensorModel, params.comRange(ii, jj), params.maxIter(ii), params.initialStepSize(ii), 5.0, sprintf("Agent %d", jj), tc.plotCommsGeometry);
|
||||||
end
|
end
|
||||||
|
|
||||||
% randomly shuffle agents to make the network more interesting (probably)
|
% randomly shuffle agents to make the network more interesting (probably)
|
||||||
|
|||||||
+325
-50
@@ -9,8 +9,8 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
plotCommsGeometry = false; % disable plotting communications geometries
|
plotCommsGeometry = false; % disable plotting communications geometries
|
||||||
|
|
||||||
% Sim
|
% Sim
|
||||||
maxIter = 50;
|
maxIter = 250;
|
||||||
timestep = 0.05;
|
timestep = 0.1;
|
||||||
|
|
||||||
% Domain
|
% Domain
|
||||||
domain = rectangularPrism; % domain geometry
|
domain = rectangularPrism; % domain geometry
|
||||||
@@ -31,6 +31,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
|
|
||||||
% Agents
|
% Agents
|
||||||
initialStepSize = 0.2; % gradient ascent step size at the first iteration. Decreases linearly to 0 based on maxIter.
|
initialStepSize = 0.2; % gradient ascent step size at the first iteration. Decreases linearly to 0 based on maxIter.
|
||||||
|
initialMaxAngleStepSize = 0.1; % angular step size (degrees) for tilt/azimuth gradient ascent per timestep.
|
||||||
minAgents = 3; % Minimum number of agents to be randomly generated
|
minAgents = 3; % Minimum number of agents to be randomly generated
|
||||||
maxAgents = 4; % Maximum number of agents to be randomly generated
|
maxAgents = 4; % Maximum number of agents to be randomly generated
|
||||||
useDoubleIntegrator = false;
|
useDoubleIntegrator = false;
|
||||||
@@ -43,6 +44,8 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
collisionRanges = NaN;
|
collisionRanges = NaN;
|
||||||
|
|
||||||
% Sensing
|
% Sensing
|
||||||
|
sensor = sigmoidSensor;
|
||||||
|
% sigmoidSensor
|
||||||
betaDistMin = 3;
|
betaDistMin = 3;
|
||||||
betaDistMax = 15;
|
betaDistMax = 15;
|
||||||
betaTiltMin = 3;
|
betaTiltMin = 3;
|
||||||
@@ -51,10 +54,19 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
alphaDistMax = 3;
|
alphaDistMax = 3;
|
||||||
alphaTiltMin = 15; % degrees
|
alphaTiltMin = 15; % degrees
|
||||||
alphaTiltMax = 30; % degrees
|
alphaTiltMax = 30; % degrees
|
||||||
sensor = sigmoidSensor;
|
opticalPartitioningMin = 1e-6;
|
||||||
|
% rfSensor
|
||||||
|
P_TX = 1e-3; % Transmit power (Watts)
|
||||||
|
BW = 20e6; % Bandwidth (Hz)
|
||||||
|
f_c = 3e9; % Center frequency (Hz)
|
||||||
|
G_RX_dBi = 3; % Receiving Antenna Gain (dBi)
|
||||||
|
beamwidthExponent = 16;
|
||||||
|
lossExponent = 2;
|
||||||
|
sinrPartitioningMin = 50;
|
||||||
|
|
||||||
% Communications
|
% Communications
|
||||||
useFixedTopology = false;
|
useFixedTopology = false;
|
||||||
|
optimizeSensorPointing = false;
|
||||||
minCommsRange = 3; % Minimum randomly generated collision geometry size
|
minCommsRange = 3; % Minimum randomly generated collision geometry size
|
||||||
maxCommsRange = 5; % Maximum randomly generated collision geometry size
|
maxCommsRange = 5; % Maximum randomly generated collision geometry size
|
||||||
commsRanges = NaN;
|
commsRanges = NaN;
|
||||||
@@ -173,7 +185,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
tc.sensor = tc.sensor.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
tc.sensor = tc.sensor.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
||||||
|
|
||||||
% Initialize candidate agent
|
% Initialize candidate agent
|
||||||
newAgent = tc.agents{ii}.initialize(candidatePos, candidateGeometry, tc.sensor, tc.commsRanges(ii), tc.maxIter, tc.initialStepSize);
|
newAgent = tc.agents{ii}.initialize(candidatePos, candidateGeometry, tc.sensor, tc.commsRanges(ii), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Make sure candidate agent doesn't collide with
|
% Make sure candidate agent doesn't collide with
|
||||||
% domain
|
% domain
|
||||||
@@ -227,7 +239,155 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
% Initialize the simulation
|
% Initialize the simulation
|
||||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
end
|
||||||
|
function miSim_run_rf_sensor(tc)
|
||||||
|
% randomly create obstacles
|
||||||
|
nGeom = tc.minNumObstacles + randi(tc.maxNumObstacles - tc.minNumObstacles);
|
||||||
|
tc.obstacles = cell(nGeom, 1);
|
||||||
|
|
||||||
|
% Iterate over obstacles to initialize
|
||||||
|
for ii = 1:size(tc.obstacles, 1)
|
||||||
|
badCandidate = true;
|
||||||
|
while badCandidate
|
||||||
|
% Instantiate a rectangular prism obstacle inside the domain
|
||||||
|
tc.obstacles{ii} = rectangularPrism;
|
||||||
|
tc.obstacles{ii} = tc.obstacles{ii}.initializeRandom(REGION_TYPE.OBSTACLE, sprintf("Obstacle %d", ii), tc.minObstacleSize, tc.maxObstacleSize, tc.domain, tc.minAlt);
|
||||||
|
|
||||||
|
% Check if the obstacle collides with an existing obstacle
|
||||||
|
if ~tc.obstacleCollisionCheck(tc.obstacles(1:(ii - 1)), tc.obstacles{ii})
|
||||||
|
badCandidate = false;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Add agents individually, ensuring that each addition does not
|
||||||
|
% invalidate the initialization setup
|
||||||
|
for ii = 1:size(tc.agents, 1)
|
||||||
|
initInvalid = true;
|
||||||
|
while initInvalid
|
||||||
|
candidatePos = [tc.domain.objective.groundPos, 0];
|
||||||
|
% Generate a random position for the agent based on
|
||||||
|
% existing agent positions
|
||||||
|
if ii == 1
|
||||||
|
while agentsCrowdObjective(tc.domain.objective, candidatePos, mean(tc.domain.dimensions) / 2)
|
||||||
|
candidatePos = tc.domain.random();
|
||||||
|
candidatePos(3) = min([tc.domain.maxCorner(3) * 0.95, tc.minAlt + rand * (tc.alphaDistMax * (1.1) - 0.5)]); % place agents at decent altitudes for sensing
|
||||||
|
end
|
||||||
|
else
|
||||||
|
candidatePos = tc.agents{randi(ii - 1)}.pos + sign(randn([1, 3])) .* (rand(1, 3) .* tc.commsRanges(ii)/sqrt(2));
|
||||||
|
candidatePos(3) = min([tc.domain.maxCorner(3) * 0.95, tc.minAlt + rand * (tc.alphaDistMax * (1.1) - 0.5)]); % place agents at decent altitudes for sensing
|
||||||
|
end
|
||||||
|
|
||||||
|
% Make sure that the candidate position is within the
|
||||||
|
% domain
|
||||||
|
if ~tc.domain.contains(candidatePos)
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Make sure that the candidate position does not crowd
|
||||||
|
% the sensing objective and create boring scenarios
|
||||||
|
if agentsCrowdObjective(tc.domain.objective, candidatePos, mean(tc.domain.dimensions) / 2)
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Make sure that there exist unobstructed lines of sight at
|
||||||
|
% appropriate ranges to form a connected communications
|
||||||
|
% graph between the agents
|
||||||
|
connections = false(1, ii - 1);
|
||||||
|
for jj = 1:(ii - 1)
|
||||||
|
if norm(tc.agents{jj}.pos - candidatePos) <= min(tc.commsRanges([ii, jj]))
|
||||||
|
% Check new agent position against all existing
|
||||||
|
% agent positions for communications range
|
||||||
|
connections(jj) = true;
|
||||||
|
for kk = 1:size(tc.obstacles, 1)
|
||||||
|
if tc.obstacles{kk}.containsLine(tc.agents{jj}.pos, candidatePos)
|
||||||
|
connections(jj) = false;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% New agent must be connected to an existing agent to
|
||||||
|
% be valid
|
||||||
|
if ii ~= 1 && ~any(connections)
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Initialize candidate agent collision geometry
|
||||||
|
% candidateGeometry = rectangularPrism;
|
||||||
|
% candidateGeometry = candidateGeometry.initialize([candidatePos - tc.collisionRanges(ii) * ones(1, 3); candidatePos + tc.collisionRanges(ii) * ones(1, 3)], REGION_TYPE.COLLISION);
|
||||||
|
candidateGeometry = spherical;
|
||||||
|
candidateGeometry = candidateGeometry.initialize(candidatePos, tc.collisionRanges(ii), REGION_TYPE.COLLISION);
|
||||||
|
|
||||||
|
% Initialize candidate agent sensor model
|
||||||
|
tc.sensor = rfSensor;
|
||||||
|
tilt = 0; azimuth = 0;
|
||||||
|
tc.sensor = tc.sensor.initialize(tc.P_TX * 1 + rand * 4, tc.BW, tc.f_c, tc.G_RX_dBi, tc.beamwidthExponent + randi(100), tilt, azimuth, tc.lossExponent);
|
||||||
|
|
||||||
|
% Initialize candidate agent
|
||||||
|
newAgent = tc.agents{ii}.initialize(candidatePos, candidateGeometry, tc.sensor, tc.commsRanges(ii), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
|
% Make sure candidate agent doesn't collide with
|
||||||
|
% domain
|
||||||
|
violation = false;
|
||||||
|
for jj = 1:size(newAgent.collisionGeometry.vertices, 1)
|
||||||
|
% Check if collision geometry exits domain
|
||||||
|
if ~tc.domain.contains(newAgent.collisionGeometry.vertices(jj, 1:3))
|
||||||
|
violation = true;
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if violation
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Make sure candidate doesn't collide with obstacles
|
||||||
|
violation = false;
|
||||||
|
for kk = 1:size(tc.obstacles, 1)
|
||||||
|
if geometryIntersects(tc.obstacles{kk}, newAgent.collisionGeometry)
|
||||||
|
violation = true;
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if violation
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Make sure candidate doesn't collide with existing
|
||||||
|
% agents
|
||||||
|
violation = false;
|
||||||
|
for kk = 1:(ii - 1)
|
||||||
|
if geometryIntersects(tc.agents{kk}.collisionGeometry, newAgent.collisionGeometry)
|
||||||
|
violation = true;
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Make sure candidate clears domain floor
|
||||||
|
if newAgent.pos(3) - newAgent.collisionGeometry.radius <= tc.minAlt
|
||||||
|
violation = true;
|
||||||
|
end
|
||||||
|
|
||||||
|
if violation
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Candidate agent is valid, store to pass in to sim
|
||||||
|
initInvalid = false;
|
||||||
|
tc.agents{ii} = newAgent;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Initialize the simulation
|
||||||
|
tc.optimizeSensorPointing = true;
|
||||||
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
|
% Write out initialization state
|
||||||
|
tc.testClass.writeInits();
|
||||||
|
|
||||||
|
% Run simulation loop
|
||||||
|
tc.testClass = tc.testClass.run();
|
||||||
end
|
end
|
||||||
function miSim_run(tc)
|
function miSim_run(tc)
|
||||||
% randomly create obstacles
|
% randomly create obstacles
|
||||||
@@ -312,7 +472,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
tc.sensor = tc.sensor.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
tc.sensor = tc.sensor.initialize(tc.alphaDistMin + rand * (tc.alphaDistMax - tc.alphaDistMin), tc.betaDistMin + rand * (tc.betaDistMax - tc.betaDistMin), tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
||||||
|
|
||||||
% Initialize candidate agent
|
% Initialize candidate agent
|
||||||
newAgent = tc.agents{ii}.initialize(candidatePos, candidateGeometry, tc.sensor, tc.commsRanges(ii), tc.maxIter, tc.initialStepSize);
|
newAgent = tc.agents{ii}.initialize(candidatePos, candidateGeometry, tc.sensor, tc.commsRanges(ii), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Make sure candidate agent doesn't collide with
|
% Make sure candidate agent doesn't collide with
|
||||||
% domain
|
% domain
|
||||||
@@ -366,7 +526,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
% Initialize the simulation
|
% Initialize the simulation
|
||||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
% Write out initialization state
|
% Write out initialization state
|
||||||
tc.testClass.writeInits();
|
tc.testClass.writeInits();
|
||||||
@@ -392,15 +552,15 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
|
|
||||||
% Initialize agents
|
% Initialize agents
|
||||||
tc.commsRanges = 3 * d * ones(size(tc.agents));
|
tc.commsRanges = 3 * d * ones(size(tc.agents));
|
||||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + [d, 0, 0], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize);
|
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + [d, 0, 0], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - [d, 0, 0], geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize);
|
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - [d, 0, 0], geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center - [0, d, 0], geometry3, tc.sensor, tc.commsRanges(3), tc.maxIter, tc.initialStepSize);
|
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center - [0, d, 0], geometry3, tc.sensor, tc.commsRanges(3), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Initialize the simulation
|
% Initialize the simulation
|
||||||
tc.obstacles = cell(0, 1);
|
tc.obstacles = cell(0, 1);
|
||||||
tc.makePlots = false;
|
tc.makePlots = false;
|
||||||
tc.makeVideo = false;
|
tc.makeVideo = false;
|
||||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
centerIdx = floor(size(tc.testClass.partitioning, 1) / 2);
|
centerIdx = floor(size(tc.testClass.partitioning, 1) / 2);
|
||||||
tc.verifyEqual(tc.testClass.partitioning(centerIdx, centerIdx:(centerIdx + 2)), [2, 3, 1]); % all three near center
|
tc.verifyEqual(tc.testClass.partitioning(centerIdx, centerIdx:(centerIdx + 2)), [2, 3, 1]); % all three near center
|
||||||
@@ -419,13 +579,13 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
tc.sensor = tc.sensor.initialize(tc.minDimension / 2, 3, 20, 3);
|
tc.sensor = tc.sensor.initialize(tc.minDimension / 2, 3, 20, 3);
|
||||||
|
|
||||||
% Initialize agents
|
% Initialize agents
|
||||||
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2), 3], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize);
|
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2), 3], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Initialize the simulation
|
% Initialize the simulation
|
||||||
tc.obstacles = cell(0, 1);
|
tc.obstacles = cell(0, 1);
|
||||||
tc.makePlots = false;
|
tc.makePlots = false;
|
||||||
tc.makeVideo = false;
|
tc.makeVideo = false;
|
||||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
close(tc.testClass.fPerf);
|
close(tc.testClass.fPerf);
|
||||||
|
|
||||||
tc.verifyEqual(unique(tc.testClass.partitioning), [0; 1]);
|
tc.verifyEqual(unique(tc.testClass.partitioning), [0; 1]);
|
||||||
@@ -437,7 +597,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||||
|
|
||||||
% make basic sensing objective
|
% make basic sensing objective
|
||||||
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([7, 6]), tc.domain, tc.discretizationStep, tc.protectedRange, 1e-6, [7, 6]);
|
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([7, 6]), tc.domain, tc.discretizationStep, tc.protectedRange, tc.opticalPartitioningMin, [7, 6]);
|
||||||
|
|
||||||
% Initialize agent collision geometry
|
% Initialize agent collision geometry
|
||||||
tc.agents = {agent};
|
tc.agents = {agent};
|
||||||
@@ -449,14 +609,129 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
|
|
||||||
% Initialize agents
|
% Initialize agents
|
||||||
tc.maxIter = 75;
|
tc.maxIter = 75;
|
||||||
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize);
|
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Initialize the simulation
|
% Initialize the simulation
|
||||||
tc.obstacles = cell(0, 1);
|
tc.obstacles = cell(0, 1);
|
||||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
% Run the simulation
|
% Run the simulation
|
||||||
tc.testClass = tc.testClass.run();end
|
tc.testClass = tc.testClass.run();
|
||||||
|
end
|
||||||
|
function test_single_agent_gradient_ascent_tilted(tc)
|
||||||
|
% make basic domain
|
||||||
|
tc.minDimension = 10; % domain size
|
||||||
|
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||||
|
|
||||||
|
% make basic sensing objective
|
||||||
|
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([7, 6]), tc.domain, tc.discretizationStep, tc.protectedRange, tc.opticalPartitioningMin, [7, 6]);
|
||||||
|
|
||||||
|
% Initialize agent collision geometry
|
||||||
|
tc.agents = {agent};
|
||||||
|
geometry1 = spherical;
|
||||||
|
geometry1 = geometry1.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], tc.collisionRanges(1), REGION_TYPE.COLLISION);
|
||||||
|
|
||||||
|
% Initialize agent sensor model with fixed parameters
|
||||||
|
tc.sensor = tc.sensor.initialize(tc.minDimension / 2, 3, 20, 3, 25, 155);
|
||||||
|
|
||||||
|
% Initialize agents
|
||||||
|
tc.maxIter = 75;
|
||||||
|
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
|
% Initialize the simulation
|
||||||
|
tc.obstacles = cell(0, 1);
|
||||||
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
|
% Run the simulation
|
||||||
|
tc.testClass = tc.testClass.run();
|
||||||
|
end
|
||||||
|
function test_single_agent_gradient_ascent_tilted_RF_sensor(tc)
|
||||||
|
% make basic domain
|
||||||
|
tc.minDimension = 10; % domain size
|
||||||
|
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||||
|
|
||||||
|
% make basic sensing objective
|
||||||
|
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([7, 6]), tc.domain, tc.discretizationStep, tc.protectedRange, tc.sinrPartitioningMin, [7, 6]);
|
||||||
|
|
||||||
|
% Initialize agent collision geometry
|
||||||
|
tc.agents = {agent};
|
||||||
|
geometry1 = spherical;
|
||||||
|
geometry1 = geometry1.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], tc.collisionRanges(1), REGION_TYPE.COLLISION);
|
||||||
|
|
||||||
|
tc.sensor = rfSensor;
|
||||||
|
tc.sensor = tc.sensor.initialize(tc.P_TX, tc.BW, tc.f_c, tc.G_RX_dBi, tc.beamwidthExponent, 45, 45, tc.lossExponent);
|
||||||
|
|
||||||
|
% Initialize agents
|
||||||
|
tc.maxIter = 75;
|
||||||
|
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
|
% Initialize the simulation
|
||||||
|
tc.obstacles = cell(0, 1);
|
||||||
|
tc.minAlt = 0.5;
|
||||||
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
|
% Run the simulation
|
||||||
|
tc.testClass = tc.testClass.run();
|
||||||
|
end
|
||||||
|
function test_single_agent_gradient_ascent_sensor_pointing(tc)
|
||||||
|
% make basic domain
|
||||||
|
tc.minDimension = 10; % domain size
|
||||||
|
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||||
|
|
||||||
|
% make basic sensing objective
|
||||||
|
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([7, 6]), tc.domain, tc.discretizationStep, tc.protectedRange, tc.opticalPartitioningMin, [7, 6]);
|
||||||
|
|
||||||
|
% Initialize agent collision geometry
|
||||||
|
tc.agents = {agent};
|
||||||
|
geometry1 = spherical;
|
||||||
|
geometry1 = geometry1.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], tc.collisionRanges(1), REGION_TYPE.COLLISION);
|
||||||
|
|
||||||
|
% Initialize agent sensor model with fixed parameters
|
||||||
|
tc.sensor = tc.sensor.initialize(tc.minDimension / 2, 3, 20, 3);
|
||||||
|
|
||||||
|
% Initialize agents
|
||||||
|
tc.maxIter = 75;
|
||||||
|
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
|
% Initialize the simulation
|
||||||
|
tc.optimizeSensorPointing = true;
|
||||||
|
tc.obstacles = cell(0, 1);
|
||||||
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
|
% Run the simulation
|
||||||
|
tc.testClass = tc.testClass.run();
|
||||||
|
end
|
||||||
|
function test_single_agent_gradient_ascent_rf_sensor_pointing(tc)
|
||||||
|
% make basic domain
|
||||||
|
tc.minDimension = 10; % domain size
|
||||||
|
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||||
|
|
||||||
|
% make basic sensing objective
|
||||||
|
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([7, 6]), tc.domain, tc.discretizationStep, tc.protectedRange, tc.sinrPartitioningMin, [7, 6]);
|
||||||
|
|
||||||
|
% Initialize agent collision geometry
|
||||||
|
tc.agents = {agent};
|
||||||
|
geometry1 = spherical;
|
||||||
|
geometry1 = geometry1.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], tc.collisionRanges(1), REGION_TYPE.COLLISION);
|
||||||
|
|
||||||
|
% Initialize agent sensor model
|
||||||
|
|
||||||
|
tc.sensor = rfSensor;
|
||||||
|
tc.sensor = tc.sensor.initialize(tc.P_TX, tc.BW, tc.f_c, tc.G_RX_dBi, tc.beamwidthExponent, 0, 0, tc.lossExponent);
|
||||||
|
|
||||||
|
% Initialize agents
|
||||||
|
tc.maxIter = 75;
|
||||||
|
tc.agents{1} = tc.agents{1}.initialize([tc.domain.center(1:2)-tc.domain.dimensions(1)/4, 3], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
|
% Initialize the simulation
|
||||||
|
tc.optimizeSensorPointing = true;
|
||||||
|
tc.obstacles = cell(0, 1);
|
||||||
|
tc.minAlt = 0.5;
|
||||||
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
|
% Run the simulation
|
||||||
|
tc.testClass = tc.testClass.run();
|
||||||
|
end
|
||||||
function test_collision_avoidance(tc)
|
function test_collision_avoidance(tc)
|
||||||
% No obstacles
|
% No obstacles
|
||||||
% Fixed agent initial conditions
|
% Fixed agent initial conditions
|
||||||
@@ -466,7 +741,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||||
|
|
||||||
% make basic sensing objective
|
% make basic sensing objective
|
||||||
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([3, 7]), tc.domain, tc.discretizationStep, tc.protectedRange, 1e-6, [3, 7]);
|
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([3, 7]), tc.domain, tc.discretizationStep, tc.protectedRange, tc.opticalPartitioningMin, [3, 7]);
|
||||||
|
|
||||||
% Initialize agent collision geometry
|
% Initialize agent collision geometry
|
||||||
tc.agents = {agent; agent};
|
tc.agents = {agent; agent};
|
||||||
@@ -483,12 +758,12 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
% Initialize agents
|
% Initialize agents
|
||||||
tc.maxIter = 25;
|
tc.maxIter = 25;
|
||||||
tc.commsRanges = 5 * ones(size(tc.agents));
|
tc.commsRanges = 5 * ones(size(tc.agents));
|
||||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + d, geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize);
|
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + d, geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - d, geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize);
|
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - d, geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Initialize the simulation
|
% Initialize the simulation
|
||||||
tc.obstacles = cell(0, 1);
|
tc.obstacles = cell(0, 1);
|
||||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
% Run the simulation
|
% Run the simulation
|
||||||
tc.testClass.run();
|
tc.testClass.run();
|
||||||
@@ -504,7 +779,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||||
|
|
||||||
% make basic sensing objective
|
% make basic sensing objective
|
||||||
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([8, 5.2195]), tc.domain, tc.discretizationStep, tc.protectedRange, 1e-6, [8, 5.2195]);
|
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([8, 5.2195]), tc.domain, tc.discretizationStep, tc.protectedRange, tc.opticalPartitioningMin, [8, 5.2195]);
|
||||||
|
|
||||||
% Initialize agent collision geometry
|
% Initialize agent collision geometry
|
||||||
tc.agents = {agent; agent;};
|
tc.agents = {agent; agent;};
|
||||||
@@ -530,11 +805,11 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
|
|
||||||
% Initialize agents
|
% Initialize agents
|
||||||
tc.commsRanges = (2 * tc.collisionRanges(1) + obstacleLength) * 0.9 * ones(size(tc.agents)); % defined such that they cannot go around the obstacle on both sides
|
tc.commsRanges = (2 * tc.collisionRanges(1) + obstacleLength) * 0.9 * ones(size(tc.agents)); % defined such that they cannot go around the obstacle on both sides
|
||||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center - d + [0, tc.collisionRanges(1) * 1.1 - yOffset, 0], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize);
|
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center - d + [0, tc.collisionRanges(1) * 1.1 - yOffset, 0], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - d - [0, tc.collisionRanges(2) *1.1 + yOffset, 0], geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize);
|
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - d - [0, tc.collisionRanges(2) *1.1 + yOffset, 0], geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Initialize the simulation
|
% Initialize the simulation
|
||||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
% Run the simulation
|
% Run the simulation
|
||||||
tc.testClass.run();
|
tc.testClass.run();
|
||||||
@@ -570,11 +845,11 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
% Initialize agents
|
% Initialize agents
|
||||||
tc.maxIter = 50;
|
tc.maxIter = 50;
|
||||||
tc.commsRanges = 4 * ones(size(tc.agents)); % defined such that they cannot reach their objective without breaking connectivity
|
tc.commsRanges = 4 * ones(size(tc.agents)); % defined such that they cannot reach their objective without breaking connectivity
|
||||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + d, geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize);
|
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + d, geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - d, geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize);
|
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - d, geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Initialize the simulation
|
% Initialize the simulation
|
||||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
% Run the simulation
|
% Run the simulation
|
||||||
tc.testClass = tc.testClass.run();
|
tc.testClass = tc.testClass.run();
|
||||||
@@ -588,7 +863,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
tc.domain = tc.domain.initialize([zeros(1, 3); tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
tc.domain = tc.domain.initialize([zeros(1, 3); tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||||
|
|
||||||
% make basic sensing objective
|
% make basic sensing objective
|
||||||
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([8, 5]), tc.domain, tc.discretizationStep, tc.protectedRange, 1e-6, [8, 5]);
|
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([8, 5]), tc.domain, tc.discretizationStep, tc.protectedRange, tc.opticalPartitioningMin, [8, 5]);
|
||||||
|
|
||||||
% Initialize agent collision geometry
|
% Initialize agent collision geometry
|
||||||
tc.agents = {agent; agent;};
|
tc.agents = {agent; agent;};
|
||||||
@@ -605,8 +880,8 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
% Initialize agents
|
% Initialize agents
|
||||||
tc.maxIter = 125;
|
tc.maxIter = 125;
|
||||||
tc.commsRanges = 5 * ones(size(tc.agents));
|
tc.commsRanges = 5 * ones(size(tc.agents));
|
||||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center - [d, 0, 0], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize);
|
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center - [d, 0, 0], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - [0, d, 0], geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize);
|
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center - [0, d, 0], geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Initialize obstacles
|
% Initialize obstacles
|
||||||
obstacleLength = 1.5;
|
obstacleLength = 1.5;
|
||||||
@@ -617,7 +892,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
tc.minAlt = 0;
|
tc.minAlt = 0;
|
||||||
tc.makePlots = false;
|
tc.makePlots = false;
|
||||||
tc.makeVideo = false;
|
tc.makeVideo = false;
|
||||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
% Communications link should be established
|
% Communications link should be established
|
||||||
tc.assertEqual(tc.testClass.adjacency, logical(true(2)));
|
tc.assertEqual(tc.testClass.adjacency, logical(true(2)));
|
||||||
@@ -633,7 +908,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
tc.domain = tc.domain.initialize([zeros(1, 3);tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||||
|
|
||||||
% make basic sensing objective
|
% make basic sensing objective
|
||||||
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([8, 5]), tc.domain, tc.discretizationStep, tc.protectedRange, 1e-6, [8, 5]);
|
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([8, 5]), tc.domain, tc.discretizationStep, tc.protectedRange, tc.opticalPartitioningMin, [8, 5]);
|
||||||
|
|
||||||
% Initialize agent collision geometry
|
% Initialize agent collision geometry
|
||||||
tc.agents = {agent; agent; agent; agent; agent;};
|
tc.agents = {agent; agent; agent; agent; agent;};
|
||||||
@@ -652,17 +927,17 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
% Initialize agents
|
% Initialize agents
|
||||||
tc.maxIter = 125;
|
tc.maxIter = 125;
|
||||||
tc.commsRanges = ones(size(tc.agents));
|
tc.commsRanges = ones(size(tc.agents));
|
||||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + [d, 0, 0], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize);
|
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + [d, 0, 0], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center, geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize);
|
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center, geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center + [-d, d, 0], geometry3, tc.sensor, tc.commsRanges(3), tc.maxIter, tc.initialStepSize);
|
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center + [-d, d, 0], geometry3, tc.sensor, tc.commsRanges(3), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{4} = tc.agents{4}.initialize(tc.domain.center + [-2*d, d, 0], geometry4, tc.sensor, tc.commsRanges(4), tc.maxIter, tc.initialStepSize);
|
tc.agents{4} = tc.agents{4}.initialize(tc.domain.center + [-2*d, d, 0], geometry4, tc.sensor, tc.commsRanges(4), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{5} = tc.agents{5}.initialize(tc.domain.center + [0, d, 0], geometry5, tc.sensor, tc.commsRanges(5), tc.maxIter, tc.initialStepSize);
|
tc.agents{5} = tc.agents{5}.initialize(tc.domain.center + [0, d, 0], geometry5, tc.sensor, tc.commsRanges(5), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Initialize the simulation
|
% Initialize the simulation
|
||||||
tc.minAlt = 0;
|
tc.minAlt = 0;
|
||||||
tc.makePlots = false;
|
tc.makePlots = false;
|
||||||
tc.makeVideo = false;
|
tc.makeVideo = false;
|
||||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
% Constraint adjacency matrix defined by LNA should be as follows
|
% Constraint adjacency matrix defined by LNA should be as follows
|
||||||
tc.assertEqual(tc.testClass.constraintAdjacencyMatrix, logical( ...
|
tc.assertEqual(tc.testClass.constraintAdjacencyMatrix, logical( ...
|
||||||
@@ -683,7 +958,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
tc.domain = tc.domain.initialize([zeros(1, 3); tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
tc.domain = tc.domain.initialize([zeros(1, 3); tc.minDimension* ones(1, 3)], REGION_TYPE.DOMAIN, "Domain");
|
||||||
|
|
||||||
% make basic sensing objective
|
% make basic sensing objective
|
||||||
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([8, 5]), tc.domain, tc.discretizationStep, tc.protectedRange, 1e-6, [8, 5]);
|
tc.domain.objective = tc.domain.objective.initialize(objectiveFunctionWrapper([8, 5]), tc.domain, tc.discretizationStep, tc.protectedRange, tc.opticalPartitioningMin, [8, 5]);
|
||||||
|
|
||||||
% Initialize agent collision geometry
|
% Initialize agent collision geometry
|
||||||
tc.agents = {agent; agent; agent; agent; agent; agent; agent;};
|
tc.agents = {agent; agent; agent; agent; agent; agent; agent;};
|
||||||
@@ -704,19 +979,19 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
% Initialize agents
|
% Initialize agents
|
||||||
tc.maxIter = 125;
|
tc.maxIter = 125;
|
||||||
tc.commsRanges = d * ones(size(tc.agents));
|
tc.commsRanges = d * ones(size(tc.agents));
|
||||||
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + [-0.9 * d/sqrt(2), 0.9 * d/sqrt(2), 0], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize);
|
tc.agents{1} = tc.agents{1}.initialize(tc.domain.center + [-0.9 * d/sqrt(2), 0.9 * d/sqrt(2), 0], geometry1, tc.sensor, tc.commsRanges(1), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center + [-0.5 * d, 0.25 * d, 0], geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize);
|
tc.agents{2} = tc.agents{2}.initialize(tc.domain.center + [-0.5 * d, 0.25 * d, 0], geometry2, tc.sensor, tc.commsRanges(2), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center + [0.9 * d, 0, 0], geometry3, tc.sensor, tc.commsRanges(3), tc.maxIter, tc.initialStepSize);
|
tc.agents{3} = tc.agents{3}.initialize(tc.domain.center + [0.9 * d, 0, 0], geometry3, tc.sensor, tc.commsRanges(3), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{4} = tc.agents{4}.initialize(tc.domain.center + [0.9 * d/sqrt(2), -0.9 * d/sqrt(2), 0], geometry4, tc.sensor, tc.commsRanges(4), tc.maxIter, tc.initialStepSize);
|
tc.agents{4} = tc.agents{4}.initialize(tc.domain.center + [0.9 * d/sqrt(2), -0.9 * d/sqrt(2), 0], geometry4, tc.sensor, tc.commsRanges(4), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{5} = tc.agents{5}.initialize(tc.domain.center + [0, 0.9 * d, 0], geometry5, tc.sensor, tc.commsRanges(5), tc.maxIter, tc.initialStepSize);
|
tc.agents{5} = tc.agents{5}.initialize(tc.domain.center + [0, 0.9 * d, 0], geometry5, tc.sensor, tc.commsRanges(5), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{6} = tc.agents{6}.initialize(tc.domain.center, geometry6, tc.sensor, tc.commsRanges(6), tc.maxIter, tc.initialStepSize);
|
tc.agents{6} = tc.agents{6}.initialize(tc.domain.center, geometry6, tc.sensor, tc.commsRanges(6), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
tc.agents{7} = tc.agents{7}.initialize(tc.domain.center + [d/2, d/2, 0], geometry7, tc.sensor, tc.commsRanges(7), tc.maxIter, tc.initialStepSize);
|
tc.agents{7} = tc.agents{7}.initialize(tc.domain.center + [d/2, d/2, 0], geometry7, tc.sensor, tc.commsRanges(7), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Initialize the simulation
|
% Initialize the simulation
|
||||||
tc.minAlt = 0;
|
tc.minAlt = 0;
|
||||||
tc.makePlots = false;
|
tc.makePlots = false;
|
||||||
tc.makeVideo = false;
|
tc.makeVideo = false;
|
||||||
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.testClass = tc.testClass.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, tc.makePlots, tc.makeVideo, tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
% Constraint adjacency matrix defined by LNA should be as follows
|
% Constraint adjacency matrix defined by LNA should be as follows
|
||||||
tc.assertEqual(tc.testClass.constraintAdjacencyMatrix, logical( ...
|
tc.assertEqual(tc.testClass.constraintAdjacencyMatrix, logical( ...
|
||||||
@@ -796,7 +1071,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), ...
|
tc.alphaTiltMin + rand * (tc.alphaTiltMax - tc.alphaTiltMin), ...
|
||||||
tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
tc.betaTiltMin + rand * (tc.betaTiltMax - tc.betaTiltMin));
|
||||||
newAgent = agent;
|
newAgent = agent;
|
||||||
newAgent = newAgent.initialize(candidatePos, geom, tc.sensor, tc.commsRanges(ii), tc.maxIter, tc.initialStepSize);
|
newAgent = newAgent.initialize(candidatePos, geom, tc.sensor, tc.commsRanges(ii), tc.maxIter, tc.initialStepSize, tc.initialMaxAngleStepSize);
|
||||||
|
|
||||||
% Domain / obstacle / agent collision checks
|
% Domain / obstacle / agent collision checks
|
||||||
violation = false;
|
violation = false;
|
||||||
@@ -831,7 +1106,7 @@ classdef test_miSim < matlab.unittest.TestCase
|
|||||||
sim1 = miSim;
|
sim1 = miSim;
|
||||||
sim1 = sim1.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, ...
|
sim1 = sim1.initialize(tc.domain, tc.agents, tc.barrierGain, tc.barrierExponent, ...
|
||||||
tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, false, false, ...
|
tc.minAlt, tc.timestep, tc.maxIter, tc.obstacles, false, false, ...
|
||||||
tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology);
|
tc.useDoubleIntegrator, tc.dampingCoeff, tc.useFixedTopology, tc.optimizeSensorPointing);
|
||||||
|
|
||||||
% Write inits and build file path
|
% Write inits and build file path
|
||||||
sim1.writeInits();
|
sim1.writeInits();
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
classdef test_rfSensor < matlab.unittest.TestCase
|
||||||
|
properties (Access = private)
|
||||||
|
% System under test
|
||||||
|
testClass = sigmoidSensor;
|
||||||
|
end
|
||||||
|
|
||||||
|
methods (TestMethodSetup)
|
||||||
|
function tc = setup(tc)
|
||||||
|
% Reinitialize sensor with random parameters
|
||||||
|
tc.testClass = rfSensor;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function plot_RSS(tc)
|
||||||
|
% Plot sensor performance with no sources of interference
|
||||||
|
P_TX = 1e-3; % Transmit power (Watts)
|
||||||
|
BW = 20e6; % Bandwidth (Hz)
|
||||||
|
f_c = 2e9; % Center frequency (Hz)
|
||||||
|
G_RX_dBi = 3; % Receiving Antenna Gain (dBi)
|
||||||
|
beamwidthExponent = 6;
|
||||||
|
lossExponent = 2;
|
||||||
|
|
||||||
|
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent, 0, 0, lossExponent);
|
||||||
|
|
||||||
|
tc.testClass.plotParameters();
|
||||||
|
end
|
||||||
|
function plot_SNR(tc)
|
||||||
|
% Plot sensor performance with no sources of interference
|
||||||
|
P_TX = 1e-3; % Transmit power (Watts)
|
||||||
|
BW = 20e6; % Bandwidth (Hz)
|
||||||
|
f_c = 2e9; % Center frequency (Hz)
|
||||||
|
G_RX_dBi = 3; % Receiving Antenna Gain (dBi)
|
||||||
|
beamwidthExponent = 6;
|
||||||
|
lossExponent = 2;
|
||||||
|
|
||||||
|
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent, 30, 135, lossExponent);
|
||||||
|
|
||||||
|
altitude = 30;
|
||||||
|
|
||||||
|
% Boresight azimuth=135° (between +X at 90° and -Y at 180°) → hotspot at +X,-Y.
|
||||||
|
% SNR at (5,-5) should be higher than at (5,+5).
|
||||||
|
agentPos = [0, 0, altitude];
|
||||||
|
[~, snrA] = tc.testClass.sensorPerformance(agentPos, [5, -5, 0]);
|
||||||
|
% tc.testClass = tc.testClass.clearRssCache();
|
||||||
|
[~, snrB] = tc.testClass.sensorPerformance(agentPos, [5, 5, 0]);
|
||||||
|
tc.assertGreaterThan(snrA, snrB, "SNR should be higher toward boresight (+X,-Y) than away from it (+X,+Y)");
|
||||||
|
|
||||||
|
tc.testClass.plotPerformance(altitude);
|
||||||
|
end
|
||||||
|
function plot_SINR_one_interferer(tc)
|
||||||
|
% Plot sensor performance with no sources of interference
|
||||||
|
P_TX = 1e-3; % Transmit power (Watts)
|
||||||
|
BW = 20e6; % Bandwidth (Hz)
|
||||||
|
f_c = 2e9; % Center frequency (Hz)
|
||||||
|
G_RX_dBi = 3; % Receiving Antenna Gain (dBi)
|
||||||
|
beamwidthExponent = 6;
|
||||||
|
lossExponent = 2;
|
||||||
|
|
||||||
|
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent, 0, 0, lossExponent);
|
||||||
|
|
||||||
|
altitude = 30;
|
||||||
|
otherSensorsPos = [6, -4, -1]; % relative to main sensor
|
||||||
|
otherSensors = cell(1, 1);
|
||||||
|
otherSensors{1} = tc.testClass; % One interfering sensor, identical to the main sensor
|
||||||
|
|
||||||
|
tc.testClass.plotPerformance(altitude, otherSensorsPos, otherSensors);
|
||||||
|
end
|
||||||
|
|
||||||
|
function plot_SINR_heterogenous_interferers(tc)
|
||||||
|
% Plot sensor performance with no sources of interference
|
||||||
|
P_TX = 1e-3; % Transmit power (Watts)
|
||||||
|
BW = 20e6; % Bandwidth (Hz)
|
||||||
|
f_c = 2e9; % Center frequency (Hz)
|
||||||
|
G_RX_dBi = 3; % Receiving Antenna Gain (dBi)
|
||||||
|
beamwidthExponent = 6;
|
||||||
|
lossExponent = 2;
|
||||||
|
|
||||||
|
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent, 0, 0, lossExponent);
|
||||||
|
|
||||||
|
altitude = 30;
|
||||||
|
otherSensorsPos = [6, -4, -1; -2, 6, 0]; % relative to main sensor
|
||||||
|
otherSensors = cell(2, 1);
|
||||||
|
otherSensors{1} = rfSensor; % two heterogenous interfering sensors
|
||||||
|
otherSensors{2} = rfSensor;
|
||||||
|
|
||||||
|
% Must use same center frequency and bandwidth for interference sources
|
||||||
|
otherSensors{1} = otherSensors{1}.initialize(10 * P_TX, BW, f_c, G_RX_dBi, beamwidthExponent, 0, 0, lossExponent);
|
||||||
|
otherSensors{2} = otherSensors{2}.initialize(10 * P_TX, BW, f_c, G_RX_dBi, beamwidthExponent, 0, 0, lossExponent);
|
||||||
|
|
||||||
|
tc.testClass.plotPerformance(altitude, otherSensorsPos, otherSensors);
|
||||||
|
end
|
||||||
|
function plot_SINR_heterogenous_interferers_efficiently(tc)
|
||||||
|
P_TX = 1e-3;
|
||||||
|
BW = 20e6;
|
||||||
|
f_c = 2e9;
|
||||||
|
G_RX_dBi = 3;
|
||||||
|
altitude = 30;
|
||||||
|
beamwidthExponent = [6, 4, 10];
|
||||||
|
lossExponent = 2;
|
||||||
|
|
||||||
|
sensor1 = rfSensor;
|
||||||
|
sensor1 = sensor1.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent(1), 15, 45, lossExponent);
|
||||||
|
sensor2 = rfSensor;
|
||||||
|
sensor2 = sensor2.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent(2), 10, 150, lossExponent);
|
||||||
|
sensor3 = rfSensor;
|
||||||
|
sensor3 = sensor3.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent(3), 20, 200, lossExponent);
|
||||||
|
|
||||||
|
pos1 = [0, 0, altitude];
|
||||||
|
pos2 = [6, -4, altitude - 1];
|
||||||
|
pos3 = [-2, 6, altitude];
|
||||||
|
|
||||||
|
% Build a shared target grid
|
||||||
|
distances = -15:0.25:15;
|
||||||
|
[Xg, Yg] = meshgrid(distances, distances);
|
||||||
|
targetPos = [Xg(:), Yg(:), zeros(numel(Xg), 1)];
|
||||||
|
|
||||||
|
% Call 1: cache empty, does all computations for this timestep
|
||||||
|
[~, ~, sensor1, others] = sensor1.sensorPerformance(pos1, targetPos, [pos2; pos3], {sensor2; sensor3});
|
||||||
|
sensor2 = others{1};
|
||||||
|
sensor3 = others{2};
|
||||||
|
|
||||||
|
% Calls 2 and 3 use cached data
|
||||||
|
[~, ~, sensor2, others] = sensor2.sensorPerformance(pos2, targetPos, [pos1; pos3], {sensor1; sensor3});
|
||||||
|
sensor1 = others{1};
|
||||||
|
sensor3 = others{2};
|
||||||
|
|
||||||
|
[~, ~, sensor3, ~] = sensor3.sensorPerformance(pos3, targetPos, [pos1; pos2], {sensor1; sensor2});
|
||||||
|
|
||||||
|
% All caches should be populated after the three calls
|
||||||
|
tc.assertNotEmpty(sensor1.rssCache);
|
||||||
|
tc.assertNotEmpty(sensor2.rssCache);
|
||||||
|
tc.assertNotEmpty(sensor3.rssCache);
|
||||||
|
|
||||||
|
% Plot SINR from each UAV's perspective.
|
||||||
|
% otherSensorsPos for plotPerformance: XY = offset from calling sensor, Z = absolute_alt - calling_alt.
|
||||||
|
% This is exactly posOther - posSelf for each row.
|
||||||
|
sensor1.plotPerformance(pos1(3), [pos2 - pos1; pos3 - pos1], {sensor2; sensor3});
|
||||||
|
sensor2.plotPerformance(pos2(3), [pos1 - pos2; pos3 - pos2], {sensor1; sensor3});
|
||||||
|
sensor3.plotPerformance(pos3(3), [pos1 - pos3; pos2 - pos3], {sensor1; sensor2});
|
||||||
|
end
|
||||||
|
function plot_SINR_heterogenous_interferers_3d(tc)
|
||||||
|
P_TX = 1e-3;
|
||||||
|
BW = 20e6;
|
||||||
|
f_c = 2e9;
|
||||||
|
G_RX_dBi = 3;
|
||||||
|
altitude = 30;
|
||||||
|
beamwidthExponent = [50, 20, 200];
|
||||||
|
lossExponent = 2;
|
||||||
|
|
||||||
|
sensor1 = rfSensor;
|
||||||
|
sensor1 = sensor1.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent(1), 15, 45, lossExponent);
|
||||||
|
sensor2 = rfSensor;
|
||||||
|
sensor2 = sensor2.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent(2), 10, 150, lossExponent);
|
||||||
|
sensor3 = rfSensor;
|
||||||
|
sensor3 = sensor3.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent(3), 20, 200, lossExponent);
|
||||||
|
|
||||||
|
pos1 = [0, 0, altitude];
|
||||||
|
pos2 = [6, -4, altitude - 5];
|
||||||
|
pos3 = [-2, 6, altitude + 10];
|
||||||
|
|
||||||
|
% Plot SINR from each UAV's perspective.
|
||||||
|
% otherSensorsPos for plotPerformance: XY = offset from calling sensor, Z = absolute_alt - calling_alt.
|
||||||
|
% This is exactly posOther - posSelf for each row.
|
||||||
|
sensor1.plot(pos1(3), [pos2 - pos1; pos3 - pos1], {sensor2; sensor3});
|
||||||
|
sensor2.plot(pos2(3), [pos1 - pos2; pos3 - pos2], {sensor1; sensor3});
|
||||||
|
sensor3.plot(pos3(3), [pos1 - pos3; pos2 - pos3], {sensor1; sensor2});
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -4,12 +4,15 @@ function f = objectiveFunctionWrapper(center, sigma)
|
|||||||
% composite objectives in particular
|
% composite objectives in particular
|
||||||
arguments (Input)
|
arguments (Input)
|
||||||
center (:, 2) double;
|
center (:, 2) double;
|
||||||
sigma (:, 2, 2) double = eye(2);
|
sigma (:, 2, 2) double = reshape(eye(2), 1, 2, 2);
|
||||||
end
|
end
|
||||||
arguments (Output)
|
arguments (Output)
|
||||||
f (1, 1) {mustBeA(f, "function_handle")};
|
f (1, 1) {mustBeA(f, "function_handle")};
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if size(sigma, 1) == 1 && size(center, 1) > 1
|
||||||
|
sigma = repmat(sigma, size(center, 1), 1, 1);
|
||||||
|
end
|
||||||
assert(size(center, 1) == size(sigma, 1));
|
assert(size(center, 1) == size(sigma, 1));
|
||||||
f = @(x,y) sum(cell2mat(arrayfun(@(i) mvnpdf([x(:), y(:)], center(i,:), squeeze(sigma(i, :, :))), 1:size(center,1), "UniformOutput", false)), 2);
|
f = @(x,y) sum(cell2mat(arrayfun(@(i) mvnpdf([x(:), y(:)], center(i,:), squeeze(sigma(i, :, :))), 1:size(center,1), "UniformOutput", false)), 2);
|
||||||
end
|
end
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
function mustBeSensor(sensorModel)
|
function mustBeSensor(sensorModel)
|
||||||
if isa(sensorModel, 'cell')
|
if isa(sensorModel, 'cell')
|
||||||
for ii = 1:size(sensorModel, 1)
|
for ii = 1:size(sensorModel, 1)
|
||||||
assert(isa(sensorModel{ii}, 'sigmoidSensor'), ...
|
assert(isa(sensorModel{ii}, 'sigmoidSensor', 'rfSensor'), ...
|
||||||
'Sensor in index %d is not a valid sensor class', ii);
|
'Sensor in index %d is not a valid sensor class', ii);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
assert(isa(sensorModel, 'sigmoidSensor'), ...
|
assert(isa(sensorModel, 'sigmoidSensor') || isa(sensorModel, 'rfSensor'), ...
|
||||||
'Sensor is not a valid sensor class');
|
'Sensor is not a valid sensor class');
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Reference in New Issue
Block a user