Code covered by the BSD License

# Controls Tutor

### Craig Borghesani (view profile)

Help understand the fundamentals of classical control theory.

timeplot(axs_hand,mode)
```function timeplot(axs_hand,mode)
%
% Utility Function: TIMEPLOT
%
% The purpose of this function is to handle the plotting of all the time
% response options

% Author: Craig Borghesani
% Date: 8/8/94
% Revised: 11/15/94

% if no time response axis present, get out
if ~length(axs_hand), return; end

% obtain handle information
f = gcf;
ui_data = get(f,'userdata');
ui_han = ui_data{1};
open_loop = ui_han(78);
clos_loop = ui_han(79);
unit_imp  = ui_han(80);
unit_step = ui_han(81);
unit_ramp = ui_han(82);
rise_time = ui_han(83);
dlay_time = ui_han(84);
peak_time = ui_han(85);
over_shot = ui_han(86);
setl_2per = ui_han(87);
setl_5per = ui_han(88);
cur_sys = get(ui_han(30),'userdata');
stat_bar = get(ui_han(43),'userdata');
range1 = 78:82;
range2 = 83:88;

% distribute handles
axs_data = get(axs_hand,'userdata');

if ~length(mode) | any(mode == [13,14,15]),

% determine various states of time response environment

if ~length(mode), mode = 0; end
ct = 2;
for k = range1,
if strcmp(get(ui_han(k),'checked'),'on'),
mode(ct) = k-(range1(1)-1);
else
mode(ct) = 0;
end
ct = ct + 1;
end

end

if length(mode) > 1,
set(axs_data(2:length(axs_data)),'vis','off');
end

open_imp = axs_data(2);
clos_imp = axs_data(5);
open_step = axs_data(3);
clos_step = axs_data(6);
open_ramp = axs_data(4);
clos_ramp = axs_data(7);
tim_txt = axs_data(8:length(axs_data));

plant_mat = get(ui_han(3+cur_sys),'userdata');
for_mat  = get(ui_han(6+cur_sys),'userdata');
bac_mat  = get(ui_han(9+cur_sys),'userdata');

term_mat  = termjoin(plant_mat,for_mat,bac_mat);
[num,den] = termextr(term_mat);

if length(num)==1 & length(den) == 1,
set(stat_bar,'string','No Time Response computed');
return;
end

ln = length(num); ld = length(den);
if ln > ld,
set(stat_bar,'string','You have more Zeros than Poles.  Time response not plotted.');
return
end

if polyval(den,0) ~= 0,
final = polyval(num,0)/polyval(den,0);
else
final = inf;
end

[nump,denp] = termextr(plant_mat);
[numg,deng] = termextr(for_mat);
[numh,denh] = termextr(bac_mat);
numt = conv(conv(nump,numg),numh);
dent = conv(conv(denp,deng),denh);
lnt = length(numt); ldt = length(dent);
numt = [zeros(1,ldt-lnt),numt];
dent = [zeros(1,lnt-ldt),dent];
numcl = conv(conv(nump,numg),denh);
dencl = dent + numt;

finalcl = polyval(numcl,0)/polyval(dencl,0);

tvec = get(ui_han(40),'userdata');
imp_input = [1/(tvec(2)-tvec(1));zeros(length(tvec)-1,1)];
stp_input = ones(length(tvec),1);
rmp_input = tvec';

if term_mat(1,2)~=0, % pure delay time
loc_t = find(tvec <= term_mat(1,2));
len = length(loc_t);
if len > 1,
imp_input = [zeros(len,1);imp_input(1:(length(imp_input)-len))];
stp_input = [zeros(len,1);stp_input(1:(length(stp_input)-len))];
rmp_input = [zeros(len,1);rmp_input(1:(length(rmp_input)-len))];
end
end

if any(mode==1), % Open-Loop

if strcmp(get(open_loop,'checked'),'off') | length(mode)>1,
set(open_loop,'checked','on');

if strcmp(get(unit_imp,'checked'),'on'),

set(stat_bar,'string','Computing open-loop impulse response');
imp_ol = lsim(num,den,imp_input,tvec);
set(open_imp,'xdata',tvec,'ydata',imp_ol,'vis','on');
if length(mode) > 1, mode(4) = 0; end

end

if strcmp(get(unit_step,'checked'),'on'),

set(stat_bar,'string','Computing open-loop step response');
step_ol = lsim(num,den,stp_input,tvec);
set(open_step,'xdata',tvec,'ydata',step_ol,'vis','on');
if length(mode) > 1, mode(5) = 0; end

end

if strcmp(get(unit_ramp,'checked'),'on'),

set(stat_bar,'string','Computing open-loop ramp response');
ramp_ol = lsim(num,den,rmp_input,tvec);
set(open_ramp,'xdata',tvec,'ydata',ramp_ol,'vis','on');
if length(mode) > 1, mode(6) = 0; end

end

else

set(stat_bar,'string','Removing Open-Loop');
set(open_loop,'checked','off');
set([open_imp,open_step,open_ramp,tim_txt([1:2:9])],'vis','off');

end

end

if any(mode==2), % Closed-Loop

if strcmp(get(clos_loop,'checked'),'off') | length(mode)>1,
set(clos_loop,'checked','on');

if strcmp(get(unit_imp,'checked'),'on'),

set(stat_bar,'string','Computing closed-loop impulse response');
imp_cl = lsim(numcl,dencl,imp_input,tvec);
set(clos_imp,'xdata',tvec,'ydata',imp_cl,'vis','on');
if length(mode) > 1, mode(4) = 0; end

end

if strcmp(get(unit_step,'checked'),'on'),

set(stat_bar,'string','Computing closed-loop step response');
step_cl = lsim(numcl,dencl,stp_input,tvec);
set(clos_step,'xdata',tvec,'ydata',step_cl,'vis','on');
if length(mode) > 1, mode(5) = 0; end

end

if strcmp(get(unit_ramp,'checked'),'on'),

set(stat_bar,'string','Computing closed-loop ramp response');
ramp_cl = lsim(numcl,dencl,rmp_input,tvec);
set(clos_ramp,'xdata',tvec,'ydata',ramp_cl,'vis','on');
if length(mode) > 1, mode(6) = 0; end

end

else

set(stat_bar,'string','Removing Closed-Loop');
set(clos_loop,'checked','off');
set([clos_imp,clos_step,clos_ramp,tim_txt([2:2:10])],'vis','off');

end

end

if any(mode==3), % unit impulse

if strcmp(get(unit_imp,'checked'),'off') | length(mode)>1,
set(unit_imp,'checked','on');

if strcmp(get(open_loop,'checked'),'on'),

set(stat_bar,'string','Computing open-loop impulse response');
imp_ol = lsim(num,den,imp_input,tvec);
set(open_imp,'xdata',tvec,'ydata',imp_ol,'vis','on');

end

if strcmp(get(clos_loop,'checked'),'on'),

set(stat_bar,'string','Computing closed-loop impulse response');
imp_cl = lsim(numcl,dencl,imp_input,tvec);
set(clos_imp,'xdata',tvec,'ydata',imp_cl,'vis','on');

end

else

set(stat_bar,'string','Removing impulse response');
set(unit_imp,'checked','off');
set([open_imp,clos_imp],'vis','off');

end

end

if any(mode==4), % unit step

if strcmp(get(unit_step,'checked'),'off') | length(mode)>1,
set(unit_step,'checked','on');

if strcmp(get(open_loop,'checked'),'on'),

set(stat_bar,'string','Computing open-loop step response');
step_ol = lsim(num,den,stp_input,tvec);
set(open_step,'xdata',tvec,'ydata',step_ol,'vis','on');

end

if strcmp(get(clos_loop,'checked'),'on'),

set(stat_bar,'string','Computing closed-loop step response');
step_cl = lsim(numcl,dencl,stp_input,tvec);
set(clos_step,'xdata',tvec,'ydata',step_cl,'vis','on');

end

set(ui_han(range2),'enable','on');

else

set(stat_bar,'string','Removing step response');
set(unit_step,'checked','off');
set([open_step,clos_step,tim_txt],'vis','off');
set(ui_han(range2),'enable','off');

end

end

if any(mode==5), % unit ramp

if strcmp(get(unit_ramp,'checked'),'off') | length(mode)>1,
set(unit_ramp,'checked','on');

if strcmp(get(open_loop,'checked'),'on'),

set(stat_bar,'string','Computing open-loop ramp response');
ramp_ol = lsim(num,den,rmp_input,tvec);
set(open_ramp,'xdata',tvec,'ydata',ramp_ol,'vis','on');

end

if strcmp(get(clos_loop,'checked'),'on'),

set(stat_bar,'string','Computing closed-loop ramp response');
ramp_cl = lsim(numcl,dencl,rmp_input,tvec);
set(clos_ramp,'xdata',tvec,'ydata',ramp_cl,'vis','on');

end

else

set(stat_bar,'string','Removing ramp response');
set(unit_ramp,'checked','off');
set([open_ramp,clos_ramp],'vis','off');

end

end

if any(mode < 6),

pageview(1,axs_hand);
ct = 1;
mode = 0;
for k = range2,
if strcmp(get(ui_han(k),'checked'),'on'),
mode(ct) = k-(range1(1)-1);
else
mode(ct) = 0;
end
ct = ct + 1;
end

end

if any(mode==6) & strcmp(get(rise_time,'enable'),'on'), % rise time

if strcmp(get(rise_time,'checked'),'off') | length(mode)>1,

if strcmp(get(open_loop,'checked'),'on'),
set(stat_bar,'string','Computing open-loop rise time');
set(rise_time,'checked','on');
amp = get(open_step,'ydata');
diff_amp = diff(amp);
loc_neg = find(diff_amp < 0);
if ~length(loc_neg), % overdamped system
less10 = find(amp>=0.1*final);
less90 = find(amp>=0.9*final);
riset = tvec(less90(1)) - tvec(less10(1));
risea = amp(less90(1));
set(tim_txt(1),'pos',[riset,risea,0],...
'string',['Rise time (10-90%) = ',num2str(riset)],'vis','on');
else  % underdamped system
less0 = 1;
less100 = find(amp>=final);
riset = tvec(less100(1)) - tvec(less0);
risea = amp(less100(1));
set(tim_txt(1),'pos',[riset,risea,0],...
'string',['Rise time (0-100%) = ',num2str(riset)],'vis','on');
end
end

if strcmp(get(clos_loop,'checked'),'on'),
set(stat_bar,'string','Computing closed-loop rise time');
set(rise_time,'checked','on');
amp = get(clos_step,'ydata');
diff_amp = diff(amp);
loc_neg = find(diff_amp < 0);
if ~length(loc_neg), % overdamped system
less10 = find(amp>=0.1*finalcl);
less90 = find(amp>=0.9*finalcl);
riset = tvec(less90(1)) - tvec(less10(1));
risea = amp(less90(1));
set(tim_txt(2),'pos',[riset,risea,0],...
'string',['Rise time (10-90%) = ',num2str(riset)],'vis','on');
else % underdamped system
less0 = 1;
less100 = find(amp>=finalcl);
riset = tvec(less100(1)) - tvec(less0);
risea = amp(less100(1));
set(tim_txt(1),'pos',[riset,risea,0],...
'string',['Rise time (0-100%) = ',num2str(riset)],'vis','on');
end
end

else

set(stat_bar,'string','Removing rise time');
set(rise_time,'checked','off');
set(tim_txt(1:2),'vis','off');
end

end

if any(mode==7) & strcmp(get(dlay_time,'enable'),'on'), % delay time

if strcmp(get(dlay_time,'checked'),'off') | length(mode)>1,

if strcmp(get(open_loop,'checked'),'on'),
set(stat_bar,'string','Computing open-loop delay time');
set(dlay_time,'checked','on');
amp = get(open_step,'ydata');
less50 = find(amp>=0.5*final);
dlayt = tvec(less50(1));
dlaya = amp(less50(1));
set(tim_txt(3),'pos',[dlayt,dlaya,0],...
'string',['Delay time = ',num2str(dlayt)],'vis','on');
end

if strcmp(get(clos_loop,'checked'),'on'),
set(stat_bar,'string','Computing closed-loop delay time');
set(dlay_time,'checked','on');
amp = get(clos_step,'ydata');
less50 = find(amp>=0.5*finalcl);
dlayt = tvec(less50(1));
dlaya = amp(less50(1));
set(tim_txt(4),'pos',[dlayt,dlaya,0],...
'string',['Delay time = ',num2str(dlayt)],'vis','on');
end

else

set(stat_bar,'string','Removing delay time');
set(dlay_time,'checked','off');
set(tim_txt(3:4),'vis','off');
end

end

if any(mode==8) & strcmp(get(peak_time,'enable'),'on'), % peak time

if strcmp(get(peak_time,'checked'),'off') | length(mode)>1,

if strcmp(get(open_loop,'checked'),'on'),
amp = get(open_step,'ydata');
diff_amp = diff(amp);
loc_neg = find(diff_amp < 0);
if length(loc_neg),
set(stat_bar,'string','Computing open-loop peak time');
set(peak_time,'checked','on');
peakt = tvec(loc_neg(1)-1);
peaka = amp(loc_neg(1)-1);
set(tim_txt(5),'pos',[peakt,peaka,0],...
'string',['Peak time = ',num2str(peakt)],'vis','on');
else
set(stat_bar,'string','Unable to determine open-loop peak time');
end
end

if strcmp(get(clos_loop,'checked'),'on'),
amp = get(clos_step,'ydata');
diff_amp = diff(amp);
loc_neg = find(diff_amp < 0);
if length(loc_neg),
set(stat_bar,'string','Computing closed-loop peak time');
set(peak_time,'checked','on');
peakt = tvec(loc_neg(1)-1);
peaka = amp(loc_neg(1)-1);
set(tim_txt(6),'pos',[peakt,peaka,0],...
'string',['Peak time = ',num2str(peakt)],'vis','on');
else
set(stat_bar,'string','Unable to determine closed-loop peak time');
end
end

else

set(stat_bar,'string','Removing peak time');
set(peak_time,'checked','off');
set(tim_txt(5:6),'vis','off');
end

end

if any(mode==9) & strcmp(get(over_shot,'enable'),'on'), % percent overshoot

if strcmp(get(over_shot,'checked'),'off') | length(mode)>1,

if strcmp(get(open_loop,'checked'),'on'),
set(stat_bar,'string','Computing open-loop % overshoot');
set(over_shot,'checked','on');
amp = get(open_step,'ydata');
[max_amp,k] = max(amp);
perover = 100*(max_amp-final)/final;
set(tim_txt(7),'pos',[tvec(k),max_amp,0],...
'string',[sprintf('%0.2f',perover),'% overshoot'],'vis','on');
end

if strcmp(get(clos_loop,'checked'),'on'),
set(stat_bar,'string','Computing closed-loop % Overshoot');
set(over_shot,'checked','on');
amp = get(clos_step,'ydata');
[max_amp,k] = max(amp);
perover = 100*(max_amp-finalcl)/finalcl;
set(tim_txt(8),'pos',[tvec(k),max_amp,0],...
'string',[sprintf('%0.2f',perover),'% overshoot'],'vis','on');
end

else

set(stat_bar,'string','Removing % overshoot');
set(over_shot,'checked','off');
set(tim_txt(7:8),'vis','off');
end

end

if any(mode==10) & strcmp(get(setl_2per,'enable'),'on'), % 2% settling time

if strcmp(get(setl_2per,'checked'),'off') | length(mode)>1,

if strcmp(get(open_loop,'checked'),'on'),
set(stat_bar,'string','Computing open-loop 2% settling time');
set(setl_2per,'checked','on');
amp = get(open_step,'ydata');
per2 = length(amp);
while (amp(per2)>0.98*final & amp(per2)<1.02*final), per2=per2-1; end
per2t = tvec(per2);
per2a = amp(per2);
set(tim_txt(9),'pos',[per2t,per2a,0],...
'string',['2%=',sprintf('%0.2f',per2t)],'vis','on');
end

if strcmp(get(clos_loop,'checked'),'on'),
set(stat_bar,'string','Computing closed-loop 2% settling time');
set(setl_2per,'checked','on');
amp = get(clos_step,'ydata');
per2 = length(amp);
while (amp(per2)>0.98*finalcl & amp(per2)<1.02*finalcl), per2=per2-1; end
per2t = tvec(per2);
per2a = amp(per2);
set(tim_txt(10),'pos',[per2t,per2a,0],...
'string',['2%=',sprintf('%0.2f',per2t)],'vis','on');
end

else

set(stat_bar,'string','Removing 2% settling time');
set(setl_2per,'checked','off');
set(tim_txt(9:10),'vis','off');
end

end

if any(mode==11) & strcmp(get(setl_5per,'enable'),'on'), % 5% settling time

if strcmp(get(setl_5per,'checked'),'off') | length(mode)>1,

if strcmp(get(open_loop,'checked'),'on'),
set(stat_bar,'string','Computing open-loop 5% settling time');
set(setl_5per,'checked','on');
amp = get(open_step,'ydata');
per5 = length(amp);
while (amp(per5)>0.95*final & amp(per5)<1.05*final), per5=per5-1; end
per5t = tvec(per5);
per5a = amp(per5);
set(tim_txt(11),'pos',[per5t,per5a,0],...
'string',['5%=',sprintf('%0.2f',per5t)],'vis','on');
end

if strcmp(get(clos_loop,'checked'),'on'),
set(stat_bar,'string','Computing closed-loop 5% settling time');
set(setl_5per,'checked','on');
amp = get(clos_step,'ydata');
per5 = length(amp);
while (amp(per5)>0.95*finalcl & amp(per5)<1.05*finalcl), per5=per5-1; end
per5t = tvec(per5);
per5a = amp(per5);
set(tim_txt(12),'pos',[per5t,per5a,0],...
'string',['5%=',sprintf('%0.2f',per5t)],'vis','on');
end

else

set(stat_bar,'string','Removing 5% settling time');
set(setl_5per,'checked','off');
set(tim_txt(11:12),'vis','off');
end

end

```