% Cmdhndlr- Version 2.0
%
%  This is an event handler for the cscra.m screen
%
% 7/17/98 - Changes made to support lower resolutions
% 8/30/98 - Changes made to support Bode Design
% 11/7/98 - Background plant with foreground compensated system
%
%
%   Written by Raymond C. Garcia
%              Georgia Institute of Technology
%              Atlanta, Georgia
%              gt7877c@prism.gatech.edu






% This event handler has the following functions:
%
%function qlocus(n,d)
%function mv(type,point,mode)
%function setlocus
%function clrgain
%function clraxes(tag,type,mode)
%function rtsdif=chkdif(obj,rts,mode)
%function del(type,point,mode)
%function movelocus
%function subflocus
%function [exists,h]=chkfig(tag)
%function add2locus
%function stataction(tag)
%function runstep
%function setvis(mat,vtype)
%function chggain(type)
%function cfont(type,x)
%function setalt(x)
%function on=getrad(tag)
%function setrad(tag1,tag2)
%function clrflds(x)
%function modset(tag,prop,val)                           
%function [val]=modget(tag,prop)                         
%function [sys,err]=gettf(x)
%function settf(num,den)
%function flag = inrect(tag)
%function setstat(str)
%function stripz(vect)

function cmdhndlr(action)
   global cdata;
   global stpfunstr;
   global qbodedsgnstr;
   cmdmsg=cell(1,10);
   cmdmsg{1}='Enter the numerator and the denominator of the plant and compensator in the spaces provided.  The default is to enter the coefficients in descending order of s separated by spaces or commas; there is no need for brackets.';
   cmdmsg{2}='';
   cmdmsg{3}='For example,';
   cmdmsg{4}='      if G(s) = 10(s+2)/(s^2+2s+5) then';
   cmdmsg{5}='enter 10 20 in the numerator field and 1 2 5 in the denominator field.';
   cmdmsg{6}='';
   cmdmsg{7}='You also have the option of entering the poles and zeros; in this case, just enter the values separated by commas.  The above transfer function is entered as -2 in the numerator field and -1+2j, -1-2j in the denominator field.';
   cmdmsg{8}='';
   cmdmsg{9}='The coefficients for a simple proportional compensator should be entered as constants.';
   cmdmsg{10}='';
   cmdmsg{11}='For example,';
   cmdmsg{12}='     if G(s) = 10 then';
   cmdmsg{13}='10 is entered in the numerator field and a 1 in the denominator field.';
   cmdmsg{14}='';
   cmdmsg{15}='The gain can be entered in the command window or in the root locus window. The transfer functions are displayed in the command window in either polynomial form or factored form.  The font size can be increased or decreased by clicking on the +" and "-" buttons next to the "Display" label.';
   cmdmsg{16}='';
   cmdmsg{17}='Click on the "Root locus" button to view the root locus and the corresponding closed loop step response.';
   cmdmsg{18}='';
   cmdmsg{19}='Click on the "Bode" button to view the open loop Bode plot.';  

   rlmsg=cell(1,17);
   rlmsg{1}='Gain Adjust:';
   rlmsg{2}='The compenator gain can be changed by entering a value in the keyboard field or by using the mouse.  To use the mouse, click on the "Mouse" button in the "Gain Adjustment" area.  The resulting crosshairs can be positioned over the desired point on the root locus; click on the point to set the gain.';  
   rlmsg{3}='';
   rlmsg{4}='Adding a pole/zero:';
   rlmsg{5}='Select your choice - pole or zero, real or complex - then click on "Add".  Position the crosshairs over the desired point and click the mouse (if the "Complex" choice was selected , then the conjugate will be added as well).';
   rlmsg{6}='';
   rlmsg{7}='Removing a pole/zero:';
   rlmsg{8}='Click the "Remove" button.  Position the crosshairs over the pole/zero to be removed and then click the mouse. Since this tool is for compensator design, only compensator poles/zeros can be removed or moved.  Their positions are highlighted during root placement while the plant poles/zeros are not.';
   rlmsg{9}='';
   rlmsg{10}='Moving a pole/zero:';
   rlmsg{11}='Click on the "Move" button. Position the crosshairs over the pole/zero to be moved and push the mouse button down.  Move the cursor to a new position and let up the mouse button; the root locus and closed loop step response will refresh on the button up action.  If you move the mouse slowly while keeping the button down, you will also see updates while the mouse is being moved.  Since this tool is for compensator design, only compensator poles/zeros can be moved.  Their positions are highlighted during root placement while the plant poles/zeros are not.';
   rlmsg{12}='';
   rlmsg{13}='Statistics:';
   rlmsg{14}='The closed loop pole positions can be seen from the pull-down menu item labeled "Statistics". The damping ratio and natural frequency are shown for complex poles.';
   rlmsg{15}='';
   rlmsg{16}='Known bugs:';
   rlmsg{17}='The Control System Toolbox version 4.0 has some bugs in the root locus command.  These bugs will affect this program.  So if your root locus is incorrect, it is probably due to the bug in the root locus command.';

   bdmsg=cell(1,17);
   bdmsg{1}='Gain Adjust:';
   bdmsg{2}='The compenator gain (in dB) can be changed by entering a value in the keyboard field or by using the mouse.  To use the mouse, click on the "Mouse" button in the "Gain Adjustment" area.  The resulting crosshairs can be positioned over the desired point on the magnitude plot; click on the point to set the gain.';  
   bdmsg{3}='';
   bdmsg{4}='Adding a pole/zero:';
   bdmsg{5}='Select your choice - pole or zero - then click on "Add".  Position the crosshairs over the desired point and click the mouse.';
   bdmsg{6}='';
   bdmsg{7}='Removing a pole/zero:';
   bdmsg{8}='Click the "Remove" button.  Position the crosshairs over the pole/zero to be removed and then click the mouse. Since this tool is for compensator design, only compensator poles/zeros can be removed or moved.  Their positions are highlighted during root placement while the plant poles/zeros are not.';
   bdmsg{9}='';
   bdmsg{10}='Moving a pole/zero:';
   bdmsg{11}='Click on the "Move" button. Position the crosshairs over the pole/zero to be moved and push the mouse button down.  Move the cursor to a new position and let up the mouse button; the frequency response as well as other open windows will refresh on the button up action.  If you move the mouse slowly while keeping the button down, you will also see updates while the mouse is being moved.  Since this tool is for compensator design, only compensator poles/zeros can be moved.  Their positions are highlighted during root placement while the plant poles/zeros are not.';
   bdmsg{12}='';
   bdmsg{13}='Statistics:';
   bdmsg{14}='The closed loop pole positions can be seen from the pull-down menu item labeled "Statistics". The damping ratio and natural frequency are shown for complex poles.';
   bdmsg{15}='';
   bdmsg{16}='Gain and Phase Margins:';
   bdmsg{17}='The gain and phase margins are given in the bottom right of the window.  When appropriate, the Zero-dB and -180 degree crossover points are also given.';

   stpmsg=cell(1,2);
   stpmsg{1}='Step Response:';
   stpmsg{2}='The closed loop step response corresponding to the selected compensator is shown in this window.  Performance variables can be displayed on the graph.  Select the desired items from the "Performance" pull down menu.  An item can be deselected by clicking on the item a second time.';

   switch (action)
      case 'btnmotion'
         % check to see if the mouse passes over any field.  if so, set the status field.
         if inrect('edtnum')
            if getrad('rdcoef')
               setstat('Enter NUMERATOR coeffs (i.e. 2s^2 + 1 => [2 0 1]).');
            else
               setstat('Enter ZEROES (i.e. (s + 2)(s + 4) => [2 4]).');
            end
         elseif inrect('btnplus')
            setstat('Click to INCREASE font size of display.');
         elseif inrect('btnminus')
            setstat('Click to DECREASE font size of display.'); 
         elseif inrect('edtden')
            if getrad('rdcoef')
               setstat('Enter DENOMINATOR coeffs (i.e. 2s^2 + S + 1 => [2 1 1]).');
            else
               setstat('Enter POLES (i.e. (s + 2)(S + 9)(s + 4) => [2 9 4]).');
            end 
         elseif inrect('btnbode')
            setstat('Click here to generate a BODE plot.');
         elseif inrect('btnlocus')
            setstat('Click here to generate a ROOT LOCUS plot.');
         elseif inrect('btnstep')
            setstat('Click here to generate a plot of the STEP RESPONSE.');
         elseif inrect('txttf')
            setstat('This is an ALTERNATE form of the input function.');
         elseif inrect('rdpz')
            setstat('Select to enter polynomial in POLES and ZEROES.');
         elseif inrect('rdcoef')
            setstat('Select to enter polynomial in COEFFICIENTS.');
         elseif inrect('rdpoly')
            setstat('Select to display in POLYNOMIAL form.');
         elseif inrect('rdfact')
            setstat('Select to display in FACTORED form.');
         else
            setstat('Place the mouse over any object for HELP.')
         end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%% Menu Action %%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'mnucmdmsg'
         helpdlg(cmdmsg,'Command Window Help - Getting Started');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%% Edit fields %%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'edtnump'                                     %
         % check that both num and den are not empty     %
         % and update the alt field                      %
         setalt('p');                                    %
      case 'edtdenp'                                     %
         % check that both num and den are not empty     %    
         % and update the alt field                      %
         setalt('p');                                    %
      case 'edtnumc'                                     %
         % check that both num and den are not empty     %
         % and update the alt field                      %
         setalt('c');                                    %
      case 'edtdenc'                                     %
         % check that both num and den are not empty     %     
         % and update the alt field                      %
         setalt('c');                                    %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% radio buttons for the root locus %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'rdpole'                       %
         setrad('rdpole','rdzero');       %
      case 'rdzero'                       %
         setrad('rdzero','rdpole');       %
      case 'rdreal'                       %
         setrad('rdreal','rdcomplex');    %
      case 'rdcomplex'                    %
         setrad('rdcomplex','rdreal');    %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%% Radio button for pole and zero %%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'rdpzp'                                                      %
         setrad('rdpzp','rdcoefp');  %update the radio buttons          %
         clrflds('p'); % clear the edit fields and the alt form field   %
      case 'rdpzc'                                                      %
         setrad('rdpzc','rdcoefc');  %update the radio buttons          %
         clrflds('c'); % clear the edit fields and the alt form field   %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%% Radio button for coefficient entering %%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'rdcoefp'                                                    %
         setrad('rdcoefp','rdpzp');                                     %
         clrflds('p'); % clear the edit fields and the alt form field   %
      case 'rdcoefc'                                                    %
         setrad('rdcoefc','rdpzc');                                     %
         clrflds('c'); % clear the edit fields and the alt form field   %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%% Radio button for polynomial display %%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'rdpolyp'                                   %
         setrad('rdpolyp','rdfactp');                  %
         setalt('p');                                  %
      case 'rdpolyc'                                   %
         setrad('rdpolyc','rdfactc');                  %
         setalt('c');                                  %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%% Radio button for factored display %%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'rdfactp'                                   %
         setrad('rdfactp','rdpolyp');                  %
         setalt('p');                                  %
      case 'rdfactc'                                   %
         setrad('rdfactc','rdpolyc');                  %
         setalt('c');                                  %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Bode plot button %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'btnbode'                                                              %
            [sys,err]=gettf('full');                                              %
            if ~(err)                                                             %
               [gm,pm,wcg,wcp] = margin(sys);
              %
               wmin = min(min(wcg,wcp)/10,.1);
               if wmin==0
                  wmin=1e-2;
               end                                   %
               wmax = max(max(wcg,wcp)*10,1e2);                                   %
               deltaw=(wmax-wmin)/1e3;
               [exists,hndl]=chkfig('bode');
               if ~exists         %
                  figure;                                                            %
               else  
                  figure(hndl);
                  clf;
               end
               %qbode(sys,wmin:deltaw:wmax);                                       %
               bode(sys,{wmin,wmax});
               hndls=get(gcf,'children');
               pmstr=sprintf('     PHASE Margin (deg): %0.5g',pm);                %
               gmstr=sprintf('GAIN Margin (dB): %0.5g',gm);                       %
               set(hndls(1:2),'nextplot','add');
               if ~isnan(wcp)
                  axes(hndls(2));
                  plot([wmin wmax],[0 0],'k-.');
                  wpstr=sprintf('   Zero dB Crossover @ %0.4g',wcp);
                  wpstr=strvcat(' ',' ',wpstr);
                  plot(wcp,0,'ro');
                  h=text(wcp,0,wpstr);
                  set(h,'verticalalignment','bottom');
               end

               axes(hndls(1));
               if ~isnan(wcg)
                  plot([wmin wmax],[-180 -180],'k-.');
                  wcstr=sprintf('  -180^o Crossover @ %0.4g',wcg);
                  wcstr=strvcat(' ',' ',wcstr);
                  plot(wcg,-180,'ro');
                  h=text(wcg,-180,wcstr);
                  set(h,'verticalalignment','bottom');
               end
               title(strcat(gmstr,pmstr));                                        %
               set(gcf,'numbertitle','off','name','Bode Plot Window','tag','bode');            %
            end                                                                   %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%% Plus and minus buttons for the font size %%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'btnplusp'                                     %
         cfont('plus','p');                               %
      case 'btnminusp'                                    %
         cfont('minus','p');                              %
      case 'btnplusc'                                     %
         cfont('plus','c');                               %
      case 'btnminusc'                                    %
         cfont('minus','c');                              %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%% Button for the step response %%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'btnstep'                            %
         [exists,hndl]=chkfig('step');          %
         if ~exists                             %
            figure;
            % set up the figure and the menu               
            set(gcf,'units','normalized','numbertitle','off','name','Step Response Window', ...
               'position',[0   0.04333333333333   0.99500000000000   0.39000000000000],'tag','step'); 
            
            b = uimenu('Parent',gcf, ...
                        'Callback','cmdhndlr(''mnustpmsg'')',...
                     	'Label','&Instructions', ...
                     	'Tag','mnustpmsg');
            b = uimenu('Parent',gcf, ...
                     	'Label','&Performance', ...
                     	'Tag','mnuperf');
            c = uimenu('Parent',b, ...
                  	'Callback','cmdhndlr(''mnumaxos'')', ...
                     'checked','off', ...
                  	'Label','Max % Overshoot', ...
                   	'Tag','mnumaxos');
            c = uimenu('Parent',b, ...
                  	'Callback','cmdhndlr(''mnupeak'')', ...
                     'checked','off', ...
                  	'Label','Peak Value', ...
                  	'Tag','mnupeak');
            c = uimenu('Parent',b, ...
                  	'Callback','cmdhndlr(''mnufinal'')', ...
                     'checked','off', ...
                  	'Label','Final Value', ...
                  	'Tag','mnufinal');
            c = uimenu('Parent',b, ...
                  	'Callback','cmdhndlr(''mnurise'')', ...
                     'checked','off', ...
                  	'Label','Rise Time', ...
                  	'Tag','mnurise');
            c = uimenu('Parent',b, ...
                     'separator','on', ...
                     'checked','off', ...
                  	'Label','Settling Time', ...
                  	'Tag','mnuset');
               d = uimenu('parent',c, ...
                        'callback', 'cmdhndlr(''mnuts2'')', ...
                        'checked','off', ...
                        'label','2% Time', ...
                        'tag','mnuts2');
   
               d = uimenu('parent',c, ...
                        'callback', 'cmdhndlr(''mnuts5'')', ...
                        'checked','off', ...
                        'label','5% Time', ...
                        'tag','mnuts5');
                                %
         else                                   %
            figure(hndl);                       %
            cla reset;
         end                                    %
         runstep;                               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%% Step Response menu actions %%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'mnustpmsg'
         helpdlg(stpmsg,'Step Response Help');
      case 'mnufinal'                           %
         stataction('mnufinal');                %
      case 'mnurise'                            %
         stataction('mnurise');                 %
      case 'mnumaxos'                           %
         stataction('mnumaxos');                %
      case 'mnuts2'                             %
         stataction('mnuts2');                  %
      case 'mnuts5'                             %
         stataction('mnuts5');                  %
      case 'mnupeak'                            %
         stataction('mnupeak');                 %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%% Root Locus Button %%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'btnlocus'                                          %
            [sys,err]=gettf('full');
            if ~(err)                                          %
               cdata=cell(1,14);
               [exists,h]=chkfig('figlocus');                  %
               if exists                                       %
                  figure(h);                                   %
               else                                            %
                  figure;                                      %
                  setlocus;                                       % 
               end                                             %
               rlocus(sys);
               set(gca,'tag','axlocus');
               cmdhndlr('edtgain');                                    %
               cmdhndlr('btnstep');                            %
               [exists,hndl]=chkfig('figstats'); 
               if exists
                  cmdhndlr('mnurstats');
               end         %
            end                                                %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%% Root locus control buttons %%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'btnadd'                                            %
         add2locus;                                            %
         cmdhndlr('btnstep');
         cmdhndlr('edtgain');
      case 'btnmove'                                           %
         [sys,err]=gettf('c');                                 %
         [num,den]=tfdata(sys,'v');                            %
         if num==1 & den==1                                    %
            errordlg('There are no compensator poles or zeroes to MOVE.','Nothing to move','replace');
         else                                                  %                      
            movelocus;                                         %
         end                                                   %
                                                               %
      case 'btnremove'                                         %
         [sys,err]=gettf('c');                                 %
         [num,den]=tfdata(sys,'v');                            %
         if num==1 & den==1
            errordlg('There are no compensator poles or zeroes to REMOVE.','Nothing to remove','replace');
         else                                    %                      
            subflocus;                                         %
         end
                                                   %                                                            %
      case 'edtgain'
         gain=str2num(modget('edtgain','string'));
         modset('txtnumc','userdata',gain);                    %
         hax=findobj('tag','axlocus');
         [sys,err]=gettf('full');
         [num,den]=tfdata(sys,'v');
         num=num*gain;
         rts=rlocus(sys,gain);
         clrgain;
         axes(hax);
         rlocus(tf(num,den));
         set(gca,'tag','axlocus');
         hold on;
         indx=rts==max(real(rts));
         for x=1:length(indx)
            if indx(x)
               break;
            end
         end
         plot(real(rts),imag(rts),'r+');
         if imag(rts(x,1))
            ht=text(real(rts(x,1)),imag(rts(x,1)),strcat(' K=',num2str(gain)));  %
         else
            gainstr=strvcat(' ',' ',strcat(' K=',num2str(gain)));
            ht=text(real(rts(x,1)),imag(rts(x,1)),gainstr);  %
         end
         set(ht,'fontunits','normalized','fontsize',0.0674810936591041);
         hold off;
         cmdhndlr('btnstep');
         [exists,hndl]=chkfig('figstats'); 
         if exists
            cmdhndlr('mnurstats');
         end
         [exists,hndl]=chkfig('bode'); 
         if exists
            cmdhndlr('btnbode');
         end         %
         %
      case 'btngain'                                           %
         [sys,err]=gettf('full');                              %
         if ~err 
            clrgain;                                           %
            [k,poles]=rlocfind(sys);                           %
            modset('txtnumc','userdata',k);                    %
            modset('edtgain','string',num2str(k));             %
            ylim=get(gca,'ylim');
            pos=get(gca,'currentpoint');
            if abs(pos(2,2))>.1*abs(ylim(2)-ylim(1))                       %
               ht=text(pos(2,1),pos(2,2),strcat(' K=',num2str(k)));  %
            else
               gainstr=strvcat(' ',' ',strcat(' K=',num2str(k)));
               ht=text(pos(2,1),0,gainstr);  %
            end
            set(ht,'fontunits','normalized','fontsize',0.0674810936591041);
            cmdhndlr('btnstep');
            [exists,hndl]=chkfig('figstats'); 
            if exists
               cmdhndlr('mnurstats');
            end
            [exists,hndl]=chkfig('bode'); 
            if exists
               cmdhndlr('btnbode');
            end         %
         end                                                   %

      case 'delpole'
