domingo, 13 de abril de 2014

Simulação: equalizando um canal de comunicação digital

Fonte da figura aqui.

Quando falamos "canal digital" quase sempre não estamos sendo 100% precisos. Na maioria das vezes não se trata de fato de um "canal digital", mas um canal de comunicação (analógico) pelo qual trafega alguma informação digital.

Feito esse esclarecimento, vamos ao passo seguinte: o canal de comunicação causa uma distorção ao sinal. Essa distorção pode ser pequena ou muito significativa, vai depender, entre outros fatores, da taxa de bits, distância entre transmissor e receptor, potência do sinal transmitido, linearidade dos amplificadores usados, uso de repetidores, etc. Uma das coisas que podemos fazer para mitigar o efeito do canal e tentar manter a taxa de erro baixa é usar um equalizador no receptor que irá, aproximadamente, compensar o canal.

O equalizador é um filtro digital (FIR ou IIR), em geral, de coeficientes ajustáveis, pois o canal, em especial os canais sem fio, são variantes no tempo. Existem técnicas que podem avaliar o comportamento do canal e, automaticamente, ajustar os coeficientes do equalizador.

No código Scilab abaixo é suposto que o canal é conhecido para o cálculo dos coeficientes "ótimos" do equalizador segundo os critérios "zero forcing" e MSE. Em seguida, os coeficientes são encontrados iterativamente usando um algoritmo LMS de passo fixo*. Adicionalmente, as curvas teóricas para a evolução dos coeficientes e para curva de aprendizagem são apresentadas. 

* Para saber mais sobre essa sopa de siglas, consultar, por exemplo, Digital Communications de J. G. Proakis.

Se você conseguiu chegar até aqui (parabéns!), é hora de encarar o código Scilab. Note que existem, propositalmente**, poucos comentários. Agora chegou a sua vez de colocar uns dois ou três neurônios para funcionar. Bom estudo!

** a forma mais "culta" e indicada é propositadamente, como nos ensina didaticamente o professor Daniel Vícola.

Gráficos da simulação:

Resposta ao impulso do canal; zeros do canal; resposta em frequência, sinal {-1, +1} após o canal.
Diagrama de olho após o canal; diagrama de olho do sinal antes do canal; sinal equalizado (ZF) e sinal equalizado (MSE).
Equalização adaptativa (LMS); curva de aprendizado (erro médio quadrático).

Evolução dos coeficientes do equalizador; curva de aprendizado (erro) simulada e teórica.

Código Scilab:

clear; clc; close; close; close;

// canal:
h=[0.7, -0.35, 0.25, 0.15, -0.1];
// Equalizador zero forcing:
H=[h(1),0,0,0,0
   h(2),h(1),0,0,0
   h(3),h(2),h(1),0,0
   h(4),h(3),h(2),h(1),0
   h(5),h(4),h(3),h(2),h(1)];
wz = pinv(H)*[1;0;0;0;0];
hw = convol(h,wz); disp(hw);
X=[h,0,0,0,0
   0,h,0,0,0
   0,0,h,0,0
   0,0,0,h,0
   0,0,0,0,h];
Rx = X*X' + 0.01*eye(5,5);
v=zeros(9,1); v(1)=1; p = X*v;
wx = inv(Rx)*p;
Jmin = 1 - 2*p'*wx + wx'*Rx*wx;
hwx = convol(h,wx); disp(hwx);

// resposta em freq. do canal:
w=0:0.01:%pi;
z=exp(-%i*w); zk=z;
hz = h(1) + h(2)*z;
for k=3:5
    zk = zk.*z;
    hz = hz + h(k)*zk;
end
hza = abs(hz);
// zeros do canal:
zr = roots(h);
cc=cos(2*w); ss=sin(2*w);
//sinal após o canal:
N = 699;
a = sign(rand(1,N,'n'));
af = filter(h,1,a);
n = 0.1*rand(1,N,'n');
af = af + n;
// gráficos:
figure;
subplot(2,2,1); plot2d3(h); plot(h,'o');xgrid;
subplot(2,2,2); plot(cc,ss,real(zr),imag(zr),'o'); xgrid;
subplot(2,2,3); plot(w,hza); xgrid;
subplot(2,2,4); plot(1:N,af,'.'); xgrid;
// olho:
figure;
p1 = 1; p2 = 3; subplot(2,2,1);
for k=1:25
    plot(1:3,af(p1:p2));
    p1 = p2; p2 = p1 + 2;
end
an = a + n/5;
p1 = 1; p2 = 3;
subplot(2,2,2);
for k=1:15
    plot(1:3,an(p1:p2));
    p1 = p2;  p2 = p1 + 2;
end

// filtrando/equalizando o sinal:
az = filter(wz,1,af);
ax = filter(wx,1,af);
subplot(2,2,3); plot(1:N,az,'.'); xgrid;
subplot(2,2,4); plot(1:N,ax,'.'); xgrid;
// filtragem adaptativa (LMS):
wc = zeros(5,N);
wa = 0*wx; // inicializando
mi = 0.025; // passo de adaptação
d = a; // sinal desejado - treinamento
y = 0*a;  // sinal equalizado - saida
e = y;  // inicializando o vetor de erro
for k=5:N
    y(k) = wa'*(af(k-4:k))';
    e(k) = d(k) - y(k);
    wa = wa + mi*e(k)*(af(k-4:k))';
    wc(:,k) = wa;
end
e2 = e.*e;
figure;
subplot(2,1,1); plot(1:N,y,'.'); xgrid;
subplot(2,1,2); plot(1:N,e2); xgrid;
// filtragem adaptativa (LMS) - gerando uma curva de erro média:
for mm=1:39
a = sign(rand(1,N,'n'));
af = filter(h,1,a); n = 0.1*rand(1,N,'n'); af = af + n;
wa = 0*wx; // inicializando
d = a; // sinal desejado - treinamento
yk = 0;  // sinal equalizado - saida
e=0*a;
for k=5:N
    yk = wa'*(af(k-4:k))';
    e(k) = d(k) - yk;
    wa = wa + mi*e(k)*(af(k-4:k))';
    wc(:,k) = wc(:,k) + wa;
end
e2 = e2 + e.*e;
end;
e2 = e2/(mm+1);
wc = wc/(mm+1);
subplot(2,1,2); plot(1:N,e2,'r',[1, N],[Jmin, Jmin],'k'); xgrid;
wkk = zeros(5,N); wk=0*wx;
I5 = eye(5,5); ek2 = 1+0*e2;
for k=5:N
    wk = (I5 - mi*Rx)*wk + mi*p;
    wkk(:,k) = wk;
    ek2(k) = 1 - 2*p'*wk + wk'*Rx*wk;
end;
figure;
subplot(2,1,1); plot(1:N,wc,'k',1:N,wkk); xgrid;
subplot(2,1,2); plot(1:N,e2,1:N,ek2); xgrid;

Nenhum comentário:

Postar um comentário