rfsensor parameterization

This commit is contained in:
2026-05-06 17:16:57 -07:00
parent ea111e56f8
commit bc26cbc706
9 changed files with 37 additions and 21 deletions
+1 -1
View File
@@ -10,6 +10,6 @@ function value = RSS(obj, d, t, a)
end end
assert(size(d, 1) == size(t, 1), "Mismatch in number of distances (%d) and tilts (%d) provided", size(d, 1), size(t, 1)); assert(size(d, 1) == size(t, 1), "Mismatch in number of distances (%d) and tilts (%d) provided", size(d, 1), size(t, 1));
% RSS (dBm) = TX Power (dBm) + TX Antenna Gain (dB) + RX Antenna Gain (dBi) - Path Loss (dB) % RSS (dBm) = TX Power (dBm) + TX Antenna Gain (dBi) + RX Antenna Gain (dBi) - Path Loss (dB)
value = obj.P_TX_dBm + obj.transmitterGain(t, a) + obj.G_RX_dBi - obj.pathLoss(d); value = obj.P_TX_dBm + obj.transmitterGain(t, a) + obj.G_RX_dBi - obj.pathLoss(d);
end end
+9 -3
View File
@@ -1,26 +1,32 @@
function obj = initialize(obj, txPower, bandwidth, centerFreq, rxGain_dBi, tilt, azimuth) function obj = initialize(obj, txPower, bandwidth, centerFreq, rxGain_dBi, beamwidthExponent, tilt, azimuth, lossExponent)
arguments (Input) arguments (Input)
obj (1, 1) {mustBeA(obj, "rfSensor")} obj (1, 1) {mustBeA(obj, "rfSensor")}
txPower (1, 1) double; txPower (1, 1) double;
bandwidth (1, 1) double; bandwidth (1, 1) double;
centerFreq (1, 1) double; centerFreq (1, 1) double;
rxGain_dBi (1, 1) double; rxGain_dBi (1, 1) double;
beamwidthExponent (1, 1) double;
tilt (1, 1) double = 0; tilt (1, 1) double = 0;
azimuth (1, 1) double = 0; azimuth (1, 1) double = 0;
lossExponent (1, 1) double = NaN;
end end
arguments (Output) arguments (Output)
obj (1, 1) {mustBeA(obj, "rfSensor")} obj (1, 1) {mustBeA(obj, "rfSensor")}
end end
% Provided values %% Provided values
obj.P_TX = txPower; % Transmit power (W) obj.P_TX = txPower; % Transmit power (W)
obj.BW = bandwidth; % Bandwidth (Hz) obj.BW = bandwidth; % Bandwidth (Hz)
obj.f_c = centerFreq; % Center frequency (Hz) obj.f_c = centerFreq; % Center frequency (Hz)
obj.G_RX_dBi = rxGain_dBi; % Receiving Antenna Gain (dBi) 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.tilt = tilt;
obj.azimuth = azimuth; obj.azimuth = azimuth;
% Computed values %% Computed values
obj.P_TX_dBm = 10*log10(obj.P_TX/1e-3); % Transmit power in dBm 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 obj.N = obj.k_B * obj.T_0 * obj.BW; % Thermal noise
end end
+1 -1
View File
@@ -8,6 +8,6 @@ function L_FSPL_dB = pathLoss(obj, d)
end end
% Free Space Path Loss (dB); d clamped away from zero (log undefined at d=0) % Free Space Path Loss (dB); d clamped away from zero (log undefined at d=0)
L_FSPL_dB = 20*log10(max(d, eps)) + 20*log10(obj.f_c) + 20*log10((4*pi)/obj.c); L_FSPL_dB = obj.lossExponent * 10 * log10(max(d, eps)) + 20 * log10(obj.f_c) + 20 * log10((4*pi)/obj.c);
end end
+1 -1
View File
@@ -40,7 +40,7 @@ function f = plotParameters(obj)
end end
colormap(turbo); colormap(turbo);
colorbar; c = colorbar; c.Label.String = "Received Signal Strength (dB)";
daspect([1 1 0.2]); daspect([1 1 0.2]);
xlabel('X (log_{10} units)'); ylabel('Y (log_{10} units)'); zlabel('log_{10} Altitude (m)'); xlabel('X (log_{10} units)'); ylabel('Y (log_{10} units)'); zlabel('log_{10} Altitude (m)');
set(gca, 'ZDir', 'reverse'); set(gca, 'ZDir', 'reverse');
+1 -1
View File
@@ -52,7 +52,7 @@ function f = plotPerformance(obj, altitude, otherSensorsPos, otherSensors)
colorbar; xlabel("X (m)"); ylabel("Y (m)"); colorbar; 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); addSensorOverlay(gca, sensorXY(1, 1:2), sensorTilts(1, 1), sensorAzimuths(1, 1), tailScale);
nexttile; nexttile;
imagesc(distances, distances, SINR); imagesc(distances, distances, SINR);
+3 -1
View File
@@ -4,6 +4,7 @@ classdef rfSensor
c = 3e8; % Speed of light (m/s) c = 3e8; % Speed of light (m/s)
k_B = 1.38e-23 % Boltzmann constant (W/Hz/K) for thermal noise model k_B = 1.38e-23 % Boltzmann constant (W/Hz/K) for thermal noise model
T_0 = 300; % Ambient temperature (Kelvin) 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 % Sensor parameters
P_TX = NaN; % Transmit power (Watts) P_TX = NaN; % Transmit power (Watts)
BW = NaN; % Bandwidth (Hz) BW = NaN; % Bandwidth (Hz)
@@ -11,6 +12,7 @@ classdef rfSensor
G_RX_dBi = NaN; % Receiver antenna gain G_RX_dBi = NaN; % Receiver antenna gain
tilt = NaN; % Antenna boresight tilt (deg): 0=nadir, 90=horizon tilt = NaN; % Antenna boresight tilt (deg): 0=nadir, 90=horizon
azimuth = NaN; % Antenna boresight azimuth (deg): 0=+y, 90=+x, 180=-y, 270=-x azimuth = NaN; % Antenna boresight azimuth (deg): 0=+y, 90=+x, 180=-y, 270=-x
beamwidthExponent = NaN; % Antenna beamwidth exponent for cosine radiation pattern, larger exponent -> narrower beam
% Values computed at initialization % Values computed at initialization
P_TX_dBm = NaN; % Transmit power (dBm) P_TX_dBm = NaN; % Transmit power (dBm)
N = NaN; % Thermal noise N = NaN; % Thermal noise
@@ -19,7 +21,7 @@ classdef rfSensor
end end
methods (Access = public) methods (Access = public)
[obj] = initialize(obj, txPower, bandwidth, centerFreq, rxGain, tilt, azimuth); % initialize sensor, define parameters [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 [SINR, SNR, obj, otherSensors] = sensorPerformance(obj, agentPos, targetPos, otherSensorsPos, otherSensors); % determine sensor performance for a given single sensor and target geometry
[d, t, a] = computePointToPoints(obj, agentPos, targetPos); [d, t, a] = computePointToPoints(obj, agentPos, targetPos);
[value] = halfAngle(obj); % tilt angle (deg) at which sensor performance is halved [value] = halfAngle(obj); % tilt angle (deg) at which sensor performance is halved
+1 -3
View File
@@ -11,8 +11,6 @@ function value = transmitterGain(obj, t, a)
error("t and a must be the same size"); error("t and a must be the same size");
end end
n = 6; % beamwidth exponent (higher = narrower beam)
% Angular offset from boresight via spherical law of cosines % Angular offset from boresight via spherical law of cosines
% Convention: t=0° nadir, t=90° horizon; a=0° +y, a=90° +x % Convention: t=0° nadir, t=90° horizon; a=0° +y, a=90° +x
cos_theta = sind(obj.tilt) .* sind(t) .* cosd(a - obj.azimuth) + ... cos_theta = sind(obj.tilt) .* sind(t) .* cosd(a - obj.azimuth) + ...
@@ -21,5 +19,5 @@ function value = transmitterGain(obj, t, a)
theta = acosd(cos_theta); theta = acosd(cos_theta);
% Cardioid family: peak at boresight (theta=0), null opposite (theta=180°) % Cardioid family: peak at boresight (theta=0), null opposite (theta=180°)
value = 10 .* n .* log10((1 + cosd(theta)) ./ 2); value = 10 .* obj.beamwidthExponent .* log10((1 + cosd(theta)) ./ 2);
end end
+1 -1
View File
@@ -20,7 +20,7 @@ function f = plot(obj, ind, f)
hold(f.CurrentAxes, "off"); hold(f.CurrentAxes, "off");
else else
hold(f.Children(1).Children(ind(1)), "on"); hold(f.Children(1).Children(ind(1)), "on");
o = surf(f.Children(1).Children(ind(1)), obj.X, obj.Y, zeros(size(obj.X)), obj.values ./ max(obj.values, [], "all"), "EdgeColor", "none"); o = surf(f.Children(1).Children(ind(1)), obj.X, obj.Y, zeros(size(obj.X)), obj.values ./ sum(obj.values, "all"), "EdgeColor", "none");
o.HitTest = "off"; o.HitTest = "off";
o.PickableParts = "none"; o.PickableParts = "none";
hold(f.Children(1).Children(ind(1)), "off"); hold(f.Children(1).Children(ind(1)), "off");
+19 -9
View File
@@ -18,8 +18,10 @@ classdef test_rfSensor < matlab.unittest.TestCase
BW = 20e6; % Bandwidth (Hz) BW = 20e6; % Bandwidth (Hz)
f_c = 2e9; % Center frequency (Hz) f_c = 2e9; % Center frequency (Hz)
G_RX_dBi = 3; % Receiving Antenna Gain (dBi) 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, 0, 0); tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent, 0, 0, lossExponent);
tc.testClass.plotParameters(); tc.testClass.plotParameters();
end end
@@ -29,8 +31,10 @@ classdef test_rfSensor < matlab.unittest.TestCase
BW = 20e6; % Bandwidth (Hz) BW = 20e6; % Bandwidth (Hz)
f_c = 2e9; % Center frequency (Hz) f_c = 2e9; % Center frequency (Hz)
G_RX_dBi = 3; % Receiving Antenna Gain (dBi) 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, 30, 135); tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent, 30, 135, lossExponent);
altitude = 30; altitude = 30;
@@ -50,8 +54,10 @@ classdef test_rfSensor < matlab.unittest.TestCase
BW = 20e6; % Bandwidth (Hz) BW = 20e6; % Bandwidth (Hz)
f_c = 2e9; % Center frequency (Hz) f_c = 2e9; % Center frequency (Hz)
G_RX_dBi = 3; % Receiving Antenna Gain (dBi) 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, 0, 0); tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent, 0, 0, lossExponent);
altitude = 30; altitude = 30;
otherSensorsPos = [6, -4, -1]; % relative to main sensor otherSensorsPos = [6, -4, -1]; % relative to main sensor
@@ -67,8 +73,10 @@ classdef test_rfSensor < matlab.unittest.TestCase
BW = 20e6; % Bandwidth (Hz) BW = 20e6; % Bandwidth (Hz)
f_c = 2e9; % Center frequency (Hz) f_c = 2e9; % Center frequency (Hz)
G_RX_dBi = 3; % Receiving Antenna Gain (dBi) 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, 0, 0); tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent, 0, 0, lossExponent);
altitude = 30; altitude = 30;
otherSensorsPos = [6, -4, -1; -2, 6, 0]; % relative to main sensor otherSensorsPos = [6, -4, -1; -2, 6, 0]; % relative to main sensor
@@ -77,8 +85,8 @@ classdef test_rfSensor < matlab.unittest.TestCase
otherSensors{2} = rfSensor; otherSensors{2} = rfSensor;
% Must use same center frequency and bandwidth for interference sources % Must use same center frequency and bandwidth for interference sources
otherSensors{1} = otherSensors{1}.initialize(10 * P_TX, BW, f_c, G_RX_dBi, 0, 0); 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, 0, 0); otherSensors{2} = otherSensors{2}.initialize(10 * P_TX, BW, f_c, G_RX_dBi, beamwidthExponent, 0, 0, lossExponent);
tc.testClass.plotPerformance(altitude, otherSensorsPos, otherSensors); tc.testClass.plotPerformance(altitude, otherSensorsPos, otherSensors);
end end
@@ -88,13 +96,15 @@ classdef test_rfSensor < matlab.unittest.TestCase
f_c = 2e9; f_c = 2e9;
G_RX_dBi = 3; G_RX_dBi = 3;
altitude = 30; altitude = 30;
beamwidthExponent = [6, 4, 10];
lossExponent = 2;
sensor1 = rfSensor; sensor1 = rfSensor;
sensor1 = sensor1.initialize(P_TX, BW, f_c, G_RX_dBi, 15, 45); sensor1 = sensor1.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent(1), 15, 45, lossExponent);
sensor2 = rfSensor; sensor2 = rfSensor;
sensor2 = sensor2.initialize(P_TX, BW, f_c, G_RX_dBi, 10, 150); sensor2 = sensor2.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent(2), 10, 150, lossExponent);
sensor3 = rfSensor; sensor3 = rfSensor;
sensor3 = sensor3.initialize(P_TX, BW, f_c, G_RX_dBi, 20, 200); sensor3 = sensor3.initialize(P_TX, BW, f_c, G_RX_dBi, beamwidthExponent(3), 20, 200, lossExponent);
pos1 = [0, 0, altitude]; pos1 = [0, 0, altitude];
pos2 = [6, -4, altitude - 1]; pos2 = [6, -4, altitude - 1];