%         disp('delpole');
         cp=get(gca,'currentpoint');
         del('pole',cp(1,1:2),'rl');
         cmdhndlr('edtgain');
      case 'delzero'
%         disp('delzero');
         cp=get(gca,'currentpoint');
         del('zero',cp(1,1:2),'rl');
         cmdhndlr('edtgain');
     case 'mvpole'
%         disp('mvpole');
         cp=get(gca,'currentpoint');
         mv('pole',cp(1,1:2),'rl');
         [exists,hndl]=chkfig('bode'); 
         if exists
            cmdhndlr('btnbode');
         end         %
         [exists,hndl]=chkfig('figstats'); 
         if exists
            cmdhndlr('mnurstats');
         end         %
      case 'mvzero'
%         disp('mvzero');
         cp=get(gca,'currentpoint');
         mv('zero',cp(1,1:2),'rl');
         [exists,hndl]=chkfig('bode'); 
         if exists
            cmdhndlr('btnbode');
         end         %
         [exists,hndl]=chkfig('figstats'); 
         if exists
            cmdhndlr('mnurstats');
         end         %
      case 'moveRZ'
         % userdata contains the following:
         %   [axis_handle object_type roots number_type cnum_rts cden_rts pnum_rts pden_rts handles handles handles handles rl_gains]
         %cdata=get(gcf,'userdata');

         hax=cdata{1};
         type=cdata{2};
         rts=cdata{3};
         numtype=cdata{4};
         cnum=cdata{5}';
         cden=cdata{6}';
         pnum=cdata{7}';
         pden=cdata{8}';
         cp=get(hax,'currentpoint');

         % set up for a real zero
         nrts=[rts cp(1,1)];
         x=cp(1,1);
         y=0;
         cdata{5}=nrts';
         num=poly([pnum nrts]);
         den=poly([pden cden]);
         mark='ko';

         settf(poly(cdata{5}'),poly(cdata{6}'));
         qstep;
         axes(hax);
         set(hax,'tag','axtemp');
         qlocus(num,den,x,y,mark,hax);
         %set(gcf,'userdata',cdata);
      case 'moveIZ'
         % userdata contains the following:
         %   [axis_handle object_type roots number_type cnum_rts cden_rts pnum_rts pden_rts handles handles handles handles rl_gains]
         %cdata=get(gcf,'userdata');

         hax=cdata{1};
         type=cdata{2};
         rts=cdata{3};
         numtype=cdata{4};
         cnum=cdata{5}';
         cden=cdata{6}';
         pnum=cdata{7}';
         pden=cdata{8}';
         cp=get(hax,'currentpoint');

         % set up for an imaginary zero
         nrts=[rts cp(1,1)+j*cp(1,2) cp(1,1)-j*cp(1,2)];
         x=[cp(1,1) cp(1,1)];
         y=[cp(1,2) -cp(1,2)];
         cdata{5}=nrts';
         num=poly([pnum nrts]);
         den=poly([pden cden]);
         mark='ko';

         settf(poly(cdata{5}'),poly(cdata{6}'));
         qstep;
         axes(hax);
         set(hax,'tag','axtemp');
         qlocus(num,den,x,y,mark,hax);

      case 'moveRP'
         % userdata contains the following:
         %   [axis_handle object_type roots number_type cnum_rts cden_rts pnum_rts pden_rts handles handles handles handles rl_gains]

         hax=cdata{1};
         type=cdata{2};
         rts=cdata{3};
         numtype=cdata{4};
         cnum=cdata{5}';
         cden=cdata{6}';
         pnum=cdata{7}';
         pden=cdata{8}';
         cp=get(hax,'currentpoint');

         % set up for a real pole
         nrts=[rts cp(1,1)];
         x=cp(1,1);
         y=0;
         cdata{6}=nrts';
         den=poly([pden nrts]);
         num=poly([pnum cnum]);
         mark='kx';

         settf(poly(cdata{5}'),poly(cdata{6}'));
         qstep;
         axes(hax);
         set(hax,'tag','axtemp');
         qlocus(num,den,x,y,mark,hax);
     case 'moveIP'
         % userdata contains the following:
         %   [axis_handle object_type roots number_type cnum_rts cden_rts pnum_rts pden_rts handles handles handles handles rl_gains]

         hax=cdata{1};
         type=cdata{2};
         rts=cdata{3};
         numtype=cdata{4};
         cnum=cdata{5}';
         cden=cdata{6}';
         pnum=cdata{7}';
         pden=cdata{8}';
         cp=get(hax,'currentpoint');

         % set up for an imaginary pole
         nrts=[rts cp(1,1)+j*cp(1,2) cp(1,1)-j*cp(1,2)];
         x=[cp(1,1) cp(1,1)];
         y=[cp(1,2) -cp(1,2)];
         cdata{6}=nrts';
         den=poly([pden nrts]);
         num=poly([pnum cnum]);
         mark='kx';

         settf(poly(cdata{5}'),poly(cdata{6}'));
         qstep;
         axes(hax);
         set(hax,'tag','axtemp');
         qlocus(num,den,x,y,mark,hax);
      case 'btnup' 
         set(gcf,'pointer','arrow','windowbuttonupfcn','','windowbuttonmotionfcn','');
         %cdata=get(gcf,'userdata');
         num=poly([cdata{5}' cdata{7}']);
         den=poly([cdata{6}' cdata{8}']);
         settf(poly(cdata{5}'),poly(cdata{6}'));
         setalt('c');
         delete(cdata{1});
         rlocus(tf(num,den));
         set(gca,'tag','axlocus');
         cmdhndlr('edtgain');                                    %
      case 'mnurstats'   % user selected the root statistics from the root locus window
          [sys,err]=gettf('full');
         if ~err
            [exists,hndl]=chkfig('figstats');
            if ~exists
               stats; % open the stats window
            else
               figure(hndl);
            end
            gain=modget('txtnumc','userdata');
            namestr=sprintf('Statistics for Roots @ K = %0.5g',gain);
            set(gcf,'name',namestr);
            rts=rlocus(sys,gain);
            modset('pmnuroots','string',num2str(rts));
            val=modget('pmnuroots','value');
            if val>length(rts);
               modset('pmnuroots','value',1);
            end
            setstats(rts);
         end
      case 'mnurlmsg'
         helpdlg(rlmsg,'Root Locus Help');
      case 'pmnuroots'
         rts=str2num(modget('pmnuroots','string'));
         setstats(rts);
       
