function bbFUN(action)

%**************************************************************%
%This functions is intended for use with the bbGUI.m file.  It %
%contains the code necessary to run the GUI's simulations and  %
%controls.						       %
%                                                              %
%Copyright (C) 1997 by the Regents of the University of        %
%Michigan.                                                     %
%**************************************************************%

%The Callback for the Run Button%
if action == 1
    g=-9.8;
    A=[0 1 0 0;0 0 -5/7*g 0;0 0 0 1;0 0 0 0];
    B=[0;0;0;1];
    C=[1 0 1 0];
    D=[0];	
    
%Get the poles from the editable text in the GUI%
    realhandle = findobj('Tag','realtext');
    real = eval(get(realhandle,'String'));
    imaghandle = findobj('Tag','imagtext');
    imag = eval(get(imaghandle,'String'));
    p1=real+imag*i;
    p2=real-imag*i;
    p3handle = findobj('Tag','pole3');
    p3=eval(get(p3handle,'String'));
    p4handle = findobj('Tag','pole4');
    p4=eval(get(p4handle,'String'));

%Place the poles and create the K-matrix%    
    K=place(A,B,[p1,p2,p3,p4]);

%Store the K-matrix in the GUI.    
    Khandle = findobj('Tag','Kframe');
    set(Khandle,'Value',K);  
    
%Get the value of the step input from the step slider%    
    stephandle = findobj('Tag','stepslider');
    stepval=get(stephandle,'Value');
    stepaxis=stepval;
       
%The following Lines represent the rscale function to find Nbar%
%The reference input checkbox is checked for its value, also%
    Nbarhandle = findobj('Tag','Checkbox3');
    Nbarval = get(Nbarhandle,'Value');
    if Nbarval == 0
        Nbar = 1
        Nbarfhandle = findobj('Tag','Nbarframe');
        set(Nbarfhandle,'Value',Nbar);
        stepaxis=stepval/1000;      
    elseif Nbarval == 1
        s = size(A,1);
        Z = [zeros([1,s]) 1];
        N = inv([A,B;C,D])*Z';
        Nx = N(1:s);
        Nu = N(1+s);
        Nbar=Nu + K*Nx;
        Nbarfhandle = findobj('Tag','Nbarframe');
        set(Nbarfhandle,'Value',Nbar);  
    end    
    
%Check if the system is linear or non-linear from checkbox%    
    syshandle = findobj('Tag','syscheckbox');
    sysval = get(syshandle,'Value');

%Linear System Simulation%    
    if sysval == 0     
       T = 0:0.05:6;                  
       U = stepval*ones(size(T));             
       [Y,X]=lsim(A-B*K,B*Nbar,C,D,U,T); 
       ball=X(:,1);    
       theta=X(:,3);

%Non-Linear System Simulation%    
    else 
       t0=0;
       tfinal=6;
       x0=[0 0 0 0];
	   v=version;
	   if eval(v(1))>=5
       	      'Please wait while simulation is running'
       	      [T,X]=ode23('bbFUNODE',[t0 tfinal],x0);
	   else	
	      tol=1e-5;
	      'Please wait while simulation is running'
	      [T,X]=ode45('bbFUNODE',t0,tfinal,x0,tol);
	   end
       ball=X(:,1);
       theta=X(:,3);  
    end

%Store the values of ballx anf theta%    
    ballhandle = findobj('Tag','ballxframe');
    set(ballhandle,'Value',ball);
    thetahandle = findobj('Tag','thetaframe');
    set(thetahandle,'Value',theta);
    timehandle = findobj('Tag','timeframe');
    set(timehandle,'Value',T);
    
%Set ball and beam characteristics for animation% 
    ball=ball*100; 
    beam_length = 100;  
    bl2 = beam_length/2;
    radius = 3;              %Ball radius% 
    arcstep = 36;
    ballx=ball.*cos(theta);     
    bally = - ballx .* tan(theta) + radius;  
    j = 0:arcstep:(360-arcstep);  
    arcx = radius * cos((j+arcstep) * pi/180);  
    arcy = radius * sin((j+arcstep) * pi/180);  
    beamx1 = -bl2 * cos(theta);  
    beamx2 = bl2 * cos(theta);  
    beamy1 = bl2 * sin(theta);  
    beamy2 = -bl2 * sin(theta);

