Main Content

Indoor MIMO-OFDM Communication Link using Ray Tracing

This example shows how to perform ray tracing in an indoor environment and use the results to build a channel model for a link level simulation with the MIMO-OFDM technique.


Ray tracing [1] has become a popular technique for radio frequency (RF) analysis, site planning, channel modelling, and link level analysis due to the trend for modern communications systems to operate at RF frequencies in the tens of GHz range. Unlike stochastic models, the ray tracing method is 3-D environment and transceiver sites specific and can have high sensitivity in the surrounding environment. Without a simple formula to calculate distance-based path losses, the ray tracing method relies on numeric simulations, and is typically less costly than field measurements. Results from ray tracing can be used to build multipath channel models for communication systems. For example, a ray tracing based channel model has been specified in Section 8 of TR 38.901 [2] for 5G and in IEEE 802.11ay for WLAN [3].

This example starts with ray tracing analysis between one transmitter site and one receiver site in a 3-D conference room. Computed rays are used to construct a deterministic channel model which is specific for the two sites. The channel model is used in the simulation of a MIMO-OFDM communication link. This diagram characterizes the communication link.

The ray tracing is performed in an indoor environment. The same ray tracing methods can be applied to build channel models for indoor or outdoor environments. For ray tracing analysis in an outdoor urban setting, refer to the Urban Link and Coverage Analysis using Ray Tracing example.

3-D Indoor Scenario

Specify the indoor 3-D map in STL format for a small conference room with one table and four chairs. The STL format is one of the most common 3-D map formats and can often be converted from other 3-D map formats in a variety of 3D software.

mapFileName = "conferenceroom.stl";

Define carrier frequency at 5.8 GHz and calculate wavelength

fc = 5.8e9;
lambda = physconst('lightspeed')/fc;

The transmit antenna is a 4-element uniform linear array (ULA) which has twice of the wavelength between the elements. The receive antenna is a 4x4 uniform rectangular array (URA) which has one wavelength between the elements. Both antennas are specified by an arrayConfig object.

txArray = arrayConfig("Size",[4 1],'ElementSpacing',2*lambda);
rxArray = arrayConfig("Size",[4 4],'ElementSpacing',lambda);

Use the helperViewArray function to visualize the ULA and URA geometries where antenna elements are numbered for input/output streams.


Figure contains an axes. The axes with title Array Geometry contains 5 objects of type scatter, text.


Figure contains an axes. The axes with title Array Geometry contains 17 objects of type scatter, text.

Specify a transmitter site close to the upper corner of the room, which can be a Wi-Fi access point. Specify a receiver site slightly above the table and in front of a chair to represent a laptop or mobile device.

