added antenna pointing parameters
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
function obj = initialize(obj, txPower, bandwidth, centerFreq, rxGain_dBi)
|
function obj = initialize(obj, txPower, bandwidth, centerFreq, rxGain_dBi, boresightTilt, boresightAzimuth)
|
||||||
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;
|
||||||
|
boresightTilt (1, 1) double = 0;
|
||||||
|
boresightAzimuth (1, 1) double = 0;
|
||||||
end
|
end
|
||||||
arguments (Output)
|
arguments (Output)
|
||||||
obj (1, 1) {mustBeA(obj, "rfSensor")}
|
obj (1, 1) {mustBeA(obj, "rfSensor")}
|
||||||
@@ -15,6 +17,8 @@ function obj = initialize(obj, txPower, bandwidth, centerFreq, rxGain_dBi)
|
|||||||
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.boresightTilt = boresightTilt;
|
||||||
|
obj.boresightAzimuth = boresightAzimuth;
|
||||||
|
|
||||||
% 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
|
||||||
|
|||||||
+27
-31
@@ -5,52 +5,48 @@ function f = plotParameters(obj)
|
|||||||
arguments (Output)
|
arguments (Output)
|
||||||
f (1, 1) {mustBeA(f, "matlab.ui.Figure")};
|
f (1, 1) {mustBeA(f, "matlab.ui.Figure")};
|
||||||
end
|
end
|
||||||
|
|
||||||
% Distance and tilt sample points
|
% Agent altitude layers and angle sample points
|
||||||
d_values = 10.^[1, 2, 3, 4, 5, 6];
|
alt_values = 10.^[1, 2, 3, 4];
|
||||||
t_values = 0:2.5:180; % 0=nadir (center), 180=zenith (edge)
|
t_values = 0:2.5:87.5; % 0=nadir (center), <90=near horizon (edge)
|
||||||
a_values = 0:2.5:360;
|
a_values = 0:2.5:360;
|
||||||
|
|
||||||
% Make grid of values of distances and tilts
|
|
||||||
[d_mg, t_mg, a_mg] = meshgrid(d_values, t_values, a_values);
|
|
||||||
d = d_mg(:); t = t_mg(:); a = a_mg(:); % flatten
|
|
||||||
|
|
||||||
% Sample received signal strength (no interference or noise)
|
|
||||||
s_x = obj.RSS(d, t, a);
|
|
||||||
s_x = reshape(s_x, size(d_mg));
|
|
||||||
|
|
||||||
[T, A] = meshgrid(t_values, a_values); % Naz x Nel
|
[T, A] = meshgrid(t_values, a_values); % Naz x Nel
|
||||||
Ar = deg2rad(A);
|
Ar = deg2rad(A);
|
||||||
|
|
||||||
f = figure;
|
f = figure;
|
||||||
hold("on");
|
hold("on");
|
||||||
|
|
||||||
for ii = 1:numel(d_values)
|
for ii = 1:numel(alt_values)
|
||||||
% Linear radial mapping: t=0 (nadir) -> center, t=180 (zenith) -> edge
|
alt = alt_values(ii);
|
||||||
% Radius in log10 units to match Z axis scale
|
|
||||||
r = log10(d_values(ii)) .* T ./ 180;
|
% 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);
|
X = r .* cos(Ar);
|
||||||
Y = r .* sin(Ar);
|
Y = r .* sin(Ar);
|
||||||
Z = log10(d_values(ii)) * ones(size(X));
|
Z = log10(alt) * ones(size(X));
|
||||||
|
|
||||||
% evaluate or extract this slice
|
hs = surf(X, Y, Z, Fslice);
|
||||||
Fslice = squeeze(s_x(:, ii, :))';
|
hs.EdgeColor = 'none';
|
||||||
|
hs.FaceColor = 'interp';
|
||||||
% plot as its own surface
|
hs.FaceAlpha = 0.25;
|
||||||
h = surf(X, Y, Z, Fslice);
|
|
||||||
h.EdgeColor = 'none';
|
|
||||||
h.FaceColor = 'interp';
|
|
||||||
h.FaceAlpha = 0.25;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
colormap(turbo);
|
colormap(turbo);
|
||||||
colorbar;
|
colorbar;
|
||||||
daspect([1 1 0.2]) % Separate Z further for more distinct layers
|
daspect([1 1 0.2]);
|
||||||
xlabel('X (log_{10} units)'); ylabel('Y (log_{10} units)'); zlabel('log_{10} Distance (m)');
|
xlabel('X (log_{10} units)'); ylabel('Y (log_{10} units)'); zlabel('log_{10} Altitude (m)');
|
||||||
set(gca,'ZDir','reverse');
|
set(gca, 'ZDir', 'reverse');
|
||||||
view(3);
|
view(3);
|
||||||
axis("vis3d");
|
axis("vis3d");
|
||||||
grid("on");
|
grid("on");
|
||||||
scatter3(0, 0, 0, 'rx');
|
scatter3(0, 0, 0, 'rx');
|
||||||
hold("off");
|
hold("off");
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ classdef rfSensor
|
|||||||
BW = NaN; % Bandwidth (Hz)
|
BW = NaN; % Bandwidth (Hz)
|
||||||
f_c = NaN; % Center frequency (Hz)
|
f_c = NaN; % Center frequency (Hz)
|
||||||
G_RX_dBi = NaN; % Receiver antenna gain
|
G_RX_dBi = NaN; % Receiver antenna gain
|
||||||
|
boresightTilt = 0; % Antenna boresight tilt (deg): 0=nadir, 90=horizon
|
||||||
|
boresightAzimuth = 0; % Antenna boresight azimuth (deg): 0=+y, 90=+x
|
||||||
% 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
|
||||||
|
|||||||
@@ -11,11 +11,15 @@ 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_t = 4; % tilt beamwidth (higher = narrower beam)
|
n = 4; % beamwidth exponent (higher = narrower beam)
|
||||||
n_a = 4; % azimuth rolloff sharpness (higher = more directional)
|
|
||||||
|
|
||||||
% Elevation: cardioid family, null at zenith (t=180°), peak at nadir (t=0°)
|
% Angular offset from boresight via spherical law of cosines
|
||||||
% Azimuth: cardioid family, peak at a=0° (+y), null at a=180° (-y)
|
% Convention: t=0° nadir, t=90° horizon; a=0° +y, a=90° +x
|
||||||
value = 10 .* n_t .* log10((1 + cosd(t)) ./ 2) + ...
|
cos_theta = sind(obj.boresightTilt) .* sind(t) .* cosd(a - obj.boresightAzimuth) + ...
|
||||||
10 .* n_a .* log10((0.5 + 0.5 .* cosd(a)));
|
cosd(obj.boresightTilt) .* 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 .* n .* log10((1 + cosd(theta)) ./ 2);
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ classdef test_rfSensor < matlab.unittest.TestCase
|
|||||||
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)
|
||||||
|
|
||||||
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi);
|
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, 0, 0);
|
||||||
|
|
||||||
tc.testClass.plotParameters();
|
tc.testClass.plotParameters();
|
||||||
end
|
end
|
||||||
@@ -30,7 +30,7 @@ classdef test_rfSensor < matlab.unittest.TestCase
|
|||||||
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)
|
||||||
|
|
||||||
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi);
|
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, 0, 0);
|
||||||
|
|
||||||
altitude = 30;
|
altitude = 30;
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ classdef test_rfSensor < matlab.unittest.TestCase
|
|||||||
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)
|
||||||
|
|
||||||
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi);
|
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, 0, 0);
|
||||||
|
|
||||||
altitude = 30;
|
altitude = 30;
|
||||||
otherSensorsPos = [6, -4, -1]; % relative to main sensor
|
otherSensorsPos = [6, -4, -1]; % relative to main sensor
|
||||||
@@ -60,7 +60,7 @@ classdef test_rfSensor < matlab.unittest.TestCase
|
|||||||
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)
|
||||||
|
|
||||||
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi);
|
tc.testClass = tc.testClass.initialize(P_TX, BW, f_c, G_RX_dBi, 0, 0);
|
||||||
|
|
||||||
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
|
||||||
@@ -69,8 +69,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);
|
otherSensors{1} = otherSensors{1}.initialize(10 * P_TX, BW, f_c, G_RX_dBi, 0, 0);
|
||||||
otherSensors{2} = otherSensors{2}.initialize(100 * P_TX, BW, f_c, G_RX_dBi);
|
otherSensors{2} = otherSensors{2}.initialize(10 * P_TX, BW, f_c, G_RX_dBi, 0, 0);
|
||||||
|
|
||||||
tc.testClass.plotPerformance(altitude, otherSensorsPos, otherSensors);
|
tc.testClass.plotPerformance(altitude, otherSensorsPos, otherSensors);
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user