diff scripts/control/bddemo.m @ 3213:ba1c7cdc6090

[project @ 1998-11-06 16:15:36 by jwe]
author jwe
date Fri, 06 Nov 1998 16:16:31 +0000
parents
children dbcc24961c44
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/scripts/control/bddemo.m
@@ -0,0 +1,622 @@
+# Copyright (C) 1996 A. Scottedward Hodel 
+#
+# This file is part of Octave. 
+#
+# Octave is free software; you can redistribute it and/or modify it 
+# under the terms of the GNU General Public License as published by the 
+# Free Software Foundation; either version 2, or (at your option) any 
+# later version. 
+# 
+# Octave is distributed in the hope that it will be useful, but WITHOUT 
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+# for more details.
+# 
+# You should have received a copy of the GNU General Public License 
+# along with Octave; see the file COPYING.  If not, write to the Free 
+# Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ 
+function bddemo()
+# Octave Controls toolbox demo: Block Diagram Manipulations demo
+# Written by David Clem August 15, 1994
+# Modified by A S Hodel Summer-Fall 1996
+
+# Revision 1.6  1998/05/05 17:02:45  scotte
+# updated May 5 by Kai Meuller
+#
+# Revision 1.2  1998/05/05  13:21:51  mueller
+# buildssic command description
+# buildssic example added
+#
+# Revision 1.1  1998/05/05  13:20:26  mueller
+# Initial revision
+#
+ 
+  str_sav = implicit_str_to_num_ok;
+  sav_page = page_screen_output;
+  implicit_str_to_num_ok = 1;
+  page_screen_output = 1;
+
+  while (1)
+    clc
+    k=0;
+    while(k > 14 || k < 1)
+      k = menu("Octave Block Diagram Manipulations Demo", ...
+  	"sysadd/syssub: F(s) = G(s) +/- H(s)", ...
+ 	"sysappend: add new inputs/outputs", ...
+	"syschnames: change names of inputs, outputs, and/or states", ...
+	"sysconnect: connect specified system inputs/outputs", ...
+	"syscont/sysdisc: extract the continuous (discrete) part of a system", ...
+	"sysdup: duplicate specified inputs/outputs", ...
+	"sysgroup: group two systems into a single system,", ...
+	"sysmult: F(s) = G(s)*H(s) (series connection)", ...
+	"sysprune: keep only specified inputs/outputs", ...
+	"sysscale: scale inputs/outputs by specified gain matrices", ...
+	"parallel: parallel connection of two systems", ...
+	"buildssic: the combination of all", ...
+	"Design examples:", ...
+	"Return to main demo menu");
+    endwhile
+    if (k == 1)
+      clc
+      disp("sysadd: add two systems together")
+      disp("syssub: subtract F = G - H")
+      prompt
+      help sysadd
+      prompt
+      help syssub
+      prompt
+      disp('Example #1, \n')
+      cmd = "sys1 = tf2sys([1 -1],[1 2 1]);";
+      run_cmd
+      cmd = "sys2 = tf2sys([1 -1],[1 2 3]);";
+      run_cmd
+      disp("sys1=")
+      sysout(sys1);
+      prompt
+      disp("sys2=")
+      sysout(sys2);
+      cmd = "sys_sum1 = sysadd(sys1,sys1);";
+      run_cmd
+      disp("This example adds sys1 to itself.")
+      cmd = "sysout(sys_sum1)";
+      run_cmd
+      disp("Notice that the numerator is twice what it used to be.")
+      prompt
+      disp("Example 2:")
+      cmd = "sys_sub1 = syssub(sys1,sys2);";
+      run_cmd
+      disp("Notice that sysadd (actually sysgroup, called by sysadd) lets you")
+      disp("know that your two systems had identical names for their states,")
+      disp("inputs and outputs.  The warning message is perfectly harmless,")
+      disp("and is provided for user information only.")
+      disp("sys_sub1=")
+      sysout(sys_sub1)
+      disp("Notice that, since the two transfer functions had different")
+      disp("denominators, syssub converted the primary system type to ")
+      disp("state space.  This is the typical behavior unless the")
+      disp("the two systems are both SISO, they both have the same poles,")
+      disp("and at least one of them has  tf for its primary system type.");
+      prompt
+    elseif (k == 2)
+      disp("sysappend: add new inputs and/or outputs to a system")
+      help sysappend
+      prompt
+      disp("Consider a double-integrator system:")
+      sys = tf2sys(1,[1 0 0]);
+      sys=sysupdate(sys,"ss");
+      sysout(sys,"ss");
+      disp("We add a velocity disturbance input as follows:")
+      cmd = "sys1=sysappend(sys,[1;0]);";
+      run_cmd
+      sysout(sys1,"ss");
+      disp("Names of inputs can be included as follows:")
+      cmd = "sys1=sysappend(sys,[1;0], [],[],[],\"Disturb\");";
+      run_cmd
+      disp("Notice that empty matrices can be listed for the D matrix if")
+      disp("all entries are zeros.")
+      disp(" ")
+      disp("sys1 is thus:")
+      sysout(sys1);
+      prompt
+    elseif (k == 3)
+      disp("syschnames:")
+      help syschnames
+      disp("Example system");
+      a = rand(3,3);
+      b = rand(3,2);
+      c = rand(2,3);
+      sys = ss2sys(a,b,c);
+      sysout(sys);
+      prompt
+      disp("Change state names to larry, moe, and curly as follows:")
+      sys = syschnames(sys,"st",1:3,["larry";"moe  " ; "curly"]);
+      cmd = "sys = syschnames(sys,\"st\",1:3,[\"larry\";\"moe  \" ; \"curly\"]);";
+      run_cmd
+      disp("Indicate that output 2 is discrete-time:")
+      cmd = "sys = syschnames(sys,\"yd\",2,1);";
+      run_cmd
+      disp("Resulting system is:")
+      sysout(sys);
+      prompt
+    elseif (k == 4)
+      help sysconnect
+      prompt
+      disp("********* N O T E *********")
+      disp("sysconnect is demonstrated fully in the design examples (option 13)");
+      prompt
+    elseif (k == 5)
+      disp("syscont and sysdisc: ")
+      disp("Example block diagram 1:")
+      disp("        ------------------     ---------------------");
+      disp(" u_in ->| Discrete system |--->| Continuous system | ---> y_out");
+      disp("        ------------------     ---------------------");
+      sys1 = tf2sys([1 2],[1 2 1], 1,"u_in","y_disc");
+      sys2 = tf2sys([1 0],[1 -3 -2],0,"c_in","y_out");
+      sys = sysmult(sys2,sys1);
+      disp("Consider the hybrid system")
+      sysout(sys);
+      prompt
+      help syscont
+      disp("The continuous part of the system can be extracted with syscont")
+      cmd = "[csys,Acd,Ccd] = syscont(sys);";
+      run_cmd
+      disp("The resulting csys is")
+      sysout(csys);
+      disp("Notice that B is 0; there is no purely continuous path from the")
+      disp("input to the output");
+      prompt
+      help sysdisc
+      disp("The discrete part of the system can be extracted with sysdisc")
+      cmd = "[dsys,Adc,Cdc] = sysdisc(sys)";
+      run_cmd
+      disp("The resulting dsys is")
+      sysout(dsys);
+      disp("sysdisc returns dsys=empty since sys has no discrete outputs.");
+      prompt
+      disp("Example block diagram 2:")
+      sys1 = tf2sys([1 2],[1 2 1], 1,"u_in","y_disc");
+      sys2 = tf2sys([1 0],[1 -3 -2],0,"c_in","y_out");
+      disp("             ---------------------")
+      disp(" u_in -->o-->| Discrete system   | --------> y_disc")
+      disp("         ^   ---------------------    |")  
+      disp("         |                            | ");
+      disp("         -----------------------------|---")
+      disp("                                      |  |")
+      disp("         ------------------------------  |")
+      disp("         |                               |")
+      disp("         v   ---------------------       |")
+      disp(" c_in -->o-->| continuous system | --------> y_out")
+      disp("             ---------------------")
+      disp("repeat the above example with sys=")
+      sys = sysgroup(sys1, sys2);
+      sysout(sys)
+      prompt
+      sys = sysconnect(sys,[1 2],[2 1]);
+      sysout(sys);
+      cmd = "[csys,Acd,Bcd] = syscont(sys);";
+      run_cmd
+      cmd = "[dsys,Acd,Bcd] = sysdisc(sys);";
+      run_cmd
+      disp("csys is now")
+      sysout(csys)
+      disp("dsys is now")
+      sysout(dsys);
+      prompt
+    elseif (k == 6)
+      help sysdup
+      prompt
+      disp("********* N O T E *********")
+      disp("sysdup is fully demonstrated in the design examples (option 13)")
+      prompt
+    elseif (k == 7)
+      help sysgroup
+      disp(" ")
+      prompt
+      disp("Example: combine two SISO systems together:")
+      cmd = "sys_a=tf2sys([1 2],[3 4]);";
+      run_cmd
+      cmd = "sys_b=tf2sys([5 6],[7 8],1);";
+      run_cmd
+      cmd = "sys_g=sysgroup(sys_a,sys_b);";
+      run_cmd
+      disp("Notice that sysgroup warns you when you join a purely continuous")
+      disp("system to a purely discrete system.  sysgroup also warns when")
+      disp("you join two systems that have common state, input, or output names.")
+      cmd = "sysout(sys_g)";
+      run_cmd
+      disp("Since the grouped system is a multiple-input multiple-output system,")
+      disp("the output system is by default in state-space format.")
+      disp(" ")
+      disp("********* N O T E *********")
+      disp("sysgroup is further demonstrated in the design examples (option 13)")
+      prompt
+    elseif (k == 8)
+      help sysmult
+      disp("sysmult performs a series connection of two systems.")
+      disp("Example 1")
+      disp(" ")
+      disp("         ----------     ----------")
+      disp("   u --->|  Bsys  |---->|  Asys  |---> y")
+      disp("         ----------     ----------")
+      disp(" ")
+      Asys = tf2sys(1,[1 2 1],0,"a_in","a_out");
+      Bsys = tf2sys([2 3],[1 3 2],0,"b_in","b_out");
+      disp("Asys=")
+      sysout(Asys);
+      disp("Bsys=");
+      sysout(Bsys);
+      cmd = "sys = sysmult(Asys,Bsys);";
+      run_cmd
+      disp("sys =")
+      sysout(sys);
+      disp("Notice that sysmult automatically transforms to state space")
+      disp("internal representation.  This is to avoid numerical problems")
+      disp("when multiplying polynomials");
+      prompt
+      disp("Example 2: same system, except that Bsys is discrete-time");
+      Bsys = tf2sys([2 3],[1 3 2],1e-2,"b_in","b_out");
+      sysout(Bsys);
+      cmd = "sys = sysmult(Asys,Bsys);";
+      run_cmd
+      disp("sys =")
+      sysout(sys);
+      prompt
+    elseif (k == 9)
+      help sysprune
+      prompt
+      disp("********* N O T E *********")
+      disp("sysprune is demonstrated in the design examples (option 13)");
+      prompt
+    elseif (k == 10)
+      help sysscale
+      disp(" ")
+      prompt
+      disp("********* N O T E *********")
+      disp("See the design examples (option 13) for use of sysscale.")
+      prompt
+    elseif ( k == 11)
+      help parallel
+      disp("parallel operates by making a call to sysgroup and sysscale.")
+      disp("Example:")
+      sys1 = tf2sys(1,[1 1],0,"in1","out1");
+      sys2 = tf2sys(2,[1 2],0,"in2","out2");
+      disp("sys1=")
+      sysout(sys1);
+      disp("sys2=")
+      sysout(sys2);
+      cmd = "sysp = parallel(sys1,sys2);";
+      run_cmd
+      disp("sysp=")
+      sysout(sysp);
+      prompt
+      disp("parallel can be used for multiple input systems as well:")
+
+      in1 = ["u1.1";"u1.2"];
+      in2 = ["u2.1";"u2.2"];
+      out1 = ["y1.1";"y1.2"];
+      out2 = ["y2.1";"y2.2"];
+
+      sys1 = ss2sys([-1,0;0 -2],eye(2),eye(2),[]);
+      sys2 = ss2sys([-2,0;0 -4],eye(2),eye(2),[]);
+
+      sys1 = syschnames(sys1,"in",1:2,in1);
+      sys1 = syschnames(sys1,"out",1:2,out1);
+
+      sys2 = syschnames(sys2,"in",1:2,in2);
+      sys2 = syschnames(sys2,"out",1:2,out2);
+     
+      disp("sys1=")
+      sysout(sys1);
+      disp("sys2=")
+      sysout(sys2);
+      cmd = "sysp = parallel(sys1,sys2);";
+      run_cmd
+      disp("sysp=")
+      sysout(sysp);
+      prompt
+    elseif (k == 12)
+      # buildssic description
+      disp(" ")
+      disp("        ---------------------------------------")
+      disp("                    b u i l d s s i c")
+      disp("          (BUILD State Space InterConnections)")
+      disp("        ---------------------------------------")
+      disp(" ")
+      disp("buildssic builds a single system from up to 8 systems.")
+      disp("It's primary pupose is the forming of interconnections")
+      disp("for H2/H_inf designs and the building of closed loop")
+      disp("systems.")
+      disp("The interconnections may be of arbitrary complexity.")
+      disp("The use of buildssic is an alternative to sysgroup,")
+      disp("sysadd/syssub, sysappend, sysconnect, sysdup, sysmult")
+      disp("sysprune, sysscale, parallel etc.")
+      disp("In contrast to these functions buildssic does not")
+      disp("handle mixed continuous and discrete systems. However,")
+      disp("discrete systems can be connected as long as their")
+      disp("sampling times are identical. Another drawback: the")
+      disp("names of input/output and state variables are clobbered.")
+      disp("Of course, buildsysic is useful in combination with sysgroup,")
+      disp("sysmult etc.")
+      prompt
+      disp("********* N O T E *********")
+      disp("buildssic is demonstrated in the design examples (option 13)");
+      prompt
+    elseif (k == 13)
+      disp("Design examples")
+      disp("Packed system matrices may be connected and manipulated")
+      disp("With the functions listed below:")
+      disp("  sysdup: duplicate selected inputs/outputs")
+      disp("  sysconnect: connect selected inputs/outputs")
+      disp("  sysgroup: group two systems together")
+      disp("  sysprune: prune a system to keep only selected inputs and outputs")
+      disp("  sysscale:pre/post multiply a system by constant matrices")
+      disp("  buildssic: connect systems with arbitrary complexity.")
+      prompt
+      disp("As a simple example, we will construct the system block ")
+      disp("diagram shown below ")
+      disp(" ")
+      disp("         +          --------    --------");
+      disp("  r(t) ---> (+) --->| K(s) |--->| P(s) | ----> y(t)");
+      disp("            -^      --------    --------  |");
+      disp("             |                            |");
+      disp("             ------------------------------");
+      disp(" ")
+      disp("where P(s) is the plant, K(s) is the controller.")
+      prompt
+      disp("Simple example: P(s) is a first order lag, K(s) is a PI ")
+      disp("controller")
+      nump = 1;
+      denp = [1  1];
+      disp("P(s)=")
+      tfout(nump,denp)
+      numk = [1 1];
+      denk = [1 0];
+      disp("\nK(s)=")
+      tfout(numk,denk);
+      prompt
+      disp("We'll show three approaches.  ")
+      P = tf2sys(nump,denp,0,"plant input","plant output");
+      K = tf2sys(numk, denk,0,"controller input","controller output");
+
+      meth = 0;
+      while(meth != 5)
+        disp("The first method consists of the following steps:")
+        disp("   step 1: create systems P and K")
+        disp("   step 2: group P and K together")
+        disp("   step 3: create a summing junction")
+        disp("   step 4: connect outputs to respective inputs")
+        disp("   step 5: prune the desired i/o connections")
+        disp("The second method is done as follows:")
+        disp("   step 1: create systems P and K and a summing block S")
+        disp("   step 2: connect P, K, and S in series")
+        disp("   step 3: connect y to inverted summing connection")
+        disp("   step 4: prune the desired i/o connections")
+        disp("The third method uses buildssic:")
+        disp("   step 1: GW = buildssic(...,K,P)")
+        disp(" ")
+        disp("Other design examples are in dgkfdemo (controldemo option 7)")
+        disp(" ")
+        meth = menu("Select design example method", ...
+		"Method 1 ", ...
+		"Method 1 (w/o algebraic loop warning)", ...
+		"Method 2", ...
+		"Method 3", ...
+		"Exit design examples");
+        if(meth == 1)
+          disp(" * * * Method 1 * * *")
+          disp(" ")
+          disp("         +          --------    --------");
+          disp("  r(t) ---> (+) --->| K(s) |--->| P(s) | ----> y(t)");
+          disp("            -^      --------    --------  |");
+          disp("             |                            |");
+          disp("             ------------------------------");
+          disp(" ")
+          disp("Step 1: put plants in system format:");
+          nump
+          denp
+          cmd =  "P = tf2sys(nump,denp,0,""plant input"",""plant output"");";
+          run_cmd
+          disp("P=")
+          sysout(P)
+          prompt
+          numk
+          denk
+          cmd = "K = tf2sys(numk, denk,0,""controller input"",""controller output"");";
+          run_cmd
+          sysout(K)
+          prompt
+          disp("Step 2: group the systems together")
+          cmd = "PK = sysgroup(P,K);";
+          run_cmd
+          disp("PK=")
+          sysout(PK);
+          prompt
+          disp(" ")
+          disp("                           y2   u1")
+          disp("         +          --------    --------");
+          disp("  r(t) ---> (+) --->| K(s) |--->| P(s) | ----> y(t)");
+          disp("  u2        -^      --------    --------    |  y1");
+          disp("          u3 |                              |");
+          disp("             --------------------------------");
+          disp(" ")
+          disp("The controller has two inputs summed together, r(t)")
+          disp("and the negative feedback of  y(t)")
+          disp("Step 3a: duplicate controller input: (input 2 of PK)")
+          prompt
+          cmd = "PK = sysdup(PK,[],2);";
+          run_cmd
+          disp("PK=")
+          sysout(PK);
+          disp("Notice that PK now has three inputs (input 3 is a duplicate ");
+          prompt("of input 2).  Press return to go on")
+          disp("Step 3b: scale input 3 by -1")
+          cmd = "PK = sysscale(PK,[],diag([1,1,-1]));";
+          run_cmd
+          disp("PK=")
+          sysout(PK);
+          prompt
+          disp("Step 4: connect:")
+          disp("   y(t) (output 1) to the negative sum junction (input 3)")
+          disp("   u(t) (output 2) to plant input (input 1)")
+          disp("and prune extraneous inputs/outputs (retain input 2, output 1)")
+          prompt
+          out_connect = [1 2]
+          in_connect = [3 1]
+          cmd = "PK0 = sysconnect(PK,out_connect,in_connect);"; 
+          run_cmd
+          prompt
+          disp("Notice that sysconnect detects the possibility of algebraic") 
+          disp("connections when connecting inputs.  Option 2 (Method 1 ")
+          disp("without algebraic loops) shows how to avoid this warning")
+          disp("by performing connections one at a time.")
+          prompt
+          disp("PK0=")
+          sysout(PK0);
+          disp("Notice that the connected inputs now have stars on their")
+          disp("names.  This is how the Octave controls toolbox reminds you")
+          disp("that the loop has been closed around these inputs.")
+          prompt("Press return to prune extra inputs/outputs from system")
+          disp("Only keep plant output (output 1) and r(t) (input 2)")
+          cmd = "PK0 = sysprune(PK0,1,2);";
+          run_cmd
+          disp("PK0=")
+          sysout(PK0);
+          prompt
+          disp("The resulting closed-loop transfer function is obtained as follows:")
+          cmd = "[num,den] = sys2tf(PK0);";
+          run_cmd
+          prompt
+          disp("Transfer function is now")
+          tfout(num,den)
+          disp("You can check this: Pk0=PK/(1+PK), as expected")
+          prompt
+        elseif(meth == 2)
+          disp("Method 1 without algebraic loops")
+          disp(" ")
+          disp("                           y2   u1")
+          disp("         +          --------    --------");
+          disp("  r(t) ---> (+) --->| K(s) |--->| P(s) | ----> y(t)");
+          disp("  u2        -^      --------    --------    |  y1");
+          disp("          u3 |                              |");
+          disp("             --------------------------------");
+          disp(" ")
+          disp("Recall that sysconnect checks for algebraic loops.  Although")
+          disp("Design option 1 gets a warning message about a possible");
+ 	  disp("algebraic loop, such a loop does not exist.")
+          disp("This can be seen by performing the connections one at a time");
+          cmd = "PK = sysgroup(P,K);";
+          run_cmd
+          disp("PK=")
+          sysout(PK);
+          disp("Create an additial inverted input to the controller.")
+          cmd = "PK = sysdup(PK,[],2);";
+          run_cmd
+          cmd = "PK = sysscale(PK,[],diag([1,1,-1]));";
+          run_cmd
+          disp("PK=")
+          sysout(PK);
+          disp("Connect controller to plant:")
+          cmd = "PK0 = sysconnect(PK,2,1);"; 
+          run_cmd
+          disp("Plant output to negative control input")
+          cmd = "PK0 = sysconnect(PK0,1,3);"; 
+          run_cmd
+          disp("Only keep plant output (output 1) and r(t) (input 2)")
+          cmd = "PK0 = sysprune(PK0,1,2);";
+          run_cmd
+          disp("PK0=")
+          sysout(PK0);
+          prompt
+          disp("The transfer function form of PK0 is:")
+          sysout(PK0,"tf");
+          prompt
+        elseif(meth == 3)
+          disp(" * * * Method 2 * * *")
+          disp(" ")
+          disp("         +          --------    --------");
+          disp("  r(t) ---> (+) --->| K(s) |--->| P(s) | ----> y(t)");
+          disp("            -^      --------    --------  |");
+          disp("             |                            |");
+          disp("             ------------------------------");
+          disp(" ")
+      disp("Step 1: We've already created systems P and K.  Create a sum ")
+      disp("block as follows:")
+      implicit_str_to_num_ok = "warn";
+      cmd = "S = ss2sys([],[],[],[1 -1],0,0,0,[],[""r(t)"";""y(t)""],""e(t)"");";
+      run_cmd
+      implicit_str_to_num_ok = 1;
+      disp("You may avoid the string conversion warning by setting the ")
+      disp("Octave global variables implicit_str_to_num_ok = 1");
+      disp(" ");
+      disp("(You may wish to look at help ss2sys to see what the above does)");
+      disp("S=")
+      sysout(S)
+      disp("notice that this is just a gain block that outputs e = r - y")
+      prompt
+      disp("Step 2: series connections of P, K, and S")
+      cmd = "PKS = sysmult(P,sysmult(K,S));";
+      run_cmd
+      disp("PKS=")
+      sysout(PKS)
+      disp("Step 3: connect y to inverted input")
+      cmd = "PKcl = sysconnect(PKS,1,2);";
+      run_cmd
+      disp("PKcl=")
+      sysout(PKcl)
+      disp("Step 4: prune desired inputs/outputs")
+      cmd = "PKcl=sysprune(PKcl,1,1);";
+      run_cmd
+      disp("PKcl=")
+      sysout(PKcl)
+      prompt
+        elseif(meth == 4)
+          disp(" * * * Method 3 * * *")
+          disp(" ")
+          disp("         +          --------    --------");
+          disp("  r(t) ---> (+) --->| K(s) |--->| P(s) | ----> y(t)");
+          disp("            -^      --------    --------  |");
+          disp("             |                            |");
+          disp("             ------------------------------");
+          disp(" ")
+      disp("Step 1: We've already created systems P and K.")
+      disp("        Let us call buildssic:")
+      disp("   PKcl = buildssic([1 2;2 -1],[],[1],[2],P,K)")
+      disp(" ")
+      disp("                         ^      ^  ^   ^  ^ ^")
+      disp("                         |      |  |   |  | |")
+      disp("     Connection list ----+      |  |   |  | |")
+      disp(" internal input list -----------+  |   |  | +-- controller")
+      disp("         output list --------------+   |  |")
+      disp("          input list ------------------+  +---- plant")
+      disp(" ")
+      disp(" Connection list: connect input 1 (P) with output 2 (K)")
+      disp("                  connect input 2 (K) with neg. outp. 1 (P)")
+      disp(" ")
+      disp("  int. inp. list: do not append internal inputs")
+      disp("                  (e.g. the internal input of K (r-y))")
+      disp(" ")
+      disp("     output list: the only output is 1 (P), positive")
+      disp(" ")
+      disp("      input list: the only input is 2 (K), positive")
+      disp(" ")
+      cmd = "PKcl = buildssic([1 2;2 -1],[],[1],[2],P,K);"
+      run_cmd
+      sysout(PKcl)
+      prompt
+      disp("The transfer function form of PKcl is:")
+      sysout(PKcl,"tf");
+      disp("You can check this: PKcl = PK / (1 + PK), as expected")
+      prompt
+      elseif(meth != 5)
+        disp("Illegal selection")
+     endif
+    endwhile
+      
+    elseif (k == 14)
+      return
+    endif
+  endwhile  
+  implict_str_to_num_ok = str_sav;
+  page_screen_output = sav_page;
+endfunction