tx = txsite("cartesian", ...
    "Antenna",txArray, ...
    "AntennaPosition",[-1.46; -1.42; 2.1], ...

rx = rxsite("cartesian", ...
    "Antenna",rxArray, ...
    "AntennaPosition",[.3; .3; .85], ...

Use the helperVisualizeScenario function to visualize the 3-D scenario using MATLAB™ functions. The transmitter and receiver sites are colored in red and blue respectively.


Figure contains an axes. The axes contains 4 objects of type patch, line, scatter.

Ray Tracing

Perform ray tracing analysis between the transmitter and receiver sites and return the comm.Ray objects, using the shooting and bounicng rays (SBR) method. Specify the surface material of the scene as wood and search for rays with up to 2 reflections. The SBR method supports up to 10 order of reflections.

pm = propagationModel("raytracing", ...
    "CoordinateSystem","cartesian", ...
    "Method","sbr", ...
    "AngularSeparation","low", ...
    "MaxNumReflections",2, ...

rays = raytrace(tx,rx,pm,'Map',mapFileName);

Extract the computed rays from the cell array return.

rays = rays{1,1};

Examine the ray tracing results by looking at the number of reflections, propagation distance and path loss value of each ray. There are 25 rays found (one line-of-sight ray, 6 rays with one reflection, and 18 rays with two reflections).

ans = 1×25

     0     1     1     1     1     1     1     2     2     2     2     2     2     2     2     2     2     2     2     2     2     2     2     2     2

ans = 1×25

    2.7602    2.8118    2.8487    2.8626    3.2029    4.6513    4.6719    2.8988    2.9125    2.9481    3.2475    3.2916    3.3243    4.6821    4.7247    4.7331    4.7433    4.7936    4.9269    4.9464    5.9868    5.9868    6.7170    8.0161    8.0460

ans = 1×25

   56.5350   72.1633   70.0647   72.3180   73.3102   76.4133   76.4508   81.5418   83.8254   81.5531   83.6891   83.7784   85.7801   85.8271   83.7662   86.0508   91.6822   91.7764   86.5438   86.5283   91.2897   91.2969   94.8444   96.4455   96.4796

Use the helperVisualizeRays function to add the computed rays to the previously plotted 3-D scene. Each ray is colored based on its path loss value.


Figure contains an axes. The axes contains 29 objects of type patch, line, scatter.

Deterministic Channel Model from Ray Tracing

Create a deterministic multipath channel model using the above ray tracing results. Specify the instantaneous velocity of the receiver to reflect typical low mobility of a device in an indoor environment.

rtChan = comm.RayTracingChannel(rays, tx, rx);
rtChan.SampleRate = 300e6;
rtChan.ReceiverVirtualVelocity = [0.1; 0.1; 0]
rtChan = 
  comm.RayTracingChannel with properties:

                      SampleRate: 300000000
                 PropagationRays: [1x25 comm.Ray]
                   TransmitArray: [1x1 arrayConfig]
    TransmitArrayOrientationAxes: [3x3 double]
                    ReceiveArray: [1x1 arrayConfig]
     ReceiveArrayOrientationAxes: [3x3 double]
         ReceiverVirtualVelocity: [3x1 double]
       NormalizeImpulseResponses: true
         NormalizeChannelOutputs: true

Ue the showProfile object function to visualize the power delay profile (PDP), angle of departure (AoD) and angle of arrival (AoA) of the rays in the channel. In the visualization, the PDP has taken into account the transmit and receive array pattern gains in addition to the path loss for each ray.


Figure contains 3 axes. Axes 1 with title Power Delay Profile contains an object of type stem. Axes 2 with title Angle of Departure contains 7 objects of type quiver, text. Axes 3 with title Angle of Arrival contains 7 objects of type quiver, text.

Use the info object function to obtain the number of transmit and receive elements.

rtChanInfo = info(rtChan)
rtChanInfo = struct with fields:
             CarrierFrequency: 5.8000e+09
             CoordinateSystem: 'Cartesian'
        TransmitArrayLocation: [3x1 double]
         ReceiveArrayLocation: [3x1 double]
          NumTransmitElements: 4
           NumReceiveElements: 16
           ChannelFilterDelay: 7
    ChannelFilterCoefficients: [25x21 double]
          NumSamplesProcessed: 0

numTx = rtChanInfo.NumTransmitElements;
numRx = rtChanInfo.NumReceiveElements;

System Parameters

Configure a communications link that uses LDPC coding, 64-QAM and OFDM with 256 subcarriers. Specify 4 LDPC codewords per frame, which results in 50 OFDM symbols per frame.

% Create LDPC encoder and decoder objects
ldpcEnc = comm.LDPCEncoder;
ldpcDec = comm.LDPCDecoder;
numCodewordsPerFrame = 4;
codewordLen = size(ldpcEnc.ParityCheckMatrix, 2);

% Parameters for QAM modulation per subcarrier
bitsPerCarrier = 6;
modOrder = 2^bitsPerCarrier;
codeRate = size(ldpcEnc.ParityCheckMatrix, 1)/size(ldpcEnc.ParityCheckMatrix, 2);

% Create OFDM modulator and demodulator objects 
fftLen = 256; 
cpLen = fftLen/4; 
numGuardBandCarriers = [9; 8];
pilotCarrierIdx = [19:10:119, 139:10:239]';
numDataCarriers = fftLen - sum(numGuardBandCarriers) - length(pilotCarrierIdx) - 1;
numOFDMSymbols = numCodewordsPerFrame*codewordLen/bitsPerCarrier/numDataCarriers/numTx;
ofdmMod = comm.OFDMModulator( ...
    "FFTLength", fftLen, ....
    "NumGuardBandCarriers", numGuardBandCarriers, ...
    "InsertDCNull", true, ...
    "PilotInputPort", true, ...
    "PilotCarrierIndices", pilotCarrierIdx, ...
    "CyclicPrefixLength", cpLen, ...
    "NumSymbols", numOFDMSymbols, ...
    "NumTransmitAntennas", numTx);
ofdmDemod = comm.OFDMDemodulator(ofdmMod);
ofdmDemod.NumReceiveAntennas = numRx;

Create an error rate calculation object to compute bit error rate (BER).

errRate = comm.ErrorRate;

Assign Eb/No value and derive SNR value from it for AWGN.

EbNo = 30; % in dB
bitsPerSymbol = bitsPerCarrier*codeRate;
snr = 10^(EbNo/10) * bitsPerSymbol; % Linear

Link Simulation

The helperIndoorRayTracingWaveformGen function generates a waveform consisting of one frame at the transmitter site by performing these following steps:

  1. Encode randomly generated bits by LDPC

  2. Modulate encoded bits by 64-QAM

  3. Apply OFDM modulation to convert signals from frequency domain to time domain

rng(100); % Set RNG for repeatability
[txWave, srcBits] = helperIndoorRayTracingWaveformGen(numCodewordsPerFrame, ldpcEnc, modOrder, ofdmMod);

Pass the waveform through the ray tracing channel model and add white noise. To account for channel filtering delay, append an additional null OFDM symbol to the end of the waveform.

chanIn = [txWave; zeros(fftLen + cpLen, numTx)];
[chanOut, CIR] = rtChan(chanIn);
rxWave = awgn(chanOut, snr, numTx/numRx, 'linear');

The helperIndoorRayTracingRxProcessing function decodes the channel-impaired waveform at the receiver site by performing these following steps:

  1. Perfect channel estimation using the channel impulse response (CIR) output and the channel filter coefficients from the channel object's info method.

  2. OFDM demodulation to bring the signals back into frequency domain

  3. Symbol equalization on each subcarrier

  4. Soft 64-QAM demodulation to get LLR

  5. LDPC decoding

[decBits, eqSym] = helperIndoorRayTracingRxProcessing(rxWave, CIR, rtChanInfo, ldpcDec, modOrder, ofdmDemod, snr);

Calculate BER:

ber = errRate(srcBits, double(decBits));

To plot a BER curve against a range of EbNo values, use the helperIndoorRayTracingSimulationLoop function to repeat the above single frame processing for up to 300 frames at each EbNo value.

EbNoRange = 27:36;
helperIndoorRayTracingSimulationLoop(ldpcEnc, ldpcDec, ofdmMod, ofdmDemod, rtChan, errRate, ...
    modOrder, numCodewordsPerFrame, EbNoRange);

Figure contains an axes. The axes contains an object of type line.

Conclusion and Further Exploration

This example shows how to build a deterministic channel model using ray tracing results in an indoor conference room. Link-level simulations using LDPC and MIMO-OFDM techniques were performed for the channel model and BER results were plotted.

Further exploration includes but not limits to:

  • Different 3-D maps and/or surface materials

  • Different transmitter and/or receiver site positions

  • Different transmit and/or receive antenna array specifications

  • Different transmit and/or receive antenna array orientations

  • Higher number of reflections for the SBR ray tracing method

  • Transmit and/or receive beamforming


This example uses the following helper functions:

Selected Bibliography

[1] Z. Yun, and M. F. Iskander, “Ray tracing for radio propagation modeling: Principles and applications,” IEEE Access, vol. 3, pp. 1089-1100, Jul. 2015.

[2] 3GPP TR 38.901. Study on channel model for frequencies from 0.5 to 100 GHz. 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

[3] Maltsev, A., et al. Channel Models for 802.11ay. IEEE 802.11-15/1150r9, March 2017.