Matlab create measured antenna
Skill matlab/matlab-agentic-toolkit/skills-catalog/rf-and-mixed-signal/matlab-create-measured-antenna
Create measuredAntenna objects from simulated or measured data using MATLAB Antenna Toolbox. Converts catalog antennas and arrays into measuredAntenna for RF site planning (txsite/rxsite), satellite scenarios, beam steering, and pattern multiplication. Use when the user wants to create a measuredAntenna, convert an antenna to measured data, use an antenna with txsite/rxsite, build a satellite link budget, or steer an array beam with phase shifts.From its SKILL.md
npx -y skills add matlab/matlab-agentic-toolkit --skill matlab-create-measured-antennaAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
What its file declares
Copied from the file, not written here
The file declares its own license as MathWorks BSD-3-Clause. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
19.5 KB, ~5.3k tokens by cl100k_base, as published. Nobody here has run it
Measured Antenna Skill
You are an expert RF and antenna engineer assisting a professional antenna engineer or RF system designer. Use MATLAB Antenna Toolbox to create measuredAntenna objects from simulated or measured antenna data.
When to Use
- User wants to create a
measuredAntennafrom pattern data or catalog antenna simulation - User needs to use an antenna with
txsite/rxsitefor propagation or site planning - User wants to steer a beam or apply pattern multiplication with measured data
- User asks about satellite link budget with a directional antenna
- User has measured data (directivity, gain) and wants to create an antenna object
When NOT to Use
- User wants to design a new antenna from scratch — use
matlab-design-antenna - User wants RF propagation/coverage analysis — use
matlab-analyze-rf-propagation - User wants to build a custom antenna from shapes — use
matlab-create-custom-antenna
Core Workflow
-
Parse the request -- Identify the source antenna or array, operating frequency (or frequency band), the intended use case (general E-field capture, RF site planning, satellite link, array beam steering, or element-in-array), and any additional constraints (grid resolution, tilt, scan angle).
-
Select the workflow -- Choose the correct constructor variant based on the use case (see Workflow Selection table below).
-
Generate the spherical grid -- Create the evaluation grid with azimuth-fast ordering. Always transpose after
meshgrid. -
Extract field or pattern data -- Use
EHfieldsfor E-field workflows orpatternwithType="directivity"for directivity-only workflows. Transpose all outputs to the expected orientation. -
Build the measuredAntenna -- Construct the object with the correct property combination for the selected workflow.
-
Verify -- Compare the
measuredAntennapattern against the original antenna or array pattern. Usepatternfor E-field and EmbeddedE workflows,patternMultiplyfor element-in-array. -
Present results professionally -- Summarize in a table including: workflow name, key functions used (e.g.
EHfields,pattern), data sizes (e.g. P-by-3), ordering method (e.g. az-fast meshgrid transpose), and key constructor properties set (e.g.E = [],CalculateTotalField = true). Include peak gain/directivity with units.
Workflow Selection
| Goal | Workflow | Key Property |
|---|---|---|
| Preserve full E-field data for a single element | E-field | E = P-by-3-by-F |
Use antenna with txsite/rxsite/coverage | Directivity-only | Directivity = P-by-F, E = [] |
| Tilted antenna for satellite uplink | Directivity-only with tilt | Directivity = P-by-F, E = [] |
| Array with per-element beam steering | EmbeddedE | EmbeddedE = P-by-3-by-N-by-F |
| Use measuredAntenna as element in a larger array | Element-in-array | E = P-by-3, use patternMultiply |
Informal name mapping -- When the user gives a common description, map to the correct workflow:
- "convert antenna to measured" / "create measuredAntenna" --> E-field workflow
- "use antenna with txsite" / "RF propagation" / "coverage map" --> Directivity-only workflow
- "satellite link" / "uplink" / "ground station antenna" --> Directivity-only with tilt
- "array beam steering" / "phase shift array" / "embedded element" --> EmbeddedE workflow
- "measured element in array" / "patternMultiply" --> Element-in-array workflow
Critical: Azimuth-Fast Data Ordering
measuredAntenna expects data with azimuth as the fast-varying index. meshgrid produces el-fast by default because MATLAB flattens column-major. Always transpose after meshgrid:
[phi, elv] = meshgrid(az, el);
phi = phi'; % Transpose: now az-by-el
elv = elv'; % Transpose: now az-by-el
% phi(:) and elv(:) are now az-fast column vectors
Failing to transpose produces silently wrong patterns -- the data maps to incorrect angular positions.
pattern() output is also el-fast
pattern(ant, freq, az, el) returns an el-by-az matrix. Transpose before flattening:
[pat, ~, ~] = pattern(ant, freq, az, el, Type="directivity");
pat1 = pat'; % Transpose to az-by-el
D = pat1(:); % Flatten az-fast
EHfields output is 3-by-P
EHfields returns 3-by-P. Transpose to P-by-3 for measuredAntenna:
[e, ~] = EHfields(ant, freq, points);
E = e.'; % P-by-3
FieldCoordinate: Rectangular vs Polar
measuredAntenna supports two field coordinate systems:
| FieldCoordinate | E columns (P-by-3) | Source |
|---|---|---|
"rectangular" (default) | [Ex, Ey, Ez] | EHfields(ant, freq, points) |
"polar" | [Ephi, Etheta, Er] | EHfields(ant, freq, points, Coordinate="spherical") |
When to use "polar"
- Importing measured data from an anechoic chamber (which outputs Etheta/Ephi)
- Importing from external EM tools (HFSS .ffd files, CST, FEKO)
- When source data is already in spherical components
Extracting polar data from Antenna Toolbox
EHfields with Coordinate="spherical" returns rows [Ephi; Etheta; Er]. Transpose gives exactly what measuredAntenna expects:
[e, ~] = EHfields(ant, freq, points, Coordinate="spherical");
E_polar = e.'; % P-by-3: [Ephi, Etheta, Er]
mAnt = measuredAntenna( ...
E = E_polar, ...
Direction = Direction, ...
FieldFrequency = freq, ...
FieldCoordinate = "polar", ...
Azimuth = az, ...
Elevation = el);
Importing external chamber measurements
Measurement systems typically output Etheta and Ephi directly. Er is zero in the far field:
% From chamber data (Etheta_meas and Ephi_meas are P-by-1 complex vectors)
E_polar = [Ephi_meas, Etheta_meas, zeros(numPoints, 1)];
mAnt = measuredAntenna( ...
E = E_polar, ...
Direction = Direction, ...
FieldFrequency = measuredFreq, ...
FieldCoordinate = "polar", ...
Azimuth = az, ...
Elevation = el);
Column order is [Ephi, Etheta, Er] -- not [Etheta, Ephi, Er]. This matches the HFSS .ffd import convention.
Common Setup: Spherical Grid (All Workflows)
Used by all workflows. The az-fast ordering after meshgrid is universal.
freq = 2.4e9;
c = physconst("LightSpeed");
lambda = c / freq;
ant = design(patchMicrostrip, freq);
az = -180:5:180;
el = -90:5:90;
R = 100*lambda;
[phi, elv] = meshgrid(az, el);
phi = phi'; % Transpose for az-fast
elv = elv';
numPoints = numel(phi);
% Cartesian points for EHfields (3-by-P)
[x, y, z] = sph2cart(deg2rad(phi(:)), deg2rad(elv(:)), R);
points = [x, y, z].';
% Direction matrix for measuredAntenna (P-by-3: [az, el, R])
Direction = [phi(:) elv(:) R*ones(numPoints, 1)];
Workflow 1: Single-Element E-Field (Multi-Frequency)
Creates a measuredAntenna preserving full E-field data. Supports multiple frequencies via P-by-3-by-F array.
fieldFreqs = [2.2e9, 2.4e9, 2.6e9];
numFreqs = numel(fieldFreqs);
E_data = zeros(numPoints, 3, numFreqs);
for k = 1:numFreqs
[e, ~] = EHfields(ant, fieldFreqs(k), points);
E_data(:, :, k) = e.'; % Transpose 3-by-P to P-by-3
end
sParams = sparameters(ant, fieldFreqs);
mAnt = measuredAntenna( ...
E = E_data, ...
Direction = Direction, ...
FieldFrequency = fieldFreqs(:), ...
FieldCoordinate = "rectangular", ...
Azimuth = az, ...
Elevation = el, ...
Sparameters = sParams);
Verification
% Compare simulated vs measuredAntenna pattern
figure; pattern(ant, freq, "Type", "efield");
figure; pattern(mAnt, freq);
Properties Used
| Property | Size | Description |
|---|---|---|
E | P-by-3-by-F | E-field in rectangular coordinates |
Direction | P-by-3 | [az, el, R] for each point |
FieldFrequency | F-by-1 | Frequencies in Hz |
FieldCoordinate | string | "rectangular" for Ex/Ey/Ez |
Azimuth | 1-by-Naz | Azimuth values in degrees |
Elevation | 1-by-Nel | Elevation values in degrees |
Sparameters | sparameters | S-parameter object |
Workflow 2: Directivity-Only for RF Site Planning
txsite and rxsite require measuredAntenna with non-empty Directivity and empty E and EmbeddedE.
Direction and Directivity must use the same az-fast ordering — transpose after meshgrid, same as E-field workflows.
% Direction: az-fast (transpose after meshgrid)
[phi, elv] = meshgrid(az, el);
phi = phi';
elv = elv';
numPoints = numel(phi);
Direction = [phi(:) elv(:) R*ones(numPoints, 1)];
D_data = zeros(numPoints, numFreqs);
for k = 1:numFreqs
[pat, ~, ~] = pattern(ant, fieldFreqs(k), az, el, Type="directivity");
pat1 = pat'; % Transpose el-by-az to az-by-el
D_data(:, k) = pat1(:); % Flatten az-fast
end
mAntSite = measuredAntenna( ...
E = [], ...
Directivity = D_data, ...
Direction = Direction, ...
FieldFrequency = fieldFreqs(:), ...
Azimuth = az, ...
Elevation = el);
Using with txsite/rxsite
tx = txsite( ...
Name = "Patch TX", ...
Antenna = mAntSite, ...
AntennaHeight = 30, ...
TransmitterFrequency = freq, ...
TransmitterPower = 10);
rx = rxsite( ...
Name = "Receiver", ...
Latitude = 42.30, Longitude = -71.35, ...
AntennaHeight = 1.5, ...
ReceiverSensitivity = -90);
ss = sigstrength(rx, tx);
coverage(tx, SignalStrengths=[-60 -70 -80 -90], MaxRange=5000);
Properties Used
| Property | Size | Description |
|---|---|---|
E | [] | Must be empty for txsite/rxsite |
Directivity | P-by-F | Directivity in dBi |
Direction | P-by-3 | [az, el, R] for each point |
Workflow 3: Tilted Antenna for Satellite Communication
Tilt the antenna beam toward zenith for ground-to-satellite uplink. Uses Directivity-only (same constructor as Workflow 2) with a tilted simulated antenna. Same az-fast ordering for Direction and Directivity.
antTilted = design(patchMicrostrip, freq);
antTilted.Tilt = 90;
antTilted.TiltAxis = [0 1 0];
% Direction: az-fast (same as Workflow 2)
[phi, elv] = meshgrid(az, el);
phi = phi';
elv = elv';
numPoints = numel(phi);
Direction = [phi(:) elv(:) R*ones(numPoints, 1)];
D_data_tilted = zeros(numPoints, numFreqs);
for k = 1:numFreqs
[pat, ~, ~] = pattern(antTilted, fieldFreqs(k), az, el, Type="directivity");
pat1 = pat';
D_data_tilted(:, k) = pat1(:);
end
mAntSat = measuredAntenna( ...
E = [], ...
Directivity = D_data_tilted, ...
Direction = Direction, ...
FieldFrequency = fieldFreqs(:), ...
Azimuth = az, ...
Elevation = el);
Satellite Scenario Usage
sc = satelliteScenario(startTime, stopTime, sampleTime);
sat = satellite(sc, semiMajorAxis, eccentricity, inclination, ...
RAAN, argPeriapsis, trueAnomaly);
gs = groundStation(sc, lat, lon, MaskElevationAngle=10);
% Gimbal on ground station to track satellite
gimGS = gimbal(gs);
pointAt(gimGS, sat);
% Mount transmitter on gimbal with measuredAntenna
gsTx = transmitter(gimGS, ...
Antenna = mAntSat, ...
Frequency = freq, ...
Power = 100, ...
BitRate = 1, ...
SystemLoss = 3);
% Gimbal on satellite pointing at ground station
gimSat = gimbal(sat);
pointAt(gimSat, gs);
satRx = receiver(gimSat, SystemLoss=3, RequiredEbNo=5);
gaussianAntenna(satRx, DishDiameter=0.5);
lnk = link(gsTx, satRx);
lnkIntervals = linkIntervals(lnk);
Key notes:
- Mount transmitter/receiver on a
gimbal(not directly on station/satellite); usepointAt(gimbal, target)for tracking on both ends. Tilt=90withTiltAxis=[0 1 0]rotates beam from broadside to zenith.
Workflow 4: Array with EmbeddedE (Beam Steering)
Extract per-element embedded E-fields from an array. Enables beam steering via PhaseShift and AmplitudeTaper.
arr = linearArray( ...
Element = design(patchMicrostrip, freq), ...
NumElements = 4, ...
ElementSpacing = lambda/2);
sParamsArr = sparameters(arr, fieldFreqs);
numElements = arr.NumElements;
% Extract embedded E-field per element: P-by-3-by-N-by-F
EmbE = zeros(numPoints, 3, numElements, numFreqs);
for k = 1:numFreqs
for n = 1:numElements
[e, ~] = EHfields(arr, fieldFreqs(k), points, ElementNumber=n);
EmbE(:, :, n, k) = e.';
end
end
mAntArray = measuredAntenna( ...
E = [], ...
EmbeddedE = EmbE, ...
Direction = Direction, ...
NumPorts = numElements, ...
FieldFrequency = fieldFreqs(:), ...
FieldCoordinate = "rectangular", ...
Azimuth = az, ...
Elevation = el, ...
Sparameters = sParamsArr, ...
CalculateTotalField = true);
Beam Steering
steerAz = 30;
ps = phaseShift(arr, freq, [steerAz, 0]);
mAntArray.PhaseShift = ps;
figure;
pattern(mAntArray, freq);
Verification
% Compare total pattern
figure; pattern(arr, freq, "Type", "efield");
figure; pattern(mAntArray, freq);
% Compare per-element embedded patterns
figure; pattern(arr, freq, az, el, ElementNumber=1, Type="efield");
figure; pattern(mAntArray, freq, az, el, ElementNumber=1);
Properties Used
| Property | Size | Description |
|---|---|---|
E | [] | Must be empty when using EmbeddedE |
EmbeddedE | P-by-3-by-N-by-F | Per-element E-field |
NumPorts | scalar | Number of array elements |
CalculateTotalField | logical | true to sum element contributions |
PhaseShift | 1-by-N | Phase weights per element (degrees) |
AmplitudeTaper | 1-by-N | Amplitude weights per element |
Workflow 5: measuredAntenna as Element in Array
Create a measuredAntenna from a single element, then assign it as the Element of an array. Only patternMultiply is supported when measuredAntenna is used as an array element -- not pattern.
ant2 = design(patchMicrostrip, freq);
% Single-frequency E-field extraction
E0 = EHfields(ant2, freq, points);
mesAnt = measuredAntenna( ...
E = E0.', ...
Direction = Direction, ...
NumPorts = 1, ...
Azimuth = az, ...
Elevation = el, ...
FieldCoordinate = "rectangular", ...
FieldFrequency = freq);
% Use as element in a rectangular array
rectArray = design(rectangularArray, freq, ant2);
rectArrayMes = copy(rectArray);
rectArrayMes.Element = mesAnt;
% Compare using patternMultiply (NOT pattern)
figure; patternMultiply(rectArray, freq);
figure; patternMultiply(rectArrayMes, freq);
Performance
- Start with 5-degree grid steps; use 1-degree only when high accuracy is needed.
- Limit multi-frequency extraction to 3--5 frequencies unless dense sweeps are required.
- For EmbeddedE with >8 elements, warn about computation time before proceeding.
MATLAB Coding Standards
- Use 4-space indentation, lowerCamelCase for variables, UpperCamelCase for Name-Value args.
- Use
"double quotes"for strings. Parse frequency units (MHz, GHz, Hz); default to Hz if unspecified. - Do not add titles to Antenna Toolbox plots (
show,pattern,patternMultiply, etc.) -- they already generate their own titles. - Use
fprintffor formatted numerical output. - Follow the MATLAB coding guidelines from
guidelines://coding.
Gotchas
- Forgot to transpose meshgrid -- All workflows: always
phi = phi'; elv = elv';aftermeshgrid. This ensures az-fast ordering for both Direction and data (E, Directivity, EmbeddedE). - Mismatched Direction and Directivity ordering -- Direction and Directivity must use the same az-fast flattening. If you transpose one but not the other, each index maps to a different angular position, producing silently wrong patterns.
- Forgot to transpose pattern() output --
patternreturns el-by-az. Dopat'then(:). - Forgot to transpose EHfields output -- Returns 3-by-P, need P-by-3 for
measuredAntenna. - Using E-field measuredAntenna with txsite --
txsiterequiresDirectivitypopulated andE = []. SetE = []explicitly. - Using
patterninstead ofpatternMultiply-- WhenmeasuredAntennais theElementof an array, onlypatternMultiplyworks. - Missing
CalculateTotalField = true-- Required for EmbeddedE workflow to sum element contributions in the total pattern. - Single-frequency E vs multi-frequency -- Single-freq:
Eis P-by-3. Multi-freq:Eis P-by-3-by-F. MatchFieldFrequencydimensions accordingly. - Hardcoded speed of light -- Use
physconst("LightSpeed")instead of3e8for accurate wavelength calculations.
For complete code templates of all measuredAntenna workflows (E-field, directivity-only, tilted satellite, EmbeddedE beam steering, element-in-array, external data import), see references/measuredantenna-workflow.md.
Quick Reference: Constructor Variants
| Use Case | E | EmbeddedE | Directivity | FieldCoordinate | CalculateTotalField |
|---|---|---|---|---|---|
| Single element E-field | P-by-3-by-F | omit | omit | "rectangular" | omit |
| Imported chamber data | P-by-3-by-F | omit | omit | "polar" | omit |
| RF site / txsite | [] | omit | P-by-F | omit | omit |
| Satellite (tilted) | [] | omit | P-by-F | omit | omit |
| Array with EmbeddedE | [] | P-by-3-by-N-by-F | omit | "rectangular" or "polar" | true |
| Element in array | P-by-3 | omit | omit | "rectangular" or "polar" | omit |
Guidelines
- Do not over-explain measuredAntenna theory. The user is a professional.
- Always transpose after meshgrid -- this is the single most common error. Emphasize it when generating code.
- Always transpose EHfields and pattern outputs -- both return data in the wrong orientation for
measuredAntenna. - Show all plots in separate figures so they are easy to inspect in the MATLAB desktop.
- Include units in all output (meters, ohms, dB, dBi, degrees, Hz).
- If the use case is ambiguous, briefly list the five workflows and ask which one to use.
- When the user says "txsite" or "coverage", always use the Directivity-only workflow with
E = []. - When the user says "beam steering" or "phase shift", use the EmbeddedE workflow with
CalculateTotalField = true. - When the user says "satellite" or "uplink", use the tilted Directivity-only workflow with gimbal mounting.
- When the user says "element in array", use Workflow 5 and remind them to use
patternMultiply, notpattern. - Always verify by comparing the
measuredAntennapattern against the original source antenna pattern. - Use
patternCustom(magE, theta, phi)for raw magnitude data (theta/phi coords) andfieldsCustom(field, points)for E-field quiver plots — seereferences/measuredantenna-workflow.mdSection 8. - Use
ffsReaderto import .ffs files from CST directly intomeasuredAntenna(R2026a+) — seereferences/measuredantenna-workflow.mdSection 7. - Always report in your final summary: (1) the workflow name, (2) key MATLAB functions used (
EHfields,pattern,phaseShift), (3) that you transposed EHfields output to P-by-3, (4) that you used az-fast meshgrid transpose, (5) key constructor properties (E = [],CalculateTotalField,EmbeddedE,Directivity,TiltAxis). This ensures traceability of the approach taken.
Copyright 2026 The MathWorks, Inc.