795 lines
21 KiB
Markdown
795 lines
21 KiB
Markdown
# KL630 Host Stream Firmware
|
||
|
||
即時影像語義分割系統,運行於 Kneron KL630 (Cortex-A7, uClibc)。
|
||
透過 IMX662 DOL-HDR 雙曝光攝影機進行 STDC 語義分割,並將結果以 RTSP 串流或 HDMI 輸出。
|
||
|
||
**技術細節 → [`docs/technical_report.md`](docs/technical_report.md)**
|
||
|
||
---
|
||
|
||
## 目錄結構
|
||
|
||
```
|
||
kl630_build/
|
||
├── web_serve.py # Web 控制台(主要使用)
|
||
├── build_and_serve.py # CLI 版本(不需要瀏覽器)
|
||
├── compile.sh # Docker 內 ARM 交叉編譯腳本
|
||
├── Dockerfile # kl630-dev image 定義
|
||
├── requirements.txt # Python 套件清單
|
||
│
|
||
├── src/
|
||
│ ├── host_stream/ # 主程式(初始化、推論迴圈、結果處理)
|
||
│ ├── app_flow/ # VMF pipeline 控制
|
||
│ ├── pre_post/ # YOLOv5 前後處理
|
||
│ └── stdc/ # STDC 語義分割後處理
|
||
│
|
||
├── include/
|
||
│ ├── stdc/ # stdc_post_process.h(分析結果結構)
|
||
│ └── fake/ # SDK 缺少時的 stub headers
|
||
│
|
||
├── ini/
|
||
│ └── host_stream.ini # 執行期設定(model、stream、ISP、FEC 參數)
|
||
│
|
||
│
|
||
├── lib/ # 裝置端 .so 函式庫(VMF SDK)
|
||
├── docs/
|
||
│ └── technical_report.md # 完整技術文件
|
||
└── build/ # 編譯輸出(由 compile.sh 產生)
|
||
```
|
||
|
||
---
|
||
|
||
## 快速開始
|
||
|
||
### 前置條件
|
||
|
||
- [Docker Desktop](https://www.docker.com/products/docker-desktop/) 已安裝並執行中
|
||
- Python 3.8+
|
||
|
||
### 安裝
|
||
|
||
```bash
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
| 套件 | 用途 |
|
||
|------|------|
|
||
| `flask` | Web 控制台 + HTTP file server |
|
||
| `opencv-python` | RTSP 串流預覽(內建 FFmpeg,無需另外安裝)|
|
||
|
||
### 啟動
|
||
|
||
```bash
|
||
python web_serve.py
|
||
```
|
||
|
||
瀏覽器開啟 `http://localhost:8080/`
|
||
|
||
---
|
||
|
||
## 新機器首次設定 SOP
|
||
|
||
全新 KL630 裝置依序執行以下步驟:
|
||
|
||
### Step 1 — Compile
|
||
|
||
在 Web 控制台按 **Compile**。
|
||
- 自動建立 Docker image(若不存在)
|
||
- 交叉編譯 ARM binary
|
||
- 複製 binary / INI / 腳本到 `build/`
|
||
|
||
> 若 binary 已是最新版本,可跳過此步驟直接從 Step 2 開始。
|
||
|
||
### Step 2 — 設定 Output Mode
|
||
|
||
在 **INI Settings** 面板選擇輸出模式(預設 RTSP):
|
||
|
||
| 組合 | RTSP | HDMI | 啟動腳本 |
|
||
|------|------|------|---------|
|
||
| RTSP 串流 | ON | OFF | `demo_rtsp.sh` |
|
||
| HDMI 顯示 | OFF | ON | `demo_hdmi.sh` |
|
||
| RTSP + HDMI 同時 | ON | ON | `demo_rtsp_hdmi.sh`(INI voc_enable=1)|
|
||
| 純推論(無輸出) | OFF | OFF | 直接啟動 binary |
|
||
|
||
### Step 3 — Deploy to KL630
|
||
|
||
按 **Deploy to KL630**,自動透過 Telnet 完成:
|
||
1. 停止舊 firmware
|
||
2. 下載 binary、INI、NEF 模型
|
||
3. 下載 `demo_rtsp.sh`、`demo_hdmi.sh`、`demo_rtsp_hdmi.sh`
|
||
4. 設定 VOC 輸出模式
|
||
5. 啟動 firmware
|
||
|
||
### Step 4 — First-time ISP Setup
|
||
|
||
按 **First-time ISP Setup**。
|
||
寫入 DOL-HDR 所需的 flash 參數(`dwStatisticsSrcType=2`、`bGTREnable=1`),
|
||
**只需執行一次**,設定永久保留在 flash,重新 Deploy 不會被覆蓋。
|
||
|
||
> 跳過此步驟影像會過暗或曝光不正確。
|
||
|
||
### Step 5 — 魚眼鏡頭校正(FEC)
|
||
|
||
在 **INI Settings** 面板設定 Fish-Eye Correction:
|
||
|
||
| 參數 | 推薦設定 | 說明 |
|
||
|------|---------|------|
|
||
| FEC | ON | 開啟魚眼校正 |
|
||
| **Mode** | **4 — 180° Two Direction** | 天花板魚眼鏡頭推薦模式,同時展開水平與垂直方向 |
|
||
| Install Type | 0 — Ceiling | 天花板安裝 |
|
||
| EIS | 視需求 | 電子防手震 |
|
||
|
||
按 **Apply to Device + Restart** 套用並重啟 firmware。
|
||
|
||
|
||
---
|
||
|
||
## Web 控制台功能說明
|
||
|
||
### Network Config
|
||
設定 **Host IP**(這台 PC)、**KL630 IP**、**HTTP Port**、**Docker Image**。
|
||
按 Save 後自動更新 `deploy.sh` 的 `HOST_URL`。
|
||
|
||
### HTTP Server Files
|
||
列出 `build/` 目錄下所有可下載的檔案,以及裝置端手動部署指令:
|
||
```sh
|
||
wget http://<host_ip>:8080/deploy.sh -O /tmp/deploy.sh && sh /tmp/deploy.sh
|
||
```
|
||
|
||
### RTSP Stream Preview
|
||
直接在網頁預覽 KL630 串流,不需要開 VLC。
|
||
按 **▶ Start Stream** 即可,連線失敗時 6 秒內回報錯誤。
|
||
|
||
---
|
||
|
||
## Actions
|
||
|
||
| 按鈕 | 說明 |
|
||
|------|------|
|
||
| **Compile** | Docker 交叉編譯 ARM binary,複製到 `build/` |
|
||
| **Deploy to KL630** | Telnet 部署 binary / INI / NEF / 腳本,依 Output Mode 啟動 firmware |
|
||
| **First-time ISP Setup** | 新機器一次性 ISP flash 設定(DOL-HDR 參數) |
|
||
| **Write Autostart** | 寫入開機自動啟動腳本 `/etc/init.d/S99firmware` |
|
||
|
||
---
|
||
|
||
## INI Settings
|
||
|
||
### Fish-Eye Correction (FEC)
|
||
|
||
| 參數 | 說明 |
|
||
|------|------|
|
||
| FEC ON/OFF | 開啟或關閉魚眼校正(`fec_mode = 0` 為關閉)|
|
||
| Mode 1 | Single Region |
|
||
| Mode 2 | 180° All Direction |
|
||
| Mode 3 | 180° One Direction |
|
||
| **Mode 4** | **180° Two Direction(推薦)** |
|
||
| Mode 5 | PT Mode |
|
||
| Install Type | Ceiling / Table / Wall(`initial_fec_app_type`)|
|
||
| EIS | 電子防手震(`eis_enable`)|
|
||
| DrawBox | H.264 burn-in 偵測框(`DrawBoxEnable`)|
|
||
|
||
### Output Mode
|
||
|
||
| 選項 | 說明 |
|
||
|------|------|
|
||
| RTSP | H.264 RTSP 串流輸出,由 `demo_rtsp.sh` 管理 |
|
||
| HDMI | VOC HDMI 顯示輸出,由 `demo_hdmi.sh` 管理 |
|
||
|
||
- **Save INI(disk only)** — 更新本地 `ini/host_stream.ini`,下次 Deploy 時推送至裝置
|
||
- **Apply to Device + Restart** — 立即 Telnet 更新裝置 INI 並重啟 firmware
|
||
|
||
### Model Settings
|
||
|
||
切換推論模型(NEF 檔)、ModelId、JobId,支援上傳新 NEF。
|
||
**Apply to Device + Restart** 會下載 NEF 到裝置並依目前 Output Mode 重啟。
|
||
|
||
---
|
||
|
||
## Terminal
|
||
|
||
Output Log 下方有命令輸入列,可直接在網頁對 KL630 下指令:
|
||
|
||
```sh
|
||
cat /tmp/fw.log # 查看 firmware 啟動 log
|
||
cat /tmp/rtsp_demo.log # 查看 RTSP demo log
|
||
ps | grep firmware # 確認 firmware 是否在執行
|
||
killall kp_firmware_host_stream
|
||
```
|
||
|
||
---
|
||
|
||
---
|
||
|
||
## Web Server 命令行操作指南
|
||
|
||
若不喜歡 GUI,可透過指令和 API 完全控制 `web_serve.py`,不需要開瀏覽器。
|
||
|
||
### 啟動 Web Server
|
||
|
||
```bash
|
||
# 預設 port 8080
|
||
python web_serve.py
|
||
|
||
# 指定端口
|
||
python web_serve.py --port 8080
|
||
python web_serve.py --port 9090
|
||
```
|
||
|
||
Server 啟動後可用 `curl` 調用各項功能。
|
||
|
||
### Web Server API 參考
|
||
|
||
#### 1. **查詢/保存設定**
|
||
|
||
```bash
|
||
# 查看現在設定(Host IP、KL630 IP、HTTP Port、Docker Image)
|
||
curl http://localhost:8080/api/config
|
||
|
||
# 修改設定
|
||
curl -X POST http://localhost:8080/api/config \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"host_ip": "192.168.3.1",
|
||
"kl630_ip": "192.168.3.10",
|
||
"port": 8080,
|
||
"docker_image": "kl630-dev"
|
||
}'
|
||
```
|
||
|
||
#### 2. **查看 build/ 目錄下載文件列表**
|
||
|
||
```bash
|
||
curl http://localhost:8080/api/files
|
||
```
|
||
|
||
輸出示例:
|
||
```json
|
||
[
|
||
{"name": "kp_firmware_host_stream", "size": 5242880},
|
||
{"name": "host_stream.ini", "size": 2048},
|
||
{"name": "demo_rtsp.sh", "size": 512},
|
||
{"name": "deploy.sh", "size": 1024}
|
||
]
|
||
```
|
||
|
||
#### 3. **編譯(Server-Sent Events 串流輸出)**
|
||
|
||
```bash
|
||
# 啟動編譯,即時輸出編譯 log
|
||
curl http://localhost:8080/api/compile/run
|
||
|
||
# 搭配 jq 只看 error
|
||
curl http://localhost:8080/api/compile/run | grep -o '"kind":"error"' | wc -l
|
||
```
|
||
|
||
編譯 log 格式(SSE):
|
||
```json
|
||
{"kind": "log", "text": "Starting cross-compile..."}
|
||
{"kind": "ok", "text": "Compile SUCCESS"}
|
||
{"kind": "error", "text": "Compile FAILED (exit 1)"}
|
||
```
|
||
|
||
#### 4. **部署到 KL630(Telnet)**
|
||
|
||
```bash
|
||
# 執行完整部署流程(停止舊 firmware、下載 binary、啟動新 firmware)
|
||
curl http://localhost:8080/api/deploy/run
|
||
|
||
# 查看部署 log(最後 100 行)可透過網頁 Terminal 或直接用 tail
|
||
```
|
||
|
||
部署流程等同於 Web UI 按下 **Deploy to KL630**。
|
||
|
||
#### 5. **ISP / Flash 一次性設定**
|
||
|
||
```bash
|
||
# 一次性 ISP setup(DOL-HDR 參數)
|
||
curl http://localhost:8080/api/spi_setup/run
|
||
|
||
# 或藍牙相關設定
|
||
curl http://localhost:8080/api/bt_setup/run
|
||
```
|
||
|
||
#### 6. **INI 設定讀取/寫入**
|
||
|
||
```bash
|
||
# 讀取目前 INI 設定
|
||
curl http://localhost:8080/api/ini
|
||
|
||
# 修改 INI 並立即套用到裝置(等同 Web UI "Apply to Device + Restart")
|
||
curl -X POST http://localhost:8080/api/ini/apply \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"fec_mode": 4,
|
||
"DrawBoxEnable": 1,
|
||
"voc_enable": 0
|
||
}'
|
||
```
|
||
|
||
常見 INI 參數:
|
||
- `fec_mode`: 0=關閉, 1-5=魚眼校正模式
|
||
- `DrawBoxEnable`: 0/1 — H.264 burn-in 偵測框
|
||
- `voc_enable`: 0/1 — HDMI VOC 輸出
|
||
- `ModelPath`, `ModelId`, `JobId`: 推論模型設定
|
||
|
||
#### 7. **RTSP 串流預覽 / 停止**
|
||
|
||
```bash
|
||
# 啟動 RTSP 預覽(返回 MJPEG 影像串流)
|
||
curl http://localhost:8080/api/stream/video > stream.mjpeg
|
||
|
||
# 停止 RTSP 預覽
|
||
curl -X POST http://localhost:8080/api/stream/stop
|
||
```
|
||
|
||
#### 8. **STDC 推論統計**
|
||
|
||
```bash
|
||
# 查看即時推論統計(幀率、語義分割百分比)
|
||
curl http://localhost:8080/api/stdc/stats
|
||
|
||
# 啟動推論
|
||
curl -X POST http://localhost:8080/api/stdc/start
|
||
|
||
# 停止推論
|
||
curl -X POST http://localhost:8080/api/stdc/stop
|
||
```
|
||
|
||
輸出示例:
|
||
```json
|
||
{
|
||
"frame": 42,
|
||
"mov": 1,
|
||
"diff": 4.2,
|
||
"classes": {
|
||
"bunker": 0.0,
|
||
"car": 8.3,
|
||
"grass": 0.0,
|
||
"greenery": 12.1,
|
||
"person": 0.0,
|
||
"pond": 0.0,
|
||
"road": 71.4,
|
||
"tree": 8.2
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 9. **遠端執行指令(Telnet 到裝置)**
|
||
|
||
```bash
|
||
# 在裝置上執行指令並取得輸出
|
||
curl -X POST http://localhost:8080/api/terminal/exec \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"cmd": "ps | grep firmware"}'
|
||
|
||
# 查看 firmware log
|
||
curl -X POST http://localhost:8080/api/terminal/exec \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"cmd": "cat /tmp/fw.log"}'
|
||
|
||
# 查看可用模型
|
||
curl -X POST http://localhost:8080/api/terminal/exec \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"cmd": "ls -lh /mnt/flash/vienna/nef/"}'
|
||
```
|
||
|
||
#### 10. **開機自動啟動設定**
|
||
|
||
```bash
|
||
# 查看自動啟動腳本設定
|
||
curl http://localhost:8080/api/autostart/read
|
||
|
||
# 寫入自動啟動腳本(`/etc/init.d/S99firmware`)
|
||
curl -X POST http://localhost:8080/api/autostart/write \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"autostart_mode": "rtsp"}' # or "hdmi", "rtsp_hdmi"
|
||
```
|
||
|
||
#### 11. **模型管理**
|
||
|
||
```bash
|
||
# 查看可用模型列表
|
||
curl http://localhost:8080/api/model/list
|
||
|
||
# 切換模型(需要指定 ModelId / JobId)
|
||
curl -X POST http://localhost:8080/api/model \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model_id": "100001",
|
||
"job_id": 1
|
||
}'
|
||
```
|
||
|
||
### 完整工作流示例(指令行完全不用 GUI)
|
||
|
||
```bash
|
||
# 1. 設定網路(Host IP 和 KL630 IP)
|
||
curl -X POST http://localhost:8080/api/config \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"host_ip": "192.168.3.1", "kl630_ip": "192.168.3.10"}'
|
||
|
||
# 2. 編譯
|
||
echo "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Compiling..."
|
||
curl http://localhost:8080/api/compile/run | grep '"kind"' | tail -1
|
||
|
||
# 3. 檢查生成的文件
|
||
echo "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Build files:"
|
||
curl http://localhost:8080/api/files | grep name
|
||
|
||
# 4. 部署到裝置
|
||
echo "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Deploying to KL630..."
|
||
curl http://localhost:8080/api/deploy/run
|
||
|
||
# 5. 查看推論統計
|
||
echo "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> STDC Stats:"
|
||
curl http://localhost:8080/api/stdc/stats | python -m json.tool
|
||
|
||
# 6. 設定魚眼校正(FEC Mode 4)
|
||
curl -X POST http://localhost:8080/api/ini/apply \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"fec_mode": 4}'
|
||
```
|
||
|
||
---
|
||
|
||
## CLI 指令完整參考
|
||
|
||
完全不用瀏覽器,所有操作均可透過指令完成。
|
||
|
||
---
|
||
|
||
### 1. 編譯(交叉編譯 ARM binary)
|
||
|
||
**方法 A — `build_and_serve.py`(推薦)**
|
||
|
||
```bash
|
||
# 完整流程:編譯 + 檢查 binary + 啟動 HTTP server
|
||
python build_and_serve.py
|
||
|
||
# 常用旗標
|
||
python build_and_serve.py --no-build # 跳過編譯,直接 serve(binary 已存在時)
|
||
python build_and_serve.py --no-serve # 只編譯 + 檢查,不啟動 server
|
||
python build_and_serve.py --port 9090 # 指定 HTTP server port(預設 8080)
|
||
python build_and_serve.py --image my-kl630 # 指定 Docker image 名稱
|
||
python build_and_serve.py --no-copy # 不複製到網路資料夾
|
||
python build_and_serve.py --copy-dst /tmp/out # 指定複製目的地
|
||
```
|
||
|
||
**方法 B — 直接 Docker**
|
||
|
||
```bash
|
||
# 建立 Docker image(只需一次)
|
||
docker build -t kl630-dev .
|
||
|
||
# 交叉編譯
|
||
docker run --rm \
|
||
-v "$(pwd):/workspace/kl630_build" \
|
||
kl630-dev \
|
||
bash /workspace/kl630_build/compile.sh
|
||
|
||
# 確認輸出
|
||
ls -lh build/kp_firmware_host_stream
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 啟動 HTTP File Server(裝置 wget 用)
|
||
|
||
```bash
|
||
# 用 build_and_serve.py(推薦,自動 copy INI + deploy.sh)
|
||
python build_and_serve.py --no-build --no-check --port 8080
|
||
|
||
# 或直接 Python 內建 server
|
||
cd build && python -m http.server 8080
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 部署到裝置(Telnet / 裝置端指令)
|
||
|
||
先確認 HTTP server 在 PC 端已啟動,再 Telnet 進裝置:
|
||
|
||
```bash
|
||
telnet 192.168.3.10
|
||
```
|
||
|
||
在裝置端執行:
|
||
|
||
```sh
|
||
# 一鍵下載並部署(最常用)
|
||
wget http://192.168.3.1:8080/deploy.sh -O /tmp/deploy.sh && sh /tmp/deploy.sh
|
||
|
||
# 或分步驟手動執行:
|
||
|
||
# 停止舊 firmware
|
||
killall -9 kp_firmware_host_stream 2>/dev/null; killall -9 rtsps 2>/dev/null
|
||
sleep 1; rm -f /dev/shm/*
|
||
|
||
# 下載 binary 和 INI
|
||
wget http://192.168.3.1:8080/kp_firmware_host_stream -O /mnt/flash/vienna/kp_firmware_host_stream
|
||
chmod +x /mnt/flash/vienna/kp_firmware_host_stream
|
||
wget http://192.168.3.1:8080/host_stream.ini -O /mnt/flash/plus/kp_firmware/kp_firmware_0/kp_firmware/bin/ini/host_stream.ini
|
||
|
||
# 下載並啟動 RTSP demo
|
||
wget http://192.168.3.1:8080/demo_rtsp.sh -O /mnt/flash/plus/kp_firmware/kp_firmware_0/kp_firmware/bin/ini/demo_rtsp.sh
|
||
chmod +x /mnt/flash/plus/kp_firmware/kp_firmware_0/kp_firmware/bin/ini/demo_rtsp.sh
|
||
cd /mnt/flash/plus/kp_firmware/kp_firmware_0/kp_firmware/bin
|
||
sh ./ini/demo_rtsp.sh
|
||
```
|
||
|
||
**新機器一次性 ISP 設定**(只需跑一次):
|
||
|
||
```sh
|
||
wget http://192.168.3.1:8080/deploy.sh -O /tmp/deploy.sh && sh /tmp/deploy.sh --setup
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 裝置端常用指令
|
||
|
||
```sh
|
||
# 確認 firmware 是否在跑
|
||
ps | grep firmware
|
||
|
||
# 查看 firmware log
|
||
cat /tmp/fw.log
|
||
tail -f /tmp/fw.log # 持續監看(BusyBox 無 -f,用 watch 替代)
|
||
|
||
# 查看 RTSP demo log
|
||
cat /tmp/rtsp_demo.log
|
||
|
||
# 手動停止 firmware
|
||
killall -9 kp_firmware_host_stream
|
||
killall -9 rtsps
|
||
|
||
# 直接啟動(指定模型)
|
||
BIN_DIR=/mnt/flash/plus/kp_firmware/kp_firmware_0/kp_firmware/bin
|
||
FW=/mnt/flash/vienna/kp_firmware_host_stream
|
||
LD_LIBRARY_PATH=/mnt/flash/vienna/lib $FW \
|
||
-m nef/stdc_scnn_fp.nef \
|
||
-i 100001 -j 1 &
|
||
|
||
# 切換輸出模式(不用重新 deploy)
|
||
sh $BIN_DIR/ini/demo_rtsp.sh # RTSP 串流
|
||
sh $BIN_DIR/ini/demo_hdmi.sh # HDMI 顯示
|
||
sh $BIN_DIR/ini/demo_rtsp_hdmi.sh # RTSP + HDMI 同時
|
||
```
|
||
|
||
---
|
||
|
||
### 5. INI 設定(指令修改)
|
||
|
||
直接用 `sed` 修改裝置上的 INI,不需要重新 deploy:
|
||
|
||
```sh
|
||
INI=/mnt/flash/plus/kp_firmware/kp_firmware_0/kp_firmware/bin/ini/host_stream.ini
|
||
|
||
# 開啟 / 關閉魚眼校正 FEC
|
||
sed -i 's/^fec_mode.*/fec_mode = 4/' $INI # Mode 4(180° Two Direction)
|
||
sed -i 's/^fec_mode.*/fec_mode = 0/' $INI # 關閉
|
||
|
||
# 開啟 / 關閉 DrawBox(H.264 burn-in 框)
|
||
sed -i 's/^DrawBoxEnable.*/DrawBoxEnable = 1/' $INI
|
||
sed -i 's/^DrawBoxEnable.*/DrawBoxEnable = 0/' $INI
|
||
|
||
# 開啟 HDMI / VOC 輸出
|
||
sed -i 's/^voc_enable.*/voc_enable = 1/' $INI
|
||
|
||
# 查看目前設定
|
||
grep -E "fec_mode|DrawBoxEnable|voc_enable|ModelPath|ModelId" $INI
|
||
```
|
||
|
||
修改 INI 後需重啟 firmware 才生效:
|
||
|
||
```sh
|
||
killall -9 kp_firmware_host_stream 2>/dev/null
|
||
sh /mnt/flash/plus/kp_firmware/kp_firmware_0/kp_firmware/bin/ini/demo_rtsp.sh
|
||
```
|
||
|
||
---
|
||
|
||
### 6. Mock Server(事件測試)
|
||
|
||
```bash
|
||
# 啟動 mock server(port 8081)
|
||
python tools/mock_server/server.py
|
||
|
||
# 開啟監控網頁
|
||
# http://localhost:8081/
|
||
```
|
||
|
||
用 `curl` 送測試事件(不用開網頁):
|
||
|
||
```bash
|
||
# Channel A — 送即時事件(HTTP)
|
||
curl -X POST http://localhost:8081/api/event \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"response_type":"violation","content":{"id":"1","date":"2025-01-01T00:00:00+08:00","type":"road","level":2}}'
|
||
|
||
# 常用事件類型:road / grass / hazard / person / bunker / pond / tree / car
|
||
# level:0=解除, 1=警告, 2=嚴重, 3=緊急
|
||
|
||
# 查詢事件列表
|
||
curl http://localhost:8081/api/events
|
||
|
||
# Channel C — 送 CAN 事件(測試 CAN bus TX)
|
||
curl -X POST http://localhost:8081/api/can/send \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"type":"hazard","level":1,"can_id":256}'
|
||
|
||
# 送油門控制指令(CAN ID 0x75)
|
||
curl -X POST http://localhost:8081/api/can/send_cmd \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"cmd":128,"can_id":117}' # cmd: 0=關閉, 32/64/128/255=油門檔位
|
||
|
||
# 查詢 CAN bus 狀態
|
||
curl http://localhost:8081/api/can/status
|
||
|
||
# 啟動 CAN interface(等同 UI Bring Up 按鈕)
|
||
curl -X POST http://localhost:8081/api/can/bringup \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"channel":"can0","bitrate":250000}'
|
||
```
|
||
|
||
---
|
||
|
||
## BLE 指令協議(藍牙通訊)
|
||
|
||
KL630 透過 DX-BT24 模組(UART `/dev/ttyS1` @ 115200)與 iPad / 手機 app 溝通。
|
||
所有訊息均為 UTF-8 JSON,無需 CRLF。
|
||
|
||
---
|
||
|
||
### Command(App → KL630)
|
||
|
||
#### 狀態確認
|
||
```json
|
||
{"command":"status_check"}
|
||
```
|
||
回傳 Notify:`response_type=status_check`
|
||
|
||
#### 查詢租借狀態
|
||
```json
|
||
{"command":"get_rent_status"}
|
||
```
|
||
回傳 Notify:`response_type=rent_status`
|
||
|
||
#### 租借
|
||
```json
|
||
{"command":"rent"}
|
||
```
|
||
若目前 status=0 則轉為 1,其他狀態忽略。回傳 Notify:`response_type=rent_status`
|
||
|
||
#### 歸還
|
||
```json
|
||
{"command":"return"}
|
||
```
|
||
若目前 status=1 則轉為 0,其他狀態忽略。回傳 Notify:`response_type=rent_status`
|
||
|
||
---
|
||
|
||
### Notify(KL630 → App)
|
||
|
||
#### 系統狀態(回應 status_check)
|
||
```json
|
||
{"response_type":"status_check","content":{"ares_x_version":"1.0.0","bluetooth_peripheral_name":"BT-24","is_intervention_cart_control":false}}
|
||
```
|
||
|
||
| 欄位 | 說明 |
|
||
|------|------|
|
||
| `ares_x_version` | 韌體版本,由 INI `event:ares_version` 設定 |
|
||
| `bluetooth_peripheral_name` | BLE 掃描名稱,由 INI `event:bt_name` 設定 |
|
||
| `is_intervention_cart_control` | 是否正在介入車輛控制(CAN bus 活動中)|
|
||
|
||
#### 租借狀態(回應 rent / return / get_rent_status)
|
||
```json
|
||
{"response_type":"rent_status","content":{"status":0}}
|
||
```
|
||
|
||
| status | 說明 |
|
||
|--------|------|
|
||
| `0` | 未租借 |
|
||
| `1` | 租借中 |
|
||
| `2` | 管理模式 |
|
||
|
||
#### 違規事件(由推論結果觸發)
|
||
```json
|
||
{"response_type":"violation","content":{"id":"abcd-1234-0000-0000","date":"2025-12-08T06:08:49Z","type":"lane","level":2}}
|
||
```
|
||
|
||
| level | 說明 |
|
||
|-------|------|
|
||
| `0` | 解除 |
|
||
| `1` | 違規發生 |
|
||
| `2` | 違規持續 6 秒 |
|
||
| `3` | 違規持續 10 秒 |
|
||
|
||
#### 危險區域警告
|
||
```json
|
||
{"response_type":"alert","content":{"left_level":0,"right_level":1}}
|
||
```
|
||
左右各獨立,`0`=無危險,`1`=有危險。
|
||
|
||
---
|
||
|
||
### INI 設定(`ini/host_stream.ini` `[event]` 區段)
|
||
|
||
```ini
|
||
bt_uart_dev = /dev/ttyS1 # UART 裝置路徑
|
||
bt_at_probe = 0 # 0: 正常啟動;1: 首次設定(9600→115200 升速)
|
||
ares_version = 1.0.0 # 韌體版本字串
|
||
bt_name = BT-24 # BLE 掃描名稱
|
||
```
|
||
|
||
---
|
||
|
||
### 測試指令
|
||
|
||
#### 用 BLE app(nRF Connect 等)直接測試
|
||
|
||
複製以下 JSON 貼入 Write Characteristic 欄位送出:
|
||
|
||
```
|
||
{"command":"status_check"}
|
||
```
|
||
```
|
||
{"command":"get_rent_status"}
|
||
```
|
||
```
|
||
{"command":"rent"}
|
||
```
|
||
```
|
||
{"command":"return"}
|
||
```
|
||
|
||
#### 用 Mock Server 模擬裝置回傳(curl)
|
||
|
||
```bash
|
||
# 模擬違規事件通知
|
||
curl -X POST http://localhost:8081/api/event \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"response_type":"violation","content":{"id":"test-001","date":"2026-04-22T00:00:00Z","type":"lane","level":1}}'
|
||
|
||
# 模擬違規持續 6 秒
|
||
curl -X POST http://localhost:8081/api/event \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"response_type":"violation","content":{"id":"test-001","date":"2026-04-22T00:00:00Z","type":"lane","level":2}}'
|
||
|
||
# 模擬違規解除
|
||
curl -X POST http://localhost:8081/api/event \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"response_type":"violation","content":{"id":"test-001","date":"2026-04-22T00:00:00Z","type":"lane","level":0}}'
|
||
|
||
# 模擬危險區域警告(右側有危險)
|
||
curl -X POST http://localhost:8081/api/event \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"response_type":"alert","content":{"left_level":0,"right_level":1}}'
|
||
|
||
# 模擬租借狀態更新
|
||
curl -X POST http://localhost:8081/api/event \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"response_type":"rent_status","content":{"status":1}}'
|
||
|
||
# 查看目前所有事件記錄
|
||
curl http://localhost:8081/api/events
|
||
```
|
||
|
||
---
|
||
|
||
## Firmware 執行結果(console log)
|
||
|
||
```
|
||
[STDC] frame=42 mov=1 diff=4.2 bunker=0.0% car=8.3% grass=0.0% greenery=12.1% person=0.0% pond=0.0% road=71.4% tree=8.2%
|
||
[STDC] ON ROAD
|
||
[STDC WARN] CAR 8.3%
|
||
```
|
||
|
||
---
|
||
|
||
## 詳細說明
|
||
|
||
IMX662 DOL-HDR 雙曝光設定、STDC 語義分割架構、新裝置部署 SOP、故障排查:
|
||
|
||
**[`docs/technical_report.md`](docs/technical_report.md)**
|