亞光上位機開發文件
JinXiang Tech ROS — 服務型機器人控制系統
版本:v2.7.0 | 更新日期:2026-03-14
目錄
- 專案概述
- 系統架構
- 技術棧
- 專案結構
- 環境需求與快速開始
- 前端應用 (React Web UI)
- WebSocket Proxy (通訊橋接)
- AMR 通訊協議
- Android 原生應用 (Capacitor)
- Electron 桌面應用
- Orange Pi 部署
- 艙門控制系統
- MQTT 遠端控制
- CMS 地圖 API
- TTS 語音系統
- 建構與發布
- 除錯指南
- 相關文件索引
1. 專案概述
JinXiang Tech ROS 是一套全端服務型機器人控制系統,專為餐飲、飯店、展覽等場景設計。系統由三大部分組成:
| 元件 |
說明 |
| React Web UI |
觸控介面,機器人操作主畫面 |
| WebSocket Proxy |
Node.js 橋接服務,瀏覽器與 AMR 間的通訊中繼 |
| AMR 設備 |
亞光 (Asia Optical) 自主移動機器人硬體 |
支援模式
| 模式 |
英文代碼 |
說明 |
| 待機 |
IDLE |
主畫面待機顯示角色 |
| 首頁 |
HOME |
模式選擇選單 |
| 配送 |
DELIVERY |
餐點/物品配送(支援艙門控制) |
| 領位 |
LEADING |
帶領賓客至指定位置 |
| 回收 |
COLLECTION |
餐盤/物品回收(支援艙門控制) |
| 生日 |
BIRTHDAY |
生日慶祝模式(含燈光控制) |
| 巡航 |
CRUISE |
定點巡邏/巡航模式 |
| 導覽 |
GUIDE |
多媒體導覽(支援文字/圖片/影片) |
| 語音互動 |
VOICE_INTERACTION |
Gemini AI 語音對話 |
| 設定 |
SETTINGS |
系統設定與地圖管理 |
部署平台
| 平台 |
技術 |
用途 |
| Android 平板 |
Capacitor 6 |
主要生產環境(乙太網直連 AMR) |
| Windows 桌機 |
Electron 33 |
開發測試 + 展示(含艙門控制) |
| Orange Pi Zero3 |
ARM64 Linux + Nginx |
嵌入式低成本部署 |
| 瀏覽器 |
Vite Dev Server |
開發測試 |
2. 系統架構
整體架構圖
┌─────────────────────────────────────────────────────────────────────────┐
│ JinXiang Robot System │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │
│ │ React UI │←─WS─→│ WebSocket │←TCP─→│ AMR Device │ │
│ │ (Browser) │ 8980 │ Proxy (Node) │ 8900 │ 192.168.168.168 │ │
│ │ Port 3000 │ │ Port 8980/8981 │ 8901 │ │ │
│ └─────────────┘ └─────────────────┘ └─────────────────────┘ │
│ ↓ ↓ ↓ │
│ Touch Screen Command Bridge Navigation/Sensors │
│ Mode Selection Binary Data Handling SLAM Mapping │
│ Task Management Notification Relay Location Tracking │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Android 原生架構(無需外部 Proxy)
┌─────────────────────────────────────────────────────────────┐
│ Android Native Mode │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────────┐ ┌─────────┐ │
│ │ React UI │←────→│ AmrPlugin │←TCP─→│ AMR │ │
│ │ (WebView) │ │ (Capacitor) │ 8900 │ Device │ │
│ │ │ │ + WS Server │ 8901 │ │ │
│ └─────────────┘ └─────────────────┘ └─────────┘ │
│ ↓ ↓ │
│ Capacitor Bridge Direct TCP + MQTT │
│ or WS localhost:8980 (no external proxy) │
└─────────────────────────────────────────────────────────────┘
Electron 桌面架構
┌─────────────────────────────────────────────────────────────┐
│ JinXiang Robot OS.exe │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
│ │ Electron Main │───→│ Embedded WebSocket Proxy │ │
│ │ (main.cjs) │ │ (Auto-start with app) │ │
│ └────────┬────────┘ └─────────────────────────────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ BrowserWindow │ │
│ │ (React UI) │ │
│ └─────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Features: System Tray, AMR Status, Auto-reconnect, │
│ RoboClaw Door Control (serialport) │
└─────────────────────────────────────────────────────────────┘
3. 技術棧
前端
| 技術 |
版本 |
用途 |
| React |
19 |
UI 框架 |
| TypeScript |
5.8 |
型別系統 |
| Vite |
6.2 |
開發伺服器與打包工具 |
| Tailwind CSS |
4 |
樣式框架 (PostCSS) |
| Lucide React |
0.555 |
圖標庫 |
| QRCode React |
4.2 |
QR Code 生成 |
原生橋接
| 技術 |
版本 |
用途 |
| Capacitor |
6 |
Android 原生應用 |
| Electron |
33 |
Windows 桌面應用 |
| serialport |
13 |
RoboClaw 串口通訊 |
後端 / 通訊
| 技術 |
版本 |
用途 |
| Node.js |
18+ |
WebSocket Proxy 運行環境 |
| ws |
8.18 |
WebSocket 伺服器 |
| Socket.io |
4.7 |
即時推送 |
| Express |
4.18 |
HTTP API |
| aws-iot-device-sdk-v2 |
- |
AWS IoT MQTT |
品牌色彩
| 名稱 |
色碼 |
用途 |
| Primary Blue |
#1B4B8F |
主色 |
| Gold/Orange |
#F59E0B |
強調色 |
| Sky Blue |
#7DD3FC |
輔助色 |
| Background |
#020617 |
背景 (slate-950) |
4. 專案結構
重要: 原始碼檔案(Context、types、constants)直接放在專案根目錄,不在 src/ 下。
JinXiang-Tech-ROS-main/
│
├── App.tsx # 主程式:模式路由、Context 嵌套
├── types.ts # TypeScript 型別定義 (AppMode, RobotStatus)
├── constants.ts # 翻譯文字、預設配置、Mock 資料
├── index.tsx # React 進入點
├── index.html # HTML 模板
│
├── AmrContext.tsx # AMR WebSocket 連線、導航、狀態、CMS API
├── ConfigContext.tsx # 啟用模式、餐盤配置、API 設定
├── LanguageContext.tsx # 多語系 i18n (zh/en/ja)
├── CloudContext.tsx # 設備啟用、硬體 ID、OTA 更新
├── CharacterContext.tsx # 機器人角色 (熊/女孩/戰士/自訂)
├── SpeechContext.tsx # TTS 狀態與語音覆蓋層
├── LogContext.tsx # 操作日誌
├── VoiceAIContext.tsx # Gemini AI 語音對話
├── ModeSettingsContext.tsx # 各模式設定
├── SettingsStorage.ts # LocalStorage 持久化 (auto-save)
│
├── components/ # React UI 元件 (24 個)
│ ├── MainAvatar.tsx # 待機角色顯示
│ ├── StatusBar.tsx # 頂部狀態列(電量/位置/時間)
│ ├── TaskView.tsx # 任務執行 UI(配送/領位/回收/生日/巡航)
│ ├── GuideModeView.tsx # 多媒體導覽模式
│ ├── VoiceView.tsx # Gemini AI 語音互動
│ ├── SettingsView.tsx # 設定主頁面
│ ├── MapSettingsPanel.tsx # 地圖站點管理
│ ├── MapEditModeView.tsx # 離線地圖編輯(站點/虛擬牆/高速路)
│ ├── MapViewPanel.tsx # 地圖視覺化面板
│ ├── MappingModeView.tsx # 建圖模式
│ ├── MappingControlPage.tsx # 手機遙控建圖(獨立頁面 #/mapping-control)
│ ├── ModeSettingsPanel.tsx # 各模式配置面板
│ ├── DoorSettingsPanel.tsx # 艙門控制設定(RoboClaw)
│ ├── SecuritySettingsPanel.tsx # 密碼安全設定
│ ├── ActivationView.tsx # 設備啟用畫面
│ ├── PasswordGate.tsx # 密碼驗證閘門
│ ├── NumericKeypad.tsx # 數字鍵盤
│ ├── DiagnosticsPanel.tsx # 系統診斷面板
│ ├── DebugConsole.tsx # 除錯主控台
│ ├── BearFace.tsx # 台灣黑熊角色臉部
│ ├── FaceOverlay.tsx # 角色臉部覆蓋層
│ ├── MiniAvatar.tsx # 迷你角色
│ ├── VideoAvatar.tsx # 影片角色
│ └── JinherLogo.tsx # 金禾公司 Logo
│
├── src/
│ ├── index.css # 全域 CSS
│ └── plugins/
│ ├── AmrPlugin.ts # Capacitor AMR 插件介面
│ ├── AmrPluginWeb.ts # Web 實現(走 WebSocket Proxy)
│ └── TtsPlugin.ts # 跨平台 TTS 插件
│
├── websocket-proxy/ # 獨立 Node.js 代理服務
│ ├── server.js # 主伺服器 (WS+Socket.io+TCP+MQTT+TTS)
│ ├── control-manager.js # MQTT 控制權管理
│ ├── map-utils.js # 地圖處理工具
│ ├── amr-map-converter.js # AMR 地圖格式轉換器
│ └── package.json # v2.1.0
│
├── electron/
│ ├── main.cjs # Electron 主程序(含嵌入式 Proxy + 艙門控制)
│ └── preload.cjs # IPC 橋接
│
├── android/
│ └── app/src/main/java/com/jinxiang/robotos/
│ ├── MainActivity.java # Android 主 Activity
│ └── plugins/
│ ├── amr/
│ │ ├── AmrPlugin.java # 原生入口,自動連接 AMR
│ │ ├── AmrTcpClient.java # TCP 客戶端 (8900/8901)
│ │ ├── MqttManager.java # AWS IoT MQTT
│ │ ├── AmrWebSocketServer.java # 本地 WS 伺服器
│ │ ├── SimpleHttpServer.java # HTTP 檔案服務
│ │ ├── RoboClawManager.java # RoboClaw 馬達控制
│ │ ├── AmrMapDownloadHandler.java # 地圖下載
│ │ ├── MapImportHandler.java # 地圖匯入
│ │ ├── MapUploadHandler.java # 地圖上傳
│ │ ├── AtomToAmrConverter.java # 格式轉換器
│ │ └── TarGzFilter.java # 壓縮過濾器
│ └── tts/
│ └── TtsPlugin.java # Android 原生 TTS
│
├── deploy/ # Orange Pi 部署
│ ├── scripts/install.sh # 主安裝腳本
│ ├── systemd/ # systemd 服務檔案
│ ├── config/ # 運行時配置
│ └── SETUP-GUIDE.md # 部署指南
│
├── scripts/ # 工具腳本
│ ├── test-door.cjs # 艙門控制測試
│ ├── clean-ports.mjs # 清理開發埠
│ └── generate-*.mjs # 角色影片/音訊生成
│
├── docs/ # 開發文件
├── public/ # 靜態資源(圖標/音訊)
└── old/ # 舊版/歷史檔案
5. 環境需求與快速開始
環境需求
| 需求 |
版本 |
備註 |
| Node.js |
18+ |
所有建構必備 |
| npm |
9+ |
隨 Node.js 安裝 |
| Android SDK |
34+ |
僅 Android 建構 |
| Java JDK |
17 |
僅 Android 建構 (需設 JAVA_HOME) |
快速開始
# 1. 安裝前端依賴
npm install
# 2. 設定環境變數(如需語音 AI)
cp .env.local.example .env.local
# 編輯 .env.local,填入 GEMINI_API_KEY
# 3. 啟動前端開發伺服器
npm run dev # http://localhost:3000
# 4. 另開終端,啟動 WebSocket Proxy
cd websocket-proxy
npm install
npm run dev # port 8980
全部 npm 腳本
# === Web UI ===
npm run dev # 啟動開發伺服器 (port 3000)
npm run dev:clean # 清理埠後啟動
npm run build # 生產建構
npm run preview # 預覽生產版本
npx tsc --noEmit # TypeScript 型別檢查
# === Electron 桌面 ===
npm run electron:dev # 開發模式 (Vite + Electron)
npm run electron:preview # 預覽生產建構
npm run electron:build # 建構 EXE 安裝檔 + 免安裝版
# === Android ===
npm run android:sync # 建構 Web + 同步到 Android
npm run android:open # 開啟 Android Studio
npm run android:build # 建構 Debug APK
npm run android:build:release # 建構 Release APK
# === 部署 ===
npm run deploy:pack # 打包 Orange Pi 部署包
6. 前端應用 (React Web UI)
6.1 Context 架構
Context 在 App.tsx 中嵌套(順序重要,後面的 Provider 可存取前面的 Context):
LogProvider
→ ConfigProvider
→ LanguageProvider
→ CharacterProvider
→ SpeechProvider
→ CloudProvider
→ AmrProvider
→ VoiceAIProvider
→ ModeSettingsProvider
→ AppContent
| Context |
檔案 |
功能 |
| LogContext |
LogContext.tsx |
操作日誌記錄 |
| ConfigContext |
ConfigContext.tsx |
啟用模式、餐盤配置、API 設定、密碼需求 |
| LanguageContext |
LanguageContext.tsx |
多語系 (zh/en/ja) 的 t() 翻譯函式 |
| CharacterContext |
CharacterContext.tsx |
機器人角色切換 (bear/girl/warrior/custom) |
| SpeechContext |
SpeechContext.tsx |
TTS 狀態與語音文字覆蓋層 |
| CloudContext |
CloudContext.tsx |
設備啟用、硬體 ID、OTA 更新 |
| AmrContext |
AmrContext.tsx |
AMR WebSocket 連線、導航指令、狀態監控 |
| VoiceAIContext |
VoiceAIContext.tsx |
Gemini API 整合、語音辨識/合成 |
| ModeSettingsContext |
ModeSettingsContext.tsx |
各模式獨立設定(目的地、計時器、巡航點等) |
6.2 模式與元件對應
| 模式 |
元件 |
使用的 AMR 命令 |
| IDLE |
MainAvatar |
- |
| HOME |
Menu Grid |
- |
| DELIVERY |
TaskView |
GoToLocation, GetRobotStatus |
| LEADING |
TaskView |
GoToLocation, GetRobotStatus |
| COLLECTION |
TaskView |
GoToLocation, GetRobotStatus |
| BIRTHDAY |
TaskView |
GoToLocation, SetLight |
| CRUISE |
TaskView |
GoToLocation (巡航迴圈) |
| GUIDE |
GuideModeView |
GoToLocation, 自訂 TTS |
| VOICE_INTERACTION |
VoiceView |
Gemini API + TTS |
| SETTINGS |
SettingsView |
SetMap, SetLocation, GetProfile |
6.3 多語系 (i18n)
翻譯定義在 constants.ts 的 TRANSLATIONS 物件中,支援三種語言:
const { t } = useLanguage();
<span>{t('modeDelivery')}</span>
// 中文: "配送模式" / English: "Delivery" / 日本語: "配膳モード"
新增文字時須同時加入 zh、en、ja 三種語言的 key。
6.4 路由頁面
| 路由 |
元件 |
說明 |
| 主應用 |
App.tsx |
所有模式的主畫面 |
#/mapping-control |
MappingControlPage |
手機遙控建圖(橫向 D-Pad 設計) |
6.5 全螢幕 UI 規範
在 App 內顯示全螢幕面板時,必須保留 StatusBar (40px):
// ✅ 正確做法
<div className="fixed top-10 left-0 right-0 bottom-0 z-50 bg-slate-950">
<YourFullscreenComponent />
</div>
// ❌ 錯誤做法 — 會被 StatusBar 擋住
<div className="fixed inset-0 z-50 bg-slate-950">
6.6 路徑別名
// vite.config.ts & tsconfig.json
// @ → 專案根目錄
import { AppMode } from '@/types';
import { TRANSLATIONS } from '@/constants';
7. WebSocket Proxy (通訊橋接)
7.1 概述
因瀏覽器無法直接使用 TCP Socket,需要 Node.js 中繼服務。位於 websocket-proxy/ 目錄。
7.2 服務端口
| Port |
協議 |
方向 |
用途 |
| 8980 |
WebSocket |
React ↔ Proxy |
命令/回應 + TTS |
| 8981 |
Socket.io |
Proxy → React |
即時推送 |
| 8900 |
TCP |
Proxy ↔ AMR |
命令/回應 (JSON) |
| 8901 |
TCP |
AMR → Proxy |
通知與狀態更新 |
7.3 核心檔案
| 檔案 |
功能 |
server.js |
主伺服器(整合 WS + Socket.io + TCP + MQTT + TTS) |
control-manager.js |
MQTT 控制權管理模組 |
map-utils.js |
地圖資料處理工具 |
amr-map-converter.js |
AMR 地圖格式轉換 |
7.4 功能清單
- WebSocket Server (port 8980) — 前端通訊
- Socket.io Server (port 8981) — 即時推送
- TCP Client → AMR port 8900 — 命令發送/回應接收
- TCP Server ← AMR port 8901 — 接收通知
- 二進制地圖資料處理 (base64 編碼)
- AWS IoT MQTT 整合(選配遠端控制)
- espeak-ng TTS 語音服務
8. AMR 通訊協議
8.1 JSON 命令格式
// 請求
{"Command": "GoToLocation", "Name": "Table1"}
// 回應
{"Command": "GoToLocation", "Result": "Ack"}
8.2 主要命令
| 命令 |
用途 |
參數範例 |
GetRobotStatus |
查詢狀態 |
Para: "location" / "battery_level" / "move_state" |
GoToLocation |
導航至站點 |
Name: "Table1" |
GoToXY |
座標導航 |
X, Y, Orientation |
SwitchMode |
切換 SLAM 模式 |
Mode: "mapping" / "localization", MapName |
SetMap |
地圖操作 |
Para: "list" / "save" / "switch" / "get" |
SetLocation |
站點操作 |
Para: "add" / "delete" / "list" |
EMS |
緊急停止 |
- |
GoCharge |
回充電站 |
- |
SetLight |
燈光控制 |
- |
8.3 移動狀態流程
Start → Calculating → Going → Complete / Abort / Stuck
8.4 重要限制
- 導航命令(GoToLocation、GoToXY)僅在 localization 模式 下有效
- 使用
SwitchMode 並指定 Mode: "localization" + MapName 後才能導航
- mapping 模式僅用於建立/編輯地圖
8.5 FileAccess 協議(地圖上傳/下載)
下載地圖 (send):
1. 發送: {"Command":"FileAccess","Para":"send","Type":"map","Name":"mapName"}
2. 收到: {"Command":"FileAccess","Result":"Ack","Length":2029663,...}
3. 接收二進制數據(JSON 後有一個 0x0a 換行符需跳過)
上傳地圖 (receive):
1. 發送: {"Command":"FileAccess","Para":"receive","Type":"map","Name":"mapName","Length":size}
2. 等待 Ack
3. 發送二進制數據
注意: FileAccess 二進制數據在 8900 端口 傳輸,不是 8901!
8.6 電池/充電 API
| 訂閱類型 |
返回 Command |
返回 Para |
欄位 |
GetBatteryLevel |
GetRobotStatus |
battery_level |
battery_level (0-20) |
GetChargingStatus |
GetRobotStatus |
charging |
charging (True/False) |
GetBatteryLevel 訂閱不含 charging 欄位
- 需要即時電池 + 充電狀態:使用
GetBatteryStatus 命令
9. Android 原生應用 (Capacitor)
9.1 架構
Android App 使用 Capacitor 原生插件直接 TCP 連接 AMR,不需外部 WebSocket Proxy。
原生插件在 localhost:8980 運行 WebSocket 伺服器,使 AmrContext.tsx 跨平台統一連接。
9.2 原生插件檔案
| 檔案 |
功能 |
AmrPlugin.java |
原生入口,自動連接 AMR |
AmrTcpClient.java |
TCP 客戶端 (8900/8901) |
MqttManager.java |
AWS IoT MQTT 遠端控制 |
AmrWebSocketServer.java |
本地 WS Server (統一 API) |
SimpleHttpServer.java |
HTTP 檔案服務 |
RoboClawManager.java |
RoboClaw 馬達控制 |
AmrMapDownloadHandler.java |
地圖下載處理 |
MapImportHandler.java |
地圖匯入 |
MapUploadHandler.java |
地圖上傳 |
9.3 雙網卡配置
Android 同時連接兩個網路:
| 介面 |
用途 |
連接目標 |
| eth0 (乙太網) |
AMR 通訊 |
192.168.168.168 |
| wlan0 (WiFi) |
外網 (MQTT/CMS) |
Internet |
系統預設走乙太網,須特殊處理才能讓 MQTT/CMS 走 WiFi。解決方案共 4 層:WiFi 自動連接 → 路由設定 → 自訂 DNS → IP-based SSL。
9.4 建構指令
npm run android:sync # 建構 Web + 同步到 Android
npm run android:open # 開啟 Android Studio
npm run android:build # Debug APK
npm run android:build:release # Release APK (unsigned)
APK 位置: android/app/build/outputs/apk/debug/app-debug.apk
10. Electron 桌面應用
10.1 核心檔案
| 檔案 |
功能 |
electron/main.cjs |
主程序:視窗管理、嵌入式 Proxy、System Tray、艙門控制 |
electron/preload.cjs |
安全 IPC 橋接 |
electron.d.ts |
TypeScript 型別 (window.electronAPI) |
10.2 Renderer 可用 API
if (window.electronAPI) {
const info = await window.electronAPI.getAppInfo();
const connected = await window.electronAPI.checkAmr();
window.electronAPI.toggleFullscreen();
// 艙門控制 (RoboClaw)
await window.electronAPI.doorControl('upper', 'open');
await window.electronAPI.doorGetAllStates();
}
10.3 建構輸出
npm run electron:build
# → release/JinXiang Robot OS Setup.exe (NSIS 安裝檔)
# → release/JinXiang Robot OS.exe (免安裝版)
11. Orange Pi 部署
11.1 目標環境
ARM64 Linux (Orange Pi Zero3 + 觸控螢幕)
11.2 部署包結構
release/orangepi/
├── dist/ # Web 前端靜態檔案
├── websocket-proxy/ # Node.js 代理服務
├── scripts/ # 安裝腳本
├── config/ # Nginx 配置
├── systemd/ # systemd service 檔案
└── version.json # 版本資訊
11.3 安裝
# 打包
npm run deploy:pack
# 傳輸到 Orange Pi 後
sudo bash scripts/install.sh
11.4 音訊配置
| 選項 |
AUDIO_OUTPUT |
用途 |
| 1 |
auto |
自動選擇 |
| 2 |
hdmi |
HDMI 音訊 |
| 3 |
headphone |
3.5mm 耳機孔 |
| 4 |
usb |
USB 音訊設備 |
配置檔:/opt/jinxiang-ros/config/audio.conf
12. 艙門控制系統
12.1 硬體
透過 RoboClaw 馬達控制器 + Arduino 驅動實體艙門。僅 Electron 平台支援(需 serialport)。
僅 DELIVERY 和 COLLECTION 模式有艙門功能。
12.2 RoboClaw 配置 (RoboClawConfig)
儲存:LocalStorage jixiang_roboclaw_config
| 參數 |
預設值 |
說明 |
comPort |
'' |
COM 連接埠 |
baudRate |
38400 |
串口鮑率 |
address |
0x80 |
裝置地址 |
controlMode |
'speed' |
speed / position / auto |
motorSpeed |
64 |
馬達速度 (1-127) |
motorTimeout |
10000 |
安全逾時 (ms) |
openDuration |
2000 |
定時開門時長 (ms) |
12.3 Electron API
// 控制
doorControl(door: 'upper'|'lower', action: 'open'|'close')
doorOpenAll() / doorCloseAll() / doorStop()
// 狀態查詢
doorGetState(door) // → state: 'open'|'closed'|'mostly_open'|'mostly_closed'
doorGetAllStates() // → status: 'idle'|'opening'|'closing'|'completed'|'timeout'
// 編碼器
encoderRead() // → { m1, m2 }
encoderReset() / encoderPollingStart() / encoderPollingStop()
// 位置學習
learningModeStart(door) / learningModeSave() / learningModeCancel()
12.4 位置學習流程
learningModeStart(door)
│
▼ phase: 'open'
手動將門推到「開啟」位置
│
▼ learningModeSave() ← 記錄位置
phase: 'close'
│
▼ 手動將門推到「關閉」位置
│
▼ learningModeSave() ← 記錄位置,自動寫入 config
學習完成
13. MQTT 遠端控制
13.1 概述
支援 AWS IoT Core MQTT 遠端控制,WebSocket Proxy 與 Android 原生兩套實現功能同等。
13.2 配置
| 項目 |
設定位置 |
| Proxy |
websocket-proxy/server.js → MQTT_ENABLED / MQTT_DEVICE_ID |
| Android |
DeviceId: JR2_ROBOT_{serial_number}(從 AMR GetProfile 取得) |
13.3 相關文件
| 文件 |
內容 |
docs/MQTT_PROTOCOL_UNIFIED.md |
統一協議規範 v2.1.7 |
docs/MQTT_DEV_NOTES.md |
開發筆記(動態上報、電文統一、Y 軸翻轉) |
docs/MQTT_THIRD_PARTY_SPEC.md |
第三方機器人接入規範 |
MQTT_REMOTE_CONTROL.md |
AWS IoT 基礎設定 |
13.4 雙平台同步維護
修改通訊相關程式碼時,必須同步更新兩套實現:
| Proxy |
Android |
server.js |
AmrTcpClient.java / AmrWebSocketServer.java |
control-manager.js |
MqttManager.java |
14. CMS 地圖 API
14.1 跨平台實現
| 平台 |
方式 |
| Android |
httpGetViaWifi / httpPostViaWifi (OkHttp + WiFi DNS) |
| Windows/Orange Pi |
sendCmsRequest() → WebSocket Proxy → Node.js fetch |
前端統一使用 useAmr() 的 sendCmsRequest()。
14.2 設定
在 UI 的「設定 → API 串接設置」和「設定 → 地圖站點管理」中配置。
15. TTS 語音系統
15.1 跨平台架構
| 平台 |
TTS 後端 |
說明 |
| Android |
TextToSpeech (原生) |
Capacitor 原生插件 |
| Windows/Mac |
Web Speech API |
瀏覽器原生 |
| Orange Pi/Linux |
WebSocket → espeak-ng |
Proxy 轉發系統 TTS |
15.2 自動 Fallback 機制
1. 嘗試 Web Speech API
2. 若 1 秒內無語音 → fallback WebSocket TTS
3. WebSocket TTS 透過 ws://localhost:8980 發送
4. Proxy 調用 espeak-ng 播放
15.3 WebSocket TTS 消息格式
// 請求
{"type": "tts", "action": "speak", "text": "你好", "lang": "zh-TW"}
{"type": "tts", "action": "stop"}
// 回應
{"type": "tts_response", "action": "speak", "success": true}
15.4 導覽語音流程
| 時機 |
內容 |
來源 |
| 出發後 3 秒 |
引導語輪播 |
固定 GUIDANCE_PHRASES |
| 每 7 秒 |
引導語輪播 |
固定 |
| 到達站點 |
站點內容 |
路線設定 (TEXT/描述) |
| 最後一站完成 |
「導覽結束,正在返回起點」 |
固定 |
| 返回完成 |
「感謝您的參觀」 |
固定 |
16. 建構與發布
16.1 全平台建構工具
.\build-all.bat # Windows 互動式選單
| 選項 |
目標 |
輸出位置 |
| 1 |
Android APK |
release/android/JinXiang-Robot-OS.apk |
| 2 |
Orange Pi ARM64 |
release/orangepi/ |
| 3 |
Windows EXE |
release/JinXiang Robot OS Setup.exe + portable |
| 4 |
全部 |
以上皆是 |
16.2 TypeScript 檢查
本專案無 lint 或 test 腳本。TypeScript 使用 noEmit: true(僅型別檢查):
npx tsc --noEmit # 檢查 TypeScript 錯誤
17. 除錯指南
17.1 AMR 連線問題
- 確認 AMR 已開機且 IP 為
192.168.168.168
- 確認開發機與 AMR 在同一網段(有線連接)
- 檢查 WebSocket Proxy:
cd websocket-proxy && npm start
- 瀏覽器 DevTools 檢查 WebSocket 連線狀態
17.2 導航指令失敗
- 確認 AMR 處於 localization 模式(非 mapping)
- 使用
SwitchMode 切換模式並指定地圖名
- 確認目標站點名稱正確且存在於當前地圖
17.3 Android 雙網卡
MQTT/CMS 連外網失敗 → 檢查 adb logcat -s AmrPlugin | grep -i wifi
17.4 命令逾時處理
| 命令類型 |
逾時時間 |
| 一般查詢 |
10 秒 |
| 導航命令 |
30 秒 |
| 地圖操作 |
30 秒 |
詳見 AMR_COMMAND_TROUBLESHOOTING.md。
18. 相關文件索引
協議與 API
| 文件 |
內容 |
AMR-API-Documentation.md |
AMR TCP 協議完整參考 (V1.18.0) |
AMR_COMMAND_TROUBLESHOOTING.md |
命令失敗診斷指南 |
docs/MQTT_PROTOCOL_UNIFIED.md |
統一 MQTT 協議規範 v2.1.7 |
docs/MQTT_DEV_NOTES.md |
MQTT 開發筆記 |
docs/MQTT_THIRD_PARTY_SPEC.md |
第三方機器人 MQTT 規範 |
docs/MAP_PACKAGE_SPEC.md |
地圖包規格 v2.1 |
docs/AMR_MAP_UPLOAD_SPEC.md |
AMR 原生格式參考 |
FRONTEND_API_GUIDE.md |
前端 API 指南 |
元件文件
| 文件 |
內容 |
docs/AmrContext.md |
AMR 通訊模組文件 |
docs/TaskView.md |
任務視圖元件文件 |
docs/MapSettingsPanel.md |
地圖站點管理文件 |
docs/VoiceAIContext.md |
語音 AI 互動文件 |
docs/SettingsView.md |
設定頁面文件 |
docs/ARCHITECTURE.md |
系統架構文件 |
平台指南
| 文件 |
內容 |
ANDROID_BUILD_GUIDE.md |
Android APK 打包指南 |
ANDROID_NATIVE_PLUGIN.md |
Capacitor 原生插件開發 |
deploy/SETUP-GUIDE.md |
Orange Pi Zero3 部署指南 |
附錄:程式碼統計
| 區域 |
行數 |
檔案數 |
| 根目錄 TypeScript |
~9,300 行 |
15 個 |
| React 元件 |
~20,000 行 |
24 個 |
| WebSocket Proxy |
~3,000 行 |
7 個 |
| Android Java |
~8,000 行 |
13 個 |
| Electron |
~2,500 行 |
2 個 |
| 文件 |
18+ 個 MD |
- |
本文件由 Claude Code 自動生成,基於 JinXiang Tech ROS v2.7.0 專案內容整理。