added antenna LOS pointing to diagnostic plots
This commit is contained in:
@@ -9,6 +9,12 @@ function f = plotPerformance(obj, altitude, otherSensorsPos, otherSensors)
|
|||||||
f (1, 1) {mustBeA(f, "matlab.ui.Figure")};
|
f (1, 1) {mustBeA(f, "matlab.ui.Figure")};
|
||||||
end
|
end
|
||||||
|
|
||||||
|
% Clear local caches so this visualization always uses its own grid
|
||||||
|
obj.rssCache = [];
|
||||||
|
for ii = 1:numel(otherSensors)
|
||||||
|
otherSensors{ii}.rssCache = [];
|
||||||
|
end
|
||||||
|
|
||||||
otherSensorsPos = otherSensorsPos + [0, 0, altitude];
|
otherSensorsPos = otherSensorsPos + [0, 0, altitude];
|
||||||
|
|
||||||
% Create grid on which to evalute SINR, SNR
|
% Create grid on which to evalute SINR, SNR
|
||||||
@@ -29,7 +35,13 @@ function f = plotPerformance(obj, altitude, otherSensorsPos, otherSensors)
|
|||||||
|
|
||||||
% normalize in linear scale
|
% normalize in linear scale
|
||||||
SINR = 10.^(SINR/10); SINR = SINR ./ max(SINR(:)); SINR = 10 * log10(SINR);
|
SINR = 10.^(SINR/10); SINR = SINR ./ max(SINR(:)); SINR = 10 * log10(SINR);
|
||||||
SNR = 10.^(SNR/10); SNR = SNR ./ max(SNR(:)); SNR = 10 * log10(SNR);
|
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;
|
f = figure;
|
||||||
tiledlayout(1, 2, TileSpacing="compact", Padding="compact");
|
tiledlayout(1, 2, TileSpacing="compact", Padding="compact");
|
||||||
@@ -37,16 +49,42 @@ function f = plotPerformance(obj, altitude, otherSensorsPos, otherSensors)
|
|||||||
nexttile;
|
nexttile;
|
||||||
imagesc(distances, distances, SNR);
|
imagesc(distances, distances, SNR);
|
||||||
axis("image"); set(gca, 'YDir', 'normal');
|
axis("image"); set(gca, 'YDir', 'normal');
|
||||||
colorbar;
|
colorbar; xlabel("X (m)"); ylabel("Y (m)");
|
||||||
xlabel("X (m)"); ylabel("Y (m)");
|
|
||||||
title("Linearly Normalized SNR (dB)");
|
title("Linearly Normalized SNR (dB)");
|
||||||
subtitle("No interfering sources");
|
subtitle("No interfering sources");
|
||||||
|
addSensorOverlay(gca, sensorXY, sensorTilts, sensorAzimuths, tailScale);
|
||||||
|
|
||||||
nexttile;
|
nexttile;
|
||||||
imagesc(distances, distances, SINR);
|
imagesc(distances, distances, SINR);
|
||||||
axis("image"); set(gca, 'YDir', 'normal');
|
axis("image"); set(gca, 'YDir', 'normal');
|
||||||
colorbar;
|
colorbar; xlabel("X (m)"); ylabel("Y (m)");
|
||||||
xlabel("X (m)"); ylabel("Y (m)");
|
|
||||||
title("Linearly Normalized SINR (dB)");
|
title("Linearly Normalized SINR (dB)");
|
||||||
subtitle(sprintf("%d interfering source(s)", size(otherSensorsPos, 1)));
|
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
|
end
|
||||||
+12
-33
@@ -91,11 +91,11 @@ classdef test_rfSensor < matlab.unittest.TestCase
|
|||||||
altitude = 30;
|
altitude = 30;
|
||||||
|
|
||||||
sensor1 = rfSensor;
|
sensor1 = rfSensor;
|
||||||
sensor1 = sensor1.initialize(P_TX, BW, f_c, G_RX_dBi, 0, 0);
|
sensor1 = sensor1.initialize(P_TX, BW, f_c, G_RX_dBi, 15, 45);
|
||||||
sensor2 = rfSensor;
|
sensor2 = rfSensor;
|
||||||
sensor2 = sensor2.initialize(P_TX, BW, f_c, G_RX_dBi, 0, 0);
|
sensor2 = sensor2.initialize(P_TX, BW, f_c, G_RX_dBi, 10, 150);
|
||||||
sensor3 = rfSensor;
|
sensor3 = rfSensor;
|
||||||
sensor3 = sensor3.initialize(P_TX, BW, f_c, G_RX_dBi, 0, 0);
|
sensor3 = sensor3.initialize(P_TX, BW, f_c, G_RX_dBi, 20, 200);
|
||||||
|
|
||||||
pos1 = [0, 0, altitude];
|
pos1 = [0, 0, altitude];
|
||||||
pos2 = [6, -4, altitude - 1];
|
pos2 = [6, -4, altitude - 1];
|
||||||
@@ -107,49 +107,28 @@ classdef test_rfSensor < matlab.unittest.TestCase
|
|||||||
targetPos = [Xg(:), Yg(:), zeros(numel(Xg), 1)];
|
targetPos = [Xg(:), Yg(:), zeros(numel(Xg), 1)];
|
||||||
|
|
||||||
% Call 1: cache empty, does all computations for this timestep
|
% Call 1: cache empty, does all computations for this timestep
|
||||||
[SINR1, ~, sensor1, others] = sensor1.sensorPerformance(pos1, targetPos, [pos2; pos3], {sensor2; sensor3});
|
[~, ~, sensor1, others] = sensor1.sensorPerformance(pos1, targetPos, [pos2; pos3], {sensor2; sensor3});
|
||||||
sensor2 = others{1};
|
sensor2 = others{1};
|
||||||
sensor3 = others{2};
|
sensor3 = others{2};
|
||||||
|
|
||||||
% Calls 2 and 3 use cached data
|
% Calls 2 and 3 use cached data
|
||||||
[SINR2, ~, sensor2, others] = sensor2.sensorPerformance(pos2, targetPos, [pos1; pos3], {sensor1; sensor3});
|
[~, ~, sensor2, others] = sensor2.sensorPerformance(pos2, targetPos, [pos1; pos3], {sensor1; sensor3});
|
||||||
sensor1 = others{1};
|
sensor1 = others{1};
|
||||||
sensor3 = others{2};
|
sensor3 = others{2};
|
||||||
|
|
||||||
[SINR3, ~, sensor3, ~] = sensor3.sensorPerformance(pos3, targetPos, [pos1; pos2], {sensor1; sensor2});
|
[~, ~, sensor3, ~] = sensor3.sensorPerformance(pos3, targetPos, [pos1; pos2], {sensor1; sensor2});
|
||||||
|
|
||||||
|
|
||||||
% All caches should be populated after the three calls
|
% All caches should be populated after the three calls
|
||||||
tc.assertNotEmpty(sensor1.rssCache);
|
tc.assertNotEmpty(sensor1.rssCache);
|
||||||
tc.assertNotEmpty(sensor2.rssCache);
|
tc.assertNotEmpty(sensor2.rssCache);
|
||||||
tc.assertNotEmpty(sensor3.rssCache);
|
tc.assertNotEmpty(sensor3.rssCache);
|
||||||
|
|
||||||
% Plot SINR from each UAV's perspective
|
% Plot SINR from each UAV's perspective.
|
||||||
sz = size(Xg);
|
% otherSensorsPos for plotPerformance: XY = offset from calling sensor, Z = absolute_alt - calling_alt.
|
||||||
SINR1 = reshape(SINR1, sz);
|
% This is exactly posOther - posSelf for each row.
|
||||||
SINR2 = reshape(SINR2, sz);
|
sensor1.plotPerformance(pos1(3), [pos2 - pos1; pos3 - pos1], {sensor2; sensor3});
|
||||||
SINR3 = reshape(SINR3, sz);
|
sensor2.plotPerformance(pos2(3), [pos1 - pos2; pos3 - pos2], {sensor1; sensor3});
|
||||||
|
sensor3.plotPerformance(pos3(3), [pos1 - pos3; pos2 - pos3], {sensor1; sensor2});
|
||||||
f = figure;
|
|
||||||
tiledlayout(f, 1, 3, TileSpacing="compact", Padding="compact");
|
|
||||||
|
|
||||||
nexttile;
|
|
||||||
imagesc(distances, distances, SINR1); axis image; set(gca, YDir="normal"); hold on;
|
|
||||||
scatter(pos1(1), pos1(2), 80, "g", "o", LineWidth=2);
|
|
||||||
scatter([pos2(1), pos3(1)], [pos2(2), pos3(2)], 80, "r", "x", LineWidth=2);
|
|
||||||
hold off; cb = colorbar; cb.Label.String = "SINR (dB)"; xlabel("X (m)"); ylabel("Y (m)"); title("SINR: UAV 1");
|
|
||||||
|
|
||||||
nexttile;
|
|
||||||
imagesc(distances, distances, SINR2); axis image; set(gca, YDir="normal"); hold on;
|
|
||||||
scatter(pos2(1), pos2(2), 80, "g", "o", LineWidth=2);
|
|
||||||
scatter([pos1(1), pos3(1)], [pos1(2), pos3(2)], 80, "r", "x", LineWidth=2);
|
|
||||||
hold off; cb = colorbar; cb.Label.String = "SINR (dB)"; xlabel("X (m)"); ylabel("Y (m)"); title("SINR: UAV 2");
|
|
||||||
|
|
||||||
nexttile;
|
|
||||||
imagesc(distances, distances, SINR3); axis image; set(gca, YDir="normal"); hold on;
|
|
||||||
scatter(pos3(1), pos3(2), 80, "g", "o", LineWidth=2);
|
|
||||||
scatter([pos1(1), pos2(1)], [pos1(2), pos2(2)], 80, "r", "x", LineWidth=2);
|
|
||||||
hold off; cb = colorbar; cb.Label.String = "SINR (dB)"; xlabel("X (m)"); ylabel("Y (m)"); title("SINR: UAV 3");
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Reference in New Issue
Block a user