Code covered by the BSD License  

Highlights from
QCAT

image thumbnail
from QCAT by Ola Harkegard
Quadratic Programming Control Allocation Toolbox

sls_alloc(B,v,umin,umax,Wv,Wu,ud,u,W,imax)
function [u,W,iter] = sls_alloc(B,v,umin,umax,Wv,Wu,ud,u,W,imax)
  
% SLS_ALLOC - Control allocation using sequential least squares.
%
%  [u,W,iter] = sls_alloc(B,v,umin,umax,[Wv,Wu,ud,u0,W0,imax])
%
% Solves the bounded sequential least-squares problem
%
%   min ||Wu(u-ud)||   subj. to   u in M
%
% where M is the set of control signals solving
%
%   min ||Wv(Bu-v)||   subj. to   umin <= u <= umax
%
% using a two stage active set method. To handle the case of coplanar
% controls, pass B+i instead of just B.
%
%  Inputs:
%  -------
% B     control effectiveness matrix (k x m)
% v     commanded virtual control (k x 1)
% umin  lower position limits (m x 1)
% umax  upper position limits (m x 1)
% Wv    virtual control weighting matrix (k x k) [I]
% Wu    control weighting matrix (m x m) [I]
% ud    desired control (m x 1) [0]
% u0    initial point (m x 1) 
% W0    initial working set (m x 1) [empty]
% imax  max no. of iterations [100]
% 
%  Outputs:
%  -------
% u     optimal control
% W     optimal active set
% iter  no. of iterations (= no. of changes in the working set + 1)
%
%                           0 if u_i not saturated
% Active set syntax: W_i = -1 if u_i = umin_i
%                          +1 if u_i = umax_i
%
% See also: MLS_ALLOC, CGI_ALLOC, QP_SIM, ISCOPLANAR.
  
