文章目錄
- 卡爾曼濾波
- 卡爾曼濾波的核心思想
- 卡爾曼濾波的數學模型
- 1. 狀態轉移模型(預測系統狀態)
- 2. 觀測模型(預測測量值)
- 卡爾曼濾波的五個關鍵步驟
- 1. 預測狀態
- 2. 預測誤差協方差
- 3. 計算卡爾曼增益
- 4. 更新狀態
- 5. 更新誤差協方差
- 卡爾曼濾波算法步驟總結
- 代碼實現(Python 示例)
- PID調節
- 總結
- MicroPython
- 示例代碼:控制 LED 燈并連接 WiFi
- 1. 硬件準備
- 2. 連接方式
- 3. 示例代碼
- 代碼說明
- 開發環境搭建
今天開組會,中午沒睡困得要死,但是每天都得不停學習。
參考下面視頻
卡爾曼濾波
卡爾曼濾波是一種用于估計動態系統狀態的算法,它是一種線性遞歸濾波
器,即使測量數據中存在噪聲,它也能提供對真實狀態的最佳估計。這種濾波算法在控制系統、導航、信號處理等領域應用廣泛。
卡爾曼濾波的核心思想
卡爾曼濾波是一種遞歸估計算法,它在每個時刻執行兩步:
- 預測階段:根據上一時刻的狀態,利用系統的動態模型預測當前時刻的狀態。
- 更新階段:結合當前的測量數據,校正預測值,得到更準確的狀態估計。
卡爾曼濾波的數學模型
卡爾曼濾波假設系統可以用線性模型描述,并且噪聲服從高斯分布。系統模型由以下兩部分組成:
1. 狀態轉移模型(預測系統狀態)
x k = F k x k ? 1 + B k u k + w k x_k = F_k x_{k-1} + B_k u_k + w_k xk?=Fk?xk?1?+Bk?uk?+wk?
- x k x_k xk?:系統在時刻 k k k 的狀態向量(例如位置、速度)。
- F k F_k Fk?:狀態轉移矩陣,描述狀態之間的變化關系。
- B k B_k Bk?:控制輸入矩陣,描述控制輸入對狀態的影響。
- u k u_k uk?:控制輸入。
- w k w_k wk?:過程噪聲,服從均值為 0 0 0,協方差為 Q Q Q 的高斯分布。
2. 觀測模型(預測測量值)
z k = H k x k + v k z_k = H_k x_k + v_k zk?=Hk?xk?+vk?
- z k z_k zk?:時刻 k k k 的觀測值。
- H k H_k Hk?:觀測矩陣,描述狀態如何映射到觀測空間。
- v k v_k vk?:測量噪聲,服從均值為 0 0 0,協方差為 R R R 的高斯分布。
卡爾曼濾波的五個關鍵步驟
1. 預測狀態
根據狀態轉移模型,預測當前時刻的狀態:
x ^ k ? = F k x ^ k ? 1 + B k u k \hat{x}_k^- = F_k \hat{x}_{k-1} + B_k u_k x^k??=Fk?x^k?1?+Bk?uk?
這里, x ^ k ? \hat{x}_k^- x^k?? 表示預測的狀態。
2. 預測誤差協方差
預測狀態的誤差協方差:
P k ? = F k P k ? 1 F k T + Q P_k^- = F_k P_{k-1} F_k^T + Q Pk??=Fk?Pk?1?FkT?+Q
- P k ? P_k^- Pk??:預測誤差協方差矩陣,反映預測值的不確定性。
- Q Q Q:過程噪聲協方差矩陣。
3. 計算卡爾曼增益
根據預測的不確定性和測量的不確定性計算卡爾曼增益:
K k = P k ? H k T ( H k P k ? H k T + R ) ? 1 K_k = P_k^- H_k^T (H_k P_k^- H_k^T + R)^{-1} Kk?=Pk??HkT?(Hk?Pk??HkT?+R)?1
- K k K_k Kk?:卡爾曼增益,決定了預測和測量數據的權重。
4. 更新狀態
結合測量值更新狀態估計:
x ^ k = x ^ k ? + K k ( z k ? H k x ^ k ? ) \hat{x}_k = \hat{x}_k^- + K_k (z_k - H_k \hat{x}_k^-) x^k?=x^k??+Kk?(zk??Hk?x^k??)
- z k ? H k x ^ k ? z_k - H_k \hat{x}_k^- zk??Hk?x^k??:測量殘差(即預測值與觀測值的差異)。
5. 更新誤差協方差
更新誤差協方差矩陣:
P k = ( I ? K k H k ) P k ? P_k = (I - K_k H_k) P_k^- Pk?=(I?Kk?Hk?)Pk??
- I I I:單位矩陣。
卡爾曼濾波算法步驟總結
- 初始化:設定初始狀態 x ^ 0 \hat{x}_0 x^0? 和初始協方差矩陣 P 0 P_0 P0?。
- 循環執行:
- 預測狀態 x ^ k ? \hat{x}_k^- x^k?? 和協方差 P k ? P_k^- Pk??。
- 計算卡爾曼增益 K k K_k Kk?。
- 更新狀態 x ^ k \hat{x}_k x^k? 和協方差 P k P_k Pk?。
代碼實現(Python 示例)
以位置和速度為狀態(經典一維運動模型)為例:
import numpy as np# 初始化參數
F = np.array([[1, 1], [0, 1]]) # 狀態轉移矩陣
H = np.array([[1, 0]]) # 觀測矩陣
Q = np.array([[1, 0], [0, 1]]) # 過程噪聲協方差
R = np.array([[10]]) # 測量噪聲協方差
B = np.array([[0], [0]]) # 控制輸入矩陣
u = np.array([[0]]) # 控制輸入# 初始狀態和協方差
x = np.array([[0], [1]]) # 初始狀態:[位置, 速度]
P = np.array([[1, 0], [0, 1]]) # 初始誤差協方差# 模擬觀測數據
z_real = [5, 6, 7, 9, 10] # 實際觀測值for z in z_real:# 預測階段x_predict = F @ x + B @ uP_predict = F @ P @ F.T + Q# 計算卡爾曼增益K = P_predict @ H.T @ np.linalg.inv(H @ P_predict @ H.T + R)# 更新階段z = np.array([[z]]) # 當前觀測值x = x_predict + K @ (z - H @ x_predict)P = (np.eye(2) - K @ H) @ P_predict# 輸出當前狀態估計print("位置估計:", x[0, 0], "速度估計:", x[1, 0])
PID調節
之前學過點,所以就簡單學下怎么調節。
環節 | 功能描述 | 作用 | 優點 | 缺點 | 實際應用注意事項 |
---|---|---|---|---|---|
P(比例環節) | 將比例系數與偏差信號e(t)相乘后輸出 | 快速響應系統誤差,調節系統向誤差減小的方向移動 | 響應迅速,能快速調整系統 | 可能引起系統震蕩,存在穩態誤差 | 1. 比例增益系數KP不能過大,以避免震蕩。 通過逐步增大KP,找到系統等幅振蕩時的KP值,取其70%作為最優比例增益系數。 |
I(積分環節) | 對偏差信號e(t)進行積分,使輸出持續增加或減少,直至偏差為零 | 消除穩態誤差 | 消除穩態誤差,提高系統精度 | 可能引起系統慣性干擾,導致響應變慢 | 1. 在無過諧振蕩、穩態誤差近似為0時,積分時間常數TI取值合理。 與比例環節結合(PI控制),可同時提高響應速度和消除穩態誤差。 |
D(微分環節) | 對偏差信號e(t)的變化率進行反饋,提前修正偏差 | 減少調節時間,提前校正系統 | 提高動態性能,減少超調 | 對噪聲敏感,可能導致誤調節 | 1. 在動態系統中,微分環節可以提前發出校正信號,防止偏差擴大。 |
總結
- P環節:快速響應,但可能導致震蕩和穩態誤差。
- I環節:消除穩態誤差,但可能使系統響應變慢。
- D環節:提前校正偏差,提高動態性能,但對噪聲敏感。
三者結合(PID控制)可綜合各環節的優點,克服單一環節的缺點,廣泛應用于閉環控制系統中,以實現快速、穩定且無誤差的控制效果。感覺PID可以對應快準穩。P越大,沖的越快,I適度,可以用來調節沖刺到最后的精度,D適度可以用來調價波痕,更加穩定。
MicroPython
MicroPython 是一種輕量級的 Python 解釋器,專為嵌入式系統和微控制器設計,能夠在資源受限的硬件上運行。它保留了 Python 的核心語法,同時提供了豐富的硬件控制接口,非常適合在 ESP32 等單片機上開發。
以下是一個基于 ESP32 單片機的 MicroPython 示例代碼,介紹如何通過 GPIO 控制 LED 燈的閃爍,并連接 WiFi 網絡。
示例代碼:控制 LED 燈并連接 WiFi
1. 硬件準備
- ESP32 開發板
- 一個 LED 燈
- 電阻(可選)
- 杜邦線若干
2. 連接方式
將 LED 的正極連接到 ESP32 的 GPIO 引腳(如 GPIO 5),負極通過電阻連接到 GND。
3. 示例代碼
以下代碼展示了如何控制 GPIO 引腳來點亮和熄滅 LED,并連接到 WiFi 網絡。
# 導入必要的模塊
from machine import Pin
import network
import time# 初始化 LED 引腳
led = Pin(5, Pin.OUT) # GPIO 5 作為輸出# 定義 WiFi 連接函數
def connect_wifi(ssid, password):wlan = network.WLAN(network.STA_IF) # 創建 WLAN 對象wlan.active(True) # 激活 WiFi 接口if not wlan.isconnected(): # 檢查是否已連接print("Connecting to WiFi...")wlan.connect(ssid, password) # 連接到指定 WiFiwhile not wlan.isconnected(): # 等待連接passprint("Connected to WiFi!")print("IP Address:", wlan.ifconfig()[0]) # 打印 IP 地址# 連接到 WiFi
connect_wifi("your_ssid", "your_password") # 替換為你的 WiFi 名稱和密碼# 主循環:控制 LED 閃爍
while True:led.value(1) # 點亮 LEDtime.sleep(1) # 等待 1 秒led.value(0) # 熄滅 LEDtime.sleep(1) # 等待 1 秒
代碼說明
-
GPIO 控制:
- 使用
machine.Pin
模塊控制 GPIO 引腳。 Pin(5, Pin.OUT)
表示將 GPIO 5 設置為輸出模式。led.value(1)
和led.value(0)
分別用于點亮和熄滅 LED。
- 使用
-
WiFi 連接:
- 使用
network
模塊連接到 WiFi 網絡。 network.WLAN(network.STA_IF)
創建一個 WiFi 客戶端對象。wlan.connect(ssid, password)
用于連接到指定的 WiFi 網絡。
- 使用
開發環境搭建
-
固件燒錄:
- 從 MicroPython 官網下載適用于 ESP32 的固件。
- 使用
esptool.py
工具將固件燒錄到 ESP32 開發板。
-
IDE 選擇:
- 推薦使用 Thonny IDE 或 uPyCraft IDE。
- 在 Thonny 中配置 MicroPython 解釋器,并連接到 ESP32 的串口。