You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AirTrapMine/src/GUI/README_SET_MODE.md

267 lines
7.2 KiB
Markdown

# GUI Set Mode 功能 - 快速參考
## 📍 在 GUI 中使用 Set Mode 的最快方式
### 現有代碼(無需修改)
gui.py 中已經在使用 set_mode 功能:
```python
def handle_mode_change(self, drone_id):
"""單個無人機模式切換"""
mode = panel.mode_combo.currentText() # 從下拉列表獲取模式
future = self.monitor.set_mode(drone_id, mode)
loop.create_task(self.handle_service_response(future, ...))
def _handle_group_mode_change(self, group_id, mode):
"""群組模式切換"""
for drone_id in group.drone_ids:
future = self.monitor.set_mode(drone_id, mode)
loop.create_task(self.handle_service_response(future, ...))
```
### 實現位置
- **核心實現**[`communication.py`](communication.py#L585-L685)
- `DroneMonitor.MODE_MAPPING` - 模式映射表
- `DroneMonitor.set_mode()` - 非同步方法
- **使用位置**[`gui.py`](gui.py#L391-L401)
- `handle_mode_change()` - 單個無人機
- `_handle_group_mode_change()` - 群組無人機
---
## 🎮 模式支援列表
| 模式名稱 | custom_mode | 備註 |
|---------|-----------|------|
| STABILIZE | 0 | 自穩定 |
| ACRO | 1 | 特技 |
| ALT_HOLD | 2 | 保持高度 |
| AUTO | 3 | 自動任務 |
| GUIDED | 4 | 引導(常用) |
| LOITER | 5 | 盤旋 |
| RTL | 6 | 返回起點 |
| CIRCLE | 7 | 圓形飛行 |
| POSITION | 8 | 位置保持 |
| LAND | 9 | 著陸 |
| SMART_RTL | 21 | 智能返回 |
---
## 🔧 API 參考
### DroneMonitor.set_mode()
```python
async def set_mode(self, drone_id, mode_name) -> bool:
"""
改變無人機飛行模式
參數:
drone_id: str - 無人機ID (如: "s0_1", "s1_11")
mode_name: str - 模式名稱 (如: "GUIDED", "AUTO")
返回:
bool - 成功返回 True失敗返回 False
"""
```
### 使用示例
```python
# 單個無人機
success = await self.monitor.set_mode("s0_1", "GUIDED")
# 或在 asyncio 中
loop = asyncio.get_event_loop()
future = self.monitor.set_mode("s0_1", "GUIDED")
loop.create_task(handle_result(future))
```
---
## 📂 相關文件
### 文檔
- [`IMPLEMENTATION_SUMMARY.md`](IMPLEMENTATION_SUMMARY.md) - 完整實現總結
- [`SET_MODE_INTEGRATION.md`](SET_MODE_INTEGRATION.md) - 詳細集成指南
- [`example_set_mode_usage.py`](example_set_mode_usage.py) - 使用示例和文檔
- 此文件:`README_SET_MODE.md` - 快速參考
### 代碼
- [`communication.py`](communication.py) - DroneMonitor 實現 (L585-L685)
- [`gui.py`](gui.py) - GUI 中的使用 (L391-L401, L656-L664)
- [`demo_set_mode.py`](demo_set_mode.py) - 可執行的演示腳本
### 原始模塊
- `fc_network_apps/changeMode.py` - change_mode() 函數
- `fc_network_apps/__init__.py` - 模塊導出
---
## 🚀 快速開始
### 1. 檢查實現
查看 communication.py 中的 MODE_MAPPING 和 set_mode() 方法是否存在:
```bash
grep -n "MODE_MAPPING\|async def set_mode" GUI/communication.py
```
✓ 應該能看到相關代碼
### 2. 驗證 fc_network_apps 可用
```bash
python3 -c "from fc_network_apps import change_mode; print('OK')"
```
✓ 輸出 "OK" 表示模塊可用
### 3. 在 GUI 中使用
直接點擊 GUI 中的模式選擇器和「切換」按鈕即可。
### 4. 查看日誌
```bash
# 在 GUI 終端查看日誌輸出
# [INFO]: Changing mode for drone s0_1 to GUIDED (custom_mode=4)
# [INFO]: Mode change successful for s0_1: Success
```
---
## 🐛 常見問題
### Q1: 模式切換失敗
**A:** 檢查以下事項:
- ✓ 無人機是否已連接到 fc_network
- ✓ 模式名稱是否正確(區分大小寫)
- ✓ drone_id 格式是否正確 (格式:`s{socket_id}_{sysid}`)
- ✓ 查看 ROS2 日誌了解詳細錯誤信息
### Q2: "Unknown mode" 錯誤
**A:**
- 檢查模式名稱的大小寫
- 確保模式在 MODE_MAPPING 中
- 參考上面的 "模式支援列表"
### Q3: "fc_network_apps is not available" 錯誤
**A:**
- 確保在 ROS2 workspace 中安裝了 fc_network_apps
- 運行 `colcon build --packages-select fc_network_apps`
- 重新 source setup 文件
### Q4: Service call timeout
**A:**
- 檢查 fc_network 節點是否運行
- 檢查無人機連接狀態
- 增加 timeout 值(在 set_mode() 中修改)
---
## 💡 設計要點
### 為什麼使用 fc_network_apps.change_mode()?
**優點**
- 經過驗證的 MAVLink 實現
- 統一的 ROS2 service interface
- 自動錯誤處理
- 支持多個無人機系統
**直接使用 MAVLink 的缺點**
- 需要管理連接
- 錯誤處理複雜
- 與 fc_network 架構不一致
### drone_id 格式設計
`s{socket_id}_{sysid}` 的含義:
- `s` - 前綴,表示 socket 連接
- `socket_id` - 連接序號0, 1, 2...
- `_` - 分隔符
- `sysid` - MAVLink system ID
例如 `s0_1`
- socket_id = 0第一個連接
- sysid = 1該連接上的第一個無人機
---
## 📊 流程圖
```
GUI 用戶界面
├─ 單無人機流程 ─────────────────────────┐
│ │
│ 1. 選擇模式 │
│ 2. 點擊「切換」 │
│ 3. handle_mode_change(drone_id) │
│ 4. monitor.set_mode(drone_id, mode) │
│ 5. change_mode(sysid, custom_mode) │
│ 6. ROS2 service call │
│ 7. 無人機執行模式切換 │
│ 8. 返回結果並更新 UI │
│ │
└─────────────────────────────────────────┘
├─ 群組流程 ────────────────────────────┐
│ │
│ 1. 為群組選擇模式 │
│ 2. 點擊群組「切換」 │
│ 3. _handle_group_mode_change() │
│ 4. For each drone_id in group: │
│ monitor.set_mode(drone_id, mode) │
│ 5. 並行發送多個 ROS2 service calls │
│ 6. 所有無人機執行模式切換 │
│ 7. 返回結果並更新 UI │
│ │
└────────────────────────────────────────┘
```
---
## 🔗 相關資源
- **ArduCopter 模式文檔**: https://ardupilot.org/copter/docs/flight-modes.html
- **MAVLink 文檔**: https://mavlink.io/en/
- **fc_network_adapter**: 本項目中的 `fc_network_adapter/` 目錄
- **fc_network_apps**: 本項目中的 `fc_network_apps/` 目錄
---
## 📌 重要提示
1. **模式名稱必須大寫**
- `"GUIDED"`
- `"guided"`
2. **drone_id 格式固定**
- 必須包含 `_` 分隔符
- `"s0_1"`
- `"s01"`
3. **async/await 模式**
- `set_mode()` 是 async 函數
- 必須通過 `await` 或 asyncio 調用
4. **超時設定**
- 預設 2.0 秒
- 無響應時返回 False
5. **日誌記錄**
- 所有操作都記錄在 ROS2 日誌中
- 便於調試和監控
---
**最後更新**: 2026年4月7日
**版本**: 1.0
**作者**: GUI 團隊