Main Content

Antenna Alignment for Wireless Communications Link

R2026b
Since R2026b

This example shows how to align antennas in a line-of-sight (LOS) wireless communication link to ensure adequate received signal strength. This example does not consider environments dominated by non-LOS propagation, where the optimal orientation instead corresponds to the strongest reflected or diffracted path.

When antennas used in wireless communications are directional, they must be oriented correctly for the link to operate as intended. In some links, both antennas are directional. In others, one antenna is directional while the other is omnidirectional. Some antennas can also be steered, either physically or electronically whereas others have fixed orientation. Consider a cellular network base station, its antenna likely has fixed physical orientation that can be steered electronically. The UEs that communicate with that base station are likely mobile, moving in both translation and rotation, and present a challenge to maintain optimal physical transmit-receive antenna alignment.

In many wireless applications, an antenna is implemented as an antenna array, which enables electronic beam steering. For simplicity, assume the array is mounted on a flat surface. The array pointing direction can then be represented by the unit vector normal to that surface. It is typical in MathWorks toolboxes that antennas default to facing due east (using geographic coordinates) or positive x-axis (using Cartesian coordinates).

In the wireless domain, the antenna beam orientation, also known as pointing direction, is often described using azimuth and elevation angles. This is similar to the horizontal coordinate system described in [1]. Azimuth and elevation specify the pointing direction of the array normal. Together with a rotation about the pointing axis (roll), they form a complete 3-D orientation description. The azimuth angle is equivalent to a compass direction and is typically in the interval [–180, 180] degrees, often defaulting to 0 (or due east). The angle between the array pointing direction and the surface of the earth is known as elevation. The elevation angle is typically in the interval [–90, 90]. These same terms are used in the graphics arena to determine display orientation as described in Setting the Viewpoint with Azimuth and Elevation. In addition to the azimuth and elevation pointing direction angles, a third rotation angle defines orientation around the axis along the antenna pointing direction. The rotation angle is important for simulations that consider antenna polarization. Antenna orientation angles correspond to the aircraft principal axes (yaw, pitch, and roll) as described in [2]. Specifically,

  • Azimuth correlates to yaw.

  • Elevation correlates to pitch.

  • Rotation correlates to roll.

To orient the antenna within a scene, specify azimuth and elevation relative to the global coordinate system (GCS). In contrast, the local coordinate system (LCS) is useful when describing antenna gain relative to the antenna's current pointing direction. Throughout this example, antenna positions are specified in GCS, while antenna patterns are often interpreted in the antenna LCS.

Occasionally you must convert between orientation angles and the array-normal representation. To do this, represent the normal vector using a rotation matrix, which yields the desired normal vector when multiplied by the unit vector from the default orientation (typically [1; 0; 0]).

Rotations in Two Dimensions

Begin by considering how to mathematically represent the operation of rotating a unit vector from an initial condition in both azimuth and elevation by a prescribed amount relative to a desired orientation in the GCS. Specifically, multiplying a complex number v by ejθ rotates the vector by θ radians in the complex plane while preserving its magnitude.

v = 1;
thetaDegrees = 45;
theta = thetaDegrees * pi / 180;
zCplx = exp(1i * theta) * v
zCplx = 
0.7071 + 0.7071i

Express the rotation as separated real and imaginary values.

zRe = cos(theta) * real(v) - sin(theta) * imag(v)
zRe = 
0.7071
zIm = sin(theta) * real(v) + cos(theta) * imag(v)
zIm = 
0.7071

Express the rotation as separated real and imaginary in matrix form.

z2d = [cos(theta) -sin(theta); sin(theta) cos(theta)] * [real(v); imag(v)]
z2d = 2×1

    0.7071
    0.7071

You can use the matrix representation in any 2-D Cartesian visualization of the complex plane.

Rotations in Three Dimensions

Such 2-D rotations can be embedded into 3-by-3 matrices to represent orientation in the 3-D physical world where they can also be accumulated. Because matrix multiplication is order dependent, apply the elevation rotation before the azimuth rotation. For example, this code rotates a starting vector v from due east to a given elevation, elAngle, rotating in xz plane around the y-axis. Next, apply an azimuth rotation about the z-axis.

v = [1; 0; 0];
elAngle = 10; % Degrees
rotEl = [cosd(elAngle) 0 -sind(elAngle); ...
    0 1 0; ...
    sind(elAngle) 0 cosd(elAngle)] % Same as roty(-elAngle)
