# 從 Goddard QuarterCar 到 FSAE Traction Control 模型

# 從 Goddard QuarterCar 到 FSAE Traction Control 模型
撰寫人: 范紹捷/動力組/5~9代
基於TTR9開發

目標：
- 以 Phil Goddard 的 *Slip Control of a Quarter Car Model* 為基礎，改成符合 FSAE 後驅電動車的牽引力控制（TC）實驗環境。
[Goddard QuarterCar 模型介紹網頁、模型下載](http://www.goddardconsulting.ca/simulink-quarter-car-model.html)
[Academia.edu - 詳細說明](https://www.academia.edu/42663444/Car_Wheel_slip_Modelling_Simulation_And_Control_Using_Quarter_Car_Model)
- 在 Simulink 上：
  - 先驗證 QuarterCar plant 是否物理正確
  - 再以 PI 控制滑移率 λ，限制輪上扭矩

---

## 1. 車輛與驅動配置

### 1.1 FSAE 車輛條件

- 總重：$m_{total} = 300 \,\text{kg}$
- 前後配重（估）：前 45%、後 55%
  - 單後輪垂直力
$$F_{z,\text{rear,single}} \approx \frac{m_{total} g \cdot 0.55}{2} \approx 809 \,\text{N}$$
- 單馬達後驅，馬達接小齒輪、後輪大齒輪，總傳動比：$i = 4.02$

### 1.2 馬達與輪上扭矩

- 馬達峰值扭矩：$T_{motor,max} = 220\,\text{Nm}$
- 後軸總輪上扭矩：
$$T_{wheel,total} = T_{motor} \cdot i \approx 220 \times 4.02 \approx 884.4 \,\text{Nm}$$
- 後驅兩輪分配 → 單後輪扭矩（QuarterCar 模型使用）：
$$T_{wheel,single} \approx \frac{884.4}{2} \approx 442.2\,\text{Nm}$$

在 Simulink 中，對 QuarterCar 單輪模型：

```matlab
T_driver = 442.2;  % Nm, 單後輪全油門扭矩
```

---

## 2. 輪胎與半徑設定

### 2.1 輪胎尺寸與半徑

- 輪胎：Goodyear D2773（FSAE 常用 20x7-13 slick）
- 名目直徑：13 吋輪圈，滾動半徑近似：
$$R_{wheel} \approx \frac{13}{2}\,\text{in} \times 0.0254 \approx 0.165\,\text{m}$$

參數設定（`QuarterCarParams.m` 或 `tc_params.h`）：

```matlab
R_REAR  = 0.165;   % m
R_FRONT = 0.165;   % m
```

---

## 3. 從 ABS 模型轉成 TC 模型

Goddard 原始模型是 ABS（煞車控制）：踏煞 → 調整煞車扭矩 Tb，維持 λ 在 0.2 左右。  
這裡要改成 TC（驅動控制）：加速 → 限制驅動扭矩 $T_{driver}$，讓 λ 維持在最佳打滑附近。

### 3.1 Slip 定義與符號

ABS 常用定義（煞車）：

$$\lambda_{ABS} = \frac{v - R \omega}{v}$$

TC 驅動時採用：

$$\lambda_{TC} = \frac{R \omega - v}{v}$$

在 Goddard 模型的 `Slip Calculation` block 中，確認 / 修改為：

```text
lambda = (R * angVel - vel) / max(vel, 0.1);
```

> 若只想先看打滑量不管正負，可額外加 `Abs`，但正式 TC 建議保留正負號，方便判斷「超驅 / 欠驅」。

### 3.2 動力學方程符號

ABS → 減速；TC → 加速。需修改：

- 輪方程：
  - ABS（原）：$J \dot{\omega} = -T_b - R F_x$
  - TC（目標）：
$$J \dot{\omega} = T_{driver} - R F_x$$

- 車身方程：
  - ABS（原）：$m \dot{v} = -F_x$
  - TC（目標）：
$$m \dot{v} = F_x$$

在 QuarterCar 子系統中的對應：

- 驅動輪 `Sum` → 連到 `1/J` 的積分器：輸入為 `+T_driver` 和 `- R*Fx`。
- 車身 `Sum` → 連到 `1/m` 的積分器：輸入為 `+Fx` （而非 `-Fx`）。

這樣就可以讓模型由 **「煞車減速」** 改為 **「驅動加速」**。

---

## 4. 輪胎模型與 Goodyear D2773 近似

Goddard 使用類 Pacejka 模型：

$$\mu_x = c \cdot \sin\bigl(b \cdot \arctan(a \lambda)\bigr)$$

`QuarterCarParams.m` 中原始參數：

```matlab
roadCoeffs = [1.28 23.99 0.52]; % [a, b, c], 乾地 μ_peak ≈ 0.52
```

此組參數的 `Fx` 峰值出現在 `λ≈0.05` 附近。

### 4.1 直接沿用（簡單版）

若先不追求完全對應 D2773，直接沿用：

```matlab
roadCoeffs = [1.28, 23.99, 0.52];
lambda_base = 0.05;  % 目標滑移率
```

- λ_peak 約 0.05
- 建議 `DesiredSlip` 的 Final value 也設在 0.05～0.08 之間

### 4.2 近似 FSAE Goodyear（進階）

參考 FSAE 文獻與 μ 值，可略調高峰值：$\mu_{peak} \approx 0.55$

```matlab
% FSAE Goodyear 乾地近似
roadCoeffs = [1.67, 22.0, 0.55];   % [a, b, mu_peak]
lambda_base = 0.05;                % 峰值附近
```

> 最準確作法：用實車量測的 ax、輪速與車速 log，計算 Fx–λ 曲線，透過 `lsqcurvefit` 或 Curve Fitting Tool 擬合 Pacejka 係數。

---

## 5. 扭矩、車速顯示與基礎驗證

### 5.1 單輪驅動扭矩

依前述計算，單後輪峰值扭矩約 442.2 Nm：

```matlab
T_driver = 440;  % QuarterCar 單後輪輸入扭矩
```

測試時可先使用 Constant block，或 Step block 0→450 Nm 模擬全油門起步。

### 5.2 車速 km/h 顯示

QuarterCar 輸出的 `vel` 單位是 m/s，可加一個 Gain **3.6** 轉成 km/h：

```text
vel (m/s) ── Gain(3.6) ──> v_kmh
```

接到 Scope 或 Display，方便閱讀 0–50 / 0–100 km/h 表現。

### 5.3 Plant 驗證步驟（無控制）

1. `T_driver = 440 Nm` Constant，`DesiredSlip` 不用（或 Final=0）。
2. Scope 觀察：`v (km/h)`、`omega`、`lambda`、`Fx`。
3. 確認：
   - v 隨時間單調上升。
   - `R*omega > v` → λ 為正，表示有打滑。
   - λ 峰值約在 0.05～0.1（取決於路面係數），Fx 對應峰值（輪胎最大抓地力）。

---

## 6. PI Traction Control 結構

### 6.1 閉環架構

在 Goddard 的控制器層級上，改成下列 TC 架構：

```text
DesiredSlip (Step, 0 → lambda_base)
         |
         v
      [ + ] <──── slip (λ)
         |
         v
      PI(s)
         |
         v
TorqueLimit = min( PI_out, T_demand )
         |
         v
    MotorActuator / QuarterCar (T_driver = TorqueLimit)
```

- `DesiredSlip`：Step block，Initial=0，Final=`lambda_base`（例如 0.05），Sample time=0.005。
- `PI(s)`：離散 PI；Sample time=0.005 s。
- `T_demand`：駕駛扭矩需求，例如 Step 0→450 Nm。
- `TorqueLimit`：MinMax block，Mode=**min**，輸入 `[PI_out, T_demand]`。
  - 表示：$T_{driver} = \min(T_{demand}, T_{PI})$，即控制器只會「減扭」，不會要求超過駕駛需求。

### 6.2 PI 參數建議

根據 QuarterCar 估算與 FSAE 經驗，可用以下範圍作起點：

```matlab
Kp = 800;
Ki = 8000;
lambda_base = 0.05;  % 乾地 Goodyear 峰值附近
Ts = 0.005;          % 5 ms 控制週期
```

調參方向：

- λ 超調很大（例如先衝到 0.15 再回 0.05） → **Kp 降低**（800 → 500）。
- λ 收斂太慢（>1 s 才貼近 0.05） → **Kp 提高**（800 → 1200–1500）。
- λ 有穩態誤差（例如停在 0.07） → **Ki 提高**（8000 → 20000）。
- λ 出現明顯振盪 → **Ki 降低**（8000 → 2000–4000）。

---

## 7. 實車數據收集與模擬參數修正流程

目標：利用實車的 **CAN-logger** 與量測訊號，把 Simulink 模型中的輪胎/車輛參數
（尤其 roadCoeffs、質量分佈、實際半徑）調整到貼近真實 FSAE 車。

### 7.1 實車量測需求

建議至少量到下列訊號（你現有硬體已足夠）：

- 四輪輪速：$\omega_{FL}$ , $\omega_{FR}$, $\omega_{RL}$, $\omega_{RR}$
- IMU：縱向加速度 $a_x$、橫向加速度 $a_y$、偏航率 $r$
- 馬達：轉速 $\omega_m$、實際扭矩指令 / 回授 $T_{motor}$
- 其它：油門開度、模式切換狀態等（方便之後分析）

所有訊號以 CAN logger 記錄成時間序列檔（例如 CSV / MDF）。

### 7.2 建議實驗型態

1. **直線全油門起步（乾地）**
   - 場地：平坦乾柏油。  
   - 操作：檔位固定、TC 關閉，從靜止全油門加速到約 50–60 km/h。  
   - 目的：取得高 μ 乾路下的 $\lambda–a_x$ 關係與最大加速度。  

2. **中低扭矩掃描（低打滑）**
   - 多次 run，用 20%、40%、60% 油門限制。  
   - 目的：在低打滑區（λ<0.05）估計「線性區」的剛度，以修正 Pacejka 的 a、b 係數。

3. **低 μ 路面（如濕地 / 噴水）**
   - 同樣的全油門起步，在明顯較滑的路段。  
   - 目的：取得另一組 $\lambda–a_x$ 曲線，用來驗證 μ 估測與多路面設定。

### 7.3 從實車資料計算 λ 與 Fx

離線分析（MATLAB）：

1. 由前輪輪速估車速（假設前輪未打滑）：

```matlab
v_est = 0.5 * (omega_fl + omega_fr) * R_FRONT;  % m/s
```

2. 計算後輪滑移率 λ：

```matlab
lambda_rl = (omega_rl * R_REAR - v_est) ./ max(v_est, 0.1);
lambda_rr = (omega_rr * R_REAR - v_est) ./ max(v_est, 0.1);
lambda_avg = 0.5 * (lambda_rl + lambda_rr);
```

3. 以 IMU 縱向加速度估計總縱向力：

```matlab
Fx_total = m_total * ax_imu;   % N
Fx_single = Fx_total / 2;      % 假設主要由兩後輪提供
```

得到一組實車資料點 $(\lambda_{avg}, F_{x,single})$。

### 7.4 擬合 Pacejka 係數

使用非線性最小平方法（lsqcurvefit）擬合 roadCoeffs = [a, b, c]：

```matlab
lambda_data = lambda_avg(:);
Fx_data      = Fx_single(:);
Fz_single    = m_total * 9.81 * 0.55 / 2;

pacejka_fx = @(p, lam) Fz_single .* (p(3) .* sin(p(2) .* atan(p(1) .* lam)));

p0 = [1.3, 24, 0.55];  % 初始猜測 [a, b, mu_peak]
opts = optimoptions('lsqcurvefit', 'Display', 'iter');
[p_fit, ~] = lsqcurvefit(pacejka_fx, p0, lambda_data, Fx_data, [], [], opts);

a_fit = p_fit(1);
b_fit = p_fit(2);
mu_fit = p_fit(3);

roadCoeffs_new = [a_fit, b_fit, mu_fit];
```

將 `roadCoeffs_new` 帶回 Simulink 之後，再重跑 QuarterCar 模型，Comparing：

- 實車 vs 模擬的 `lambda(t)`、`v(t)`、`ax(t)` 曲線。  
- 若誤差仍大，可根據特定區間再調整 a / b（斜率）與 c（峰值 μ）。

### 7.5 根據實車檢查 Kp / Ki

在更新後的輪胎模型下：

1. 用 Simulink 模型跑與實車相同的油門 / 路面情境（T_demand, lambda_base 同步）。
2. 比較：
   - 模擬 λ 是否與實車趨勢相近（尤其峰值與收斂時間）。
   - 若模擬反應太快 → Kp/Ki 太大；反之太慢 → Kp/Ki 太小。
3. 以「實車 λ 波形」為 benchmark，把 PI 參數調到模擬與實車時間響應接近，再將這組 Kp/Ki 寫回 STM32 Firmware。

---

## 8. 關鍵參數總表（FSAE 設定）

| 參數 | 數值 | 說明 |
|------|------|------|
| $m_{total}$ | 300 kg | FSAE 整車質量 |
| 重量分配 | 45:55 | 前:後，估計 |
| 單後輪 $F_z$ | ≈ 809 N | 300·9.81·0.55/2 |
| 馬達峰扭 $T_{motor}$ | 220 Nm | 80 kW 電機 |
| 傳動比 $i$ | 4.02 | 馬達小齒→後輪大齒 |
| 單後輪峰扭 $T_{wheel}$ | ≈ 440 Nm | 220·4.02/2 |
| 輪半徑 $R$ | 0.165 m | 13 吋滾動半徑估計 |
| roadCoeffs (原) | [1.28, 23.99, 0.52] | Goddard 乾地 |
| roadCoeffs (FSAE 初猜) | [1.67, 22.0, 0.55] | Goodyear D2773 近似 |
| λ_target | 0.05 | 乾地峰值附近 |
| Ts | 0.005 s | 控制週期 5 ms |
| Kp | 800 | PI 初始 |
| Ki | 8000 | PI 初始 |

這份筆記對應的 Simulink 模型改動完成後，就可以直接拿來：
- 在桌上跑 QuarterCar + PI/TC 算法調參
- 以實車數據反推輪胎模型，持續修正 roadCoeffs
- 把同一套 PI/TC 參數下放到 STM32 上，做實車迴圈驗證