%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Bode Design Button %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'btnbodedsgn'
         stpfunstr='qstep';
         qbodedsgnstr='qbodedsgn(sys)';
         [sys,errf]=gettf('full');
         if ~(errf)
            [comp,err]=gettf('c');
            if ~(err)
               bodedsgn(sys,comp);
            end
            cmdhndlr('btnstep');                            %
            [exists,hndl]=chkfig('figstats'); 
            if exists
               cmdhndlr('mnurstats');
            end         %
         end
         
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%% Bode Design Controls %%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      case 'mnubdmsg'
         helpdlg(bdmsg,'Bode Design Help');

      case 'btnbdup' 
         set(gcf,'pointer','arrow','windowbuttonupfcn','','windowbuttonmotionfcn','');
         %cdata=get(gcf,'userdata');
         num=poly([cdata{5}' cdata{7}']);
         den=poly([cdata{6}' cdata{8}']);
         settf(poly(cdata{5}'),poly(cdata{6}'));
         setalt('c');
         delete(cdata{1});
         
         [sys,err]=gettf('full');
         
         %gaindb=getbdgain(sys);
         %modset('edtbdgain','string',num2str(gaindb));
         cmdhndlr('edtbdgain');
         [exists,hndl]=chkfig('figlocus'); 
         if exists
            cmdhndlr('btnlocus');
         end
         [exists,hndl]=chkfig('bode'); 
         if exists
            cmdhndlr('btnbode');
         end         %
         [exists,hndl]=chkfig('figstats'); 
         if exists
            cmdhndlr('mnurstats');
         end         %

         stpfunstr='qstep';
         qbodedsgnstr='qbodedsgn(sys)';
      case 'movebdRZ'
         % userdata contains the following:
         %   [axis_handle object_type roots number_type cnum_rts cden_rts pnum_rts pden_rts handles handles handles handles rl_gains]
         %cdata=get(gcf,'userdata');

         hax=cdata{1};
         type=cdata{2};
         rts=cdata{3};
         numtype=cdata{4};
         cnum=cdata{5}';
         cden=cdata{6}';
         pnum=cdata{7}';
         pden=cdata{8}';
         cp=get(hax,'currentpoint');

         % set up for a real zero
         nrts=[rts -cp(1,1)];
         x=cp(1,1);
         y=0;
         cdata{5}=nrts';

         num=poly([pnum nrts]);
         znum=stripz(fliplr(num));
         num=num/znum(1);

         den=poly([pden cden]);
         zden=stripz(fliplr(den));
         den=den/zden(1);

         mark='ko';

         settf(poly(cdata{5}'),poly(cdata{6}'));

         [sys,err]=gettf('full');
         gaindb=20*log10(modget('txtnumc','userdata'));
         edtgainbd=str2num(modget('edtbdgain','string'));
         gaindb=gaindb + edtgainbd - getbdgain(sys);

         modset('txtnumc','userdata',10^(gaindb/20));

         eval(stpfunstr);

         eval(qbodedsgnstr);

         plot(cp(1,1),0,'ko','linewidth',2,'markersize',10);

      case 'movebdRP'
         % userdata contains the following:
         %   [axis_handle object_type roots number_type cnum_rts cden_rts pnum_rts pden_rts handles handles handles handles rl_gains]

         hax=cdata{1};
         type=cdata{2};
         rts=cdata{3};
         numtype=cdata{4};
         cnum=cdata{5}';
         cden=cdata{6}';
         pnum=cdata{7}';
         pden=cdata{8}';
         cp=get(hax,'currentpoint');

         % set up for a real pole
         nrts=[rts -cp(1,1)];
         x=cp(1,1);
         y=0;
         cdata{6}=nrts';
         
         mark='kx';

         settf(poly(cdata{5}'),poly(cdata{6}'));
         [sys,err]=gettf('full');
         gaindb=20*log10(modget('txtnumc','userdata'));
         edtgainbd=str2num(modget('edtbdgain','string'));
         gaindb=gaindb + edtgainbd - getbdgain(sys);

         modset('txtnumc','userdata',10^(gaindb/20));

         eval(stpfunstr);

         eval(qbodedsgnstr);
         plot(cp(1,1),0,'kx','linewidth',2,'markersize',10);

      case 'btnbdmove'                                           %
         [sys,err]=gettf('c');                                 %
         [num,den]=tfdata(sys,'v');                            %
         if num==1 & den==1                                    %
            errordlg('There are no compensator poles or zeroes to MOVE.','Nothing to move','replace');
         else
            edtgainbd=str2num(modget('edtbdgain','string'));
                    
            [sys,err]=gettf('full');
            gain=modget('txtnumc','userdata');
            gaindb=20*log10(gain);
            gaindb=gaindb + edtgainbd - getbdgain(sys);
            modset('txtnumc','userdata',10^(gaindb/20));
            cdata{13}=10^(gaindb/20);
            cdata{14}=edtgainbd;                                      %                      
            movebode;                                         %
         end                                                   %
                                                               %
      case 'delbdpole'
%         disp('delbdpole');
         cp=get(gca,'currentpoint');
         del('pole',[cp(1,1) 0],'bode');
         cmdhndlr('edtbdgain');
      case 'delbdzero'
%         disp('delbdzero');
         cp=get(gca,'currentpoint');
         del('zero',[cp(1,1) 0],'bode');
         cmdhndlr('edtbdgain');
      case 'mvbdpole'
%         disp('mvpole');
         cp=get(gca,'currentpoint');
         plot(cp(1,1),0,'wx','markersize',10,'linewidth',2);
         mv('pole',[cp(1,1) 0],'bode');
         cmdhndlr('btnstep');
         figure(findobj('tag','figbodedsgn'));
      case 'mvbdzero'
%         disp('mvzero');
         cp=get(gca,'currentpoint');
         plot(cp(1,1),0,'wo','markersize',10,'linewidth',2);
         mv('zero',[cp(1,1) 0],'bode');
         cmdhndlr('btnstep');
         figure(findobj('tag','figbodedsgn'));
      case 'btnbdremove'                                         %
         [sys,err]=gettf('c');                                 %
         [num,den]=tfdata(sys,'v');                            %
         if num==1 & den==1
            errordlg('There are no compensator poles or zeroes to REMOVE.','Nothing to remove','replace');
         else                                    %                      
            subfbode;                                         %
         end
      case 'btnbdadd'
         add2bode;
      case 'edtbdgain'
         edtgainbd=str2num(modget('edtbdgain','string'));
         
         [sys,err]=gettf('full');
         gain=modget('txtnumc','userdata');
         gaindb=20*log10(gain);
         gaindb=gaindb + edtgainbd - getbdgain(sys);
         modset('txtnumc','userdata',10^(gaindb/20));
         [comp,err]=gettf('c');
         bodedsgn(sys,comp);
         cmdhndlr('btnstep');

      case 'btnbdgain'
         [w,g,btn]=ginput(1);
         if btn ~= 27
            [sys,err]=gettf('full');
            gain=modget('txtnumc','userdata');
            [mag,phase]=bode(gain*sys,w);
            gaindb=20*log10(gain);
            gaindb=gaindb + g - 20*log10(mag);

            modset('txtnumc','userdata',10^(gaindb/20));
            modset('edtbdgain','string',num2str(getbdgain(sys)));

            [comp,err]=gettf('c');
            bodedsgn(sys,comp);
            cmdhndlr('btnstep');
         end   
   end

% move a pole or zero from the root locus plot   
function movebode
   h=findobj('tag','AxBodePZ');
   pos=get(h,'position');
   axes(h);
   v=axis;
   [sysc,err]=gettf('c');
   hax=axes;
   set(hax,'position',pos);
   axis(v);
   pzbode(sysc);
   set(gca,'tag','AxNewBodePZ');
   axis(v);
   clraxes('AxNewBodePZ','move','bode');
   set(gca,'visible','of');
   set(gcf,'pointer','fullcross','userdata',hax);
   set(hax,'userdata',get(hax,'currentpoint'));


% subtract a pole or zero from the root locus plot   
function subfbode
   h=findobj('tag','AxBodePZ');
   pos=get(h,'position');
   axes(h);
   v=axis;
   [sysc,err]=gettf('c');
   hax=axes;
   set(hax,'position',pos);
   axis(v);
   pzbode(sysc);
   set(gca,'tag','AxNewBodePZ');
   axis(v);
   clraxes('AxNewBodePZ','del','bode');
   set(gca,'visible','of');
   set(gcf,'pointer','fullcross');


% this function adds a pole or zero to the current
% compensator and plots the frequency response
function add2bode
   [x,y,btn]=ginput(1);
   if btn ~= 27          
      [sys,err]=gettf('c');

      [num,den]=tfdata(sys,'v');

      if getrad('rdpole')
        den=conv(den,[1 x]);
      else
        num=conv(num,[1 x]);
      end

      settf(num,den);
      setalt('c');
   
      cmdhndlr('btnbodedsgn');
   end
   