% Numerical tolerance
  tol = 1e-10;
  
  % Check if the coplanar safe version of the algorithm should be
  % used.
  coplanar = ~isreal(B);
  B = real(B);
  
  % k = number of virtual controls
  % m = number of variables (actuators)
  [k,m] = size(B);

  % Set default values of optional arguments
  if nargin < 10
    imax = 100; % Heuristic value
    if nargin < 9, u = (umin+umax)/2; W = zeros(m,1); end
    if nargin < 7,  ud = zeros(m,1); end
    if nargin < 6,  Wu = eye(m);     end
    if nargin < 5,  Wv = eye(k);     end
  end

  % Start with phase one.
  phase = 1;
  % Compute "A"-matrix and initial residual:
  % ||Wv(B(u0+p)-v)|| = ||Ap-d||
  A = Wv*B;
  d = Wv*(v-B*u);
  
  % Iterate until optimum is found or maximum number of iterations
  % is reached.
  for iter = 1:imax
    % ----------------------------------------
    %  Compute optimal perturbation vector p.
    % ----------------------------------------
    
    % Determine indeces of free variables
    i_free = W==0;
    % and number of free variables.
    m_free = sum(i_free);
    
    if phase == 1
      % ---------
      %  Phase 1 
      % ---------
      
      % Eliminate saturated variables.
      A_free = A(:,i_free);
      
      % Solve the reduced optimization problem for free variables. If
      % A_free p_free = d does not have a unique least-squares
      % solution, pick the minimum length solution.
      if coplanar
	% Actuators are allowed to produce coplanar controls. This means
	% that A_free may not be of full rank even if m_free>k.
	p_free = pinv_sol(A_free,d);
      else
	% A_free will allways be of full (row or column) rank. This
	% leads to two different cases:
	if m_free <= k
	  % A_free p_free = d has a unique least-squares solution.
	  p_free = A_free\d;
	else
	  % Pick minimum norm solution to A_free p_free = d.
	  [Q1,R1] = qr(A_free',0);
	  p_free = Q1*(R1'\d);
	end
      end 
	  
      % Insert perturbations from p_free into free the variables.
      p = zeros(m,1);
      p(i_free) = p_free;
      
    else
      % ---------
      %  Phase 2 
      % ---------

      % Determine indeces of fixed variables,
      i_fixed = find(W);
      % and number of fixed variables.
      m_fixed = length(i_fixed);
      % Construct C0 containing the active inequalities.
      C0 = zeros(m_fixed,m);
      for i = 1:m_fixed
	C0(i,i_fixed(i)) = -W(i_fixed(i));
      end
      % Construct E containing all equality constraints. By
      % construction, the rows of E (= the equality constraints) are
      % linearly independent.
      E = [B ; C0];

      % Number of  constraints.
      k_c = k + m_fixed;
      
      % Compute its QR decomposition E' = QR =(Q1 Q2)(R1)
      %                                              ( 0)
      % Note that the computation of lambda also uses this
      % decomposition.
      [Q,R] = qr(E');
      Q1 = Q(:,1:k_c);
      Q2 = Q(:,k_c+1:end);
      R1 = R(1:k_c,:);
      % Optimal solution:      
      q2 = (A*Q2)\d;
      p = Q2*q2;
      
    end 
    % Optimal perturbation p computed.
    
    % --------------------------------
    %  Is the optimal point feasible?
    % --------------------------------
    
    u_opt = u + p;
    if ~any(u_opt(i_free) < umin(i_free) | u_opt(i_free) > umax(i_free))
      
      % ------
      %  Yes.
      % ------
      
      % Update point.
      u = u_opt;
      % Update residual.
      d = d - A*p;
      
      % --------------------------------------------------------
      %  Is the point the optimal solution to the full problem?
      % --------------------------------------------------------
    
      if (~coplanar) & (phase == 1) & (m_free >= k)
	% No planar controls. If u is feasible, then Bu=v must hold,
        % by construction, i.e., one phase 1 optimum found.
	% Move to phase 2.
	phase = 2;
	% Update "A"-matrix and residual.
	A = Wu;
	d = A*(ud-u);
      else
	% Check for optimality by computing the Lagrange multipliers.
	
	% Compute gradient of optimization criterion.
	g = -A'*d; % d = b-Au --> gradient g = A'(Au-b)
	
	% Compute lambda for all bounds (including inactive ones).
	if phase == 1
	  % Only box constraints.
	  lambda = -W.*g;
	else
	  % Box constraints and equality constraints. Use QR decomp.
	  Lambda = R1\(Q1'*g);
	  % Extract multipliers related to bounds.
	  lambda = zeros(m,1);
	  lambda(i_fixed) = Lambda(k+1:end);
	end
	
	if lambda >= -tol
	  % All relevant Lagrange multipliers are positive.
	  if coplanar & (phase == 1)
	    % Although ||Wv(Bu-v)|| is minimal, ||Wu(u-ud)|| may be
            % reduced further in phase 2.
	    phase = 2;
	    % Update "A"-matrix and residual.
	    % ||Wu(u+p-ud)|| = ||Ap-d||
	    A = Wu;
	    d = Wu*(ud-u);
	    % Caveat: Adding the constraint Bp = 0 in phase 2 may
            % cause linear dependence among the active constraints.
	    % Therefore remove the active box constraints causing
            % such linear dependence.
	    %
	    % Not found a way to do this with quickly with
            % precision --> use "brute force" and empty the working
            % set.
	    W = zeros(m,1);
	  else
	    % / ------------------------ \
	    % | Optimum found, bail out. |
	    % \ ------------------------ /
	    return;
	  end
	else
	  
	  % --------------------------------------------------
	  %  Optimum not found, remove one active constraint.
	  % --------------------------------------------------
	  
	  % Remove constraint with most negative lambda from the
	  % working set.
	  [lambda_neg,i_neg] = min(lambda);
	  W(i_neg) = 0;
	end % lambda >= 0
      end	
    else % feasible?
      
      % ------------------------------------------------------------
      %  No (point not feasible), find primary bounding constraint.
      % ------------------------------------------------------------
      
      % Compute distances to the different boundaries. Since alpha < 1
      % is the maximum step length, initiate with ones.
      dist = ones(m,1);
      i_min = i_free & p<-tol; % rather than <0
      i_max = i_free & p>tol;
      
      dist(i_min) = (umin(i_min) - u(i_min)) ./ p(i_min);
      dist(i_max) = (umax(i_max) - u(i_max)) ./ p(i_max);
      
      % Proportion of p to travel.
      [alpha,i_alpha] = min(dist);
      % Update point and residual.
      u = u + alpha*p;
      d = d - A*alpha*p;
      
      % Add corresponding constraint to working set.
      W(i_alpha) = sign(p(i_alpha));
      
    end
    
  end

Contact us at files@mathworks.com