# FSAE-E 循跡控制 (TC) 系統：Simulink_Simscape 建模與模擬全攻略

本文件是一份開發筆記與教學，旨在指導如何使用 MathWorks 軟體 (Simulink, Simscape) 為 FSAE 電動賽車開發、模擬並驗證一套循跡控制 (TC) 系統。

**理論基礎：**
1.  **UTAS 論文 (Pengcheng Ji, 2020):** 以 DTC (直接轉矩控制) 為馬達控制核心。
2.  **波多大學論文 (Tiago Marques, 2023):** 以 FOC (磁場導向控制) 為馬達控制核心，並引入 PSO (粒子群最佳化) 演算法來自動調校 PID。

**核心工具：**
* **Simulink®:** 用於建立「控制器」的邏輯（演算法）。
* **Simscape™:** 用於建立「受控體 (Plant)」的物理模型（虛擬賽車）。

---

## 階段一：環境設定與資源準備

在開始建模之前，首要任務是「蒐集食材」。

### 1.1 必備的 MathWorks 工具箱 (Toolboxes)

確保你已安裝：
* `Simulink` (核心平台)
* `Simscape` (物理建模基礎)
* `Simscape Multibody` (用於 3D 底盤、懸吊的物理建模)
* `Simscape Electrical` (用於馬達、逆變器、電池的物理建模)
* `Motor Control Blockset` (**關鍵！** 內含 FOC/DTC 的官方範例)
* `Vehicle Dynamics Blockset` (可選，但內含許多輪胎/車輛範例)
* `Optimization Toolbox` (若要使用波多論文的 PSO 自動調校)

### 1.2 下載官方範例模型 (你的起點)

不要從 0 開始！前往 **MATLAB Central File Exchange**：
1.  **下載「受控體 (Plant)」模板：**
    * 搜尋 `Formula Student Vehicle with Simscape` 或 `Racing Lounge: Vehicle Modeling with Simscape Multibody`。
    * 這就是你的**高精準度虛擬賽車**。
2.  **下載「控制器」模板：**
    * 在 `Motor Control Blockset` 的說明文件中，找到 `Field-Oriented Control (FOC) of PMSM` 或 `Direct Torque Control (DTC) of PMSM` 的範例。
    * 這就是你的**低階馬達控制器**。

### 1.3 蒐集你「自家車隊」的參數

你必須用你車隊的**真實數據**去替換範例模型中的預設值。這稱為「參數化」(Parameterization)。

* **[ ] 車身 (Chassis):** 總質量 (Mass), 重心 (CG) 位置, 轉動慣量 (Inertia)。
* **[ ] 懸吊 (Suspension):** 懸吊幾何點 (Hard points), 彈簧K值, 阻尼C值。
* **[ ] 馬達 (Motor):** (參考規格書) 電感 $L_d, L_q$, 電阻 $R_s$, 磁通鏈 (Flux Linkage)。
* **[ ] 輪胎 (Tire):** (最重要) **Magic Formula (Pacejka) 係數**。若沒有，先用 `Tire (Simple)` block 暫代。

---

## 階段二：建立「受控體 (Plant)」- 你的虛擬賽車 (Simscape)

在這個階段，我們專注於建立一個高精準度的「物理模型」。

1.  **開啟範例：** 打開你在 `1.2` 下載的 `Formula Student Vehicle with Simscape` 模型。
2.  **參數化模型：** 點擊各個 Simscape block (如 `Rigid Body`, `Spring-Damper`, `PMSM`)，將 `1.3` 中蒐集的參數一一填入。
3.  **建立輪胎模型：** 這是 TC 的核心。
    * Simscape 中的 `Tire (Magic Formula)` block 是你的首選。
    * 將你的輪胎係數填入。
    * 這個 block 會**自動**根據負載 (Normal Force) 和滑移率 (Slip) 輸出縱向力 (Longitudinal Force)。
4.  **建立馬達模型：**
    * 使用 `Simscape Electrical` 中的 `PMSM` block。
    * 將你的馬達參數填入。
5.  **測試受控體：**
    * 此時，先**不要**連接你的 TC 控制器。
    * 給馬達一個「恆定扭矩」或「階梯扭矩」輸入。
    * 執行模擬，打開 `Simscape Multibody Explorer` (3D 視覺化視窗)。
    * **你應該要能看到車輪瘋狂空轉、車輛失控。** 如果是，恭喜你，你的「受控體」已準備好接受 TC 的挑戰。

---

## 階段三：建立「控制器 (Controller)」- TC 的大腦 (Simulink)

這個階段，我們在「標準 Simulink」環境中，用「邏輯積木」打造 TC 演算法。

**[架構]** 你的 TC 控制器會是一個 Subsystem，它包含：

### 3.1 Step 1: 低階馬達控制器 (FOC / DTC)
1.  開啟 `Motor Control Blockset` 中的 FOC (或 DTC) 範例。
2.  將它複製/貼到你的主模型中，建立成一個 Subsystem，命名為 `Motor_Controller_L` (和 `_R`)。
3.  **輸入：** 這個 Subsystem 的輸入是 `Target_Torque` (目標扭矩)。
4.  **輸出：** 輸出是 `PWM Signals` (給逆變器) 或 `Actual_Torque` (給 Simscape 馬達)。

### 3.2 Step 2: 高階 TC 邏輯 (Slip Ratio Control)
這是你的演算法核心。

1.  **滑移率計算 (Slip Ratio Calculator):**
    * **輸入：** 4 顆輪的輪速 (Wheel Speeds)，來自 Simscape Plant。
    * **邏輯：**
        * $V_{vehicle} \approx \text{avg}(\text{WheelSpeed\_FL}, \text{WheelSpeed\_FR}) \times R_{wheel}$ (使用非驅動輪估算真實車速)
        * $Slip_{RL} = ( \text{WheelSpeed\_RL} \times R_{wheel} - V_{vehicle} ) / V_{vehicle}$
    * **輸出：** `Actual_Slip_RL`, `Actual_Slip_RR`

