Archive

Archive for September, 2012

create_signal_flow

September 26, 2012 1 comment

A function that produces a signal flow diagram of a discrete system given b and a coefficients

% Create a signal flow diagram given a set of b and a coefficients of a
% discrete system
%
% example usage: 
%    b = [ 2 -0.5]; 
%    a = [1 -.025]
%    create_signal_flow(b, a)
%
% By David Dorran, david.dorran@dit.ie, September 2012.
% with thanks to Richard Hayes for excellent guidence on character display
% using Latex. Not so much thanks for the suggestion to remove the
% multiplier.

function create_signal_flow(b,a)
% The diagram consists of lines, arrows, boxes and circles. The following
% variables set up the dimiensions of these components.
x_arrow = 0.2;
y_arrow_original = 0.9;
y_arrow = y_arrow_original;
arrow_len = 0.1;
delay_line_len = 0.1;
mult_line_len = 0.02;
circle_dia = 0.05;
box_width = 0.05;
y_increment = -delay_line_len-box_width;

% Check that the parameters passed to the function are oc
if(length(b) < 1)
    error('There must be at least one b coefficient');
end
if(length(b) > 6 | length(a) > 6)
    error('Unfortunately the max number of coeeficients is 6');
end

%make the output arrow longer if there is feedback in the system
if(length(a) > 1)
    op_len_mult =3.5;
else
    op_len_mult =1;
end


figure
annotation('textbox', [x_arrow-0.1 y_arrow-delay_line_len/2-box_width/2+0.01 box_width box_width],'fontname','Times New Roman','fontsize',16,'String', '\it{x}', 'LineStyle','none' , 'HorizontalAlignment','Center' ,'VerticalAlignment','middle');


if(length(b) > 1 | length(a) > 1)
    annotation('textbox', [x_arrow+arrow_len+circle_dia+arrow_len+circle_dia+arrow_len*op_len_mult+0.01 y_arrow-delay_line_len/2-box_width/2+0.01 box_width box_width],'fontname','Times New Roman','fontsize',16,'String', '\ity', 'LineStyle','none' , 'HorizontalAlignment','Center' ,'VerticalAlignment','middle');
else
    annotation('textbox', [x_arrow+arrow_len+circle_dia+arrow_len+0.01 y_arrow-delay_line_len/2-box_width/2+0.01 box_width box_width],'fontname','Times New Roman','fontsize',16,'String', '\ity', 'LineStyle','none' , 'HorizontalAlignment','Center' ,'VerticalAlignment','middle');
end
annotation('line', [x_arrow-0.05 x_arrow+arrow_len],[y_arrow-delay_line_len/2 y_arrow-delay_line_len/2] );

%multiplier
annotation('ellipse', [x_arrow+arrow_len y_arrow-circle_dia/2-delay_line_len/2 circle_dia circle_dia] );
annotation('line', [x_arrow+arrow_len+circle_dia/4 x_arrow+arrow_len+3*circle_dia/4],[y_arrow+circle_dia/4-delay_line_len/2 y_arrow-circle_dia/4-delay_line_len/2] );
annotation('line', [x_arrow+arrow_len+circle_dia/4 x_arrow+arrow_len+3*circle_dia/4],[y_arrow-circle_dia/4-delay_line_len/2 y_arrow+circle_dia/4-delay_line_len/2] );
annotation('arrow', [x_arrow+arrow_len+circle_dia x_arrow+arrow_len+circle_dia+arrow_len],[y_arrow-delay_line_len/2 y_arrow-delay_line_len/2] );

%multiplier value
annotation('line', [x_arrow+arrow_len+circle_dia/2 x_arrow+arrow_len+circle_dia/2],[y_arrow-circle_dia/2-mult_line_len-delay_line_len/2 y_arrow-circle_dia/2-delay_line_len/2] );
annotation('Textbox', [x_arrow+arrow_len y_arrow-circle_dia/2-mult_line_len-box_width-delay_line_len/2 box_width box_width ],  'String', num2str(b(1)), 'LineStyle','none' , 'HorizontalAlignment','Center' ,'VerticalAlignment','middle');