%Check if the step response is to be plotted seperately%
    handle2 = findobj('Tag','Checkbox2');
    value2=get(handle2,'Value');   
    if value2 == 1
       subplot(2,2,2)
       plot(T,ball)
    else
       subplot(2,2,2) 
       plot(T(1),ball(1), 'EraseMode', 'none')
    end

%Assign values for the axis based on the value of stepval%
    if stepval > 0
       axis([0 6 0 stepaxis*200])
    elseif stepval < 0
       axis([0 6 stepaxis*200 0])
    else
       axis([0 6 -50 50])
    end

%Add title, xlabel, and ylabel to the step response plot%   
    title(sprintf('Step Response to %2.2f cm input',stepval*100))
    ylabel('Ball Position (cm)')
    xlabel('Time (sec)') 
   
    hold on

%Plot the first element of the ball and beam with title,etc...%
    subplot(2,2,4)
    L = plot([beamx1(1) beamx2(1)], [beamy1(1) beamy2(1)], 'r', 'EraseMode',...
    'xor','LineWidth',[3]);
    axis([-55 55 -55 55]); 
    title('Animation')
    xlabel('Horizontal Position (cm)')
    ylabel('Vertical Position (cm)') 
    H = patch(arcx+ballx(1), arcy+bally(1), 'b', 'EraseMode', 'xor');

%Check if the graphs should advance manuallly%  
    handle = findobj('Tag','Checkbox');
    value=get(handle,'Value');
    if value == 1
       'Press any key to advance the animation'
       pause
       
    end   

%For-loop runs the animation%   
    ltheta=length(theta);
    for k = 2:ltheta-1,  

    %Manual advance% 	      
       if value == 1
           pause
       end
     
    %Set ball and beam data and draw the new coordinates% 
       set(L, 'XData', [beamx1(k) beamx2(k)]);  
       set(L, 'YData', [beamy1(k) beamy2(k)]);  
       set(H, 'XData', arcx+ballx(k));  
       set(H, 'YData', arcy+bally(k));  
       drawnow;
    
    %Check if ball is still on the beam%
       if ball(k) > 50
          subplot(2,2,4)	
          text(-25,25,'Ball has fallen off beam!')
          return
       end 		
    
    %Plot response with animation%     
       if value2 == 0	
          subplot(2,2,2)
          plot([T(k),T(k+1)],[ball(k),ball(k+1)], 'EraseMode', 'none')
       end
      	
    end
   
   
   
%The Callback for the Reset Button%
elseif action == 2	   

%Clears the step response axis%
    subplot(2,2,2)
    cla
    axis([0 5 0 50])
    ylabel('Ball Position (cm)')
    xlabel('Time (sec)')
    title('Step Response')

%Returns ball and beam to their zero conditions%      
    beam_length = 100; 
    bl2 = beam_length/2;
    radius = 3.0; 
    arcstep = 36;
    ballx = 0;
    bally = - ballx .* tan(0) + radius; 
    j = 0:arcstep:(360-arcstep); 
    arcx = radius * cos((j+arcstep) * pi/180); 
    arcy = radius * sin((j+arcstep) * pi/180); 
    beamx1 = -bl2 * cos(0); 
    beamx2 = bl2 * cos(0); 
    beamy1 = bl2 * sin(0); 
    beamy2 = -bl2 * sin(0);
    subplot(2,2,4)
    L = plot([beamx1(1) beamx2(1)], [beamy1(1) beamy2(1)], 'r', 'EraseMode', ...
      'xor','LineWidth',[3]);
    axis([-55 55 -55 55]);
    title('Animation')
    xlabel('Horizontal Position (cm)')
    ylabel('Vertical Position (cm)')
    H = patch(arcx+ballx(1), arcy+bally(1), 'b', 'EraseMode', 'xor');    	
  