function bodedsgn(sys,comp)
   global cdata;
   [exists,h0]=chkfig('figbodedsgn');
   if ~exists         %
       h0 = figure('Units','normalized', ...
   	'Color',[0.8 0.8 0.8], ...
   	'Name','Bode Design Window', ...
   	'NumberTitle','off', ...
   	'Position',[0.0078125 0.5520833333333333 0.9873046875 0.3776041666666666], ...
   	'Tag','figbodedsgn');
   
         % Set up the figure and the bode controls
         h1 = uimenu('Parent',h0, ...
      	'Callback','cmdhndlr(''mnubdmsg'')', ...
      	'Label','&Instructions', ...
      	'Tag','mnurlmsg');
         h1 = uimenu('Parent',h0, ...
      	'Label','&Statistics', ...
      	'Tag','mnustats');
            h2 = uimenu('Parent',h1, ...
         	'Callback','cmdhndlr(''mnurstats'')', ...
         	'Label','Root Statistics', ...
         	'Tag','mnurstats');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'BackgroundColor',[0.8 0.8 0.8], ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.8536102868447082 0.04482758620689655 0.1355093966369931 0.5206896551724138], ...
      	'Style','frame', ...
      	'Tag','Frame1');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'BackgroundColor',[0.752941 0.752941 0.752941], ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.86745796241345   0.52413793103448   0.10583580613254   0.07586206896552], ...
      	'Style','frame', ...
      	'Tag','Frame3');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.85361028684471   0.64137931034483   0.13748763600396   0.23448275862069], ...
      	'Style','frame', ...
      	'Tag','Frame4');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'BackgroundColor',[0.752941 0.752941 0.752941], ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.8714144411473788 0.8379310344827586 0.09990108803165183 0.07241379310344828], ...
      	'Style','frame', ...
      	'Tag','Frame5');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'BackgroundColor',[0.752941 0.752941 0.752941], ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.86251236399604   0.23103448275862   0.11869436201780   0.23448275862069], ...
      	'Style','frame', ...
      	'Tag','Frame2');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'FontUnits','normalized', ...
      	'Callback','cmdhndlr(''btnbdgain'')', ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.8585558852621167 0.6620689655172414 0.1266073194856578 0.06896551724137931], ...
      	'String','Mouse', ...
      	'Tag','btnbdgain');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'FontUnits','normalized', ...
      	'Callback','cmdhndlr(''btnbdadd'')', ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.8803165182987142 0.3620689655172414 0.08110781404549951 0.06551724137931034], ...
      	'String','Add', ...
      	'Tag','btnbdadd');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'FontUnits','normalized', ...
      	'Callback','cmdhndlr(''btnbdremove'')', ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.8813056379821959 0.1448275862068966 0.0830860534124629 0.06896551724137931], ...
      	'String','Remove', ...
      	'Tag','btnbdremove');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'FontUnits','normalized', ...
      	'BackgroundColor',[0.752941 0.752941 0.752941], ...
      	'Callback','cmdhndlr(''rdpole'')', ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.8724035608308605 0.2689655172413793 0.05143422354104846 0.04482758620689655], ...
      	'String','Pole', ...
      	'Style','radiobutton', ...
      	'Tag','rdpole', ...
      	'Value',1);
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'FontUnits','normalized', ...
      	'BackgroundColor',[0.752941 0.752941 0.752941], ...
      	'Callback','cmdhndlr(''rdzero'')', ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.9258160237388724 0.2689655172413793 0.05341246290801187 0.04482758620689655], ...
      	'String','Zero', ...
      	'Style','radiobutton', ...
      	'Tag','rdzero');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
       	'FontUnits','normalized', ...
      	'BackgroundColor',[1 1 1], ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.86943620178042   0.53448275862069   0.10089020771513   0.05862068965517], ...
      	'String','Root Placement', ...
      	'Style','text', ...
         'Tag','StaticText1');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'FontUnits','normalized', ...
      	'BackgroundColor',[1 1 1], ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.8743818001978239 0.8448275862068966 0.09396636993076162 0.06206896551724138], ...
      	'String','Gain (dB)', ...
         'horizontalalignment','center', ...
      	'Style','text', ...
      	'Tag','StaticText1');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'BackgroundColor',[1 1 1], ...
      	'Callback','cmdhndlr(''edtbdgain'')', ...
         'FontUnits','normalized', ...
      	'FontSize',0.477366255144033, ...
      	'Position',[0.9287833827893175 0.7482758620689655 0.04747774480712166 0.07241379310344828], ...
      	'ListboxTop',0, ...
      	'Style','edit', ...
      	'Tag','edtbdgain');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'FontUnits','normalized', ...
      	'BackgroundColor',[0.752941 0.752941 0.752941], ...
      	'Callback','cmdhndlr(''rdreal'')', ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.8951533135509396 0.3068965517241379 0.04648862512363996 0.04482758620689655], ...
      	'String','Real', ...
      	'Style','radiobutton', ...
         'visible','of', ...
      	'Tag','rdreal', ...
      	'Value',1);
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'FontUnits','normalized', ...
      	'BackgroundColor',[0.752941 0.752941 0.752941], ...
      	'Callback','cmdhndlr(''rdcomplex'')', ...
      	'Position',[0.8951533135509396 0.2413793103448276 0.0712166172106825 0.05517241379310345], ...
      	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'String','Complex', ...
      	'Style','radiobutton', ...
         'visible','of', ...
      	'Tag','rdcomplex');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'FontUnits','normalized', ...
         'Callback','cmdhndlr(''btnbdmove'')', ...
      	'FontSize',0.477366255144033, ...
         'ListboxTop',0, ...
      	'Position',[0.8822947576656776 0.06206896551724138 0.08110781404549951 0.06551724137931034], ...
      	'String','Move', ...
      	'Tag','btnbdmove');
         h1 = uicontrol('Parent',h0, ...
      	'Units','normalized', ...
      	'FontUnits','normalized', ...
      	'BackgroundColor',[0.752941 0.752941 0.752941], ...
        	'FontSize',0.477366255144033, ...
      	'ListboxTop',0, ...
      	'Position',[0.8585558852621167 0.7551724137931034 0.06726013847675569 0.06206896551724138], ...
      	'String','Keyboard:', ...
      	'Style','text', ...
      	'Tag','StaticText2');
         h1 = axes('Parent',h0, ...
      	'CameraUpVector',[0 1 0], ...
      	'CameraUpVectorMode','manual', ...
      	'Color',[1 1 1], ...
      	'Position',[0.06627101879327399 0.3827586206896552 0.4035608308605341 0.5310344827586206], ...
      	'Tag','AxMag', ...
      	'XColor',[0 0 0], ...
      	'YColor',[0 0 0], ...
      	'ZColor',[0 0 0]);
         h1 = axes('Parent',h0, ...
      	'CameraUpVector',[0 1 0], ...
      	'CameraUpVectorMode','manual', ...
      	'Color',[1 1 1], ...
      	'Position',[0.5450049455984174 0.3793103448275862 0.2828882294757666 0.5310344827586206], ...
      	'Tag','AxPhase', ...
      	'XColor',[0 0 0], ...
      	'YColor',[0 0 0], ...
      	'ZColor',[0 0 0]);

         h1 = axes('Parent',h0, ...
      	'CameraUpVector',[0 1 0], ...
      	'CameraUpVectorMode','manual', ...
      	'Color',[1 1 1], ...
      	'Position',[0.06627101879327399 0.3827586206896552 0.4035608308605341 0.5310344827586206], ...
      	'Tag','PlantAxMag', ...
         'xscale','log',...
      	'XColor',[0 0 0], ...
      	'YColor',[0 0 0], ...
      	'ZColor',[0 0 0]);
         h1 = axes('Parent',h0, ...
      	'CameraUpVector',[0 1 0], ...
      	'CameraUpVectorMode','manual', ...
      	'Color',[1 1 1], ...
      	'Position',[0.5450049455984174 0.3793103448275862 0.2828882294757666 0.5310344827586206], ...
      	'Tag','PlantAxPhase', ...
         'xscale','log',...
      	'XColor',[0 0 0], ...
      	'YColor',[0 0 0], ...
      	'ZColor',[0 0 0]);



         h1 = axes('Parent',h0, ...
      	'CameraUpVector',[0 1 0], ...
      	'CameraUpVectorMode','manual', ...
      	'Color',[1 1 1], ...
      	'GridLineStyle','none', ...
      	'Position',[0.06627101879327399 0.2241379310344828 0.4035608308605341 0.02068965517241379], ...
         'Tag','AxBodePZ', ...
      	'XColor',[0 0 0], ...
      	'XTickLabelMode','manual', ...
      	'YColor',[0 0 0], ...
      	'YTickLabelMode','manual', ...
      	'ZColor',[0 0 0]);
         h1 = uicontrol('Parent',h0, ...
            'Units','normalized', ...
         	'BackgroundColor',[0.8 0.8 0.8], ...
         	'HorizontalAlignment','left', ...
         	'ListboxTop',0, ...
         	'Position',[0.0712166172106825 0.01724137931034483 0.2106824925816024 0.05517241379310345], ...
         	'String','Gain Margin:', ...
         	'Style','text', ...
         	'Tag','txtgm');
         h1 = uicontrol('Parent',h0, ...
         	'Units','normalized', ...
         	'BackgroundColor',[0.8 0.8 0.8], ...
         	'HorizontalAlignment','left', ...
         	'ListboxTop',0, ...
         	'Position',[0.5459940652818991 0.08620689655172414 0.2324431256181998 0.05517241379310345], ...
         	'String','Gain Crossover @', ...
            'visible','off', ...
         	'Style','text', ...
         	'Tag','txtgmc');
         h1 = uicontrol('Parent',h0, ...
         	'Units','normalized', ...
         	'BackgroundColor',[0.8 0.8 0.8], ...
         	'HorizontalAlignment','left', ...
         	'ListboxTop',0, ...
         	'Position',[0.5509396636993076 0.02068965517241379 0.2176063303659743 0.05517241379310345], ...
         	'String','Phase Margin:', ...
         	'Style','text', ...
         	'Tag','txtpm');
         h1 = uicontrol('Parent',h0, ...
         	'Units','normalized', ...
      	   'BackgroundColor',[0.8 0.8 0.8], ...
         	'HorizontalAlignment','left', ...
         	'ListboxTop',0, ...
         	'Position',[0.07220573689416419 0.0793103448275862 0.2245301681503462 0.05517241379310345], ...
         	'String','Phase Crossover @', ...
            'visible','off', ...
         	'Style','text', ...
         	'Tag','txtpmc');

   else  
       figure(h0);
   end

   gainbd=getbdgain(sys);

   modset('edtbdgain','String',num2str(gainbd));
   gain=modget('txtnumc','userdata');
   [mag,phase,w]=bode(gain*sys);
   m=mag(1,:)';
   p=phase(1,:)';
   [gm,pm,wcg,wcp] = margin(m,p,w);
   if ~isnan(wcp)
      if wcp < w(1)
         w=[wcp; w];
      elseif wcp > w(length(w))
         w=[w; wcp];
      end
      [mag,phase]=bode(gain*sys,w);
      [gm,pm,wcg,wcp] = margin(mag(1,:)',phase(1,:)',w);
   end

   if ~isnan(wcg)
      if wcg < w(1)
         w=[wcg; w];
      elseif wcg > w(length(w))
         w=[w; wcg];
      end
      [mag,phase]=bode(gain*sys,w);
      [gm,pm,wcg,wcp] = margin(mag(1,:)',phase(1,:)',w);
   end

   % plot the entire system
   pltmagphase(mag,phase,w,gm,pm,wcg,wcp);

   [plant,err]=gettf('p');
   [PlantMag,PlantPhase]=bode(plant,w);

   % plot the plant mag
   haxMag=findobj('tag','PlantAxMag');
   axes(haxMag);
   cla;
   nmag=PlantMag(1,1:length(w));
   hp=plot(w,20*log10(nmag));
   set(hp,'tag','nmagplt');
   cdata{15}=hp;
   set(hp,'color',[0 0 0]);
   set(haxMag,'visible','off','xscale','log','tag','PlantAxMag');

   % plot the plant phase
   nphase=PlantPhase(1,1:length(w));
   haxp=findobj('tag','PlantAxPhase');
   axes(haxp);
   cla;
   hp=plot(w,nphase);
   set(hp,'tag','nphaseplt');
   cdata{16}=hp;
   set(hp,'color',[0 0 0]);   
   set(haxp,'visible','off','xscale','log','tag','PlantAxPhase');

   % find the limits of the y-axis
      % magnitude
   PlantYlim=get(haxMag,'ylim');
   SysYlim=modget('AxMag','ylim');
   minlim=min([PlantYlim SysYlim]);
   maxlim=max([PlantYlim SysYlim]);
   lim=[minlim-.1*(maxlim-minlim) maxlim+.1*(maxlim-minlim)];
   set(haxMag,'ylim',lim);
   modset('AxMag','ylim',lim);
      % phase
   PlantYlim=get(haxp,'ylim');
   SysYlim=modget('AxPhase','ylim');
   minlim=min([PlantYlim SysYlim]);
   maxlim=max([PlantYlim SysYlim]);
   lim=[minlim-.1*(maxlim-minlim) maxlim+.1*(maxlim-minlim)];
   set(haxp,'ylim',lim);
   modset('AxPhase','ylim',lim);

   axes(findobj('tag','AxBodePZ'));
   cla;
   pzbode(sys);

