0
$\begingroup$

I am trying to design a Nth order continous time Butterworth filter in state space, with pole placement technique.

n = varargin{1}
Fc = this.fc 
wc = 2*pi*Fc;
T = 1/(2*pi*Fc);
%----------------Finding Poles--------------------------
 p = exp(1i*(pi*(1:2:n-1)/(2*n) + pi/2)); %n is the order of the filter
                 p = [p; conj(p)];
                 p = p(:);
                 if rem(n,2)==1   % n is odd
                     p = [p; -1];
                 end
%----------------Finding Filter co efficents---------------
                 if length(p)<= 2
                    a = conv([1,-p(1)],[1,-p(2)]);
                end
                if length(p) > 2
                    a = conv([1,-p(1)],[1,-p(2)]);
                    for i = 3: length(p)
                        a = conv(a,[1,-p(i)]);
                    end
                end
                a = real(a)
                a = fliplr(a);
%----------------- calculating the matricies%-----------------

            %--------------A matrix---------------
            N = length(a)-1;% order of the matrix
            last_row = (a(1:end-1))*(-1/a(end));% creating the last row

             last_row = (wc.^(N:-1:1)).*last_row;% creating the last row

            k = ones(1,N-1);
            this.x = diag(k,1) ; % diag(vector, k) produce a matrix filled with zero's and k'th off diagonal as vector, in this  case, 1's.
            this.x(end,:) = last_row;% adding the last_row

            %-------------desiging B matrix--------------
            this.y = zeros(N,1); % creates a coloumn matrix with zeros
            this.y(N,:) = 1/(a(end)*wc^n); % writes last elements as a

            %--------------- writing C matrix--------------
            this.z = zeros(1,N); %creates a row matrix
            this.z(1,1) = 1;

            %------------ writing the D matrix----------------

            this.u = [0];

I know the code is bit lengthy, but i have tried everything, but can't figure out where i am going wrong. Because I am not getting any error. The resultant output is just 0. The code is pretty simple, I find the poles, then the filter coefficients. with the filter coefficients. i design A,B;C,D Matrices. This is a continuous butterworth filter, Can anyone point the mistake i am doing?

edit1: A low pass PT2 filter: enter image description here

A low pass 2nd order butterworth filter: enter image description here

$\endgroup$
6
  • $\begingroup$ Your code looks OK. How do you compute the output? $\endgroup$
    – Matt L.
    Sep 21, 2016 at 8:08
  • $\begingroup$ I discretize the filter, and apply it to my signal. I have another filter which works fine, i will show you the output. Maybe you can compare. Are you sure i compute A,B,C,D matrices correctly? I have a doubt about my A matrix $\endgroup$ Sep 21, 2016 at 8:45
  • $\begingroup$ I took same configuration for both filter, same order, same Fc, same Ts. $\endgroup$ Sep 21, 2016 at 8:51
  • $\begingroup$ So you used the same code to implement both filters using SS matrices? How did you obtain the matrices for the PT2 filter? $\endgroup$
    – Matt L.
    Sep 21, 2016 at 10:41
  • $\begingroup$ I did not use same code for implementation of both filter, i said the parameters used for both the plot is same, my another PT2 filter is general PTn filter which is achieved by cascading of low pass PT1 filter. I have edited the code. $\endgroup$ Sep 21, 2016 at 11:49

1 Answer 1

1
$\begingroup$

I think I found the problem. Everything was fine except for the denormalization step for arbitrary cut-off frequencies wc. I changed the following lines to obtain the correct state-space matrices (and to handle the case n=1):

...
if (n == 1)
    a = [1,1];
else
    p = ...
    ...
end

a = real(a);
a = a./(wc.^(n:-1:0))   % new!
a = fliplr(a);
...

% last_row = (wc.^(N:-1:1)).*last_row;    % removed!

if( n == 1)
    this.x = last_row;
else
    k = ones(1,N-1);
    this.x = diag(k,1) ;
    this.x(end,:) = last_row;
end

...

this.y(N,:) = 1/a(end);    % changed!

...

I used the function ss2tf to compute the polynomial coefficients from the state-space matrices computed above, and the coefficients were correct for different values of wc. This means that the matrices are correct. If the output signal is still different from what you expect, the problem must be in the filtering routine.

$\endgroup$
5
  • $\begingroup$ Thank you! Oh my god! But i have a problem when i choose 1st order, above 2nd order everything works fine. but when i give 1st order i get this error. Attempted to access p(2); index out of bounds because numel(p)=1. Error in ltiFilter.PTn/test1 (line 29) a = conv([1,-p(1)],[1,-p(2)]); I kinda understand how this is happening, but not entirely sure. any idea? Again thank you! $\endgroup$ Sep 21, 2016 at 14:26
  • $\begingroup$ i did some debugging, I think i will hard code the filter coeffcients if the order is 1. seems like a simple fix $\endgroup$ Sep 21, 2016 at 14:37
  • $\begingroup$ Ok i thought i would hard code these values when the order is 1, A= [-1/wc]; B = [1]; C = [1]; D = [0]; I am clearly missing something, any idea? $\endgroup$ Sep 21, 2016 at 14:43
  • $\begingroup$ @user5603723: I added some code for handling the case n=1. It's a quick hack but I think it should work. $\endgroup$
    – Matt L.
    Sep 21, 2016 at 17:40
  • $\begingroup$ I am not yet allowed to upvote, but accepted. Thank you! $\endgroup$ Sep 22, 2016 at 6:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.