Mercurial > hg > octave-nkf
view scripts/control/base/lqg.m @ 7962:0665d457fabb
Added tag ss-3-1-51 for changeset a5d1e27ee1f4
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 22 Jul 2008 11:41:09 -0400 |
parents | 4a375de63f66 |
children |
line wrap: on
line source
## Copyright (C) 1996, 1997, 2000, 2002, 2004, 2005, 2006, 2007 ## Auburn University. All rights reserved. ## ## 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 3 of the License, 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, see ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{k}, @var{q1}, @var{p1}, @var{ee}, @var{er}] =} lqg (@var{sys}, @var{sigw}, @var{sigv}, @var{q}, @var{r}, @var{in_idx}) ## Design a linear-quadratic-gaussian optimal controller for the system ## @example ## dx/dt = A x + B u + G w [w]=N(0,[Sigw 0 ]) ## y = C x + v [v] ( 0 Sigv ]) ## @end example ## or ## @example ## x(k+1) = A x(k) + B u(k) + G w(k) [w]=N(0,[Sigw 0 ]) ## y(k) = C x(k) + v(k) [v] ( 0 Sigv ]) ## @end example ## ## @strong{Inputs} ## @table @var ## @item sys ## system data structure ## @item sigw ## @itemx sigv ## intensities of independent Gaussian noise processes (as above) ## @item q ## @itemx r ## state, control weighting respectively. Control @acronym{ARE} is ## @item in_idx ## names or indices of controlled inputs (see @command{sysidx}, @command{cellidx}) ## ## default: last dim(R) inputs are assumed to be controlled inputs, all ## others are assumed to be noise inputs. ## @end table ## @strong{Outputs} ## @table @var ## @item k ## system data structure format @acronym{LQG} optimal controller (Obtain A, B, C ## matrices with @command{sys2ss}, @command{sys2tf}, or @command{sys2zp} as ## appropriate). ## @item p1 ## Solution of control (state feedback) algebraic Riccati equation. ## @item q1 ## Solution of estimation algebraic Riccati equation. ## @item ee ## Estimator poles. ## @item es ## Controller poles. ## @end table ## @seealso{h2syn, lqe, lqr} ## @end deftypefn ## Author: A. S. Hodel <a.s.hodel@eng.auburn.edu> ## Created: August 1995 ## revised for new system format August 1996 function [K, Q1, P1, Ee, Er] = lqg (sys, Sigw, Sigv, Q, R, input_list) if (nargin < 5 || nargin > 6) print_usage (); elseif (! isstruct (sys)) error ("sys must be in system data structure"); endif DIG = is_digital (sys); [A, B, C, D, tsam, n, nz, stname, inname, outname] = sys2ss (sys); [n, nz, nin, nout] = sysdimensions (sys); if (nargin == 5) ## construct default input_list input_list = (columns(Sigw)+1):nin; endif if (! (n+nz)) error("lqg: 0 states in system"); elseif (nin != columns (Sigw) + columns (R)) error ("lqg: sys has %d inputs, dim(Sigw)=%d, dim(u)=%d", nin, columns (Sigw), columns (R)); elseif (nout != columns (Sigv)) error ("lqg: sys has %d outputs, dim(Sigv)=%d", nout, columns (Sigv)); endif ## check for names of signals if (is_signal_list (input_list) || ischar (input_list)) input_list = sysidx (sys, "in", input_list); endif if (length (input_list) != columns (R)) error ("lqg: length(input_list)=%d, columns(R)=%d", length (input_list), columns (R)); endif if (! issquare (Sigw)) error ("lqg: Sigw is not square"); endif if (! issquare (Sigv)) error ("lqg: Sigv is not square"); endif if (! issquare (Q)) error ("lqg: Q is not square"); endif if (! issquare (R)) error ("lqg: Q is not square"); endif ## permute (if need be) if (nargin == 6) all_inputs = sysreorder (nin, input_list); B = B(:,all_inputs); inname = inname (all_inputs); endif ## put parameters into correct variables m1 = columns (Sigw); m2 = m1+1; G = B(:,1:m1); B = B(:,m2:nin); ## now we can just do the design; call dlqr and dlqe, since all matrices ## are not given in Cholesky factor form (as in h2syn case) if (DIG) [Ks, P1, Er] = dlqr (A, B, Q, R); [Ke, Q1, jnk, Ee] = dlqe (A, G, C, Sigw, Sigv); else [Ks, P1, Er] = lqr (A, B, Q, R); [Ke, Q1, Ee] = lqe (A, G, C, Sigw, Sigv); endif Ac = A - Ke*C - B*Ks; Bc = Ke; Cc = -Ks; Dc = zeros (rows (Cc), columns (Bc)); ## fix state names stname1 = strappend (stname, "_e"); ## fix controller output names outname1 = strappend (inname(m2:nin), "_K"); ## fix controller input names inname1 = strappend (outname, "_K"); if (DIG) K = ss (Ac, Bc, Cc, Dc, tsam, n, nz, stname1, inname1, outname1, 1:rows(Cc)); else K = ss (Ac, Bc, Cc, Dc, tsam, n, nz, stname, inname1, outname1); endif endfunction