STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
lqr_motor.py
Go to the documentation of this file.
1# ============================
2# LQR Motor Position Control Simulation
3# ============================
4
5import numpy as np
6import matplotlib.pyplot as plt
7from scipy.linalg import solve_continuous_are
8
9# ----------------------------
10# 1. Define Motor Parameters
11# ----------------------------
12R = 1.0 # Ohm
13L = 0.5 # Henry
14Ke = 0.01 # V·s/rad
15Kt = 0.01 # N·m/A
16J = 0.01 # kg·m²
17B = 0.1 # N·m·s/rad
18
19# ----------------------------
20# 2. Build State-Space Model
21# ----------------------------
22A = np.array([[-R / L, -Ke / L, 0], [Kt / J, -B / J, 0], [0, 1, 0]])
23B = np.array([[1 / L], [0], [0]])
24C = np.array([[0, 0, 1]]) # output = position θ
25
26# ----------------------------
27# 3. Design LQR Controller
28# ----------------------------
29Q = np.diag([10, 1, 100]) # penalize current, speed, position error
30R_mat = np.array([[0.01]]) # penalize control effort
31
32P = solve_continuous_are(A, B, Q, R_mat)
33K = np.linalg.inv(R_mat) @ B.T @ P
34print("LQR Gain K =", K)
35
36# ----------------------------
37# 4. Simulate Closed-Loop System
38# ----------------------------
39dt = 0.001 # 1 ms
40T = 5.0 # 5 seconds
41N = int(T / dt)
42t = np.linspace(0, T, N)
43
44x = np.zeros((3, 1)) # [i, ω, θ]
45r = 1.0 # reference position (1 rad)
46
47x_hist, u_hist = [], []
48
49for _ in range(N):
50 # control law: u = -Kx + feedforward term
51 u = -K @ x + K[0, 2] * r
52 dx = A @ x + B * u
53 x += dx * dt
54
55 x_hist.append(x.flatten())
56 u_hist.append(u.item())
57
58x_hist = np.array(x_hist)
59u_hist = np.array(u_hist)
60
61# ----------------------------
62# 5. Plot Results
63# ----------------------------
64plt.figure(figsize=(10, 6))
65
66plt.subplot(3, 1, 1)
67plt.plot(t, x_hist[:, 2], label="θ (position)")
68plt.axhline(r, color="r", linestyle="--", label="reference")
69plt.ylabel("Position [rad]")
70plt.legend()
71
72plt.subplot(3, 1, 2)
73plt.plot(t, x_hist[:, 1])
74plt.ylabel("Angular Velocity [rad/s]")
75
76plt.subplot(3, 1, 3)
77plt.plot(t, u_hist)
78plt.ylabel("Control Voltage [V]")
79plt.xlabel("Time [s]")
80
81plt.tight_layout()
82plt.show()