Этот пример показывает обработку передачи и приема для 802.11ac™ многопользовательской нисходящей передачи по замирающему каналу. В примере используются методы линейного предварительного кодирования, основанные на сингулярном разложении (SVD) канала.
802.11ac поддерживает нисходящие (точка доступа - станция) многопользовательские передачи для до четырех пользователей и до восьми передающих антенн для увеличения совокупной пропускной способности ссылки [1]. На основе запланированного времени передачи для пользователя планировщик ищет другие меньшие пакеты, готовые к передаче другим пользователям. При наличии он планирует этих пользователей на том же интервале, что уменьшает общее время, затрачиваемое на несколько передач.
Эта одновременная передача имеет более высокую сложность, потому что успешный прием полезных нагрузок индивидуального пользователя требует предварительного кодирования, также известного как формирование луча на конце передачи. Предварительное кодирование принимает, что информация о состоянии канала (CSI) известна в передатчике. Зондирующий пакет, как описано в примере 802.11ac Transmit Beamforming, используется для определения CSI для каждого пользователя в многопользовательской передаче. Каждый из пользователей осуществляет обратную связь своего отдельного CSI с beamformer. Beamformer использует CSI от всех пользователей, чтобы задать матрицу предварительного кодирования (пространственное отображение) для последующей передачи данных.
Этот пример использует метод инверсии канала для передачи с тремя пользователями с другим количеством пространственных потоков, выделенных на пользователя, и различными параметрами скорости на пользователя. Система может быть охарактеризована рисунком ниже.
Пример генерирует многопользовательскую форму волны передачи, передает ее через канал для каждого пользователя и декодирует принятый сигнал для каждого пользователя, чтобы вычислить биты в ошибку. Перед передачей данных в примере используется передача пакета с нулевыми данными (NDP) для звучания различных каналов и определяется матрица предварительного кодирования при условии идеальной обратной связи.
Для 802.11ac разрешено максимум восемь пространственных потоков. В этом примере используется строение MIMO 6x6 для трех пользователей, где первый пользователь имеет три потока, второй имеет один, а третий имеет два потока, выделенных ему. В качестве векторных параметров заданы различные параметры скорости и размеры полезной нагрузки для четырех пользователей. Они индексируются соответствующим образом в строении передачи на основе количества активных пользователей.
s = rng(21); % Set RNG seed for repeatability % Transmission parameters chanBW = 'CBW80'; % Channel bandwidth numUsers = 3; % Number of active users numSTSAll = [3 1 2 2]; % Number of streams for 4 users userPos = [0 1 2 3]; % User positions for maximum 4 users mcsVec = [4 6 2 2]; % MCS for maximum 4 users apepVec = [15120 8192 5400 6000]; % Payload, in bytes, for 4 users chCodingVec = {'BCC', 'LDPC', 'LDPC', 'BCC'}; % Channel coding for 4 users % Channel and receiver parameters chanMdl = 'Model-A'; % TGac fading channel model precodingType = 'ZF'; % Precoding type; ZF or MMSE snr = 38; % SNR in dB eqMethod = 'ZF'; % Equalization method % Create the multi-user VHT format configuration object, appropriately % indexing into the vector values for the active users if (numUsers==1) groupID = 0; else groupID = 2; end numSTSVec = numSTSAll(1:numUsers); numTx = sum(numSTSVec); cfgVHTMU = wlanVHTConfig('ChannelBandwidth', chanBW,... 'NumUsers', numUsers, ... 'NumTransmitAntennas', numTx, ... 'GroupID', groupID, ... 'NumSpaceTimeStreams', numSTSVec,... 'UserPositions', userPos(1:numUsers), ... 'MCS', mcsVec(1:numUsers), ... 'APEPLength', apepVec(1:numUsers), ... 'ChannelCoding', chCodingVec(1:numUsers));
Количество передающих антенн устанавливается равным общей сумме всех используемых пространственно-временных потоков. Это не подразумевает пространственно-временного блочного кодирования (STBC) или пространственного расширения, используемого для передачи.
Для предварительного кодирования сначала используется зондирование канала, чтобы определить канал, испытываемый пользователями (приемниками). Эта информация о состоянии канала отправляется назад передатчику, чтобы она использовалась для последующей передачи данных. Принято, что канал изменяется медленно по двум передачам. Для многопользовательских передач тот же NDP (Null Data Packet) передается каждому из запланированных пользователей [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);
Количество заданных потоков является суммарной суммой всех используемых пространственно-временных потоков. Это позволяет прозвучать полному каналу.
% Generate the null data packet, with no data
txNDPSig = wlanWaveformGenerator([], cfgVHTNDP);
Многопользовательский канал TGac состоит из независимых однопользовательских каналов MIMO между точкой доступа и пространственно разделенными станциями [4]. В этом примере тот же самый профиль задержки канала Model-A применяется для каждого из пользователей, даже если отдельные пользователи могут испытывать различные условия. Канал с плоским замиранием позволяет использовать более простой приемник без фронтальной синхронизации. Также принято, что количество приемных антенн каждого пользователя равно количеству выделенных им пространственно-временных потоков.
Массивы ячеек используются в примере для хранения элементов на пользователя, которые допускают гибкое число пользователей. Здесь, в качестве примера, каждый образец канала TGac на пользователя сохранен как элемент массива ячеек.
% Create three independent channels 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', wlanSampleRate(cfgVHTMU), ... 'TransmitReceiveDistance',5); chanInfo = info(TGAC{uIdx}); chanDelay(uIdx) = chanInfo.ChannelFilterDelay; end
Каналы для каждого отдельного пользователя используют различные начальные значения для генерации случайных чисел. Другой пользовательский индекс задан, чтобы разрешить применение случайных смещений угла к углам прибытия (AoA) и отправления (AoD) для кластеров. Задержка фильтрации канала сохранена, чтобы обеспечить ее компенсацию в приемнике. На практике может использоваться оценка временных параметров символа.
% Append zeroes to allow for channel filter delay txNDPSig = [txNDPSig; zeros(10, numTx)]; % Sound the independent channels per user for all transmit streams rxNDPSig = cell(numUsers, 1); for uIdx = 1:numUsers rxNDPChan = TGAC{uIdx}(txNDPSig); % Add WGN per receiver rxNDPSig{uIdx} = awgn(rxNDPChan, snr); end
Каждый пользователь оценивает свой собственный канал, используя принятый сигнал NDP, и вычисляет информацию о состоянии канала, которую он может отправить назад передатчику. Этот пример использует сингулярное разложение канала, наблюдаемое каждым пользователем, чтобы вычислить обратную связь CSI.
mat = cell(numUsers,1); for uIdx = 1:numUsers % Compute the feedback matrix based on received signal per user mat{uIdx} = vhtCSIFeedback(rxNDPSig{uIdx}(chanDelay(uIdx)+1:end,:), ... cfgVHTNDP, uIdx, numSTSVec); end
Принимая идеальную обратную связь, без сжатия или потерь квантования CSI, передатчик вычисляет матрицу управления для передачи данных с помощью методов предварительного кодирования на основе нулевого или минимального среднего квадрата (MMSE). Оба метода пытаются отменить интерференцию внутри потока для интересующего пользователя и интерференцию от других пользователей. Основанный на MMSE подход избегает усиления шума, присущего методу нулевого воздействия. В результате он лучше работает при низких ОСШ.
% 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 % Zero-forcing or MMSE precoding solution if strcmp(precodingType, 'ZF') delta = 0; % Zero-forcing else delta = (numTx/(10^(snr/10))) * eye(numTx); % MMSE end for i = 1:numST % Channel inversion precoding h = squeeze(steeringMatrix(i,:,:)); steeringMatrix(i,:,:) = h/(h'*h + delta); end % Set the spatial mapping based on the steering matrix cfgVHTMU.SpatialMapping = 'Custom'; cfgVHTMU.SpatialMappingMatrix = permute(steeringMatrix,[1 3 2]);
Случайные биты используются в качестве полезной нагрузки для отдельных пользователей. Массив ячеек используется для хранения бит данных для каждого пользователя, txDataBits
. Для многопользовательской передачи полезные нагрузки отдельных пользователей заполняются таким образом, чтобы длительность передачи была одинаковой для всех пользователей. Этот процесс заполнения описан в разделе 9.12.6 [1]. В этом примере для простоты полезная нагрузка заполняется нулями, чтобы создать PSDU для каждого пользователя.
% Create data sequences, one for each user txDataBits = cell(numUsers, 1); psduDataBits = cell(numUsers, 1); for uIdx = 1:numUsers % Generate payload for each user txDataBits{uIdx} = randi([0 1], cfgVHTMU.APEPLength(uIdx)*8, 1, 'int8'); % Pad payload with zeros to form a PSDU psduDataBits{uIdx} = [txDataBits{uIdx}; ... zeros((cfgVHTMU.PSDULength(uIdx)-cfgVHTMU.APEPLength(uIdx))*8, 1, 'int8')]; end
Используя строение формата, cfgVHTMU
с помощью матрицы управления данные передаются по каналу с замираниями.
% Generate the multi-user VHT waveform txSig = wlanWaveformGenerator(psduDataBits, 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
Приемные сигналы для каждого пользователя обрабатываются индивидуально. Пример принимает, что нет никаких ослаблений переднего плана и что строение передачи известно приемнику для простоты.
Номер пользователя определяет интересующего пользователя, который декодируется для передачи. Это также используется для индекса в векторные свойства объекта строения, которые являются специфичными для пользователя.
% Get field indices from configuration, assumed known at receiver ind = wlanFieldIndices(cfgVHTMU); % Single-user receivers recover payload bits rxDataBits = cell(numUsers, 1); scaler = zeros(numUsers, 1); spAxes = gobjects(sum(numSTSVec), 1); hfig = figure('Name','Per-stream equalized symbol constellation'); 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); % 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); % Get single stream channel estimate chanEstSSPilots = vhtSingleStreamChannelEstimate(demodVHTLTF,cfgVHTMU); % Extract VHT Data samples from the waveform rxVHTData = rxNSig(ind.VHTData(1):ind.VHTData(2),:); % Estimate the noise power in VHT data field nVar = vhtNoiseEstimate(rxVHTData,chanEstSSPilots,cfgVHTMU); % Recover information bits in VHT Data field [rxDataBits{uIdx}, ~, eqsym] = wlanVHTDataRecover(rxVHTData, ... chanEst, nVar, cfgVHTMU, uIdx, 'EqualizationMethod', eqMethod, ... 'PilotPhaseTracking', 'None', 'LDPCDecodingMethod', 'layered-bp'); % Plot equalized symbols for all streams per user scaler(uIdx) = ceil(max(abs([real(eqsym(:)); imag(eqsym(:))]))); for i = 1:stsU subplot(numUsers, max(numSTSVec), (uIdx-1)*max(numSTSVec)+i); plot(reshape(eqsym(:,:,i), [], 1), '.'); axis square spAxes(sum([0 numSTSVec(1:(uIdx-1))])+i) = gca; % Store axes handle title(['User ' num2str(uIdx) ', Stream ' num2str(i)]); grid on; end end % Scale axes for all subplots and scale figure for i = 1:numel(spAxes) xlim(spAxes(i),[-max(scaler) max(scaler)]); ylim(spAxes(i),[-max(scaler) max(scaler)]); end pos = get(hfig, 'Position'); set(hfig, 'Position', [pos(1)*0.7 pos(2)*0.7 1.3*pos(3) 1.3*pos(4)]);
Графики созвездия выравниваемого символа в потоке подтверждают параметры симуляции и передают эффективность метода. Обратите внимание на различимые 16QAM, 64QAM и созвездия QPSK на пользователя, как указано на конце передачи. Также наблюдайте деградацию EVM по различным потокам для отдельного пользователя. Это репрезентативная характеристика метода инверсии канала.
Восстановленные биты данных сравнивают с переданными битами полезной нагрузки для определения частоты битовой ошибки.
% Compare recovered bits against per-user APEPLength information bits ber = inf(1, numUsers); for uIdx = 1:numUsers idx = (1:cfgVHTMU.APEPLength(uIdx)*8).'; [~, ber(uIdx)] = biterr(txDataBits{uIdx}(idx), rxDataBits{uIdx}(idx)); disp(['Bit Error Rate for User ' num2str(uIdx) ': ' num2str(ber(uIdx))]); end rng(s); % Restore RNG state
Bit Error Rate for User 1: 0.00013228 Bit Error Rate for User 2: 0 Bit Error Rate for User 3: 0
Небольшое количество битовых ошибок в пределах отклонения шума указывает на успешное декодирование данных для всех потоков для каждого пользователя, несмотря на изменения в EVM, наблюдаемые в отдельных потоках.
Пример показывает многопользовательское строение передачи, независимое моделирование канала на пользователя и индивидуальную обработку приема с использованием методов предварительного кодирования инверсии канала.
Дальнейшее исследование включает в себя модификации параметров передачи и канала, альтернативные методы предварительного кодирования, более реалистичные приемники и механизм обратной связи, включающий задержки и квантование.
В этом примере используются следующие вспомогательные функции:
Стандарт IEEE Std 802.11ac™-2013 IEEE на информационные технологии - Телекоммуникации и обмен информацией между системами - Локальные и столичные сети - Особые требования - Часть 11: Беспроводное управление доступом к локальной сети (MAC) и физический уровень (PHY) Спецификации - Поправка 4: Улучшения для очень высокой пропускной способности
Perahia, E., R. Stacey, «Next Generation Wireless LANS: 802.11n and 802.11ac», Cambridge University Press, 2013.
Стандарт IEEE Std 802.11™-2012 IEEE на информационные технологии - Телекоммуникации и обмен информацией между системами - Локальные и столичные сети - Особые требования - Часть 11: Беспроводное управление доступом к среде локальной сети (MAC) и физический слой (PHY) Спецификации.
Breit, G., H. Sampath, S. Vermani, et al., «TGac Channel Model Addendment», Version 12. IEEE 802.11-09/0308r12, март 2010.