Mercurial > hg > ltpda
comparison m-toolbox/classes/@ssm/bodecst.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0afece42f48 |
---|---|
1 % BODECST makes a bodecst plot from the given inputs to outputs. | |
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
3 % | |
4 % DESCRIPTION: BODECST makes a bodecst plot from the given inputs to outputs. | |
5 % | |
6 % CALL: as = bodecst(sys, pl) | |
7 % as = bodecst(sys, 'key1', 'option1') | |
8 % | |
9 % INPUTS: | |
10 % 'sys' - ssm object | |
11 % 'pl' - plist of options | |
12 % | |
13 % OUTPUTS: | |
14 % | |
15 % 'as' - array of output AOs containing the requested responses. | |
16 % | |
17 % <a href="matlab:utils.helper.displayMethodInfo('ssm', 'bodecst')">Parameters Description</a> | |
18 % | |
19 % VERSION: $Id: bodecst.m,v 1.14 2011/04/08 08:56:23 hewitson Exp $ | |
20 % | |
21 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
22 | |
23 function varargout = bodecst(varargin) | |
24 | |
25 %% starting initial checks | |
26 % Check if this is a call for parameters | |
27 if utils.helper.isinfocall(varargin{:}) | |
28 varargout{1} = getInfo(varargin{3}); | |
29 return | |
30 end | |
31 | |
32 utils.helper.msg(utils.const.msg.MNAME, ['running ', mfilename]); | |
33 | |
34 % Collect input variable names | |
35 in_names = cell(size(varargin)); | |
36 for ii = 1:nargin,in_names{ii} = inputname(ii);end | |
37 | |
38 % Collect all AOs and plists | |
39 [system, ssm_invars, rest] = utils.helper.collect_objects(varargin(:), 'ssm', in_names); | |
40 [pl, invars2, rest] = utils.helper.collect_objects(rest(:), 'plist'); | |
41 if ~isempty(rest) | |
42 pl = combine(pl, plist(rest{:})); | |
43 end | |
44 pl = combine(pl, getDefaultPlist()); | |
45 | |
46 %%% Internal call: Only one object + don't look for a plist | |
47 internal = strcmp(varargin{end}, 'internal'); | |
48 | |
49 %% retrieving system's infos | |
50 if numel(system)~=1 | |
51 error('we should have only one ssm and one plist object as an input') | |
52 end | |
53 if ~internal | |
54 inhist = system.hist; | |
55 if ~system.isStable | |
56 error('input ssm is not stable!') | |
57 end | |
58 end | |
59 if (system.isnumerical == 0) | |
60 warning(['The system ' system.name ' is symbolic. The system is made numeric for bode calculation.']) | |
61 sys = copy(system,1); | |
62 sys.keepParameters; | |
63 else | |
64 sys = system; | |
65 end | |
66 | |
67 %% Compute frequency vector | |
68 f = pl.find('f'); | |
69 if isempty(f) | |
70 % finding "f2" | |
71 if isempty(pl.find('f2')) | |
72 if sys.timestep>0 | |
73 f2 = 0.5/sys.timestep; | |
74 else | |
75 f2 = 1; | |
76 end | |
77 else | |
78 f2 = pl.find('f2'); | |
79 end | |
80 % finding "f1" | |
81 if isempty(pl.find('f1')) | |
82 f1 = f2*1e-5; | |
83 else | |
84 f1 = pl.find('f1'); | |
85 end | |
86 nf = pl.find('nf'); | |
87 scale = pl.find('scale'); | |
88 % building "f" vector | |
89 switch lower(scale) | |
90 case 'log' | |
91 f = logspace(log10(f1), log10(f2), nf); | |
92 case 'lin' | |
93 f = linspace(f1, f2, nf); | |
94 otherwise | |
95 error('### Unknown scale option'); | |
96 end | |
97 end | |
98 | |
99 % Is the f vector in an AO? | |
100 if isa(f, 'ao') && (isa(f.data, 'fsdata') || isa(f.data, 'xydata')) | |
101 f = f.x; | |
102 end | |
103 | |
104 % Compute omega | |
105 w = 2*pi*f; | |
106 | |
107 if find(pl, 'reorganize') | |
108 sys = reorganize(sys, pl, 'set', 'for bode', 'internal', 'internal'); | |
109 end | |
110 | |
111 %% getting system's i/o sizes | |
112 timestep = sys.timestep; | |
113 fs = 1/timestep; | |
114 | |
115 inputSizes = sys.inputsizes; | |
116 outputSizes = sys.outputsizes; | |
117 | |
118 Nin = inputSizes(1); | |
119 NstatesOut = outputSizes(1); | |
120 NoutputsOut = outputSizes(2); | |
121 | |
122 A = sys.amats{1,1}; | |
123 Coutputs = sys.cmats{2,1}; | |
124 Cstates = sys.cmats{1,1}; | |
125 B = sys.bmats{1,1}; | |
126 D = sys.dmats{2,1}; | |
127 Dstates = zeros(size(Cstates,1), size(D,2)); | |
128 | |
129 %% bode computation | |
130 sys_ss = ss(A, B, [Cstates; Coutputs], [Dstates; D], timestep); | |
131 [mag,phase] = bode(sys_ss, w); | |
132 resps = mag.*(cos(phase*pi/180) + 1i.*sin(phase*pi/180)); | |
133 %% build AO | |
134 | |
135 myinfo = getInfo('None'); | |
136 isysStr = sys.name; | |
137 ao_out = ao.initObjectWithSize(NstatesOut+NoutputsOut, Nin); | |
138 myInfo = getInfo('None'); | |
139 | |
140 for ii=1:Nin | |
141 for oo=1:NstatesOut | |
142 ao_out(oo,ii).setData(fsdata(f, squeeze(resps(oo,ii,:)), fs)); | |
143 if ~ internal | |
144 ao_out(oo,ii).setName( [sys.inputs(1).ports(ii).name '-->' sys.outputs(1).ports(oo).name]); | |
145 ao_out(oo,ii).setXunits('Hz'); | |
146 ao_out(oo,ii).setYunits( simplify(sys.outputs(1).ports(oo).units / sys.inputs(1).ports(ii).units)); | |
147 ao_out(oo,ii).setDescription(... | |
148 ['Bode of ' isysStr, ' from ', sys.inputs(1).ports(ii).description,... | |
149 ' to ' sys.outputs(1).ports(oo).description]); | |
150 | |
151 ao_out(oo,ii).addHistory(myInfo, pl, ssm_invars, inhist ); | |
152 end | |
153 end | |
154 for oo=1:NoutputsOut | |
155 ao_out(NstatesOut+oo,ii).setData(fsdata(f, squeeze(resps(NstatesOut+oo,ii,:)), fs)); | |
156 if ~ internal | |
157 ao_out(NstatesOut+oo,ii).setName( [sys.inputs(1).ports(ii).name '-->' sys.outputs(2).ports(oo).name]); | |
158 ao_out(NstatesOut+oo,ii).setXunits('Hz'); | |
159 ao_out(NstatesOut+oo,ii).setYunits( simplify(sys.outputs(2).ports(oo).units / sys.inputs(1).ports(ii).units)); | |
160 ao_out(NstatesOut+oo,ii).setDescription(... | |
161 ['Bode of ' isysStr, ' from ', sys.inputs(1).ports(ii).description,... | |
162 ' to ' sys.outputs(2).ports(oo).description]); | |
163 ao_out(NstatesOut+oo,ii).addHistory(myinfo, pl, ssm_invars(1), inhist ); | |
164 end | |
165 end | |
166 end | |
167 | |
168 %% Set output depending on nargout | |
169 if nargout == numel(ao_out) | |
170 for jj=1:nargout | |
171 varargout{jj} = ao_out(jj); | |
172 end | |
173 elseif nargout == 1; | |
174 varargout{1} = ao_out; | |
175 elseif nargout == 0; | |
176 iplot(ao_out); | |
177 else | |
178 error('Wrong number of outputs') | |
179 end | |
180 | |
181 end | |
182 | |
183 | |
184 %-------------------------------------------------------------------------- | |
185 % Get Info Object | |
186 %-------------------------------------------------------------------------- | |
187 function ii = getInfo(varargin) | |
188 | |
189 if nargin == 1 && strcmpi(varargin{1}, 'None') | |
190 sets = {}; | |
191 pl = []; | |
192 else | |
193 sets = {'Default'}; | |
194 pl = getDefaultPlist; | |
195 end | |
196 % Build info object | |
197 ii = minfo(mfilename, 'ssm', 'ltpda', utils.const.categories.sigproc, '$Id: bodecst.m,v 1.14 2011/04/08 08:56:23 hewitson Exp $', sets, pl); | |
198 end | |
199 | |
200 %-------------------------------------------------------------------------- | |
201 % Get Default Plist | |
202 %-------------------------------------------------------------------------- | |
203 function pl = getDefaultPlist() | |
204 pl = ssm.getInfo('reorganize', 'for bode').plists; | |
205 pl.remove('set'); | |
206 | |
207 p = param({'f', 'A frequency vector (replaces f1, f2 and nf).'}, paramValue.EMPTY_DOUBLE) ; | |
208 pl.append(p); | |
209 | |
210 p = param({'f2', 'The maximum frequency. Default is Nyquist or 1Hz.'}, paramValue.EMPTY_DOUBLE); | |
211 pl.append(p); | |
212 | |
213 p = param({'f1', 'The minimum frequency. Default is f2*1e-5.'}, paramValue.EMPTY_DOUBLE); | |
214 pl.append(p); | |
215 | |
216 p = param({'nf', 'The number of frequency bins.'}, paramValue.DOUBLE_VALUE(1000)); | |
217 pl.append(p); | |
218 | |
219 p = param({'scale', 'Distribute frequencies on a ''log'' or ''lin'' scale.'}, {1, {'log', 'lin'}, paramValue.SINGLE}); | |
220 pl.append(p); | |
221 | |
222 p = param({'reorganize', 'When set to 0, this means the ssm does not need be modified to match the requested i/o. Faster but dangerous!'}, paramValue.TRUE_FALSE); | |
223 pl.append(p); | |
224 | |
225 end | |
226 | |
227 | |
228 | |
229 |