rfsensor parameterization
This commit is contained in:
+1
-1
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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');
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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];
|
||||||
|
|||||||
Reference in New Issue
Block a user