%An adder is only required if there are delays in the system
if(length(b) > 1 | length(a) > 1)
    %adder
    annotation('ellipse', [x_arrow+arrow_len+circle_dia+arrow_len y_arrow-circle_dia/2-delay_line_len/2 circle_dia circle_dia] );
    annotation('line', [x_arrow+arrow_len+circle_dia+arrow_len+circle_dia/4 x_arrow+arrow_len+circle_dia+arrow_len+3*circle_dia/4],[y_arrow-delay_line_len/2 y_arrow-delay_line_len/2] );
    annotation('line', [x_arrow+arrow_len+circle_dia+arrow_len+circle_dia/2 x_arrow+arrow_len+circle_dia+arrow_len+circle_dia/2],[y_arrow+circle_dia/4-delay_line_len/2  y_arrow-circle_dia/4-delay_line_len/2 ] );    
    annotation('arrow', [x_arrow+arrow_len+circle_dia+arrow_len+circle_dia x_arrow+arrow_len+circle_dia+arrow_len+circle_dia+arrow_len*op_len_mult],[y_arrow-delay_line_len/2 y_arrow-delay_line_len/2] );
end

%Add a feedforward delay line for each b coefficient
for k = 2: length(b)    
    if(k == max([length(a) length(b)]) & length(a)~= length(b))
        line_extra = circle_dia/2;
        line_type = 'line' ;
    else
        line_extra = 0;
        line_type = 'arrow' ;
    end
    
    % delay box feedforward
    annotation('line', [x_arrow x_arrow],[y_arrow-delay_line_len/2 y_arrow-delay_line_len] );
    annotation('rectangle', [x_arrow-box_width/2 y_arrow-delay_line_len-box_width box_width box_width  ] );
    annotation('textbox', [x_arrow-box_width/2 y_arrow-delay_line_len-box_width box_width box_width  ], 'String', 'D' , 'HorizontalAlignment','Center' ,'VerticalAlignment','middle');
    annotation('line', [x_arrow x_arrow],[y_arrow-delay_line_len-box_width y_arrow-3*delay_line_len/2-box_width] );
    
    %line to multiplier
    annotation('line', [x_arrow x_arrow+arrow_len],[y_arrow-3*delay_line_len/2-box_width y_arrow-3*delay_line_len/2-box_width] );
    
    %multiplier
    annotation('ellipse', [x_arrow+arrow_len y_arrow-3*delay_line_len/2-box_width-circle_dia/2 circle_dia circle_dia] );
    annotation('line', [x_arrow+arrow_len+circle_dia/4 x_arrow+arrow_len+3*circle_dia/4],[y_arrow-3*delay_line_len/2-box_width-circle_dia/4 y_arrow-3*delay_line_len/2-box_width+circle_dia/4] );
    annotation('line', [x_arrow+arrow_len+circle_dia/4 x_arrow+arrow_len+3*circle_dia/4],[y_arrow-3*delay_line_len/2-box_width+circle_dia/4 y_arrow-3*delay_line_len/2-box_width-circle_dia/4] );
    
    %line out of multiplier
    annotation(line_type, [x_arrow+arrow_len+circle_dia x_arrow+arrow_len*2+circle_dia+line_extra],[y_arrow-3*delay_line_len/2-box_width y_arrow-3*delay_line_len/2-box_width] );
    
    % multiplier value
    annotation('line', [x_arrow+arrow_len+circle_dia/2 x_arrow+arrow_len+circle_dia/2],[y_arrow-3*delay_line_len/2-box_width-circle_dia/2 y_arrow-3*delay_line_len/2-box_width-circle_dia/2-mult_line_len] );
    annotation('textbox', [x_arrow+arrow_len+circle_dia/2-box_width/2  y_arrow-3*delay_line_len/2-box_width-circle_dia/2-mult_line_len-box_width box_width box_width],  'String', num2str(b(k)), 'LineStyle','none' , 'HorizontalAlignment','Center' ,'VerticalAlignment','middle' );
    
    %Adder
    if(k ~= max([length(a) length(b)])  | length(a) == length(b))
        annotation('ellipse', [x_arrow+arrow_len*2+circle_dia y_arrow-3*delay_line_len/2-box_width-circle_dia/2 circle_dia circle_dia] );
        annotation('line', [x_arrow+arrow_len*2+circle_dia+circle_dia/2 x_arrow+arrow_len*2+circle_dia+circle_dia/2],[y_arrow-3*delay_line_len/2-box_width-circle_dia/4 y_arrow-3*delay_line_len/2-box_width+circle_dia/4] );
        annotation('line', [x_arrow+arrow_len*2+circle_dia+circle_dia/4 x_arrow+arrow_len*2+circle_dia+3*circle_dia/4],[y_arrow-3*delay_line_len/2-box_width y_arrow-3*delay_line_len/2-box_width] );
    end
    %line out of adder
    annotation('arrow', [x_arrow+arrow_len*2+circle_dia+circle_dia/2 x_arrow+arrow_len*2+circle_dia+circle_dia/2],[y_arrow-3*delay_line_len/2-box_width+circle_dia/2-line_extra y_arrow-delay_line_len/2-circle_dia/2]);
    
    y_arrow = y_arrow+y_increment;
