2024-07-23 18:07:50 +02:00
|
|
|
function u = control_act(t, q)
|
2024-07-16 10:58:00 +02:00
|
|
|
global ref dref K b SATURATION PREDICTION_SATURATION_TOLERANCE USE_PREDICTION PREDICTION_STEPS
|
2024-07-12 19:14:53 +02:00
|
|
|
|
|
|
|
ref_s = double(subs(ref, t));
|
|
|
|
dref_s = double(subs(dref, t));
|
|
|
|
|
|
|
|
|
2024-07-23 18:07:50 +02:00
|
|
|
err = ref_s - feedback(q);
|
2024-07-16 10:58:00 +02:00
|
|
|
u_track = dref_s + K*err;
|
2024-07-12 19:14:53 +02:00
|
|
|
|
2024-07-23 18:07:50 +02:00
|
|
|
theta = q(3);
|
2024-07-12 19:14:53 +02:00
|
|
|
|
|
|
|
T_inv = [cos(theta), sin(theta); -sin(theta)/b, cos(theta)/b];
|
2024-07-16 10:58:00 +02:00
|
|
|
|
|
|
|
u = zeros(2,1);
|
|
|
|
if USE_PREDICTION==true
|
|
|
|
% 1-step prediction
|
|
|
|
|
|
|
|
% quadprog solves the problem in the form
|
|
|
|
% min 1/2 x'Hx +f'x
|
|
|
|
% where x is u_corr. Since u_corr is (v_corr; w_corr), and I want
|
2024-07-23 18:07:50 +02:00
|
|
|
% to minimize u'u (norm squared of u_corr itself) H must be
|
2024-07-16 10:58:00 +02:00
|
|
|
% the identity matrix of size 2
|
|
|
|
H = eye(2)*2;
|
|
|
|
% no linear of constant terms, so
|
|
|
|
f = [];
|
|
|
|
|
|
|
|
% and there are box constraints on the saturation, as upper/lower
|
|
|
|
% bounds
|
|
|
|
%T = inv(T_inv);
|
|
|
|
%lb = -T*saturation - u_track;
|
|
|
|
%ub = T*saturation - u_track;
|
|
|
|
% matlab says this is a more efficient way of doing
|
|
|
|
% inv(T_inv)*saturation
|
|
|
|
%lb = -T_inv\saturation - u_track;
|
|
|
|
%ub = T_inv\saturation - u_track;
|
|
|
|
|
|
|
|
% Resolve box constraints as two inequalities
|
|
|
|
A_deq = [T_inv; -T_inv];
|
|
|
|
d = T_inv*u_track;
|
|
|
|
b_deq = [SATURATION - ones(2,1)*PREDICTION_SATURATION_TOLERANCE - d;
|
|
|
|
SATURATION - ones(2,1)*PREDICTION_SATURATION_TOLERANCE + d];
|
|
|
|
|
|
|
|
% solve the problem
|
|
|
|
% no <= constraints
|
|
|
|
% no equality constraints
|
|
|
|
% only upper/lower bound constraints
|
|
|
|
options = optimoptions('quadprog', 'Display', 'off');
|
|
|
|
u_corr = quadprog(H, f, A_deq, b_deq, [],[],[],[],[],options);
|
|
|
|
|
|
|
|
u = T_inv * (u_track + u_corr);
|
2024-07-12 19:14:53 +02:00
|
|
|
|
2024-07-16 10:58:00 +02:00
|
|
|
global tu uu
|
|
|
|
tu = [tu, t];
|
|
|
|
uu = [uu, u_corr];
|
|
|
|
else
|
|
|
|
u = T_inv * u_track;
|
|
|
|
end
|
2024-07-12 19:14:53 +02:00
|
|
|
|
|
|
|
% saturation
|
2024-07-16 10:58:00 +02:00
|
|
|
u = min(SATURATION, max(-SATURATION, u));
|
2024-07-12 19:14:53 +02:00
|
|
|
end
|
|
|
|
|
2024-07-23 18:07:50 +02:00
|
|
|
function q_track = feedback(q)
|
2024-07-12 19:14:53 +02:00
|
|
|
global b
|
2024-07-23 18:07:50 +02:00
|
|
|
q_track = [ q(1) + b*cos(q(3)); q(2) + b*sin(q(3)) ];
|
2024-07-12 19:14:53 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|