%      EventtriggeredSync.M
%
%   Synchronisation of a robot formation with event-triggered control
%
% J. Lunze
% 16.11.2018
% Version of 21.11.2018
% 
close all
clear all




%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   Robot formation problem
%   from DelayDemo.m  of 7.10.2018
%  new robot parameters
%  Vehicle model with velocity and position control loops
m=10;           % m= 10 kg  mass
c=0.2;          %  c=1kg/s friction constant
                % forces in N,  hence input  u=acceleration in N
                % time in seconds
                % distance in m
                % velocity in m/s,   
                %         hence output  v=velocity in m/s
%               PI velocity controller
kI=5;          % kI=5
kP=14;          % kP=10
%               Controlled vehicle
%               input = set-point for velocity controller
%               output = velocity
Ac=[-c/m-kP/m -kI/m; 1 0];
Bc=[kP/m; -1];
Cc=[1 0];
Dc=0;
na=2;            % dynamical order of vehicle with velocity controller
%
%
%  Vehicle with output=position
A=[0 Cc; zeros(na,1) Ac];
B=[0; Bc];
C=[1 zeros(1,na)];
D=0;
nTS=length(A);
Robot=ss(A, B, C, D);
%
Ts=0.3;
Tend=25;
Time=0:Ts:Tend;
kend=length(Time);


%% Design of the feedback gain k
%
figure(1)
rlocprintblue(Robot);
hold on
axis([-1 0.2 -0.6 0.6]);
axis('square');
latextitle('$${\tt EventtriggeredSync:}$$ Root locus of controlled robot');
% kP=rlocfind(vehicle);
kP=0.3;          % feedback gain 0.03
Poles=rlocus(Robot, kP);
plot(real(Poles(1)), imag(Poles(1)), 'kd');
plot(real(Poles(2)), imag(Poles(2)), 'kd');
plot(real(Poles(3)), imag(Poles(3)), 'kd');
yticks([-0.5 0 0.5]);
xticks([-1 -0.5 0]);
hold off

%%  Synchronisation by continuous feedback
%   leader-follower structure
figure(2)
%   coupling matrix
N1=6;
nGS=N1*nTS;
Adj=[0 0 0 0 0 0;
     1 0 0 0 0 0;
     1 1 0 0 0 0;
     0 1 1 0 0 0;
     0 1 0 1 0 0;
     0 0 1 0 1 0];
