3213
|
1 # Copyright (C) 1996 A. Scottedward Hodel |
|
2 # |
|
3 # This file is part of Octave. |
|
4 # |
|
5 # Octave is free software; you can redistribute it and/or modify it |
|
6 # under the terms of the GNU General Public License as published by the |
|
7 # Free Software Foundation; either version 2, or (at your option) any |
|
8 # later version. |
|
9 # |
|
10 # Octave is distributed in the hope that it will be useful, but WITHOUT |
|
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
13 # for more details. |
|
14 # |
|
15 # You should have received a copy of the GNU General Public License |
|
16 # along with Octave; see the file COPYING. If not, write to the Free |
|
17 # Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
|
18 |
|
19 function sysrepdemo() |
|
20 |
|
21 # Octave Controls toolbox demo: System representation |
|
22 |
|
23 # Written by A. S. Hodel June 1995 |
|
24 # Revised Aug 1995 for system data structure format |
|
25 |
|
26 # $Revision: 1.1.1.1 $ |
|
27 # $Log: sysrepdemo.m,v $ |
|
28 # Revision 1.1.1.1 1998/05/19 20:24:09 jwe |
|
29 # |
|
30 # Revision 1.4 1997/02/13 15:38:26 hodel |
|
31 # fixed misprint in zp2sys demo (needed empty zeros vector in option 3) |
|
32 # |
|
33 # Revision 1.3 1997/02/13 15:22:32 hodel |
|
34 # fixed typo in menu option |
|
35 # |
|
36 # Revision 1.2 1997/02/12 11:53:22 hodel |
|
37 # *** empty log message *** |
|
38 # |
|
39 # Revision 1.1 1997/02/12 11:35:14 hodel |
|
40 # Initial revision |
|
41 # |
|
42 |
|
43 save_val = page_screen_output; |
|
44 page_screen_output = 1; |
|
45 |
|
46 disp('System representation demo:') |
|
47 num = [5 -1]; |
|
48 denom = [1 -2 6]; |
|
49 a = b = c = []; |
|
50 syschoice = -1; |
|
51 ch_init = 2; |
|
52 ch_extract = ch_init+1; |
|
53 ch_update = ch_extract+1; |
|
54 ch_view = ch_update+1; |
|
55 ch_details = ch_view+1; |
|
56 ch_quit = ch_details+1; |
|
57 while(syschoice != ch_quit) |
|
58 disp(" ") |
|
59 syschoice = menu('Octave System Representation Menu', ... |
|
60 "General overview of system representation (DO THIS FIRST)", ... |
|
61 "Initialize a system (ss2sys, tf2sys, zp2sys)", ... |
|
62 "Extract data from a system(sys2ss, sys2tf, sys2zp)", ... |
|
63 "Update internal representation (sysupdate)", ... |
|
64 "View the internal contents of a system (sysout)", ... |
|
65 "Details of internal representation", ... |
|
66 "Return to main menu"); |
|
67 if(syschoice == 1) # general overview |
|
68 disp("The Octave Control Systems Toolbox (OCST) was designed to") |
|
69 disp("provide a simple user interface to a powerful set of tools.") |
|
70 disp(' ') |
|
71 disp(' ----------') |
|
72 disp(' input(s) ---->| System | ---> output(s) ') |
|
73 disp(' ----------') |
|
74 disp(' ') |
|
75 disp("Like other computer-aided control system design tools, the OCST") |
|
76 disp("enables users to enter their descriptions of dynamic systems in ") |
|
77 disp("their preferred form (state space, transfer function, or "); |
|
78 disp("zero-pole format). "); |
|
79 disp("The OCST stores system descriptions in a single variable data "); |
|
80 disp("structure that allows for continuous time, discrete-time, or mixed "); |
|
81 disp("(sampled-data) systems. "); |
|
82 disp(" "); |
|
83 disp("This single variable description of dynamic systems greatly simplifies "); |
|
84 disp("both the code of the OCST as well as the user interface, since only") |
|
85 disp("one variable is passed per system, regardless of the internal ") |
|
86 disp("representation used in the data structure. As a result, the "); |
|
87 disp("likelihood of user error is greatly reduced when calling OCST") |
|
88 disp("functions. Further, all OCST functions have been written to") |
|
89 disp("provide meaningful warning or error message to assist the user") |
|
90 disp("in correcting their programming errors while using the OCST.") |
|
91 disp("The details of the internal representation can be seen in "); |
|
92 disp(["menu option ",num2str(ch_details)]); |
|
93 disp("The data structure used in the OCST is called a \"system data structure.\""); |
|
94 disp("A system data structure is contstructed with one of:") |
|
95 disp(" fir2sys (FIR transfer function to system)") |
|
96 disp(" ss2sys (state space matrices to system)") |
|
97 disp(" tf2sys (SISO transfer function to system)") |
|
98 disp(" zp2sys (SISO zero/pole/leading coefficient to system)") |
|
99 disp(" ") |
|
100 disp(["These functions are discussed in in menu option ",num2str(ch_init)]) |
|
101 disp("The data in a system may be extracted using ") |
|
102 disp(" sys2fir (FIR transfer function from system") |
|
103 disp(" sys2ss (state space matrices from system)") |
|
104 disp(" sys2tf (SISO transfer function from system)") |
|
105 disp(" sys2zp (SISO zero/pole/leading coefficient from system)") |
|
106 disp(" ") |
|
107 disp(["These functions are discussed in menu option ", ... |
|
108 num2str(ch_extract)]); |
|
109 disp("Other options discussed under this menu are updating the internal") |
|
110 disp("representation form of a system data structure with sysupdate and printing") |
|
111 disp("the description of a dynamic system to the screen with sysout.") |
|
112 disp(" ") |
|
113 disp("Once the user is familiar with these commands, the rest of the ") |
|
114 disp("OCST package will be quite easy to use.") |
|
115 elseif(syschoice == ch_init) % Initialize |
|
116 disp("Initialization of a system:"); |
|
117 disp(' '); |
|
118 formopt = 0; |
|
119 while(formopt != 4) |
|
120 disp("Three data formats may be used to initialize a system:") |
|
121 formopt = menu("System data structure initialization menu", ... |
|
122 "State space form (ss2sys)", ... |
|
123 "Transfer function form (tf2sys)", ... |
|
124 "zero-pole form (zp2sys)", ... |
|
125 "Return to System representation menu"); |
|
126 if(formopt == 1) |
|
127 disp('State space representation of a system is based on the usual') |
|
128 disp('multi-variable differential equations') |
|
129 disp(' ') |
|
130 disp(' . ') |
|
131 disp(' x = A x + B u -or - x(k+1) = A x(k) + B u(k) ') |
|
132 disp(' y = C x + D u y(k) = C x(k) + D u(k) ') |
|
133 disp(' ') |
|
134 disp('for matrices A, B, C, D of appropriate dimension.') |
|
135 disp(' ') |
|
136 ssopt = 0; |
|
137 ssquit = 5; |
|
138 while(ssopt < ssquit) |
|
139 ssopt = menu("State space initialization examples", ... |
|
140 "Double integrator example", ... |
|
141 "Double delay (discrete-time) example", ... |
|
142 "Summing junction (D-matrix only) example", ... |
|
143 "ss2sys details (help ss2sys)", ... |
|
144 "return to system initialization menu", ... |
|
145 "return to system representation main menu"); |
|
146 if(ssopt == 1) |
|
147 disp("Example: construct a system representation of a") |
|
148 disp("double integrator via state-space form") |
|
149 cmd = "a = [0 1; 0 0];"; |
|
150 run_cmd |
|
151 cmd = "b = [0 ; 1];"; |
|
152 run_cmd |
|
153 cmd = "c = [1 0];"; |
|
154 run_cmd |
|
155 cmd = "sys = ss2sys(a,b,c);"; |
|
156 run_cmd |
|
157 disp("The state space form of the system is seen via sysout:") |
|
158 cmd = "sysout(sys)"; |
|
159 run_cmd |
|
160 disp("Notice that the Octave controls toolbox automatically") |
|
161 disp("assigns names to the states, inputs and outputs,") |
|
162 disp("and that the D matrix was filled in automatically.") |
|
163 disp("We verify that it's a double integrator via sysout:") |
|
164 cmd = "sysout(sys,""tf"")"; |
|
165 run_cmd |
|
166 prompt |
|
167 elseif(ssopt == 2) |
|
168 disp("Example: discrete-time double-delay:") |
|
169 disp("This example is identical to the double-integrator,") |
|
170 disp("except that it is a discrete-time system, and so has") |
|
171 disp("a sampling interval. We arbitrarily select T=1e-3."); |
|
172 cmd = "a = [0 1; 0 0];"; |
|
173 run_cmd |
|
174 cmd = "b = [0 ; 1];"; |
|
175 run_cmd |
|
176 cmd = "c = [1 0];"; |
|
177 run_cmd |
|
178 cmd = "sys=ss2sys(a,b,c,[],1e-3);"; |
|
179 run_cmd |
|
180 cmd = "sysout(sys)"; |
|
181 run_cmd |
|
182 disp("Notice that the D matrix was filled in automatically.") |
|
183 disp("This is done if D is input as the empty matrix.") |
|
184 disp(" ") |
|
185 disp("Notice also that the output y_1 is labelled as a discrete") |
|
186 disp("output. The OCST data structure keeps track of states") |
|
187 disp("and output signals that are produced by the discrete-time") |
|
188 disp("portion of a system. Discrete states and outputs are ") |
|
189 disp("implemented as shown in the block diagram below:") |
|
190 disp(" ") |
|
191 disp(" ") |
|
192 disp(" _________ ________ x(kT) ________________") |
|
193 disp("f(t)-->|sampler|-->| delay |----->|zero order hold| -->") |
|
194 disp(" --------- -------- ----------------") |
|
195 disp(" ") |
|
196 disp(" ___________ _______________") |
|
197 disp("f(t)-->| sampler |-->|zero-order hold| --> y(discrete)") |
|
198 disp(" ----------- ---------------") |
|
199 disp(" ") |
|
200 disp("where f(t) is an input signal to either the output or the") |
|
201 disp(" discrete state.") |
|
202 disp(" ") |
|
203 disp("The OCST does not implement samplers on inputs to continuous") |
|
204 disp("time states (i.e., there are no samplers implicit in the B") |
|
205 disp("or D matrices unless there are corresponding discrete") |
|
206 disp("outputs or states. The OCST provides warning messages when") |
|
207 disp("if this convention is violated.") |
|
208 prompt |
|
209 elseif(ssopt == 3) |
|
210 disp("A summing junction that computes e(t) = r(t) - y(t) may be"); |
|
211 disp("constructed as follows:"); |
|
212 disp("First, we set the matrix D:") |
|
213 cmd = "D = [1 -1];"; |
|
214 run_cmd |
|
215 disp("ss2sys allows the initialization of signal and state names") |
|
216 disp("(see option 4), so we initialize these as follows:") |
|
217 cmd = "inname = [\"r(t)\";\"y(t)\"];"; |
|
218 run_cmd; |
|
219 cmd = "outname = \"e(t)\";"; |
|
220 run_cmd |
|
221 disp("Since the system is continous time and without states,") |
|
222 disp("the ss2sys inputs tsam, n, and nz are all zero:") |
|
223 cmd = "sys = ss2sys([],[],[],D,0,0,0,[],inname,outname);"; |
|
224 run_cmd |
|
225 disp("The resulting system is:") |
|
226 cmd = "sysout(sys)"; |
|
227 run_cmd |
|
228 disp("A discrete-time summing block can be implemented by setting") |
|
229 disp("the sampling time positive:") |
|
230 cmd = "sys = ss2sys([],[],[],D,1e-3,0,0,[],inname,outname);"; |
|
231 run_cmd |
|
232 disp("The resulting system is:") |
|
233 cmd = "sysout(sys)"; |
|
234 run_cmd |
|
235 prompt |
|
236 elseif(ssopt == 4) |
|
237 help ss2sys |
|
238 disp(" ") |
|
239 disp(" ") |
|
240 disp("Notice that state-space form allows a single system to have") |
|
241 disp("both continuous and discrete-time states and to have both continuous") |
|
242 disp("and discrete-time outputs. Since it's fairly easy to make an") |
|
243 disp("error when mixing systems of this form, the Octave controls") |
|
244 disp("toolbox attempts to print warning messages whenever something") |
|
245 disp("questionable occurs.") |
|
246 elseif(ssopt == 6) |
|
247 formopt = 4; # return to main menu |
|
248 endif |
|
249 endwhile |
|
250 elseif(formopt == 2) |
|
251 tfopt = 0; |
|
252 while(tfopt < 5) |
|
253 tfopt = menu("Transfer function initialization menu", ... |
|
254 "Continuous time initialization" , ... |
|
255 "Discrete time initialization" , ... |
|
256 "User specified signal names" , ... |
|
257 "tf2sys details (help tf2sys)", ... |
|
258 "Return to system initialization menu", ... |
|
259 "Return to system representation main menu"); |
|
260 if(tfopt == 1) # continuous time |
|
261 disp("A transfer function is represented by vectors of the") |
|
262 disp("coefficients of the numerator and denominator polynomials"); |
|
263 disp(" ") |
|
264 disp("For example: the transfer function"); |
|
265 disp(" "); |
|
266 num = [5 -1]; |
|
267 denom = [1 -2 6]; |
|
268 tfout(num,denom); |
|
269 disp(" ") |
|
270 disp("is generated by the following commands:") |
|
271 cmd = "num = [5 -1]"; |
|
272 run_cmd |
|
273 cmd = "denom = [1 -2 6]"; |
|
274 run_cmd |
|
275 cmd = "sys = tf2sys(num,denom);"; |
|
276 run_cmd |
|
277 disp("alternatively, the system can be generated in a single command:"); |
|
278 cmd = "sys = tf2sys([5 -1],[1 -2 6]);"; |
|
279 run_cmd |
|
280 disp("Notice the output of sys: it is an Octave data structure.") |
|
281 disp("The details of its member variables are explained under") |
|
282 disp("System Representation Menu option 5 (the details of system form)") |
|
283 disp(" "); |
|
284 disp("The data structure can be observed with the sysout command:") |
|
285 cmd = "sysout(sys)"; |
|
286 run_cmd |
|
287 disp("Notice that Octave assigns names to inputs and outputs.") |
|
288 disp("The user may manually select input and output names; see option 3"); |
|
289 prompt |
|
290 elseif(tfopt == 2) # discrete time |
|
291 disp("A transfer function is represented by vectors of the") |
|
292 disp("coefficients of the numerator and denominator polynomials"); |
|
293 disp("Discrete-time transfer functions require ") |
|
294 disp("the additional parameter of a sampling period:") |
|
295 cmd = "sys=tf2sys([5 -1],[1 2 -6],1e-3);"; |
|
296 run_cmd |
|
297 cmd = "sysout(sys)"; |
|
298 run_cmd |
|
299 disp("The OCST recognizes discrete-time transfer functions and") |
|
300 disp("accordingly prints them with the frequency domain variable z."); |
|
301 disp("Notice that Octave assigns names to inputs and outputs.") |
|
302 disp("The user may set input and output names; see option 3"); |
|
303 elseif(tfopt == 3) # user specified names |
|
304 disp("The OCST requires all signals to have names. The OCST assigned default"); |
|
305 disp("names to the signals in the other examples. We may initialize a transfer"); |
|
306 disp("function with user-specified names as follows: Consider a simple ") |
|
307 disp("double-integrator model of aircraft roll dynamics with ") |
|
308 disp("input \"aileron angle\" and output \"theta\". A ") |
|
309 disp("system for this model is generated by the command") |
|
310 cmd = "aircraft=tf2sys(1,[1 0 0],0,\"aileron angle\",\"theta\");"; run_cmd |
|
311 disp("The sampling time parameter 0 indicates that the system") |
|
312 disp("is continuous time. A positive sampling time indicates a") |
|
313 disp("discrete-time system (or sampled data system).") |
|
314 cmd = "sysout(aircraft)"; |
|
315 run_cmd |
|
316 disp("Notice that the user-selected signal names are listed.") |
|
317 disp("These signal names are used in OCST plots and design functions."); |
|
318 disp("(Run the frequency response demo to see an example of the use of "); |
|
319 disp("signal names in plots.)") |
|
320 prompt |
|
321 elseif(tfopt == 4) # help |
|
322 help tf2sys |
|
323 prompt |
|
324 elseif(tfopt == 6) # return to main menu |
|
325 formopt = 4; |
|
326 endif |
|
327 endwhile |
|
328 elseif (formopt == 3) |
|
329 zpopt = 0; |
|
330 while(zpopt < 5) |
|
331 zpopt = menu("Zero-pole initialization menu", ... |
|
332 "Continuous time initialization" , ... |
|
333 "Discrete time initialization" , ... |
|
334 "User specified signal names" , ... |
|
335 "zp2sys details (help zp2sys)", ... |
|
336 "Return to system initialization menu", ... |
|
337 "Return to system representation main menu"); |
|
338 if(zpopt == 1) # continuous time |
|
339 disp("A zero-pole form representation of a system includes vectors") |
|
340 disp("of the system poles and zeros and a scalar leading coefficient."); |
|
341 disp(" ") |
|
342 disp("For example: the transfer function"); |
|
343 disp(" "); |
|
344 k = 5; |
|
345 num = [5 -1]; |
|
346 denom = [1 -2 6]; |
|
347 zpout(num,denom,k); |
|
348 disp(" ") |
|
349 disp("is generated by the following commands:") |
|
350 cmd = "num = [5 -1]"; |
|
351 run_cmd |
|
352 cmd = "denom = [1 -2 6]"; |
|
353 run_cmd |
|
354 cmd = "k = 5"; |
|
355 run_cmd |
|
356 cmd = "sys = zp2sys(num,denom,k);"; |
|
357 run_cmd |
|
358 disp("alternatively, the system can be generated in a single command:"); |
|
359 cmd = "sys = zp2sys([5 -1],[1 -2 6],5);"; |
|
360 run_cmd |
|
361 disp("Notice the output of sys: it is an Octave data structure.") |
|
362 disp("The details of its member variables are explained under") |
|
363 disp("System Representation Menu option 5 (the details of system form)") |
|
364 disp(" "); |
|
365 disp("The data structure can be observed with the sysout command:") |
|
366 cmd = "sysout(sys)"; |
|
367 run_cmd |
|
368 disp("Notice that Octave assigns names to inputs and outputs.") |
|
369 disp("The user may manually select input and output names; see option 3"); |
|
370 prompt |
|
371 elseif(zpopt == 2) # discrete time |
|
372 disp("A zero-pole form representation of a system includes vectors") |
|
373 disp("of the system poles and zeros and a scalar leading coefficient."); |
|
374 disp(" ") |
|
375 disp("Discrete-time systems require the additional parameter of a sampling period:") |
|
376 cmd = "sys=zp2sys([5 -1],[1 2 -6],5,1e-3);"; |
|
377 run_cmd |
|
378 cmd = "sysout(sys)"; |
|
379 run_cmd |
|
380 disp("The OCST recognizes discrete-time transfer functions and") |
|
381 disp("accordingly prints them with the frequency domain variable z."); |
|
382 disp("Notice that Octave assigns names to inputs and outputs.") |
|
383 disp("The user may set input and output names; see option 3"); |
|
384 elseif(zpopt == 3) # user specified names |
|
385 disp("The OCST requires all signals to have names. The OCST assigned default"); |
|
386 disp("names to the signals in the other examples. We may initialize a transfer"); |
|
387 disp("function with user-specified names as follows: Consider a simple ") |
|
388 disp("double-integrator model of aircraft roll dynamics with ") |
|
389 disp("input \"aileron angle\" and output \"theta\". A ") |
|
390 disp("system for this model is generated by the command") |
|
391 cmd = "aircraft=zp2sys([],[0 0],1,0,\"aileron angle\",\"theta\");"; run_cmd |
|
392 disp("The sampling time parameter 0 indicates that the system") |
|
393 disp("is continuous time. A positive sampling time indicates a") |
|
394 disp("discrete-time system (or sampled data system).") |
|
395 cmd = "sysout(aircraft)"; |
|
396 run_cmd |
|
397 disp("Notice that the user-selected signal names are listed.") |
|
398 disp("These signal names are used in OCST plots and design functions."); |
|
399 disp("(Run the frequency response demo to see an example of the use of "); |
|
400 disp("signal names in plots.)") |
|
401 prompt |
|
402 elseif(zpopt == 4) # help |
|
403 help zp2sys |
|
404 prompt |
|
405 elseif(zpopt == 6) # return to main menu |
|
406 formopt = 4; |
|
407 endif |
|
408 endwhile |
|
409 endif |
|
410 endwhile |
|
411 elseif(syschoice == ch_extract) # extract system information |
|
412 disp("Extract information from a system data structure in a selected format:") |
|
413 disp("The actions of operations ss2sys, tf2sys, and zp2sys are reversed by") |
|
414 disp("respective functions sys2ss, sys2tf, and sys2zp. The latter two"); |
|
415 disp("functions are applicable only to SISO systems.") |
|
416 formopt = 0; |
|
417 while(formopt != 4) |
|
418 formopt = menu("Extract system information", ... |
|
419 "in state space form (sys2ss)", ... |
|
420 "in transfer function form (sys2tf)", ... |
|
421 "in zero pole form (sys2zp)", ... |
|
422 "Return to system representation menu"); |
|
423 if(formopt == 1) |
|
424 help sys2ss |
|
425 elseif(formopt == 2) |
|
426 help sys2tf |
|
427 elseif(formopt == 3) |
|
428 help sys2zp |
|
429 endif |
|
430 prompt |
|
431 endwhile |
|
432 elseif(syschoice== ch_update) |
|
433 disp("The OCST system data structure format will store a system in the same format") |
|
434 disp("as that with which it was initialized. For example, consider the following:") |
|
435 cmd = "sys=zp2sys([1 2],[3 4 5],6)"; |
|
436 run_cmd |
|
437 disp(" ") |
|
438 disp("Notice the internal variables in the structure include zer, pol, and k,") |
|
439 disp("the required variables for zero-pole form. We can update the system") |
|
440 disp("to include state-space form as follows:") |
|
441 cmd = "sys = sysupdate(sys,\"ss\")"; |
|
442 run_cmd |
|
443 disp(" ") |
|
444 disp("Now the sys data structure includes variables a, b, c, and d, as well") |
|
445 disp("the default state names stname. sysupdate is usually used internally in") |
|
446 disp("the OCST, but can be used manually if desired. A full description of") |
|
447 disp("sysupdate is as follows:") |
|
448 help sysupdate |
|
449 prompt |
|
450 elseif(syschoice == ch_view) |
|
451 disp("The sysout command can be used to view a system in any desired format.") |
|
452 disp("For example, consider the system created as follows:") |
|
453 cmd = "aircraft=zp2sys(1,[0 0],1,0,\"aileron angle\",\"theta\");"; run_cmd |
|
454 disp("The system may be viewed in its default format (zero-pole) as follows") |
|
455 cmd = "sysout(aircraft)"; |
|
456 run_cmd |
|
457 disp(" ") |
|
458 disp("The system may be viewed in state-space or transfer function form as well:") |
|
459 cmd = "sysout(aircraft,\"ss\")"; |
|
460 run_cmd |
|
461 cmd = "sysout(aircraft,\"tf\")"; |
|
462 run_cmd |
|
463 disp("A complete description of sysout is below:") |
|
464 help sysout |
|
465 prompt |
|
466 elseif(syschoice == ch_details) |
|
467 packedform |
|
468 endif |
|
469 |
|
470 endwhile |
|
471 page_screen_output = save_val; |
|
472 endfunction |
|
473 |