Przetwarzanie sygnałów w systemach MIMO
Autorzy: Paweł Turcza
Pliki: rozdzial_24.zip
Przyklad dekoder ML i MMSE w systemie MIMO
Przykład dekodowania strumienia danych w systemie MIMO (2, 2), tj. w systemie wyposażonym w dwie anteny nadawcze i dwie odbiorcze.
Program (plik mimo_bpsk.m) wyznacza bitowa stopę błędów (BER) osiąganą przez dekodery ML i MMSE w przypadku transmisji z modulacją BPSK dla kanału radiowego z zanikami Rayleigh'a. BER wyznaczany jest w funkcji stosunku sygnału-do-szumu (Eb_N0_dB). Celem oceny zysku wynikającego ze stosowania systemu konkretnego dekoder wyznaczone wartości BER(Eb/NO) zestawione są z wartościami teoretycznymi dla systemów SISO i MRC. Przyjęto, ze łączna moc emitowana przez anteny nadawcze, w obu wariantach systemu MIMO, jest równa mocy emitowanej przez pojedyncza antenę nadawcza systemu SISO. Przy porównywaniu systemów należny pamiętać, ze system MIMO pracuje z dwukrotnie większa przepustowością jak system SISO oraz MRC. Oznacza to, ze energia przypadająca na jeden transmitowany bit w systemie MIMO jest o polowe mniejsza jak w systemie SISO.
% Przyklad implementacji dekoderow ML i MMSE w systemie MIMO (2, 2) clear; close all randn('seed',0); rand('seed',0); N = 10^6; % liczba transmitowanych symboli Eb_N0_dB = [0:25]; % Eb/N0 [dB] nTx = 2; nRx = 2; fprintf('start symulacji\n'); % probki czasowe realizacji kanalu MIMO Rayleigha (nRx, nTx) h = 1/sqrt(2)*[randn(nRx, nTx, N/nTx) + j*randn(nRx, nTx, N/nTx)]; % szum AWGN o wariancji 1 (0dB) n = 1/sqrt(2)*[randn(nRx, N/nTx) + j*randn(nRx, N/nTx)]; % generacja strumienia danych (bit stream) bs = rand(1,N)>0.5; % modulacja BPSK 0 -> -1; 1 -> 0 s = 2*bs-1; % przeksztalcenie sygnalu s w macierzy o wymiarach [nRx, nTx, N/NTx] % celem transmisji przez kanal MIMO h % najpierw powielenie nRx razy x = repmat(s, nRx, 1); % potem, rozdzialenie na NTx anten nadawczych x = reshape(x, [nRx, nTx, N/nTx]); % transmisja przez kanal h r = sum(h.*x, 2); r = squeeze(r); for i = 1:length(Eb_N0_dB) fprintf('------- Eb/N0 = %d [dB]\n', Eb_N0_dB(i)); % sygnal odbierany zaszumiony y = r + 10^(-Eb_N0_dB(i)/20)*n; %%dekoder ML rVec = []; % wszystkie mozliwe kombinacje bitow dla dwoch anten nadawczych i modulacji BPSK x_ref = [1 1; ... 1 0; ... 0 1; ... 0 0 ]; % wyznacz odleglosci dla wszystkich kombinacji z x_ref for k=1:size(x_ref, 1) % modulacja BPSK 0 -> -1; 1 -> 0 s = 2*x_ref(k,:)-1; x_hat = repmat(s, [nRx ,N/2]); x_hat = reshape(x_hat, [nRx,nTx,N/nTx]); z_hat = squeeze(sum(h.*x_hat, 2)) ; J = sum(abs(y - z_hat), 1); rVec = [rVec; J]; end % znajdz kombinacje symboli dajaca najmniejszy blad [jj dd] = min(rVec,[],1); % konwertuj symbole na bity bs_hat(1:2:N) = x_ref(dd, 1); bs_hat(2:2:N) = x_ref(dd, 2); % wyznacz BER nErr_ML(i) = sum(bs ~= bs_hat); fprintf('dekoder ML: BER= %.3d\n', nErr_ML(i)/N); %%dekoder MMSE % Utworzenie macierzy hInv = inv(h' * h + N_0^2*I) % najpierw budujemy: [a b; c d] = h' * h + N_0^2*I N0 = 10^(-Eb_N0_dB(i)/20); a = sum( conj(h(:,1,:)) .* h(:,1,:), 1) + N0^2; b = sum( conj(h(:,1,:)) .* h(:,2,:), 1); c = sum( conj(h(:,2,:)) .* h(:,1,:), 1); d = sum( conj(h(:,2,:)) .* h(:,2,:), 1) + N0^2; % nastepnie: hInv=inv([a b; c d]) = 1/(ad-bc)[d -b;-c a] hInv = zeros(2,2,N/nTx); D = a.*d - b.*c; % ad-bc hInv(1,1,:) = d./D; hInv(1,2,:) = -b./D; hInv(2,1,:) = -c./D; hInv(2,2,:) = a./D; % Utworzenie macierzy W = hInv * h' W = zeros(2,2,N/nTx); W(1,1,:) = sum( hInv(1,:,:) .* conj(h(1,:,:)), 2); W(1,2,:) = sum( hInv(1,:,:) .* conj(h(2,:,:)), 2); W(2,1,:) = sum( hInv(2,:,:) .* conj(h(1,:,:)), 2); W(2,2,:) = sum( hInv(2,:,:) .* conj(h(2,:,:)), 2); % dekoder strumienia z anteny 1 w1 = squeeze(W(1,:,:)); y1 = sum(w1.*y); % dekoder strumienia z anteny 2 w2 = squeeze(W(2,:,:)); y2 = sum(w2.*y); % polacz strumienie transmitowane przez anten 1 i 2 w jeden strumien % odpowiadajacy strumieniowi oryginalnemu y_hat = zeros(1,N); y_hat(1:2:end) = y1; y_hat(2:2:end) = y2; % dekoder bpsk (kwantyzacja) bs_hat = real(y_hat)>0; % wyznacz BER nErr_MMSE(i) = sum(bs ~= bs_hat); fprintf('dekoder MMSE: BER= %.3d\n', nErr_ML(i)/N); end Ber_ML = nErr_ML/N; Ber_MMSE = nErr_MMSE/N; Eb_N0 = 10.^(Eb_N0_dB/10); Ber_SISO = 0.5.*(1-1*(1+1./Eb_N0).^(-0.5)); p = 1/2 - 1/2*(1+1./Eb_N0).^(-1/2); Ber_MRC_nRx2 = p.^2.*(1+2*(1-p)); figure; title('Modulacja BPSK, kanal Rayleigha'); xlabel('Eb/No [dB]'); ylabel('BER'); semilogy(Eb_N0_dB, Ber_SISO, 'bp-', ... Eb_N0_dB, Ber_MMSE, 'ro-', ... Eb_N0_dB, Ber_ML,'mo-', ... Eb_N0_dB, Ber_MRC_nRx2, 'kd-', 'LineWidth',2); axis([0 25 10^-5 0.5]); grid on legend( 'SISO (nTx=1,nRx=1)', 'MMSE (nTx=2, nRx=2)', 'ML (nTx=2, nRx=2)', 'MRC (nTx=1,nRx=2)');
Przyklad Kodowanie Alamoutiego
W przykładzie pokazano zasadę działania dekodera Alamoutiego w wersji z dwiema antenami nadawczymi i jedną anteną odbiorczą.
Program (plik alamouti_bpsk_r1.m) wyznacza bitowa stopę błędów (BER) osiąganą przez dekodery Alamoutiego w przypadku transmisji z modulacją BPSK dla kanału radiowego z zanikami Rayleigh'a. BER wyznaczany jest w funkcji stosunku sygnału-do-szumu (Eb_N0_dB). Celem oceny zysku wynikającego ze stosowania dekodera Alamoutiego , wyznaczone wartości BER(Eb/NO) zestawione są z wartościami teoretycznymi dla systemów SISO i MRC (dwie anteny odbiorcze). W programie przyjęto, że łączna moc emitowana przez anteny nadawcze jest równa mocy emitowanej przez pojedyncza antenę nadawcza systemu SISO i MRC. Oznacza to, że w przypadku systemu z kodowaniem Alamoutiego moc przypadająca na jedną antenę nadawczą jest o połowę mniejsza niż moc w systemie z dekoderem MRC.
% Przyklad kodowania Alamoutiego, % modulacja BPSK, dwie anteny nadawcze, jedna odbiorcza clear; close all randn('seed',0); rand('seed',0); N = 10^6; % liczba transmitowanych symboli Eb_N0_dB = [0:25]; % Eb/N0 % kanal z zanikami Rayleigh'a h1 = 1/sqrt(2)*[randn(1,N/2) + j*randn(1,N/2)]; h2 = 1/sqrt(2)*[randn(1,N/2) + j*randn(1,N/2)]; % wektor szumu AWGN o wariancji 1 (0dB) n1 = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; % strumienia danych (bit stream) bs = rand(1,N)>0.5; % modulacja BPSK 0 -> -1; 1 -> 0 x = 2*bs-1; % kodowanie Alamoutiego: antena 1: [x1, x2] -> [x1, x2*] a1 = zeros(1,N); a1(1:2:end) = x(1:2:end); a1(2:2:end) = conj(x(2:2:end)); % kodowanie Alamoutiego: antena 2: [x1, x2] -> [x2, -x1*] a2 = zeros(1,N); a2(1:2:end) = x(2:2:end); a2(2:2:end) = -conj(x(1:2:end)); % sygnal odbierany r1 = a1/sqrt(2) .* kron(h1, [1 1]) + a2/sqrt(2) .* kron(h2, [1 1]); % wyznaczenie BER dla roznych poziomow szumu for i = 1:length(Eb_N0_dB) % sygnal odbierany zaszumiony y = r1 + 10^(-Eb_N0_dB(i)/20) * n1; % rozdzielenie na dwie szczeliny y1 = sqrt(2) * y(1:2:end); y2 = sqrt(2) * y(2:2:end); % dekoder Alamoutiego(2,1) H2 = abs(h1).^2 + abs(h2).^2; x1_hat = conj(h1) .* y1 - h2 .* conj(y2); x2_hat = conj(h2) .* y1 + h1 .* conj(y2); % utworz jeden strumien x_hat(1:2:N) = x1_hat./H2; x_hat(2:2:N) = x2_hat./H2; % dekoder BPSK bs_hat = real(x_hat) > 0; % liczba blednie zdekodowanych symboli nErr_A21(i) = sum(bs ~= bs_hat); end % wyznacza BER Ber_Alamouti21 = nErr_A21/N; % BER dla kanalu Rayleigh i modulacji BPSK if(0) % BER ze wzoru teoretycznego Eb_N0_Lin = 10.^(Eb_N0_dB/10); Ber_SISO = 1/2*(1-1./sqrt(1+1./Eb_N0_Lin)); else % BER wyznaczony symulacyjnie h = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; %kanal % sygnal odbierany r = h .* x; for i = 1:length(Eb_N0_dB) % sygnal odbierany zaszumiony y = r + 10^(-Eb_N0_dB(i)/20) * n1; % dekoder BPSK x_hat = y./h; bs_hat = real(x_hat) > 0; % liczba blednie zdekodowanych symboli nErr_SISO(i) = sum(bs ~= bs_hat); end Ber_SISO = nErr_SISO/N; end % BER dla dekodera MRC, kanal Rayleigh, modulacja BPSK if(0) % BER ze wzoru teoretycznego Eb_N0_Lin = 10.^(Eb_N0_dB/10); p = 1/2 - 1/2*(1+1./Eb_N0_Lin).^(-1/2); Ber_MRC_nRx2 = p.^2.*(1+2*(1-p)); else % BER wyznaczony symulacyjnie n2 = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; %szum AWGN h1 = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; %kanal Tx->Rx1 h2 = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; %kanal Tx->Rx2 r1 = h1 .* x; % sygnal odbierany przez antene nr 1 r2 = h2 .* x; % sygnal odbierany przez antene nr 2 for i = 1:length(Eb_N0_dB) % sygnal odbierany zaszumiony y1 = r1 + 10^(-Eb_N0_dB(i)/20) * n1; y2 = r2 + 10^(-Eb_N0_dB(i)/20) * n2; % dekoder MRC x_hat = (y1 .* conj(h1) + y2 .* conj(h2)) ./ (h1.*conj(h1) + h2.*conj(h2)); % dekoder BPSK bs_hat = real(x_hat) > 0; % liczba blednie zdekodowanych symboli nErr_MRC_nRx2(i) = sum(bs ~= bs_hat); end Ber_MRC_nRx2 = nErr_MRC_nRx2/N; end figure; title('Modulacja BPSK, kanal Rayleigha'); xlabel('Eb/No, dB'); ylabel('BER'); semilogy(Eb_N0_dB, Ber_SISO, 'bp-', ... Eb_N0_dB, Ber_Alamouti21,'mo-', ... Eb_N0_dB, Ber_MRC_nRx2,'kd-', 'LineWidth',2); axis([0 25 10^-5 0.5]); grid on legend( 'SISO (nTx=1, nRx=1)', ... 'Alamouti (nTx=2, nRx=1)', ... 'MRC (nTx=1, nRx=2)');