rotEl = 3×3

    0.9848         0    -0.1736
         0    1.0000          0
    0.1736         0     0.9848

azAngle = 30; % Degrees
rotAz = [cosd(azAngle) -sind(azAngle) 0; ...
    sind(azAngle) cosd(azAngle) 0; ...
    0 0 1] % Same as rotz(azAngle)
rotAz = 3×3

    0.8660    -0.5000         0
    0.5000     0.8660         0
         0          0    1.0000

totalRot = rotAz * rotEl;
z = totalRot * v;

The three-element vectors v and z represent a point in space.

Use the quiver or quiver3 functions to visualize these rotations.

myThetaDegrees = 45; % degrees
myTheta = myThetaDegrees * pi / 180;
z1 = 1; % initial vector
z2 = z1 * exp(sqrt(-1) * myTheta); % Rotate original vector by myTheta
hold off
quiver(0,0,real(z1),imag(z1),AutoScale=false)
axis equal;axis([-0.1 1 -0.1 1])
hold on
quiver(0,0,real(z2),imag(z2),0)
legend("original","rotated")

Figure contains an axes object. The axes object contains 2 objects of type quiver. These objects represent original, rotated.

Specify orientation of comm.RayTracingChannel

Several System objects in wireless communications toolboxes require antenna orientation information. For example:

  • The TransmitArrayOrientationAxes and ReceiveArrayOrientationAxes properties in the comm.RayTracingChannel System object™ specify 3-by-3 rotation matrices to define the pointing direction.

  • The AntennaAngle property in the txsite and rxsite objects specifies a 2-by-1 vector that defines the azimuth and elevation in degrees.

  • The txsite and rxsite objects also include the angleobject function to compute azimuth and elevation between two sites.

The comm.RayTracingChannel object includes a syntax that accepts the txsite and rxsite objects as arguments and performs this coordinate-system conversion. This example includes a local function, rotAzEl(azAngle,elAngle), to demonstrate how the ray tracing channel object performs the coordinate system conversion.

Output the coordinate system conversion from txsite to antenna array coordinates by using the comm.RayTracingChannel object syntax. Then use the rotAzEl local function to compute the rotation matrices, rotMat, for the TransmitArrayOrientationAxes property required by the ray tracing channel object. The two approaches achieve the same result.

myChan = comm.RayTracingChannel(comm.Ray,txsite(AntennaAngle=[azAngle;elAngle]),rxsite);
myChan.TransmitArrayOrientationAxes
ans = 3×3

    0.8529    -0.5000    -0.1504
    0.4924     0.8660    -0.0868
    0.1736          0     0.9848

rotMat = rotAzEl(azAngle,elAngle)
rotMat = 3×3

    0.8529    -0.5000    -0.1504
    0.4924     0.8660    -0.0868
    0.1736          0     0.9848

Physically Steering Antennas

Antennas placed in a setting must define an initial position and orientation with respect that location and scene. This example shows an antenna array whose element phases are adjusted to form an electronically steered beam. Alternately the antenna may be mounted in a fixed unchanging orientation or a gimbal that allows it to be physically steered. This code sample uses Cartesian coordinates with ENU coordinate system convention, but the concepts apply when working with geographic coordinates. When starting with geographic coordinates, functions such as geodetic2enu (Mapping Toolbox), ecefOffset (Mapping Toolbox), and latlon2local (Automated Driving Toolbox) may be used to convert to Cartesian and then continue as above.

Define the transmitter and receiver location as TxLoc and RxLoc, respectively. Represent the separation between the transmitter and receiver by the vector v. The transmit and receive antenna locations are defined but orientation with respect to one another is not defined.

TxLoc = [10 2 0];
RxLoc = [1 -1 -5];
v = RxLoc - TxLoc
v = 1×3

    -9    -3    -5

Given the transmitter and receiver positions, compute the azimuth and elevation angles such that the antennas point directly at each other along the LOS path. Convert the displacement vector v to azimuth and elevation angles.

The azimuth angle is the angle from the x-axis to the projection of v onto the xy-plane.

TxAz = atan2(v(2),v(1))
TxAz = 
-2.8198

The elevation angle is the angle between v and the xy-plane.