Asum=sum(Adj');
Asum(1,1)=1;
Ahat=inv(diag(Asum))*Adj;
Lhat=diag(sum(Ahat'))-Ahat;
%   model of the synchronised robots
AGS=kron(eye(N1,N1), A)-kron(Lhat,B*kP*C);
CGS=kron(eye(N1,N1), C);
BGS=eye(N1*nTS,1);       % not used
RobotsCont=ss(AGS, BGS, CGS, 0);
%   different initial positions, initial velocity=0
x0=zeros(nGS,1);
s0(1)=7;
s0(2)=5;
s0(3)=2;
s0(4)=10;
s0(5)=3;
s0(6)=0;
for k1=1:N1
    x0((k1-1)*nTS+1,1)=s0(k1);
end
v0=0;
for k1=1:N1
    x0((k1-1)*nTS+2,1)=v0;
    x0((k1-1)*nTS+3,1)=-Ac(1,1)*v0/Ac(1,2);
end
%   Behaviour of the synchronised robots
[Y,Time,X]=initial(RobotsCont,x0,Time);
subplot(5,1,[1,2]);
for k2=1:N1
    plot(Time, X(:,(k2-1)*nTS+1), 'b');
    hold on
end
xleer;
latexylabel('$$y_i$$ in m');
rotateY;
axis([0 Tend -0.5 10.5]);
yticks([0 5 10]);
latexxlabel('$$t$$ in s');
latextitle('$${\tt EventtriggeredSync:}$$ Robots with continuous controller');
xticks([0 10 20 30 40]),


%%    Event-triggered synchronisation
%
figure(3)
ebar=0.25;
%   discrete-time models
Pi=ss(A, B, C, 0);
Pid=c2d(Pi, Ts);
Ad=Pid.A;
Bd=Pid.B;
%
X=[];
Xs1=[];    % state of the control input generator I_i
Xs2=[];
Xs3=[];
Xs4=[];
Xs5=[];
Xs6=[];
Ys1=[];     % output of the control input generator I_i
Ys2=[];
Ys3=[];
Ys4=[];
Ys5=[];
Ys6=[];
Xhat1=[];   % state estimate used in the event generator E_i
Xhat2=[];
Xhat3=[];
Xhat4=[];
Xhat5=[];
Xhat6=[];
U1=[];      % input to agent i
U2=[];
U3=[];
U4=[];
U5=[];
U6=[];
X(1,:)=x0';
xs0=kron(Ahat,eye(nTS,nTS))*x0;
Xs1(1,:)=xs0(1:3,1);
Xs2(1,:)=xs0(4:6,1);
Xs3(1,:)=xs0(7:9,1);
Xs4(1,:)=xs0(10:12,1);
Xs5(1,:)=xs0(13:15,1);
Xs6(1,:)=xs0(16:18,1);
Ys1(1)=C*Xs1(1,:)';
Ys2(1)=C*Xs2(1,:)';
Ys3(1)=C*Xs3(1,:)';
Ys4(1)=C*Xs4(1,:)';
Ys5(1)=C*Xs5(1,:)';
Ys6(1)=C*Xs6(1,:)';
Xhat1(1,:)=x0(1:3,1);
Xhat2(1,:)=x0(4:6,1);
Xhat3(1,:)=x0(7:9,1);
Xhat4(1,:)=x0(10:12,1);
Xhat5(1,:)=x0(13:15,1);
Xhat6(1,:)=x0(16:18,1);
Eventtime1=zeros(kend,1);
Eventtime2=zeros(kend,1);
Eventtime3=zeros(kend,1);
Eventtime4=zeros(kend,1);
Eventtime5=zeros(kend,1);
Eventtime6=zeros(kend,1);
Eventtime1(1,1)=1;
Eventtime2(1,1)=1;
Eventtime3(1,1)=1;
Eventtime4(1,1)=1;
Eventtime5(1,1)=1;
Eventtime6(1,1)=1;
for k1=2:kend
   %  leader without feedback loop
   %  hence, Xhat1=X1 for all time, no event generated
       U1(k1-1)=0;
       X(k1,1:3)=Ad*X(k1-1,1:3)'+Bd*U1(k1-1);
   %  feedback loop 2
    Test2=max(abs(X(k1-1,4:6)-Xhat2(k1-1,:)));
   if Test2>ebar
         % reset the state of the input generator of neighbouring agents
       Xs3(k1-1,:)=Xs3(k1-1,:)'+Ahat(3,2)*(X(k1-1,4:6)-Xhat2(k1-1,:))';
       Xs4(k1-1,:)=Xs4(k1-1,:)'+Ahat(4,2)*(X(k1-1,4:6)-Xhat2(k1-1,:))';
       Xs5(k1-1,:)=Xs5(k1-1,:)'+Ahat(5,2)*(X(k1-1,4:6)-Xhat2(k1-1,:))';
          % reset the state estimate 
       Xhat2(k1-1,:)=X(k1-1,4:6);
       Eventtime2(k1-1,1)=1;   % event generated by x_2
   end
       Xs2(k1,:)=Ad*Xs2(k1-1,:)';
       Xhat2(k1,:)=Ad*Xhat2(k1-1,:)';
       Ys2(k1-1)=C*Xs2(k1-1,:)';
       U2(k1-1)=-kP*(C*X(k1-1,4:6)'-Ys2(k1-1));
       X(k1,4:6)=Ad*X(k1-1,4:6)'+Bd*U2(k1-1);
   %  feedback loop 3
    Test3=max(abs(X(k1-1,7:9)-Xhat3(k1-1,:)));
   if Test3>ebar
         % reset the state of the input generator of neighbouring agents
       Xs4(k1-1,:)=Xs4(k1-1,:)'+Ahat(4,3)*(X(k1-1,7:9)-Xhat3(k1-1,:))';
       Xs6(k1-1,:)=Xs6(k1-1,:)'+Ahat(6,3)*(X(k1-1,7:9)-Xhat3(k1-1,:))';
          % reset the state estimate 
       Xhat3(k1-1,:)=X(k1-1,7:9);
       Eventtime3(k1-1,1)=1;   % event generated by x_3
   end
       Xs3(k1,:)=Ad*Xs3(k1-1,:)';
       Xhat3(k1,:)=Ad*Xhat3(k1-1,:)';
       Ys3(k1-1)=C*Xs3(k1-1,:)';
       U3(k1-1)=-kP*(C*X(k1-1,7:9)'-Ys3(k1-1));
       X(k1,7:9)=Ad*X(k1-1,7:9)'+Bd*U3(k1-1);
  %  feedback loop 4
    Test4=max(abs(X(k1-1,10:12)-Xhat4(k1-1,:)));
   if Test4>ebar
         % reset the state of the input generator of neighbouring agents
       Xs5(k1-1,:)=Xs5(k1-1,:)'+Ahat(5,4)*(X(k1-1,10:12)-Xhat4(k1-1,:))';
          % reset the state estimate 
       Xhat4(k1-1,:)=X(k1-1,10:12);
       Eventtime4(k1-1,1)=1;   % event generated by x_1
   end
       Xs4(k1,:)=Ad*Xs4(k1-1,:)';
       Xhat4(k1,:)=Ad*Xhat4(k1-1,:)';
       Ys4(k1-1)=C*Xs4(k1-1,:)';
       U4(k1-1)=-kP*(C*X(k1-1,10:12)'-Ys4(k1-1));
       X(k1,10:12)=Ad*X(k1-1,10:12)'+Bd*U4(k1-1);
   %  feedback loop 5
    Test5=max(abs(X(k1-1,13:15)-Xhat5(k1-1,:)));
   if Test5>ebar
         % reset the state of the input generator of neighbouring agents
       Xs6(k1-1,:)=Xs6(k1-1,:)'+Ahat(6,5)*(X(k1-1,13:15)-Xhat5(k1-1,:))';
          % reset the state estimate 
       Xhat5(k1-1,:)=X(k1-1,13:15);
       Eventtime5(k1-1,1)=1;   % event generated by x_5
   end
       Xs5(k1,:)=Ad*Xs5(k1-1,:)';
       Xhat5(k1,:)=Ad*Xhat5(k1-1,:)';
       Ys5(k1-1)=C*Xs5(k1-1,:)';
       U5(k1-1)=-kP*(C*X(k1-1,13:15)'-Ys5(k1-1));
       X(k1,13:15)=Ad*X(k1-1,13:15)'+Bd*U5(k1-1);
   %  feedback loop 6
    Test6=max(abs(X(k1-1,16:18)-Xhat6(k1-1,:)));
   if Test6>ebar
          % reset the state estimate 
       Xhat6(k1-1,:)=X(k1-1,16:18);
       Eventtime6(k1-1,1)=1;   % event generated by x_1
   end
       Xs6(k1,:)=Ad*Xs6(k1-1,:)';
       Xhat6(k1,:)=Ad*Xhat6(k1-1,:)';
       Ys6(k1-1)=C*Xs6(k1-1,:)';
       U6(k1-1)=-kP*(C*X(k1-1,16:18)'-Ys6(k1-1));
       X(k1,16:18)=Ad*X(k1-1,16:18)'+Bd*U6(k1-1);
end
subplot(8,1,[1,2,3])
for k2=1:N1
    plot(Time, X(:,(k2-1)*nTS+1), 'b');
    hold on
end
xleer;
latexylabel('$$y_i$$ in m');
rotateY;
axis([0 Tend -0.5 10.5]);
yticks([0 5 10]);
latextitle('$${\tt EventtriggeredSync:}$$ Robots with event-triggered controller');
% Determination of the remaining synchronisation error
L22tilde=Lhat(2:N1,2:N1)-ones(N1-1,1)*Lhat(1,2:N1);
Ac=kron(eye(N1-1,N1-1),A)-kron(L22tilde, kP*B*C);
A22bar=Ahat(2:N1,1:N1)-ones(N1-1,1)*Ahat(1,1:N1);
Bc=kron(A22bar, kP*B*C);
Cc=kron(eye(N1-1,N1-1), C);
Errormodel=ss(Ac, Bc, Cc, 0);
Ks=dcgain(Errormodel);
emax=ebar*max(sum(abs(Ks')));
plot([Tend-1 Tend Tend Tend-1 Tend-1],...
     [s0(1)-emax s0(1)-emax s0(1)+emax s0(1)+emax s0(1)-emax],'b');
hold off
%
subplot(8,1,[4,5,6])
plot(Time, Xs1(:,1), 'b');
hold on
plot(Time, Xs2(:,1), 'b');
plot(Time, Xs3(:,1), 'b');
plot(Time, Xs4(:,1), 'b');
plot(Time, Xs5(:,1), 'b');
plot(Time, Xs6(:,1), 'b');
xleer;
latexylabel('$$\hat{y}_{{\rm s}i}$$ in m');
rotateY;
axis([0 Tend -0.5 10.5]);
yticks([0 5 10]);
%
subplot(8,1,[7,8])
for k1=1:kend
    if Eventtime1(k1)==1
        plot(k1*Ts, 1, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime2(k1)==1
        plot(k1*Ts, 2, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime3(k1)==1
        plot(k1*Ts, 3, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime4(k1)==1
        plot(k1*Ts, 4, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime5(k1)==1
        plot(k1*Ts, 5, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime6(k1)==1
        plot(k1*Ts, 6, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
axis([0, Tend, 2, 6]);
yticks([2 4 6]);
latexxlabel('$$t$$ in s');
latexylabel('events');
rotateY;
xticks([0 10 20 30 40]),


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%    Event-triggered synchronisation of undamped oscillators
%     oscillator model of SyncDemo.m, figure(4)
figure(4)
A=[0 3; -3 0];
B=[1; 1];
C=[1 10];
kP=0.15;
N1=6;
nTS=2;
Tend=10;
Ts=0.05;
Time=0:Ts:Tend;
kend=length(Time);
%   the same communication structure as in figure(1)
nGS=N1*nTS;
Adj=[0 0 0 0 0 0;
     1 0 0 0 0 0;
     1 1 0 0 0 0;
     0 1 1 0 0 0;
     0 1 0 1 0 0;
     0 0 1 0 1 0];
Asum=sum(Adj');
Asum(1,1)=1;
Ahat=inv(diag(Asum))*Adj;
Lhat=diag(sum(Ahat'))-Ahat;
%   model of the synchronised robots
AGS=kron(eye(N1,N1), A)-kron(Lhat,B*kP*C);
CGS=kron(eye(N1,N1), C);
BGS=kron(Ahat, B*kP*C);       % used to determine the final sync error
OscillatorsCont=ss(AGS, BGS, CGS, 0);
%   different initial phases
%EventtriggeredSync1=rng;                         % save s to restore the generator setting
%save('EventtriggeredSync1', 'EventtriggeredSync1');
load('EventtriggeredSync1');       % Seed (initialisation) of the number generator
rng(EventtriggeredSync1);
x0=2*rand(nGS,1)-1;
%   Behaviour of the synchronised robots
[Y,Time,X]=initial(OscillatorsCont,x0,Time);
subplot(5,1,[1,2]);
for k2=1:N1
    plot(Time, X(:,(k2-1)*nTS+1), 'b');
    hold on
end
xleer;
latexylabel('$$y_i$$');
rotateY;
axis([0 Tend -1.3 1.3]);
yticks([-1 0 1]);
latexxlabel('$$t$$ in s');
latextitle('$${\tt EventtriggeredSync:}$$ Oscillators with continuous controller');
xticks([0 5 10 15]);
hold off


%%    Event-triggered synchronisation of six oscillators
%
figure(5)
ebar=0.1;
%   discrete-time models
Pi=ss(A, B, C, 0);
Pid=c2d(Pi, Ts);
Ad=Pid.A;
Bd=Pid.B;
%
X=[];
Xs1=[];    % state of the control input generator I_i
Xs2=[];
Xs3=[];
Xs4=[];
Xs5=[];
Xs6=[];
Ys1=[];     % output of the control input generator I_i
Ys2=[];
Ys3=[];
Ys4=[];
Ys5=[];
Ys6=[];
Xhat1=[];   % state estimate used in the event generator E_i
Xhat2=[];
Xhat3=[];
Xhat4=[];
Xhat5=[];
Xhat6=[];
U1=[];      % input to agent i
U2=[];
U3=[];
U4=[];
U5=[];
U6=[];
X(1,:)=x0';
xs0=kron(Ahat,eye(nTS,nTS))*x0;
Xs1(1,:)=xs0(1:2,1);
Xs2(1,:)=xs0(3:4,1);
Xs3(1,:)=xs0(5:6,1);
Xs4(1,:)=xs0(7:8,1);
Xs5(1,:)=xs0(9:10,1);
Xs6(1,:)=xs0(11:12,1);
Ys1(1)=C*Xs1(1,:)';
Ys2(1)=C*Xs2(1,:)';
Ys3(1)=C*Xs3(1,:)';
Ys4(1)=C*Xs4(1,:)';
Ys5(1)=C*Xs5(1,:)';
Ys6(1)=C*Xs6(1,:)';
Xhat1(1,:)=x0(1:2,1);
Xhat2(1,:)=x0(3:4,1);
Xhat3(1,:)=x0(5:6,1);
Xhat4(1,:)=x0(7:8,1);
Xhat5(1,:)=x0(9:10,1);
Xhat6(1,:)=x0(11:12,1);
Eventtime1=zeros(kend,1);
Eventtime2=zeros(kend,1);
Eventtime3=zeros(kend,1);
Eventtime4=zeros(kend,1);
Eventtime5=zeros(kend,1);
Eventtime6=zeros(kend,1);
Eventtime1(1,1)=1;
Eventtime2(1,1)=1;
Eventtime3(1,1)=1;
Eventtime4(1,1)=1;
Eventtime5(1,1)=1;
Eventtime6(1,1)=1;
for k1=2:kend
   %  leader without feedback loop
   %  hence, Xhat1=X1 for all time, no event generated
       U1(k1-1)=0;
       X(k1,1:2)=Ad*X(k1-1,1:2)'+Bd*U1(k1-1);
   %  feedback loop 2
    Test2=max(abs(X(k1-1,3:4)-Xhat2(k1-1,:)));
   if Test2>ebar
         % reset the state of the input generator of neighbouring agents
       Xs3(k1-1,:)=Xs3(k1-1,:)'+Ahat(3,2)*(X(k1-1,3:4)-Xhat2(k1-1,:))';
       Xs4(k1-1,:)=Xs4(k1-1,:)'+Ahat(4,2)*(X(k1-1,3:4)-Xhat2(k1-1,:))';
       Xs5(k1-1,:)=Xs5(k1-1,:)'+Ahat(5,2)*(X(k1-1,3:4)-Xhat2(k1-1,:))';
          % reset the state estimate 
       Xhat2(k1-1,:)=X(k1-1,3:4);
       Eventtime2(k1-1,1)=1;   % event generated by x_2
   end
       Xs2(k1,:)=Ad*Xs2(k1-1,:)';
       Xhat2(k1,:)=Ad*Xhat2(k1-1,:)';
       Ys2(k1-1)=C*Xs2(k1-1,:)';
       U2(k1-1)=-kP*(C*X(k1-1,3:4)'-Ys2(k1-1));
       X(k1,3:4)=Ad*X(k1-1,3:4)'+Bd*U2(k1-1);
   %  feedback loop 3
    Test3=max(abs(X(k1-1,5:6)-Xhat3(k1-1,:)));
   if Test3>ebar
         % reset the state of the input generator of neighbouring agents
       Xs4(k1-1,:)=Xs4(k1-1,:)'+Ahat(4,3)*(X(k1-1,5:6)-Xhat3(k1-1,:))';
       Xs6(k1-1,:)=Xs6(k1-1,:)'+Ahat(6,3)*(X(k1-1,5:6)-Xhat3(k1-1,:))';
          % reset the state estimate 
       Xhat3(k1-1,:)=X(k1-1,5:6);
       Eventtime3(k1-1,1)=1;   % event generated by x_3
   end
       Xs3(k1,:)=Ad*Xs3(k1-1,:)';
       Xhat3(k1,:)=Ad*Xhat3(k1-1,:)';
       Ys3(k1-1)=C*Xs3(k1-1,:)';
       U3(k1-1)=-kP*(C*X(k1-1,5:6)'-Ys3(k1-1));
       X(k1,5:6)=Ad*X(k1-1,5:6)'+Bd*U3(k1-1);
  %  feedback loop 4
    Test4=max(abs(X(k1-1,7:8)-Xhat4(k1-1,:)));
   if Test4>ebar
         % reset the state of the input generator of neighbouring agents
       Xs5(k1-1,:)=Xs5(k1-1,:)'+Ahat(5,4)*(X(k1-1,7:8)-Xhat4(k1-1,:))';
          % reset the state estimate 
       Xhat4(k1-1,:)=X(k1-1,7:8);
       Eventtime4(k1-1,1)=1;   % event generated by x_1
   end
       Xs4(k1,:)=Ad*Xs4(k1-1,:)';
       Xhat4(k1,:)=Ad*Xhat4(k1-1,:)';
       Ys4(k1-1)=C*Xs4(k1-1,:)';
       U4(k1-1)=-kP*(C*X(k1-1,7:8)'-Ys4(k1-1));
       X(k1,7:8)=Ad*X(k1-1,7:8)'+Bd*U4(k1-1);
   %  feedback loop 5
    Test5=max(abs(X(k1-1,9:10)-Xhat5(k1-1,:)));
   if Test5>ebar
         % reset the state of the input generator of neighbouring agents
       Xs6(k1-1,:)=Xs6(k1-1,:)'+Ahat(6,5)*(X(k1-1,9:10)-Xhat5(k1-1,:))';
          % reset the state estimate 
       Xhat5(k1-1,:)=X(k1-1,9:10);
       Eventtime5(k1-1,1)=1;   % event generated by x_5
   end
       Xs5(k1,:)=Ad*Xs5(k1-1,:)';
       Xhat5(k1,:)=Ad*Xhat5(k1-1,:)';
       Ys5(k1-1)=C*Xs5(k1-1,:)';
       U5(k1-1)=-kP*(C*X(k1-1,9:10)'-Ys5(k1-1));
       X(k1,9:10)=Ad*X(k1-1,9:10)'+Bd*U5(k1-1);
   %  feedback loop 6
    Test6=max(abs(X(k1-1,11:12)-Xhat6(k1-1,:)));
   if Test6>ebar
          % reset the state estimate 
       Xhat6(k1-1,:)=X(k1-1,11:12);
       Eventtime6(k1-1,1)=1;   % event generated by x_1
   end
       Xs6(k1,:)=Ad*Xs6(k1-1,:)';
       Xhat6(k1,:)=Ad*Xhat6(k1-1,:)';
       Ys6(k1-1)=C*Xs6(k1-1,:)';
       U6(k1-1)=-kP*(C*X(k1-1,11:12)'-Ys6(k1-1));
       X(k1,11:12)=Ad*X(k1-1,11:12)'+Bd*U6(k1-1);
end
subplot(8,1,[1,2,3])
for k2=1:N1
    plot(Time, X(:,(k2-1)*nTS+1), 'b');
    hold on
end
xleer;
latexylabel('$$y_i$$ in m');
rotateY;
axis([0 Tend -1.2 1.2]);
yticks([-1 0 1]);
latextitle('$${\tt EventtriggeredSync:}$$ Oscillators with event-triggered controller');
%
subplot(8,1,[4,5,6])
plot(Time, Xs1(:,1), 'b');
hold on
plot(Time, Xs2(:,1), 'b');
plot(Time, Xs3(:,1), 'b');
plot(Time, Xs4(:,1), 'b');
plot(Time, Xs5(:,1), 'b');
plot(Time, Xs6(:,1), 'b');
xleer;
latexylabel('$$\hat{y}_{{\rm s}i}$$ in m');
rotateY;
axis([0 Tend -1.2 1.2]);
yticks([-1 0 1]);
%
subplot(8,1,[7,8])
for k1=1:kend
    if Eventtime1(k1)==1
        plot(k1*Ts, 1, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime2(k1)==1
        plot(k1*Ts, 2, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime3(k1)==1
        plot(k1*Ts, 3, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime4(k1)==1
        plot(k1*Ts, 4, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime5(k1)==1
        plot(k1*Ts, 5, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime6(k1)==1
        plot(k1*Ts, 6, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
axis([0, Tend, 2, 6]);
yticks([2 4 6]);
latexxlabel('$$t$$ in s');
latexylabel('events');
rotateY;
xticks([0 5 10 15]);


%%    Event-triggered synchronisation of six oscillators
%     the same as in figure(4) with path-graph
figure(6)
Tend=15;
Time=0:Ts:Tend;
kend=length(Time);
%   communication graph
Adj=[0 0 0 0 0 0;
     1 0 0 0 0 0;
     0 1 0 0 0 0;
     0 0 1 0 0 0;
     0 0 0 1 0 0;
     0 0 0 0 1 0];
Asum=sum(Adj');
Asum(1,1)=1;
Ahat=inv(diag(Asum))*Adj;
Lhat=diag(sum(Ahat'))-Ahat;
%
X=[];
Xs1=[];    % state of the control input generator I_i
Xs2=[];
Xs3=[];
Xs4=[];
Xs5=[];
Xs6=[];
Ys1=[];     % output of the control input generator I_i
Ys2=[];
Ys3=[];
Ys4=[];
Ys5=[];
Ys6=[];
Xhat1=[];   % state estimate used in the event generator E_i
Xhat2=[];
Xhat3=[];
Xhat4=[];
Xhat5=[];
Xhat6=[];
U1=[];      % input to agent i
U2=[];
U3=[];
U4=[];
U5=[];
U6=[];
X(1,:)=x0';
xs0=kron(Ahat,eye(nTS,nTS))*x0;
Xs1(1,:)=xs0(1:2,1);
Xs2(1,:)=xs0(3:4,1);
Xs3(1,:)=xs0(5:6,1);
Xs4(1,:)=xs0(7:8,1);
Xs5(1,:)=xs0(9:10,1);
Xs6(1,:)=xs0(11:12,1);
Ys1(1)=C*Xs1(1,:)';
Ys2(1)=C*Xs2(1,:)';
Ys3(1)=C*Xs3(1,:)';
Ys4(1)=C*Xs4(1,:)';
Ys5(1)=C*Xs5(1,:)';
Ys6(1)=C*Xs6(1,:)';
Xhat1(1,:)=x0(1:2,1);
Xhat2(1,:)=x0(3:4,1);
Xhat3(1,:)=x0(5:6,1);
Xhat4(1,:)=x0(7:8,1);
Xhat5(1,:)=x0(9:10,1);
Xhat6(1,:)=x0(11:12,1);
Eventtime1=zeros(kend,1);
Eventtime2=zeros(kend,1);
Eventtime3=zeros(kend,1);
Eventtime4=zeros(kend,1);
Eventtime5=zeros(kend,1);
Eventtime6=zeros(kend,1);
for k1=2:kend
   %  leader without feedback loop
   %  hence, Xhat1=X1 for all time, no event generated
       U1(k1-1)=0;
       X(k1,1:2)=Ad*X(k1-1,1:2)'+Bd*U1(k1-1);
   %  feedback loop 2
    Test2=max(abs(X(k1-1,3:4)-Xhat2(k1-1,:)));
   if Test2>ebar
         % reset the state of the input generator of neighbouring agents
       Xs3(k1-1,:)=Xs3(k1-1,:)'+Ahat(3,2)*(X(k1-1,3:4)-Xhat2(k1-1,:))';
          % reset the state estimate 
       Xhat2(k1-1,:)=X(k1-1,3:4);
       Eventtime2(k1-1,1)=1;   % event generated by x_2
   end
       Xs2(k1,:)=Ad*Xs2(k1-1,:)';
       Xhat2(k1,:)=Ad*Xhat2(k1-1,:)';
       Ys2(k1-1)=C*Xs2(k1-1,:)';
       U2(k1-1)=-kP*(C*X(k1-1,3:4)'-Ys2(k1-1));
       X(k1,3:4)=Ad*X(k1-1,3:4)'+Bd*U2(k1-1);
   %  feedback loop 3
    Test3=max(abs(X(k1-1,5:6)-Xhat3(k1-1,:)));
   if Test3>ebar
         % reset the state of the input generator of neighbouring agents
       Xs4(k1-1,:)=Xs4(k1-1,:)'+Ahat(4,3)*(X(k1-1,5:6)-Xhat3(k1-1,:))';
          % reset the state estimate 
       Xhat3(k1-1,:)=X(k1-1,5:6);
       Eventtime3(k1-1,1)=1;   % event generated by x_3
   end
       Xs3(k1,:)=Ad*Xs3(k1-1,:)';
       Xhat3(k1,:)=Ad*Xhat3(k1-1,:)';
       Ys3(k1-1)=C*Xs3(k1-1,:)';
       U3(k1-1)=-kP*(C*X(k1-1,5:6)'-Ys3(k1-1));
       X(k1,5:6)=Ad*X(k1-1,5:6)'+Bd*U3(k1-1);
  %  feedback loop 4
    Test4=max(abs(X(k1-1,7:8)-Xhat4(k1-1,:)));
   if Test4>ebar
         % reset the state of the input generator of neighbouring agents
       Xs5(k1-1,:)=Xs5(k1-1,:)'+Ahat(5,4)*(X(k1-1,7:8)-Xhat4(k1-1,:))';
          % reset the state estimate 
       Xhat4(k1-1,:)=X(k1-1,7:8);
       Eventtime4(k1-1,1)=1;   % event generated by x_1
   end
       Xs4(k1,:)=Ad*Xs4(k1-1,:)';
       Xhat4(k1,:)=Ad*Xhat4(k1-1,:)';
       Ys4(k1-1)=C*Xs4(k1-1,:)';
       U4(k1-1)=-kP*(C*X(k1-1,7:8)'-Ys4(k1-1));
       X(k1,7:8)=Ad*X(k1-1,7:8)'+Bd*U4(k1-1);
   %  feedback loop 5
    Test5=max(abs(X(k1-1,9:10)-Xhat5(k1-1,:)));
   if Test5>ebar
         % reset the state of the input generator of neighbouring agents
       Xs6(k1-1,:)=Xs6(k1-1,:)'+Ahat(6,5)*(X(k1-1,9:10)-Xhat5(k1-1,:))';
          % reset the state estimate 
       Xhat5(k1-1,:)=X(k1-1,9:10);
       Eventtime5(k1-1,1)=1;   % event generated by x_5
   end
       Xs5(k1,:)=Ad*Xs5(k1-1,:)';
       Xhat5(k1,:)=Ad*Xhat5(k1-1,:)';
       Ys5(k1-1)=C*Xs5(k1-1,:)';
       U5(k1-1)=-kP*(C*X(k1-1,9:10)'-Ys5(k1-1));
       X(k1,9:10)=Ad*X(k1-1,9:10)'+Bd*U5(k1-1);
   %  feedback loop 6
    Test6=max(abs(X(k1-1,11:12)-Xhat6(k1-1,:)));
   if Test6>ebar
          % reset the state estimate 
       Xhat6(k1-1,:)=X(k1-1,11:12);
       Eventtime6(k1-1,1)=1;   % event generated by x_1
   end
       Xs6(k1,:)=Ad*Xs6(k1-1,:)';
       Xhat6(k1,:)=Ad*Xhat6(k1-1,:)';
       Ys6(k1-1)=C*Xs6(k1-1,:)';
       U6(k1-1)=-kP*(C*X(k1-1,11:12)'-Ys6(k1-1));
       X(k1,11:12)=Ad*X(k1-1,11:12)'+Bd*U6(k1-1);
end
subplot(8,1,[1,2,3])
for k2=1:N1
    plot(Time, X(:,(k2-1)*nTS+1), 'b');
    hold on
end
xleer;
latexylabel('$$y_i$$ in m');
rotateY;
axis([0 Tend -1.6 1.6]);
yticks([-1 0 1]);
latextitle('$${\tt EventtriggeredSync:}$$ Oscillators with event-triggered controller');
%
subplot(8,1,[4,5,6])
plot(Time, Xs1(:,1), 'b');
hold on
plot(Time, Xs2(:,1), 'b');
plot(Time, Xs3(:,1), 'b');
plot(Time, Xs4(:,1), 'b');
plot(Time, Xs5(:,1), 'b');
plot(Time, Xs6(:,1), 'b');
xleer;
latexylabel('$$\hat{y}_{{\rm s}i}$$ in m');
rotateY;
axis([0 Tend -1.6 1.6]);
yticks([-1 0 1]);
%
subplot(8,1,[7,8])
for k1=1:kend
    if Eventtime1(k1)==1
        plot(k1*Ts, 1, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime2(k1)==1
        plot(k1*Ts, 2, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime3(k1)==1
        plot(k1*Ts, 3, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime4(k1)==1
        plot(k1*Ts, 4, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime5(k1)==1
        plot(k1*Ts, 5, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
for k1=1:kend
    if Eventtime6(k1)==1
        plot(k1*Ts, 6, 'bo',...
            'MarkerEdgeColor','b',...
            'MarkerFaceColor','b');
        hold on
%        plot([k1*Ts k1*Ts],[1 0],'b');
    end
end
axis([0, Tend, 2, 6]);
yticks([2 4 6]);
latexxlabel('$$t$$ in s');
latexylabel('events');
rotateY;
xticks([0 5 10 15]);

%%   Figures
epsfigc15('EventtriggeredSync');

