% This function defines the system dynamics for "sfbindir_ex5"

function [y] = sfbindir_ex5sys(t, x, flag, SysData, fcnflag)
global tnext;

kappa = SysData.kappa;
eta = SysData.eta;
Gamma = SysData.Gamma;
sigma = SysData.sigma;
theta = SysData.theta;

% Strip out the states
x1 = x(1); x2 = x(2);
hat_theta = x(3);
dx = zeros(3, 1);     % pre-allocate

% the current approximation
switch (SysData.update)
case 'adapt'
  Isys = -hat_theta*x(1)*x(1);
otherwise
  Isys = 0;
  hat_theta = 0;
end

% Define the error system
e1 = x(1);
v1 = -(kappa+eta)*e1 + Isys;
e2 = x(2) - v1;

% Define the control law
z21 = (kappa+eta) + 2*hat_theta*x1;
nu2 = eta*(1 + z21*z21);
D2 = x1*x1;
q1 = -x1*x1;
q2 = -z21*x1*x1;
m21 = x1*x1*Gamma*q1;
m22 = x1*x1*Gamma*q2;
tau2 = -(m21*e1 + m22*e2) + sigma*D2*Gamma*hat_theta;

switch (SysData.update)
case 'adapt'
  u = -(kappa+nu2)*e2 - e1 - (kappa+eta+2*hat_theta*x1)*(x2 - Isys) + tau2;
otherwise
  u = -(kappa+nu2)*e2 - e1 - (kappa+eta)*x2;
end

% define the update law
switch (SysData.update)
case 'adapt'
  dth = -Gamma*(q1*e1 + q2*e2 + sigma*hat_theta);
otherwise
  dth = 0;
end

% Define the derivative
switch (fcnflag)
case 'deriv'
  dx(1) = theta*x1*x1 + x2;
  dx(2) = u;
  dx(3) = dth;
  y = dx;

case 'output'  
  y = [x(1); x(2); x(3)];
end