function gainbd=getbdgain(sys)
   [num,den]=tfdata(sys,'v');
   znum=stripz(fliplr(num));
   num=num/znum(1);
   zden=stripz(fliplr(den));
   den=den/zden(1);
   gain=modget('txtnumc','userdata');

   gainbd=20*log10(gain*znum(1)/zden(1));


function pltmagphase(mag,phase,w,gm,pm,wcg,wcp)
   % plot the mag and phase
   axes(findobj('tag','AxMag'));
   cla;
   nmag=mag(1,1:length(w));
   plot(w,20*log10(nmag));
   ylabel('Magnitude (dB)');
   set(gca,'xscale','log','xgrid','on','ygrid','on','tag','AxMag','nextplot','add');
   lim=get(gca,'xlim');
   if ~isinf(gm)
      modset('txtgm','string',sprintf('Gain Margin: %5.3f dB',20*log10(gm)));
   else
      modset('txtgm','string','Gain Margin: Infinite');
   end

   if ~isinf(pm)
      modset('txtpm','string',sprintf('Phase Margin: %5.3f',pm));
   else
      modset('txtpm','string','Phase Margin: Infinite');
   end

   if ~isnan(wcp)
      plot([lim(1) lim(2)],[0 0],'k-.');
      plot(wcp,0,'ro');
      modset('txtpmc','visible','on');
      modset('txtpmc','string',sprintf('Zero-dB Crossover @%5.3f rad/sec',wcp));
   else
      modset('txtpmc','visible','off');
   end


   nphase=phase(1,1:length(w));
   haxp=findobj('tag','AxPhase');
   axes(haxp);
   cla;
   plot(w,nphase);
   ylabel('Phase (deg^o)');
   xlabel('Frequency (rad/sec)');
   set(haxp,'xscale','log','xgrid','on','ygrid','on','tag','AxPhase','nextplot','add');

   if ~isnan(wcg) 
      plot([lim(1) lim(2)],[-180 -180],'k-.');
      plot(wcg,-180,'ro');
      modset('txtgmc','visible','on');
      modset('txtgmc','string',sprintf('-180 deg Crossover @%5.3f rad/sec',wcg));
   else
      modset('txtgmc','visible','off');
   end

function pzbode(sys)
   % Parse the tf for p's and z's and plot the real ones
   [num,den]=tfdata(sys,'v');

   syszeros=roots(num);
   syspoles=roots(den);
   set(gca,'nextplot','add');
   for x=1:length(syszeros)
      if imag(syszeros(x))==0
         plot(abs(syszeros(x)),0,'ko','markersize',8,'linewidth',1);
      end
   end
   for x=1:length(syspoles)
      if imag(syspoles(x))==0
         plot(abs(syspoles(x)),0,'kx','markersize',8,'linewidth',1);
      end
   end
   lim=get(findobj('tag','AxMag'),'xlim');
   set(gca,'color',[.8 .8 .8],'xlim',lim,'xticklabel','','xscale','log','tag','AxBodePZ','Position',[0.06627101879327399 0.2241379310344828 0.4035608308605341 0.02068965517241379]);

function qbodedsgn(sys)
   global cdata;
   global qbodedsgnstr;

   edtgainbd=str2num(modget('edtbdgain','string'));
        
   gain=modget('txtnumc','userdata');
   gaindb=20*log10(gain);
   gaindb=gaindb + edtgainbd - getbdgain(sys);
   gain=10^(gaindb/20);
   % plot the mag and phase
   haxm=findobj('tag','AxMag');
   lim=get(haxm,'xlim');
   w=log10(lim(1)):abs(log10(lim(2)/lim(1)))/25:log10(lim(2));
   w=10.^w;
   [mag,phase]=bode(gain*sys,w);
   nmag=mag(1,1:length(w));
   hm=cdata{11};
   hp=cdata{12};
   if length(hm)~=0
      set(hm,'xdata',w,'ydata',20*log10(nmag));
      set(hp,'xdata',w,'ydata',phase);
   else
      axes(haxm);   
      cla;
      ylabel('Magnitude (dB)');
      set(haxm,'xscale','log','xgrid','on','ygrid','on','tag','AxMag','nextplot','add');
      cdata{11}=plot(w,20*log10(nmag));

      nphase=phase(1,1:length(w));
      haxp=findobj('tag','AxPhase');
      axes(haxp);
      cla;
      ylabel('Phase (deg^o)');
      xlabel('Frequency (rad/sec)');
      set(haxp,'xscale','log','xgrid','on','ygrid','on','tag','AxPhase','nextplot','add');
      cdata{12}=plot(w,nphase);
      cdata{15}=findobj('tag','nmagplt');
      cdata{16}=findobj('tag','nphaseplt');
      set(cdata{15},'parent',haxm);
      set(cdata{16},'parent',haxp);
      qbodedsgnstr='qbode_mat_full(sys)';      
   end

   axes(findobj('tag','AxBodePZ'));
   cla;

function qbode_mat_full(sys)
   global cdata;

   edtgainbd=str2num(modget('edtbdgain','string'));
        
   gain=modget('txtnumc','userdata');
   gaindb=20*log10(gain);
   gaindb=gaindb + edtgainbd - getbdgain(sys);
   gain=10^(gaindb/20);
   % plot the mag and phase
   haxm=findobj('tag','AxMag');
   lim=get(haxm,'xlim');
   w=log10(lim(1)):abs(log10(lim(2)/lim(1)))/25:log10(lim(2));
   w=10.^w;
   [mag,phase]=bode(gain*sys,w);
   nmag=mag(1,1:length(w));
   hm=cdata{11};
   hp=cdata{12};
   set(hm,'xdata',w,'ydata',20*log10(nmag));
   set(hp,'xdata',w,'ydata',phase);
   axes(findobj('tag','AxBodePZ'));
   cla;


function qstep
   global cdata;
   global stpfunstr;
   global stepfig;

   [exists,hndl]=chkfig('step');
   if (exists)
      stepfig=hndl;
      [sys,err]=gettf('full');
      if ~(err)
         gain=modget('txtnumc','userdata'); % global var contains the gain
         [num,den]=tfdata(sys);
         num=num{1}*gain;  % apply the gain
         sys=tf(num,den);
         sys=feedback(sys,1);
         [y,t]=step(sys);
         len=size(y,1);
         figure(hndl);
         h=cdata{10};
         if length(h)~=0
            set(h,'xdata',t(1:len),'ydata',y(1:len));
         else                       %
            cla reset;
            h=plot(t(1:len),y(1:len));
            cdata{10}=h;
            stpfunstr='step_mat_full';
         end
      end
   else
      runstep;
      stpfunstr='step_mat_empty';
   end

function step_mat_empty;
   global cdata;
   global stpfunstr;

   [exists,hndl]=chkfig('step');
   [sys,err]=gettf('full');
   k=modget('txtnumc','userdata'); % global var contains the gain
   [num,den]=tfdata(sys);
   num=num{1}*k;  % apply the gain
   sys=tf(num,den);
   sys=feedback(sys,1);
   [y,t]=step(sys);
   len=size(y,1);
   figure(hndl);
   h=cdata{10};
   cla reset;
   h=plot(t(1:len),y(1:len));
   cdata{10}=h;

   stpfunstr='step_mat_full';

function step_mat_full
   global cdata;
   global stpfunstr;
   global stepfig;
   gain=modget('txtnumc','userdata'); % global var contains the gain

   [sys,err]=gettf('full');
   [num,den]=tfdata(sys);
   num=num{1}*gain;  % apply the gain
   sys=tf(num,den);
   sys=feedback(sys,1);
   [y,t]=step(sys);
   len=size(y,1);
   figure(stepfig);
   h=cdata{10};
   set(h,'xdata',t(1:len),'ydata',y(1:len));

   
function setstats(rts)
         val=modget('pmnuroots','value');
         wn=norm(rts(val));
         if abs(imag(rts(val)))
            zeta=-real(rts(val))/wn;
            modset('txtzeta','string',num2str(zeta));
            modset('txtwn','string',num2str(wn));
         else
            modset('txtzeta','string','-----');
            modset('txtwn','string','-----');
         end

% quick root locus that plots points 
function qlocus(n,d,x,y,mark,hax)
   global cdata;
   %axes(hax);
   %cdata=get(gcf,'userdata');
   hdata=cdata{9};
   [n,d]=tfdata(tf(n,d),'v');
   lr=length(hdata);
   if lr~=0
      h=hdata(1,:);
      g=hdata(2,:);
      r=rlocus(tf(n,d),g);
      set(h(1),'xdata',x,'ydata',y);

      for x=2:lr
         set(h(x),'xdata',real(r(:,x)),'ydata',imag(r(:,x)));
      end
   else
      delete(get(hax,'children'));
      set(hax,'drawmode','fast');
      %H(s) = D(s) + k * N(s) =  0
      [r,g]=rlocus(tf(n,d));
      lr=length(r);
      hold on;
      i=1;
      h(i)=plot(x,y,mark);
      set(h(i),'markersize',7,'linewidth',1.5);
      for k=2:3:lr
         i=i+1;
         h(i)=plot(real(r(:,k)),imag(r(:,k)),'k.');
         set(h(i),'linewidth',.125,'markersize',6,'erasemode','back');
      end
      hold off;
      cdata{9}=[h;0 g(2:3:lr)];
   end
   %set(hax,'nextplot','replace');

