% This function defines the system dynamics for magnetic control example function [y] = ofbappl_mlsys(t, xi, flag, SysData, fcnflag) global tnext; n = SysData.n; p = SysData.p; % Get the system parameters m = SysData.m; G = SysData.G; ka = SysData.ka; kb = SysData.kb; Ra = SysData.Ra; Rb = SysData.Rb; La = SysData.La; Lb = SysData.Lb; % Get the controller parameters kappa1 = SysData.kappa1; kappa2 = SysData.kappa2; rho = SysData.rho; epsilon = SysData.epsilon; b = SysData.b; Gamma = SysData.Gamma; sigma = SysData.sigma; t_step = SysData.t_step; step = SysData.step; method = SysData.method; % Get the state estimator parameters eps_eta = SysData.eps_eta; L = SysData.L; % Strip out the plant states dxi = zeros(n, 1); % pre-allocate dhat_theta = zeros(p, 1); % pre-allocate hat_theta = xi((n+1):(n+p)); hat_theta = hat_theta(:); hat_x = xi((n+p+1):(n+p+2)); x = xi(1); v = xi(2); ia = xi(3); ib = xi(4); % The gaps ga = G - x; gb = G + x; % Run the state estimator for velocity dv = ka*ia*ia/(2*m*ga*ga) - kb*ib*ib/(2*m*gb*gb); % modeled portion of accel switch method case 'aofb' epsinv = diag([1/eps_eta, 1/eps_eta^2]); dhat_x = [hat_x(2); dv] + epsinv*L*(x - hat_x(1)); v = hat_x(2); % use the saturated estimate in the controller sat = 0.1; % max of 10mm/sec if (v > sat) v = sat; end; if (v < -sat) v = -sat; end; otherwise dhat_x = zeros(2,1); end % The estimated gap velocity dga = -v; dgb = v; % Define the reference trajectory r = step*(2*(sin(2*pi*t/t_step) > 0) - 1); % Define the control input e1 = x - r; de1 = v; dde1 = dv; e2 = v + kappa1*e1; de2 = dv + kappa1*de1; switch method case 'sfb' z = -kappa1*de1 - e1 - kappa1*e2; dz = -kappa1*dde1 - de1 - kappa1*de2; case {'asfb', 'aofb'} range = [-G, G]; sig = (max(range) - min(range))/p; [nn, dF] = rbnn(x, range, sig, hat_theta); z = -kappa1*de1 - e1 - (kappa1 + rho)*e2 + nn/m; dz = -kappa1*dde1 - de1 - (kappa1 + rho)*de2; end etaa = (z + sqrt(z^2 + epsilon))/2 + b; etab = (-z + sqrt(z^2 + epsilon))/2 + b; detaa = (dz - ((z^2 + epsilon)^(-3/2))*z*dz)/2; detab = (-dz - ((z^2 + epsilon)^(-3/2))*z*dz)/2; nu_a = sqrt(2*m*etaa/ka)*ga; nu_b = sqrt(2*m*etab/kb)*gb; e3 = ia - nu_a; e4 = ib - nu_b; qa = -((2*m*etaa/ka)^(-3/2))*m*detaa*ga/ka + sqrt(2*m*etaa/ka)*dga; qb = -((2*m*etab/kb)^(-3/2))*m*detab*gb/kb + sqrt(2*m*etab/kb)*dgb; switch method case {'asfb', 'aofb'} dnuadz = (-(2*m*etaa/ka)^(-3/2)*m*ga/ka)*(1 + 2*sqrt(z*z + epsilon)*z)/2; dnuadth = dnuadz*dF/m; dnuadv = -dnuadz*(2*kappa1 + rho); dnubdz = (-(2*m*etab/kb)^(-3/2)*m*gb/kb)*(1 + 2*sqrt(z*z + epsilon)*z)/2; dnubdth = dnubdz*dF/m; dnubdv = -dnubdz*(2*kappa1 + rho); dhat_theta = -Gamma*(dF*(e2 - e3*dnuadv/m - e4*dnubdv/m) + sigma*hat_theta); qa = qa + dnuadth'*dhat_theta; qb = qb + dnubdth'*dhat_theta; case 'sfb' dhat_theta = zeros(p, 1); end ua = Ra*ia + La*(-e2*(ka*(ia + nu_a)/(2*m*ga*ga)) + qa - kappa2*e3); ub = Rb*ib + Lb*(e2*(kb*(ib + nu_b)/(2*m*gb*gb)) + qb - kappa2*e4); e = [e1; e2; e3; e4]; V = 0.5*e'*e; switch (fcnflag) case 'deriv' % Define the uncertainty Delta = 0.5; % Define the plant dynamics v = xi(2); % use the true rather than estimated value here dxi(1) = v; dxi(2) = ka*ia*ia/(2*m*ga*ga) - kb*ib*ib/(2*m*gb*gb) + Delta/m; dxi(3) = (-Ra*ia + ua)/La; dxi(4) = (-Rb*ib + ub)/Lb; y = [dxi; dhat_theta; dhat_x]; % display the sim time if (t >= tnext) fprintf('t = %f\n', tnext) tnext = tnext + 0.02; end case 'output' y = [x; v; ia; ib; r; e1; e2; V]; end