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)');