function mv(type,point,mode)
   global cdata;
   cdata=cell(1,16);

   if strcmp(mode,'bode')
      set(gcf,'windowbuttonupfcn','cmdhndlr(''btnbdup'')');
      set(gcf,'pointer','left');
   else
      set(gcf,'windowbuttonupfcn','cmdhndlr(''btnup'')');
      set(gcf,'pointer','fleur');
   end

   [sys,err]=gettf('c');
   x=point(1);
   y=abs(point(2));
   objloc=x+j*y;

   [num,den]=tfdata(sys,'v');
   cdata{5}=roots(num);
   cdata{6}=roots(den);
   
   if strcmp(type,'zero')
      code=1.5;
      rts=roots(num);
   else
      code=.5;
      rts=roots(den);
   end

   dif=(chkdif(objloc,rts,mode)); % get the distance to the pointer
   
   objs=dif~=min(dif); % get whatever is not pointed to

   nrts=[];
   d=1;
   flag=0;
   for c=1:length(objs)
      if objs(c)==0 & flag==0 & imag(rts(c))==0 
         flag=1;
      elseif objs(c) | (imag(rts(c))==0 & objs(c)==0)
         nrts(d)=rts(c);
         d=d+1;
      end
   end

   cdata{1}=get(gcf,'userdata');
   cdata{2}=type;
   cdata{3}=nrts;
   flag=1;
   x=1;
   while flag==1 & x<=length(objs)
      if ~objs(x) & imag(rts(x))
         cdata{4}='imaginary';
         code=code+.5;
         flag=0;
      elseif ~objs(x) & ~imag(rts(x))  
         cdata{4}='real';
         code=code+2.5;
         flag=0;
      end
      x=x+1;
   end

   [sys,err]=gettf('p');
   [pnum,pden]=tfdata(sys,'v');
   cdata{7}=roots(pnum);
   cdata{8}=roots(pden);
   %set(gcf,'userdata',cdata);
   if code==1
      set(gcf,'windowbuttonmotionfcn','cmdhndlr(''moveIP'')');
   elseif code==2
      set(gcf,'windowbuttonmotionfcn','cmdhndlr(''moveIZ'')');
   elseif code==3
      if strcmp(mode,'bode')
         set(gcf,'windowbuttonmotionfcn','cmdhndlr(''movebdRP'')');
      else
         set(gcf,'windowbuttonmotionfcn','cmdhndlr(''moveRP'')');
      end
   elseif code==4
      if strcmp(mode,'bode')
         set(gcf,'windowbuttonmotionfcn','cmdhndlr(''movebdRZ'')');
      else   
         set(gcf,'windowbuttonmotionfcn','cmdhndlr(''moveRZ'')');
      end
   end

% this function sets up the root locus figure
function setlocus
   % set up the figure and the axes
   set(gcf,'numbertitle','off','tag','figlocus','name','Root Locus Window','units','normalized', ...
      	'Position',[0.19 0.5233333333333333 0.61625 0.4016666666666667]);
   set(gca,'Position',[0.1359026369168357 0.1742738589211618 0.462474645030426 0.7883817427385892],'tag','axlocus');

   b = uimenu('Parent',gcf, ...
              'Callback','cmdhndlr(''mnurlmsg'')',...
              'Label','&Instructions', ...
              'Tag','mnurlmsg');

   b = uimenu('Parent',gcf, ...
            'Label','&Statistics', ...
            'Tag','mnustats');
      c = uimenu('Parent',b, ...
               	'Callback','cmdhndlr(''mnurstats'')', ...
                  'checked','off', ...
                	'Label','Root Statistics', ...
                 	'Tag','mnurstats');

   % set up the rest of the rootlocus controls
   b = uicontrol('Parent',gcf, ...
      'Units','normalized', ...
   	'BackgroundColor',[0.8 0.8 0.8], ...
   	'ListboxTop',0, ...
   	'Position',[0.6409736308316429 0.06224066390041493 0.2778904665314402 0.5518672199170124], ...
   	'Style','frame', ...
   	'Tag','Frame1');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0.752941 0.752941 0.752941], ...
   	'Position',[0.6734279918864097 0.5726141078838174 0.2129817444219067 0.07883817427385892], ...
   	'Style','frame', ...
   	'Tag','Frame3');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'Position',[0.6409736308316429 0.6929460580912863 0.2799188640973631 0.2489626556016597], ...
   	'Style','frame', ...
   	'Tag','Frame4');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0.752941 0.752941 0.752941], ...
   	'Position',[0.6774847870182555 0.9004149377593361 0.204868154158215 0.07883817427385892], ...
   	'Style','frame', ...
   	'Tag','Frame5');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0.752941 0.752941 0.752941], ...
   	'Position',[0.659229208924949 0.261410788381743 0.243407707910751 0.24896265560166], ...
   	'Style','frame', ...
   	'Tag','Frame2');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'Callback','cmdhndlr(''btngain'')', ...
   	'FontUnits','normalized', ...
   	'FontSize',0.4444444444444443, ...
   	'Position',[0.6531440162271806 0.7136929460580913 0.255578093306288 0.07883817427385892], ...
   	'String','Mouse', ...
   	'Tag','btngain');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'Callback','cmdhndlr(''btnadd'')', ...
      'FontUnits','normalized', ...
	   'FontSize',0.4773662551440328, ...
   	'Position',[0.6937119675456389 0.4813278008298755 0.1663286004056795 0.06639004149377593], ...
   	'String','Add', ...
   	'Tag','btnadd');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
      'callback','cmdhndlr(''btnremove'')', ...
	   'FontUnits','normalized', ...
	   'FontSize',0.4773662551440328, ...
   	'Position',[0.69776876267748   0.17012448132780   0.17038539553753   0.07053941908714], ...
   	'String','Remove', ...
   	'Tag','btnremove');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0.752941 0.752941 0.752941], ...
   	'Callback','cmdhndlr(''rdpole'')', ...
   	'FontUnits','normalized', ...
	   'FontSize',0.5858585858585858, ...
   	'Position',[0.6754563894523327 0.4066390041493775 0.1075050709939148 0.04979253112033195], ...
   	'String','Pole', ...
   	'Style','radiobutton', ...
   	'Tag','rdpole', ...
   	'Value',1);
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0.752941 0.752941 0.752941], ...
   	'Callback','cmdhndlr(''rdzero'')', ...
   	'FontUnits','normalized', ...
   	'FontSize',0.5858585858585858, ...
   	'Position',[0.7890466531440162 0.4024896265560166 0.1075050709939148 0.04979253112033195], ...
   	'String','Zero', ...
   	'Style','radiobutton', ...
   	'Tag','rdzero');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'BackgroundColor',[1 1 1], ...
   	'FontUnits','normalized', ...
   	'FontSize',0.5155555555555554, ...
   	'Position',[0.6754563894523327 0.5809128630705395 0.2068965517241379 0.06224066390041494], ...
   	'String','Root Placement', ...
   	'Style','text', ...
   	'Tag','StaticText1');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'BackgroundColor',[1 1 1], ...
   	'FontUnits','normalized', ...
	   'FontSize',0.4773662551440328, ...
   	'Position',[0.67951318458418   0.90456431535270   0.20081135902637   0.06639004149378], ...
	   'String','Gain Adjust', ...
   	'Style','text', ...
   	'Tag','StaticText1');
   b = uicontrol('Parent',gcf, ...
      'callback','cmdhndlr(''edtgain'')', ...
   	'Units','normalized', ...
   	'BackgroundColor',[1 1 1], ...
   	'Position',[0.793103448275862 0.8091286307053941 0.1176470588235294 0.07241379310344828], ...
   	'Style','edit', ...
      'string',num2str(modget('txtnumc','userdata')), ...
   	'Tag','edtgain');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0.752941 0.752941 0.752941], ...
   	'FontUnits','normalized', ...
   	'FontSize',0.5858585858585858, ...
   	'Position',[0.7261663286004056 0.3402489626556016 0.09533468559837728 0.04979253112033195], ...
   	'String','Real', ...
   	'Style','radiobutton', ...
      'callback','cmdhndlr(''rdreal'')', ...
      'value',1, ...
   	'Tag','rdreal');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0.752941 0.752941 0.752941], ...
   	'FontUnits','normalized', ...
   	'FontSize',0.5370370370370369, ...
   	'Position',[0.7261663286004056 0.2738589211618257 0.1440162271805274 0.05809128630705394], ...
   	'String','Complex', ...
   	'Style','radiobutton', ...
      'callback','cmdhndlr(''rdcomplex'')', ...
      'value',0, ...
   	'Tag','rdcomplex');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
      'callback','cmdhndlr(''btnmove'')', ...
   	'FontUnits','normalized', ...
	   'FontSize',0.4773662551440328, ...
   	'Position',[0.6997971602434077 0.0829875518672199 0.1663286004056795 0.06639004149377593], ...
   	'String','Move', ...
      'Tag','btnmove');
   b = uicontrol('Parent',gcf, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0.752941 0.752941 0.752941], ...
   	'FontUnits','normalized', ...
   	'FontSize',0.241375661375661, ...
   	'Position',[0.6490872210953347 0.8132780082987552 0.1359026369168357 0.06639004149377593], ...
   	'String','Keyboard:', ...
   	'Style','text', ...
   	'Tag','StaticText2');


function clrgain
   h=modget('axlocus','children');
   for x=1:size(h,1)
      if strcmp(get(h(x),'type'),'line') 
         if strcmp(get(h(x),'marker'),'+')
            delete(h(x));        % get rid of the '+' sign
         end
      elseif strcmp(get(h(x),'type'),'text')
          delete(h(x));      
      end
   end

   
% clear everything but the poles and zeros in the root locus
function clraxes(tag,type,mode)
   h=modget(tag,'children');
   for x=1:size(h,1)
      if strcmp(get(h(x),'type'),'line')
         if ~strcmp(get(h(x),'marker'),'o') & ~strcmp(get(h(x),'marker'),'x')
            set(h(x),'visible','off');
         else
            if strcmp(get(h(x),'marker'),'o')
               if strcmp(type,'del')
                  if strcmp(mode,'bode')
                     set(h(x),'buttondownfcn','cmdhndlr(''delbdzero'')');
                  else
                     set(h(x),'buttondownfcn','cmdhndlr(''delzero'')');
                  end
               else
                  if strcmp(mode,'bode')
                     set(h(x),'buttondownfcn','cmdhndlr(''mvbdzero'')');               
                  else
                     set(h(x),'buttondownfcn','cmdhndlr(''mvzero'')');               
                  end
               end
            else
               if strcmp(type,'del')
                  if strcmp(mode,'bode')
                     set(h(x),'buttondownfcn','cmdhndlr(''delbdpole'')');
                  else
                     set(h(x),'buttondownfcn','cmdhndlr(''delpole'')');
                  end
               else
                  if strcmp(mode,'bode')
                     set(h(x),'buttondownfcn','cmdhndlr(''mvbdpole'')');               
                  else
                     set(h(x),'buttondownfcn','cmdhndlr(''mvpole'')');
                  end
               end
            end            
               set(h(x),'markersize',10,'linewidth',2,'color',[0 0 0]);
         end
      else
            set(h(x),'visible','off');         
      end
   end

function rtsdif=chkdif(obj,rts,mode)
   if strcmp(mode,'bode')
      rts=abs(rts);
   end
   obj=obj*ones(length(rts),1);
   rtsdif=zeros(length(rts),1);
   rtsdif=sqrt((real(rts)-real(obj)).^2+(abs(imag(rts))-imag(obj)).^2);

            
function del(type,point,mode)
   [sys,err]=gettf('c');
   x=point(1);
   y=abs(point(2));
   objloc=x+j*y;

   [num,den]=tfdata(sys,'v');
   
   if strcmp(type,'zero')
      rts=roots(num);
   else
      rts=roots(den);
   end

   dif=(chkdif(objloc,rts,mode));
   
   objs=dif>=min(dif)-1e-6 & dif<=min(dif)+1e-6; % get the objects that are within 1e-6 of the pointer

   nrts=[];
   d=1;
   for c=1:size(objs,1)
      if objs(c)==0
         nrts(d)=rts(c);
         d=d+1;
      end
   end

   if strcmp(type,'zero')
      num=poly(nrts);
   else
      den=poly(nrts);
   end

   settf(num,den);
   setalt('c');

   if strcmp(mode,'bode')
      delete(findobj('tag','AxNewBodePZ'));
      set(gcf,'pointer','arrow');
      cmdhndlr('edtbdgain');
   else
      hax=findobj('tag','axpzmap');
      delete(hax);
      % find the axes of the root locus plot
      h=modget('rdreal','parent');
      figure(h);
      hax=findobj('tag','axlocus');
      hax=hax(1);
      axes(hax);
      [sys,err]=gettf('full');
      if ~err
        rlocus(sys);
        set(hax,'tag','axlocus');
      end
      set(gcf,'pointer','arrow');
      cmdhndlr('btnstep');
   end                            
   