%Callback for viewing the current value of the step-slider%
elseif action == 3
    stephandle = findobj('Tag','stepslider');
    stepval=get(stephandle,'Value')*100;
    curhandle = findobj('Tag','curtext');
    set(curhandle,'String',sprintf('%6.2f',stepval));             

%Callback for the Repeat button%
elseif action == 4
%Get the stored values of ballx, theta, and time%
    ballhandle = findobj('Tag','ballxframe');
    ball=get(ballhandle,'Value');
    thetahandle = findobj('Tag','thetaframe');
    theta=get(thetahandle,'Value');
    timehandle = findobj('Tag','timeframe');
    T=get(timehandle,'Value');
    
 
%Set ball and beam characteristics for animation% 
    ball=ball*100; 
    beam_length = 100;  
    bl2 = beam_length/2;
    radius = 3;              %Ball radius% 
    arcstep = 36;
    ballx=ball.*cos(theta);     
    bally = - ballx .* tan(theta) + radius;  
    j = 0:arcstep:(360-arcstep);  
    arcx = radius * cos((j+arcstep) * pi/180);  
    arcy = radius * sin((j+arcstep) * pi/180);  
    beamx1 = -bl2 * cos(theta);  
    beamx2 = bl2 * cos(theta);  
    beamy1 = bl2 * sin(theta);  
    beamy2 = -bl2 * sin(theta);

%Check if the step response is to be plotted seperately%
    handle2 = findobj('Tag','Checkbox2');
    value2=get(handle2,'Value');   
    if value2 == 1
       subplot(2,2,2)
       plot(T,ball)
    else
       subplot(2,2,2) 
       plot(T(1),ball(1), 'EraseMode', 'none')
    end

%Assign values for the axis based on the value of stepval%
    stephandle = findobj('Tag','stepslider');
    stepval=get(stephandle,'Value');
    
    Nbarhandle = findobj('Tag','Checkbox3');
    Nbarval = get(Nbarhandle,'Value');
    if Nbarval == 1
       stepaxis=stepval;
    else
       stepaxis=stepval/1000;   
    end
    
    if stepval > 0
       axis([0 6 0 stepaxis*200])
    elseif stepval < 0
       axis([0 6 stepaxis*200 0])
    else
       axis([0 6 -50 50])
    end

%Add title, xlabel, and ylabel to the step response plot%   
    title(sprintf('Step Response to %2.2f cm input',stepval*100))
    ylabel('Ball Position (cm)')
    xlabel('Time (sec)') 
   
    hold on

%Plot the first element of the ball and beam with title,etc...%
    subplot(2,2,4)
    L = plot([beamx1(1) beamx2(1)], [beamy1(1) beamy2(1)], 'r', 'EraseMode',...
    'xor','LineWidth',[3]);
    axis([-55 55 -55 55]); 
    title('Animation')
    xlabel('Horizontal Position (cm)')
    ylabel('Vertical Position (cm)') 
    H = patch(arcx+ballx(1), arcy+bally(1), 'b', 'EraseMode', 'xor');

%Check if the graphs should advance manuallly%  
    handle = findobj('Tag','Checkbox');
    value=get(handle,'Value');

%For-loop runs the animation%   
    ltheta=length(theta);
    for k = 2:ltheta-1,  

    %Manual advance% 	      
       if value == 1
           pause
       end
     
    %Set ball and beam data and draw the new coordinates% 
       set(L, 'XData', [beamx1(k) beamx2(k)]);  
       set(L, 'YData', [beamy1(k) beamy2(k)]);  
       set(H, 'XData', arcx+ballx(k));  
       set(H, 'YData', arcy+bally(k));  
       drawnow;
    
    %Check if ball is still on the beam%
       if ball(k) > 50
          subplot(2,2,4)	
          text(-25,25,'Ball has fallen off beam!')
          return
       end 		
    
    %Plot response with animation%     
       if value2 == 0	
          subplot(2,2,2)
          plot([T(k),T(k+1)],[ball(k),ball(k+1)], 'EraseMode', 'none')
       end
      	
    end


end  
 
 
 
