gusucode.com > wlan工具箱matlab源码程序 > wlan/wlan/wlanVHTLTFChannelEstimate.m
function est = wlanVHTLTFChannelEstimate(rxSym,cfgVHT,varargin) % wlanVHTLTFChannelEstimate Channel estimation using the VHT-LTF % EST = wlanVHTLTFChannelEstimate(RXSYM,CFGVHT) returns the estimated % channel between all space-time streams and receive antennas using the % Very High Throughput Long Training Field (VHT-LTF). The channel % estimate includes the effect of the applied spatial mapping matrix and % cyclic shifts at the transmitter. % % EST is a complex Nst-by-Nsts-by-Nr array characterizing the estimated % channel for the data and pilot subcarriers, where Nst is the number of % occupied subcarriers, Nsts is the total number of space-time streams, % and Nr is the number of receive antennas. % % RXSYM is a complex Nst-by-Nsym-by-Nr array containing demodulated % VHT-LTF OFDM symbols. Nsym is the number of demodulated VHT-LTF % symbols. % % CFGVHT is a packet format configuration object of type <a href="matlab:help('wlanVHTConfig')">wlanVHTConfig</a>. % % EST = wlanVHTLTFChannelEstimate(RXSYM,CHANBW,NUMSTS) returns the % estimated channel for the specified channel bandwidth, CHANBW, and the % number of space-time streams, NUMSTS. Both CHANBW and NUMSTS have the % same attributes as the corresponding ChannelBandwidth and % NumSpaceTimeStreams properties of the wlanVHTConfig format % configuration object. % % EST = wlanVHTLTFChannelEstimate(...,SPAN) performs frequency smoothing % by using a moving average filter across adjacent subcarriers to reduce % the noise on the channel estimate. The span of the filter in % subcarriers, SPAN, must be odd. If adjacent subcarriers are highly % correlated frequency smoothing will result in significant noise % reduction, however in a highly frequency selective channel smoothing % may degrade the quality of the channel estimate. % % Examples: % % Example 1: % % Generate a time domain waveform txWaveform for an 802.11ac VHT % % packet and combine all transmit antennas onto one receive antenna. % % Extract and demodulate the VHT-LTF and perform channel estimation % % with a frequency smoothing span of 3. % % cfgVHT = wlanVHTConfig; % Create packet configuration % cfgVHT.NumTransmitAntennas = 2; % 2 transmit antennas % cfgVHT.NumSpaceTimeStreams = 2; % 2 spatial streams % txWaveform = wlanWaveformGenerator([1;0;0;1],cfgVHT); % % rxWaveform = sum(txWaveform,2); % Combine all transmit antennas % idnVHTLTF = wlanFieldIndices(cfgVHT,'VHT-LTF'); % sym = wlanVHTLTFDemodulate( ... % rxWaveform(idnVHTLTF(1):idnVHTLTF(2),:), cfgVHT); % smoothingSpan = 3; % est = wlanVHTLTFChannelEstimate(sym,cfgVHT,smoothingSpan); % % Example 2: % % Generate a time domain waveform for an 802.11ac VHT packet, pass it % % through a TGac fading channel and perform VHT-LTF channel % % estimation. % % cfgVHT = wlanVHTConfig; % Create packet configuration % txWaveform = wlanWaveformGenerator([1;0;0;1],cfgVHT); % % % Configure channel % tgacChannel = wlanTGacChannel; % tgacChannel.SampleRate = 80e6; % tgacChannel.ChannelBandwidth = 'CBW80'; % % % Pass through channel (with zeros to allow for channel delay) % rxWaveform = tgacChannel([txWaveform; zeros(15,1)]); % rxWaveform = rxWaveform(5:end,:); % Synchronize for channel delay % % % Extract VHT-LTF and perform channel estimation % indVHTLTF = wlanFieldIndices(cfgVHT,'VHT-LTF'); % sym = wlanVHTLTFDemodulate(rxWaveform( ... % indVHTLTF(1):indVHTLTF(2),:),cfgVHT); % est = wlanVHTLTFChannelEstimate(sym,cfgVHT); % % See also wlanVHTConfig, wlanVHTLTFDemodulate, wlanVHTDataRecover, % wlanLLTFChannelEstimate, wlanHTLTFChannelEstimate. % Copyright 2015-2016 The MathWorks, Inc. %#codegen narginchk(2,4); if ischar(cfgVHT) % chanBW input narginchk(3,4); wlan.internal.validateParam('CHANBW', cfgVHT, mfilename); chanBW = cfgVHT; numSTSVec = varargin{1}; wlan.internal.validateParam('NUMSTS', numSTSVec, mfilename); if nargin == 4 span = varargin{2}; enableFreqSmoothing = true; else enableFreqSmoothing = false; end else % VHT configuration object input narginchk(2,3); % cfgVHT validation validateattributes(cfgVHT, {'wlanVHTConfig'}, {'scalar'}, ... mfilename, 'VHT format configuration object'); % Dependent validation not needed for necessary fields (CHANBW, numSTS) chanBW = cfgVHT.ChannelBandwidth; numSTSVec = cfgVHT.NumSpaceTimeStreams; if nargin == 3 enableFreqSmoothing = true; span = varargin{1}; else enableFreqSmoothing = false; end end % Validate symbol type validateattributes(rxSym,{'single','double'},{'3d'}, mfilename, ... 'VHT-LTF OFDM symbol(s)'); numSC = size(rxSym,1); numRxAnts = size(rxSym,3); numSTSTotal = sum(numSTSVec); % Return an empty if empty symbols if isempty(rxSym) est = zeros(numSC,numSTSTotal,numRxAnts); return; end % Verify number of subcarriers to estimate % Get OFDM configuration [cfgOFDM,dataInd] = wlan.internal.wlanGetOFDMConfig(chanBW, 'Long', ... 'VHT',numSTSTotal); FFTLen = cfgOFDM.FFTLength; [ind,sortIdx] = sort([cfgOFDM.DataIndices; cfgOFDM.PilotIndices]); coder.internal.errorIf(numSC~=numel(ind), ... 'wlan:wlanChannelEstimate:IncorrectNumSC',numel(ind),numSC); % Get cyclic shifts applied at transmitter csh = wlan.internal.getCyclicShiftVal('VHT',numSTSTotal,FFTLen/64*20); if numSTSTotal==1 % Perform channel estimation for all subcarriers est = wlan.internal.vhtltfEstimate(rxSym,chanBW,numSTSTotal,ind); else % Perform channel estimation for data carrying subcarriers as we % must interpolate the pilots estData = wlan.internal.vhtltfEstimate(rxSym(dataInd,:,:), ... chanBW,numSTSTotal,cfgOFDM.DataIndices); % Undo cyclic shift for each STS before averaging and interpolation estData = wlan.internal.wlanCyclicShift(estData,csh,FFTLen,'Rx', ... cfgOFDM.DataIndices); % Estimate pilot subcarriers estPilots = pilotInterpolation(estData,FFTLen,cfgOFDM.DataIndices, ... cfgOFDM.PilotIndices); % Combine data and pilots into one container allSubcarriers = [estData; estPilots]; est = allSubcarriers(sortIdx,:,:); end % Perform frequency smoothing if enableFreqSmoothing % Smooth segments between DC gaps switch chanBW case 'CBW20' numGroups = 1; case 'CBW40' numGroups = 2; case 'CBW80' numGroups = 2; otherwise % 'CBW160' numGroups = 4; end groupSize = size(est,1)/numGroups; for i = 1:numGroups idx = (1:groupSize)+(i-1)*groupSize; est(idx,:,:) = wlan.internal.frequencySmoothing(est(idx,:,:),span); end end % Re-apply cyclic shift after averaging and interpolation if numSTSTotal>1 est = wlan.internal.wlanCyclicShift(est,csh,FFTLen,'Tx',ind); end end %-------------------------------------------------------------------------- function estPilots = pilotInterpolation(estData,Nfft,dataIndices,pilotIndices) % Interpolate over the pilot locations numSTS = size(estData,2); numRxAnts = size(estData,3); % Construct full FFT size to allow us to interpolate over DC nulls est = complex(ones(Nfft,numSTS,numRxAnts),ones(Nfft,numSTS,numRxAnts)); est(dataIndices,:,:) = estData; % Interpolate over missing parts of the waveform in magnitude and % phase (as opposed to real and imaginary) magPart = interp1(dataIndices,abs(est(dataIndices,:,:)),1:Nfft); phasePart = interp1(dataIndices,unwrap(angle(est(dataIndices,:,:))),1:Nfft); [realPart,imagPart] = pol2cart(phasePart,magPart); estInterp = complex(realPart,imagPart); if isrow(estInterp) est = estInterp(:,:,1).'; else est = estInterp; end % Extract pilots estPilots = est(pilotIndices,:,:); end