docs/skills-development.md
🧩 動作判斷包開發 (Skills Development)
「動作判斷包(Skill)」是 RenUniversal 最小的姿態判定單元。系統的 ActionEngine 於運行時動態掃描 skills/ 目錄,自動載入並執行每個判斷包。本文件說明如何開發自己的技能。
1. 目錄結構
每個技能是 skills/ 下的一個獨立子目錄:
skills/
└── <your_skill_name>/
├── config.json # 必要:宣告規則、描述與預設參數
└── logic.py # 選用:自訂判定邏輯(含 ActionDetector 類別)
| 檔案 | 是否必要 | 說明 |
|---|---|---|
config.json |
✅ | 技能宣告檔,定義名稱、規則與預設偏好 |
logic.py |
⬜ | 進階自訂邏輯;省略時系統自動套用通用幾何偵測器 |
2. 兩種開發路徑
RenUniversal 提供兩條路徑,視你的需求選擇:
| 🟢 無程式碼(推薦) | 🔵 進階程式碼 | |
|---|---|---|
需要 logic.py |
否 | 是 |
| 判定核心 | GenericActionDetector |
你自訂的 ActionDetector |
| 點位寫法 | f<n> / p<n> 數字語法 |
數字語法或別名(nose, chin…) |
| 運算子 | [x/y]?>< [x/y]?<> [x/y]?>><< ~~ + AND/OR/NOT |
自由,可用內建特徵鍵 |
| 適合場景 | 絕大多數兩點距離/越界判定 | 需要遲滯濾波、複合特徵或客製數學 |
3. 路徑 A:無程式碼(config.json + rule_syntax)
只需提供 config.json 並填寫 rule_syntax,系統即以 GenericActionDetector 自動判定。這是建議的預設做法。
{
"name": "slouch",
"description": "鼻子、下巴檢測縮短(低頭)",
"enabled": true,
"requirements": { "face_mesh": true, "pose": false },
"rule_syntax": "f1,f152 >< num=20%",
"default_preferences": { "slouch_threshold": 0.2 }
}
| 欄位 | 說明 |
|---|---|
name |
技能識別名(亦作為 metric/事件引用名) |
description |
人類可讀描述 |
enabled |
是否啟用;false 則略過載入 |
requirements |
感測需求,如 { "face_mesh": true, "pose": true } |
rule_syntax |
規則字串,語法見 規則語法參考 |
default_preferences |
預設門檻,會注入全域偏好供 slider 調整 |
此路徑的點位僅支援
f<n>/p<n>數字寫法(如f1、p11),不支援文字別名。完整運算子與事件組合請見 規則語法參考。
4. 路徑 B:進階自訂 logic.py
當你需要遲滯濾波(hysteresis)、多特徵複合判定或自訂數學時,新增 logic.py 並實作 ActionDetector 類別。可直接參考或繼承 backend/core/skill_template.py。
from typing import Tuple, Dict, Any
class ActionDetector:
def __init__(self, config: Dict[str, Any]):
self.config = config
def evaluate(self,
face_landmarks: Any,
pose_landmarks: Any,
face_dim: Tuple[int, int],
body_dim: Tuple[int, int],
baselines: Dict[str, float],
preferences: Dict[str, Any],
state_history: Dict[str, Any]) -> Tuple[bool, float, Dict[str, Any]]:
"""
評估當前訊號是否觸發此技能。
參數:
- face_landmarks / pose_landmarks : MediaPipe 臉部與身體地標
- face_dim / body_dim : (width, height) 解析度
- baselines : 校準基準值(eye_distance、nose_chin_distance、
shoulder_width、shoulder_midpoint_x/y…)
- preferences : 全域使用者偏好(含各門檻)
- state_history : 上一輪狀態(如 is_bad_posture,可用於遲滯)
回傳:
- is_bad (bool) : 是否判定觸發
- primary_val (float) : 主要特徵值(供前端圖表)
- info (dict) : 額外診斷資訊(回傳前端顯示)
"""
...
內建特徵鍵 (Built-in Feature Keys)
若以 skill_template.py 為基礎,可直接取用其預先計算的特徵,並用結構化規則(dict 格式)比較:
| 特徵鍵 | 意義 |
|---|---|
nose_chin_ratio |
低頭比例(正常 0.0,前傾時為負值,內建轉頭容差與遲滯) |
torso_sway |
軀幹水平搖晃比 |
torso_lean |
軀幹前傾比 |
shoulder_slope |
肩部傾斜斜率 |
yaw_deviation |
頭部左右偏轉比 |
結構化規則範例(運算子支援 > < >= <= ==):
{
"name": "lean",
"description": "軀幹前傾判定模組",
"enabled": true,
"requirements": { "pose": true },
"rules": [
{ "feature": "torso_lean", "operator": ">", "threshold_key": "lean_threshold" }
],
"default_preferences": { "lean_threshold": 0.12 }
}
skill_template的字串規則路徑另支援文字別名(nose,chin,left_eye,right_eye,left_shoulder,right_shoulder),這是 Generic 路徑所沒有的。
5. 熱載入與註冊流程
- 掃描:啟動或呼叫 reload 時,
action_engine.py掃描skills/*/config.json。 - 派發:有
logic.py→ 載入其ActionDetector;無 → 套用GenericActionDetector。 - 注入偏好:
default_preferences併入全域設定,供 Web slider 即時調參。 - 前端控制:
/api/skills系列端點可動態建立、開關、修改與刪除技能,變更後自動 reload。