Você está na página 1de 22

UNIVERSIDADE FEDERAL RURAL DO SEMI-ARIDO – UFERSA

CENTRO DE TECNOLOGIA E SOCIAIS – CAMPUS CARAÚBAS


GRADUAÇÃO EM ENGENHARIA ELETRICA
CONTROLE ANALÓGICO

PRATICA AVANÇADA 1 – CONTROLE ANALÓGICO – INTRODUÇÃO AS LMIS


Nome:
Matricula: Professor: Marcus Vinícius Costa

Nessa pratica o aluno será capaz de:


• Projetar um controlador otimizado por desigualdades matriciais lineares (LMIs)
TEORIA ENVOLVIDA

Exemplo 1 – Exemplo de estabilidade de Lyapunov via LMIs

Uma desigualdade matricial linear é definida pela seguinte expressão


𝐹(𝑥) = 𝑥1 𝐹1 + 𝑥2 𝐹2 + ⋯ + 𝑥𝑚 𝐹𝑚 ≤ 𝐹0 (1)
ou
𝑚

𝐹(𝑥) = ∑ 𝑥𝑖 𝐹𝑖 − 𝐹0 ≤ 0 (2)
𝑖=1
sendo 𝑥 ∈ ℝ𝑝 e 𝐹(𝑥) é uma função Afim, em que 𝐹𝑖 ∈ ℝ𝑝×𝑞 , 𝑖 = 0, … , 𝑚 são matrizes simétricas
semi-definidas positivas com restrição convexa em (2). Considere o sistema linear no tempo contínuo
modelado no espaço de estados definida pela seguinte equação
𝑥̇ = 𝐴𝑥 (3)

o qual deseja-se encontrar a matriz 𝑃 = 𝑃 > 0 baseada na equação quadrática de Lyapunov
𝑉(𝑥) = 𝑥 ′ 𝑃𝑥 > 0 (4)
O qual garante-se a estabilidade assintótica de (4) na seguinte condição
𝑉̇ (𝑥) ≤ 0 ⇒ 𝑉̇ (𝑥) = 𝑥 ′ (𝐴′ 𝑃 + 𝑃𝐴)𝑥 ≤ 0 (5)
Logo
𝐴′ 𝑃 + 𝑃𝐴 ≤ 0 (6)
O processo de solução da matriz 𝑃 ≥ 0 e (6) se dá por um processo de restrição linear. Para o processo
de obtenção do conjunto solução temos:
− As variáveis de decisão: que são os elementos da matriz 𝑃, que devem ser semi-definidas
positivas;
− As restrições do sistema: que consistem no conjunto de inequações que existem no
procedimento de otimização;
− Função objetivo: que é a condição de minimização aceitável que garante a convergência da
solução.
Com base nas informações dadas anteriormente, tem-se que o processo de função objetivo de (6)
pode ser o traço da matriz 𝑃. Neste caso o processo de otimização é determinado na seguinte
maneira:
 min Tr  P ,
 P = P '0
 sujeito (7)

 A ' P + PA  0
O script a seguir mostra o exemplo de estabilidade de Lyapunov na busca da solução da matriz P
com base no processo de otimização de (7). O exemplo considera o seguinte modelo:
0 1 
x ( t ) = Ax ( t )  A =   (8)
0 −10 

close all, clear all, clc


