# 6. 通訊與控制策略

## 6. 通訊與控制策略

### 6.1 CAN 設計（ID 規劃）

**CAN ID 規劃原則**：

| 優先級 | 用途 | ID 範圍（建議） |
|--------|------|----------------|
| 高（低 ID） | 安全相關（SDC 狀態、AMS Fault） | 0x001–0x0FF |
| 中 | 控制指令（扭矩命令、模式切換） | 0x100–0x2FF |
| 低 | 監測數據（電壓、溫度、速度） | 0x300–0x5FF |
| 最低 | 儀表顯示、Log 數據 | 0x600–0x7FF |

**為什麼這樣分**：CAN 是基於 ID 仲裁的，**ID 越小，優先級越高**。安全相關訊息必須在 Bus 繁忙時仍能優先傳輸。

**CAN 訊息設計範例（AMS 狀態）**：

```
CAN ID: 0x050（高優先）
DLC: 8 bytes
Byte 0: Status（0x00=OK, 0x01=OV, 0x02=UV, 0x03=OT, 0xFF=Fault）
Byte 1: Max Cell Voltage [LSB = 1 mV]（高 8 bits）
Byte 2: Max Cell Voltage（低 8 bits）
Byte 3: Min Cell Voltage（高 8 bits）
Byte 4: Min Cell Voltage（低 8 bits）
Byte 5: Max Temperature [°C, offset -40]
Byte 6: SOC [0–100%]
Byte 7: Fault Code（詳細故障碼）
```

**發送頻率設計**：
- 安全狀態訊息：10–50 ms（快速更新）
- 控制指令：5–10 ms
- 監測數據：50–100 ms
- 儀表數據：100–500 ms

### 6.2 故障處理（Fail-safe）

**Fail-safe 設計哲學**：**通訊中斷或數據異常時，系統應進入最安全的狀態，而不是繼續運行。**

**CAN 超時偵測**：

```c
// 偽碼示意
void CAN_RxCallback(uint32_t id, uint8_t *data) {
    if (id == MOTOR_CONTROLLER_STATUS_ID) {
        last_mc_heartbeat = get_timestamp();
        update_mc_status(data);
    }
}

void safety_check_task(void) {  // 每 10ms 執行
    if (get_timestamp() - last_mc_heartbeat > MC_TIMEOUT_MS) {
        // Motor Controller 通訊超時 → 扭矩命令設為 0
        set_torque_command(0);
        set_fault(FAULT_MC_TIMEOUT);
    }
}
```

**各模組超時閾值建議**：
- AMS：100 ms（若超時，禁止扭矩輸出，但不一定立刻斷 HV）
- Motor Controller：50 ms（立刻設扭矩為 0）
- 關鍵安全訊號：20 ms

**故障分級**：

| 級別 | 說明 | 處理方式 |
|------|------|----------|
| Warning | 非立即危險，需注意 | 儀表警示，繼續運行 |
| Soft Fault | 潛在問題，需降功率 | 限制扭矩輸出至 50% |
| Hard Fault | 嚴重問題，需立停 | 扭矩設 0，禁止 RTD |
| Critical Fault | 安全威脅 | 觸發 SDC 斷路（軟體觸發，補充硬體安全） |

### 6.3 State Machine（車輛狀態設計）

**整車狀態機是電控軟體的骨架。** 沒有狀態機的電控系統，就像沒有骨架的人，遇到複雜情況就垮掉。

**推薦狀態設計**：

```
                    ┌──────────────────────────────┐
                    │                              ↓
[INIT] → [LV_READY] → [HV_PRECHARGING] → [HV_READY] → [RTD]
            ↑               │                  │           │
            │          Fault/SDC Open      Fault/SDC    Fault/SDC
            │               ↓               Open           Open
            └─────── [FAULT] ←──────────────────┘←─────────┘
                        │
                    (SDC 斷路
                   所有 Contactor 斷開)
```

**各狀態說明**：

**INIT**：上電初始化。自我檢測（Selftest）：確認感測器通訊正常、SDC 節點狀態讀取、CAN 通訊建立。

**LV_READY**：GLV 系統正常，HV 尚未充電。等待駕駛操作 TSMS 進入 HV Precharge 流程。

**HV_PRECHARGING**：執行 AIR- → Precharge → AIR+ 流程。超時（如 10 秒後 MC 電壓未上升到閾值）→ 進入 FAULT。

**HV_READY**：HV 系統正常，等待 RTD 條件（煞車 + RTD 按鈕）。

**RTD（Ready To Drive）**：正常行駛狀態。扭矩控制啟用，RTDS 已觸發。

**FAULT**：任何嚴重錯誤。此狀態下，扭矩輸出為 0，向 SDC 硬體發送 Fault 訊號（透過 Watchdog 停止餵狗），重置需要物理操作（重新操作 TSMS 或解除故障）。

> 💡 **學長建議**：狀態機的進入與退出條件要寫得非常嚴謹。特別是從 FAULT 返回正常狀態的條件，不能靠軟體自動 Reset，必須有駕駛或維修人員的確認動作。

### 小結

通訊與控制策略的核心是：**預期一切可能出錯**。每個 CAN 節點可能超時，每個感測器可能輸出錯誤值，每個程式模組可能有 bug。好的狀態機設計讓系統在這些情況下仍然安全地「失效」。

---