├── azr_icdp.m └── readme.md /azr_icdp.m: -------------------------------------------------------------------------------- 1 | % THIS CODE IS FOR CHANNEL ESTIMATION IN IEEE 802.11p PHYSICAL LAYER 2 | % USE Matlabb version 2016b 3 | % Please find the detail about code in below article and cite it if you use this code in your work. 4 | % Wang, T.; Hussain, A.; Cao, Y.; Gulomjon, S. An Improved Channel Estimation Technique for IEEE 802.11p Standard in Vehicular Communications. Sensors 2019, 19, 98. 5 | 6 | clc; 7 | EsNodB = 1:35; 8 | snr = 10.^(EsNodB/10); 9 | Smp=64; 10 | mcs =2; 11 | psduLen =50*20;% byte pay load size = psduLen*8 bits 12 | 13 | W=0; 14 | 15 | Ds = 1200; % Hz 16 | 0; % doppler spread 17 | % Maximum Doppler shift, Hz 18 | c = 3e8*3.6; % Speed of light, Km/hr 19 | fc = 5.9e9; % Carrier frequency, Hz 20 | 21 | 22 | idleTime = 0; 23 | numPkts = 10; 24 | winTransTime = 0; % No windowing 25 | chDelay = 00; % arbitrary delay to account for all channel profiles 26 | 27 | h =figure; 28 | grid on ; 29 | hold on; 30 | xlabel('SNR (dB)'); 31 | ylabel('PER'); 32 | 33 | ax=gca; 34 | % ylim([1e-3 1]); 35 | ax.YScale ='log'; 36 | 37 | 38 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 39 | 40 | MC = 100; % number of frames 41 | MSErrorLS=zeros(1,length(EsNodB)); 42 | MSErroriCDP=zeros(1,length(EsNodB)); 43 | MSErrorCDP=zeros(1,length(EsNodB)); 44 | MSErrorDFT=zeros(1,length(EsNodB)); 45 | MSErrorSTA=zeros(1,length(EsNodB)); 46 | BERLS = zeros(1,length(EsNodB)); 47 | BERiCDP = zeros(1,length(EsNodB)); 48 | BERCDP = zeros(1,length(EsNodB)); 49 | BERDFT = zeros(1,length(EsNodB)); 50 | BERSTA = zeros(1,length(EsNodB)); 51 | NumOfErrorBitLS = zeros(1,MC); 52 | NumOfErrorBitiCDP = zeros(1,MC); 53 | NumOfErrorBitCDP = zeros(1,MC); 54 | NumOfErrorBitLDFT = zeros(1,MC); 55 | NumOfErrorBitSTA = zeros(1,MC); 56 | 57 | NumOfErrorBitazr =zeros(1,MC); 58 | jj = zeros(1,length(EsNodB)); 59 | 60 | chanMdl = 'E'; 61 | 62 | cfgNHT10 = wlanNonHTConfig('PSDULength', psduLen); 63 | cfgNHT10.Modulation = 'OFDM'; 64 | cfgNHT10.ChannelBandwidth = 'CBW10'; % 10 MHz channel bandwidth 65 | cfgNHT10.MCS = mcs; 66 | fs10 = helperSampleRate(cfgNHT10); % Baseband sampling rate for 10 MHz 67 | trms = 0.4e-6; 68 | fs = fs10; 69 | 70 | fd =Ds; 71 | 72 | fadingMargin = 12; % dB 73 | %chan10 = stdchan(1/fs10, fd, chantype); 74 | disp(['Speed of unit = ' num2str(c*fd/5.9e9) ' Km/hr at ' num2str(fc/1e9) ' GHz']); 75 | 76 | chan10 = stdchan(1/fs10, fd, ['hiperlan2' chanMdl]); 77 | chan10.StoreHistory = 1; 78 | s = rng(98765); 79 | ofdmInfo = wlan.internal.wlanGetOFDMConfig(cfgNHT10.ChannelBandwidth, 'Long', 'Legacy'); 80 | Nst = numel(ofdmInfo.DataIndices)+numel(ofdmInfo.PilotIndices); % Number of occupi}[ed subcarriers 81 | 82 | beta = 17/9; 83 | i=0; 84 | nFFT = 64; 85 | nCP = 16; 86 | mcsTable = wlan.internal.getRateTable(cfgNHT10); 87 | pNcbpssi = mcsTable.NCBPS; 88 | 89 | cfgRec = wlanRecoveryConfig('EqualizationMethod', 'ZF'); 90 | 91 | for ii = 1:length(EsNodB)% iterate for a particular snr 92 | 93 | ChMSE_LSo = 0; 94 | ChMSE_iCDP=0; 95 | ChMSE_CDP=0; 96 | ChMSE_DFT=0; 97 | ChMSE_STA=0; 98 | numPacketErrors = 0; 99 | numPkt = 0; % Index of packet transmitted 100 | packetErrorCDP =0; 101 | packetErrorSTA = 0; 102 | packetErrorAZR= 0; 103 | packetErrorLS = 0; 104 | packetErrorDFT = 0; 105 | NumpacketErrorCDP =0; 106 | NumpacketErrorSTA = 0; 107 | NumpacketErrorAZR =0; 108 | NumpacketErrorLS =0; 109 | NumpacketErrorDFT = 0; 110 | enableFE = true; 111 | inpPSDU = randi([0 1], 8*cfgNHT10.PSDULength, 1); 112 | ind = wlanFieldIndices(cfgNHT10); 113 | tx = wlanWaveformGenerator(inpPSDU,cfgNHT10, 'IdleTime', idleTime,... 114 | 'NumPackets', numPkts, 'WindowTransitionTime', winTransTime); 115 | awgnChannel = comm.AWGNChannel; 116 | awgnChannel.NoiseMethod = 'Signal to noise ratio (SNR)'; 117 | awgnChannel.SignalPower = 1; % Unit power 118 | awgnChannel.SNR = EsNodB (ii)-10*log10(ofdmInfo.FFTLength/Nst); % Account for energy in nulls 119 | 120 | for mc = 1:MC 121 | 122 | chDelay = 100; 123 | padTx = [tx; zeros(chDelay, 1)]; 124 | numRxAnts=1; 125 | XDD=reshape(tx,80,[]);% 80x6=480 126 | [ofdmSize,ofdmSymbols] = size(XDD); 127 | s = validateConfig(cfgNHT10);% tells the number of data ofdm symbols 128 | numOFDMSym = s.NumDataSymbols; 129 | z=1;% accouts for the L-SIG pilot Symbol 130 | refPilots = wlan.internal.nonHTPilots(s.NumDataSymbols,z); 131 | % Get OFDM configuration 132 | [cfgOFDM,dataInd,pilotInd] = wlan.internal.wlanGetOFDMConfig( ... 133 | cfgNHT10.ChannelBandwidth, 'Long', 'Legacy'); 134 | % Cross validate inputs 135 | numST = numel([dataInd; pilotInd]); % Total number of occupied subcarriers 136 | % Cross-validation between inputs 137 | minInputLen = numOFDMSym*(cfgOFDM.FFTLength+cfgOFDM.CyclicPrefixLength); 138 | rx = filter(chan10, padTx); 139 | rx = awgnChannel(rx); 140 | chDelay = chan10.ChannelFilterDelay; 141 | rx = rx(chDelay+1:end,:); 142 | 143 | lltftx = tx(ind.LLTF(1):ind.LLTF(2),:); 144 | lstftx = tx(ind.LSTF(1):ind.LSTF(2),:); 145 | 146 | lltfDemodtx = wlanLLTFDemodulate(lltftx, cfgNHT10, 1); 147 | lstfDemodtx = wlanLLTFDemodulate(lstftx, cfgNHT10, 1); 148 | 149 | lltf = rx(ind.LLTF(1):ind.LLTF(2),:); 150 | lstf = rx(ind.LSTF(1):ind.LSTF(2),:); 151 | 152 | lltfDemod = wlanLLTFDemodulate(lltf, cfgNHT10, 1); 153 | lstfDemod = wlanLLTFDemodulate(lstf, cfgNHT10, 1); 154 | 155 | 156 | %%%%%%%%%%%%%%%%%%% LEAST SQUARE ESTIMATION %%%%%%%%%%%%%%%%% 157 | lltfo = lltfReference(1); % Get reference subcarriers 158 | ls = lltfDemod./lltfDemodtx;%repmat(lltfo,1,size(lltfDemod,2),numRxAnts); % Least-square estimate 159 | 160 | 161 | HhatLSo = mean(ls,2); % Average over the symbols 162 | HhatLSof = [zeros(6,1);HhatLSo;zeros(5,1)]; 163 | HhatLSx = ifft(HhatLSof,64); 164 | HhatLS = fft(HhatLSx(1:64),64); 165 | 166 | symOffset = 0.75; 167 | eqMethod = 'ZF'; 168 | pilotPhaseTracking = 'PreEQ'; 169 | 170 | coder.internal.errorIf(size(rx(ind.NonHTData(1):ind.NonHTData(2),:), 1) < minInputLen, ... 171 | 'wlan:wlanNonHTDataRecover:ShortNHTDataInput', minInputLen); 172 | chanEst = HhatLSo; %HhatLS(7:58,1); 173 | 174 | noiseVarEst = helperNoiseEstimate(lltfDemod); 175 | 176 | 177 | rxBits_LS = wlanNonHTDataRecover(rx(ind.NonHTData(1):ind.NonHTData(2),:), chanEst, noiseVarEst, cfgNHT10, cfgRec); 178 | 179 | rxNonHTData = rx(ind.NonHTData(1):ind.NonHTData(2),:); 180 | txNonHTData = tx(ind.NonHTData(1):ind.NonHTData(2),:); 181 | rxi = rxNonHTData(1:minInputLen, :); 182 | txi = txNonHTData(1:minInputLen, :); 183 | FFTLen = cfgOFDM.FFTLength; 184 | CPLen = cfgOFDM.CyclicPrefixLength; 185 | numRx = size(rxi, 2); 186 | numTx = size(txi, 2); 187 | symOffset = round(symOffset * CPLen); 188 | 189 | % Remove cyclic prefix 190 | 191 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 192 | if isscalar(CPLen) 193 | numSym = size(rxi, 1)/(FFTLen + CPLen); 194 | 195 | %%%%%%%%%%%%%%%%%% RX SIDE %%%%%%%%%%%%%% 196 | 197 | inputIn3Drx = reshape(rxi, [(FFTLen + CPLen) numSym numRx]); 198 | postCPRemovalrx = inputIn3Drx([CPLen+1:FFTLen+symOffset, symOffset+1:CPLen], :, :); 199 | 200 | %%%%%%%%%%%%%%%%%% TX SIDE %%%%%%%%%%%%%% 201 | 202 | inputIn3Dtx = reshape(txi, [(FFTLen + CPLen) numSym numTx]); 203 | postCPRemovaltx = inputIn3Dtx([CPLen+1:FFTLen+symOffset, symOffset+1:CPLen], :, :); 204 | 205 | 206 | 207 | else 208 | numSym = length(CPLen); 209 | 210 | postCPRemovalrx = coder.nullcopy(complex(zeros(FFTLen, numSym, numRx))); 211 | postCPRemovaltx = coder.nullcopy(complex(zeros(FFTLen, numSym, numTx))); 212 | 213 | 214 | currentIdx = 0; 215 | for symIdx = 1:numSym 216 | 217 | postCPRemovalrx(:, symIdx, :) = rxi(currentIdx + ... 218 | [CPLen(symIdx)+1:FFTLen+symOffset(symIdx), symOffset(symIdx)+1:CPLen(symIdx)], :); 219 | 220 | postCPRemovaltx(:, symIdx, :) = txi(currentIdx + ... 221 | [CPLen(symIdx)+1:FFTLen+symOffset(symIdx), symOffset(symIdx)+1:CPLen(symIdx)], :); 222 | 223 | 224 | 225 | 226 | currentIdx = currentIdx + CPLen(symIdx) + FFTLen; 227 | end 228 | end 229 | 230 | % Denormalization RX 231 | postCPRemovalrx = postCPRemovalrx / cfgOFDM.NormalizationFactor; 232 | postCPRemovaltx = postCPRemovaltx / cfgOFDM.NormalizationFactor; 233 | % FFT 234 | postFFTrx = fft(postCPRemovalrx, [], 1); 235 | postFFTtx = fft(postCPRemovaltx, [], 1); 236 | % FFT shift 237 | if isreal(postFFTrx) 238 | postShiftrx = complex(fftshift(postFFTrx, 1), 0); 239 | else 240 | postShiftrx = fftshift(postFFTrx,1); 241 | end 242 | % FFT shift 243 | if isreal(postFFTtx) 244 | postShifttx = complex(fftshift(postFFTtx, 1), 0); 245 | else 246 | postShifttx = fftshift(postFFTtx,1); 247 | end 248 | % Phase rotation on frequency subcarriers 249 | postShiftrx = bsxfun(@rdivide, postShiftrx, cfgOFDM.CarrierRotations); 250 | postShifttx = bsxfun(@rdivide, postShifttx, cfgOFDM.CarrierRotations); 251 | % Output data 252 | ofdmDemodData = postShiftrx(cfgOFDM.DataIndices, :, :); 253 | ofdmDemodDatatx = postShifttx(cfgOFDM.DataIndices, :, :); 254 | % Output pilots 255 | ofdmDemodPilots = postShiftrx(cfgOFDM.PilotIndices, :, :); 256 | ofdmDemodPilotstx = postShifttx(cfgOFDM.PilotIndices, :, :); 257 | 258 | %% 259 | chanEstData = chanEst(dataInd,:,:); 260 | chanEstPilots = chanEst(pilotInd,:,:); 261 | % Estimate CPE and phase correct symbols 262 | % cpe = wlan.internal.commonPhaseErrorEstimate(ofdmDemodPilots, ... 263 | % chanEstPilots, refPilots); 264 | rxPilots = ofdmDemodPilots; 265 | Nsts = size(chanEstPilots,2); 266 | %%%%%%%%%%%%%%%%%%%% DFT BASED CHANNEL ESTIMATION %%%%%%%%%%%%%%%%%%%%%%%%% 267 | HhatDFT = ifft(HhatLS,64); 268 | HhatDFT = [HhatDFT(1:18);zeros(40,1)]; 269 | HhatDFT = fft(HhatDFT,64); 270 | rxBits_LDFT = wlanNonHTDataRecover(rx(ind.NonHTData(1):ind.NonHTData(2),:), HhatDFT(7:58,1), noiseVarEst, cfgNHT10, cfgRec); 271 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%HERE DO CDP ESTIMATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 272 | ShatRiofK = ofdmDemodData; 273 | [Nsc,Nsym,Nr] = size(ShatRiofK); 274 | Np=4; 275 | csiDatai = complex(zeros(Nsc,Nsym,Nr)); 276 | csiDataticki = complex(zeros(Nsc,Nsym,Nr)); 277 | csiDatatickticki = complex(zeros(Nsc,Nsym,Nr)); 278 | 279 | XhatSym = complex(zeros(Nsc,Nsym,Nr)); 280 | XhattickSym = complex(ones(Nsc,Nsym,Nr)); 281 | XhatticktickSym = complex(ones(Nsc,Nsym,Nr)); 282 | 283 | HiofK = (ones(Nsc,Nsym)); 284 | HiofKoriginal = (ones(Nsc,Nsym)); 285 | 286 | HiofKsta = (ones(52,Nsym)); 287 | Hupdate = (ones(52,Nsym)); 288 | HupdateAzr = (ones(52,Nsym)); 289 | 290 | DemappedTx = ones(pNcbpssi,Nsym); 291 | DemappedRx = ones(pNcbpssi,Nsym); 292 | DemappedSC = ones(pNcbpssi,Nsym); 293 | DemappedSSC = ones(pNcbpssi,Nsym); 294 | DemappedRxstadata = ones(pNcbpssi,Nsym); 295 | DemappedRxstapilot = ones(8,Nsym); 296 | 297 | 298 | HCDPiofK = (ones(Nsc,Nsym)); 299 | h_estiSEMI0 = HCDPiofK; 300 | Hsta = (ones(Nsc,Nsym)); 301 | Hazr = (ones(Nsc,Nsym)); 302 | X=(ones(Nsc,Nsym)); 303 | Xtest=(ones(Nsc,Nsym)); 304 | 305 | 306 | Xstadata =(ones(Nsc,Nsym)); 307 | Xstapilot =(ones(4,Nsym)); 308 | XSC=(ones(Nsc,Nsym)); 309 | XSSC=(ones(Nsc,Nsym)); 310 | XSSC0 = lltfDemodtx(:,2); 311 | XSSC0 = XSSC0(dataInd,1,:); 312 | 313 | XT=(ones(Nsc,Nsym)); 314 | XZ=(ones(Nsc,Nsym)); 315 | 316 | 317 | ShattickCiminus1 = complex(ones(Nsc,Nsym,Nr)); 318 | ShatticktickCiminus1 = complex(ones(Nsc,Nsym,Nr)); 319 | ShatTiofKK = ofdmDemodDatatx;% complex(zeros(Np,Nsym,Nr)); 320 | ShatTiofK = ShatTiofKK;% complex(zeros(Np,Nsym,Nr)); 321 | SCiofK = complex(ones(Nsc,Nsym,Nr)); 322 | ShatRiofK = ofdmDemodData; 323 | SSCiofK = complex(ones(Nsc,Nsym,Nr)); 324 | SCiofK0=complex(ones(Nsc,Nsym,Nr)); 325 | 326 | chanEstCDPData = complex(ones(Nsc,Nsym,Nr)); 327 | ShatTiofKstadata =complex(ones(Nsc,Nsym,Nr)); 328 | ShatTiofKstapilot = complex(ones(4,Nsym,Nr)); 329 | ShatRiofKsta = [postShiftrx(7:32,:);postShiftrx(34:59,:)]; 330 | ShatTiofKstao = [postShifttx(7:32,:);postShifttx(34:59,:)]; 331 | ShatTiofKsta =ShatRiofKsta; 332 | ShatTiofKstaFix =complex(ones(64,Nsym,Nr)); 333 | Hooo = ShatRiofKsta; 334 | chanEstCDPData = chanEst(dataInd,:,:); 335 | HCDPiofK0(:,1,1) = chanEst(dataInd,:,:); 336 | HCDPiofKsta = ShatRiofKsta; 337 | HCDPiofKazr = ShatRiofKsta; 338 | ShatRiofKstatemp = ShatRiofKsta; 339 | Hh = ShatRiofKstatemp; 340 | HCDPiofKsta0 = chanEst; 341 | SU = real(lltfDemod(:,2)); 342 | SU = SU(dataInd,:,:); 343 | Beta =2; 344 | Wlembda = 1/(2*Beta+1); 345 | Nsc=48; 346 | for r = 1:Nr 347 | for s =1:Nsts 348 | for i = 1:Nsym 349 | 350 | if i==1 351 | ShatTiofKsta(:,i,r) = ShatRiofKsta(:,i,r)./HCDPiofKsta0; 352 | ShatTiofKstadata(:,i,r) = ShatTiofKsta(dataInd,i,r); 353 | ShatTiofKstapilot(:,i,r) = ShatTiofKsta(pilotInd,i,r); 354 | AAA = wlan.internal.wlanConstellationDemodulate(ShatTiofKstadata(:,i,r),mcsTable.NBPSCS,1); 355 | DemappedRxstadata(:,i) = wlan.internal.wlanConstellationDemodulate(ShatTiofKstadata(:,i,r),mcsTable.NBPSCS,1); 356 | [Xstadata(:,i),k2] = demapper( DemappedRxstadata(:,i) ,Nsc); 357 | DemappedRxstapilot(:,i) = wlan.internal.wlanConstellationDemodulate(ShatTiofKstapilot(:,i,r),2,1);Xstapilot(:,i) = demapper( DemappedRxstapilot(:,i),Np ); 358 | ShatRiofKstatemp(dataInd,i,r) = Xstadata(:,i); 359 | ShatRiofKstatemp(pilotInd,i,r) = Xstapilot(:,i); 360 | HiofKsta(:,i) = ShatRiofKsta(:,i,r)./ ShatRiofKstatemp(:,i); 361 | Hupdate(:,i) = HiofKsta(:,i); 362 | for k = 1:52-2 363 | Hupdate(k+1,i) = (Hupdate(k+1,i)+ Hupdate(k,i) + Hupdate(k+2,i))/3; 364 | end 365 | HCDPiofKsta(:,i) = (Hupdate(:,i)+ HCDPiofKsta0)/2; 366 | Hsta(:,i) = HCDPiofKsta(dataInd,i,r); 367 | SRsta(:,i,r) = ShatRiofKsta(dataInd,i,r); 368 | SRazr(:,i,r) = ShatRiofKsta(dataInd,i,r); 369 | ShatTiofK(:,i,r) = ShatRiofK(:,i,r)./chanEstCDPData(:,1,1); 370 | DemappedRx(:,i) = wlan.internal.wlanConstellationDemodulate(ShatTiofK(:,i,r),mcsTable.NBPSCS,1); 371 | DemappedTx(:,i) = wlan.internal.wlanConstellationDemodulate(ShatTiofKK(:,i,r),mcsTable.NBPSCS,1); 372 | XT(:,i) = demapper( DemappedTx(:,i) ,Nsc); 373 | X(:,i) = demapper( DemappedRx(:,i) ,Nsc); 374 | HiofK(:,i) = ShatRiofK(:,i,r)./ X(:,i); 375 | HiofKoriginal(:,i) = ShatRiofK(:,i,r)./ XT(:,i); 376 | SCiofK0(:,1,r) = SU./(HiofK(:,i)); 377 | for k =1:Nsc 378 | if (SCiofK0(k,1,r)>0) 379 | 380 | XSC0(k,1) = 1; 381 | else 382 | XSC0(k,1) = -1; 383 | end 384 | end 385 | if XSC0(:,1)==XSSC0(:,1) 386 | 387 | HCDPiofK(:,i) = (HiofK(:,i)); 388 | Hazr(:,i) = Hsta(:,i); 389 | else 390 | HCDPiofK(:,i) = chanEstCDPData(:,1,1); 391 | Hazr(:,i) = HCDPiofK(:,i); 392 | end 393 | 394 | 395 | end 396 | 397 | 398 | if i>1 399 | 400 | ShatTiofKsta(:,i,r) = ShatRiofKsta(:,i,r)./HCDPiofKsta(:,i-1); 401 | ShatTiofKstadata(:,i,r) = ShatTiofKsta(dataInd,i,r); 402 | ShatTiofKstapilot(:,i,r) = ShatTiofKsta(pilotInd,i,r); 403 | DemappedRxstadata(:,i) = wlan.internal.wlanConstellationDemodulate(ShatTiofKstadata(:,i,r),mcsTable.NBPSCS,1); 404 | DemappedRxstapilot(:,i) = wlan.internal.wlanConstellationDemodulate(ShatTiofKstapilot(:,i,r),2,1); 405 | Xstadata(:,i) = demapper( DemappedRxstadata(:,i) ,Nsc); 406 | Xstapilot(:,i) = demapper( DemappedRxstapilot(:,i),Np ); 407 | ShatRiofKstatemp(dataInd,i,r) = Xstadata(:,i); 408 | ShatRiofKstatemp(pilotInd,i,r) = Xstapilot(:,i); 409 | HiofKsta(:,i) = ShatRiofKsta(:,i,r)./ ShatRiofKstatemp(:,i); 410 | Hupdate(:,i) = HiofKsta(:,i); 411 | HupdateAzr(:,i) = HiofKsta(:,i); 412 | for k = 1:52-2 413 | Hupdate(k+1,i) = (Hupdate(k+1,i)+ Hupdate(k,i) + Hupdate(k+2,i))/3; 414 | end 415 | HCDPiofKsta(:,i) = (Hupdate(:,i)+ HCDPiofKsta(:,i-1))/2; 416 | Hsta(:,i) = HCDPiofKsta(dataInd,i,r); 417 | SRsta(:,i,r) = ShatRiofKsta(dataInd,i,r); 418 | SRazr(:,i,r) = ShatRiofKsta(dataInd,i,r); 419 | ShatTiofK(:,i,r) = ShatRiofK(:,i,r)./HCDPiofK(:,i-1); 420 | DemappedRx(:,i) = wlan.internal.wlanConstellationDemodulate(ShatTiofK(:,i,r),mcsTable.NBPSCS,1); 421 | X(:,i) = demapper( DemappedRx(:,i) ,Nsc); 422 | DemappedTx(:,i) = wlan.internal.wlanConstellationDemodulate(ShatTiofKK(:,i,r),mcsTable.NBPSCS,1); 423 | XT(:,i) = demapper( DemappedTx(:,i),Nsc ); 424 | HiofK(:,i) = ShatRiofK(:,i,r)./ X(:,i); 425 | HiofKoriginal(:,i) = ShatRiofK(:,i,r)./ XT(:,i); 426 | SCiofK(:,i-1,r) = ShatRiofK(:,i-1,r)./(HiofK(:,i)); 427 | SSCiofK(:,i-1,r) = ShatRiofK(:,i-1,r)./(HCDPiofK(:,i-1)); 428 | DemappedSC(:,i-1) = wlan.internal.wlanConstellationDemodulate(SCiofK(:,i-1,r),mcsTable.NBPSCS,1); 429 | DemappedSSC(:,i-1) = wlan.internal.wlanConstellationDemodulate(SSCiofK(:,i-1,r),mcsTable.NBPSCS,1); 430 | XSC(:,i-1) = demapper( DemappedSC(:,i-1),Nsc); 431 | XSSC(:,i-1) = demapper( DemappedSSC(:,i-1),Nsc ); 432 | if XSC(:,i-1)==XSSC(:,i-1) 433 | HCDPiofK(:,i) = (HiofK(:,i)); 434 | Hazr(:,i) = (Hsta(:,i)+(HiofK(:,i)))/2; 435 | jj(1,EsNodB (ii))=1; 436 | else 437 | 438 | HCDPiofK(:,i) = HCDPiofK(:,i-1) ; 439 | if i>1 440 | Hazr(:,i) = HCDPiofKsta(dataInd,i-1,r); %Hazr(:,i-1) ; 441 | end 442 | end 443 | end 444 | end 445 | end 446 | 447 | end 448 | 449 | dlmwrite('H:\Desktop Folders\Folders\MATLAB\HiofK.csv',HiofK,'delimiter',',','-append') 450 | [Np,Nsym,Nr] = size(rxPilots); 451 | % Calculate an estimate of the received pilots using the channel estimate 452 | temp = complex(zeros(Np,Nsym,Nsts,Nr)); 453 | for r = 1:Nr 454 | for s = 1:Nsts 455 | for k = 1:Np 456 | temp(k,:,s,r) = chanEstPilots(k,s,r).*refPilots(k,:,s); 457 | end 458 | end 459 | end 460 | % Sum over space-time streams and remove that dimension by permuting 461 | estRxPilots = permute(sum(temp,3),[1 2 4 3]); 462 | 463 | % Phase correction based on Allert val Zelst and Tim C. W. Schenk, 464 | % Implementation of a MIMO OFDM-Based Wireless LAN System, IEEE 465 | % Transactions on Signal Processing, Vol. 52, No. 2, February 2004. The 466 | % result is averaged over the number of receive antennas (summed over the 467 | % 3rd dimension). 468 | cpe = angle(sum(sum(rxPilots.*conj(estRxPilots),1),3)); 469 | sym = ShatRiofK;%ofdmDemodData; 470 | [Nsc,~,Nr] = size(sym); 471 | x = exp(-1i*cpe); % Create constant 472 | ofdmDemodData = ShatRiofK; 473 | [rxBits_sim,csi_sim(:,:)] = recoverBitsNow( ofdmDemodData,Nsym,Nr,Nsts,HCDPiofK,noiseVarEst,mcsTable,pNcbpssi,cfgNHT10); 474 | [rxBits_simsta,csi_simsta(:,:) ]= recoverBitsNow( ofdmDemodData,Nsym,Nr,Nsts,Hsta,noiseVarEst,mcsTable,pNcbpssi,cfgNHT10); 475 | [rxBits_simazr,csi_simazr(:,:) ]= recoverBitsNow( ofdmDemodData,Nsym,Nr,Nsts,Hazr,noiseVarEst,mcsTable,pNcbpssi,cfgNHT10); 476 | HhatCDP=zeros(64,1); 477 | HhatCDP2=HhatCDP; 478 | for xu=2:63 479 | HhatCDP(xu,1)=( HhatLS(xu,1) + HhatLS(xu+1,1)+ HhatLS(xu-1,1))/3; 480 | end 481 | HhatCDP = 0.5*(HhatCDP+HhatDFT); 482 | rxBits_CDP = wlanNonHTDataRecover(rx(ind.NonHTData(1):ind.NonHTData(2),:), HhatCDP(7:58,1), noiseVarEst, cfgNHT10, cfgRec); 483 | [numerr_CDP, ber_CDP] = biterr(rxBits_sim, inpPSDU); 484 | [numerr_STA, ber_STA] = biterr(rxBits_simsta, inpPSDU); % Compare bits 485 | [numerr_azr, ber_azr] = biterr(rxBits_simazr, inpPSDU); % Compare bits 486 | [numerr_LS, ber_LS] = biterr(rxBits_LS, inpPSDU); % Compare bits 487 | [numerr_LDFT, ber_LDFT] = biterr(rxBits_LDFT, inpPSDU); % Compare bits 488 | 489 | % Compare bits 490 | NumOfErrorBitCDP(1,mc) = ber_CDP; 491 | NumOfErrorBitazr(1,mc) = ber_azr; 492 | NumOfErrorBitSTA(1,mc) = ber_STA; 493 | NumOfErrorBitLS(1,mc) = ber_LS; 494 | NumOfErrorBitLDFT(1,mc) = ber_LDFT; 495 | HOFLS = HiofK; 496 | HOFDFT = HiofK; 497 | HOFCDP = HCDPiofK; 498 | HOFSTA = Hsta; 499 | HOFAZR = Hazr; 500 | TEMPHDFT = HhatDFT(7:58,1); 501 | for pin=1:Nsym 502 | HOFLS(:,pin) = HhatLSo(dataInd,:,:); 503 | HOFDFT(:,pin) = TEMPHDFT( dataInd,:,:); 504 | end 505 | HOFLS = ifft(HOFLS); 506 | HOFDFT = ifft( HOFDFT); 507 | HOFCDP = ifft( HOFCDP); 508 | HOFSTA = ifft( HOFSTA); 509 | HOFAZR = ifft(HOFAZR); 510 | HiofKoriginal =ifft(HiofKoriginal); 511 | ChMSE_LSo = ChMSE_LSo +sqrt( mse(abs(HOFLS-HiofKoriginal))); 512 | ChMSE_DFT = ChMSE_DFT + sqrt( mse(abs(HOFDFT-HiofKoriginal))); 513 | ChMSE_CDP = ChMSE_CDP + sqrt( mse(abs(HOFCDP-HiofKoriginal))); 514 | ChMSE_STA = ChMSE_STA + sqrt( mse(abs(HOFSTA-HiofKoriginal))); 515 | ChMSE_iCDP = ChMSE_iCDP + sqrt( mse(abs(HOFAZR-HiofKoriginal))); 516 | end 517 | BERSTA(1, (ii)) = mean(NumOfErrorBitSTA); 518 | BERDFT(1, (ii)) = mean(NumOfErrorBitLDFT); 519 | BERLS(1, (ii)) = mean(NumOfErrorBitLS); 520 | BERiCDP(1, (ii)) = mean(NumOfErrorBitazr); 521 | BERCDP(1, (ii)) = mean(NumOfErrorBitCDP); 522 | NumOfErrorBitLS = zeros(1,MC); 523 | NumOfErrorBitCDP = zeros(1,MC); 524 | NumOfErrorBitLDFT = zeros(1,MC); 525 | NumOfErrorBitSTA = zeros(1,MC); 526 | NumOfErrorBitazr = zeros(1,MC); 527 | MSErrorLS(1,ii) = ChMSE_LSo/MC; 528 | MSErrorDFT(1,ii) = ChMSE_DFT/MC; 529 | MSErrorCDP(1,ii) = ChMSE_CDP/MC; 530 | MSErrorSTA(1,ii) = ChMSE_STA/MC; 531 | MSErroriCDP(1,ii) = ChMSE_iCDP/MC; 532 | end 533 | semilogy(EsNodB,BERLS,'bx-','LineWidth',1.2); hold on 534 | semilogy(EsNodB,BERDFT,'cs-','LineWidth',1.2);hold on 535 | semilogy(EsNodB,BERCDP,'mo-','LineWidth',1.2);hold on 536 | semilogy(EsNodB,BERSTA,'rp-','LineWidth',1.2);hold on 537 | semilogy(EsNodB,BERiCDP,'gd-','LineWidth',1.2);hold on 538 | title('HyperLAN Channel Model "E"') 539 | legend('LS','DFT','CDP','STA','iCDP'); 540 | %axis([1 40 1e-4 1 ]) 541 | xlabel('SNR(dB)') 542 | ylabel('BER') 543 | grid on ; 544 | figure 545 | plot(EsNodB,MSErrorLS,'bx-'); hold on 546 | plot(EsNodB,MSErrorDFT,'go-');hold on 547 | plot(EsNodB,MSErrorCDP,'mo-');hold on 548 | plot(EsNodB,MSErrorSTA,'yo-');hold on 549 | plot(EsNodB,MSErroriCDP,'ro-');hold on 550 | 551 | title('HyperLAN Channel Model "E"') 552 | 553 | legend('LS','DFT','CDP','STA','iCDP'); 554 | 555 | xlabel('SNR(dB)') 556 | ylabel('RMSE') 557 | grid on ; 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # An Improved Channel Estimation Technique for IEEE 802.11p Standard in Vehicular Communications 2 | 3 | IEEE 802.11p based Dedicated Short-Range Communication (DSRC) is considered a potential wireless technology to enable transportation safety and traffic efficiency. A major challenge in the development of IEEE 802.11p technology is ensuring communication reliability in highly dynamic Vehicle-to-Vehicle (V2V) environments. The design of IEEE 802.11p does not have a sufficient number of training symbols in the time domain and pilot carriers in the frequency domain to enable accurate estimation of rapidly varying V2V channels. The channel estimation of IEEE 802.11p is preamble based, which cannot guarantee a suitable equalization in urban and highway scenarios, especially for longer length data packets. This limitation has been investigated by some research works, which suggest that one major challenge is determining an accurate means of updating channel estimate over the course of packet length while adhering to the standard. The motivation behind this article is to overcome this challenge. We have proposed an improved Constructed Data Pilot (iCDP) scheme which adheres to the standard and constructs data pilots by considering the correlation characteristics between adjacent data symbols in time domain and adjacent subcarriers in frequency domain. It is in contrast to previous schemes which considered the correlation in the time domain. The results have shown that the proposed scheme performs better than previous schemes in terms of bit error rate (BER) and root-mean-square error (RMSE). 4 | 5 | THIS CODE IS FOR CHANNEL ESTIMATION IN IEEE 802.11p PHYSICAL LAYER 6 | USE Matlab version 2016b 7 | Please find the detail about code in below article and cite it if you use this code in your work. 8 | 9 | Wang, T.; Hussain, A.; Cao, Y.; Gulomjon, S. An Improved Channel Estimation Technique for IEEE 802.11p Standard in Vehicular Communications. Sensors 2019, 19, 98. 10 | 11 | --------------------------------------------------------------------------------