A=[0 1;0 -10]; %matriz A
% Declarando as variáveis semidefinidas positivas (sdp)
m=size(A,1); % tamanho da matriz A
P=sdpvar(m,m); %declarando a matriz simétrica
% Processo de otimização
LMIs=[P>=0,A'*P+P*A<=0];
% Condições de otimização
ops=sdpsettings;
ops.solver='sedumi'; %solver sedumi
ops.tol=1e-5; % tolerancia
ops.verbose=0;
% verbose 0 - Oculta as iterações no codigo
% verbose 1 - Mostra as iterações no código
% verbose 2 - Mostra as iterações do codigo com cor
chamativa

% Uso do Solver
solvesdp(LMIs,trace(P),ops)
P=value(P); %valor numerico de P

Para projeto de controladores LMIs usando Pyhton, pode-se usar o Google Colab pelo seguinte
comando:
pip install control
pip install cvxpy
Portanto, considerando o exemplo Python usando o Google Colab
#Importando bibliotecas
from numpy import * # Traz todas as funções NumPy
from matplotlib.pyplot import * # Traz todas as funções de plotti
n MATLAB
from control.matlab import * # Funções como se fosse MATLAB
import control
from scipy import linalg
from numpy.linalg import matrix_rank
from numpy.linalg import inv
import numpy as np
import matplotlib.pyplot as plt
import random
import cvxpy as cp # Traz todas as funções de otimiz
ação convexa

A=zeros((2,2)); #inicializando matriz 2x2


A[0,1]=-1; A[1,1]=-10;
A=matrix(A); #convertendo em matriz

#Declarando as variáveis semidefinidas positivas


[n,m]=A.shape; #tamanho da matriz
P = cp.Variable((n,n), symmetric=True); #declarando a matriz P

# operando as restrições
constraints = [P >> 1e-5*eye(n)] # 1e-
5*eye(n) é tolerância p/convergência
constraints += [A @ P + P @ A.T << 0]
obj = cp.trace(P);
prob = cp.Problem(cp.Minimize(obj), constraints)
prob.solve(solver=cp.SCS, verbose=True);

# Print result.
Ps=P.value
[Es, Vs]=linalg.eig(Ps);
print("The optimal value is", prob.value)
print("Solution P is")
print(Ps)

print("The eigenvalues are", prob.value)


print(Es)

Exemplo 2 – Exemplo de estabilidade de Lyapunov via LMIs no modelo de malha fechada

Considere agora o mesmo modelo no exemplo 1 considerando o seguinte fato


0 1  0
x ( t ) = Ax ( t ) + Bu ( t )  A =   ; B = 1 
0 −10   (9)
u ( t ) = − Kx ( t ) .
Deseja estabelecer um ganho de realimentação de estados em K. Utilizando a realimentação de
estados tem-se que
x ( t ) = ( A − BK ) x ( t ) = Ac x (t ) (10)
Aplicando (10) na desigualdade de Lyapunov em (6), tem-se que
( A − BK ) ' P + P ( A − BK )  0 (11)
Fazendo algumas modificações matriciais em (11), e P = Q−1 , Q = Q '  0 , observa-se que
( A − BK ) ' Q−1 + Q−1 ( A − BK )  0 (12)
Multiplicando Q à direita e à esquerda de (12), tem-se que
Q ( A − BK ) '+ ( A − BK ) Q  0 (13)
Logo
( AQ − BKQ ) '+ ( AQ − BKQ )  0 (14)
Fazendo Y = KQ  K = YQ−1 , de (14), obtém-se
( AQ − BY ) '+ ( AQ − BY )  0 (15)
Onde (15) é a estabilização de Lyapunov de malha fechada por realimentação de estados. Portanto,
o processo de restrição para este caso é dado por
 Q = Q '  0, sujeito a
 (16)
( AQ − BY ) '+ ( AQ − BY )  0

O qual (16) não requer função objetivo, portanto este será vazio no código. O script a seguir, mostra
o modelo de estabilização com base no exemplo e mostra os autovalores de malha fechada.
close all, clear all, clc
A=[0 1;0 -10]; %matriz A
B=[0 1]'; %matriz B
% Declarando as variáveis semidefinidas positivas (sdp)
[m,n]=size(B); % tamanho da matriz A
Q=sdpvar(m,m); %declarando a matriz simétrica
Y=sdpvar(n,m); %declarando a matriz Y
% Processo de restrição
LMIs=[Q>=0,(A*Q-B*Y)'+(A*Q-B*Y)<=0];
% Condições de otimização
ops=sdpsettings;
ops.solver='sedumi'; %solver sedumi
ops.tol=1e-5; % tolerancia
ops.verbose=0;
% verbose 0 - Oculta as iterações no codigo
% verbose 1 - Mostra as iterações no código
% verbose 2 - Mostra as iterações do codigo com cor
chamativa

% Uso do Solver
solvesdp(LMIs,[],ops)
Q=value(Q); %valor numerico de Q
Y=value(Y); %valor numerico de Y
K=Y*inv(Q);

E=eig(A-B*K),
O qual E = −0,4375  j1,0489 respectivamente.

Para o exemplo em Python, é necessário impor o critério de minimização (16).



 min tr ( Q ) , sujeito a
Q = Q ' 0
 (17)
( AQ − BY ) '+ ( AQ − BY )  0

O script do código em Pyhton para o exemplo é dado a seguir:
#Importando bibliotecas
from numpy import * # Traz todas as funções
NumPy
from matplotlib.pyplot import * # Traz todas as funções
de plottin MATLAB
from control.matlab import * # Funções como se fosse
MATLAB
import control
from scipy import linalg
from numpy.linalg import matrix_rank
from numpy.linalg import inv
import numpy as np
import matplotlib.pyplot as plt
import random
import cvxpy as cp # Traz todas as funções
de otimização convexa

A=zeros((2,2)); #inicializando matriz 2x2


A[0,1]=-1; A[1,1]=-10; A=matrix(A); #convertendo em
matriz

B=zeros((2,1)); B[1,0]=1; B=matrix(B);

#Declarando as variáveis positivas


[n,m]=B.shape; #tamanho da matriz
Q = cp.Variable((n,n), symmetric=True); #declarando a
matriz Q simétrica
Y = cp.Variable((m,n)); #declarando a matriz Y

# operando as restrições
constraints = [Q >= 0]
constraints += [
(A @ Q - B @ Y + Q @ A.T - Y.T @ B.T ) << 0
]

obj = cp.trace(Q);
prob = cp.Problem(cp.Minimize(obj),
constraints)
prob.solve(solver=cp.SCS, verbose=True);

# Print result.
Qs=Q.value; Qs=matrix(Qs);
Ys=Y.value; Ys=matrix(Ys);
K = -Ys*inv(Qs)
[Es,Vs]=linalg.eig(A-B*K)
print("The optimal value is", prob.value)
print("Solution Q is")
print(Qs)
print("Solution Y is")
print(Ys)
print("Gain K is")
print(K)
print("The Eigenvalues are")
print(Es)
Os autovalores associados ao modelo de malha fechada são dados por −1,58266676 ± j13,06890836

Exemplo 3 – Exemplo de estabilidade de Lyapunov via LMIs alinhado a um ponto de operação

Os exemplos anteriores, o conceito de estabilidade de Lyapunov considerou-se a estabilização em


uma desigualdade menor que zero. Neste exemplo, é mostrada ainda que o conceito de estabilização
de Lyapunov pode ser aplicado para qualquer ponto de estabilização desejado. Considere (6) alinhado
à uma matriz arbitrária N. Portanto, tem-se que:

A ' P + PA  − N  A ' P + PA + N  0 (18)


Onde (18), a estabilização de Lyapunov está limitada a uma estabilização arbitrária em N. Para uma
condição alternativa, tem-se que
( AQ) '+ AQ  − M  ( AQ) '+ AQ + M  0 (19)
−1
onde Q = Q ' = P  0 e M = QNQ , que se mantém arbitrário. Para o modelo de malha fechada, (19)
torna-se
( AQ − BY ) '+ ( AQ − BY ) + M  0 (20)
Onde K = YQ−1 e M é uma matriz arbitrária. Alinhando-se M = −2h1Q , observa-se que o plano
complexo se organizará para valores reais menores que −2h1 ,onde h1 é a condição real máxima
admissível na reorganização dos polos de malha fechada. Caso M = 2h2Q , o polos de malha fechada
são alinhados de modo a serem limitadas à uma condição mínima, cujos valores reais admitirão o
valor real a partir de h2 . Este conceito é conhecido como D-Estabilidade, que consiste na alocação
dos polos de malha fechada dentro de uma região arbitrária limitada em um processo de otimização.
O exemplo a seguir mostra a alocação dos polos de malha fechada a uma região entre h1 = −3 e
h2 = −8 de modo que haja as seguintes restrições

 Q = Q '  0, sujeito a

−2h1 + ( AQ − BY ) '+ ( AQ − BY )  0 (21)
2h − AQ − BY '+ AQ − BY  0
 2 (( ) ( ))
Os valores de projeto consideram o modelo da planta do exemplo 2
close all, clear all, clc
A=[0 1;0 -10]; %matriz A
B=[0 1]'; %matriz B
h1=-3;
h2=-8;
% Declarando as variáveis semidefinidas positivas (sdp)
[m,n]=size(B); % tamanho da matriz A
Q=sdpvar(m,m); %declarando a matriz simétrica
Y=sdpvar(n,m); %declarando a matriz Y
% Processo de restrição
LMIs=[Q>=0,-2*h1*Q+(A*Q-B*Y)'+(A*Q-B*Y)<=0, 2*h2*Q-
((A*Q-B*Y)'+(A*Q-B*Y))<=0];
% Condições de otimização
ops=sdpsettings;
ops.solver='sedumi'; %solver sedumi
ops.tol=1e-5; % tolerancia
ops.verbose=0;
% verbose 0 - Oculta as iterações no codigo
% verbose 1 - Mostra as iterações no código
% verbose 2 - Mostra as iterações do codigo com cor
chamativa

% Uso do Solver
solvesdp(LMIs,[],ops)
Q=value(Q); %valor numerico de Q
Y=value(Y); %valor numerico de Y
K=Y*inv(Q);

E=eig(A-B*K),
Sendo E = −3,9213  j3,2096 respectivamente. Usando Python, os script é dado por
#Importando bibliotecas
from numpy import * # Traz todas as funções NumPy
from matplotlib.pyplot import * # Traz todas as funções de plotti
n MATLAB
from control.matlab import * # Funções como se fosse MATLAB
import control
from scipy import linalg
from numpy.linalg import matrix_rank
from numpy.linalg import inv
import numpy as np
import matplotlib.pyplot as plt
import random
import cvxpy as cp # Traz todas as funções de otimiz
ação convexa

A=zeros((2,2)); #inicializando matriz 2x2


A[0,1]=-1; A[1,1]=-10; A=matrix(A); #convertendo em matriz

B=zeros((2,1)); B[1,0]=1; B=matrix(B);

# Limites de operação por D-Estabilidade


h1=-3; h1=matrix(h1);
h2=-8; h2=matrix(h2);
#Declarando as variáveis positivas
[n,m]=B.shape; #tamanho da matriz
Q = cp.Variable((n,n), symmetric=True); #declarando a matriz Q Si
metrica
Y = cp.Variable((m,n)); #declarando a matriz Y

# operando as restrições
constraints = [Q >> 1e-6*eye(n)] #Procedimento de convergência
constraints += [ -
2*h1@Q + (A @ Q - B @ Y + Q @ A.T - Y.T @ B.T ) << 0 ]
constraints += [ 2*h2@Q - (A @ Q - B @ Y + Q @ A.T - Y.T @ B.T )
<< 0 ]

obj = cp.trace(Q);
prob = cp.Problem(cp.Minimize(obj), constraints)
prob.solve(solver=cp.SCS, verbose=True); # SCS Solver - Splitting
Conic Sol.
#prob.solve(solver=cp.CVXOPT, verbose=True); # CVXOPT Solver - CV
X Optimization.
#prob.solve(); # Resolução padrão

# Print result.
Qs=Q.value; Qs=matrix(Qs);
Ys=Y.value; Ys=matrix(Ys);
K = Ys*inv(Qs)
[Es,Vs]=linalg.eig(A-B*K)

print("The optimal value is", prob.value)


print("Solution Q is")
print(Qs)
print("Solution Y is")
print(Ys)
print("Gain K is")
print(K)
print("The Eigenvalues are")
print(Es)
Cujos autovalores associados de malha fechada são dados por −3,34781597 ± j3,14311048j
usando o SCS como solver e −4,0113979 ± 𝑗2,98720656 usando o CVXOPT como solver. Já o
procedimento de convergência permite que o solver alcance os resultados dentro das condições de D-
Estabilidade dentro do contexto lógico da factibilidade.
Os demais critérios de D-Estabilidade são:
− Disco centrado em (q, 0) e raio r:
 −rQ qQ + ( AQ − BY )
 0 (22)
 qQ + ( AQ − BY ) ' −rQ 

− Setor cônico com vértice na origem e ângulo interno de 2


 T 1sen −T 2 cos  
T cos  T sen   0 (23)
 2 1 
Onde em (23)
T1 = ( AQ − BY )'+ ( AQ − BY ) (24)
T2 = ( AQ − BY )'− ( AQ − BY ) (25)
O script a seguir mostra a aplicação do exemplo 2 utilizando a seção cônica e o disco centrado em (-
2,0) , raio 10 e limitado com polo mínimo em h1 = −3 .
close all, clear all, clc
A=[0 1;0 -10]; %matriz A
B=[0 1]'; %matriz B
% Condições de D-Estabilidade
h1=-3;
q=0;
raio=10;
% Declarando as variáveis semidefinidas positivas (sdp)
[m,n]=size(B); % tamanho da matriz A
Q=sdpvar(m,m); %declarando a matriz simétrica
Y=sdpvar(n,m); %declarando a matriz Y
% Processo de restrição
LMIs=[Q>=0];
DiscoCentrado=[[-raio*Q q*Q+(A*Q-B*Y);q*Q+(A*Q-B*Y)' -
raio*Q]<=0];
LMIs=[LMIs, DiscoCentrado];
LMIs=[LMIs, -2*h1*Q+(A*Q-B*Y)'+(A*Q-B*Y)<=0];
% Condições de otimização
ops=sdpsettings;
ops.solver='sedumi'; %solver sedumi
ops.tol=1e-5; % tolerancia
ops.verbose=1;
% verbose 0 - Oculta as iterações no codigo
% verbose 1 - Mostra as iterações no código
% verbose 2 - Mostra as iterações do codigo com cor
chamativa

% Uso do Solver
solvesdp(LMIs,[],ops)
Q=value(Q); %valor numerico de Q
Y=value(Y); %valor numerico de Y
K=Y*inv(Q);

E=eig(A-B*K),
Sendo E = −4,2500  j3,1370 respectivamente e raio absoluto de 5,29, ou seja, dentro das condições
de D-estabilidade. O script a seguir mostra a mesma implementação usando Python.
#Importando bibliotecas
from numpy import * # Traz todas as funções NumPy
from matplotlib.pyplot import * # Traz todas as funções de plotti
n MATLAB
from control.matlab import * # Funções como se fosse MATLAB
import control
from scipy import linalg
from numpy.linalg import matrix_rank
from numpy.linalg import inv
import numpy as np
import matplotlib.pyplot as plt
import random
import cvxpy as cp # Traz todas as funções de otimiz
ação convexa

A=zeros((2,2)); #inicializando matriz 2x2


A[0,1]=-1; A[1,1]=-10; A=matrix(A); #convertendo em matriz

B=zeros((2,1)); B[1,0]=1; B=matrix(B);

# Condições de D-Estabilidade
h1=-3; h1=matrix(h1);
q=0; q=matrix(q);
raio=10; raio=matrix(raio);

#Declarando as variáveis positivas


[n,m]=B.shape; #tamanho da matriz
Q = cp.Variable((n,n), symmetric=True); #declarando a matriz Q Si
metrica
Y = cp.Variable((m,n)); #declarando a matriz Y

# operando as restrições
constraints = [Q >> 1e-6*eye(n)]
constraints += [cp.bmat([[-raio@Q, q@Q+(A@Q-B@Y)],
[q@Q+(Q@A.T-Y.T@B.T), -raio@Q]]) << 0]
constraints += [ -2*h1@Q + (A@Q - B@Y + Q@A.T - Y.T@B.T ) <<0 ]

obj = cp.trace(Q);
prob = cp.Problem(cp.Minimize(obj), #função objetivo é minimizar
Q
constraints)
prob.solve(solver=cp.SCS, verbose=True);
#prob.solve(solver=cp.CVXOPT, verbose=True);

# Print result.
Qs=Q.value; Qs=matrix(Qs);
Ys=Y.value; Ys=matrix(Ys);
K = Ys*inv(Qs)
[Es,Vs]=linalg.eig(A-B*K)
Rd = abs(Es)

print("The optimal value is", prob.value)


print("Solution Q is")
print(Qs)
print("Solution Y is")
print(Ys)
print("Gain K is")
print(K)
print("The Eigenvalues are")
print(Es)
print("The Radius are")
print(Rd)

Usando o SCS como solver −3, 58163442 ± 𝑗3,10832826 e raio 4.74234222 . Já usando o
CVXOPT, os autovalores são −4,90517488 ± 𝑗2,51303464 com raio 5,51145023.

O script subsequente realiza a D-estabilidade para o setor cônico considerando h1 = −2 e o


ângulo de  = 60º .
close all, clear all, clc
A=[0 1;0 -10]; %matriz A
B=[0 1]'; %matriz B
% Condições de D-Estabilidade
h1=-2;
teta=pi-(pi/3); % th= 60º
% Declarando as variáveis semidefinidas positivas (sdp)
[m,n]=size(B); % tamanho da matriz A
Q=sdpvar(m,m); %declarando a matriz simétrica
Y=sdpvar(n,m); %declarando a matriz Y
% Processo de restrição
LMIs=[Q>=0];
T1=(A*Q-B*Y)'+(A*Q-B*Y);
T2=(A*Q-B*Y)'-(A*Q-B*Y);

SetorConico=[[sin(teta)*T1 -cos(teta)*T2; cos(teta)*T2


sin(teta)*T1]<=0];
LMIs=[LMIs, SetorConico];
LMIs=[LMIs, -2*h1*Q+(A*Q-B*Y)'+(A*Q-B*Y)<=0];

% Condições de otimização
ops=sdpsettings;
ops.solver='sedumi'; %solver sedumi
ops.tol=1e-5; % tolerancia
ops.verbose=1;
% verbose 0 - Oculta as iterações no codigo
% verbose 1 - Mostra as iterações no código
% verbose 2 - Mostra as iterações do codigo com cor
chamativa

% Uso do Solver
solvesdp(LMIs,[],ops)
Q=value(Q); %valor numerico de Q
Y=value(Y); %valor numerico de Y
K=Y*inv(Q);
E=eig(A-B*K),
Sendo E = −4,7406  j0,5157 respectivamente e raio absoluto de 4,76, ou seja, e ângulo de 6,2º,
comprovando a alocação por D-estabilidade. Em Pyhton, a mesma representação é dada pelo seguinte
código:
#Importando bibliotecas
from numpy import * # Traz todas as funções NumPy
from matplotlib.pyplot import * # Traz todas as funções de plotti
n MATLAB
from control.matlab import * # Funções como se fosse MATLAB
import control
from scipy import linalg
from numpy.linalg import matrix_rank
from numpy.linalg import inv
import numpy as np
import matplotlib.pyplot as plt
import random
import cvxpy as cp # Traz todas as funções de otimiz
ação convexa

A=zeros((2,2)); #inicializando matriz 2x2


A[0,1]=-1; A[1,1]=-10; A=matrix(A); #convertendo em matriz

B=zeros((2,1)); B[1,0]=1; B=matrix(B);

# Condições de D-Estabilidade
h1=-2; h1=matrix(h1);
teta=pi - (pi/3); teta=matrix(teta); # th= 60º

#Declarando as variáveis positivas


[n,m]=B.shape; #tamanho da matriz
Q = cp.Variable((n,n), symmetric=True); #declarando a matriz Q Si
metrica
Y = cp.Variable((m,n)); #declarando a matriz Y

#Restrições conicas
T1=(A@Q-B@Y).T+(A@Q-B@Y);
T2=(A@Q-B@Y).T-(A@Q-B@Y);

# operando as restrições
constraints = [Q >> 1e-6*eye(n)]
constraints += [cp.bmat([[sin(teta)@T1, -cos(teta)@T2],
[cos(teta)@T2, sin(teta)@T1]]) << 0]
constraints += [-2*h1@Q + ((A@Q - B@Y) + (A@Q - B@Y).T) <<0 ]

obj = cp.trace(Q);
prob = cp.Problem(cp.Minimize(obj), #função objetivo é minimizar
Q
constraints)
#prob.solve(solver=cp.SCS, verbose=True);
prob.solve(solver=cp.CVXOPT, verbose=True);

# Print result.
Qs=Q.value; Qs=matrix(Qs);
Ys=Y.value; Ys=matrix(Ys);
K = Ys*inv(Qs)
[Es,Vs]=linalg.eig(A-B*K)
Rd = abs(Es)
Ang=angle(Es)

print("The optimal value is", prob.value)


print("Solution Q is")
print(Qs)
print("Solution Y is")
print(Ys)
print("Gain K is")
print(K)
print("The Eigenvalues are")
print(Es)
print("The Radius are")
print(Rd)
print("The Angles is")
print((180/pi)*(pi - Ang[0]))
Os autovalores associados usando o solver CVXOPT, o raio e o ângulo são dados respectivamente
por −2,00035508, −1,93069239 × 105 , os raios são iguais aos autovalores e o ângulo é de zero
graus. Usando o SCS, os autovalores são −2,89196365 ± 𝑗2.05046402, com raio de 3.54511727
e ângulo de 35°.

Exemplo 4 – Complemento de Schur

O complemento de Schur consiste em uma estratégia algébrica por transformação de congruência que
converte uma expressão matricial quadrática com matrizes inversas em uma matriz linear. Os
principais tipos de conversão por complemento de Schur utilizado nesta prática são:
 M M2 
M = M1 − M 2 M 3−1M 2 ' =  1  = M \ M3 (26)
M 2 ' M 3 
e
 M M2 
M = M 3 − M 2 M1−1M 2 ' =  1  = M \ M1 (27)
 M 2 ' M 3 

A notação em (26) é conhecida como complemento de Schur em de M em M3, pois M3 é a matriz


invertível na expressão. Já a expressão em (27) é conhecida como complemento de Schur de M em
M1, já que M1 é invertível. Estas expressões apenas são válidas para condições em que as matrizes
impostas sejam plenamente invertíveis, ou seja, definidas positivas. Para entender melhor o conceito,
seja a inequação de Riccati para obtenção do ganho LQR definido por:
A ' P + PA − ( PB) Rc −1 ( PB)'+ Qc  0 (28)
e
Kc = Rc −1B ' P (29)
Onde em (28), Qc = Qc '  0 e Rc = Rc '  0 são matrizes de ponderação e (29) é a expressão do ganho
de realimentação de estados. Reorganizando (28), tem-se que

A ' P + PA + Qc − ( PB) Rc −1 ( PB) '  0  A ' P + PA + Qc − ( PB) Rc −1 ( PB) '  0


(30)
M1 M2 M3 M2 '

Aplicando Schur de M\M3 em (30), obtém-se


 A ' P + PA + Qc PB 
 0
Rc 
(31)
 ( PB) '
O resultado em (31) consiste na formulação equivalente da inequação de Riccati utilizando Schur.
Contudo, esta formulação não é muito eficiente para uso em LMI, pois tende à infactibilidade e sua
solução diverge comparado ao método clássico existente em literatura. O conceito do LQR via LMIs
podem ser visto nas mais diversas formas, uma delas é a seguinte:
( A − BK ) ' P + P ( A − BK ) + K ' Rc K + Qc  0 (32)
Fazendo P = Q−1 , Q = Q '  0 e, em seguida multiplicando por Q à direita e à esquerda de (32), tem -
se que
( AQ − BKQ ) '+ ( AQ − BKQ ) + ( KQ ) ' Rc ( KQ ) + QQcQ  0 (33)
Fazendo Y = KQ e considerando as matrizes de ponderação totalmente invertíveis, multiplicando
(33) por -1 e aplicando Schur de (33) em Y ' RcY , tem-se que
 − ( AQ − BY ) '− ( AQ − BY ) − QQcQ Y ' 
 −1 
0 (34)
 Y Rc 
Aplicando Schur em (34) referente ao primeiro elemento da matriz em (34), a matriz é reorganizada
de modo que
 − ( AQ − BY ) '− ( AQ − BY ) Q Y' 
 
 Q Qc −1 0   0 (35)
 Y 0 Rc 
−1

que consiste na formulação da equação de Riccati na forma de LMIs. Portanto o processo de restrição
para a minimização e obtenção do modelo de solução é dado por
min − Tr Q
Q =Q ',Y

 − ( AQ − BY ) '− ( AQ − BY ) Q Y' 
  (36)
−1
 Q Qc 0 0
 Y 0 Rc −1 
Sendo K = YQ−1 . O script a seguir mostra a aplicação do processo de restrição de (36) no exemplo 2,
considera-se Q c = 100I 2 e Rc = 1
close all, clear all, clc
A=[0 1;0 -10]; %matriz A
B=[0 1]'; %matriz B
% Matrizes de Ponderação
Qc=100*eye(2);
Rc=1;
% Declarando as variáveis semidefinidas positivas (sdp)
[m,n]=size(B); % tamanho da matriz A
Q=sdpvar(m,m); %declarando a matriz simétrica
Y=sdpvar(n,m); %declarando a matriz

% Processo de restrição
LMIs=[Q>=0];
Riccati=[[-(A*Q-B*Y)-(A*Q-B*Y)' Q Y';
Q inv(Qc) zeros(m,n);
Y zeros(n,m) inv(Rc) ] >= 0];

LMIs=[LMIs, Riccati];

% Condições de otimização
ops=sdpsettings;
ops.solver='sedumi'; %solver sedumi
ops.tol=1e-5; % tolerancia
ops.verbose=1;
% verbose 0 - Oculta as iterações no codigo
% verbose 1 - Mostra as iterações no código
% verbose 2 - Mostra as iterações do codigo com cor
chamativa

% Uso do Solver
solvesdp(LMIs,-trace(Q),ops)
Q=value(Q); %valor numerico de P
Y=value(Y); %valor numerico de P

Kc=Y*inv(Q); Ac=A-B*Kc; Bc=B*Kc(1); Cc=[1 0];


Dc=0;
sysmf=ss(Ac,Bc,Cc,Dc); Ec=eig(Ac), x0=[0 0]';
ts=0.01; t=0:ts:10; u=0;
ref=ones(1,length(t));
[y,t,x]=lsim(sysmf,ref,t,x0);

figure(1)
plot(t,y); xlabel('t(s)'), ylabel('\theta (rad)')
grid
A Figura 1 mostra a resposta ao degrau no formato de um servo tipo 1, cuja planta possui um
integrador.
Figura 1. Resposta ao degrau do modelo.

A mesma implementação realizada em Matlab pode ser vista em Python usando o Google Colab.
#Importando bibliotecas
from numpy import * # Traz todas as funções NumPy
from matplotlib.pyplot import * # Traz todas as funções de plotti
n MATLAB
from control.matlab import * # Funções como se fosse MATLAB
import control
from scipy import linalg
from numpy.linalg import matrix_rank
from numpy.linalg import inv
import numpy as np
import matplotlib.pyplot as plt
import random
import cvxpy as cp # Traz todas as funções de otimiz
ação convexa

A=zeros((2,2)); #inicializando matriz 2x2


A[0,1]=-1; A[1,1]=-10; A=matrix(A); #convertendo em matriz

B=zeros((2,1)); B[1,0]=1; B=matrix(B);

#Declarando as variáveis positivas


[m,n]=B.shape; #tamanho da matriz
Q = cp.Variable((m,m), symmetric=True); #declarando a matriz Q si
métrica
Y = cp.Variable((n,m)); #declarando a matriz Y

# Matrizes de Ponderação
Qc=100*eye(2); Qc=matrix(Qc);
Rc=1; Rc=matrix(Rc);

FI=-((A@Q - B@Y) + (A@Q - B@Y).T);


# operando as restrições
constraints = [Q >> 1e-6*eye(m)]
constraints += [cp.bmat([[FI, Q, Y.T],
[Q, inv(Qc), zeros((m,n))],
[Y, zeros((n,m)), inv(Rc)]
]) >> 0]
obj = cp.trace(Q);
prob = cp.Problem(cp.Maximize(obj), #função objetivo é maximizar
Q
constraints)
#prob.solve(solver=cp.SCS, verbose=True);
prob.solve(solver=cp.CVXOPT, verbose=True);

# Print result.
Qs=Q.value; Qs=matrix(Qs);
Ys=Y.value; Ys=matrix(Ys);
K = Ys*inv(Qs)
[Es,Vs]=linalg.eig(A-B*K)

print("The optimal value is", prob.value)


print("Solution Q is")
print(Qs)
print("Solution Y is")
print(Ys)
print("Gain K is")
print(K)
print("The Eigenvalues are")
print(Es)

# Análise do modelo de malha fechada


AA=A-B*K;
BB=B*K[0,0];
CC=matrix([1, 0]);
DD=0;
# Condição Inicial
x0=transpose([0, 0]);
npts=100; t=linspace(0,10,npts); #tempo de resposta
ref=ones(npts);
#u=0;
sys_mf=ss(AA, BB, CC, DD);
[y,t,x] = lsim(sys_mf,ref,t,x0);

figure(1)
subplot(2,2,1)
plot(t,x[:,0]); grid(True)
axis([0, t[npts-1], 0, 1])
xlabel('t (s)'), ylabel('x1')

A Figura 2 mostra a reposta da implementação LMI em Python.


Figura 3. Resposta ao degrau do modelo usando Python.

Exemplo 5 - Controle LMI com extensão em politopos

Politopo consiste em um vértice do conjunto poliedral convexo no processo de otimização. Cada


ponto de operação do modelo pode ser tratado como um politopo. Dessa maneira, o conjunto de
incertezas existentes em uma planta pode ser tratado como um politopo de modo que os extremos do
ponto de operação podem ser modelados como partes do modelo e consequentemente dos vértices.
Exemplo: se um sistema possui 2 parâmetros incertos, teremos para cada parâmetro 2 ou mais faixas
de operação. Dessa maneira o sistema possui 4 politopos, pois n=2p=22 = 4, onde p é a quantidade
de parâmetros incertos, e n é o número de vértices do politopo. Para o exemplo, considere que o
exemplo 2 possui um parâmetro incerto   0 10 de modo que:
0 1  0
x ( t ) = Ax ( t ) + Bu ( t )  A =   ; B = 1 
0 −    (37)
u ( t ) = − Kx ( t ) .
Portanto, o sistema possui um parâmetro incerto e 2 politopos. Considere então que o sistema tem 2
pontos de operação. Acrescenta-se ainda que h1 = −3 e raio = 20 com disco centrado em zero como
especificação de alocação de polos. O script a seguir mostra a implementação do código para obtenção
do ganho de realimentação de estados para o modelo politópico. A aplicação baseia-se na topologia
do servomecanistmo tipo 1, cujo modelo possui um integrador. Considera-se ainda que o modelo
nominal é dado pela média aritmética entre os extremos politópicos do modelo.
close all, clear all, clc

% Matrizes Politopicas e modelo nominal


A1=[0 1;0 0]; A2=[0 1;0 -10];
Anom=0.5*(A1+A2);
B=[0 1]'; %matriz B
% Especificação
h1=-3;
q=0;
raio=20;
% Matrizes de Ponderação
Qc=100*eye(2);
Rc=1;
% Declarando as variáveis semidefinidas positivas (sdp)
[m,n]=size(B); % tamanho da matriz A
Q=sdpvar(m,m); %declarando a matriz simétrica
Y=sdpvar(n,m); %declarando a matriz

% Processo de restrição
LMIs=[Q>=0];
DiscoCentrado1=[[-raio*Q q*Q+(A1*Q-B*Y);q*Q+(A1*Q-B*Y)'
-raio*Q]<=0];
DiscoCentrado2=[[-raio*Q q*Q+(A2*Q-B*Y);q*Q+(A2*Q-B*Y)'
-raio*Q]<=0];

LMIs=[LMIs, DiscoCentrado1, DiscoCentrado2];


LMIs=[LMIs,-2*h1*Q+(A1*Q-B*Y)'+(A1*Q-B*Y)<=0];
LMIs=[LMIs,-2*h1*Q+(A2*Q-B*Y)'+(A2*Q-B*Y)<=0];

% Condições de otimização
ops=sdpsettings;
ops.solver='sedumi'; %solver sedumi
ops.tol=1e-5; % tolerancia
ops.verbose=1;
% verbose 0 - Oculta as iterações no codigo
% verbose 1 - Mostra as iterações no código
% verbose 2 - Mostra as iterações do codigo com cor
chamativa

% Uso do Solver
solvesdp(LMIs,[],ops)
Q=value(Q); %valor numerico de Q
Y=value(Y); %valor numerico de Y

Kc=Y*inv(Q);
% Modelo de malha fechada aplicada a cada ponto de
operação
Ac1=A1-B*Kc; Ac2=A2-B*Kc; Acn=Anom-B*Kc;

E1=eig(Ac1),
E2=eig(Ac2),
En=eig(Acn),

Bc=B*Kc(1); Cc=[1 0]; Dc=0;


x0=[0 0]';
ts=0.1;
t=0:ts:3;
ref=ones(1,length(t));

sysmf1=ss(Ac1,Bc,Cc,Dc);
sysmf2=ss(Ac2,Bc,Cc,Dc);
sysmfn=ss(Acn,Bc,Cc,Dc);

[y1,t,x1]=lsim(sysmf1,ref,t,x0);
[y2,t,x2]=lsim(sysmf2,ref,t,x0);
[yn,t,xn]=lsim(sysmfn,ref,t,x0);

figure(1)
plot(t,y1,t,y2,t,yn); legend('A_1', 'A_2', 'A_{nom}')
axis([0 t(end) 0 1.2*y1(end)])
xlabel('t(s)'), ylabel('\theta (rad)')
grid
A Figura 4 mostra o resultado do script para o modelo politópico proposto.

Figura 4. Resposta ao degrau do modelo com incertezas politópicas.

Para a implementação em Python, o script a seguir mostra a implementação politopica.


#Importando bibliotecas
from numpy import * # Traz todas as funções NumPy
from matplotlib.pyplot import * # Traz todas as funções de plotti
n MATLAB
from control.matlab import * # Funções como se fosse MATLAB
import control
from scipy import linalg
from numpy.linalg import matrix_rank
from numpy.linalg import inv
import numpy as np
import matplotlib.pyplot as plt
import random
import cvxpy as cp # Traz todas as funções de otimiz
ação convexa
A1=matrix([[0,1],[0,-1]]); #Matriz A1
A2=matrix([[0,1],[0,-10]]); #Matriz A2
An = 0.5*(A1+A2); # Modelo nominal - Media entre A1 e A2
B=zeros((2,1)); B[1,0]=1; B=matrix(B);

# Especificação
h1=-3; h1=matrix(h1);
q=0; q=matrix(q);
raio=20; raio=matrix(raio);

#Declarando as variáveis positivas


[m,n]=B.shape; #tamanho da matriz
Q = cp.Variable((m,m), symmetric=True); #declarando a matriz Q si
métrica
Y = cp.Variable((n,m)); #declarando a matriz Y

# operando as restrições
constraints = [Q >> 1e-6*eye(m)]
#Disco Centrado e Lyapunov para A1
constraints += [cp.bmat([[-raio@Q, q@Q+(A1@Q-B@Y)],
[q@Q+(Q@A1.T-Y.T@B.T), -raio@Q]
]) << 0]
constraints += [ -
2*h1@Q + (A1@Q - B@Y + Q@A1.T - Y.T@ B.T ) << 0 ]
#Disco Centrado e Lyapunov para A2
constraints += [cp.bmat([[-raio@Q, q@Q+(A2@Q-B@Y)],
[q@Q+(Q@A2.T-Y.T@B.T), -raio@Q]
]) << 0]
constraints += [ -
2*h1@Q + (A2@Q - B@Y + Q@A2.T - Y.T@ B.T ) << 0 ]

obj = cp.trace(Q);
prob = cp.Problem(cp.Minimize(obj), #função objetivo é minimizar
Q
constraints)
prob.solve(solver=cp.SCS, verbose=True);
#prob.solve(solver=cp.CVXOPT, verbose=True);

# Print result.
Qs=Q.value; Qs=matrix(Qs);
Ys=Y.value; Ys=matrix(Ys);
K = Ys*inv(Qs)
[Es,Vs]=linalg.eig(An-B*K)

print("The optimal value is", prob.value)


print("Solution Q is")
print(Qs)
print("Solution Y is")
print(Ys)
print("Gain K is")
print(K)
print("The Eigenvalues are")
print(Es)

# Análise do modelo de malha fechada


AAn=An-B*K;
AA1=A1-B*K;
AA2=A2-B*K;

BB=B*K[0,0];
CC=matrix([1, 0]);
DD=0;
# Condição Inicial
x0=transpose([0, 0]);
npts=100; t=linspace(0,3,npts); #tempo de resposta
ref=ones(npts);
#u=0;
sys_mfn=ss(AAn, BB, CC, DD); [yn,t,x] = lsim(sys_mfn,ref,t,x0);
sys_mf1=ss(AA1, BB, CC, DD); [y1,t,x] = lsim(sys_mf1,ref,t,x0);
sys_mf2=ss(AA2, BB, CC, DD); [y2,t,x] = lsim(sys_mf2,ref,t,x0);

figure(1)
subplot(2,2,1)
plot(t,y1,'b', t,y2,'g', t,yn,'r'); grid(True)
axis([0, t[npts-1], 0, 1.2])
xlabel('t (s)'), ylabel('\u03B8')
legend(('A1', 'A2', 'An'), loc='lower right'); #insere legendas n
a figura
show()

Figura 5. Resposta ao degrau do modelo com incertezas politópicas considerando a


implementação em Pyhton.

Você também pode gostar