end
y_arrow = y_arrow_original;
x_arrow = x_arrow+(arrow_len+circle_dia+arrow_len+circle_dia/2)*2;
for k = 2: length(a)
    %
    if(k == max([length(a) length(b)]) & length(a)~= length(b))
        line_extra = circle_dia/2;
        line_type = 'line' ;
    else
        line_extra = 0;
        line_type = 'arrow' ;
    end
    
    
    % delay box feedforward
    annotation('line', [x_arrow x_arrow],[y_arrow-delay_line_len/2 y_arrow-delay_line_len] );
    annotation('rectangle', [x_arrow-box_width/2 y_arrow-delay_line_len-box_width box_width box_width  ] );
    annotation('textbox', [x_arrow-box_width/2 y_arrow-delay_line_len-box_width box_width box_width  ], 'String', 'D' , 'HorizontalAlignment','Center' ,'VerticalAlignment','middle');
    annotation('line', [x_arrow x_arrow],[y_arrow-delay_line_len-box_width y_arrow-3*delay_line_len/2-box_width] );
    
    %line to multiplier
    annotation('line', [x_arrow x_arrow-arrow_len],[y_arrow-3*delay_line_len/2-box_width y_arrow-3*delay_line_len/2-box_width] );
    
    %multiplier
    annotation('ellipse', [x_arrow-arrow_len-circle_dia y_arrow-3*delay_line_len/2-box_width-circle_dia/2 circle_dia circle_dia] );
    annotation('line', [x_arrow-arrow_len-circle_dia/4 x_arrow-arrow_len-3*circle_dia/4],[y_arrow-3*delay_line_len/2-box_width-circle_dia/4 y_arrow-3*delay_line_len/2-box_width+circle_dia/4] );
    annotation('line', [x_arrow-arrow_len-circle_dia/4 x_arrow-arrow_len-3*circle_dia/4],[y_arrow-3*delay_line_len/2-box_width+circle_dia/4 y_arrow-3*delay_line_len/2-box_width-circle_dia/4] );
    
    
    %line out of multiplier
    annotation(line_type, [x_arrow-arrow_len-circle_dia x_arrow-arrow_len*2-circle_dia-line_extra],[y_arrow-3*delay_line_len/2-box_width y_arrow-3*delay_line_len/2-box_width] );
    
    % multiplier value
    annotation('line', [x_arrow-arrow_len-circle_dia/2 x_arrow-arrow_len-circle_dia/2],[y_arrow-3*delay_line_len/2-box_width-circle_dia/2 y_arrow-3*delay_line_len/2-box_width-circle_dia/2-mult_line_len] );
    annotation('textbox', [x_arrow-arrow_len-circle_dia/2-box_width/2  y_arrow-3*delay_line_len/2-box_width-circle_dia/2-mult_line_len-box_width box_width box_width],  'String', num2str(-1*a(k)/a(1)), 'LineStyle','none' , 'HorizontalAlignment','Center' ,'VerticalAlignment','middle' );
    
    %Adder
    
    if(k ~= max([length(a) length(b)]) | length(a)== length(b))
        annotation('ellipse', [x_arrow-arrow_len*2-circle_dia*2 y_arrow-3*delay_line_len/2-box_width-circle_dia/2 circle_dia circle_dia] );
        annotation('line', [x_arrow-arrow_len*2-circle_dia-circle_dia/2 x_arrow-arrow_len*2-circle_dia-circle_dia/2],[y_arrow-3*delay_line_len/2-box_width-circle_dia/4 y_arrow-3*delay_line_len/2-box_width+circle_dia/4] );
        annotation('line', [x_arrow-arrow_len*2-circle_dia-circle_dia/4 x_arrow-arrow_len*2-circle_dia-3*circle_dia/4],[y_arrow-3*delay_line_len/2-box_width y_arrow-3*delay_line_len/2-box_width] );
    end
    %line out of adder
    annotation('arrow', [x_arrow-arrow_len*2-circle_dia-circle_dia/2 x_arrow-arrow_len*2-circle_dia-circle_dia/2],[y_arrow-3*delay_line_len/2-box_width+circle_dia/2-line_extra y_arrow-delay_line_len/2-circle_dia/2]);
    
    y_arrow = y_arrow+y_increment;
end
%end
Categories: matlab code