Estabilizando um Pêndulo Invertido com LQR
O pêndulo invertido é o benchmark canônico do controle não-linear — instável, simples o suficiente para modelar analiticamente, mas rico o suficiente para revelar todo o fluxo de projeto LQR. Este post deriva o modelo linearizado a partir da física e mostra como estabilizá-lo com Synapsys em poucas dezenas de linhas de Python.
Física e linearização
Uma haste rígida de massa e comprimento é articulada em um carrinho. Seja o ângulo em relação à vertical. Linearizando em torno de :
Escolhendo o vetor de estados e a força do carrinho :
Para kg, m, m/s²:
import numpy as np
from synapsys.api import ss
m, L, g = 0.5, 0.3, 9.81
A = np.array([[0, 1 ],
[g/L, 0 ]])
B = np.array([[0 ],
[-1/(m*L**2) ]])
C = np.array([[1, 0]])
D = np.zeros((1, 1))
planta = ss(A, B, C, D)
print(planta.is_stable()) # False — polos em ±√(g/L) = ±5,72 rad/s
Projeto LQR
O LQR encontra o ganho de realimentação de estados que minimiza:
grande penaliza erro de estado (rápido, agressivo). grande penaliza esforço de controle (lento, conservador):
from synapsys.algorithms import lqr
Q = np.diag([100.0, 1.0]) # penaliza ângulo pesadamente
R = np.array([[0.1]])
K, P = lqr(A, B, Q, R)
print(f"K = {K}") # K = [[33.2 5.8]]
A_cl = A - B @ K
print(np.linalg.eigvals(A_cl)) # autovalores no semiplano esquerdo
Simulação
from synapsys.api import c2d
import matplotlib.pyplot as plt
cl = ss(A_cl, B, C, D)
t = np.linspace(0, 3, 600)
x0 = np.array([0.2, 0.0]) # θ₀ = 0,2 rad (≈ 11°)
u_zero = np.zeros((len(t), 1))
t_out, y = cl.simulate(t, u_zero, x0=x0)
plt.plot(t_out, y)
plt.xlabel("Tempo (s)"); plt.ylabel("θ (rad)")
plt.title("Pêndulo Invertido — estabilização LQR de θ₀ = 0,2 rad")
plt.grid(True); plt.show()
O ângulo retorna a zero em aproximadamente 1,5 s sem sobressinal.
Discretização para deployment embarcado
dt = 0.01 # 100 Hz
planta_d = c2d(planta, dt=dt)
# Redesenhar K no tempo discreto
K_d, _ = lqr(planta_d.A, planta_d.B, Q, R)
# Laço de controle embarcado
x = np.zeros(2)
for _ in range(n_steps):
u = -K_d @ x
x, y = planta_d.evolve(x, u)
Resumo das APIs
| Etapa | API Synapsys |
|---|---|
| Modelagem | ss(A, B, C, D) |
| Verificação de estabilidade | planta.is_stable(), planta.poles() |
| Projeto LQR | lqr(A, B, Q, R) → retorna (K, P) |
| Simulação | cl.simulate(t, u, x0=x0) |
| Discretização | c2d(planta, dt=0.01) |
| Laço embarcado | planta_d.evolve(x, u) |
O notebook completo está em examples/quickstart_en.ipynb.