% move a pole or zero from the root locus plot   
function movelocus
   h=findobj('tag','axlocus');
   pos=get(h,'position');
   axes(h);
   v=axis;
   [sysc,err]=gettf('c');
   hax=axes;
   set(hax,'position',pos);
   axis(v);
   pzmap(sysc);
   set(gca,'tag','axpzmap');
   axis(v);
   clraxes('axpzmap','move','rl');
   set(gca,'visible','of');
   set(gcf,'pointer','fullcross','userdata',hax);
   set(hax,'userdata',get(hax,'currentpoint'));
% subtract a pole or zero from the root locus plot   
function subflocus
   h=findobj('tag','axlocus');
   pos=get(h,'position');
   axes(h);
   v=axis;
   [sysc,err]=gettf('c');
   hax=axes;
   set(hax,'position',pos);
   axis(v);
   pzmap(sysc);
   set(gca,'tag','axpzmap');
   axis(v);
   clraxes('axpzmap','del','rl');
   set(gca,'visible','of');
   set(gcf,'pointer','fullcross');

% check to see if a figure exits
function [exists,h]=chkfig(tag)
   exists=0;
   h=findobj('tag',tag);
   if h
      if strcmp(get(h,'type'),'figure')
         exists=1;
      end
   end
         

% this function adds a pole or zero to the current
% compensator and plots the root locus
function add2locus
   [x,y,btn]=ginput(1);
   if btn ~= 27          
          [sys,err]=gettf('c');

          [num,den]=tfdata(sys,'v');

         if getrad('rdpole')
            if y & getrad('rdcomplex')
               den=conv(den,conv([1 -x+y*j],[1 -x-y*j]));
            else
               den=conv(den,[1 -x]);
            end
         else
            if y & getrad('rdcomplex')
               num=conv(num,conv([1 -x+y*j],[1 -x-y*j]));
            else
               num=conv(num,[1 -x]);
            end
         end

         settf(num,den);
         setalt('c');

         % find the axes of the root locus plot
         h=modget('rdreal','parent');
         figure(h);
         hax=findobj('tag','axlocus');
         hax=hax(1);
         axes(hax);
         [sys,err]=gettf('full');
         if ~err
            rlocus(sys);
            set(hax,'tag','axlocus');
         end
   end   

% this function performs the actions necessary to update the menu
% and make visible the statistical comments
function stataction(tag)
   hndls=modget(tag,'userdata');
   if strcmp(modget(tag,'checked'),'off')
      setvis(hndls,'on');
      modset(tag,'checked','on');
   else
      setvis(hndls,'off');
      modset(tag,'checked','off');
   end