TxEl = atan2(v(3),sqrt(v(2)*v(2) + v(1)*v(1)))
TxEl = 
-0.4850

Alternatively, you can use the cart2sph function to output the desired azimuth and elevation angles in radians.

[TxAz, TxEl]= cart2sph(v(1), v(2), v(3))
TxAz = 
-2.8198
TxEl = 
-0.4850

To point the transmitter and receiver antenna pattern peaks toward each other, the receiver must point in the opposite direction of the transmitter. Specifically, if the transmitter is oriented in the direction v, the receiver must be oriented in the direction –v.

RxAz = TxAz + pi
RxAz = 
0.3218
RxEl = -TxEl
RxEl = 
0.4850

Use siteviewer, together with the pattern and show functions to visualize transmitter and receiver antenna orientations and radiation patterns. Visualize a configuration with transmit and receive antennas not aligned. Adjust the antenna orientations to point toward each other, and then visualize the orientations again.

sv = siteviewer(SceneModel="none");
nelem = 50;
fc = 6e9;
lambda = physconst("LightSpeed") / fc;
txArray = phased.URA(Element=phased.ShortDipoleAntennaElement, ...
    Size=[nelem nelem], ...
    ElementSpacing=0.5*lambda);
myTx = txsite(TransmitterFrequency=fc, ...
    Antenna=txArray, ...
    CoordinateSystem="cartesian", ...
    AntennaPosition=TxLoc);
show(myTx,ShowAntennaHeight=false)
pattern(myTx)
rxArray = phased.URA(Element=phased.ShortDipoleAntennaElement, ...
    Size=[nelem nelem], ...
    ElementSpacing=0.5*lambda);
myRx = rxsite(Antenna=rxArray, CoordinateSystem="cartesian", ...
    AntennaPosition=RxLoc);
show(myRx,ShowAntennaHeight=false)
pattern(myRx,fc)
disp("Antennas not aligned")
Antennas not aligned

Siteviewer plot showing antennas that are not aligned to point at each other.

Use the AntennaAngle property of txsite and rxsite to point the antennas at each other.

myTx.AntennaAngle=[TxAz;TxEl]*180/pi; % Convert angles to degrees
myRx.AntennaAngle=[RxAz;RxEl]*180/pi; % Convert angles to degrees
pattern(myTx)
pattern(myRx,fc)
disp("Antennas now pointing at each other.")
Antennas now pointing at each other.

Siteviewer plot showing antennas that are aligned to point at each other.

Electronic Beamsteering

Suppose that the transmitter must retarget its beam dynamically during operation to point toward a second receiver. Define a second receiver location and electronically steer the transmit array between the two receivers. Use phased.SteeringVector (Phased Array System Toolbox) System object™ to create complex weights to use for electronically steering the transmitter array towards either receiver. The phased.SteeringVector object requires azimuth and elevation angles, so convert the transmitter-to-receiver displacement vectors into angular coordinates.

% Reset the scenario:
myTx.AntennaAngle = [0;0];
myRx.AntennaAngle = [0;0];
% Make new siteviewer
sv2 = siteviewer(SceneModel="none");
% Specify a second receiver
RxLoc2 = [1 -1  5];
myRx2 = rxsite(Antenna=rxArray, ...
    CoordinateSystem="cartesian", ...
    AntennaPosition=RxLoc2);
show(myRx2, ShowAntennaHeight=false)
show(myRx, ShowAntennaHeight=false)
show(myTx, ShowAntennaHeight=false)
svObj = phased.SteeringVector(SensorArray=txArray);
z = RxLoc2 - TxLoc;
az = atan2d(z(2),z(1))
az = 
-161.5651
el = atan2d(z(3),sqrt(z(1)^2 + z(2)^2))
el = 
27.7913
sv1 = svObj(fc,[az; -el]);
myTx.Antenna.Taper = conj(sv1); % conjugate because steering vector returns weights for receive beamforming
pattern(myTx)
disp("Tx array is electronically steered towards the 1st receiver (xyz = [1 -1 -5]).")
Tx array is electronically steered towards the 1st receiver (xyz = [1 -1 -5]).

Siteviewer plot showing transmit antenna electronically steered to point a beam peak at the first receiver but not at the second receiver.

The extra lobe is due to an ambiguity in 2-D arrays. The delays are the same for a signal coming from the back side as from the front. Now steer towards the second receiver.

