3228
|
1 # Copyright (C) 1996,1998 A. Scottedward Hodel |
3213
|
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 |
3228
|
19 function retsys = ss2sys (a,b,c,d,tsam,n,nz,stname,inname,outname,outlist) |
|
20 # retsys = ss2sys (a,b,c{,d,tsam,n,nz,stname,inname,outname,outlist}) |
3213
|
21 # Create system structure from state-space data. May be continous, |
|
22 # discrete, or mixed (sampeld-data) |
|
23 # inputs: |
|
24 # a, b, c, d: usual state space matrices. |
|
25 # default: d = zero matrix |
|
26 # tsam: sampling rate. Default: tsam = 0 (continuous system) |
|
27 # n, nz: number of continuous, discrete states in the system |
|
28 # default: tsam = 0: n = rows(a), nz = 0 |
|
29 # tsam > 0: n = 0, nz = rows(a), n |
|
30 # see below for system partitioning |
3228
|
31 # stname: list of strings of state signal names |
3213
|
32 # default (stname=[] on input): x_n for continuous states, |
|
33 # xd_n for discrete states |
3228
|
34 # inname: list of strings of input signal names |
3213
|
35 # default (inname = [] on input): u_n |
3228
|
36 # outname: list of strings of output signal names |
3213
|
37 # default (outname = [] on input): y_n |
|
38 # outlist: list of indices of outputs y that are sampled |
|
39 # default: (tsam = 0) outlist = [] |
|
40 # (tsam > 0) outlist = 1:rows(c) |
|
41 # Unlike states, discrete/continous outputs may appear |
|
42 # in any order. |
|
43 # Note: sys2ss returns a vector yd where |
|
44 # yd(outlist) = 1; all other entries of yd are 0. |
|
45 # |
|
46 # System partitioning: Suppose for simplicity that outlist specified |
|
47 # that the first several outputs were continuous and the remaining outputs |
|
48 # were discrete. Then the system is partitioned as |
|
49 # x = [ xc ] (n x 1) |
|
50 # [ xd ] (nz x 1 discrete states) |
|
51 # a = [ acc acd ] b = [ bc ] |
|
52 # [ adc add ] [ bd ] |
|
53 # c = [ ccc ccd ] d = [ dc ] |
|
54 # [ cdc cdd ] d = [ dd ] (cdc = c(outlist,1:n), etc.) |
|
55 # |
|
56 # with dynamic equations: |
|
57 # |
|
58 # d/dt xc(t) = acc*xc(t) + acd*xd(k*tsam) + bc*u(t) |
|
59 # xd((k+1)*tsam) = adc*xc(k*tsam) + add*xd(k*tsam) + bd*u(k*tsam) |
|
60 # yc(t) = ccc*xc(t) + ccd*xd(k*tsam) + dc*u(t) |
|
61 # yd(k*tsam) = cdc*xc(k*tsam) + cdd*xd(k*tsam) + dd*u(k*tsam) |
|
62 # |
|
63 # signal partitions: |
|
64 # | continuous | discrete | |
|
65 # ------------------------------------------------------ |
|
66 # states | stname(1:n,:) | stname((n+1):(n+nz),:) | |
|
67 # ------------------------------------------------------ |
|
68 # outputs | outname(cout,:) | outname(outlist,:) | |
|
69 # ------------------------------------------------------ |
|
70 # |
|
71 # where cout = list if indices in 1:rows(p) not contained in outlist. |
|
72 # |
|
73 |
|
74 # Written by John Ingram (ingraje@eng.auburn.edu) July 20, 1996 |
|
75 |
|
76 save_val = implicit_str_to_num_ok; # save for later |
|
77 implicit_str_to_num_ok = 1; |
|
78 |
|
79 # Test for correct number of inputs |
|
80 if ((nargin < 3) | (nargin > 11)) |
3228
|
81 usage("retsys = ss2sys (a,b,c{,d,tsam,n,nz,stname,inname,outname,outlist})"); |
3213
|
82 endif |
|
83 |
|
84 # verify A, B, C, D arguments |
|
85 # If D is not specified, set it to a zero matrix of appriate dimension. |
3228
|
86 if (nargin == 3) d = zeros(rows(c) , columns(b)); |
|
87 elseif (isempty(d)) d = zeros(rows(c) , columns(b)); endif |
3213
|
88 |
|
89 # Check the dimensions |
|
90 [na,m,p] = abcddim(a,b,c,d); |
|
91 |
|
92 # If dimensions are wrong, exit function |
|
93 if (m == -1) |
3228
|
94 error("a(%dx%d), b(%dx%d), c(%dx%d), d(%dx%d); incompatible", ... |
|
95 rows(a), columns(a), rows(b), columns(b), rows(c), columns(c), ... |
|
96 rows(d), columns(d)); |
3213
|
97 endif |
|
98 |
|
99 # check for tsam input |
3228
|
100 if(nargin < 5) tsam = 0; |
3213
|
101 elseif( !( is_sample(tsam) | (tsam == 0) ) ) |
|
102 error("tsam must be a nonnegative real scalar"); |
|
103 endif |
|
104 |
|
105 # check for continuous states |
3228
|
106 if( (nargin < 6) & (tsam == 0) ) n = na; |
|
107 elseif(nargin < 6) n = 0; |
3213
|
108 elseif( (!is_scalar(n)) | (n < 0 ) | (n != round(n)) ) |
3228
|
109 if(is_scalar(n)) error("illegal value of n=%d,%e",n,n); |
|
110 else error("illegal value of n=(%dx%d)", ... |
|
111 rows(n), columns(n)); endif |
3213
|
112 endif |
|
113 |
|
114 # check for num discrete states |
3228
|
115 if( (nargin < 7) & (tsam == 0)) nz = 0; |
|
116 elseif(nargin < 7) nz = na - n; |
3213
|
117 elseif( (!is_scalar(nz)) | (nz < 0 ) | (nz != round(nz)) ) |
|
118 if(is_scalar(nz)) |
|
119 error(["illegal value of nz=",num2str(nz)]); |
|
120 else |
|
121 error(["illegal value of nz=(",num2str(rows(nz)),"x", ... |
|
122 num2str(columns(nz)),")"]); |
|
123 endif |
|
124 endif |
|
125 |
|
126 #check for total number of states |
|
127 if( (n + nz) != na ) |
|
128 error(["Illegal: a is ",num2str(na),"x",num2str(na),", n=", ... |
|
129 num2str(n),", nz=",num2str(nz)]); |
|
130 endif |
|
131 |
3228
|
132 # construct system with default names |
|
133 retsys.a = a; |
|
134 retsys.b = b; |
|
135 retsys.c = c; |
|
136 retsys.d = d; |
|
137 |
|
138 retsys.n = n; |
|
139 retsys.nz = nz; |
|
140 retsys.tsam = tsam; |
|
141 retsys.yd = zeros(1,p); # default value entered below |
|
142 |
|
143 # Set the system vector: active = 2(ss), updated = [0 0 1]; |
|
144 retsys.sys = [2 0 0 1]; |
|
145 |
|
146 retsys.stname = sysdefstname(n,nz); |
|
147 retsys.inname = sysdefioname(m,"u"); |
|
148 retsys.outname = sysdefioname(p,"y"); |
|
149 |
3213
|
150 # check for state names |
3228
|
151 if(nargin >= 8) |
|
152 if(!isempty(stname)) retsys = syssetsignals(retsys,"st",stname); endif |
3213
|
153 endif |
|
154 |
|
155 #check for input names |
3228
|
156 if(nargin >= 9) |
3231
|
157 if(!isempty(inname)) retsys = syssetsignals(retsys,"in",inname); endif |
3213
|
158 endif |
|
159 |
|
160 #check for output names |
3228
|
161 if(nargin >= 10) |
|
162 if(!isempty(outname)) retsys = syssetsignals(retsys,"out",outname); endif |
3213
|
163 endif |
|
164 |
|
165 # set up yd |
|
166 if(nargin < 11) |
3228
|
167 retsys = syssetsignals(retsys,"yd",ones(1,p)*(tsam > 0)); |
3213
|
168 else |
3228
|
169 if(!isempty(outlist)) |
3229
|
170 retsys = syssetsignals(retsys,"yd",ones(size(outlist)),outlist); |
3213
|
171 endif |
|
172 endif |
|
173 |
|
174 implicit_str_to_num_ok = save_val; # restore value |
|
175 endfunction |