From: <par...@us...> - 2009-07-15 12:43:15
|
Revision: 6016 http://octave.svn.sourceforge.net/octave/?rev=6016&view=rev Author: paramaniac Date: 2009-07-15 12:43:10 +0000 (Wed, 15 Jul 2009) Log Message: ----------- feedback: pimped for better matlab compatibility Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-07-15 06:19:47 UTC (rev 6015) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-07-15 12:43:10 UTC (rev 6016) @@ -1,44 +1,334 @@ -## Copyright (C) 2000 Ben Sapp. All rights reserved. +## Copyright (C) 2000 Ben Sapp <bs...@la...> +## Copyright (C) 2009 Lukas Reichlin <luk...@sw...> ## -## This program 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. +## This program 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 3 of the License, or +## (at your option) any later version. ## -## This 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. +## This program 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 this program. If not, see <http://www.gnu.org/licenses/>. -## feedback(sys1,sys2) +## -*- texinfo -*- +## @deftypefn{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}) +## @deftypefnx{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}, @var{sign}) +## @deftypefnx{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}, @var{feedin}, @var{feedout}) +## @deftypefnx{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}, @var{feedin}, @var{feedout}, @var{sign}) +## Returns model sys for the feedback interconnection; i. e. filters the output of sys1 +## through sys2 and subtracts it from the input. Displays warnings if inputs, outputs +## or states of sys1 and sys2 have equal names. Occasionally warns about possible algebraic +## loops as well. These warnings are perfectly harmless and are due to the internal use +## of sysgroup and sysconnect. ## -## Filter the output of sys1 through sys2 and subtract it from the input. +## @strong{Inputs} +## @table @var +## @item sys1 +## System data structure or gain matrix. +## @item sys2 +## System data structure or gain matrix. +## @item feedin +## Optional vector of input indices for sys1. +## @item feedout +## Optional vector of output indices for sys1. +## @item sign +## If not specified, default value -1 is taken, resulting in a negative feedback. +## Use +1 for positive feedback. +## @end table ## -## _____________ -## + | | -## u --->0----->| sys1 |-------> -## |- |____________| | -## | | -## | _____________ | -## | | | | -## -------| sys2 |---- -## |____________| +## @strong{Outputs} +## @table @var +## @item sys +## System data structure of feedback interconnection. +## @end table ## -## This only works for SISO systems. +## @seealso{sysgroup, sysdup, sysscale, sysconnect, sysprune} +## +## @example +## @group +## u + +--------+ y +## ------>(+)----->| sys1 |-------+-------> +## ^ - +--------+ | +## | | +## | +--------+ | +## +-------| sys2 |<------+ +## +--------+ +## @end group +## @end example +## +## @end deftypefn ## Author: Ben Sapp <bs...@la...> +## Rewritten from scratch by Lukas Reichlin +## for better M*tl*b compatibility in July 2009 +## Version: 0.1 -function out = feedback(sys1,sys2) - if (nargin != 2) - error("only 2 arguements accepted"); +function sys = feedback (varargin) + + if (nargin < 2 || nargin > 5) + print_usage (); endif - if(!is_siso(sys1) || !is_siso(sys2)) - error("only single input single output systems supported"); + + ## Determine sys1 from input + if (isstruct (varargin{1})) + sys1 = varargin{1}; + elseif (ismatrix (varargin{1})) + sys1 = ss ([], [], [], varargin{1}); + else + error ("feedback: argument 1 (sys1) invalid"); endif - T = sysgroup(sys1,sys2); - T = sysdup(T,2,[]); - T = sysscale(T,diag([1,1,-1]),[]); - T = sysconnect(T,3,1); - T = sysconnect(T,1,2); - out = sysprune(T,1,1); + + ## Determine sys2 from input + if (isstruct (varargin{2})) + sys2 = varargin{2}; + elseif (ismatrix (varargin{2})) + sys2 = ss ([], [], [], varargin{2}); + else + error ("feedback: argument 2 (sys2) invalid"); + endif + + ## Determine feedback sign + fb_sign = -1; # Default value + + if (nargin == 3) + if (isreal (varargin{3})) + if (varargin{3} == +1) + fb_sign = +1; + endif + if (varargin{3} != -1 && varargin{3} != +1) + error ("feedback: argument 3 (sign) invalid"); + endif + endif + endif + + if (nargin == 5) + if (isreal (varargin{5})) + if (varargin{5} == +1) + fb_sign = +1; + endif + if (varargin{5} != -1 && varargin{3} != +1) + error ("feedback: argument 5 (sign) invalid"); + endif + endif + endif + + ## Get system information + [n_c_states_1, n_d_states, n_in_1, n_out_1] = sysdimensions (sys1); + [n_c_states_2, n_d_states_2, n_in_2, n_out_2] = sysdimensions (sys2); + + + ## Get connection lists feedin and feedout + for k = 1 : n_in_1 + feedin(k) = k; # Default value + endfor + + for k = 1 : n_out_1 + feedout(k) = k; # Default value + endfor + + if (nargin == 4 || nargin == 5) + if (isvector (varargin{3})) + feedin = varargin{3}; + else + error ("feedback: argument 3 (feedin) invalid"); + endif + + if (isvector (varargin{4})) + feedin = varargin{4}; + else + error ("feedback: argument 4 (feedout) invalid"); + endif + endif + + l_feedin = length (feedin); + l_feedout = length (feedout); + + if (l_feedin > n_in_1) + error ("feedback: feedin has too many indices"); + endif + + if (l_feedin != n_out_2) + error ("feedback: number of feedin indices and number of outputs of sys2 incompatible"); + endif + + if (l_feedout > n_out_1) + error ("feedback: feedout has too many indices"); + endif + + if (l_feedout != n_in_2) + error ("feedback: number of feedout indices and number of inputs of sys2 incompatible"); + endif + + + ## Group sys1 and sys2 together + sys = sysgroup(sys1, sys2); + + + ## Duplicate inputs specified in feedin + sys = sysdup(sys, [], feedin); + + ## Duplicated inputs start now at number (n_in_1 + n_in_2 + 1) + ## and end at number (n_in_1 + n_in_2 + l_feedin) + + + ## Scale inputs + for k = 1 : (n_in_1 + n_in_2) + in_scl(k) = 1; + endfor + + for k = (n_in_1 + n_in_2 + 1) : (n_in_1 + n_in_2 + l_feedin) + in_scl(k) = fb_sign; + endfor + + sys = sysscale (sys, [], diag (in_scl)); + + + ## Connect outputs with inputs + + ## connect outputs of sys1 to inputs of sys2 + ## output indices of sys1 start at (1) + ## and end at (n_out_1) --> use feedout! + ## input indices of sys2 start at (n_in_1 + 1) + ## and end at (n_in_1 + n_in_2) + + for k = 1 : l_feedout + in_idx(k) = n_in_1 + k; + endfor + + sys = sysconnect (sys, feedout, in_idx); + + ## connect outputs of sys2 to inputs of sys1 + ## output indices of sys 2 start at (n_out_1 + 1) + ## and end at (n_out_1 + n_out_2) + ## duplicated input indices of sys 1 start at (n_in_1 + n_in_2 + 1) + ## and end at (n_in_1 + n_in_2 + l_feedin) + ## sequence of feedin already mapped to duplicated inputs + ## ---> (n_in_1 + n_in_2 + k) + + for k = 1 : l_feedin + out_idx(k) = n_out_1 + k; + endfor + + for k = 1 : l_feedin + in_dup_idx(k) = n_in_1 + n_in_2 + k; + endfor + + sys = sysconnect (sys, out_idx, in_dup_idx); + + + ## Extract resulting model + for k = 1 : n_out_1 + out_idx(k) = k; + endfor + + for k = 1 : n_in_1 + in_idx(k) = k; + endfor + + sys = sysprune(sys, out_idx, in_idx); + endfunction + + +%!shared A, B, C, D, F_exp, G_exp, H_exp, J_exp, F, G, H, J, sys, sysc, M, N, outsys, zer, pol, k, zer_exp, pol_exp, k_exp +%! +%! ## Given Open Loop State Space Matrices +%! +%! A = [ -25 0 0 0 50 0 763 310.7 -27.93 -96.51 216.4 -61 ; +%! 0.261 -4 -0.002 0 0 0 0 0 0 0 0 0 ; +%! 618 7640 -3.07 0 0 338.4 17.19 -2247 5459 -2782 298.7 2849 ; +%! -0.384 5.89 0.003 -2.1 0 -0.21 -0.01822 0.9135 -0.9346 2.552 -0.0403 -1.761 ; +%! 0 0 0 0 0 0 30.52 12.43 -1.117 -3.861 8.658 -2.44 ; +%! 0 0 0 0 0 0 0.1735 -8.7 8.901 -24.31 0.3839 16.77 ; +%! 0 0 0 0 0 0 -788 -310.7 26.59 96.98 -166.4 61 ; +%! 0 0 0 0 0 0 5.22 -4 -7.945 0.2199 0 0 ; +%! 0 0 0 0 0 0 3.004 13.14 -31.54 13.91 -1.493 -12.56 ; +%! 0 0 0 0 0 0 -7.316 -12.38 30.69 -54.82 0.8061 31.01 ; +%! 0 0 0 0 0 0 -30.52 -12.43 0.6207 3.803 -8.658 2.44 ; +%! 0 0 0 0 0 0 -0.1735 8.7 -8.958 24.8 -0.3839 -16.77 ]; +%! +%! B = [ 0 0 ; +%! 0 0 ; +%! 0 0 ; +%! 0 0 ; +%! 0 0 ; +%! 0 0 ; +%! 0.006741 -9.319 ; +%! -0.0002757 -4.397 ; +%! 0.005862 0.01201 ; +%! 3.002e-06 33.54 ; +%! 0.002484 1.146 ; +%! 0.0002864 -9.934 ]; +%! +%! C = [ 0 0 1 0 0 0 0 0 0 0 0 0 ; +%! 0 0 0 1 0 0 0 0 0 0 0 0 ]; +%! +%! D = [ 0 0 ; +%! 0 0 ]; +%! +%! ## Expected Closed Loop State Space Matrices +%! +%! F_exp = [ -25 0 0 0 50 0 763 310.7 -27.93 -96.51 216.4 -61 ; +%! 0.261 -4 -0.002 0 0 0 0 0 0 0 0 0 ; +%! 618 7640 -3.07 0 0 338.4 17.19 -2247 5459 -2782 298.7 2849 ; +%! -0.384 5.89 0.003 -2.1 0 -0.21 -0.01822 0.9135 -0.9346 2.552 -0.0403 -1.761 ; +%! 0 0 0 0 0 0 30.52 12.43 -1.117 -3.861 8.658 -2.44 ; +%! 0 0 0 0 0 0 0.1735 -8.7 8.901 -24.31 0.3839 16.77 ; +%! 0 0 -0.006741 9.319 0 0 -788 -310.7 26.59 96.98 -166.4 61 ; +%! 0 0 0.0002757 4.397 0 0 5.22 -4 -7.945 0.2199 0 0 ; +%! 0 0 -0.005862 -0.01201 0 0 3.004 13.14 -31.54 13.91 -1.493 -12.56 ; +%! 0 0 -3.002e-06 -33.54 0 0 -7.316 -12.38 30.69 -54.82 0.8061 31.01 ; +%! 0 0 -0.002484 -1.146 0 0 -30.52 -12.43 0.6207 3.803 -8.658 2.44 ; +%! 0 0 -0.0002864 9.934 0 0 -0.1735 8.7 -8.958 24.8 -0.3839 -16.77 ]; +%! +%! G_exp = [ 0 0 ; +%! 0 0 ; +%! 0 0 ; +%! 0 0 ; +%! 0 0 ; +%! 0 0 ; +%! 0.006741 -9.319 ; +%! -0.0002757 -4.397 ; +%! 0.005862 0.01201 ; +%! 3.002e-06 33.54 ; +%! 0.002484 1.146 ; +%! 0.0002864 -9.934 ]; +%! +%! H_exp = [ 0 0 1 0 0 0 0 0 0 0 0 0 ; +%! 0 0 0 1 0 0 0 0 0 0 0 0 ]; +%! +%! J_exp = [ 0 0 ; +%! 0 0 ]; +%! +%! sys1 = ss(A, B, C, D); +%! sys = feedback(sys1, eye(2)); +%! [F, G, H, J] = sys2ss(sys); +%! +%! sysc = feedback(sys1, eye(2), [1, 2], [1, 2], -1); +%! +%! +%! M = tf([2, 5, 1], [1, 2, 3]); +%! N = zp(-2, -10, 5); +%! outsys = feedback(M, N); +%! [zer, pol, k] = sys2zp(outsys); +%! +%! zer_exp = [ -2.280776406404418 ; +%! -0.219223593595584 ; +%! -9.999999999999996 ]; +%! pol_exp = [ -0.881474800310081 + 0.535367413587643i ; +%! -0.881474800310081 - 0.535367413587643i ; +%! -3.418868581198019 + 0.000000000000000i ]; +%! k_exp = 0.181818181818182; +%! +%!assert(F, F_exp); +%!assert(G, G_exp); +%!assert(H, H_exp); +%!assert(J, J_exp); +%!assert(sys, sysc) +%!assert(zer, zer_exp); +%!assert(pol, pol_exp, 2*eps); +%!assert(k, k_exp, 2*eps); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <par...@us...> - 2009-07-15 13:14:11
|
Revision: 6017 http://octave.svn.sourceforge.net/octave/?rev=6017&view=rev Author: paramaniac Date: 2009-07-15 13:14:09 +0000 (Wed, 15 Jul 2009) Log Message: ----------- feedback: corrected possible bug Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-07-15 12:43:10 UTC (rev 6016) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-07-15 13:14:09 UTC (rev 6017) @@ -222,14 +222,14 @@ ## Extract resulting model for k = 1 : n_out_1 - out_idx(k) = k; + out_pr_idx(k) = k; endfor for k = 1 : n_in_1 - in_idx(k) = k; + in_pr_idx(k) = k; endfor - sys = sysprune(sys, out_idx, in_idx); + sys = sysprune(sys, out_pr_idx, in_pr_idx); endfunction This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <par...@us...> - 2009-07-16 20:40:08
|
Revision: 6019 http://octave.svn.sourceforge.net/octave/?rev=6019&view=rev Author: paramaniac Date: 2009-07-16 20:39:56 +0000 (Thu, 16 Jul 2009) Log Message: ----------- feedback: got some advises from package maintainer Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-07-16 19:34:01 UTC (rev 6018) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-07-16 20:39:56 UTC (rev 6019) @@ -1,4 +1,3 @@ -## Copyright (C) 2000 Ben Sapp <bs...@la...> ## Copyright (C) 2009 Lukas Reichlin <luk...@sw...> ## ## This program is free software: you can redistribute it and/or modify @@ -19,10 +18,8 @@ ## @deftypefnx{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}, @var{sign}) ## @deftypefnx{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}, @var{feedin}, @var{feedout}) ## @deftypefnx{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}, @var{feedin}, @var{feedout}, @var{sign}) -## Returns model sys for the negative feedback interconnection; i. e. filters the output of -## sys1 through sys2 and subtracts it from the input. Occasionally warns about possible -## algebraic loops even if they don't exist. These warnings are perfectly harmless and are -## due to the internal use of sysconnect. +## Return model sys for the negative feedback interconnection; i. e. filter the output of +## sys1 through sys2 and subtract it from the input. ## ## @strong{Inputs} ## @table @var @@ -61,9 +58,8 @@ ## ## @end deftypefn -## Author: Ben Sapp <bs...@la...> -## Rewritten from scratch by Lukas Reichlin -## for better M*tl*b compatibility in July 2009 +## Author: Lukas Reichlin +## Rewritten from scratch for better compatibility in July 2009 ## Version: 0.1 function sys = feedback (varargin) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <par...@us...> - 2009-07-18 01:45:36
|
Revision: 6020 http://octave.svn.sourceforge.net/octave/?rev=6020&view=rev Author: paramaniac Date: 2009-07-18 01:45:21 +0000 (Sat, 18 Jul 2009) Log Message: ----------- feedback: added support for digital gains Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-07-16 20:39:56 UTC (rev 6019) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-07-18 01:45:21 UTC (rev 6020) @@ -71,8 +71,10 @@ ## Determine sys1 from input if (isstruct (varargin{1})) sys1 = varargin{1}; + sys1wasmatrix = 0; elseif (ismatrix (varargin{1})) sys1 = ss ([], [], [], varargin{1}); + sys1wasmatrix = 1; else error ("feedback: argument 1 (sys1) invalid"); endif @@ -80,12 +82,29 @@ ## Determine sys2 from input if (isstruct (varargin{2})) sys2 = varargin{2}; + sys2wasmatrix = 0; elseif (ismatrix (varargin{2})) sys2 = ss ([], [], [], varargin{2}); + sys2wasmatrix = 1; else error ("feedback: argument 2 (sys2) invalid"); endif + ## Handle digital gains + if (sys1wasmatrix) + if (is_digital (sys2, 2)) + t_sam = sysgettsam (sys2); + sys1 = c2d (sys1, t_sam); + endif + endif + + if (sys2wasmatrix) + if (is_digital (sys1, 2)) + t_sam = sysgettsam (sys1); + sys2 = c2d (sys2, t_sam); + endif + endif + ## Determine feedback sign fb_sign = -1; # Default value This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <par...@us...> - 2009-07-18 10:45:39
|
Revision: 6021 http://octave.svn.sourceforge.net/octave/?rev=6021&view=rev Author: paramaniac Date: 2009-07-18 10:45:38 +0000 (Sat, 18 Jul 2009) Log Message: ----------- feedback: cosmetic changes Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-07-18 01:45:21 UTC (rev 6020) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-07-18 10:45:38 UTC (rev 6021) @@ -199,7 +199,7 @@ endif - sys = sysgroup(sys1, sys2); + sys = sysgroup (sys1, sys2); ## Duplicate inputs specified in feedin @@ -272,7 +272,7 @@ in_pr_idx(k) = k; endfor - sys = sysprune(sys, out_pr_idx, in_pr_idx); + sys = sysprune (sys, out_pr_idx, in_pr_idx); endfunction @@ -353,7 +353,6 @@ %! %! sysc = feedback(sys1, eye(2), [1, 2], [1, 2], -1); %! -%! %! M = tf([2, 5, 1], [1, 2, 3]); %! N = zp(-2, -10, 5); %! outsys = feedback(M, N); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sla...@us...> - 2009-08-16 23:43:24
|
Revision: 6100 http://octave.svn.sourceforge.net/octave/?rev=6100&view=rev Author: slackydeb Date: 2009-08-16 23:43:16 +0000 (Sun, 16 Aug 2009) Log Message: ----------- feedback: clean, tweak test tol to run successfully, add TODO/FIXME comments. Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-08-16 23:10:20 UTC (rev 6099) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-08-16 23:43:16 UTC (rev 6100) @@ -18,7 +18,7 @@ ## @deftypefnx{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}, @var{sign}) ## @deftypefnx{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}, @var{feedin}, @var{feedout}) ## @deftypefnx{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}, @var{feedin}, @var{feedout}, @var{sign}) -## Return model sys for the negative feedback interconnection; i. e. filter the output of +## Return model sys for the negative feedback interconnection; i.e. filter the output of ## sys1 through sys2 and subtract it from the input. ## ## @strong{Inputs} @@ -43,31 +43,33 @@ ## @end table ## ## @seealso{sysgroup, sysdup, sysscale, sysconnect, sysprune} -## +## ## @example ## @group ## u + +--------+ y ## ------>(+)----->| sys1 |-------+-------> -## ^ - +--------+ | +## ^ - +--------+ | ## | | ## | +--------+ | ## +-------| sys2 |<------+ -## +--------+ +## +--------+ ## @end group ## @end example ## ## @end deftypefn - + ## Author: Lukas Reichlin ## Rewritten from scratch for better compatibility in July 2009 -## Version: 0.1 - +## Version: 0.1.1 + + # TODO: don't use varargin + function sys = feedback (varargin) - + if (nargin < 2 || nargin > 5) print_usage (); endif - + ## Determine sys1 from input if (isstruct (varargin{1})) sys1 = varargin{1}; @@ -78,7 +80,7 @@ else error ("feedback: argument 1 (sys1) invalid"); endif - + ## Determine sys2 from input if (isstruct (varargin{2})) sys2 = varargin{2}; @@ -89,7 +91,7 @@ else error ("feedback: argument 2 (sys2) invalid"); endif - + ## Handle digital gains if (sys1wasmatrix) if (is_digital (sys2, 2) == 1) # -1 for mixed systems! @@ -97,17 +99,17 @@ sys1 = ss ([], [], [], varargin{1}, t_sam); # sys1 = c2d (sys1, t_sam) doesn't work endif endif - + if (sys2wasmatrix) if (is_digital (sys1, 2) == 1) t_sam = sysgettsam (sys1); sys2 = ss ([], [], [], varargin{2}, t_sam); endif endif - + ## Determine feedback sign fb_sign = -1; # Default value - + if (nargin == 3) if (isreal (varargin{3})) if (varargin{3} == +1) @@ -118,7 +120,7 @@ endif endif endif - + if (nargin == 5) if (isreal (varargin{5})) if (varargin{5} == +1) @@ -129,98 +131,98 @@ endif endif endif - + ## Get system information [n_c_states_1, n_d_states, n_in_1, n_out_1] = sysdimensions (sys1); [n_c_states_2, n_d_states_2, n_in_2, n_out_2] = sysdimensions (sys2); - - + + ## Get connection lists feedin and feedout for k = 1 : n_in_1 feedin(k) = k; # Default value endfor - + for k = 1 : n_out_1 feedout(k) = k; # Default value endfor - + if (nargin == 4 || nargin == 5) if (isvector (varargin{3})) feedin = varargin{3}; else error ("feedback: argument 3 (feedin) invalid"); endif - + if (isvector (varargin{4})) feedin = varargin{4}; else error ("feedback: argument 4 (feedout) invalid"); endif endif - + l_feedin = length (feedin); l_feedout = length (feedout); - + if (l_feedin > n_in_1) error ("feedback: feedin has too many indices"); endif - + if (l_feedin != n_out_2) error ("feedback: number of feedin indices and number of outputs of sys2 incompatible"); endif - + if (l_feedout > n_out_1) error ("feedback: feedout has too many indices"); endif - + if (l_feedout != n_in_2) error ("feedback: number of feedout indices and number of inputs of sys2 incompatible"); endif - - + + ## Group sys1 and sys2 together - + ## Rename inputs, outputs and states of sys2 temporarily - ## to avoid spurious warnings from sysgroup - + ## to avoid spurious warnings from sysgroup + in_name = __sysdefioname__ (n_in_2, "in_feedback_tmp_name"); out_name = __sysdefioname__ (n_out_2, "out_feedback_tmp_name"); - + sys2 = syssetsignals (sys2, "in", in_name); sys2 = syssetsignals (sys2, "out", out_name); - + if ((n_c_states_2 + n_d_states_2) != 0) # If there are any states - + for k = 1 : (n_c_states_2 + n_d_states_2) st_name{k} = sprintf ("st_feedback_tmp_name_%d", k); endfor - + sys2 = syssetsignals (sys2, "st", st_name); - + endif - + sys = sysgroup (sys1, sys2); - - + + ## Duplicate inputs specified in feedin sys = sysdup(sys, [], feedin); - + ## Duplicated inputs start now at number (n_in_1 + n_in_2 + 1) ## and end at number (n_in_1 + n_in_2 + l_feedin) - - + + ## Scale inputs for k = 1 : (n_in_1 + n_in_2) in_scl(k) = 1; endfor - + for k = (n_in_1 + n_in_2 + 1) : (n_in_1 + n_in_2 + l_feedin) in_scl(k) = fb_sign; endfor - + sys = sysscale (sys, [], diag (in_scl)); - - + + ## Connect outputs with inputs ## FIXME: Unable to prevent algebraic loop warnings from sysconnect ## even if connections are made one by one with @@ -231,19 +233,19 @@ ## for k = 1 : l_feedin ## sys = sysconnect (sys, out_idx(k), in_dup_idx(k)); ## endfor - + ## Connect outputs of sys1 to inputs of sys2 ## Output indices of sys1 start at (1) ## and end at (n_out_1) --> use feedout! ## Input indices of sys2 start at (n_in_1 + 1) ## and end at (n_in_1 + n_in_2) - + for k = 1 : l_feedout in_idx(k) = n_in_1 + k; endfor - + sys = sysconnect (sys, feedout, in_idx); - + ## Connect outputs of sys2 to inputs of sys1 ## Output indices of sys 2 start at (n_out_1 + 1) ## and end at (n_out_1 + n_out_2) @@ -255,25 +257,25 @@ for k = 1 : l_feedin out_idx(k) = n_out_1 + k; endfor - + for k = 1 : l_feedin in_dup_idx(k) = n_in_1 + n_in_2 + k; endfor - + sys = sysconnect (sys, out_idx, in_dup_idx); - - + + ## Extract resulting model for k = 1 : n_out_1 out_pr_idx(k) = k; endfor - + for k = 1 : n_in_1 in_pr_idx(k) = k; endfor - + sys = sysprune (sys, out_pr_idx, in_pr_idx); - + endfunction @@ -293,7 +295,7 @@ %! 0 0 0 0 0 0 -7.316 -12.38 30.69 -54.82 0.8061 31.01 ; %! 0 0 0 0 0 0 -30.52 -12.43 0.6207 3.803 -8.658 2.44 ; %! 0 0 0 0 0 0 -0.1735 8.7 -8.958 24.8 -0.3839 -16.77 ]; -%! +%! %! B = [ 0 0 ; %! 0 0 ; %! 0 0 ; @@ -306,15 +308,15 @@ %! 3.002e-06 33.54 ; %! 0.002484 1.146 ; %! 0.0002864 -9.934 ]; -%! +%! %! C = [ 0 0 1 0 0 0 0 0 0 0 0 0 ; %! 0 0 0 1 0 0 0 0 0 0 0 0 ]; -%! +%! %! D = [ 0 0 ; %! 0 0 ]; -%! -%! ## Expected Closed Loop State Space Matrices %! +%! ## Expected Closed Loop State Space Matrices +%! %! F_exp = [ -25 0 0 0 50 0 763 310.7 -27.93 -96.51 216.4 -61 ; %! 0.261 -4 -0.002 0 0 0 0 0 0 0 0 0 ; %! 618 7640 -3.07 0 0 338.4 17.19 -2247 5459 -2782 298.7 2849 ; @@ -327,7 +329,7 @@ %! 0 0 -3.002e-06 -33.54 0 0 -7.316 -12.38 30.69 -54.82 0.8061 31.01 ; %! 0 0 -0.002484 -1.146 0 0 -30.52 -12.43 0.6207 3.803 -8.658 2.44 ; %! 0 0 -0.0002864 9.934 0 0 -0.1735 8.7 -8.958 24.8 -0.3839 -16.77 ]; -%! +%! %! G_exp = [ 0 0 ; %! 0 0 ; %! 0 0 ; @@ -340,17 +342,17 @@ %! 3.002e-06 33.54 ; %! 0.002484 1.146 ; %! 0.0002864 -9.934 ]; -%! +%! %! H_exp = [ 0 0 1 0 0 0 0 0 0 0 0 0 ; %! 0 0 0 1 0 0 0 0 0 0 0 0 ]; -%! +%! %! J_exp = [ 0 0 ; %! 0 0 ]; -%! +%! %! sys1 = ss(A, B, C, D); %! sys = feedback(sys1, eye(2)); %! [F, G, H, J] = sys2ss(sys); -%! +%! %! sysc = feedback(sys1, eye(2), [1, 2], [1, 2], -1); %! %! M = tf([2, 5, 1], [1, 2, 3]); @@ -366,11 +368,8 @@ %! -3.418868581198019 + 0.000000000000000i ]; %! k_exp = 0.181818181818182; %! -%!assert(F, F_exp); -%!assert(G, G_exp); -%!assert(H, H_exp); -%!assert(J, J_exp); +%!assert([F, G; H, J], [F_exp, G_exp; H_exp, J_exp]); %!assert(sys, sysc) -%!assert(zer, zer_exp); -%!assert(pol, pol_exp, 2*eps); +%!assert(zer, zer_exp, 16*eps); # FIXME: why is a so high tol needed? +%!assert(pol, pol_exp, 16*eps); # FIXME: why is a so high tol needed? %!assert(k, k_exp, 2*eps); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sla...@us...> - 2009-08-31 10:45:14
|
Revision: 6177 http://octave.svn.sourceforge.net/octave/?rev=6177&view=rev Author: slackydeb Date: 2009-08-31 10:45:05 +0000 (Mon, 31 Aug 2009) Log Message: ----------- feedback: varargin removal and style fixes. Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 09:40:46 UTC (rev 6176) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 10:45:05 UTC (rev 6177) @@ -19,7 +19,7 @@ ## @deftypefnx{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}, @var{feedin}, @var{feedout}) ## @deftypefnx{Function File} {@var{sys} =} feedback (@var{sys1}, @var{sys2}, @var{feedin}, @var{feedout}, @var{sign}) ## Return model sys for the negative feedback interconnection; i.e. filter the output of -## sys1 through sys2 and subtract it from the input. +## @var{sys1} through @var{sys2} and subtract it from the input. ## ## @strong{Inputs} ## @table @var @@ -32,8 +32,8 @@ ## @item feedout ## Optional vector of output indices for sys1. ## @item sign -## If not specified, default value -1 is taken, resulting in a negative feedback. -## Use +1 for positive feedback. +## @code{-1} means negative feedback (default if not specified), +## @code{+1} means positive one. ## @end table ## ## @strong{Outputs} @@ -60,9 +60,9 @@ ## Author: Lukas Reichlin ## Rewritten from scratch for better compatibility in July 2009 -## Version: 0.2 +## Version: 0.2.1 -function sys = feedback (_sys1, _sys2, varargin) +function sys = feedback (_sys1, _sys2, _sign_or_feedin, _feedout, sign = -1) if (nargin < 2 || nargin > 5) print_usage (); @@ -106,28 +106,14 @@ endif ## Determine feedback sign - fb_sign = -1; # Default value - if (nargin == 3) - if (isreal (varargin{1})) - if (varargin{1} == +1) - fb_sign = +1; - endif - if (varargin{1} != -1 && varargin{1} != +1) - error ("feedback: argument 3 (sign) invalid"); - endif - endif + sign = _sign_or_feedin; endif - if (nargin == 5) - if (isreal (varargin{3})) - if (varargin{3} == +1) - fb_sign = +1; - endif - if (varargin{3} != -1 && varargin{3} != +1) - error ("feedback: argument 5 (sign) invalid"); - endif - endif + ## Sanitize feedback sign + if ((! isreal (sign)) && ((sign != -1) && # "&&" is short-circuit + (sign != +1))) + error ("feedback: sign must be -1 or +1"); endif ## Get system information @@ -148,14 +134,14 @@ endfor if (nargin == 4 || nargin == 5) - if (isvector (varargin{1})) - feedin = varargin{1}; + if (isvector (_sign_or_feedin)) + feedin = _sign_or_feedin; else error ("feedback: argument 3 (feedin) invalid"); endif - if (isvector (varargin{2})) - feedin = varargin{2}; + if (isvector (_feedout)) + feedin = _feedout; else error ("feedback: argument 4 (feedout) invalid"); endif @@ -218,7 +204,7 @@ endfor for k = (n_in_1 + n_in_2 + 1) : (n_in_1 + n_in_2 + l_feedin) - in_scl(k) = fb_sign; + in_scl(k) = sign; endfor sys = sysscale (sys, [], diag (in_scl)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sla...@us...> - 2009-08-31 11:01:53
|
Revision: 6178 http://octave.svn.sourceforge.net/octave/?rev=6178&view=rev Author: slackydeb Date: 2009-08-31 11:01:47 +0000 (Mon, 31 Aug 2009) Log Message: ----------- feedback: remove unuseful for loop. Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 10:45:05 UTC (rev 6177) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 11:01:47 UTC (rev 6178) @@ -60,7 +60,7 @@ ## Author: Lukas Reichlin ## Rewritten from scratch for better compatibility in July 2009 -## Version: 0.2.1 +## Version: 0.2.2 function sys = feedback (_sys1, _sys2, _sign_or_feedin, _feedout, sign = -1) @@ -122,17 +122,9 @@ ## Get connection lists feedin and feedout - feedin = zeros (1, n_in_1); - feedout = zeros (1, n_out_1); + feedin = 1 : n_in_1; # Default value + feedout = 1 : n_out_1; # Default value - for k = 1 : n_in_1 - feedin(k) = k; # Default value - endfor - - for k = 1 : n_out_1 - feedout(k) = k; # Default value - endfor - if (nargin == 4 || nargin == 5) if (isvector (_sign_or_feedin)) feedin = _sign_or_feedin; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sla...@us...> - 2009-08-31 11:18:19
|
Revision: 6179 http://octave.svn.sourceforge.net/octave/?rev=6179&view=rev Author: slackydeb Date: 2009-08-31 11:18:07 +0000 (Mon, 31 Aug 2009) Log Message: ----------- feedback: remove unuseful for loops. Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 11:01:47 UTC (rev 6178) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 11:18:07 UTC (rev 6179) @@ -60,7 +60,7 @@ ## Author: Lukas Reichlin ## Rewritten from scratch for better compatibility in July 2009 -## Version: 0.2.2 +## Version: 0.2.3 function sys = feedback (_sys1, _sys2, _sign_or_feedin, _feedout, sign = -1) @@ -191,14 +191,8 @@ ## Scale inputs - for k = 1 : (n_in_1 + n_in_2) - in_scl(k) = 1; - endfor - - for k = (n_in_1 + n_in_2 + 1) : (n_in_1 + n_in_2 + l_feedin) - in_scl(k) = sign; - endfor - + in_scl(1, 1 : (n_in_1 + n_in_2 + l_feedin)) = \ + [(ones (1, n_in_1 + n_in_2)), (sign * ones (1, l_feedin))]; sys = sysscale (sys, [], diag (in_scl)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sla...@us...> - 2009-08-31 11:21:54
|
Revision: 6180 http://octave.svn.sourceforge.net/octave/?rev=6180&view=rev Author: slackydeb Date: 2009-08-31 11:21:47 +0000 (Mon, 31 Aug 2009) Log Message: ----------- feedback: remove unuseful for loop. Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 11:18:07 UTC (rev 6179) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 11:21:47 UTC (rev 6180) @@ -60,7 +60,7 @@ ## Author: Lukas Reichlin ## Rewritten from scratch for better compatibility in July 2009 -## Version: 0.2.3 +## Version: 0.2.4 function sys = feedback (_sys1, _sys2, _sign_or_feedin, _feedout, sign = -1) @@ -213,10 +213,7 @@ ## Input indices of sys2 start at (n_in_1 + 1) ## and end at (n_in_1 + n_in_2) - for k = 1 : l_feedout - in_idx(k) = n_in_1 + k; - endfor - + in_idx = n_in_1 + (1 : l_feedout); sys = sysconnect (sys, feedout, in_idx); ## Connect outputs of sys2 to inputs of sys1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sla...@us...> - 2009-08-31 11:27:41
|
Revision: 6181 http://octave.svn.sourceforge.net/octave/?rev=6181&view=rev Author: slackydeb Date: 2009-08-31 11:27:33 +0000 (Mon, 31 Aug 2009) Log Message: ----------- feedback: remove unuseful for loops. Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 11:21:47 UTC (rev 6180) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 11:27:33 UTC (rev 6181) @@ -60,7 +60,7 @@ ## Author: Lukas Reichlin ## Rewritten from scratch for better compatibility in July 2009 -## Version: 0.2.4 +## Version: 0.2.5 function sys = feedback (_sys1, _sys2, _sign_or_feedin, _feedout, sign = -1) @@ -224,14 +224,8 @@ ## Sequence of feedin already mapped to duplicated inputs ## ---> (n_in_1 + n_in_2 + k) - for k = 1 : l_feedin - out_idx(k) = n_out_1 + k; - endfor - - for k = 1 : l_feedin - in_dup_idx(k) = n_in_1 + n_in_2 + k; - endfor - + out_idx = n_out_1 + (1 : l_feedin); + in_dup_idx = n_in_1 + n_in_2 + (1 : l_feedin); sys = sysconnect (sys, out_idx, in_dup_idx); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sla...@us...> - 2009-08-31 11:33:08
|
Revision: 6182 http://octave.svn.sourceforge.net/octave/?rev=6182&view=rev Author: slackydeb Date: 2009-08-31 11:33:01 +0000 (Mon, 31 Aug 2009) Log Message: ----------- feedback: remove unuseful for loops. Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 11:27:33 UTC (rev 6181) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 11:33:01 UTC (rev 6182) @@ -60,7 +60,7 @@ ## Author: Lukas Reichlin ## Rewritten from scratch for better compatibility in July 2009 -## Version: 0.2.5 +## Version: 0.2.6 function sys = feedback (_sys1, _sys2, _sign_or_feedin, _feedout, sign = -1) @@ -230,14 +230,8 @@ ## Extract resulting model - for k = 1 : n_out_1 - out_pr_idx(k) = k; - endfor - - for k = 1 : n_in_1 - in_pr_idx(k) = k; - endfor - + out_pr_idx = 1 : n_out_1; + in_pr_idx = 1 : n_in_1; sys = sysprune (sys, out_pr_idx, in_pr_idx); endfunction This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <par...@us...> - 2009-08-31 12:40:06
|
Revision: 6187 http://octave.svn.sourceforge.net/octave/?rev=6187&view=rev Author: paramaniac Date: 2009-08-31 12:40:00 +0000 (Mon, 31 Aug 2009) Log Message: ----------- feedback: simplified complicated expression Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 12:05:09 UTC (rev 6186) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-08-31 12:40:00 UTC (rev 6187) @@ -60,7 +60,7 @@ ## Author: Lukas Reichlin ## Rewritten from scratch for better compatibility in July 2009 -## Version: 0.2.6 +## Version: 0.2.7 function sys = feedback (_sys1, _sys2, _sign_or_feedin, _feedout, sign = -1) @@ -191,8 +191,8 @@ ## Scale inputs - in_scl(1, 1 : (n_in_1 + n_in_2 + l_feedin)) = \ - [(ones (1, n_in_1 + n_in_2)), (sign * ones (1, l_feedin))]; + in_scl = horzcat (ones (1, n_in_1 + n_in_2), sign * ones (1, l_feedin)); + sys = sysscale (sys, [], diag (in_scl)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <par...@us...> - 2009-09-29 13:22:46
|
Revision: 6277 http://octave.svn.sourceforge.net/octave/?rev=6277&view=rev Author: paramaniac Date: 2009-09-29 13:22:38 +0000 (Tue, 29 Sep 2009) Log Message: ----------- feedback: fix bug Modified Paths: -------------- trunk/octave-forge/main/control/inst/feedback.m Modified: trunk/octave-forge/main/control/inst/feedback.m =================================================================== --- trunk/octave-forge/main/control/inst/feedback.m 2009-09-28 20:19:22 UTC (rev 6276) +++ trunk/octave-forge/main/control/inst/feedback.m 2009-09-29 13:22:38 UTC (rev 6277) @@ -60,7 +60,7 @@ ## Author: Lukas Reichlin ## Rewritten from scratch for better compatibility in July 2009 -## Version: 0.2.7 +## Version: 0.2.8 function sys = feedback (_sys1, _sys2, _sign_or_feedin, _feedout, sign = -1) @@ -133,7 +133,7 @@ endif if (isvector (_feedout)) - feedin = _feedout; + feedout = _feedout; else error ("feedback: argument 4 (feedout) invalid"); endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |