Clear Filters
Clear Filters

Interpolating Phased Array Toolbox patterns

4 views (last 30 days)
I have an antenna modeled in Phased Array Toolbox, and after updating its steering I'm using the pattern() function to store the AZ/EL directivity pattern (just forward hemisphere). I want to then in another chunk of code interpolate the gain to a (large) number of grid points where in a loop over each I'm calculating the observed AZ/EL. I figure a griddedInterpolant object is what I should build which I can then query a bunch of times. However, the X1,X2 ordering for interpolation has the legacy of meshgrid/ndgrid where some dimensions are transposed. The EL and AZ arrays are both 1x181 elements which helps add to the confusion (so the pattern is 181x181). What's the best formulation, or what is the most efficient way to store/retrieve/interpolate a computed pattern?

Accepted Answer

Sudarsanan A K
Sudarsanan A K on 10 Jun 2024
Hello Martin,
To efficiently store and interpolate a computed pattern, you can follow these steps:
  1. Store the computed pattern in a variable, let us say "patternData", which is an 181x181 matrix representing the directivity pattern.
  2. Create a grid of azimuth and elevation values using the "meshgrid" function. Since the "pattern" function returns the pattern in AZ/EL order, you need to transpose the grid to match the pattern dimensions.
  3. Create a "griddedInterpolant" object using the "griddedInterpolant" function. Specify the 'linear' interpolation method for smooth interpolation.
  4. Query the interpolated pattern at any desired azimuth and elevation values using the "griddedInterpolant" object.
Here is an example:
% Step 1: Simulate the pattern data
patternData = peaks(181); % Using MATLAB's peaks function for demonstration
% Step 2: Create grids for azimuth and elevation
az = linspace(-180, 180, 181); % Azimuth from -180 to 180 degrees
el = linspace(0, 90, 181); % Elevation from 0 to 90 degrees
[azGrid, elGrid] = meshgrid(az, el); % Create 2D grids
% Step 3: Initialize the griddedInterpolant
% Note: Transpose azGrid, elGrid, and patternData to match the expected input orientation for griddedInterpolant
patternInterp = griddedInterpolant(azGrid', elGrid', patternData', 'linear');
% Step 4: Query the interpolated pattern at specific azimuth and elevation
queryAz = -45; % Query point in azimuth
queryEl = 30; % Query point in elevation
interpValue = patternInterp(queryAz, queryEl);
% Display the interpolated value
disp(['Interpolated gain value at AZ=45° and EL=30°: ', num2str(interpValue)]);
Interpolated gain value at AZ=45° and EL=30°: 2.4518
You can visualize "patternData", the interpolated value, and the actual value in the "patternData" as follows:
% Plot the patternData
figure;
surf(az, el, patternData');
shading interp; % Optional, for smoother color transition
hold on;
% Mark the query point on the plot
% Convert AZ and EL to indices (approximate)
[~, azIndex] = min(abs(az - queryAz));
[~, elIndex] = min(abs(el - queryEl));
% Convert the indices to actual AZ and EL values for plotting
azPlot = az(azIndex);
elPlot = el(elIndex);
% Plot the query point - marking both the interpolated point in the pattern
% and the actual value from the patternData for comparison
plot3(azPlot, elPlot, interpValue, 'ro', 'MarkerSize', 10, 'LineWidth', 2); % Interpolated value
plot3(azPlot, elPlot, patternData(elIndex, azIndex), 'kx', 'MarkerSize', 10, 'LineWidth', 2); % Actual value in patternData
% Enhancements for better visualization
title('Peaks Function with Query Point Marked');
xlabel('Azimuth (degrees)');
ylabel('Elevation (degrees)');
zlabel('Gain');
legend('Peaks Surface', 'Interpolated Value', 'Actual Value', 'Location', 'Best');
% Display the interpolated value and the actual value from patternData
disp(['Interpolated gain value at AZ=-45° and EL=30°: ', num2str(interpValue)]);
Interpolated gain value at AZ=-45° and EL=30°: 2.4518
disp(['Actual gain value from patternData at AZ=-45° and EL=30°: ', num2str(patternData(elIndex, azIndex))]);
Actual gain value from patternData at AZ=-45° and EL=30°: 2.4344
For detailed information about the "meshgrid" function and "griddedInterpolant", please refer to the following documentations:
I hope this helps!
  1 Comment
Martin Ryba
Martin Ryba on 10 Jun 2024
I didn't run your exact code, but via trial and error, I had found the right recipe. I think your code is incorrect in that you have to use ndgrid instead of meshgrid (which transposes X/Y), although this could be a function of whether you use MATLAB's azimuth convention or the normal aerospace/antennas one.
elSet = -90:90;
azSet = -90:90; % Note I just want forward hemisphere
w = sVec_tx(fc,[-azSteer;elSteer]); % Note MATLAB's azimuth convention is backwards
TxPat = pattern(arrTx,fc,azSet,elSet,'Weights',w); % Compute the pattern
[EL,AZ] = ndgrid(elSet,azSet); % Note I needed elevation first
FTx = griddedInterpolant(EL,AZ,TxPat);
for ipt = 1:ngrid
% Now in loop creating each points' elevation and azimuth
az = atan2(nlos_ant(2),nlos_ant(1)) * (180/pi);
el = -asin(nlos_ant(3)) * (180/pi);
GTx = FTx(el,-az);
end

Sign in to comment.

More Answers (1)

George
George on 10 Jun 2024
Another thing to consider is that pattern also accepts optional azimuth and elevation angle input arguments:
So you could just pass more azimuth and elevation sample points instead of using the default azimuth and elevation values and interpolating.
  1 Comment
Martin Ryba
Martin Ryba on 10 Jun 2024
For the case where I have literally a million (slightly changing) az/el pairs for each of my 3-D grid points, this is not going to be very efficient. That's why I wanted to use griddedInterpolant

Sign in to comment.

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!