sv2 = svObj(fc,[az; el]);
myTx.Antenna.Taper = conj(sv2);
pattern(myTx)
disp("Tx array is electronically steered towards the second receiver (xyz = [1 -1  5]).")
Tx array is electronically steered towards the second receiver (xyz = [1 -1  5]).

Siteviewer plot showing transmit antenna electronically steered to point a beam peak at the second receiver but not at the first receiver.

Compute the rotation matrices for transmitter and receiver.

txrotmat = rotAzEl(az,el); % If Tx points north, then Rx must point south
rxrotmat = rotAzEl(az+180,-el); % if Tx points up, then Rx must point down

Antenna Polarization

For simulations that account for antenna polarization, you must consider antenna rotation. Define transmit and receive sites with identical rectangular panel arrays. For the propagation model consider LOS only.

txArray = phased.NRRectangularPanelArray( ...
    ElementSet={phased.NRAntennaElement(PolarizationAngle=45)});
txs = txsite(Antenna=txArray, ...
    CoordinateSystem="Cartesian", ...
    AntennaPosition=[0;0;0]);
rxArray = phased.NRRectangularPanelArray( ...
    ElementSet={phased.NRAntennaElement(PolarizationAngle=45)});
rxs = rxsite(Antenna=rxArray, ...
    CoordinateSystem="Cartesian", ...
    AntennaPosition=[1e3;0;0]);
pm = propagationModel("raytracing", ...
    MaxNumReflections=0, ...
    CoordinateSystem="cartesian");
losRay = raytrace(txs,rxs,pm);

Results below show this is a mistake because the transmit and receive polarization orientations must be configured to maintain polarization matching. The polarization mismatch for this configuration results in excessive path loss.

losRay{1}.PathLoss
ans = 
752.5642

Correct the mismatch by setting the receiver polarization to –45 degrees. The path loss is now representative of the distance between the transmitter and receiver.

rxArray = phased.NRRectangularPanelArray( ...
    ElementSet={phased.NRAntennaElement(PolarizationAngle=-45)});
rxs = rxsite(Antenna=rxArray, ...
    CoordinateSystem="Cartesian", ...
    AntennaPosition = [1e3;0;0]);
pm = propagationModel("raytracing", ...
    MaxNumReflections=0, ...
    CoordinateSystem="cartesian")
pm = 
  RayTracing with properties:

       CoordinateSystem: "cartesian"
                 Method: "sbr"
      AngularSeparation: "medium"
      MaxNumReflections: 0
     MaxNumDiffractions: 0
    MaxAbsolutePathLoss: Inf
    MaxRelativePathLoss: 40
                 UseGPU: "off"
        SurfaceMaterial: "auto"

losRay = raytrace(txs,rxs,pm);
losRay{1}.PathLoss
ans = 
98.0229

Polarization angle is defined with respect to the propagation direction. Because the transmitter and receiver face one another, equivalent physical polarization often requires opposite polarization-angle settings. Consequently, when a transmitter uses a polarization angle of +θ, the receiver typically requires a polarization angle of −θ to achieve polarization alignment.

txArray = phased.NRAntennaElement(PolarizationAngle = 45);
rxArray = phased.NRAntennaElement(PolarizationAngle = -45);

Similar notions apply if you are using more realistic antenna elements like phased.ShortDipoleAntennaElement (Phased Array System Toolbox) or phased.CrossedDipoleAntennaElement (Phased Array System Toolbox).

Summary

This example demonstrated how antenna orientation affects wireless link performance. It examines physical alignment, electronic beam steering, coordinate-system conversions, rotation matrices, and polarization alignment. Correctly accounting for each of these factors helps maximize received signal strength and maintain reliable link operation.

References

[1] Horizontal coordinate system - Wikipedia

[2] Aircraft principal axes - Wikipedia

Utility functions

function rotMat = rotAzEl(azAngle,elAngle) % Input angles in degrees
caz = cosd(azAngle);
saz = sind(azAngle);
cel = cosd(elAngle);
sel = sind(elAngle);
rotaz = [caz -saz 0; saz caz 0; 0 0 1]; % Azimuth or "yaw"
rotel = [cel 0 -sel; 0 1 0; sel 0 cel]; % Elevation or "pitch"
rotMat = rotaz * rotel;
end

Copyright 2026 The MathWorks, Inc.

See Also

Functions

Objects

Topics