% this function handles the step response
function runstep
   [sys,err]=gettf('full');
   if ~(err)
      k=modget('txtnumc','userdata');
      [num,den]=tfdata(sys);
      num=num{1}*k;  % apply the gain
      sys=tf(num,den);
      sys=feedback(sys,1);
      [y,t]=step(sys);
      len=size(y,1); 

      % get the Tr10%
      x=1;
      flag=1;
      while flag==1 & x < len
         if abs(100*(y(x)/y(len))) >= 10
            flag=0;
         else
            x=x+1;
         end
      end
      p10=x;

      % get the Tr90%
      x=1;
      flag=1;
      while flag==1 & x<len
         if abs(100*(y(x)/y(len))) >= 90
            flag=0;
         else
            x=x+1;
         end
      end
      p90=x;

      % get the Ts 2%
      x=len;
      flag=1;
      while flag==1 & x>1
         if abs(100*(y(x)-y(len))/y(len)) >= 2
            flag=0;
         else
            x=x-1;
         end
      end
      p2=x;

      % get the Ts 5%
      x=len;
      flag=1;
      while flag==1 & x>1
         if abs(100*(y(x)-y(len))/y(len)) >= 5
            flag=0;
         else
            x=x-1;
         end
      end
      p5=x;

      hold on;
      maxy=max(y);
      x=find(y==maxy);
      plot(t,y); % step response
      h=plot([t(1) t(len)],[y(len) y(len)],'k'); % steady state line
      set(h,'linestyle',':');
      ylim=get(gca,'ylim');
      xlim=get(gca,'xlim');
      pos=100*(maxy-y(len))/y(len);
      hs=0;
      if maxy==y(len)
         pos=0;
         mxstr=sprintf('        Peak Value: %0.5g',maxy);
         ht=text(.6*xlim(2),.35*ylim(2),mxstr);
      else
         mxstr=sprintf('  Peak Value: %0.5g at %0.5g seconds.',maxy,t(x));
         hs=stem(t(x),maxy,'ro');
         ht=text(t(x),maxy,mxstr);
      end
      set(ht,'fontunits','normalized','fontsize',0.0674810936591041);
         
      poversht=sprintf('Max %%Overshoot: %0.5g%%',pos);

      lstr=sprintf('        Final Value: %0.5g',y(len));
      hts=text(.6*xlim(2),.29*ylim(2),lstr);
      set(hts,'fontunits','normalized','fontsize',0.0674810936591041);
      if strcmp(modget('mnufinal','checked'),'off')
         set(hts,'visible','off');
      end
      modset('mnufinal','userdata',hts);

      
      % store the plot of text and stem in the userdata field
      % of the menu item Peak Value
      if hs
         h=[ht hs'];
      else
         h=ht;
      end
      if strcmp(modget('mnupeak','checked'),'off')
         setvis(h,'off');
      end
      modset('mnupeak','userdata',h);

      % store the plot of text and stem in the userdata field
      % of the menu item Max %Overshoot
      ht=text(.6*xlim(2),.23*ylim(2),poversht);
      set(ht,'fontunits','normalized','fontsize',0.0674810936591041);
      if strcmp(modget('mnumaxos','checked'),'off')
         setvis(ht,'off');
      end
      modset('mnumaxos','userdata',ht);


      % store the plot of text and stem in the userdata field
      % of the menu item 2% Time
      hs=stem(t(p2),y(p2));
      ht=text(t(p2),y(p2),' Ts-2%');
      set(ht,'fontunits','normalized','fontsize',0.0674810936591041);
      lstr=sprintf('2%% Settling Time: %0.5g',t(p2));
      hts=text(.6*xlim(2),.05*ylim(2),lstr);
      set(hts,'fontunits','normalized','fontsize',0.0674810936591041);
      h=[ht hs' hts];
      if strcmp(modget('mnuts2','checked'),'off')
          setvis(h,'off');
      end
      modset('mnuts2','userdata',h);


      % store the plot of text and stem in the userdata field
      % of the menu item 5% Time    
      hs=stem(t(p5),y(p5));
      ht=text(t(p5),y(p5),' Ts-5%');
      set(ht,'fontunits','normalized','fontsize',0.0674810936591041);
      lstr=sprintf('5%% Settling Time: %0.5g',t(p5));
      hts=text(.6*xlim(2),.11*ylim(2),lstr);
      set(hts,'fontunits','normalized','fontsize',0.0674810936591041);
      h=[ht hs' hts];
      if strcmp(modget('mnuts5','checked'),'off')
         setvis(h,'off');
      end
      modset('mnuts5','userdata',h);
      

      % store the plot of text and stem in the userdata field
      % of the menu item 2% Time
      hs10=stem(t(p10),y(p10));
      ht10=text(t(p10),y(p10),' Tr-10%');
      set(ht10,'fontunits','normalized','fontsize',0.0674810936591041);
      set(hts,'fontunits','normalized','fontsize',0.0674810936591041);

      hs90=stem(t(p90),y(p90));
      ht90=text(t(p90),y(p90),' Tr-90%');
      set(ht90,'fontunits','normalized','fontsize',0.0674810936591041);
      lstr=sprintf('           Rise Time: %0.5g',t(p90)-t(p10));
      hts=text(.6*xlim(2),.17*ylim(2),lstr);
      set(hts,'fontunits','normalized','fontsize',0.0674810936591041);
      h=[ht10 hs10' ht90 hs90' hts];
      if strcmp(modget('mnurise','checked'),'off')
         setvis(h,'off');
      end
      modset('mnurise','userdata',h);

      nump=modget('txtnump','string');
      numc=modget('txtnumc','string');
      denp=modget('txtdenp','string');
      denc=modget('txtdenc','string');
      titstr=sprintf('Gp(s)=%s/%s   Gc(s)=%s/%s   Gain=%0.5g',nump,denp,numc,denc,k);
      htit=title(titstr);
      set(htit,'fontunits','normalized','fontsize',0.0674810936591041,'verticalalignment','middle');
      xlabel('Time(sec)');
      ylabel('System Output');
   end

% set the visibility of an array of objects
function setvis(mat,vtype)
   for x=1:size(mat,2)
      set(mat(x),'visible',vtype)
   end

% change the image of the gain knob
function chggain(type)
   img=get(gca,'userdata');
   x=get(gco,'userdata');
   if strcmp(type,'+')
      if x<8
         x=x+1;
      else
         x=1;
      end
   else
      if x>1
         x=x-1;
      else
         x=8;
      end
   end
   set(gco,'visible','off');
   set(img(x),'visible','on');


% this function changes the size of the font of 
% the alt text field
function cfont(type,x)
   txtnum=strcat('txtnum',x);
   txtden=strcat('txtden',x);
   sz=modget(txtnum,'fontsize');
   if strcmp(type,'plus')
      sz=sz*1.1;
   else
      sz=sz*.9;
   end
   modset(txtnum,'fontsize',sz);
   modset(txtden,'fontsize',sz);


% this function sets the alt field which displays
% the function in an alternate form
function setalt(x)
   edtnum=strcat('edtnum',x);
   edtden=strcat('edtden',x);
   rdcoef=strcat('rdcoef',x);
   rdpz=strcat('rdpz',x);
   rdpoly=strcat('rdpoly',x);
   rdfact=strcat('rdfact',x);
   txtnum=strcat('txtnum',x);
   txtden=strcat('txtden',x);

   num=modget(edtnum,'string');
   den=modget(edtden,'string');
   if ~strcmp(num,'') & ~strcmp(den,'')
      num=stripz(str2num(num));
      den=stripz(str2num(den));
      nstr='';
      dstr='';
      if getrad(rdcoef) & getrad(rdpoly)
         g=num(1)/den(1);
         if length(num) > 1
            num=num/num(1);
         end
         if length(den) > 1
            den=den/den(1);
         end
         [nstr,dstr]=getnd(num,den,'coeff'); % set the alt field
         if g~=1 & length(nstr)
            nstr=fliplr(nstr);
            nstr=deblank(nstr);
            nstr=fliplr(nstr);
            nstr=strcat(strcat(strcat(num2str(g),'('),nstr),')');
         elseif g~=1 & ~length(nstr)
            nstr = num2str(g);            
         end         
      elseif getrad(rdpz) & getrad(rdfact)
         [nstr,dstr]=getnd(num,den,'pz'); % set the alt field
      elseif getrad(rdcoef) & getrad(rdfact)
         n=roots(num)';
         d=roots(den)';
         [nstr,dstr]=getnd(n,d,'pz'); % set the alt field
         % get the gain
         numtemp=stripz(fliplr(num));
         dentemp=stripz(fliplr(den));
         npoly=stripz(fliplr(poly(n)));
         dpoly=stripz(fliplr(poly(d)));

         gain=(numtemp(1)/dentemp(1))/(npoly(1)/dpoly(1));
         %gain = num(1)/den(1);
         if ((gain <= 1-1e-5) | (gain >= 1+1e-5)) & length(nstr)
            nstr=strcat(num2str(gain),nstr);
         end
         
      elseif getrad(rdpz) & getrad(rdpoly)
         num=poly(num);
         den=poly(den);
         [nstr,dstr]=getnd(num,den,'coeff'); % set the alt field
      end
      if (length(num)==1 | length(den)==1)& getrad(rdcoef) 
         if length(num)==1
            nstr=num2str(num);
         end
         if length(den)==1
            dstr=num2str(den);
         end
      end
      modset(txtnum,'string',nstr);
      modset(txtden,'string',dstr);
   end

% this function strips the leading zeroes from a vector
function nvect=stripz(vect)
   nvect=[];
   if length(vect)>0
      c=1;
      flag=1;
      while ~vect(c) & flag==1
         if c<length(vect)
            c=c+1;
         else
            flag=0;
         end
      end
      nvect=vect(c:length(vect));
   end


% this function checks to see which radio button is selected
function on=getrad(tag)
   on=modget(tag,'value');

% this function sets the radio buttons   
function setrad(tag1,tag2)
   modset(tag1,'value',1);
   modset(tag2,'value',0);

% this function clears the input fields as well as the alt form field
function clrflds(x)
   edtnum=strcat('edtnum',x);
   edtden=strcat('edtden',x);
   txtnum=strcat('txtnum',x);
   txtden=strcat('txtden',x);
   modset(edtnum,'string','');
   modset(edtden,'string','');
   modset(txtnum,'string','');
   modset(txtden,'string','');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% the next two functions are modified versions          %
% of the get and set commands. one property             %
% can be modified and the findobj command is included.  %
function modset(tag,prop,val)                           %
   h=findobj('tag',tag);                                %
   set(h(1),prop,val);                                  %
                                                        %
function [val]=modget(tag,prop)                         %
   h=findobj('tag',tag);                                %
   if h
      val=get(h(1),prop);                                  %
   end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


% this function gets the transfer function from the 
% edit fields
% 'c' 'p' or 'full' are valid arguments
function [sys,err]=gettf(x)
   gain=modget('txtnumc','userdata');                    %

   if strcmp(x,'full')
      % get the numerator and denominator
      nump=stripz(str2num(modget('edtnump','string')));
      denp=stripz(str2num(modget('edtdenp','string')));
      lnp=size(nump,2);
      ldp=size(denp,2);
      numc=stripz(str2num(modget('edtnumc','string')));
      denc=stripz(str2num(modget('edtdenc','string')));
      lnc=size(numc,2);
      ldc=size(denc,2);

		if ldp>0 & lnp>0 & ldc>0 & lnc>0
         if getrad('rdpzc')
            numc=poly(gain*numc);
            denc=poly(denc);
         end
         if getrad('rdpzp')
            nump=poly(nump);
            denp=poly(denp);
         end
         err=0;
         sys=series(tf(nump,denp),tf(numc,denc));
      else
         err=1;
         sys=[];
         errordlg('Plant and Compensator fields cannot be empty.','Incomplete Transfer Function','replace');
      end
   else
      edtnum=strcat('edtnum',x);
      edtden=strcat('edtden',x);
      num=stripz(str2num(modget(edtnum,'string')));
      den=stripz(str2num(modget(edtden,'string')));
      rdpz=strcat('rdpz',x);
      ln=size(num,2);
      ld=size(den,2);
   
      if ld>0 & ln>0 
         err=0;
         if getrad(rdpz)
            num=poly(gain*num);
            den=poly(den);
         end

         sys=tf(num,den);
      else
         err=1;
         sys=[];
      end
   end



% set the transfer function of the compensator field
function settf(num,den)
   if getrad('rdcoefc')
      modset('edtnumc','string',num2str(stripz(num)));
      modset('edtdenc','string',num2str(stripz(den)));
   else
      modset('edtnumc','string',num2str(roots(num)));
      modset('edtdenc','string',num2str(roots(den)));
   end

% this function checks to see if the mouse pointer is in 
% a particular object's rectangle
function flag = inrect(tag)
   flag=0;
   hndls=get(gcf,'children');
   % get the current mouse point
   set(gcf,'units','points');
   cp = get(gcf,'currentpoint');
   pos=get(findobj(hndls,'tag',tag),'position');
   if any(cp) 
      if any(pos)
         if (cp(1)>pos(1)) & (cp(1)<(pos(1)+pos(3))) & (cp(2)>pos(2)) & (cp(2)<(pos(2)+pos(4)))
            flag=1; % the mouse is inside the rectangle
         else
            flag=0;
         end
      end
   end

% set the status field
function setstat(str)
   hndls=get(gcf,'children');
   htxt=findobj(hndls,'tag','txtstat');
   hp= get(htxt,'parent');
   
   if (hp)
      if hp==gcf
         set(htxt(1),'string',str);
      end
   end

function [nstr,dstr]=getnd(num,den,type)

   % construct the num polynomial
   norder=length(num);  % get the order
   nstr=' ';   % initialize the string
   % let's first construct the string then 'eval' it
   dorder=length(den);  % get the order
   dstr=' ';   % initialize the string
   
   switch(type)

   case 'coeff'
      nstr=coef2poly(num);
      dstr=coef2poly(den);

   case 'pz'
      nstr=root2term(num); 
      dstr=root2term(den);
            

end

% this function takes a vector of coeffs and transforms it
% into a polynomial of terms
function [ply]=coef2poly(coefs)
      corder=length(coefs);
      ply='';
      % construct the  polynomial
      for x=1:corder % 1 to the order of the poly
         if coefs(x) % check if greater that 1. if not, skip it
            c=coefs(x);
            if c>0
               if c~= 1 | x==corder
                  if x==1
                     c=sprintf('%0.5g',abs(c)); 
                  else
                     c=sprintf('+ %0.5g',abs(c));  % append to a plus sign
                  end
               else
                  if x>1 
                     c='+ ';  % append to a plus sign
                  else
                     c='';
                  end
               end
            elseif c<0 
               if c~= -1 | x==corder
                  c=sprintf('- %0.5g',abs(c));  % append to a minus sign
               else
                  if x>1
                     c='- ';  % append to a plus sign
                  else
                     c='-';
                  end
               end
            end 
                  
            if corder-x > 1
               ply=sprintf('%s %ss^%d',ply,c,corder-x);
            elseif x==corder-1
               ply=sprintf('%s %ss',ply,c);
            elseif x==corder & corder~=1
               ply=sprintf('%s %s',ply,c);
            end            
         end
      end



% this function takes a vector of roots and transforms it
% into a product of terms
function [terms]=root2term(rts)
      z=0;
      torder=length(rts);
      r=ones(1,torder);
      x=1;
      terms='';
      while x<=torder
         c=rts(x);
         y=x+1;
         while y<=torder
            if c==rts(y)
               rts=takeit(rts,y); % repeated roots
               r(x)=r(x)+1;
               torder=torder-1;
            else
               y=y+1;
            end
         end
         x=x+1;
      end

      for x=1:torder
         c=rts(x);
         nflag=0;
         if ~isreal(c)
            flag=1;
            realc=real(c);
            imagc=imag(c); 
            if realc < 0
               nflag=1;
               realc=num2str(realc);
               realc=realc(2:size(realc,2));
            elseif realc == 0
               c=imagc;
               if imagc>0
                  if imagc~=1
                     c=strcat(num2str(imagc),'j');
                  else
                     c='j';
                  end
               else
                  nflag=1;
                  if imagc~=-1
                     c=num2str(imagc);
                     c=strcat(c(2:size(c,2)),'j');
                  else
                     c='j';
                  end
               end
               flag=0;
            end
            if flag
               if imagc>0
                  if imagc~=1
                     c=strcat(num2str(realc),'+',num2str(imagc),'j');
                  else
                     c=strcat(num2str(realc),'+j');
                  end
               else
                  if imagc~=1
                     c=strcat(num2str(realc),num2str(imagc),'j');
                  else
                     c=strcat(num2str(realc),'-j');
                  end
               end
            end
         else
            if c<0;
               nflag=1;
               c=num2str(c);
               c=c(2:size(c,2));
            else
               c=num2str(c);
            end
         end
         if str2num(c)==0
            if r(x)>1
               terms=sprintf('s^%d%s',r(x),terms); 
            else
               terms=sprintf('s%s',terms); 
            end
         elseif ~nflag
            if r(x)>1
               terms=sprintf('%s(s - %s)^%d',terms,c,r(x)); 
            else
               terms=sprintf('%s(s - %s)',terms,c); 
            end
         elseif nflag
            if r(x)>1
               terms=sprintf('%s(s + %s)^%d',terms,c,r(x)); 
            else
               terms=sprintf('%s(s + %s)',terms,c); 
            end           
         end
      end
      


% this function removes an element from an array
function out=takeit(array,index)
   out=0;
   len=size(array,2);
   if index == 1
      out = array(2:len);
   elseif index == len
      out = array(1:len-1);
   else
      out = [array(1:index-1) array(index+1:len)];
   end


function stats()
   a = figure('Color',[0.8 0.8 0.8], ...
   	'Units','normalized', ...
      'MenuBar','none', ...
   	'Name','Root Statistics', ...
   	'NumberTitle','off', ...
   	'Position',[0.14125 0.6166666666666667 0.3625 0.13], ...
      'resize','on', ...
   	'Tag','figstats');
   b = uicontrol('Parent',a, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0 0 0], ...
   	'Position',[0.03508771929824561 0.582089552238806 0.456140350877193 0.07462686567164178], ...
   	'Style','frame', ...
   	'Tag','Frame1');
   b = uicontrol('Parent',a, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0 0 0], ...
   	'Position',[0.56140350877193 0.58208955223881 0.15789473684211 0.05970149253731], ...
   	'Style','frame', ...
   	'Tag','Frame1');
   b = uicontrol('Parent',a, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0 0 0], ...
   	'Position',[0.80701754385965 0.58208955223881 0.15789473684211 0.05970149253731], ...
   	'Style','frame', ...
	   'Tag','Frame1');
   b = uicontrol('Parent',a, ...
   	'Units','normalized', ...
   	'BackgroundColor',[1 1 1], ...
   	'Callback','cmdhndlr(''pmnuroots'')', ...
   	'Position',[0.03508771929824561 0.2238805970149254 0.4596491228070175 0.2985074626865671], ...
   	'String',' ', ...
   	'Style','popupmenu', ...
   	'Tag','pmnuroots', ...
   	'Value',1);
   b = uicontrol('Parent',a, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0.8 0.8 0.8], ...
   	'FontWeight','bold', ...
   	'Position',[0.01754385964912281 0.6268656716417911 0.4807017543859649 0.2238805970149254], ...
   	'String','Roots:', ...
   	'Style','text', ...
   	'Tag','StaticText1');
   b = uicontrol('Parent',a, ...
   	'Units','normalized', ...
   	'BackgroundColor',[0.8 0.8 0.8], ...
   	'FontWeight','bold', ...
   	'Position',[0.5368421052631579 0.6268656716417911 0.1964912280701754 0.208955223880597], ...
   	'String','Zeta', ...
   	'Style','text', ...
	   'Tag','StaticText2');
   b = uicontrol('Parent',a, ...
	   'Units','normalized', ...
   	'BackgroundColor',[0.8 0.8 0.8], ...
   	'FontWeight','bold', ...
   	'Position',[0.76140350877193 0.62686567164179 0.23157894736842 0.2089552238806], ...
   	'String','Wn', ...
   	'Style','text', ...
   	'Tag','StaticText3');
   b = uicontrol('Parent',a, ...
   	'Units','normalized', ...
   	'BackgroundColor',[1 1 1], ...
   	'Position',[0.7824561403508772 0.2388059701492537 0.1964912280701754 0.2835820895522388], ...
   	'Style','text', ...
   	'Tag','txtwn');
   b = uicontrol('Parent',a, ...
   	'Units','normalized', ...
   	'BackgroundColor',[1 1 1], ...
   	'Position',[0.5508771929824562 0.2537313432835821 0.1894736842105263 0.2686567164179105], ...
   	'Style','text', ...
   	'Tag','txtzeta');
      