2.  **目標滑移率 (Target Slip Generator):**
    * 最簡單的作法：一個 `Constant` block，例如 `0.15` (代表 15% 的目標滑移率)。
    * 進階作法：一個 `1-D Lookup Table`，根據目前車速 $V_{vehicle}$ 決定最佳滑移率。

3.  **PID 控制器 (The Core)：**
    * 為左、右輪各建立一個 `PID Controller` block。
    * **輸入：** `Error = Target_Slip - Actual_Slip_RL`
    * **輸出：** 一個「限制訊號」(例如 0~1 的百分比，或是一個扭矩值)。

4.  **扭矩限制器 (Torque Limiter)：**
    * **輸入 1：** `Driver_Requested_Torque` (來自油門踏板)。
    * **輸入 2：** `TC_Limited_Torque` (來自 PID 的輸出)。
    * **邏輯：** 使用 `Min` block。 `Final_Commanded_Torque = min(Driver_Requested_Torque, TC_Limited_Torque)`
    * **輸出：** `Final_Commanded_Torque`。

---

## 階段四：系統整合 (Controller + Plant)

將「大腦」和「身體」接起來。

1.  **[Plant -> Controller] 連線：**
    * 將 Simscape 模型的 4 顆輪速 (`Wheel_Speeds`) 訊號，拉進 Simulink 的 `Slip_Ratio_Calculator`。
2.  **[Driver -> Controller] 連線：**
    * 建立一個「油門踏板」訊號 (例如一個 `Step` block，模擬 0 -> 100% 油門)，拉進 `Torque_Limiter`。
3.  **[Controller -> Plant] 連線：**
    * 將 `Torque_Limiter` 輸出的 `Final_Commanded_Torque`，拉進 `Motor_Controller_L/R` (FOC/DTC) 的「目標扭矩」輸入。
    * 將 `Motor_Controller_L/R` 的輸出 (例如 `Phase_Voltages`)，連接到 Simscape 逆變器 (`Inverter`) 的 Gating
        ports。

> **Pro-Tip (簡化版)：** 如果你想先跳過 FOC/DTC 的複雜性，你可以讓 TC 邏輯 (3.2) **直接** 輸出 `Final_Commanded_Torque`，並將此訊號直接連到 Simscape `PMSM` block 的「扭矩輸入 (T)」介面。這稱為「理想扭矩控制」，非常適合用來**初步驗證 TC 演算法本身**。

---

## 階段五：模擬、調校與驗證

執行你的模擬，然後開始調校。

### 5.1 調校 (Tuning)
你的 PID 參數 (Kp, Ki, Kd) 幾乎不可能是對的。
* **方法 1 (手動)：** 不斷修改 PID 參數，重新執行模擬，觀察 `Scope` 上的滑移率曲線，直到它能快速且穩定地貼近你的 `Target_Slip`。
* **方法 2 (半自動)：** 使用 Simulink 內建的 **`PID Tuner` App**，讓工具幫你自動計算一組初始值。
* **方法 3 (全自動 - 專業級)：** 參考**波多大學論文**。建立一個 MATLAB 腳本，使用 `Optimization Toolbox` 中的 `pso()` 函數 (粒子群最佳化)，以「最小化滑移誤差」和「最快加速時間」為目標，**自動搜尋**最佳的 Kp, Ki, Kd。

### 5.2 驗證 (Validation) - A/B Test

你必須證明 TC (ON) > TC (OFF)。

1.  **建立「TC 總開關」:**
    * 在 `Torque_Limiter` 前面，使用一個 `Manual Switch` block。
    * **ON (A 組)：** 訊號走 TC 邏輯 (`Final_Commanded_Torque`)。
    * **OFF (B 組)：** 訊號**繞過** TC 邏輯，直接使用 `Driver_Requested_Torque`。

2.  **執行模擬 A (TC ON)：**
    * **數據 (Scope)：** 你會看到 `Actual_Slip` 被完美控制在 `Target_Slip` 附近。`Commanded_Torque` 會小於 `Requested_Torque`。
    * **視覺 (Simscape Explorer)：** 你會看到 3D 車模的輪胎「輕微打滑」，車輛**穩定地**彈射出去。

3.  **執行模擬 B (TC OFF)：**
    * **數據 (Scope)：** 你會看到 `Actual_Slip` 瞬間飆到 100%。`Commanded_Torque` = `Requested_Torque`。
    * **視覺 (Simscape Explorer)：** 你會看到 3D 車模的驅動輪**瘋狂空轉**，車尾劇烈甩動 (Fishtail)，車輛可能原地打轉或緩慢前進。

**恭喜，你已經在模擬中完成了 TC 系統的開發與「效果呈現」。**

---

## 總結：下一步

這個模擬 (SIL - Software-in-the-Loop) 的最終目的，是為了產生可以燒錄到實車 VCU 上的程式碼。

* **程式碼產生：** 當你的 TC 控制器 (Simulink 部分) 調校完畢後，你可以使用 **`Simulink Coder`** 或 **`Embedded Coder`**，將你的演算法模型一鍵轉換為 C/C++ 程式碼。
* **硬體在環 (HIL)：** 在上實車前，你會將這份 C 程式碼燒錄到一個原型控制器 (例如 dSPACE 或 Speedgoat)，並與你的 Simscape 物理模型進行即時 (Real-Time) 模擬。
* **實車測試：** 最終階段，將程式碼燒錄到你車上的 VCU。