clear all; close all; clc; % Load CasADi import casadi.* %% [Task 2.1]: Modeling the delta robot % Problem constants: g = 9.81; m = 1; J = 1; l = 0.2; L = 0.6; % Symbolic variables: p = SX.sym('p',3); dp = SX.sym('dp',3); alpha = SX.sym('alpha',3); dalpha = SX.sym('dalpha',3); lam = SX.sym('lam',3); u = SX.sym('u',3); % Potential energy: V = m*g*p(3); % Kinetic energy: T = 0.5*m*dp.'*dp; for k = 1:3 T = T + 0.5*J*dalpha(k)^2; end % Set-up of the constraints: gamma = [0 2*pi/3 4*pi/3]; c = SX.zeros(3,1); dist = 2*l; % How far is the motors attachment point from the center for k = 1:3 R{k} = [cos(gamma(k)) sin(gamma(k)) 0 ; -sin(gamma(k)) cos(gamma(k)) 0 ; 0 0 1 ]; p_arm0{k} = R{k}*[ dist; 0; 0 ]; % motors attachment point p_arm{k} = R{k}*[ l*cos(alpha(k)) + dist; 0; -l*sin(alpha(k))]; c(k,1) = ; % ... TODO: write the constraint for robot arm k! end p_armF = Function('p_armF',{alpha},p_arm); q = [p;alpha]; dq = [dp;dalpha]; cFun = Function('cFun',{q},{c}); % The Lagrange function: Lag = ; % ... TODO: complete the Lagrange function to write down the dynamics! Fg = [zeros(3,1); u]; % u are the motor torques % ... TODO: write down the dynamics, based on the Lagrange function! Ldq = ; Lq = ; % jacobian(Ldq,dq)*ddq - Lq.' == Fg % --> ddq = ... ddq = ; % DAE model : [ dot(q) == dq; % dot(dq) == ddq; % 0 == c ] %% [Task 2.2]: Index reduction % Is the above (semi-explicit) DAE of index 1? % If yes, stop. If no, apply index reduction: full(DM(jacobian(c,lam))) % Index reduction: dc = ; % ... TODO: perform time differentiation to c! % Is this new DAE of index 1? full(DM(jacobian(dc,lam))) % Index reduction: ddc = ; % ... TODO: perform time differentiation to dc! % Is this new DAE of index 1? jacobian(ddc,lam) dcFun = Function('dcFun',{[q;dq]},{dc}); dcJ = Function('dcJ',{q},{jacobian(c,q)}); ssEq = [ddq(4:6);ddc]; ssFun = Function('ssFun',{[q;dq;lam],u},{ssEq}); ssJac = Function('ssJac',{[q;dq;lam],u},{jacobian(ssEq,[lam;u])}); %% [Task 2.3]: Find a consistent initial condition q0 = [0;0;-0.5*L;pi/2;pi/2;pi/2]; % Is this value for q consistent with c? cTest = cFun({q0}); cTest = full(cTest{1}) % If not, find a consistent point using Newton's method: while norm(cTest) > 1e-10 jac = dcJ({q0}); jac = full(jac{1}); val = cFun({q0}); cTest = full(val{1}); q0 = ; % ... TODO: complete Newton's method! end dq0 = zeros(6,1); % Are these values for q and dq consistent with c and dc? % Find the corresponding steady-state torques: lam0 = zeros(3,1); u0 = zeros(3,1); ssTest = ssFun({[q0;dq0;lam0],u0}); ssTest = full(ssTest{1}) while norm(ssTest) > 1e-10 jac = ssJac({[q0;dq0;lam0],u0}); jac = full(jac{1}); val = ssFun({[q0;dq0;lam0],u0}); ssTest = full(val{1}); delta = ; % ... TODO: complete Newton's method! lam0 = lam0 + delta(1:3); u0 = u0 + delta(4:6); end %% [Task 2.4]: Use IDAS to simulate the DAE: % ... TODO: define integrator from CasADi! h = 0.1; F = ; % Simulation loop Tf = 20; xs = [q0;dq0]; cs = []; dcs = []; curT = 0; steady_state = 0; while curT < Tf % control inputs to apply if steady_state u_cur = u0; else u_cur = u0.*[1;1+4*sin(pi*curT);1]; end Fout = F(struct('x0',xs(:,end),'p',u_cur)); xs = [xs full(Fout.xf)]; cTest = cFun({xs(1:6,end)}); cs = [cs norm(full(cTest{1}))]; dcTest = dcFun({xs(:,end)}); dcs = [dcs norm(full(dcTest{1}))]; % Visualize figure(1); clf subplot(2,3,[1 2 4 5]); p = xs(1:3,end); p_arm = p_armF({xs(4:6,end)}); for k = 1:3 line([1.5*p_arm0{k}(1) 0],[1.5*p_arm0{k}(2) 0],[1.5*p_arm0{k}(3) 0],'color','k','linestyle','--');hold on line([p_arm0{k}(1) full(p_arm{k}(1))],[p_arm0{k}(2) full(p_arm{k}(2))],[p_arm0{k}(3) full(p_arm{k}(3))],'color','k','linewidth',2);hold on line([p(1) full(p_arm{k}(1))],[p(2) full(p_arm{k}(2))],[p(3) full(p_arm{k}(3))],'color','b','linewidth',1.7);hold on end plot3(p(1),p(2),p(3),'marker','o','markersize',12,'color','r');hold on % axis equal view(50,15) xlabel('x'); ylabel('y'); zlabel('z'); zlim([-0.7 0]) title(['current time: ' num2str(curT) 's']); subplot(2,3,3); semilogy(h.*[1:length(cs)],cs); xlabel('time (s)') ylabel('C') subplot(2,3,6); semilogy(h.*[1:length(cs)],dcs); xlabel('time (s)') ylabel('Cdot') drawnow curT = curT + h; end