reproduction_LQR_finiteHorizon.m 3.57 KB
Newer Older
1
function r = reproduction_LQR_finiteHorizon(DataIn, model, r, currPos, rFactor, Pfinal)
Sylvain Calinon's avatar
Sylvain Calinon committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
% Reproduction with a linear quadratic regulator of finite horizon
%
% Authors: Sylvain Calinon and Danilo Bruno, 2014
%          http://programming-by-demonstration.org/SylvainCalinon
%
% This source code is given for free! In exchange, we would be grateful if you cite  
% the following reference in any academic publication that uses this code or part of it: 
%
% @inproceedings{Calinon14ICRA,
%   author="Calinon, S. and Bruno, D. and Caldwell, D. G.",
%   title="A task-parameterized probabilistic model with minimal intervention control",
%   booktitle="Proc. {IEEE} Intl Conf. on Robotics and Automation ({ICRA})",
%   year="2014",
%   month="May-June",
%   address="Hong Kong, China",
%   pages="3339--3344"
% }

nbData = size(DataIn,2);
nbVarOut = model.nbVar - size(DataIn,1);

%% LQR with cost = sum_t X(t)' Q(t) X(t) + u(t)' R u(t) 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Definition of a double integrator system (DX = A X + B u with X = [x; dx])
A = kron([0 1; 0 0], eye(nbVarOut));
B = kron([0; 1], eye(nbVarOut));
%Initialize Q and R weighting matrices
Q = zeros(nbVarOut*2,nbVarOut*2,nbData);
for t=1:nbData
31
	Q(1:nbVarOut,1:nbVarOut,t) = inv(r.currSigma(:,:,t)); 
Sylvain Calinon's avatar
Sylvain Calinon committed
32 33 34 35
end
R = eye(nbVarOut) * rFactor;

if nargin<6
36 37
	%Pfinal = B*R*[eye(nbVarOut)*model.kP, eye(nbVarOut)*model.kV]
	Pfinal = B*R*[eye(nbVarOut)*0, eye(nbVarOut)*0]; %final feedback terms (boundary conditions)
Sylvain Calinon's avatar
Sylvain Calinon committed
38 39 40
end

%Auxiliary variables to minimize the cost function
41
P = zeros(nbVarOut*2, nbVarOut*2, nbData);
Sylvain Calinon's avatar
Sylvain Calinon committed
42 43 44 45
d = zeros(nbVarOut*2, nbData); %For optional feedforward term computation

%Feedback term
L = zeros(nbVarOut, nbVarOut*2, nbData);
46 47
%Compute P_T from the desired final feedback gains L_T,  
P(:,:,nbData) = Pfinal; 
Sylvain Calinon's avatar
Sylvain Calinon committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

%Compute derivative of target path
%dTar = diff(r.currTar, 1, 2); %For optional feedforward term computation

%Variables for feedforward term computation (optional for movements with low dynamics)
tar = [r.currTar; zeros(nbVarOut,nbData)];
dtar = gradient(tar,1,2)/model.dt;
%tar = [r.currTar; gradient(r.currTar,1,2)/model.dt];
%dtar = gradient(tar,1,2)/model.dt;
%tar = [r.currTar; diff([r.currTar(:,1) r.currTar],1,2)/model.dt];
%dtar = diff([tar tar(:,1)],1,2)/model.dt;


%Backward integration of the Riccati equation and additional equation
for t=nbData-1:-1:1
63 64 65
	P(:,:,t) = P(:,:,t+1) + model.dt * (A'*P(:,:,t+1) + P(:,:,t+1)*A - P(:,:,t+1)*B*(R\B')*P(:,:,t+1) + Q(:,:,t+1));  
	%Optional feedforward term computation
	d(:,t) = d(:,t+1) + model.dt * ((A'-P(:,:,t+1)*B*(R\B'))*d(:,t+1) +  P(:,:,t+1)*dtar(:,t+1) - P(:,:,t+1)*A*tar(:,t+1)); 
Sylvain Calinon's avatar
Sylvain Calinon committed
66
end
67
%Computation of the feedback term L and feedforward term M in u=-LX+M
Sylvain Calinon's avatar
Sylvain Calinon committed
68
for t=1:nbData
69 70
	L(:,:,t) = R\B' * P(:,:,t); 
	M(:,t) = R\B' * d(:,t); %Optional feedforward term computation
Sylvain Calinon's avatar
Sylvain Calinon committed
71 72 73 74 75 76 77
end

%% Reproduction with varying impedance parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
x = currPos;
dx = zeros(nbVarOut,1);
for t=1:nbData
78 79 80 81 82
	%Compute acceleration (with only feedback term)
	%ddx =  -L(:,:,t) * [x-r.currTar(:,t); dx];

	%Compute acceleration (with both feedback and feedforward terms)
	ddx =  -L(:,:,t) * [x-r.currTar(:,t); dx] + M(:,t);
83 84
	r.FB(:,t) = -L(:,:,t) * [x-r.currTar(:,t); dx];
	r.FF(:,t) = M(:,t);
85 86 87 88 89 90 91 92 93

	%Update velocity and position
	dx = dx + ddx * model.dt;
	x = x + dx * model.dt;
	%Log data
	r.Data(:,t) = [DataIn(:,t); x]; 
	r.ddxNorm(t) = norm(ddx);
	r.kpDet(t) = det(L(:,1:nbVarOut,t));
	r.kvDet(t) = det(L(:,nbVarOut+1:end,t));
Sylvain Calinon's avatar
Sylvain Calinon committed
94 95 96 97
end