Mercurial > forge
changeset 10201:6f1e79f2d62e octave-forge
control-devel: fix arx argument checking for degrees of numerator and denominator
author | paramaniac |
---|---|
date | Wed, 09 May 2012 10:36:17 +0000 |
parents | 6e3b26da118c |
children | 46f08d64ad0e |
files | extra/control-devel/devel/CDplayerARX.m extra/control-devel/devel/GlassFurnaceARX.m extra/control-devel/inst/arx.m |
diffstat | 3 files changed, 112 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extra/control-devel/devel/CDplayerARX.m Wed May 09 10:36:17 2012 +0000 @@ -0,0 +1,78 @@ +%{ +Contributed by: + Favoreel + KULeuven + Departement Electrotechniek ESAT/SISTA +Kardinaal Mercierlaan 94 +B-3001 Leuven +Belgium + wouter.favoreel@esat.kuleuven.ac.be +Description: + Data from the mechanical construction of a CD player arm. + The inputs are the forces of the mechanical actuators + while the outputs are related to the tracking accuracy of the arm. + The data was measured in closed loop, and then through a two-step + procedure converted to open loop equivalent data + The inputs are highly colored. +Sampling: +Number: + 2048 +Inputs: + u: forces of the mechanical actuators +Outputs: + y: tracking accuracy of the arm +References: + We are grateful to R. de Callafon of the + Mechanical Engineering Systems and Control group of Delft, who + provided us with these data. + + - Van Den Hof P., Schrama R.J.P., An Indirect Method for Transfer + Function Estimation From Closed Loop Data. Automatica, Vol. 29, + no. 6, pp. 1523-1527, 1993. + +Properties: +Columns: + Column 1: input u1 + Column 2: input u2 + Column 1: output y1 + Column 2: output y2 +Category: + mechanical systems + +%} + +clear all, close all, clc + +load CD_player_arm-1.dat +U=CD_player_arm_1(:,1:2); +Y=CD_player_arm_1(:,3:4); + + +dat = iddata (Y, U) + +% [sys, x0] = ident (dat, 15, 8) % s=15, n=8 +sys = arx (dat, 4, [4 4]) + +%[y, t] = lsim (sys, U, [], x0); +%[y, t] = lsim (sys(:,1:2), U); + +[A, B] = filtdata (sys); +%[A, B] = tfdata (sys); + + +y1 = filter (B{1,1}, A{1,1}, U(:,1)) + filter (B{1,2}, A{1,2}, U(:,2)); +y2 = filter (B{2,1}, A{2,1}, U(:,1)) + filter (B{2,2}, A{2,2}, U(:,2)); +y = [y1, y2]; + +t = 0:length(U)-1; + +err = norm (Y - y, 1) / norm (Y, 1) + +figure (1) +p = columns (Y); +for k = 1 : p + subplot (2, 1, k) + plot (t, Y(:,k), 'b', t, y(:,k), 'r') +endfor + +
--- a/extra/control-devel/devel/GlassFurnaceARX.m Wed May 09 03:49:09 2012 +0000 +++ b/extra/control-devel/devel/GlassFurnaceARX.m Wed May 09 10:36:17 2012 +0000 @@ -49,7 +49,7 @@ dat = iddata (Y, U) %[sys, x0] = ident (dat, 10, 5) % s=10, n=5 -sys = arx (dat, 5, [5 5 5]) +sys = arx (dat, 5, 5) %[y, t] = lsim (sys, U, [], x0); [y, t] = lsim (sys(:, 1:3), U);
--- a/extra/control-devel/inst/arx.m Wed May 09 03:49:09 2012 +0000 +++ b/extra/control-devel/inst/arx.m Wed May 09 10:36:17 2012 +0000 @@ -9,25 +9,36 @@ endif if (! isa (dat, "iddata")) - error ("arx: "); - endif - -## if (! is_real_scalar (na, nb)) - if (! is_real_vector (na, nb)) - error ("arx: "); - ## Test for integers - ## numel (nb) == size (dat, 3) + error ("arx: first argument must be an iddata dataset"); endif - ## TODO: handle MIMO and multi-experiment data + ## p: outputs, m: inputs, ex: experiments [~, p, m, ex] = size (dat); + ## extract data Y = dat.y; U = dat.u; - Ts = dat.tsam{1}; + tsam = dat.tsam; + + ## multi-experiment data requires equal sampling times + if (ex > 1 && ! isequal (tsam{:})) + error ("arx: require equally sampled experiments"); + else + tsam = tsam{1}; + endif + - max_nb = max (nb); - n = max (na, max_nb); + if (is_real_scalar (na, nb)) + na = repmat (na, p, 1); # na(p-by-1) + nb = repmat (nb, p, m); # nb(p-by-m) + elseif (! (is_real_vector (na) && is_real_matrix (nb) \ + && rows (na) == p && rows (nb) == p && columns (nb) == m)) + error ("arx: require na(%dx1) instead of (%dx%d) and nb(%dx%d) instead of (%dx%d)", \ + p, rows (na), columns (na), p, m, rows (nb), columns (nb)); + endif + + max_nb = max (nb, [], 2); # one maximum for each row/output, max_nb(p-by-1) + n = max (na, max_nb); # n(p-by-1) num = cell (p, m+1); @@ -38,16 +49,17 @@ for e = 1 : ex # for every experiment ## avoid warning: toeplitz: column wins anti-diagonal conflict ## therefore set first row element equal to y(1) - PhiY = toeplitz (Y{e}(1:end-1, i), [Y{e}(1, i); zeros(na-1, 1)]); % TODO: multiple na - PhiU = arrayfun (@(x) toeplitz (U{e}(1:end-1, x), [U{e}(1, x); zeros(nb(x)-1, 1)]), 1:m, "uniformoutput", false); - Phi{e} = (horzcat (-PhiY, PhiU{:}))(n:end, :); + PhiY = toeplitz (Y{e}(1:end-1, i), [Y{e}(1, i); zeros(na(i)-1, 1)]); + ## create MISO Phi for every experiment + PhiU = arrayfun (@(x) toeplitz (U{e}(1:end-1, x), [U{e}(1, x); zeros(nb(i,x)-1, 1)]), 1:m, "uniformoutput", false); + Phi{e} = (horzcat (-PhiY, PhiU{:}))(n(i):end, :); endfor Theta = __theta__ (Phi, Y, i, n); - A = [1; Theta(1:na)]; # a0 = 1, a1 = Theta(1), an = Theta(n) - ThetaB = Theta(na+1:end); # b0 = 0 (leading zero required by filt) - B = mat2cell (ThetaB, nb); + A = [1; Theta(1:na(i))]; # a0 = 1, a1 = Theta(1), an = Theta(n) + ThetaB = Theta(na(i)+1:end); # b0 = 0 (leading zero required by filt) + B = mat2cell (ThetaB, nb(i,:)); B = reshape (B, 1, []); B = cellfun (@(x) [0; x], B, "uniformoutput", false); @@ -55,7 +67,7 @@ den(i, :) = repmat ({A}, 1, m+1); endfor - sys = filt (num, den, Ts); + sys = filt (num, den, tsam); endfunction @@ -81,7 +93,7 @@ V = V(:, 1:r); S = S(1:r); U = U(:, 1:r); - theta = V * (S .\ (U' * y{1}(n+1:end, i))); # U' is the conjugate transpose + theta = V * (S .\ (U' * y{1}(n(i)+1:end, i))); # U' is the conjugate transpose else ## multi-experiment dataset ## TODO: find more sophisticated formula than @@ -92,7 +104,7 @@ C = plus (tmp{:}); ## PhiTY = (Phi1' Y1 + Phi2' Y2 + ...) - tmp = cellfun (@(Phi, Y) Phi.' * Y(n+1:end, i), phi, y, "uniformoutput", false); + tmp = cellfun (@(Phi, Y) Phi.' * Y(n(i)+1:end, i), phi, y, "uniformoutput", false); PhiTY = plus (tmp{:}); ## pseudoinverse Theta = C \ Phi'Y @@ -100,18 +112,3 @@ endif endfunction - -%{ -function Phi = __phi__ (dat, na, nb, ex) - - ## avoid warning: toeplitz: column wins anti-diagonal conflict - ## therefore set first row element equal to y(1) - PhiY = toeplitz (Y(1:end-1, :), [Y(1, :); zeros(na-1, 1)]); - - ## PhiU = toeplitz (U(1:end-1, :), [U(1, :); zeros(nb-1, 1)]); - PhiU = arrayfun (@(x) toeplitz (U(1:end-1, x), [U(1, x); zeros(nb(x)-1, 1)]), 1:m, "uniformoutput", false); - Phi = horzcat (-PhiY, PhiU{:}); - Phi = Phi(n:end, :); - -endfunction -%} \ No newline at end of file