gusucode.com > wlan工具箱matlab源码程序 > wlan/wlanexamples/VHTMUMIMOPrecodingExample.m

    %% 802.11ac Multi-User MIMO Precoding
%
% This example shows the transmit and receive processing for a 802.11ac(TM)
% multi-user downlink transmission over a fading channel. The example uses
% linear precoding techniques based on a singular-value-decomposition (SVD)
% of the channel.

%% Introduction
%
% 802.11ac supports downlink (access-point to station) multi-user
% transmissions for up to four users and up to eight transmit antennas to
% increase the aggregate throughput of the link [ <#16 1> ]. Based on a
% scheduled transmission time for a user, the scheduler looks for other
% smaller packets ready for transmission to other users. If available, it
% schedules these users over the same interval, which reduces the overall
% time it takes for multiple transmissions.
%
% This simultaneous transmission comes at a higher complexity as the
% successful reception of the individual user's payloads requires
% precoding, also known as transmit-end beamforming. Precoding assumes that
% channel state information (CSI) is known at the transmitter. Similar to
% the <VHTBeamformingExample.html 802.11ac Transmit Beamforming> example, a
% sounding packet is used to determine the CSI for each user in a
% multi-user transmission. Each of the users feed back their individual
% CSI, which is then used at the transmitter to set the precoding (spatial
% mapping) matrix for subsequent data transmission.
%
% This example uses a channel inversion technique for a three-user
% transmission with a different number of spatial streams allocated per
% user and different rate parameters per user. The system can be
% characterized by the figure below.
%
% <<vhtMUMIMODiagram.png>>
%
% The example generates the multi-user transmit waveform, passes it through
% a channel per user and decodes the received signal for each user to
% calculate the bits in error. Prior to the data transmission, the example
% uses a null-data packet (NDP) transmission to sound the different
% channels and determines the precoding matrix under the assumption of
% perfect feedback.

%% Simulation Parameters and Configuration
% For 802.11ac, a maximum of eight spatial streams is allowed. An 8x8 MIMO
% configuration for three users is used in this example, where the first
% user has three streams, second has one, and the third has four
% streams allocated to it. Different rate parameters and payload sizes 
% for each user are specified as vector parameters for the transmission
% configuration.

s = rng(21);                             % Set RNG seed for repeatability

% Transmission parameters
chanBW      = 'CBW80';                   % Channel bandwidth
numUsers    = 3;                         % Number of users
numSTSVec   = [3 1 4];                   % Number of streams per user
userPos     = [0 1 2];                   % User positions
mcsVec      = [4 6 2];                   % MCS per user: 16QAM, 64QAM, QPSK
apepVec     = [3024 8192 2464];          % Payload per user, in bytes
chCodingVec = {'BCC', 'LDPC', 'LDPC'};   % Channel coding per user

% Channel and receiver parameters
chanMdl       = 'Model-A';               % TGac fading channel model
precodingType = 'ZF';                    % Precoding type
snr           = 35;                      % SNR in dB
eqMethod      = 'ZF';                    % Equalization method

% Create the multi-user VHT format configuration object
numTx = sum(numSTSVec);    
cfgVHTMU = wlanVHTConfig('ChannelBandwidth', chanBW,...
    'NumUsers', numUsers, ...
    'NumTransmitAntennas', numTx, ...
    'GroupID', 2, ...
    'NumSpaceTimeStreams', numSTSVec,...
    'UserPositions', userPos, ...
    'MCS', mcsVec, ...
    'APEPLength', apepVec, ...
    'ChannelCoding', chCodingVec);

%%
% The number of transmit antennas is set to be the sum total of all the
% used space-time streams. This implies no space-time block coding (STBC)
% or spatial expansion is employed for the transmission.

%% Sounding (NDP) Configuration
% 
% For precoding, channel sounding is first used to determine the channel
% experienced by the users (receivers). This channel state information is
% sent back to the transmitter, for it to be used for subsequent data
% transmission. It is assumed that the channel varies slowly over the two
% transmissions. For multi-user transmissions, the same NDP (Null Data
% Packet) is transmitted to each of the scheduled users [ <#16 2> ].

% VHT sounding (NDP) configuration, for same number of streams
cfgVHTNDP = wlanVHTConfig('ChannelBandwidth', chanBW,...
    'NumUsers', 1, ...
    'NumTransmitAntennas', numTx, ...
    'GroupID', 0, ...
    'NumSpaceTimeStreams', sum(numSTSVec),...
    'MCS', 0, ...
    'APEPLength', 0);

%%
% The number of streams specified is the sum total of all space-time
% streams used, so as to sound the complete channel.

% Generate the null data packet, with no data
txNDPSig = wlanWaveformGenerator([], cfgVHTNDP);

%% Transmission Channel
%
% The TGac multi-user channel consists of independent single-user MIMO
% channels between the access point and spatially separated stations [ <#16
% 4> ]. In this example, the same delay profile Model-A channel is applied
% for each of the users, even though individual users can experience
% different conditions. The flat-fading channel allows a simpler receiver
% without front-end synchronization. It is also assumed that each user's
% number of receive antennas are equal to the number of space-time streams
% allocated to them. 
%
% Cell arrays are used in the example to store per-user elements which
% allow for a flexible number of users. Here, as an example, each instance
% of the TGac channel per user is stored as an element of a cell array.

% Create three independent channels with respective receive antennas
TGAC      = cell(numUsers, 1);
chanSeeds = [1111 2222 3333 4444];  % chosen for a maximum of 4 users
uIndex    = [10 5 2 1];             % chosen for a maximum of 4 users
chanDelay = zeros(numUsers, 1);
for uIdx = 1:numUsers
    TGAC{uIdx} = wlanTGacChannel(...
        'ChannelBandwidth', cfgVHTMU.ChannelBandwidth,...
        'DelayProfile', chanMdl, ...
        'UserIndex', uIndex(uIdx), ...
        'NumTransmitAntennas', numTx, ...
        'NumReceiveAntennas', numSTSVec(uIdx), ...
        'RandomStream', 'mt19937ar with seed', ...
        'Seed', chanSeeds(uIdx),...
        'SampleRate', helperSampleRate(chanBW));
    chanInfo = info(TGAC{uIdx});
    chanDelay(uIdx) = chanInfo.ChannelFilterDelay;
end
 
%%
% The channels for each individual user use different seeds for random
% number generation. A different user index is specified to allow for
% random angle offsets to be applied to the arrival (AoA) and departure
% (AoD) angles for the clusters. The channel filtering delay is stored
% to allow for its compensation at the receiver. In practice, symbol timing
% estimation would be used.

% Sound the independent channels per user for all transmit streams
rxNDPSig = cell(numUsers, 1);
for uIdx = 1:numUsers
    % Append zeroes to allow for channel filter delay
    rxNDPSig{uIdx} = TGAC{uIdx}([txNDPSig; zeros(10, numTx)]);
end

%% Channel State Information Feedback
%
% Each user estimates its own channel using the received NDP signal and
% computes the channel state information that it can send back to the
% transmitter. This example uses the singular value decomposition of the
% channel seen by each user to compute the CSI feedback. 

mat = cell(numUsers,1);
for uIdx = 1:numUsers
    % Add WGN per receiver
    rxNDPNsig = awgn(rxNDPSig{uIdx}, snr);

    % Compute the feedback matrix based on received signal per user
    mat{uIdx} = vhtCSIFeedback(rxNDPNsig(chanDelay(uIdx)+1:end,:), ...
        cfgVHTNDP, uIdx, numSTSVec);
end

%% 
% Assuming perfect feedback with no compression or quantization loss, the
% transmitter computes the steering matrix for the data transmission using
% either Zero-Forcing or Minimum-Mean-Square-Error (MMSE) based precoding
% techniques. Both methods attempt to cancel out the intra-stream
% interference for the user of interest and interference due to other
% users. The MMSE-based approach avoids the noise enhancement inherent in
% the zero-forcing technique. As a result, it performs better at low SNRs.

% Pack the per user CSI into a matrix
numST = length(mat{1});         % Number of subcarriers
steeringMatrix = zeros(numST, sum(numSTSVec), sum(numSTSVec)); 
%   Nst-by-Nt-by-Nsts
for uIdx = 1:numUsers
    stsIdx = sum(numSTSVec(1:uIdx-1))+(1:numSTSVec(uIdx));
    steeringMatrix(:,:,stsIdx) = mat{uIdx};     % Nst-by-Nt-by-Nsts
end

if strcmp(precodingType, 'ZF')
    % Zero-forcing precoding solution (channel inverse)
    for i = 1:numST
        h = squeeze(steeringMatrix(i,:,:));
        steeringMatrix(i,:,:) = h/(h'*h); 
    end
else
    % MMSE precoding solution (regularized channel inverse)
    delta = (numTx/(10^(snr/10))) * eye(numTx);
    for i = 1:numST
        h = squeeze(steeringMatrix(i,:,:));
        steeringMatrix(i,:,:) = h/(h'*h + delta); 
    end
end

% Set the spatial mapping based on the steering matrix
cfgVHTMU.SpatialMapping = 'Custom';
cfgVHTMU.SpatialMappingMatrix = permute(steeringMatrix,[1 3 2]); 

%% Data Transmission
%
% Random bits are used as the payload for the individual users. A cell
% array is used to hold the PSDUs for each user. Using the format
% configuration with the steering matrix, the data is transmitted over the
% fading channel.

% Create data sequences, one for each user
d = cell(numUsers, 1); dp = d;
for uIdx = 1:numUsers
    d{uIdx} = randi([0 1], cfgVHTMU.APEPLength(uIdx)*8, 1, 'int8');
    
    % Zero-pad to PSDU length per user
    dp{uIdx} = [d{uIdx}; ...
        zeros(cfgVHTMU.PSDULength(uIdx)*8-length(d{uIdx}), 1, 'int8')];
end

% Generate the multi-user VHT waveform
txSig = wlanWaveformGenerator(dp, cfgVHTMU);

% Transmit through per-user fading channel 
rxSig = cell(numUsers, 1);
for uIdx = 1:numUsers
    % Append zeroes to allow for channel filter delay
    rxSig{uIdx} = TGAC{uIdx}([txSig; zeros(10, numTx)]);
end

%% Data Recovery Per User
%
% The receive signals for each user are processed individually. The example
% assumes that there are no front-end impairments and that the transmit
% configuration is known by the receiver for simplicity.
%
% A user number specifies the user of interest being decoded for the
% transmission. This is also used to index into the vector properties of
% the configuration object that are user-specific.

% Configure recovery object 
cfgRec = wlanRecoveryConfig('EqualizationMethod', eqMethod, ...
    'PilotPhaseTracking', 'None');

% Get parameters from configuration, assumed known at receiver
numSTSVec = cfgVHTMU.NumSpaceTimeStreams;
ind = wlanFieldIndices(cfgVHTMU);

% Single-user receivers recover payload bits
rxDataBits = cell(numUsers, 1);
for uIdx = 1:numUsers
    % Add WGN per receiver
    rxNSig = awgn(rxSig{uIdx}, snr);
    rxNSig = rxNSig(chanDelay(uIdx)+1:end, :);

    % User space-time streams
    stsU = numSTSVec(uIdx);

    % Estimate noise power in VHT fields
    lltf = rxNSig(ind.LLTF(1):ind.LLTF(2),:);
    demodLLTF = wlanLLTFDemodulate(lltf, chanBW);
    nVar = helperNoiseEstimate(demodLLTF, chanBW, stsU);

    % Perform channel estimation based on VHT-LTF
    rxVHTLTF  = rxNSig(ind.VHTLTF(1):ind.VHTLTF(2),:);
    demodVHTLTF = wlanVHTLTFDemodulate(rxVHTLTF, chanBW, numSTSVec);
    chanEst = wlanVHTLTFChannelEstimate(demodVHTLTF, chanBW, numSTSVec);

    % Recover information bits in VHT Data field
    rxVHTData = rxNSig(ind.VHTData(1):ind.VHTData(2),:);
    [rxDataBits{uIdx}, ~, eqsym] = wlanVHTDataRecover(rxVHTData, ...
        chanEst, nVar, cfgVHTMU, uIdx, cfgRec);

    % Plot equalized symbols for all streams (Nss) per user 
    h = figure;
    h.Name = ['User ' num2str(uIdx) ' Equalized Symbols'];
    scaler = ceil(max(abs([real(eqsym(:)); imag(eqsym(:))])));
    for i = 1:stsU
        if stsU>2
            subplot(2, 2, i);
        else
            subplot(stsU, 1, i);
        end
        plot(reshape(eqsym(:,:,i), [], 1), '.'); grid on;
        xlim([-scaler scaler]);
        ylim([-scaler scaler]);
        title(['User ' num2str(uIdx) ', Stream ' num2str(i)]);
        xlabel('Real'); ylabel('Imag');
    end    
end

%%
% Per-stream equalized symbol constellation plots validate the simulation
% parameters and convey the effectiveness of the technique. Note the
% discernible 16QAM, 64QAM and QPSK constellations per user as specified on
% the transmit end. Also observe the EVM degradation over the different
% streams for an individual user. This is representative characteristic of
% the channel inversion technique.
%
% The recovered data bits are compared with the transmitted payload bits to
% determine the bits in error.

% Compare recovered bits against per-user APEPLength information bits
numerr = inf(1, numUsers);
for uIdx = 1:numUsers
    idx = (1:cfgVHTMU.APEPLength(uIdx)*8).';
    numerr(uIdx) = biterr(d{uIdx}(idx), rxDataBits{uIdx}(idx));
    disp(['Bit Errors for User ' num2str(uIdx) ': ' ...
        num2str(numerr(uIdx))]);
end

rng(s); % Restore RNG state

%% 
% The small number of bit errors, within noise variance, indicates
% successful data decoding for all streams for each user, despite the
% variation in EVMs seen per user streams.

%% Conclusion and Further Exploration
%
% The example shows multi-user transmit configuration, independent
% per-user channel modeling, and the individual receive processing using
% the channel inversion precoding techniques.
%
% Further exploration includes modifications to the transmission and
% channel parameters, alternate precoding techniques, more realistic
% receivers and feedback mechanism incorporating delays and quantization.
%
% A receiver function <matlab:edit('vhtSingleUserRxSigRec.m')
% vhtSingleUserRxSigRec.m>, which employs preamble field recovery to
% determine the transmitted configuration, is provided. This function
% assumes knowledge of only the channel bandwidth and transmission format
% and recovers other transmission parameters from the signaling fields of
% the VHT packet.

%% Appendix
% This example uses the following helper functions:
%
% * <matlab:edit('helperSampleRate.m') helperSampleRate.m>
% * <matlab:edit('helperFieldLengths.m') helperFieldLengths.m>
% * <matlab:edit('vhtCSIFeedback.m') vhtCSIFeedback.m>
% * <matlab:edit('vhtSingleUserRxSigRec.m') vhtSingleUserRxSigRec.m>

%% Selected Bibliography
% # IEEE Std 802.11ac(TM)-2013 IEEE Standard for Information technology -
% Telecommunications and information exchange between systems - Local and
% metropolitan area networks - Specific requirements - Part 11: Wireless
% LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications -
% Amendment 4: Enhancements for Very High Throughput for Operation in Bands
% below 6 GHz.
% # Perahia, E., R. Stacey, "Next Generation Wireless LANS: 802.11n and
% 802.11ac", Cambridge University Press, 2013.
% # IEEE Std 802.11(TM)-2012 IEEE Standard for Information technology -
% Telecommunications and information exchange between systems - Local and
% metropolitan area networks - Specific requirements - Part 11: Wireless
% LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications.
% # Breit, G., H. Sampath, S. Vermani, et al., "TGac Channel Model
% Addendum", Version 12. IEEE 802.11-09/0308r12, March 2010.

displayEndOfDemoMessage(mfilename)