rf sensor model cleanup
This commit is contained in:
1 parent
8e8bb39cd9
commit
2f9f13fdc8
8 files changed
+43
-45
No files matched your search
+1
-2
@@ -19,6 +19,5 @@ function value = RSS(obj, d, dx, dy, dz)
|
||||
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);
|
||||
value = obj.P_TX_dBm + obj.transmitterGain(theta) + obj.G_RX_dBi - obj.pathLoss(d);
|
||||
end
|
||||
@@ -5,12 +5,8 @@ function value = halfAngle(obj)
|
||||
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)));
|
||||
gain = obj.transmitterGain(dtheta);
|
||||
target = gain(1) - 3;
|
||||
idx = find(gain <= target, 1);
|
||||
if isempty(idx) || idx == 1
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
function obj = initialize(obj, txPower, bandwidth, centerFreq, rxGain_dBi, beamwidthExponent, tilt, azimuth, lossExponent)
|
||||
function obj = initialize(obj, txPower, temperature, bandwidth, centerFreq, rxGain_dBi, beamwidthExponent, tilt, azimuth, lossExponent)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, "rfSensor")}
|
||||
txPower (1, 1) double;
|
||||
temperature (1, 1) double;
|
||||
bandwidth (1, 1) double;
|
||||
centerFreq (1, 1) double;
|
||||
rxGain_dBi (1, 1) double;
|
||||
@@ -16,6 +17,7 @@ function obj = initialize(obj, txPower, bandwidth, centerFreq, rxGain_dBi, beamw
|
||||
|
||||
%% Provided values
|
||||
obj.P_TX = txPower; % Transmit power (W)
|
||||
obj.T_0 = temperature; % Temperature (K)
|
||||
obj.BW = bandwidth; % Bandwidth (Hz)
|
||||
obj.f_c = centerFreq; % Center frequency (Hz)
|
||||
obj.G_RX_dBi = rxGain_dBi; % Receiving Antenna Gain (dBi)
|
||||
@@ -29,4 +31,5 @@ function obj = initialize(obj, txPower, bandwidth, centerFreq, rxGain_dBi, beamw
|
||||
%% 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
|
||||
obj.constantGainTerm_dB = 10 .* log10(2 * (obj.beamwidthExponent + 1)); % used in RSS calculation, only need to compute once
|
||||
end
|
||||
@@ -23,8 +23,11 @@ function f = plotParameters(obj)
|
||||
% 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(:));
|
||||
% Convert LOS (D, T, A) to displacement vectors for RSS
|
||||
dx = D .* sind(T) .* sind(A);
|
||||
dy = D .* sind(T) .* cosd(A);
|
||||
dz = -D .* cosd(T); % negative: ground targets are below agent
|
||||
rss = obj.RSS(D(:), dx(:), dy(:), dz(:));
|
||||
Fslice = reshape(rss, size(D));
|
||||
|
||||
% Disc geometry: t=0 (nadir) -> center, t~90 (horizon) -> edge
|
||||
|
||||
@@ -14,6 +14,7 @@ classdef rfSensor
|
||||
% Values computed at initialization
|
||||
P_TX_dBm = NaN; % Transmit power (dBm)
|
||||
N = NaN; % Thermal noise
|
||||
constantGainTerm_dB = NaN; % used in RSS calculation, only need to compute once
|
||||
% Cached state (per timestep)
|
||||
end
|
||||
properties (Access = public)
|
||||
@@ -23,7 +24,7 @@ classdef rfSensor
|
||||
end
|
||||
|
||||
methods (Access = public)
|
||||
[obj] = initialize(obj, txPower, bandwidth, centerFreq, rxGain, beamwidthExponent, tilt, azimuth); % initialize sensor, define parameters
|
||||
[obj] = initialize(obj, txPower, temperature, 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
|
||||
@@ -34,7 +35,7 @@ classdef rfSensor
|
||||
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
|
||||
G_TX_dB = transmitterGain(obj, theta); % Antenna gain for a given angle from boresight (degrees)
|
||||
L_FSPL_dB = pathLoss(obj, d); % Free space path loss for a given TX/RX pair
|
||||
end
|
||||
end
|
||||
@@ -1,23 +1,12 @@
|
||||
function value = transmitterGain(obj, t, a)
|
||||
function value = transmitterGain(obj, theta)
|
||||
arguments (Input)
|
||||
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||
t (:, 1) double; % LOS tilt angle
|
||||
a (:, 1) double; % LOS azimuth angle
|
||||
obj (1, 1) {mustBeA(obj, "rfSensor")};
|
||||
theta (:, 1) double; % angle from boresight (degrees)
|
||||
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);
|
||||
% Cosine pattern: peak at boresight, -inf dB at 90°.
|
||||
% Clamped so targets behind the antenna (theta > 90°) get -inf rather than NaN.
|
||||
value = obj.constantGainTerm_dB + 10 .* obj.beamwidthExponent .* log10(max(0, cosd(theta)));
|
||||
end
|
||||
Reference in new issue
Block a user