20 Commits

Author SHA1 Message Date
vee 772ab685d6 feat(web-console): refine intelligent cockpit sync interface 2026-08-19 08:36:38 +08:00
vee 9b24d5c8c9 feat(web-console): rebuild intelligent cockpit sync interface 2026-08-18 13:24:36 +08:00
vee 344f662970 feat(web-console): add personalized seat weighing evolution 2026-08-14 15:53:08 +08:00
vee f77dda70fe update 2026-08-14 15:01:29 +08:00
vee 6d768aaef4 update model 2026-08-14 11:17:17 +08:00
vee 1a96d39426 feat: default users to safe virtual CAN execution 2026-08-14 09:56:22 +08:00
vee 0ec43052f3 feat: refine vehicle console and self-repair workflow 2026-08-13 17:49:37 +08:00
vee fd3c219c39 feat: integrate safer vehicle CAN reasoning 2026-08-12 22:50:55 +08:00
vee 9ce64b3a01 feat: complete dual-seat whole-vehicle orchestration 2026-08-12 15:12:40 +08:00
vee 32379a1573 feat: synchronize CH1 vehicle control and feedback 2026-08-11 10:42:13 +08:00
vee 3701192a11 feat: validate real-bench seat orchestration and self-repair 2026-08-09 19:00:16 +08:00
vee 3bceb0d5a1 feat: integrate calibration extension and self-repair modules 2026-08-07 23:39:45 +08:00
vee 156b10fda1 feat: refactor vehicle and gesture control console 2026-08-07 09:18:17 +08:00
vee dc7c91800e feat: integrate cabin CAN and verified dynamic seat modes 2026-08-04 17:51:38 +08:00
vee 155fbb59ba docs: describe hardware approval gateway 2026-08-03 10:25:05 +08:00
vee a952f37ceb feat: add local hardware approval leases 2026-08-03 10:20:55 +08:00
vee 85b4740d29 feat: serialize public hardware execution 2026-08-03 09:25:38 +08:00
vee a6d974cb29 feat: tolerate recoverable seat intent inputs 2026-08-02 06:12:36 +08:00
vee 55d0d400cb feat: harden seat intent and expand HIL coverage 2026-08-02 05:20:38 +08:00
vee 4aded5c21d feat: update CAN integration and T2G seat firmware 2026-08-01 15:55:21 +08:00
1662 changed files with 1161107 additions and 5668 deletions
+21
View File
@@ -4,4 +4,25 @@
__pycache__/
*.py[cod]
artifacts/runs/
artifacts/server/
artifacts/tmp/
artifacts/self-repair/
artifacts/*.log
tmp/*.log
.codex_tmp/
firmware/t2g/Seat_Controller_demo/Tests/manual_hil/logs/
firmware/t2g/Seat_Controller_demo/Tests/manual_hil/seat_function_runtime/
tools/zcan/seat_function_runtime/
artifacts/hil/*_server_*.log
artifacts/hil/frontend_service_*.log
tmp/can-matrix-artifact/
tmp/reference-project-code-CAN_DEV/
firmware/t2g/Seat_Controller_demo/IAR/settings/
firmware/t2g/Seat_Controller_demo/IAR/Seat_Controller_demo.eww
firmware/t2g/Seat_Controller_demo/IAR/rev_d/.Seat_Controller_demo_build_cache
firmware/t2g/Seat_Controller_demo/IAR/rev_d/.ninja_deps
firmware/t2g/Seat_Controller_demo/IAR/rev_d/.ninja_log
firmware/t2g/Seat_Controller_demo/IAR/rev_d/BrowseInfo/
firmware/t2g/Seat_Controller_demo/IAR/rev_d/List/
firmware/t2g/Seat_Controller_demo/IAR/rev_d/Obj/
firmware/t2g/tviibh8m/src/examples/crypto/ClientRunsOnCM7_0/RSA/key_data/private_key*.pem
+5 -3
View File
@@ -77,9 +77,11 @@ artifacts/runs/<request_id>/
## 可执行领域
座椅与空调等车身设备使用同一 ZLG CAN 盒双通道联动时,参见 [T2G 座椅与车身双通道 CAN 联动](docs/workflows/t2g-cabin-dual-channel-can.md)。
当前已接入四个相互隔离的可执行领域:
- 座椅:基于 `座椅部分功能CAN矩阵表.xlsx` 的主/副驾通风和加热,以及明确标识为 synthetic 的五轴位置电机演示。
- 座椅:所有热管理、位置移动和姿态预设能力仅面向副驾;未指定座位时默认副驾,显式主驾请求拒绝执行。
- 空调:基于 `空调-天幕-氛围灯CAN信号矩阵表.xlsx` 的电源、18–32℃ 分区温度、0–7 档风量、A/C、内外循环、风向和前除霜。
- 天幕:基于同一矩阵的 0–100% 透光率、后遮阳帘绝对位置和自动调光。
- 氛围灯:基于同一矩阵的总开关、24-bit RGB、0–100% 亮度和 ECU 场景模式。
@@ -92,7 +94,7 @@ make test
make dev
```
浏览器访问 `http://127.0.0.1:8000`。设置 `OPENAI_API_KEY` 后,GPT Structured Outputs 会基于各领域的 `config/capabilities.yaml` 和当前会话状态直接生成通用能力请求;后端只做结构校验、领域路由和确定性执行适配,不用本地语义规则改写 GPT 动作。本地解析器仅是未配置 GPT 或 `auto` 模式调用失败时的显式降级路径。模型由 `OPENAI_MODEL=gpt-5.6-sol` 指定;兼容 OpenAI Responses API 的服务可通过 `OPENAI_BASE_URL` 指定。无论使用哪种解析器,配置校验、CAN 编译和虚拟执行均为同一确定性路径。
浏览器访问 `http://127.0.0.1:8000`。设置 `OPENAI_API_KEY` 后,GPT Structured Outputs 会基于各领域的 `config/capabilities.yaml` 和当前会话状态直接生成通用能力请求;后端只做结构校验、领域路由和确定性执行适配,不用本地语义规则改写 GPT 动作。本地解析器用于未配置 GPT,或 GPT/`auto` 模式因 API Key、模型权限、网络或结构化响应异常而失败时的安全降级;结果会明确标记 `local_rules_fallback`。模型由 `OPENAI_MODEL=gpt-5.6-sol` 指定;兼容 OpenAI Responses API 的服务可通过 `OPENAI_BASE_URL` 指定。无论使用哪种解析器,配置校验、CAN 编译和虚拟执行均为同一确定性路径。
### 一句话、快捷模式与手势控制
@@ -134,4 +136,4 @@ PYTHONPATH=src python -m cognitive_agent.auth generate-secret
完整能力边界、矩阵解释和验收用例见 [座椅阶段一交付](docs/workflows/seat-stage1-delivery.md)。
已验证的 T2G 加热、通风和四电机能力已合并到仓库内 `firmware/t2g/Seat_Controller_demo`,并提供一条默认锁定的真实 HIL 路径。主驾与副驾目前映射到同一物理座椅;硬件请求会先做固件身份握手,可在明确启用后通过 IAR C-SPY 自动烧录,再发送 CAN 并等待真实回读。固件拓扑、IAR 构建、ZLG 32 位 bridge、CAN 接线、安全门禁和上电步骤见 [T2G 座椅真实硬件台架接入](docs/workflows/t2g-seat-hardware-bench.md)。
已验证的 T2G 加热、通风、四电机和原生动态模式能力已完整纳入 `firmware/t2g`,包括 IAR 工程及仓库内 `common/tviibh8m` 构建依赖。M0/M1/M2/M3 分别对应水平、坐盆、靠背和腿托;revision 13通过`0x306`反馈带斜向耦合补偿的木马模式与四轴全程联动动态摇篮的阶段/循环状态。木马模式围绕中间姿态在`[270,250,460,400]`和`[370,130,540,460]`之间连续俯仰往复:坐盆峰峰行程120 Hall、约18 mm垂直分量,水平峰峰行程100 Hall、90%巡航Duty,用额外水平行程抵消坐盆斜向运动约16.4 mm的反向水平分量;参数集中在`seat_dynamic_mode_config.h`并由N7长期库镜像。动态模式收到一次启动命令后由ECU连续循环,收到停止/全停命令或累计运行10分钟时停止;目标到位式阶段在底层堵转/无运动保护继续生效的前提下使用独立保护窗口。真实硬件请求先被动核对新版周期反馈与 480/374/917/647 Hall 量程,未检测到匹配固件时默认通过 IAR C-SPY 自动烧写并复验,再发送 CAN 并等待真实回读。当前前端、能力注册、编译、安全门禁和状态反馈只允许副驾 `passenger/front_right`;固件中的 `Driver_Seat_*` 仅是板端既有协议字段名。构建、ZLG bridge、接线、安全门禁、前端测试集和已知量程归零见 [T2G 座椅真实硬件台架接入](docs/workflows/t2g-seat-hardware-bench.md) 与 [前端能力测试集](docs/testing/t2g-seat-frontend-test-suite.md)。
+51 -7
View File
@@ -1,13 +1,15 @@
# Web Console
Web 控制台提供一句话、快捷功能模式与手势控制入口,不在浏览器中生成 CAN。所有动作统一提交给后端编排、配置校验、安全门禁和执行链路。
Web 控制台是车机端的远程自编排与同步显示界面。网页保留一句话指令和预设功能模式入口,请求通过同源服务发送至车机执行;同时同步显示车机任务、编排结果、设备反馈和 USB 扩展能力。真实 CAN 与硬件执行权限仍由服务端安全门禁控制。
当前页面包括:
- 一句话联动座椅、空调、天幕和氛围灯,支持 Enter 执行和 GPT/本地规则切换。
- 观影、午休、零重力快捷模式,以及当前副驾驶姿态的命名保存入口。
- 六阶段执行链路、整车联合孪生、领域状态、配置、CAN 计划和执行结果。
- 右侧手势控制抽屉,包含摄像头画面、关键点骨架、保持进度、动作速查与自定义映射。
- 自编排和自扩展合并为一个实时界面,登录身份固定为 `user`,不再提供模块切换。
- 网页端可输入一句话指令或点击预设模式,车机端同样可发起任务;两端任务与结果统一同步。
- 整车数字孪生位于工作区中央,点击或悬停热点可查看车窗、遮阳帘、主/副驾座椅、阅读灯、氛围灯、前大灯和空调的完整状态。
- 车端设备状态与外设能力板块均可独立隐藏或恢复,面板状态在当前浏览器会话中保留。
- USB 外设接入后同步显示 GSCU 链路、外设名称、类型、已学习能力和最近一次跨设备联动。
- 左侧运行日志集中显示网页/车机任务、链路、设备与外设同步事件。
UI 只展示可审计的“决策摘要”和“处理轨迹”,不展示模型私有思维过程。
@@ -17,6 +19,20 @@ UI 只展示可审计的“决策摘要”和“处理轨迹”,不展示模
make dev
```
Android PAD/模拟器联调使用:
```powershell
powershell -ExecutionPolicy Bypass -File .\tools\android_pad_dev.ps1
```
脚本会启动已配置的 Pixel Tablet AVD、建立 `adb reverse tcp:8000 tcp:8000`、
以真实硬件关闭/模拟台架开启的方式启动服务,并在 Android Chrome 中打开
`http://127.0.0.1:8000`。停止联调环境:
```powershell
powershell -ExecutionPolicy Bypass -File .\tools\android_pad_dev.ps1 -Stop
```
局域网演示使用:
```bash
@@ -25,13 +41,32 @@ make dev-lan
其他设备访问启动日志打印的 `http://<LAN-IP>:8000`。页面与后端 API 由同一服务提供,无需单独配置前端地址。
自扩展接口统一位于 `/api/extension/*`,GSCU1B 默认以 TCP 模式监听
`0.0.0.0:4444`。可通过 `GSCU_TRANSPORT=simulation` 使用演示学习器,或通过
`GSCU_TRANSPORT=mqtt` 与 `GSCU_MQTT_*` 配置接入 MQTT。MQTT 依赖可通过
项目的 `ir` 可选依赖安装。自扩展不再需要独立的 `8010` 前端服务。
TCP 模式下本服务是服务器,GSCU1B 是客户端:设备配网页中的“TCP服务器”
必须填写运行本服务的主机地址,“TCP端口”必须与 `GSCU_TCP_PORT` 一致。
如需绑定指定网卡地址,可设置 `GSCU_TCP_LISTEN_HOST`;网卡晚于服务就绪或
端口被短暂占用时,监听器会按 `GSCU_TCP_BIND_RETRY_SECONDS`(默认 1 秒)
自动重试。`/api/extension/health` 的 `listening` 表示服务器已监听,只有收到
真实设备会话后 `connected`/`peer_connected` 才会变为 `true`。
车机与网页同步使用以下同源接口:
- `GET /api/vehicle-display-sync`:网页轮询最新车机任务、结果、外设目录与扩展链路状态。
- `POST /api/requests`:车机执行时附带 `client_type: "head_unit"`;网页控制台附带 `client_type: "web_console"`。两类任务的执行结果都会写入同步快照。
- `POST /api/extension/display-sync`:车机刚识别 USB 外设时上报 `device` 与 `peripherals` 能力目录,无需等待首次执行。
- `POST /api/extension/assistant/plan` 和 `/api/extension/vehicle/execute`:联动规划与车端执行结果同样写入同步快照。
公网入口由后端统一认证,前端不保存密码或 API Key。未认证访问自动进入
`/login`,主控制台提供退出按钮。固定入口是
`https://511.kendeji.fun`,应用容器只监听服务器回环地址,再由 Caddy 提供
HTTPS。部署方式见
[`deploy/server/README.md`](../../deploy/server/README.md)。
页面支持 GPT/本地解析切换、六阶段流水线、主副驾热舒适、五轴位置状态和 3D 座椅孪生、GPT 结构化能力请求、决策与校验轨迹、FunctionConfig、CommandPlan、虚拟帧和 ExecutionReport。硬件执行在服务端固定关闭,不是仅靠前端按钮限制。
页面支持 GPT/本地解析切换、六阶段流水线、主副驾热舒适、五轴位置状态和 3D 座椅孪生、GPT 结构化能力请求、决策与校验轨迹、FunctionConfig、CommandPlan、虚拟帧和 ExecutionReport。真实硬件执行由服务端门禁控制,不是仅靠前端按钮限制;Android 联调脚本会显式关闭真实硬件执行。
## 手势资源与安全规则
@@ -42,7 +77,16 @@ assets/gesture/gesture_recognizer.task
../../config/gesture/default.yaml
```
后端提供 `/api/gesture/runtime` 和 `/api/gesture/model`,前端以二进制缓冲区加载模型,避免依赖外部 `seat_gesture_control` 目录。MediaPipe Web 运行时从 jsDelivr 按需加载;摄像头帧和手部关键点只在当前浏览器中处理。
后端提供 `/api/gesture/runtime` 和 `/api/gesture/model`,前端以二进制缓冲区加载模型,避免依赖外部 `seat_gesture_control` 目录。MediaPipe Web、Lucide 和 Three.js 均按固定版本保存在 `vendor/`,运行时不访问外部 CDN;摄像头帧和手部关键点只在当前浏览器中处理。
## PAD、PWA 与离线行为
- 竖屏 PAD 在 900 CSS px 以下切换为上下布局,横屏保留指令栏与结果区;触控目标最小 48 dp,并处理安全区和动态视口。
- 顶部连接徽标由 `/api/health` 周期探测驱动;GET 可有限重试,POST 控制请求不自动重试。
- Service Worker 缓存页面壳、固定版本依赖和按需访问的 3D/手势资源;`/api/requests` 等控制 API 始终走网络且不会写入缓存。
- 从 Android Chrome 的“安装应用”可进入 standalone PWA;首次完整在线加载后可离线打开控制台壳,实际编排仍要求 Windows 服务可达。
模拟台架需要 `COGNITIVE_AGENT_SIMULATED_HARDWARE_ENABLED=true`。选择“模拟台架”后可注入反馈超时、适配器断开、电机堵转、固件不匹配和部分反馈。结果会标记 `simulation=true`、`seat_feedback=simulated_hardware` 和 `physical_can_opened=false`,不会调用真实 CAN、ZLG 或 IAR。
安全规则:张掌保持 1 秒激活;动作保持 600 ms 且至少连续 8 帧才执行;换动作不重新锁止;握拳立即停止但不解除激活;3 秒无有效动作自动锁止;单次连续运动最多 1.5 秒;检测到多只手时不执行。自定义映射保存在浏览器 `localStorage`。
+3344 -290
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+123 -37
View File
@@ -1,6 +1,6 @@
const VISION_VERSION = "0.10.14";
const VISION_MODULE = `https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@${VISION_VERSION}/vision_bundle.mjs`;
const VISION_WASM = `https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@${VISION_VERSION}/wasm`;
const VISION_MODULE = `/vendor/mediapipe/tasks-vision/${VISION_VERSION}/vision_bundle.mjs`;
const VISION_WASM = `/vendor/mediapipe/tasks-vision/${VISION_VERSION}/wasm`;
const CONNECTIONS = [
[0, 1], [1, 2], [2, 3], [3, 4],
@@ -55,6 +55,10 @@ const state = {
customMapping: loadCustomMapping(),
customizeOpen: false,
engine: null,
runtimeReady: false,
cameraStatus: "checking",
cameraMessage: "正在检测摄像头…",
cameraCheckSequence: 0,
};
const $ = (selector) => document.querySelector(selector);
@@ -80,6 +84,91 @@ function notify(message) {
window.setTimeout(() => toast.classList.remove("visible"), 2600);
}
function cameraFailureDetails(error) {
if (!navigator.mediaDevices?.getUserMedia) {
return window.isSecureContext === false
? { status: "unsupported", message: "当前页面不是安全连接,浏览器已阻止摄像头访问" }
: { status: "unsupported", message: "当前浏览器不支持摄像头访问" };
}
switch (error?.name) {
case "NotFoundError":
case "DevicesNotFoundError":
return { status: "unavailable", message: "未检测到可用摄像头" };
case "NotAllowedError":
case "PermissionDeniedError":
case "SecurityError":
return { status: "blocked", message: "摄像头权限被拒绝,请在浏览器设置中允许访问" };
case "NotReadableError":
case "TrackStartError":
return { status: "busy", message: "摄像头正被其他程序占用或暂时不可用" };
case "OverconstrainedError":
case "ConstraintNotSatisfiedError":
return { status: "incompatible", message: "摄像头不支持当前画面参数" };
case "AbortError":
return { status: "unknown", message: "摄像头启动被中断,请重试" };
default:
return { status: "unknown", message: error?.message || "摄像头启动失败" };
}
}
function syncCameraButtonAvailability() {
const button = $("#gestureStartButton");
if (!button || state.stream) return;
button.disabled = !state.runtimeReady
|| ["checking", "unavailable", "unsupported"].includes(state.cameraStatus);
}
function setCameraAvailability(status, message, { announce = true } = {}) {
state.cameraStatus = status;
state.cameraMessage = message;
$("#gestureDrawer")?.setAttribute("data-camera-status", status);
syncCameraButtonAvailability();
if (announce && !state.stream) $("#gestureSafetyText").textContent = message;
}
async function refreshCameraAvailability({ announce = true } = {}) {
if (!navigator.mediaDevices?.enumerateDevices || !navigator.mediaDevices?.getUserMedia) {
const failure = cameraFailureDetails();
setCameraAvailability(failure.status, failure.message, { announce });
return false;
}
const checkSequence = ++state.cameraCheckSequence;
if (!state.stream) setCameraAvailability("checking", "正在检测摄像头…", { announce });
try {
const devices = await navigator.mediaDevices.enumerateDevices();
if (checkSequence !== state.cameraCheckSequence) return state.cameraStatus === "available";
const available = devices.some((device) => device.kind === "videoinput");
setCameraAvailability(
available ? "available" : "unavailable",
available ? "已检测到摄像头,点击开启开始识别" : "未检测到可用摄像头",
{ announce },
);
return available;
} catch (error) {
if (checkSequence !== state.cameraCheckSequence) return state.cameraStatus === "available";
const failure = cameraFailureDetails(error);
const message = failure.status === "blocked"
? "尚未获得摄像头权限,可点击开启并在浏览器中授权"
: "暂时无法检测摄像头,可点击开启时再次确认";
setCameraAvailability("unknown", message, { announce });
return null;
}
}
async function handleCameraDeviceChange() {
const streamWasActive = Boolean(state.stream);
const available = await refreshCameraAvailability({ announce: !streamWasActive });
const streamStillLive = state.stream?.getVideoTracks().some((track) => track.readyState === "live");
if (streamWasActive && (available === false || !streamStillLive)) {
const message = available === false
? "摄像头连接已断开,未检测到其他可用摄像头"
: "当前摄像头连接已断开,请重新开启摄像头";
stopCamera({ message });
notify(message);
}
}
function distance(a, b) {
return Math.hypot(a.x - b.x, a.y - b.y);
}
@@ -386,7 +475,6 @@ function updateEngineUI(engine, message) {
pill.className = `gesture-state-pill ${engine.armed ? (engine.currentAction ? "moving" : "armed") : "idle"}`;
pill.querySelector("b").textContent = engine.armed ? (engine.currentAction ? "执行中" : "已激活") : "已锁止";
$("#gestureSafetyText").textContent = message;
$("#gestureArmButton").textContent = engine.armed ? "已激活" : "激活控制";
}
function executeGestureAction(action) {
@@ -464,7 +552,7 @@ async function recognizeLoop() {
}
async function loadGestureRuntime() {
const response = await fetch("/api/gesture/runtime", { cache: "no-store" });
const response = await window.CognitiveAgentNetwork.request("/api/gesture/runtime", { cache: "no-store" });
if (!response.ok) throw new Error("无法读取手势能力配置");
state.runtime = await response.json();
state.engine = new GestureEngine(state.runtime.safety, executeGestureAction);
@@ -477,7 +565,10 @@ async function loadRecognizer() {
$("#gestureSafetyText").textContent = "正在加载手势模型…";
const { FilesetResolver, GestureRecognizer } = await import(VISION_MODULE);
const fileset = await FilesetResolver.forVisionTasks(VISION_WASM);
const modelResponse = await fetch("/api/gesture/model", { cache: "force-cache" });
const modelResponse = await window.CognitiveAgentNetwork.request("/api/gesture/model", {
cache: "force-cache",
timeoutMs: 60000,
});
if (!modelResponse.ok) throw new Error("内置手势模型加载失败");
const modelAssetBuffer = new Uint8Array(await modelResponse.arrayBuffer());
state.recognizer = await GestureRecognizer.createFromOptions(fileset, {
@@ -494,6 +585,8 @@ async function startCamera() {
const button = $("#gestureStartButton");
button.disabled = true;
button.querySelector("span").textContent = "正在启动…";
button.setAttribute("aria-label", "正在启动摄像头");
button.setAttribute("title", "正在启动摄像头");
try {
if (!state.runtime) await loadGestureRuntime();
await loadRecognizer();
@@ -501,27 +594,30 @@ async function startCamera() {
video: { width: { ideal: 1280 }, height: { ideal: 720 }, facingMode: "user" },
audio: false,
});
setCameraAvailability("available", "摄像头可用,点击开启开始识别", { announce: false });
const video = $("#gestureVideo");
video.srcObject = state.stream;
await video.play();
$("#gestureCameraEmpty").hidden = true;
$("#gestureLiveBadge").hidden = false;
$("#gestureArmButton").disabled = false;
$("#gestureStopButton").disabled = false;
button.classList.add("active");
button.querySelector("span").textContent = "关闭摄像头";
button.setAttribute("aria-label", "关闭摄像头");
button.setAttribute("title", "关闭摄像头");
$("#gestureSafetyText").textContent = "张开手掌并保持 1 秒以激活";
state.frameRequest = requestAnimationFrame(recognizeLoop);
} catch (error) {
$("#gestureSafetyText").textContent = error.message || "摄像头启动失败";
notify(error.message || "摄像头启动失败");
stopCamera();
const failure = cameraFailureDetails(error);
setCameraAvailability(failure.status, failure.message, { announce: false });
stopCamera({ message: failure.message });
notify(failure.message);
} finally {
button.disabled = false;
syncCameraButtonAvailability();
}
}
function stopCamera() {
function stopCamera({ message = null } = {}) {
if (state.frameRequest) cancelAnimationFrame(state.frameRequest);
state.frameRequest = null;
state.stream?.getTracks().forEach((track) => track.stop());
@@ -533,15 +629,17 @@ function stopCamera() {
canvas?.getContext("2d")?.clearRect(0, 0, canvas.width, canvas.height);
$("#gestureCameraEmpty").hidden = false;
$("#gestureLiveBadge").hidden = true;
$("#gestureArmButton").disabled = true;
$("#gestureStopButton").disabled = true;
const button = $("#gestureStartButton");
button.classList.remove("active");
button.querySelector("span").textContent = "开启摄像头";
button.setAttribute("aria-label", "开启摄像头");
button.setAttribute("title", "开启摄像头");
state.engine?.setArmed(false);
$("#gestureDetected").textContent = "—";
$("#gestureExpected").textContent = "等待启动";
$("#gestureSafetyText").textContent = "摄像头尚未开启";
$("#gestureSafetyText").textContent = message || state.cameraMessage || "摄像头尚未开启";
syncCameraButtonAvailability();
}
function toggleCamera() {
@@ -613,45 +711,33 @@ function closeDrawer() {
document.body.classList.remove("gesture-open");
}
function initModeRail() {
document.querySelectorAll("[data-mode-command]").forEach((button) => button.addEventListener("click", () => {
window.CognitiveAgentConsole?.executeUtterance?.(button.dataset.modeCommand, { autoSubmit: true });
}));
$("#saveModeToggle")?.addEventListener("click", () => {
const composer = $("#saveModeComposer");
composer.hidden = !composer.hidden;
if (!composer.hidden) $("#saveModeName").focus();
});
$("#saveModeConfirm")?.addEventListener("click", () => {
const name = $("#saveModeName").value.trim();
if (!name) return notify("请先输入模式名称");
window.CognitiveAgentConsole?.executeUtterance?.(`将当前副驾驶座椅姿态保存为${name}模式`, { autoSubmit: true });
$("#saveModeComposer").hidden = true;
$("#saveModeName").value = "";
});
}
document.addEventListener("DOMContentLoaded", async () => {
$("#gestureStartButton").disabled = true;
$("#gestureToggleButton")?.addEventListener("click", openDrawer);
$("#gestureCloseButton")?.addEventListener("click", closeDrawer);
$("#gestureBackdrop")?.addEventListener("click", closeDrawer);
$("#gestureStartButton")?.addEventListener("click", toggleCamera);
$("#gestureArmButton")?.addEventListener("click", () => state.engine?.setArmed(!state.engine.armed));
$("#gestureStopButton")?.addEventListener("click", () => state.engine?.setArmed(false));
$("#gestureCustomizeButton")?.addEventListener("click", toggleCustomize);
$("#gestureBindButton")?.addEventListener("click", bindCurrentGesture);
$("#gestureResetMapping")?.addEventListener("click", resetMapping);
document.addEventListener("keydown", (event) => {
if (event.key === "Escape" && $("#gestureDrawer")?.classList.contains("open")) closeDrawer();
if (event.key !== "Escape") return;
if ($("#gestureDrawer")?.classList.contains("open")) closeDrawer();
});
document.addEventListener("visibilitychange", () => { if (document.hidden && state.stream) stopCamera(); });
window.addEventListener("beforeunload", stopCamera);
initModeRail();
navigator.mediaDevices?.addEventListener?.("devicechange", handleCameraDeviceChange);
let runtimeError = null;
try {
await loadGestureRuntime();
$("#gestureSafetyText").textContent = state.runtime.available ? "能力就绪,开启摄像头开始识别" : "内置手势模型不可用";
state.runtimeReady = Boolean(state.runtime.available && state.runtime.model_available);
if (!state.runtimeReady) runtimeError = new Error("内置手势模型不可用");
} catch (error) {
$("#gestureSafetyText").textContent = error.message;
$("#gestureStartButton").disabled = true;
runtimeError = error;
state.runtimeReady = false;
}
await refreshCameraAvailability({ announce: !runtimeError });
if (runtimeError) $("#gestureSafetyText").textContent = runtimeError.message;
syncCameraButtonAvailability();
});
+39
View File
@@ -0,0 +1,39 @@
:root { color-scheme: dark; font-family: Inter, "Microsoft YaHei", system-ui, sans-serif; background: #070b12; color: #edf4ff; }
* { box-sizing: border-box; }
body { margin: 0; min-height: 100vh; background: radial-gradient(circle at 18% 0%, #17294b 0, transparent 35%), #070b12; }
.shell { width: min(1040px, calc(100% - 40px)); margin: 0 auto; padding: 54px 0 80px; }
header, .section-title, .policy, .request, .lease-details { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
header { margin-bottom: 34px; }
h1, h2, p { margin: 0; }
h1 { font-size: clamp(30px, 5vw, 48px); letter-spacing: -.04em; }
h2 { font-size: 22px; }
.eyebrow { color: #65a8ff; font-size: 12px; letter-spacing: .16em; font-weight: 800; margin-bottom: 8px; }
.lead, small { color: #8d9caf; }
.lead { margin-top: 12px; }
a, button { font: inherit; }
a { color: #cfe4ff; text-decoration: none; border: 1px solid #2b3a50; border-radius: 10px; padding: 10px 14px; }
.policy, .card { background: rgba(15, 23, 36, .88); border: 1px solid #26354a; border-radius: 18px; box-shadow: 0 20px 60px rgba(0,0,0,.22); }
.policy { padding: 18px 22px; justify-content: flex-start; margin-bottom: 18px; }
.policy div { display: grid; gap: 3px; flex: 1; }
.dot { width: 10px; height: 10px; border-radius: 50%; background: #41d390; box-shadow: 0 0 16px #41d390; }
#clock { color: #8d9caf; font-variant-numeric: tabular-nums; }
.card { padding: 24px; margin-top: 18px; }
.active-card { border-color: #315a86; }
.section-title { margin-bottom: 20px; }
.count { min-width: 30px; height: 30px; display: grid; place-items: center; border-radius: 999px; background: #1a2d48; color: #7fbbff; font-weight: 800; }
.empty { padding: 26px 4px; color: #74849a; text-align: center; }
.request-list { display: grid; gap: 12px; }
.request { padding: 16px; border-radius: 13px; border: 1px solid #26364d; background: #0b121e; }
.identity { display: grid; gap: 5px; min-width: 0; }
.identity strong { font-size: 17px; }
.identity code, .identity span { color: #8394aa; font-size: 12px; overflow-wrap: anywhere; }
.actions { display: flex; gap: 8px; }
button { color: #f4f8ff; background: #1577db; border: 0; border-radius: 9px; padding: 10px 14px; cursor: pointer; font-weight: 750; }
button:hover { filter: brightness(1.12); }
button:disabled { opacity: .45; cursor: wait; }
button.secondary { background: #243348; }
button.danger { background: #b83449; }
.lease-details { justify-content: flex-start; flex-wrap: wrap; padding: 18px; border-radius: 13px; background: #0b121e; border: 1px solid #284f78; }
.lease-details .timer { margin-left: auto; color: #4ce0a0; font-weight: 850; font-size: 22px; font-variant-numeric: tabular-nums; }
.message { margin-top: 18px; min-height: 24px; color: #7fbbff; }
@media (max-width: 680px) { .shell { width: min(100% - 24px, 1040px); padding-top: 26px; } header, .request, .lease-details { align-items: flex-start; flex-direction: column; } .actions { width: 100%; } .actions button { flex: 1; } .lease-details .timer { margin-left: 0; } }
+46
View File
@@ -0,0 +1,46 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>真实台架本地决策台</title>
<link rel="stylesheet" href="/hardware-control.css">
</head>
<body>
<main class="shell">
<header>
<div>
<p class="eyebrow">LOCAL BENCH AUTHORITY</p>
<h1>真实台架本地决策台</h1>
<p class="lead">只有本机可以批准、拒绝或停止终端的真实台架使用权。</p>
</div>
<a href="/">返回控制台</a>
</header>
<section class="policy">
<span class="dot"></span>
<div><strong>单终端租约</strong><small>获批终端可连续测试;最后一次真实执行后空闲 180 秒自动停止。</small></div>
<span id="clock">正在连接…</span>
</section>
<section class="card active-card">
<div class="section-title">
<div><p class="eyebrow">ACTIVE LEASE</p><h2>当前使用者</h2></div>
<button id="revokeButton" class="danger" type="button" hidden>立即停止使用</button>
</div>
<div id="activeLease" class="empty">当前无人获批使用真实台架。</div>
</section>
<section class="card">
<div class="section-title">
<div><p class="eyebrow">PENDING REQUESTS</p><h2>等待审批</h2></div>
<span id="pendingCount" class="count">0</span>
</div>
<div id="pendingRequests" class="request-list empty">暂时没有申请。</div>
</section>
<p id="message" class="message" role="status"></p>
</main>
<script src="/hardware-control.js" defer></script>
</body>
</html>
+104
View File
@@ -0,0 +1,104 @@
const activeLease = document.querySelector("#activeLease");
const pendingRequests = document.querySelector("#pendingRequests");
const pendingCount = document.querySelector("#pendingCount");
const revokeButton = document.querySelector("#revokeButton");
const message = document.querySelector("#message");
let snapshot = null;
function escapeHtml(value) {
const node = document.createElement("span");
node.textContent = String(value ?? "");
return node.innerHTML;
}
function showMessage(value, error = false) {
message.textContent = value;
message.style.color = error ? "#ff8797" : "#7fbbff";
}
async function api(path, body) {
const response = await fetch(path, {
method: body ? "POST" : "GET",
credentials: "same-origin",
headers: body ? { "Content-Type": "application/json" } : {},
body: body ? JSON.stringify(body) : undefined,
});
if (response.status === 401) {
location.replace(`/login?next=${encodeURIComponent(location.pathname)}`);
throw new Error("请先登录本机服务");
}
const payload = await response.json();
if (!response.ok) throw new Error(payload.message || payload.error);
return payload;
}
function render(data) {
snapshot = data;
pendingCount.textContent = String(data.pending.length);
if (data.active) {
const lease = data.active;
activeLease.className = "lease-details";
activeLease.innerHTML = `
<div class="identity"><strong>${escapeHtml(lease.label)}</strong><code>${escapeHtml(lease.client_id)}</code><span>来源 ${escapeHtml(lease.client_address)} · 最近执行 ${escapeHtml(lease.last_activity_at)}</span></div>
<div class="timer">${Number(lease.idle_remaining_seconds)}s</div>`;
revokeButton.hidden = false;
revokeButton.dataset.clientId = lease.client_id;
} else {
activeLease.className = "empty";
activeLease.textContent = "当前无人获批使用真实台架。";
revokeButton.hidden = true;
}
if (!data.pending.length) {
pendingRequests.className = "request-list empty";
pendingRequests.textContent = "暂时没有申请。";
return;
}
pendingRequests.className = "request-list";
pendingRequests.innerHTML = data.pending.map((request) => `
<article class="request">
<div class="identity"><strong>${escapeHtml(request.label)}</strong><code>${escapeHtml(request.client_id)}</code><span>来源 ${escapeHtml(request.client_address)} · ${escapeHtml(request.requested_at)}</span></div>
<div class="actions">
<button type="button" data-action="approve" data-client-id="${escapeHtml(request.client_id)}">同意</button>
<button type="button" class="secondary" data-action="deny" data-client-id="${escapeHtml(request.client_id)}">拒绝</button>
</div>
</article>`).join("");
}
async function refresh() {
try {
render(await api("/api/local/hardware-access"));
document.querySelector("#clock").textContent = new Date().toLocaleTimeString("zh-CN", { hour12: false });
} catch (error) {
showMessage(error.message, true);
}
}
pendingRequests.addEventListener("click", async (event) => {
const button = event.target.closest("button[data-action]");
if (!button) return;
button.disabled = true;
try {
const action = button.dataset.action;
render(await api(`/api/local/hardware-access/${action}`, { client_id: button.dataset.clientId }));
showMessage(action === "approve" ? "已授予该终端真实台架使用权。" : "已拒绝该终端的申请。");
} catch (error) {
showMessage(error.message, true);
} finally {
button.disabled = false;
}
});
revokeButton.addEventListener("click", async () => {
revokeButton.disabled = true;
try {
render(await api("/api/local/hardware-access/revoke", { client_id: revokeButton.dataset.clientId }));
showMessage("已停止该终端的真实台架使用权;再次使用必须重新申请。");
} catch (error) {
showMessage(error.message, true);
} finally {
revokeButton.disabled = false;
}
});
refresh();
setInterval(refresh, 2000);
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

+222 -81
View File
@@ -2,16 +2,26 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="color-scheme" content="light" />
<title>智舱随行 · 一句话与手势控制</title>
<link rel="stylesheet" href="/styles.css" />
<script src="https://unpkg.com/lucide@0.468.0/dist/umd/lucide.min.js" defer></script>
<script src="https://unpkg.com/three@0.147.0/build/three.min.js" defer></script>
<script src="https://unpkg.com/three@0.147.0/examples/js/libs/fflate.min.js" defer></script>
<script src="https://unpkg.com/three@0.147.0/examples/js/loaders/FBXLoader.js" defer></script>
<script src="/app.js?v=unified-cabin-22" defer></script>
<script type="module" src="/gesture-control.js?v=gesture-core-3"></script>
<meta name="theme-color" content="#146b65" />
<meta name="mobile-web-app-capable" content="yes" />
<link rel="manifest" href="/manifest.webmanifest" />
<link rel="icon" href="/icons/app-icon-192.png" />
<title>511工程-智能座舱</title>
<link rel="stylesheet" href="/styles.css?v=dual-seat-9" />
<link rel="stylesheet" href="/console-v2.css?v=sync-layout-26" />
<link rel="stylesheet" href="/self-extension.css?v=sync-layout-26" />
<script src="/vendor/lucide/0.468.0/lucide.min.js" defer></script>
<script src="/vendor/three/0.147.0/three.min.js" defer></script>
<script src="/vendor/three/0.147.0/fflate.min.js" defer></script>
<script src="/vendor/three/0.147.0/FBXLoader.js" defer></script>
<script src="/network.js?v=android-pad-1" defer></script>
<script src="/app.js?v=dual-seat-85" defer></script>
<script type="module" src="/gesture-control.js?v=android-pad-8"></script>
<script src="/pwa.js?v=android-pad-2" defer></script>
<script src="/console-v2.js?v=sync-layout-26" defer></script>
<script src="/self-extension.js?v=sync-layout-26" defer></script>
</head>
<body>
<header class="topbar">
@@ -26,6 +36,8 @@
<button class="gesture-entry" id="gestureToggleButton" type="button" aria-controls="gestureDrawer" aria-expanded="false">
<span class="gesture-entry-dot"></span><i data-lucide="scan-face"></i>手势控制
</button>
<span class="status-badge neutral connection-badge" id="connectionBadge"><i data-lucide="loader-circle"></i><span>连接中</span></span>
<button class="status-badge neutral pwa-badge" id="pwaBadge" type="button" hidden></button>
<span class="status-badge neutral" id="executionBadge"><i data-lucide="flask-conical"></i>DRY-RUN</span>
<span class="status-badge" id="modelBadge"><i data-lucide="sparkles"></i>模型检测中</span>
<span class="status-badge danger" id="hardwareBadge"><i data-lucide="shield-off"></i>硬件检测中</span>
@@ -44,15 +56,29 @@
</div>
<div class="mode-rail" aria-label="快捷功能模式">
<div class="mode-rail-heading"><span>快捷模式</span><button id="saveModeToggle" type="button"><i data-lucide="bookmark-plus"></i>保存当前</button></div>
<div class="mode-chips">
<button type="button" data-mode-command="进入观影模式:副驾驶调整为舒适观影姿态,空调24度、风量2档,天幕调暗,氛围灯切换成暖橙色"><i data-lucide="clapperboard"></i>观影</button>
<button type="button" data-mode-command="进入午休模式:副驾驶靠背后倾,腿托伸出,空调25度,天幕最暗,氛围灯切换为柔和暖色"><i data-lucide="moon-star"></i>午休</button>
<button type="button" data-mode-command="副驾驶调整为零重力模式"><i data-lucide="orbit"></i>零重力</button>
<div class="mode-rail-heading">
<div><span>功能模式</span><small>点击模式即可执行,运行状态会实时反馈</small></div>
<button id="saveModeToggle" type="button"><i data-lucide="bookmark-plus"></i>根据指令创建</button>
</div>
<div class="mode-chips" aria-label="快捷功能模式" aria-live="polite">
<button type="button" data-mode-profile-id="zero_gravity" data-mode-command="进入零重力模式"><i data-lucide="orbit"></i><span>零重力</span></button>
<button type="button" data-mode-profile-id="office" data-mode-command="进入办公模式"><i data-lucide="briefcase"></i><span>办公</span></button>
<button type="button" data-mode-profile-id="nap" data-mode-command="进入小憩模式"><i data-lucide="moon-star"></i><span>小憩</span></button>
</div>
<div class="mode-rail-controls" aria-label="功能模式浏览">
<div class="mode-rail-pager" role="group" aria-label="翻阅快捷功能模式">
<button class="mode-rail-page" id="modeRailPrev" type="button" aria-label="查看上一组功能模式" title="上一组" disabled><i data-lucide="chevron-left"></i></button>
<button class="mode-rail-page" id="modeRailNext" type="button" aria-label="查看下一组功能模式" title="下一组"><i data-lucide="chevron-right"></i></button>
</div>
<button class="mode-gallery-toggle" id="modeGalleryToggle" type="button" aria-expanded="false" aria-controls="modeGallery"><i data-lucide="layout-grid"></i><span>全部模式</span><strong id="modeGalleryCount">0</strong></button>
</div>
<div class="save-mode-composer" id="saveModeComposer" hidden>
<input id="saveModeName" maxlength="24" placeholder="给当前模式起个名字" />
<button id="saveModeConfirm" type="button">保存</button>
<div class="save-mode-source"><small>将根据当前指令创建</small><p id="saveModeSource">请先在指令框输入需要固化的功能组合</p></div>
<input id="saveModeName" maxlength="24" placeholder="输入模式名称,例如:通勤模式" aria-label="新功能模式名称" />
<div class="save-mode-actions">
<button id="saveModeCancel" type="button">取消</button>
<button id="saveModeConfirm" type="button">创建并添加</button>
</div>
</div>
</div>
@@ -81,18 +107,50 @@
<p class="provider-note" id="providerNote">正在读取运行时配置</p>
</div>
<div class="field-group" id="reasoningField">
<span class="field-label">模型推理强度</span>
<div class="segmented reasoning-segmented" role="group" aria-label="模型推理强度">
<button type="button" class="segment reasoning-option" data-reasoning-effort="low">
<i data-lucide="zap"></i><span><strong>极速</strong><small>简单指令,优先响应速度</small></span><i class="reasoning-check" data-lucide="check"></i>
</button>
<button type="button" class="segment reasoning-option active" data-reasoning-effort="medium">
<i data-lucide="scale"></i><span><strong>均衡</strong><small>日常控制,兼顾速度与理解</small></span><i class="reasoning-check" data-lucide="check"></i>
</button>
<button type="button" class="segment reasoning-option" data-reasoning-effort="high">
<i data-lucide="brain"></i><span><strong>深度</strong><small>复杂联动、相对动作与约束</small></span><i class="reasoning-check" data-lucide="check"></i>
</button>
</div>
<p class="provider-note" id="reasoningNote">均衡模式兼顾自然语言解析精度与响应速度</p>
</div>
<div class="field-group">
<span class="field-label">执行目标</span>
<div class="segmented" role="group" aria-label="执行目标">
<div class="segmented execution-mode-options" role="group" aria-label="执行目标">
<button type="button" class="mode-option active" data-execution-mode="dry_run">
<i data-lucide="flask-conical"></i>虚拟 CAN
</button>
<button type="button" class="mode-option" id="hardwareMode" data-execution-mode="hardware" disabled>
<i data-lucide="radio-tower"></i>真实台架
</button>
<button type="button" class="mode-option" id="simulationMode" data-execution-mode="simulated_hardware" disabled>
<i data-lucide="bug-play"></i>模拟台架
</button>
</div>
<p class="provider-note" id="hardwareNote">正在检查 CAN 适配器与 IAR 固件配置</p>
<p class="provider-note" id="hardwareAliasNote">主驾和副驾暂时共享同一组实体电机、加热与通风执行器</p>
<p class="provider-note" id="hardwareAliasNote">所有座椅能力仅控制副驾实体电机、加热与通风执行器</p>
</div>
<div class="field-group simulation-fault-field" id="simulationFaultField" hidden>
<label class="field-label" for="simulationFault">故障注入场景</label>
<select id="simulationFault" aria-label="选择模拟硬件故障">
<option value="normal">正常反馈</option>
<option value="feedback_timeout">反馈超时</option>
<option value="adapter_disconnect">适配器断开</option>
<option value="motor_stall">电机堵转</option>
<option value="firmware_mismatch">固件不匹配</option>
<option value="partial_feedback">部分反馈</option>
</select>
<p class="provider-note">仅生成模拟 HIL 结果,不会打开物理 CAN 适配器或调用 IAR。</p>
</div>
<div class="field-group vehicle-field">
@@ -106,14 +164,7 @@
<p class="provider-note" id="vehicleNote">正在读取座椅量程与角度标定</p>
</div>
<div class="field-group approval-field" id="approvalField" hidden>
<label class="field-label" for="approvalToken">硬件执行授权令牌</label>
<input id="approvalToken" name="approval_token" type="password" inputmode="numeric" maxlength="6" autocomplete="off" spellcheck="false" placeholder="请输入 123456" />
<p class="provider-note">演示授权令牌为 123456,仅用于本次安全校验,不会写入日志、会话或执行制品。</p>
<p class="provider-note" id="autoFlashNote">正在检查自动烧录配置</p>
</div>
<button class="primary-action" id="runButton" type="submit">
<button class="primary-action" id="runButton" type="submit" aria-label="执行车舱控制指令">
<i data-lucide="play"></i>
<span>生成并执行</span>
</button>
@@ -121,6 +172,9 @@
<div class="example-group">
<span class="field-label">示例请求</span>
<button type="button" class="example-command featured-example" data-example="副驾座椅通风3档,同时打开空调,温度设为24度,风量3档">
<i data-lucide="workflow"></i><span>副驾通风 + 空调 24℃ · 双通道联动</span><i data-lucide="chevron-right"></i>
</button>
<button type="button" class="example-command" data-example="空调打开,车内温度调到24度,风量3档">
<i data-lucide="fan"></i><span>空调 24℃ · 风量 3 档</span><i data-lucide="chevron-right"></i>
</button>
@@ -191,28 +245,36 @@
<section class="cabin-band" aria-labelledby="cabinStateTitle">
<div class="section-title-row cabin-heading">
<div>
<span class="section-kicker">JOINT DEVICE STATE</span>
<h3 id="cabinStateTitle">联合设备状态</h3>
<div class="cabin-title-copy">
<span class="section-kicker">LIVE VEHICLE EXECUTORS</span>
<h3 id="cabinStateTitle">整车设备状态</h3>
<p>CH0 独立控制副驾四电机,CH1 映射主驾与车身执行器;所有状态按当前反馈源更新。</p>
</div>
<div class="cabin-channel-legend" aria-label="整车设备通道说明">
<span data-channel="ch0"><i>CH0</i>副驾座椅</span>
<span data-channel="ch1"><i>CH1</i>主驾 / 车身</span>
<span class="simulation-label" id="feedbackModeLabel">MATRIX-BACKED · SIMULATED FEEDBACK</span>
</div>
<span class="simulation-label" id="feedbackModeLabel">MATRIX-BACKED · SIMULATED FEEDBACK</span>
</div>
<div class="domain-grid">
<article class="domain-panel climate-panel" data-domain-panel="climate">
<article class="domain-panel climate-panel" data-domain-panel="climate" data-device-channel="ch1">
<header>
<span class="domain-icon"><i data-lucide="fan"></i></span>
<div><strong>空调</strong><small>CLIMATE · 0x064</small></div>
<div><strong>空调</strong><small>CMD 0x1DE · FB 0x404 · CH1</small></div>
<span class="device-state" id="climatePower">OFF</span>
</header>
<p class="domain-capability-line"><span>可控参数</span>电源 · 温度 · 风量/风向</p>
<div class="climate-display">
<div class="zone-temperature">
<span>主驾</span><strong id="driverTemperature">24<sup>℃</sup></strong>
<small>风向<b id="driverAirDirection">-</b></small>
</div>
<div class="airflow-visual" id="airflowVisual" data-level="0" aria-label="空调风量">
<i></i><i></i><i></i><i></i><i></i><i></i><i></i>
</div>
<div class="zone-temperature passenger-temperature">
<span>副驾</span><strong id="passengerTemperature">24<sup>℃</sup></strong>
<small>风向<b id="passengerAirDirection">-</b></small>
</div>
</div>
<dl class="domain-readouts">
@@ -223,84 +285,136 @@
</dl>
</article>
<article class="domain-panel roof-panel" data-domain-panel="roof">
<article class="domain-panel vehicle-status-panel" data-domain-panel="vehicle_status" data-device-channel="ch1">
<header>
<span class="domain-icon"><i data-lucide="gauge"></i></span>
<div><strong>车辆状态</strong><small>FB 0x342 · 0x4EB · 0x407 · CH1</small></div>
<span class="device-state readonly-state" id="vehicleTelemetryState">只读</span>
</header>
<p class="domain-capability-line readonly-capability"><span>只读信号</span>档位 · 车速 · 四门锁状态</p>
<div class="vehicle-primary-readout">
<div><span>当前档位</span><strong id="vehicleGear">--</strong></div>
<div><span>实时车速</span><strong id="vehicleSpeed">-- km/h</strong></div>
</div>
<div class="door-state-grid" aria-label="四门锁状态">
<span data-door-state="front_left"><i></i>左前门<b id="frontLeftDoorState">未知</b></span>
<span data-door-state="front_right"><i></i>右前门<b id="frontRightDoorState">未知</b></span>
<span data-door-state="rear_left"><i></i>左后门<b id="rearLeftDoorState">未知</b></span>
<span data-door-state="rear_right"><i></i>右后门<b id="rearRightDoorState">未知</b></span>
</div>
</article>
<article class="domain-panel roof-panel" data-domain-panel="roof" data-device-channel="ch1">
<header>
<span class="domain-icon"><i data-lucide="panels-top-left"></i></span>
<div><strong>智能天幕</strong><small>ROOF · 0x4C1 / 0x3E6</small></div>
<div><strong>遮阳帘</strong><small>CMD 0x431 · FB 0x41A · CH1</small></div>
<span class="device-state" id="roofState">READY</span>
</header>
<div class="roof-visual" aria-label="天幕透光率与遮阳帘位置">
<div class="roof-glass" id="roofGlass">
<span class="roof-shade" id="roofShade"></span>
<i></i><i></i><i></i>
</div>
<p class="domain-capability-line"><span>可控参数</span>开关 / 停止 · 位置</p>
<div class="domain-summary-visual shade-summary-visual" aria-hidden="true">
<span>闭合</span><i><b id="shadePositionMeter"></b></i><span>打开</span>
</div>
<dl class="domain-readouts">
<div><dt>透光率</dt><dd id="transmittanceValue">100%</dd></div>
<div><dt>遮阳帘</dt><dd id="shadePositionValue">0%</dd></div>
<div><dt>自动调光</dt><dd id="automaticDimming">关闭</dd></div>
<div><dt>电机反馈</dt><dd id="roofMotorState">已停止</dd></div>
<div><dt>动作</dt><dd id="shadeMotionState">停止</dd></div>
<div><dt>初始化</dt><dd id="shadeInitializedState">未知</dd></div>
<div><dt>热保护</dt><dd id="shadeThermalState">正常</dd></div>
</dl>
</article>
<article class="domain-panel ambient-panel" data-domain-panel="ambient_light">
<article class="domain-panel ambient-panel" data-domain-panel="ambient_light" data-device-channel="ch1">
<header>
<span class="domain-icon"><i data-lucide="lamp-ceiling"></i></span>
<div><strong>氛围灯</strong><small>AMBIENT · RGB 16.8M</small></div>
<div><strong>车内灯光</strong><small>INTERIOR / AMBIENT · CH1</small></div>
<span class="device-state" id="ambientPower">OFF</span>
</header>
<div class="ambient-visual" id="ambientVisual" aria-label="副驾手套箱上方九段氛围灯排灯">
<div class="ambient-dashboard-sketch" aria-hidden="true">
<span class="ambient-dashboard-top"></span>
<span class="ambient-center-screen"></span>
<span class="ambient-glovebox"></span>
<span class="ambient-glovebox-lamp">
<i class="ambient-line"></i><i class="ambient-line"></i><i class="ambient-line"></i>
<i class="ambient-line"></i><i class="ambient-line"></i><i class="ambient-line"></i>
<i class="ambient-line"></i><i class="ambient-line"></i><i class="ambient-line"></i>
</span>
</div>
<small class="ambient-location-label">副驾 · 手套箱上方排灯</small>
<p class="domain-capability-line"><span>可控参数</span>阅读灯 · 氛围亮度 · 色号</p>
<div class="domain-summary-visual ambient-summary-visual" aria-hidden="true">
<span data-ambient-zone="front"><i id="ambientFrontMeter"></i><b>前排</b></span>
<span data-ambient-zone="rear"><i id="ambientRearMeter"></i><b>后排</b></span>
</div>
<dl class="domain-readouts">
<div><dt>颜色</dt><dd><i class="color-swatch" id="ambientSwatch"></i><span id="ambientColor">#74D9FF</span></dd></div>
<div><dt>亮度</dt><dd id="ambientBrightness">0%</dd></div>
<div><dt>模式</dt><dd id="ambientMode">关闭</dd></div>
<div><dt>控制精度</dt><dd>24-bit RGB</dd></div>
<div><dt>氛围灯</dt><dd id="ambientMode">关闭</dd></div>
<div><dt>室内/阅读灯</dt><dd id="interiorLightPower">关闭</dd></div>
<div><dt>氛围亮度</dt><dd id="ambientBrightness">0 / 0</dd></div>
<div><dt>氛围色号</dt><dd id="ambientColorIndex">- / -</dd></div>
</dl>
</article>
<article class="domain-panel window-panel" data-domain-panel="window" data-device-channel="ch1">
<header>
<span class="domain-icon"><i data-lucide="gallery-vertical-end"></i></span>
<div><strong>车窗</strong><small>CMD 0x431 · FB 0x388 · CH1</small></div>
<span class="device-state" id="windowState">READY</span>
</header>
<p class="domain-capability-line"><span>可控参数</span>四窗独立 · 开/关/停 · 位置</p>
<div class="domain-summary-visual window-summary-visual" aria-hidden="true">
<span data-window-meter="front_left"><i></i><b>左前</b></span>
<span data-window-meter="front_right"><i></i><b>右前</b></span>
<span data-window-meter="rear_left"><i></i><b>左后</b></span>
<span data-window-meter="rear_right"><i></i><b>右后</b></span>
</div>
<dl class="domain-readouts">
<div><dt>左前窗</dt><dd id="frontLeftWindow">0%</dd></div>
<div><dt>右前窗</dt><dd id="frontRightWindow">0%</dd></div>
<div><dt>左后窗</dt><dd id="rearLeftWindow">0%</dd></div>
<div><dt>右后窗</dt><dd id="rearRightWindow">0%</dd></div>
</dl>
</article>
<article class="domain-panel lighting-panel" data-domain-panel="front_light" data-device-channel="ch1">
<header>
<span class="domain-icon"><i data-lucide="car-front"></i></span>
<div><strong>前大灯</strong><small>FRONT LIGHT · SWITCH</small></div>
<span class="device-state" id="frontLightState">OFF</span>
</header>
<p class="domain-capability-line"><span>可控参数</span>近/远光 · 雾灯 · 转向灯</p>
<div class="domain-summary-visual lighting-summary-visual" aria-hidden="true">
<span data-light-meter="lowBeamState"><i></i><b>近光</b></span>
<span data-light-meter="highBeamState"><i></i><b>远光</b></span>
<span data-light-meter="fogLightState"><i></i><b>雾灯</b></span>
<span data-light-meter="turnSignalState"><i></i><b>转向</b></span>
</div>
<dl class="domain-readouts">
<div><dt>近光灯</dt><dd id="lowBeamState">关闭</dd></div>
<div><dt>远光灯</dt><dd id="highBeamState">关闭</dd></div>
<div><dt>雾灯</dt><dd id="fogLightState">关闭</dd></div>
<div><dt>转向灯</dt><dd id="turnSignalState">关闭</dd></div>
</dl>
</article>
</div>
</section>
<section class="twin-band" aria-labelledby="twinTitle">
<div class="twin-heading">
<div>
<span class="section-kicker">FULL VEHICLE DIGITAL TWIN</span>
<div class="twin-title-copy">
<span class="section-kicker">LIVE VEHICLE DIGITAL TWIN</span>
<h3 id="twinTitle">整车孪生界面</h3>
<div class="preset-indicator" id="presetIndicator" hidden>
<i data-lucide="bookmark-check"></i><span></span>
</div>
</div>
<div class="twin-toolbar">
<span class="twin-focus-badge"><i data-lucide="scan"></i>透明车体 · 实体设备</span>
<div class="twin-selector" role="tablist" aria-label="前排座椅孪生选择">
<button class="twin-seat-button active" type="button" role="tab" aria-selected="true" data-twin-seat="passenger">副驾座椅 · CH0</button>
<button class="twin-seat-button" type="button" role="tab" aria-selected="false" data-twin-seat="driver">主驾座椅 · CH1</button>
</div>
<button class="icon-button twin-reset" id="twinReset" type="button" title="复位 3D 视角" aria-label="复位 3D 视角">
<i data-lucide="rotate-3d"></i>
</button>
</div>
</div>
<div class="twin-stage" id="seatTwin" data-selected-seat="passenger">
<canvas id="seatTwinCanvas" data-vehicle-model="byd-tang-2024-reference" data-seat-layout="five-seat" data-active-seat="front-right" aria-label="具有前后遮挡明暗层次的半透明整车外壳、始终清晰显示的动态副驾、全景天幕、仪表台空调出风口与副驾手套箱上方氛围灯三维状态"></canvas>
<div class="vehicle-system-hud" aria-label="整车孪生系统状态">
<span data-twin-system="roof"><i data-lucide="panels-top-left"></i><small>全景天幕</small><b id="twinRoofState">透光 100%</b></span>
<span data-twin-system="climate"><i data-lucide="wind"></i><small>仪表台 HVAC</small><b id="twinClimateState">关闭</b></span>
<span data-twin-system="ambient"><i data-lucide="lamp-ceiling"></i><small>手套箱氛围灯</small><b id="twinAmbientState">关闭</b></span>
</div>
<div class="twin-seat-label passenger"><i></i><span>副驾动态座椅</span><small>ACTIVE · FRONT RIGHT</small></div>
<canvas id="seatTwinCanvas" data-vehicle-model="byd-tang-2024-reference" data-seat-layout="five-seat" data-active-seat="front-right" aria-label="通过模型动画展示 CH0 副驾座椅与 CH1 主驾座椅、空调气流、智能天幕、阅读灯、四门车窗与前大灯状态的整车数字孪生"></canvas>
<div class="twin-seat-label passenger"><i></i><span>副驾座椅</span><small>CH0 · 右前排</small></div>
<div class="twin-seat-label driver"><i></i><span>主驾座椅</span><small>CH1 · 左前排</small></div>
<div class="twin-callout-layer" aria-hidden="true">
<div class="twin-callout" data-callout="longitudinal"><span>水平位置</span><b>50%</b><small>导轨</small></div>
<div class="twin-callout" data-callout="cushion_tilt"><span>坐垫俯仰</span><b>7°</b><small>50%</small></div>
<div class="twin-callout" data-callout="backrest_recline"><span>靠背夹角</span><b>20.5°</b><small>20% · 相对竖直</small></div>
<div class="twin-callout" data-callout="legrest_height"><span>腿托夹角</span><b>78.5°</b><small>0% · 相对地板</small></div>
<div class="twin-callout" data-callout="cushion_tilt"><span>坐垫俯仰</span><b>4.5°</b><small>50%</small></div>
<div class="twin-callout" data-callout="height"><span>座椅高度</span><b>50%</b><small>CH1 高度电机</small></div>
<div class="twin-callout" data-callout="backrest_recline"><span>靠背夹角</span><b>13.6°</b><small>20% · 相对归零位</small></div>
<div class="twin-callout" data-callout="legrest_height"><span>腿托夹角</span><b>0°</b><small>0% · 相对垂直零位</small></div>
<div class="twin-callout" data-callout="legrest_extension"><span>腿托伸缩</span><b>0%</b><small>行程</small></div>
<div class="twin-callout included-angle-callout" data-callout="backrest_included_angle" hidden><span>靠背-坐垫夹角</span><b>104°</b><small>本轮指定夹角</small></div>
<div class="twin-callout included-angle-callout" data-callout="legrest_included_angle" hidden><span>坐垫-腿托夹角</span><b>95°</b><small>本轮指定夹角</small></div>
@@ -308,12 +422,13 @@
<div class="twin-orientation"><i data-lucide="move-down"></i><span>车头方向</span></div>
<aside class="twin-readout" aria-live="polite">
<div class="twin-readout-heading">
<div><strong id="twinSeatName">副驾</strong><span id="twinSeatZone">front_right</span></div>
<div><strong id="twinSeatName">副驾座椅</strong><span id="twinSeatZone">CH0 · 右前排</span></div>
<span class="twin-feedback"><i></i>FEEDBACK</span>
</div>
<div class="twin-axis-list">
<div data-twin-axis="longitudinal"><span>水平位置</span><b>50%</b><i></i></div>
<div data-twin-axis="cushion_tilt"><span>坐垫俯仰</span><b>50%</b><i></i></div>
<div data-twin-axis="height"><span>座椅高度</span><b>50%</b><i></i></div>
<div data-twin-axis="backrest_recline"><span>靠背夹角</span><b>20% · 104°</b><i></i></div>
<div data-twin-axis="legrest_height"><span>腿托夹角</span><b>0% · 95°</b><i></i></div>
<div data-twin-axis="legrest_extension"><span>腿托伸缩</span><b>0%</b><i></i></div>
@@ -339,22 +454,32 @@
<div class="seat-state-section">
<div class="section-title-row">
<div><span class="section-kicker">ACTUATOR STATE</span><h3>前排座椅状态</h3></div>
<span class="simulation-label" id="seatFeedbackModeLabel">SIMULATED FEEDBACK</span>
<span class="simulation-label" id="seatFeedbackModeLabel">CH0 / CH1 FEEDBACK</span>
</div>
<div class="seat-grid">
<article class="seat-card" data-seat="driver">
<div class="seat-identity"><i data-lucide="armchair"></i><div><strong>主驾</strong><span>front_left</span></div></div>
<article class="seat-card" data-seat="passenger">
<div class="seat-identity"><i data-lucide="armchair"></i><div><strong>副驾座椅</strong><span>右前排</span></div></div>
<span class="seat-channel-badge" data-seat-feedback="passenger">CH0 · 等待反馈</span>
<div class="dynamic-mode-state" data-dynamic-mode>
<i data-lucide="waves"></i><span>动态模式</span><b>未运行</b>
</div>
<div class="thermal-states">
<span data-function="ventilation"><i data-lucide="wind"></i>通风 <b>--</b></span>
<span data-function="heating"><i data-lucide="flame"></i>加热 <b>--</b></span>
<span data-function="massage"><i data-lucide="waves"></i>按摩 <b>--</b></span>
</div>
<div class="motion-state-grid" aria-live="polite"></div>
</article>
<article class="seat-card" data-seat="passenger">
<div class="seat-identity"><i data-lucide="armchair"></i><div><strong>副驾</strong><span>front_right</span></div></div>
<article class="seat-card" data-seat="driver">
<div class="seat-identity"><i data-lucide="armchair"></i><div><strong>主驾座椅</strong><span>左前排</span></div></div>
<span class="seat-channel-badge" data-seat-feedback="driver">CH1 · 等待反馈</span>
<div class="dynamic-mode-state" data-dynamic-mode>
<i data-lucide="radio-tower"></i><span>车端 CAN FD</span><b>只读同步</b>
</div>
<div class="thermal-states">
<span data-function="ventilation"><i data-lucide="wind"></i>通风 <b>--</b></span>
<span data-function="heating"><i data-lucide="flame"></i>加热 <b>--</b></span>
<span data-function="massage"><i data-lucide="waves"></i>按摩 <b>--</b></span>
</div>
<div class="motion-state-grid" aria-live="polite"></div>
</article>
@@ -368,6 +493,7 @@
<div><dt>天幕 / 遮阳帘 0–100%</dt><dd class="available">可编译</dd></div>
<div><dt>氛围灯 RGB / 亮度</dt><dd class="available">可编译</dd></div>
<div><dt>副驾座椅统一执行器</dt><dd class="simulated">t2g_primary_seat</dd></div>
<div><dt>主驾座椅车端执行器</dt><dd class="simulated">CH1 · 左前排</dd></div>
<div><dt>真实台架 CAN 下发</dt><dd class="blocked" id="hardwareCoverage">未配置</dd></div>
</dl>
</div>
@@ -474,12 +600,11 @@
<div class="gesture-actions">
<button class="gesture-primary" id="gestureStartButton" type="button"><i data-lucide="camera"></i><span>开启摄像头</span></button>
<button id="gestureArmButton" type="button" disabled><i data-lucide="hand"></i>激活控制</button>
<button id="gestureStopButton" type="button" disabled><i data-lucide="octagon"></i>停止</button>
</div>
<section class="gesture-guide-card">
<div class="gesture-card-heading"><div><span>动作速查</span><small>张掌激活 · 握拳只停止</small></div><button id="gestureCustomizeButton" type="button"><i data-lucide="sliders-horizontal"></i>自定义</button></div>
<div class="gesture-card-heading"><div><span>手势速查</span><small>张掌激活 · 握拳只停止</small></div><button id="gestureCustomizeButton" type="button"><i data-lucide="sliders-horizontal"></i>自定义</button></div>
<div class="gesture-map-grid" id="gestureMapGrid"></div>
<div class="gesture-customize" id="gestureCustomizePanel" hidden>
<div><span>识别到</span><strong id="gestureCustomizeToken">请先摆出手势</strong></div>
@@ -492,6 +617,22 @@
<footer class="gesture-footnote"><i data-lucide="shield-check"></i><span>换动作无需重新张掌;连续 3 秒无有效动作后自动锁止。</span></footer>
</aside>
<div class="mode-gallery-backdrop" id="modeGalleryBackdrop" hidden>
<section class="mode-gallery" id="modeGallery" role="dialog" aria-modal="true" aria-labelledby="modeGalleryTitle" aria-describedby="modeGalleryDescription">
<header class="mode-gallery-header">
<div>
<span class="mode-gallery-kicker">SCENE LIBRARY</span>
<h2 id="modeGalleryTitle">全部功能模式</h2>
<p id="modeGalleryDescription">按场景集中展示所有预设及用户创建模式,点击任一模式即可执行。</p>
</div>
<button class="mode-gallery-close" id="modeGalleryClose" type="button" aria-label="关闭全部功能模式"><i data-lucide="x"></i></button>
</header>
<div class="mode-gallery-summary"><span><i data-lucide="layers-3"></i>可用模式</span><strong id="modeGallerySummaryCount">0</strong></div>
<div class="mode-gallery-groups" id="modeGalleryGroups" aria-live="polite"></div>
<footer class="mode-gallery-footer"><i data-lucide="info"></i><span>执行状态与主界面同步:蓝色执行中、绿色已完成、红色执行失败。</span></footer>
</section>
</div>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
</body>
</html>
+1
View File
@@ -6,6 +6,7 @@
<meta name="color-scheme" content="light" />
<title>登录 · Cognitive Agent</title>
<link rel="stylesheet" href="/login.css" />
<script src="/network.js?v=android-pad-1" defer></script>
<script src="/login.js" defer></script>
</head>
<body>
+2 -2
View File
@@ -4,7 +4,7 @@ function nextPath() {
}
async function readAuthStatus() {
const response = await fetch("/api/auth/status", { cache: "no-store" });
const response = await window.CognitiveAgentNetwork.request("/api/auth/status", { cache: "no-store" });
if (!response.ok) return;
const status = await response.json();
if (status.authenticated) window.location.replace(nextPath());
@@ -18,7 +18,7 @@ async function submitLogin(event) {
message.textContent = "";
try {
const response = await fetch("/api/auth/login", {
const response = await window.CognitiveAgentNetwork.request("/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
+26
View File
@@ -0,0 +1,26 @@
{
"name": "Cognitive Agent PAD Console",
"short_name": "Cognitive Agent",
"description": "车舱认知编排、模拟台架与手势控制 PAD 控制台",
"lang": "zh-CN",
"start_url": "/?source=pwa",
"scope": "/",
"display": "standalone",
"orientation": "any",
"background_color": "#eef3f1",
"theme_color": "#146b65",
"icons": [
{
"src": "/icons/app-icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "/icons/app-icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
+138
View File
@@ -0,0 +1,138 @@
(function initializeCognitiveAgentNetwork() {
const nativeFetch = window.fetch.bind(window);
const listeners = new Set();
const state = {
status: navigator.onLine === false ? "offline" : "connecting",
lastSuccessAt: null,
lastError: null,
};
let probeTimer = null;
function snapshot() {
return { ...state };
}
function renderBadge() {
const badge = document.querySelector("#connectionBadge");
if (!badge) return;
const presentation = {
connecting: ["neutral", "loader-circle", "连接中"],
online: ["", "wifi", "服务已连接"],
degraded: ["warning", "wifi-low", "连接不稳定"],
offline: ["danger", "wifi-off", "服务已断开"],
}[state.status];
badge.className = `status-badge connection-badge ${presentation[0]}`.trim();
badge.innerHTML = `<i data-lucide="${presentation[1]}"></i><span>${presentation[2]}</span>`;
badge.title = state.lastError || presentation[2];
window.lucide?.createIcons?.({
attrs: { "aria-hidden": "true" },
nodes: [badge],
});
}
function publish(status, error = null) {
const changed = state.status !== status || state.lastError !== error;
state.status = status;
state.lastError = error;
if (status === "online") state.lastSuccessAt = new Date().toISOString();
renderBadge();
if (!changed) return;
const detail = snapshot();
listeners.forEach((listener) => listener(detail));
window.dispatchEvent(new CustomEvent("cognitive-agent:connection", { detail }));
}
function sleep(milliseconds) {
return new Promise((resolve) => window.setTimeout(resolve, milliseconds));
}
async function request(input, options = {}) {
const {
timeoutMs = 10000,
retries: configuredRetries,
signal: callerSignal,
...fetchOptions
} = options;
const method = String(fetchOptions.method || "GET").toUpperCase();
const retries = configuredRetries ?? (method === "GET" ? 1 : 0);
let lastError;
for (let attempt = 0; attempt <= retries; attempt += 1) {
const controller = new AbortController();
const abortFromCaller = () => controller.abort(callerSignal?.reason);
callerSignal?.addEventListener("abort", abortFromCaller, { once: true });
const timeout = window.setTimeout(() => controller.abort("timeout"), timeoutMs);
try {
const response = await nativeFetch(input, {
...fetchOptions,
signal: controller.signal,
});
publish(response.status >= 500 ? "degraded" : "online",
response.status >= 500 ? `服务返回 HTTP ${response.status}` : null);
return response;
} catch (error) {
lastError = error;
const message = controller.signal.aborted && !callerSignal?.aborted
? `请求超时(${Math.round(timeoutMs / 1000)} 秒)`
: (error?.message || "网络请求失败");
publish(attempt < retries ? "degraded" : "offline", message);
if (callerSignal?.aborted || attempt >= retries || method !== "GET") {
throw new Error(message, { cause: error });
}
await sleep(300 * (attempt + 1));
} finally {
window.clearTimeout(timeout);
callerSignal?.removeEventListener("abort", abortFromCaller);
}
}
throw lastError;
}
async function probe() {
if (document.hidden) return;
if (navigator.onLine === false) {
publish("offline", "设备当前处于离线状态");
return;
}
try {
const response = await request("/api/health", {
cache: "no-store",
timeoutMs: 4000,
retries: 0,
});
if (!response.ok && response.status !== 401) {
publish("degraded", `健康检查返回 HTTP ${response.status}`);
}
} catch (_error) {
// request() already published the detailed state.
}
}
function startMonitoring() {
if (probeTimer !== null) return;
renderBadge();
probe();
probeTimer = window.setInterval(probe, 10000);
window.addEventListener("online", () => {
publish("connecting");
probe();
});
window.addEventListener("offline", () => publish("offline", "设备当前处于离线状态"));
document.addEventListener("visibilitychange", () => {
if (!document.hidden) probe();
});
}
window.CognitiveAgentNetwork = {
request,
probe,
subscribe(listener) {
listeners.add(listener);
listener(snapshot());
return () => listeners.delete(listener);
},
getState: snapshot,
nativeFetch,
};
document.addEventListener("DOMContentLoaded", startMonitoring, { once: true });
})();
+42
View File
@@ -0,0 +1,42 @@
(function initializePwa() {
function notify(message) {
window.CognitiveAgentConsole?.notify?.(message);
}
function showUpdate(registration) {
const badge = document.querySelector("#pwaBadge");
if (!badge) return;
badge.hidden = false;
badge.innerHTML = '<i data-lucide="refresh-cw"></i><span>发现更新</span>';
badge.onclick = () => registration.waiting?.postMessage({ type: "SKIP_WAITING" });
window.lucide?.createIcons?.({ attrs: { "aria-hidden": "true" }, nodes: [badge] });
}
async function register() {
if (!("serviceWorker" in navigator) || !window.isSecureContext) return;
try {
const registration = await navigator.serviceWorker.register("/service-worker.js", {
scope: "/",
updateViaCache: "none",
});
await registration.update();
if (registration.waiting) showUpdate(registration);
registration.addEventListener("updatefound", () => {
const worker = registration.installing;
worker?.addEventListener("statechange", () => {
if (worker.state === "installed" && navigator.serviceWorker.controller) {
showUpdate(registration);
}
});
});
navigator.serviceWorker.addEventListener("controllerchange", () => window.location.reload());
navigator.serviceWorker.addEventListener("message", (event) => {
if (event.data?.type === "OFFLINE_READY") notify("PAD 离线资源已准备完成");
});
} catch (error) {
console.warn("PWA registration failed", error);
}
}
window.addEventListener("load", register, { once: true });
})();
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+96
View File
@@ -0,0 +1,96 @@
const CACHE_VERSION = "cognitive-agent-pad-v178";
const SHELL_CACHE = `${CACHE_VERSION}-shell`;
const RUNTIME_CACHE = `${CACHE_VERSION}-runtime`;
const APP_SHELL = [
"/",
"/index.html",
"/styles.css?v=dual-seat-9",
"/network.js?v=android-pad-1",
"/app.js?v=dual-seat-85",
"/gesture-control.js?v=android-pad-8",
"/pwa.js?v=android-pad-2",
"/console-v2.css?v=sync-layout-26",
"/console-v2.js?v=sync-layout-26",
"/self-extension.css?v=sync-layout-26",
"/self-extension.js?v=sync-layout-26",
"/assets/pets/self-extension-cat.png?v=3",
"/assets/pets/self-extension-cat-entrance.png?v=3",
"/manifest.webmanifest",
"/icons/app-icon-192.png",
"/icons/app-icon-512.png",
"/vendor/lucide/0.468.0/lucide.min.js",
"/vendor/three/0.147.0/three.min.js",
"/vendor/three/0.147.0/fflate.min.js",
"/vendor/three/0.147.0/FBXLoader.js",
"/vendor/mediapipe/tasks-vision/0.10.14/vision_bundle.mjs",
"/vendor/mediapipe/tasks-vision/0.10.14/wasm/vision_wasm_internal.js",
"/vendor/mediapipe/tasks-vision/0.10.14/wasm/vision_wasm_internal.wasm",
"/vendor/mediapipe/tasks-vision/0.10.14/wasm/vision_wasm_nosimd_internal.js",
"/vendor/mediapipe/tasks-vision/0.10.14/wasm/vision_wasm_nosimd_internal.wasm"
];
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(SHELL_CACHE)
.then((cache) => cache.addAll(APP_SHELL))
.then(() => self.skipWaiting())
.then(() => self.clients.matchAll({ includeUncontrolled: true }))
.then((clients) => clients.forEach((client) => client.postMessage({ type: "OFFLINE_READY" })))
);
});
self.addEventListener("activate", (event) => {
event.waitUntil(
caches.keys()
.then((keys) => Promise.all(
keys.filter((key) => key.startsWith("cognitive-agent-pad-")
&& ![SHELL_CACHE, RUNTIME_CACHE].includes(key))
.map((key) => caches.delete(key))
))
.then(() => self.clients.claim())
);
});
async function cacheFirst(request) {
const shellCache = await caches.open(SHELL_CACHE);
const runtimeCache = await caches.open(RUNTIME_CACHE);
const cached = (await shellCache.match(request)) || (await runtimeCache.match(request));
if (cached) return cached;
const response = await fetch(request);
if (response.ok) {
await runtimeCache.put(request, response.clone());
}
return response;
}
async function navigationResponse(request) {
try {
const response = await fetch(request);
if (response.ok) {
const cache = await caches.open(RUNTIME_CACHE);
await cache.put("/index.html", response.clone());
}
return response;
} catch (_error) {
const shellCache = await caches.open(SHELL_CACHE);
const runtimeCache = await caches.open(RUNTIME_CACHE);
return (await runtimeCache.match("/index.html"))
|| (await shellCache.match("/index.html"))
|| Response.error();
}
}
self.addEventListener("fetch", (event) => {
const url = new URL(event.request.url);
if (url.origin !== self.location.origin || event.request.method !== "GET") return;
if (event.request.mode === "navigate") {
event.respondWith(navigationResponse(event.request));
return;
}
if (url.pathname.startsWith("/api/") && url.pathname !== "/api/gesture/model") return;
event.respondWith(cacheFirst(event.request));
});
self.addEventListener("message", (event) => {
if (event.data?.type === "SKIP_WAITING") self.skipWaiting();
});
+882 -4
View File
@@ -45,6 +45,10 @@ body.gesture-open {
overflow: hidden;
}
body.mode-gallery-open {
overflow: hidden;
}
.topbar {
min-height: 76px;
padding: 12px clamp(18px, 2.4vw, 38px);
@@ -139,6 +143,18 @@ body.gesture-open {
color: var(--accent-ink);
}
.mode-rail-heading > div {
min-width: 0;
display: grid;
gap: 2px;
}
.mode-rail-heading small {
color: var(--muted);
font-size: 9px;
font-weight: 600;
}
.mode-rail-heading button,
.gesture-card-heading button {
display: inline-flex;
@@ -187,17 +203,557 @@ body.gesture-open {
background: #fff;
}
.mode-chips button.running {
color: #24489b;
background: #e7edff;
border-color: rgba(66, 104, 194, 0.46);
box-shadow: 0 0 0 3px rgba(66, 104, 194, 0.11);
}
.mode-chips button.succeeded {
color: #0b725d;
background: #ddf7ef;
border-color: rgba(18, 148, 115, 0.42);
box-shadow: 0 0 0 3px rgba(18, 148, 115, 0.1);
}
.mode-chips button.failed {
color: #a84039;
background: #fde9e7;
border-color: rgba(201, 72, 62, 0.42);
}
.mode-chips button.running svg {
animation: mode-chip-pulse 1s ease-in-out infinite alternate;
}
@keyframes mode-chip-pulse {
to { transform: scale(1.16); }
}
.mode-chips svg {
width: 15px;
height: 15px;
color: var(--accent);
}
.mode-rail-controls {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 7px;
margin-top: 9px;
}
.mode-rail-pager {
display: inline-grid;
grid-template-columns: repeat(2, 30px);
gap: 3px;
padding: 3px;
border: 1px solid rgba(8, 118, 110, 0.12);
border-radius: 10px;
background: rgba(255, 255, 255, 0.65);
}
.mode-rail-page,
.mode-gallery-toggle {
border: 0;
color: var(--accent-ink);
background: transparent;
cursor: pointer;
}
.mode-rail-page {
width: 30px;
height: 27px;
display: inline-grid;
place-items: center;
border-radius: 7px;
}
.mode-rail-page:hover:not(:disabled),
.mode-gallery-toggle:hover {
background: rgba(8, 118, 110, 0.09);
}
.mode-rail-page:disabled {
opacity: 0.3;
cursor: default;
}
.mode-rail-page svg,
.mode-gallery-toggle svg {
width: 14px;
height: 14px;
}
.mode-gallery-toggle {
min-height: 35px;
display: inline-flex;
align-items: center;
gap: 5px;
padding: 5px 9px;
border: 1px solid rgba(8, 118, 110, 0.13);
border-radius: 10px;
background: rgba(255, 255, 255, 0.74);
font-size: 10px;
font-weight: 800;
white-space: nowrap;
}
.mode-gallery-toggle strong {
min-width: 19px;
height: 19px;
display: inline-grid;
place-items: center;
padding: 0 5px;
border-radius: 999px;
color: #fff;
background: var(--accent);
font-size: 9px;
}
.mode-gallery-backdrop {
position: fixed;
inset: 0;
z-index: 1200;
display: grid;
place-items: center;
padding: clamp(16px, 3vw, 36px);
background: rgba(13, 35, 37, 0.52);
backdrop-filter: blur(8px);
}
.mode-gallery-backdrop[hidden] {
display: none;
}
.mode-gallery {
width: min(1080px, calc(100vw - 32px));
max-height: min(680px, calc(100dvh - 32px));
display: grid;
grid-template-rows: auto auto minmax(0, 1fr) auto;
gap: 12px;
padding: clamp(18px, 2.2vw, 26px);
overflow: hidden;
color: var(--ink);
background:
radial-gradient(circle at 98% 2%, color-mix(in srgb, var(--v2-accent, var(--accent)) 12%, white), transparent 17rem),
#f9fbfa;
border: 1px solid rgba(255, 255, 255, 0.84);
border-radius: 24px;
box-shadow: 0 30px 90px rgba(12, 38, 39, 0.27);
transform: translateY(8px) scale(0.99);
opacity: 0;
transition: transform 160ms ease, opacity 160ms ease;
}
.mode-gallery-backdrop.open .mode-gallery {
transform: translateY(0) scale(1);
opacity: 1;
}
.mode-gallery-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 24px;
}
.mode-gallery-kicker {
display: block;
margin-bottom: 4px;
color: var(--v2-accent, var(--accent));
font-size: 9px;
font-weight: 900;
letter-spacing: 0.17em;
}
.mode-gallery-header h2 {
margin: 0;
color: #153537;
font-size: clamp(22px, 2vw, 28px);
letter-spacing: -0.035em;
}
.mode-gallery-header p {
margin: 5px 0 0;
color: #748284;
font-size: 11px;
line-height: 1.55;
}
.mode-gallery-close {
width: 36px;
height: 36px;
flex: 0 0 auto;
display: inline-grid;
place-items: center;
border: 1px solid rgba(17, 71, 70, 0.12);
border-radius: 11px;
color: #4d6263;
background: rgba(255, 255, 255, 0.82);
cursor: pointer;
}
.mode-gallery-close:hover {
color: var(--v2-accent, var(--accent));
background: #fff;
}
.mode-gallery-close svg {
width: 17px;
height: 17px;
}
.mode-gallery-summary {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 11px;
border: 1px solid color-mix(in srgb, var(--v2-accent, var(--accent)) 12%, white);
border-radius: 11px;
color: #5e7273;
background: color-mix(in srgb, var(--v2-accent-soft, var(--accent-wash)) 42%, white);
font-size: 10px;
font-weight: 750;
}
.mode-gallery-summary span {
display: inline-flex;
align-items: center;
gap: 7px;
}
.mode-gallery-summary svg {
width: 14px;
height: 14px;
color: var(--v2-accent, var(--accent));
}
.mode-gallery-summary strong {
color: var(--v2-accent-strong, var(--accent-ink));
font-size: 15px;
}
.mode-gallery-groups {
min-height: 0;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
align-items: start;
gap: 13px;
padding-right: 4px;
overflow-y: auto;
overscroll-behavior: contain;
}
.mode-gallery-group {
min-width: 0;
padding: 12px;
border: 1px solid rgba(34, 82, 82, 0.1);
border-radius: 15px;
background: rgba(255, 255, 255, 0.78);
}
.mode-gallery-group > header,
.mode-gallery-group > header > span,
.mode-gallery-group > header > span > span {
min-width: 0;
display: flex;
align-items: center;
}
.mode-gallery-group > header {
justify-content: space-between;
gap: 10px;
margin-bottom: 9px;
}
.mode-gallery-group > header > span {
gap: 8px;
}
.mode-gallery-group > header > span > span {
align-items: flex-start;
flex-direction: column;
gap: 1px;
}
.mode-gallery-group > header svg {
width: 17px;
height: 17px;
color: var(--v2-accent, var(--accent));
}
.mode-gallery-group > header strong {
color: #294345;
font-size: 12px;
}
.mode-gallery-group > header small {
overflow: hidden;
color: #8a9797;
font-size: 8px;
line-height: 1.3;
text-overflow: ellipsis;
white-space: nowrap;
}
.mode-gallery-group > header b {
min-width: 23px;
height: 23px;
display: inline-grid;
place-items: center;
border-radius: 999px;
color: var(--v2-accent-strong, var(--accent-ink));
background: color-mix(in srgb, var(--v2-accent-soft, var(--accent-wash)) 70%, white);
font-size: 9px;
}
.mode-gallery-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 7px;
}
.mode-gallery-card {
min-width: 0;
min-height: 70px;
display: grid;
grid-template-columns: 34px minmax(0, 1fr);
align-items: center;
gap: 9px;
padding: 9px;
text-align: left;
border: 1px solid rgba(21, 92, 88, 0.11);
border-radius: 12px;
color: #1f393b;
background: #fff;
box-shadow: 0 4px 14px rgba(28, 66, 66, 0.035);
cursor: pointer;
transition: transform 140ms ease, border-color 140ms ease, box-shadow 140ms ease, background 140ms ease;
}
.mode-gallery-card-shell {
min-width: 0;
position: relative;
}
.mode-gallery-card-shell > .mode-gallery-card {
width: 100%;
height: 100%;
}
.mode-gallery-card-shell[data-mode-origin="user"] > .mode-gallery-card {
padding-right: 35px;
}
.mode-gallery-delete {
width: 25px;
height: 25px;
position: absolute;
top: 8px;
right: 8px;
display: inline-grid;
place-items: center;
padding: 0;
border: 1px solid rgba(168, 64, 57, 0.16);
border-radius: 8px;
color: #a84039;
background: rgba(255, 245, 243, 0.94);
cursor: pointer;
transition: color 140ms ease, background 140ms ease, border-color 140ms ease;
}
.mode-gallery-delete:hover {
color: #8f2e28;
background: #ffe7e3;
border-color: rgba(168, 64, 57, 0.32);
}
.mode-gallery-delete:focus-visible {
outline: 2px solid rgba(168, 64, 57, 0.28);
outline-offset: 2px;
}
.mode-gallery-delete:disabled {
opacity: 0.52;
cursor: wait;
}
.mode-gallery-delete svg {
width: 12px;
height: 12px;
}
.mode-gallery-card:hover {
transform: translateY(-1px);
border-color: color-mix(in srgb, var(--v2-accent, var(--accent)) 35%, white);
box-shadow: 0 8px 20px rgba(26, 78, 76, 0.09);
}
.mode-gallery-card:disabled {
cursor: wait;
}
.mode-gallery-card-icon {
width: 34px;
height: 34px;
display: inline-grid;
place-items: center;
border-radius: 10px;
color: var(--v2-accent, var(--accent));
background: color-mix(in srgb, var(--v2-accent-soft, var(--accent-wash)) 76%, white);
}
.mode-gallery-card-icon svg {
width: 16px;
height: 16px;
}
.mode-gallery-card-copy,
.mode-gallery-card-heading {
min-width: 0;
display: flex;
}
.mode-gallery-card-copy {
flex-direction: column;
gap: 3px;
}
.mode-gallery-card-heading {
align-items: center;
justify-content: space-between;
gap: 5px;
}
.mode-gallery-card-heading strong {
overflow: hidden;
font-size: 11px;
text-overflow: ellipsis;
white-space: nowrap;
}
.mode-gallery-state {
flex: 0 0 auto;
color: #829091;
font-size: 7px;
font-weight: 700;
}
.mode-gallery-card-description,
.mode-gallery-card-meta {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.mode-gallery-card-description {
color: #728182;
font-size: 8px;
}
.mode-gallery-card-meta {
color: var(--v2-accent-strong, var(--accent-ink));
font-size: 7px;
font-weight: 750;
}
.mode-gallery-card.running {
color: #294e9d;
background: #edf1ff;
border-color: rgba(66, 104, 194, 0.4);
box-shadow: 0 0 0 3px rgba(66, 104, 194, 0.09);
}
.mode-gallery-card.running .mode-gallery-card-icon {
color: #4268c2;
background: #dfe7ff;
animation: mode-chip-pulse 1s ease-in-out infinite alternate;
}
.mode-gallery-card.running .mode-gallery-state {
color: #4268c2;
}
.mode-gallery-card.succeeded {
color: #0d755f;
background: #e8f9f3;
border-color: rgba(18, 148, 115, 0.38);
}
.mode-gallery-card.succeeded .mode-gallery-state {
color: #0d856a;
}
.mode-gallery-card.failed {
color: #a84039;
background: #fff0ee;
border-color: rgba(201, 72, 62, 0.36);
}
.mode-gallery-card.failed .mode-gallery-state {
color: #bd493f;
}
.mode-gallery-empty {
min-height: 70px;
grid-column: 1 / -1;
display: flex;
align-items: center;
justify-content: center;
gap: 9px;
padding: 10px;
border: 1px dashed rgba(21, 92, 88, 0.18);
border-radius: 12px;
color: #718283;
background: rgba(247, 251, 250, 0.74);
}
.mode-gallery-empty svg {
width: 17px;
color: var(--v2-accent, var(--accent));
}
.mode-gallery-empty span {
display: grid;
gap: 2px;
}
.mode-gallery-empty strong {
color: #496162;
font-size: 10px;
}
.mode-gallery-empty small {
font-size: 8px;
}
.mode-gallery-footer {
display: flex;
align-items: center;
gap: 7px;
color: #7b898a;
font-size: 8px;
}
.mode-gallery-footer svg {
width: 13px;
height: 13px;
color: var(--v2-accent, var(--accent));
}
.save-mode-composer {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
grid-template-columns: minmax(0, 1fr);
gap: 7px;
margin-top: 10px;
padding: 10px;
background: rgba(255, 255, 255, 0.96);
border: 1px solid rgba(8, 118, 110, 0.14);
border-radius: 12px;
box-shadow: 0 16px 34px rgba(31, 70, 67, 0.14);
}
.save-mode-composer[hidden] {
@@ -215,16 +771,58 @@ body.gesture-open {
font: inherit;
}
.save-mode-composer button {
.save-mode-source {
min-width: 0;
}
.save-mode-source small {
display: block;
margin-bottom: 3px;
color: var(--muted);
font-size: 9px;
}
.save-mode-source p {
margin: 0;
overflow: hidden;
color: var(--ink);
font-size: 11px;
line-height: 1.4;
text-overflow: ellipsis;
white-space: nowrap;
}
.save-mode-source p.empty {
color: var(--muted);
}
.save-mode-actions {
display: grid;
grid-template-columns: 0.72fr 1.28fr;
gap: 6px;
}
.save-mode-composer .save-mode-actions button {
min-height: 32px;
border: 0;
border-radius: 9px;
padding: 0 12px;
padding: 6px 12px;
color: #fff;
background: var(--accent);
font-weight: 750;
cursor: pointer;
}
.save-mode-composer .save-mode-actions button:first-child {
color: var(--muted);
background: #edf2f1;
}
.save-mode-composer .save-mode-actions button:disabled {
cursor: wait;
opacity: 0.64;
}
.command-composer {
position: relative;
margin-bottom: 18px;
@@ -815,6 +1413,27 @@ body.gesture-open {
padding: 18px 15px;
border-left: 0;
}
.mode-gallery-groups {
grid-template-columns: minmax(0, 1fr);
}
}
@media (max-width: 560px) {
.mode-gallery {
max-height: calc(100dvh - 20px);
padding: 15px;
border-radius: 18px;
}
.mode-gallery-grid {
grid-template-columns: minmax(0, 1fr);
}
.mode-gallery-header p,
.mode-gallery-footer {
display: none;
}
}
@media (prefers-reduced-motion: reduce) {
@@ -1325,6 +1944,11 @@ textarea:focus {
background: var(--teal-soft);
}
.run-status.partial {
color: var(--amber);
background: var(--amber-soft);
}
.run-status.failed {
color: var(--red);
background: var(--red-soft);
@@ -2410,6 +3034,12 @@ textarea:focus {
border-color: #f0d4a2;
}
.thermal-states > span.on[data-function="massage"] {
color: #7654a8;
background: #f0eafa;
border-color: #d9c9ee;
}
.thermal-states > span.on b {
color: inherit;
}
@@ -2733,6 +3363,11 @@ pre {
border-left-color: var(--teal);
}
.execution-summary.partial {
background: var(--amber-soft);
border-left-color: var(--amber);
}
.execution-summary.failed {
background: var(--red-soft);
border-left-color: var(--red);
@@ -2945,7 +3580,8 @@ pre {
}
.joint-twin-shell .twin-readout {
display: none;
display: block;
max-width: 205px;
}
.joint-twin-shell .twin-seat-label.passenger {
@@ -2953,6 +3589,12 @@ pre {
bottom: 18px;
}
.joint-twin-shell .twin-seat-label.driver {
right: 18px;
left: auto;
bottom: 18px;
}
.vehicle-system-hud {
display: grid;
gap: 6px;
@@ -3169,6 +3811,30 @@ pre {
position: relative;
}
.seat-channel-badge {
display: inline-flex;
align-items: center;
margin-top: 7px;
padding: 3px 6px;
color: #526269;
background: #eef3f2;
border: 1px solid #d4dedb;
border-radius: 999px;
font: 700 7px "SFMono-Regular", Consolas, monospace;
}
.seat-channel-badge[data-source^="physical"] {
color: #075e57;
background: #e5f4f1;
border-color: #abd8d1;
}
.seat-channel-badge[data-source="unavailable"] {
color: #8a4d16;
background: #fff4e6;
border-color: #f1c99f;
}
.joint-seat-panel > .simulation-label {
display: block;
margin-bottom: 8px;
@@ -3892,6 +4558,11 @@ pre {
background: var(--teal-soft);
}
.workspace-panel-state.partial {
color: var(--amber);
background: var(--amber-soft);
}
.workspace-panel-state.failed {
color: var(--red);
background: var(--red-soft);
@@ -4356,3 +5027,210 @@ pre {
grid-column: 2;
}
}
.mode-cycle-badge {
margin-left: 2px;
padding: 2px 6px;
border-radius: 999px;
background: rgba(89, 214, 255, 0.12);
color: #8be3ff;
font-size: 10px;
letter-spacing: 0.02em;
}
.dynamic-mode-state {
display: flex;
align-items: center;
gap: 8px;
margin: 10px 0;
padding: 9px 11px;
border: 1px solid rgba(126, 160, 194, 0.2);
border-radius: 10px;
color: #90a7bc;
background: rgba(13, 27, 41, 0.55);
}
.dynamic-mode-state b {
margin-left: auto;
color: #b9cad8;
font-size: 12px;
}
.dynamic-mode-state.running {
border-color: rgba(89, 214, 255, 0.48);
color: #8be3ff;
box-shadow: inset 0 0 20px rgba(89, 214, 255, 0.06);
}
.dynamic-mode-state.running b {
color: #e0f8ff;
}
/* Android PAD, touch and installable-app refinements ---------------------- */
.execution-mode-options {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.simulation-fault-field select {
width: 100%;
min-height: 44px;
padding: 0 11px;
color: var(--ink);
background: var(--surface-muted);
border: 1px solid var(--line-strong);
border-radius: 6px;
font: inherit;
font-size: 13px;
font-weight: 700;
}
.status-badge.warning {
color: #7a5416;
background: var(--amber-soft);
border-color: #e9cc96;
}
.connection-badge svg[data-lucide="loader-circle"] {
animation: spin 0.9s linear infinite;
}
.pwa-badge {
cursor: pointer;
}
.pwa-badge[hidden] {
display: none;
}
@supports (min-height: 100dvh) {
body {
min-height: 100dvh;
}
.workspace {
min-height: calc(100dvh - 70px);
}
}
@media (pointer: coarse) {
button,
select,
input,
.segment,
.mode-option,
.tab,
.example-command,
.gesture-entry,
.status-badge.auth-logout {
min-height: 48px;
}
button:hover,
.example-command:hover,
.segment:hover,
.mode-option:hover {
transform: none;
}
textarea {
font-size: 16px;
}
}
@media (max-width: 900px) {
.topbar {
min-height: 64px;
align-items: center;
gap: 12px;
padding-top: max(10px, env(safe-area-inset-top));
padding-right: max(14px, env(safe-area-inset-right));
padding-left: max(14px, env(safe-area-inset-left));
}
.brand-block p,
#hardwareBadge,
#modelBadge {
display: none;
}
.runtime-badges {
flex: 1;
flex-wrap: nowrap;
justify-content: flex-end;
overflow-x: auto;
overscroll-behavior-inline: contain;
scrollbar-width: none;
}
.runtime-badges .status-badge#connectionBadge {
display: flex;
}
.runtime-badges::-webkit-scrollbar {
display: none;
}
.workspace {
display: block;
}
.command-panel {
width: auto;
max-height: none;
position: static;
padding: 22px max(18px, env(safe-area-inset-right)) 24px max(18px, env(safe-area-inset-left));
overflow: visible;
border-right: 0;
border-bottom: 1px solid var(--line);
}
.main-panel {
padding-right: max(16px, env(safe-area-inset-right));
padding-bottom: max(42px, env(safe-area-inset-bottom));
padding-left: max(16px, env(safe-area-inset-left));
}
.pipeline {
overflow-x: auto;
overscroll-behavior-inline: contain;
}
.pipeline-step {
min-width: 96px;
}
.gesture-drawer {
width: min(520px, 100vw);
padding-right: max(18px, env(safe-area-inset-right));
padding-bottom: max(22px, env(safe-area-inset-bottom));
padding-left: max(18px, env(safe-area-inset-left));
}
}
@media (max-width: 620px) {
.execution-mode-options {
grid-template-columns: 1fr;
}
.runtime-badges #executionBadge,
.pwa-badge {
display: none;
}
}
@media (orientation: landscape) and (max-height: 720px) and (min-width: 901px) {
.topbar {
min-height: 58px;
padding-top: 8px;
padding-bottom: 8px;
}
.workspace {
min-height: calc(100dvh - 58px);
}
.command-panel,
.main-panel {
padding-top: 18px;
}
}
+15
View File
@@ -0,0 +1,15 @@
ISC License
Copyright (c) for portions of Lucide are held by Cole Bemis 2013-2022 as part of Feather (MIT). All other copyright (c) for Lucide are held by Lucide Contributors 2022.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
File diff suppressed because one or more lines are too long
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+21
View File
@@ -0,0 +1,21 @@
The MIT License
Copyright © 2010-2022 three.js authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,87 @@
{
"schema_version": "1.0.0",
"validated_at": "2026-08-04T09:55:52+08:00",
"platform": "t2g_cabin_bench",
"adapter": {
"model": "USBCANFD-200U",
"device_type": 41,
"device_index": 0,
"driver_self_test": {
"passed": true,
"pointer_bits": 32,
"missing_exports": [],
"classic_frame_size": 16,
"can_fd_frame_size": 72,
"can_fd_tx_size": 76,
"can_fd_rx_size": 80
}
},
"channels": {
"seat_can": {
"channel": 0,
"format": "classic_can_11_bit",
"bitrate": 500000,
"diagnostic_self_reception": {
"frame_id": "0x7AA",
"payload_hex": "43 48 30 53 45 41 54 30",
"passed": true
},
"external_passive_observation_seconds": 6,
"external_frames_observed": 0,
"physical_feedback_verified": false
},
"body_can": {
"channel": 1,
"format": "iso_can_fd_11_bit",
"arbitration_bitrate": 500000,
"data_bitrate": 2000000,
"bitrate_switch": true,
"diagnostic_self_reception": {
"frame_id": "0x7AA",
"payload_hex": "43 48 31 2D 42 4F 44 59 2D 43 41 4E 46 44 21 21",
"payload_size": 16,
"passed": true
},
"external_passive_observation_seconds": 5,
"external_frames_observed": 0,
"physical_feedback_verified": false
}
},
"linked_request": {
"utterance": "关闭副驾座椅通风,同时关闭空调",
"dry_run": {
"status": "succeeded",
"function_configs": ["seat", "native_climate"],
"command_plans": ["seat", "native_climate"]
},
"hardware_attempts": [
{
"request_id": "req-20260804015505-713de5",
"status": "execution_failed",
"body_can": "0x1DE transmit rejected; channel_error=0x00000004",
"seat_can": "passive firmware signature not observed within 1200 ms; no seat control frame sent"
},
{
"request_id": "req-20260804015552-674fb4",
"status": "execution_failed",
"body_can": "0x1DE transmit rejected; channel_error=0x00000000",
"seat_can": "passive firmware signature not observed within 3500 ms; no seat control frame sent"
}
]
},
"verdict": {
"adapter_dual_channel_transport": "passed",
"classic_can_transport": "passed",
"iso_can_fd_brs_transport": "passed",
"one_sentence_compilation_and_routing": "passed",
"seat_ecu_closed_loop": "not_verified_no_external_frames",
"body_ecu_closed_loop": "not_verified_no_bus_ack_or_0x404_feedback",
"overall_hardware_requirement": "blocked_by_external_bus_connectivity_or_power"
},
"safety_cleanup": {
"seat_control_acknowledged": false,
"body_control_acknowledged": false,
"actuator_state_changed_by_verified_command": false,
"zcanpro_restarted": true
}
}
@@ -0,0 +1,267 @@
{
"suite": "ch1-vehicle-door-smoke-hil",
"started_with": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:26:38.774392Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 2751,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"finished_at": "2026-08-10T18:27:06.208449Z",
"results": [
{
"at": "2026-08-10T18:26:43.864787Z",
"module": "self_orchestration",
"case_id": "DOOR-VEHICLE-LOCK",
"status": "failed",
"duration_ms": 4032,
"safety_snapshot": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:26:39.775825Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 2256,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"error": "Ch1HilContractError: DOOR-VEHICLE-LOCK: request status is execution_failed"
},
{
"at": "2026-08-10T18:27:06.208449Z",
"module": "cleanup",
"case_id": "suite_finally",
"status": "passed",
"results": [
{
"case_id": "WINDOW-FRONT-LEFT-0",
"command": "window front-left position 0",
"http_status": 201,
"status": "passed",
"duration_ms": 2843,
"safety_snapshot": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:26:44.790088Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 2279,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"request_id": "req-20260810182644-0f4f23"
},
{
"case_id": "SHADE-POSITION-0",
"command": "shade position 0",
"http_status": 201,
"status": "passed",
"duration_ms": 2235,
"safety_snapshot": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:26:47.795715Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 2694,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"request_id": "req-20260810182647-436fd7"
},
{
"case_id": "DOOR-VEHICLE-UNLOCK",
"command": "door vehicle unlock",
"http_status": 201,
"status": "passed",
"duration_ms": 2906,
"safety_snapshot": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:26:49.802764Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 2017,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"request_id": "req-20260810182649-4a52a7"
},
{
"case_id": "SEAT-DRIVER-MASSAGE-OFF",
"command": "seat driver massage off",
"http_status": 201,
"status": "passed",
"duration_ms": 2500,
"safety_snapshot": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:26:52.820116Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 2374,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"request_id": "req-20260810182652-028f24"
},
{
"case_id": "SEAT-DRIVER-HEAT-OFF",
"command": "seat driver heat off",
"http_status": 201,
"status": "passed",
"duration_ms": 2000,
"safety_snapshot": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:26:54.817949Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 697,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"request_id": "req-20260810182654-200daa"
},
{
"case_id": "SEAT-DRIVER-VENT-OFF",
"command": "seat driver vent off",
"http_status": 201,
"status": "passed",
"duration_ms": 2000,
"safety_snapshot": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:26:56.821969Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 709,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"request_id": "req-20260810182656-77bc93"
},
{
"case_id": "CLIMATE-POWER-OFF",
"command": "ac off",
"http_status": 201,
"status": "passed",
"duration_ms": 1859,
"safety_snapshot": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:26:58.826087Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 735,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"request_id": "req-20260810182658-1509d2"
},
{
"case_id": "LIGHT-INDOOR-OFF",
"command": "light indoor off",
"http_status": 201,
"status": "passed",
"duration_ms": 1953,
"safety_snapshot": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:27:00.833034Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 1204,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"request_id": "req-20260810182700-64ded1"
},
{
"case_id": "AMBIENT-POWER-OFF",
"command": "light ambient off",
"http_status": 201,
"status": "passed",
"duration_ms": 2172,
"safety_snapshot": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:27:02.837333Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 1445,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"request_id": "req-20260810182702-78f422"
},
{
"case_id": "LIGHT-READING-ALL-OFF",
"command": "light reading all off",
"http_status": 201,
"status": "passed",
"duration_ms": 1875,
"safety_snapshot": {
"source": "physical_can_ch1",
"channel": 1,
"read_only": true,
"captured_at": "2026-08-10T18:27:04.842348Z",
"gear": "P",
"speed_kmh": 0.0,
"frame_count": 829,
"evidence": {
"gear_frame_id": "0x342",
"speed_frame_id": "0x4EB"
}
},
"request_id": "req-20260810182704-244a2c"
}
]
}
],
"summary": {
"total": 1,
"passed": 0,
"failed": 1,
"aborted_on_first_failure": true,
"cleanup_runs": 1,
"cleanup_failed": false,
"offline_rejection_cases": 24
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,63 @@
{
"validated_at": "2026-08-04",
"firmware_revision": 10,
"firmware_image_sha256": "85f9d67ff1efb36c37f38bb7584dffdbb6ecbee33bfc70ab491bad0d57da63b2",
"change": "remove delayed M1 clearance/catch-up and keep all four axes moving from the phase start",
"max_hall": [499, 374, 917, 647],
"known_range_home": {
"hall_before": [379, 255, 417, 416],
"hall_after": [0, 0, 0, 0],
"all_complete_ok": true,
"all_position_valid": true
},
"step_1_to_step_2": {
"start_hall": [391, 140, 406, 405],
"target_hall": [246, 281, 701, 494],
"observed_hall": [246, 281, 701, 494],
"four_axis_start_spread_s": 0.070,
"four_axis_arrival_spread_s": 0.342,
"cruise_checkpoint": {
"elapsed_s": 3.090,
"hall": [354, 202, 510, 468],
"normalized_progress": {
"longitudinal": 0.255,
"cushion_tilt": 0.440,
"backrest_recline": 0.353,
"legrest_height": 0.708
}
},
"result": "PASS"
},
"step_2_to_step_3": {
"start_hall": [246, 281, 701, 494],
"target_hall": [391, 140, 405, 404],
"observed_hall": [391, 140, 405, 404],
"four_axis_start_spread_s": 0.050,
"four_axis_arrival_spread_s": 0.339,
"cruise_checkpoint": {
"elapsed_s": 2.591,
"hall": [283, 226, 616, 435],
"normalized_progress": {
"longitudinal": 0.255,
"cushion_tilt": 0.390,
"backrest_recline": 0.287,
"legrest_height": 0.656
}
},
"result": "PASS"
},
"continuous_rollover": {
"next_cycle_all_four_axes_active": true,
"next_cycle_start_spread_s": 0.051,
"result": "PASS"
},
"stop_verification": {
"ack": 1,
"reject": 0,
"final_0x306": "00 00 00 00 00 00 00 00",
"active_mask": 0,
"fault_mask": 0,
"result": "PASS"
},
"result": "PASS"
}
@@ -0,0 +1,88 @@
{
"validated_at": "2026-08-04",
"firmware_revision": 9,
"firmware_image_sha256": "216f3f6b2d7c441f2050e99c2b9d54153a69b46466235232dec1b7ab7644b7c4",
"mode": "dynamic_cradle",
"coordinate_precondition": {
"motor": 1,
"operation": "HOME_KNOWN_RANGE",
"ack": 1,
"reject": 0,
"hall_before": 169,
"hall_after": 0,
"max_hall_preserved": 374,
"near": true,
"position_valid": true,
"result": "PASS"
},
"full_cycle": {
"entry_step_1": {
"target_hall": [391, 140, 405, 404],
"observed_hall": [392, 141, 405, 403]
},
"step_1_to_step_2": {
"target_hall": [246, 281, 701, 494],
"observed_hall": [246, 281, 701, 494],
"duration_s": 17.329,
"four_axis_start_spread_s": 0.077,
"four_axis_arrival_spread_s": 0.338,
"result": "PASS"
},
"step_2_to_step_3": {
"target_hall": [391, 140, 405, 404],
"observed_hall": [391, 140, 405, 405],
"duration_s": 15.155,
"four_axis_start_spread_s": 0.079,
"four_axis_arrival_spread_s": 0.495,
"result": "PASS"
},
"cycle_index_after_return": 1,
"fault_mask": 0,
"result": "PASS"
},
"continuous_rollover": {
"cycle_0_forward_start_spread_s": 0.052,
"cycle_0_return_start_spread_s": 0.053,
"cycle_1_forward_start_spread_s": 0.082,
"phase_transitions_s": [0.370, 17.888, 32.781],
"result": "PASS"
},
"step_3_to_step_1_semantics": "Step 3 and Step 1 have identical Hall targets, so their boundary has zero physical displacement. The ECU rolls the cycle index atomically and synchronously launches the next Step 1-to-Step 2 leg.",
"stop_verification": {
"stop_dynamic_sent": true,
"final_0x306": "00 00 00 00 00 00 00 00",
"result": "PASS"
},
"frontend_natural_language_hil": {
"start": {
"utterance": "开启动态摇篮模式",
"request_id": "req-20260804071706-45a1df",
"result": "SUCCEEDED",
"firmware_signature": "seat-controller-smv8-dynamic-modes-v9",
"command": "0x300 0E 10 06 00 02 00 00 00",
"ui_state": "动态摇篮模式 · 循环中 · 最长10分钟"
},
"active_physical_can_observation": {
"source": "physical_can",
"complete": true,
"moving_axes": {
"longitudinal_pct": 59,
"backrest_recline_pct": 75
},
"all_axes_position_valid": true,
"faults": false
},
"stop": {
"utterance": "关闭动态摇篮模式",
"request_id": "req-20260804072028-55179f",
"result": "SUCCEEDED",
"command": "0x300 0F 10 07 00 00 00 00 00",
"ui_state": "未运行",
"all_axes_stopped": true,
"all_axes_position_valid": true,
"faults": false
},
"hardware_access_after_test": "automatically released by the 180-second local idle policy",
"result": "PASS"
}
}
@@ -0,0 +1,343 @@
{
"mode": "rocking_horse",
"firmware_revision": 11,
"max_hall": [
499,
374,
917,
647
],
"homes": [
{
"motor": 0,
"hall_before": 349,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 21,
"opcode": 11,
"firmware_revision": 11
},
"terminal": {
"motor": 0,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 21,
"position_x100": 0
}
},
{
"motor": 1,
"hall_before": 163,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 22,
"opcode": 11,
"firmware_revision": 11
},
"terminal": {
"motor": 1,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 22,
"position_x100": 0
}
},
{
"motor": 2,
"hall_before": 534,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 23,
"opcode": 11,
"firmware_revision": 11
},
"terminal": {
"motor": 2,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 23,
"position_x100": 0
}
},
{
"motor": 3,
"hall_before": 456,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 24,
"opcode": 11,
"firmware_revision": 11
},
"terminal": {
"motor": 3,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 24,
"position_x100": 0
}
}
],
"start_ack": {
"ack": 1,
"reject": 0,
"sequence": 37,
"opcode": 14,
"firmware_revision": 11
},
"segments": [
{
"cycle_index": 0,
"phase": 2,
"phase_start": 262550.8121217,
"start_hall": [
320,
191,
500,
431
],
"first_active": {
"2": 262550.8883221,
"3": 262550.9146271,
"0": 262550.9401055,
"1": 262550.9661217
},
"arrival": {
"3": 262552.7830827,
"1": 262552.8335206,
"2": 262553.0696745,
"0": 262553.1213695
},
"cruise_checkpoint": {
"elapsed_s": 0.6343701000441797,
"hall": [
312,
201,
481,
417
],
"normalized_progress": [
0.26666666666666666,
0.3448275862068966,
0.475,
0.45161290322580644
]
},
"end_hall": [
290,
219,
460,
400
],
"start_spread_s": 0.07779960002517328,
"arrival_spread_s": 0.3382868000189774,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
290,
220,
460,
400
]
},
{
"cycle_index": 0,
"phase": 3,
"phase_start": 262553.4043395,
"start_hall": [
290,
219,
460,
400
],
"first_active": {
"2": 262553.4973208,
"3": 262553.5228996,
"0": 262553.5485228,
"1": 262553.5743734
},
"arrival": {
"3": 262557.0745088,
"1": 262557.1252219,
"2": 262557.2577929,
"0": 262557.3081852
},
"cruise_checkpoint": {
"elapsed_s": 1.079516199999489,
"hall": [
306,
199,
489,
422
],
"normalized_progress": [
0.26666666666666666,
0.3389830508474576,
0.3625,
0.36666666666666664
]
},
"end_hall": [
350,
160,
540,
460
],
"start_spread_s": 0.0770526000414975,
"arrival_spread_s": 0.23367639997741207,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
350,
160,
540,
460
]
},
{
"cycle_index": 1,
"phase": 2,
"phase_start": 262557.4375185,
"start_hall": [
350,
160,
540,
460
],
"first_active": {
"3": 262557.4893286,
"0": 262557.5161744,
"1": 262557.5424914,
"2": 262557.5696487
},
"arrival": {
"3": 262561.8903825,
"1": 262561.9425291,
"2": 262562.0729115,
"0": 262562.1245799
},
"cruise_checkpoint": {
"elapsed_s": 1.337460899958387,
"hall": [
335,
185,
498,
430
],
"normalized_progress": [
0.25,
0.4166666666666667,
0.525,
0.5
]
},
"end_hall": [
290,
220,
460,
400
],
"start_spread_s": 0.08032010000897571,
"arrival_spread_s": 0.23419739998644218,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
290,
220,
460,
400
]
},
{
"cycle_index": 1,
"phase": 3,
"phase_start": 262562.35135919997,
"start_hall": [
290,
220,
460,
400
],
"first_active": {
"3": 262562.3911222,
"0": 262562.4169718,
"1": 262562.4437546,
"2": 262562.4700679
},
"arrival": {
"3": 262566.0670384,
"1": 262566.1195433,
"2": 262566.1444,
"0": 262566.2991242
},
"cruise_checkpoint": {
"elapsed_s": 1.1310953000211157,
"hall": [
305,
198,
497,
423
],
"normalized_progress": [
0.25,
0.36666666666666664,
0.4625,
0.38333333333333336
]
},
"end_hall": [
350,
160,
540,
459
],
"start_spread_s": 0.07894570002099499,
"arrival_spread_s": 0.23208580003120005,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
350,
160,
540,
460
]
}
],
"repeat_first_active": {
"0": 262566.4901705,
"1": 262566.5153454,
"2": 262566.542698,
"3": 262566.5681911
},
"stop_ack": {
"ack": 1,
"reject": 0,
"sequence": 38,
"opcode": 15,
"firmware_revision": 11
},
"idle": {
"mode_id": 0,
"state": 0,
"phase": 0,
"active_mask": 0,
"fault_mask": 0,
"cycle_index": 0,
"phase_elapsed_ms": 0
}
}
@@ -0,0 +1,343 @@
{
"mode": "rocking_horse",
"firmware_revision": 12,
"max_hall": [
499,
374,
917,
647
],
"homes": [
{
"motor": 0,
"hall_before": 342,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 1,
"opcode": 11,
"firmware_revision": 12
},
"terminal": {
"motor": 0,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 1,
"position_x100": 0
}
},
{
"motor": 1,
"hall_before": 166,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 2,
"opcode": 11,
"firmware_revision": 12
},
"terminal": {
"motor": 1,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 2,
"position_x100": 0
}
},
{
"motor": 2,
"hall_before": 534,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 3,
"opcode": 11,
"firmware_revision": 12
},
"terminal": {
"motor": 2,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 3,
"position_x100": 0
}
},
{
"motor": 3,
"hall_before": 454,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 4,
"opcode": 11,
"firmware_revision": 12
},
"terminal": {
"motor": 3,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 4,
"position_x100": 0
}
}
],
"start_ack": {
"ack": 1,
"reject": 0,
"sequence": 17,
"opcode": 14,
"firmware_revision": 12
},
"segments": [
{
"cycle_index": 0,
"phase": 2,
"phase_start": 264077.9579478,
"start_hall": [
320,
191,
500,
430
],
"first_active": {
"0": 264078.038142,
"1": 264078.0663315,
"2": 264078.0774349,
"3": 264078.1169224
},
"arrival": {
"3": 264079.9439302,
"1": 264079.9959276,
"2": 264080.2325822,
"0": 264080.2840808
},
"cruise_checkpoint": {
"elapsed_s": 0.6441632999922149,
"hall": [
312,
214,
481,
416
],
"normalized_progress": [
0.26666666666666666,
0.3898305084745763,
0.475,
0.4666666666666667
]
},
"end_hall": [
290,
250,
460,
400
],
"start_spread_s": 0.07878040004288778,
"arrival_spread_s": 0.34015060000820085,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
290,
250,
460,
400
]
},
{
"cycle_index": 0,
"phase": 3,
"phase_start": 264080.62360189995,
"start_hall": [
290,
250,
460,
400
],
"first_active": {
"0": 264080.6481176,
"1": 264080.6733371,
"2": 264080.7001602,
"3": 264080.7257557
},
"arrival": {
"1": 264084.2944588,
"3": 264084.344339,
"0": 264084.475855,
"2": 264084.5271018
},
"cruise_checkpoint": {
"elapsed_s": 1.0275715000461787,
"hall": [
305,
206,
492,
421
],
"normalized_progress": [
0.25,
0.36666666666666664,
0.4,
0.35
]
},
"end_hall": [
350,
132,
540,
460
],
"start_spread_s": 0.07763810001779348,
"arrival_spread_s": 0.2326430000248365,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
350,
130,
540,
460
]
},
{
"cycle_index": 1,
"phase": 2,
"phase_start": 264084.65867120004,
"start_hall": [
350,
132,
540,
460
],
"first_active": {
"2": 264084.7388101,
"1": 264084.7410872,
"0": 264084.7599586,
"3": 264084.7926978
},
"arrival": {
"3": 264089.0549796,
"1": 264089.108405,
"0": 264089.3941196,
"2": 264089.4443601
},
"cruise_checkpoint": {
"elapsed_s": 1.391282099939417,
"hall": [
335,
187,
497,
429
],
"normalized_progress": [
0.25,
0.4661016949152542,
0.5375,
0.5166666666666667
]
},
"end_hall": [
290,
250,
460,
400
],
"start_spread_s": 0.05388769996352494,
"arrival_spread_s": 0.38938050001161173,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
290,
250,
460,
400
]
},
{
"cycle_index": 1,
"phase": 3,
"phase_start": 264089.7385309,
"start_hall": [
290,
250,
460,
400
],
"first_active": {
"1": 264089.857611,
"2": 264089.8838599,
"3": 264089.910015,
"0": 264089.938548
},
"arrival": {
"1": 264093.3849972,
"3": 264093.4384044,
"2": 264093.5165479,
"0": 264093.5667763
},
"cruise_checkpoint": {
"elapsed_s": 1.011584700027015,
"hall": [
305,
207,
492,
420
],
"normalized_progress": [
0.25,
0.35833333333333334,
0.4,
0.3333333333333333
]
},
"end_hall": [
350,
132,
540,
460
],
"start_spread_s": 0.08093699999153614,
"arrival_spread_s": 0.1817791000357829,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
350,
130,
540,
460
]
}
],
"repeat_first_active": {
"0": 264093.8496089,
"2": 264093.8578157,
"3": 264093.8843526,
"1": 264093.9379308
},
"stop_ack": {
"ack": 1,
"reject": 0,
"sequence": 18,
"opcode": 15,
"firmware_revision": 12
},
"idle": {
"mode_id": 0,
"state": 0,
"phase": 0,
"active_mask": 0,
"fault_mask": 0,
"cycle_index": 0,
"phase_elapsed_ms": 0
}
}
@@ -0,0 +1,343 @@
{
"mode": "rocking_horse",
"firmware_revision": 13,
"max_hall": [
499,
374,
917,
647
],
"homes": [
{
"motor": 0,
"hall_before": 326,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 1,
"opcode": 11,
"firmware_revision": 13
},
"terminal": {
"motor": 0,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 1,
"position_x100": 0
}
},
{
"motor": 1,
"hall_before": 138,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 2,
"opcode": 11,
"firmware_revision": 13
},
"terminal": {
"motor": 1,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 2,
"position_x100": 0
}
},
{
"motor": 2,
"hall_before": 532,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 3,
"opcode": 11,
"firmware_revision": 13
},
"terminal": {
"motor": 2,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 3,
"position_x100": 0
}
},
{
"motor": 3,
"hall_before": 451,
"hall_after": 0,
"ack": {
"ack": 1,
"reject": 0,
"sequence": 4,
"opcode": 11,
"firmware_revision": 13
},
"terminal": {
"motor": 3,
"task": 6,
"result": 2,
"active": false,
"position_valid": true,
"sequence": 4,
"position_x100": 0
}
}
],
"start_ack": {
"ack": 1,
"reject": 0,
"sequence": 17,
"opcode": 14,
"firmware_revision": 13
},
"segments": [
{
"cycle_index": 0,
"phase": 2,
"phase_start": 265437.2473564,
"start_hall": [
320,
190,
500,
430
],
"first_active": {
"2": 265437.2955111,
"3": 265437.3198522,
"0": 265437.346692,
"1": 265437.3733125
},
"arrival": {
"1": 265438.9329059,
"3": 265438.9846889,
"0": 265439.2201775,
"2": 265439.2731793
},
"cruise_checkpoint": {
"elapsed_s": 0.5042391999741085,
"hall": [
306,
209,
486,
419
],
"normalized_progress": [
0.28,
0.31666666666666665,
0.35,
0.36666666666666664
]
},
"end_hall": [
270,
250,
460,
400
],
"start_spread_s": 0.07780140003887936,
"arrival_spread_s": 0.34027340001193807,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
270,
250,
460,
400
]
},
{
"cycle_index": 0,
"phase": 3,
"phase_start": 265439.64164610003,
"start_hall": [
270,
250,
460,
400
],
"first_active": {
"2": 265439.6948618,
"3": 265439.7208077,
"0": 265439.7458537,
"1": 265439.7726268
},
"arrival": {
"1": 265442.9056772,
"3": 265442.9558483,
"2": 265443.0339587,
"0": 265443.0861803
},
"cruise_checkpoint": {
"elapsed_s": 0.8318679999792948,
"hall": [
295,
216,
484,
417
],
"normalized_progress": [
0.25,
0.2833333333333333,
0.3,
0.2833333333333333
]
},
"end_hall": [
370,
130,
540,
460
],
"start_spread_s": 0.07776499999454245,
"arrival_spread_s": 0.18050309998216107,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
370,
130,
540,
460
]
},
{
"cycle_index": 1,
"phase": 2,
"phase_start": 265443.25305889995,
"start_hall": [
370,
130,
540,
460
],
"first_active": {
"0": 265443.2954135,
"1": 265443.3206536,
"2": 265443.3348354,
"3": 265443.3728105
},
"arrival": {
"3": 265446.8221541,
"1": 265446.8749014,
"2": 265447.0045205,
"0": 265447.159461
},
"cruise_checkpoint": {
"elapsed_s": 1.084834800043609,
"hall": [
343,
175,
507,
436
],
"normalized_progress": [
0.27,
0.375,
0.4125,
0.4
]
},
"end_hall": [
270,
250,
460,
401
],
"start_spread_s": 0.07739699998637661,
"arrival_spread_s": 0.3373069000081159,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
270,
250,
460,
400
]
},
{
"cycle_index": 1,
"phase": 3,
"phase_start": 265447.3484032,
"start_hall": [
270,
250,
460,
401
],
"first_active": {
"1": 265447.3961179,
"0": 265447.400082,
"2": 265447.4222059,
"3": 265447.4483388
},
"arrival": {
"1": 265450.6434356,
"3": 265450.693563,
"2": 265450.7765666,
"0": 265450.8258244
},
"cruise_checkpoint": {
"elapsed_s": 0.9676259999978356,
"hall": [
297,
209,
490,
421
],
"normalized_progress": [
0.27,
0.3416666666666667,
0.375,
0.3389830508474576
]
},
"end_hall": [
370,
130,
540,
460
],
"start_spread_s": 0.05222090001916513,
"arrival_spread_s": 0.18238880002172664,
"all_axes_started": true,
"all_axes_arrived": true,
"target": [
370,
130,
540,
460
]
}
],
"repeat_first_active": {
"3": 265450.9977942,
"0": 265451.025777,
"2": 265451.0380102,
"1": 265451.0497914
},
"stop_ack": {
"ack": 1,
"reject": 0,
"sequence": 18,
"opcode": 15,
"firmware_revision": 13
},
"idle": {
"mode_id": 0,
"state": 0,
"phase": 0,
"active_mask": 0,
"fault_mask": 0,
"cycle_index": 0,
"phase_elapsed_ms": 0
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,764 @@
{
"suite": "t2g-seat-frontend-full-hil",
"started_at": "2026-08-01T14:53:29.226676Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801145329",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MODE-QUEEN",
"group": "mode",
"utterance": "副驾执行女王副驾行驶模式",
"started_at": "2026-08-01T14:53:29.226724Z",
"status": "failed",
"errors": [
"T2G motor 0 TIMEOUT: task_state=7, Hall=499->499"
],
"http_status": 201,
"request_id": "req-20260801145329-c441d5",
"failure_telemetry": {
"motor_selector": 0,
"motion_axis": "longitudinal",
"task_state": 7,
"motor_result": 6,
"motor_result_name": "TIMEOUT",
"position_valid": true,
"hall_before": 499,
"hall_after": 499,
"hall_delta": 0,
"endpoint_recovery_max_near_hall": 72,
"command_frame": {
"frame_id": "0x300",
"payload_size": 8,
"data_hex": "01 10 30 00 20 1C 30 75",
"timestamp": null
},
"ack_frame": {
"frame_id": "0x301",
"payload_size": 8,
"data_hex": "21 00 30 00 01 01 F0 4B",
"timestamp": 26444.37267
},
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 67 28 30 00 10 27 00",
"timestamp": 26450.902006
},
"diagnostic_before_frame": {
"frame_id": "0x303",
"payload_size": 8,
"data_hex": "00 00 F3 01 F3 01 00 90",
"timestamp": 26444.360963
},
"diagnostic_frame": {
"frame_id": "0x303",
"payload_size": 8,
"data_hex": "00 05 F3 01 F3 01 00 A0",
"timestamp": 26450.903153
},
"diagnostic_read_error": null,
"current_diagnostic": {
"sample_count": 65,
"valid_sample_count": 65,
"max_current_raw": 214,
"max_current_delta_raw": 213,
"high_current_seen": false,
"low_hall_seen": true,
"stall_overlap_seen": false,
"peak": {
"current_raw": 214,
"current_baseline_raw": 1,
"current_delta_raw": 213,
"stall_current_delta_threshold_raw": 500,
"current_sample_valid": true,
"current_baseline_valid": true,
"high_current": false,
"hall_activity_low": true,
"current_calibrating": false,
"frame": {
"frame_id": "0x304",
"payload_size": 8,
"data_hex": "00 0B D6 00 01 00 F4 01",
"timestamp": 26449.53215
}
},
"latest": {
"current_raw": 212,
"current_baseline_raw": 1,
"current_delta_raw": 211,
"stall_current_delta_threshold_raw": 500,
"current_sample_valid": true,
"current_baseline_valid": true,
"high_current": false,
"hall_activity_low": true,
"current_calibrating": false,
"frame": {
"frame_id": "0x304",
"payload_size": 8,
"data_hex": "00 0B D4 00 01 00 F4 01",
"timestamp": 26450.886864
}
}
},
"error_type": "HardwareExecutionError",
"stop_all_attempted": true,
"simulated": false
},
"finished_at": "2026-08-01T14:53:36.269029Z",
"duration_ms": 7042
},
{
"id": "MODE-BABY-NAP",
"group": "mode",
"utterance": "副驾执行宝宝午睡模式",
"status": "safety_blocked",
"started_at": "2026-08-01T14:53:36.269096Z",
"finished_at": "2026-08-01T14:53:36.269098Z",
"duration_ms": 0,
"errors": [],
"safety_block": {
"axis": "cushion_tilt",
"target_pct": 30,
"minimum_safe_target_pct": 35,
"reason": "M1 near-direction mechanical obstruction: repeated Hall stop at 122/123 with zero pulses and high current; do not drive toward the near endpoint until the mechanism is inspected.",
"evidence": {
"hall_count": 122,
"pulse_count": 0,
"peak_current_delta_raw": 1205,
"stall_threshold_raw": 500
}
}
},
{
"id": "MODE-CRUISE-SOFA",
"group": "mode",
"utterance": "副驾执行巡航沙发模式",
"status": "safety_blocked",
"started_at": "2026-08-01T14:53:36.269107Z",
"finished_at": "2026-08-01T14:53:36.269108Z",
"duration_ms": 0,
"errors": [],
"safety_block": {
"axis": "cushion_tilt",
"target_pct": 30,
"minimum_safe_target_pct": 35,
"reason": "M1 near-direction mechanical obstruction: repeated Hall stop at 122/123 with zero pulses and high current; do not drive toward the near endpoint until the mechanism is inspected.",
"evidence": {
"hall_count": 122,
"pulse_count": 0,
"peak_current_delta_raw": 1205,
"stall_threshold_raw": 500
}
}
},
{
"id": "MODE-MEDITATION",
"group": "mode",
"utterance": "副驾执行冥想空间模式",
"started_at": "2026-08-01T14:53:36.269121Z",
"status": "failed",
"errors": [
"T2G motor 1 STALL: task_state=7, Hall=374->374"
],
"http_status": 201,
"request_id": "req-20260801145336-cea6e3",
"failure_telemetry": {
"motor_selector": 1,
"motion_axis": "cushion_tilt",
"task_state": 7,
"motor_result": 5,
"motor_result_name": "STALL",
"position_valid": true,
"hall_before": 374,
"hall_after": 374,
"hall_delta": 0,
"endpoint_recovery_max_near_hall": 56,
"command_frame": {
"frame_id": "0x300",
"payload_size": 8,
"data_hex": "01 11 34 00 30 11 30 75",
"timestamp": null
},
"ack_frame": {
"frame_id": "0x301",
"payload_size": 8,
"data_hex": "21 00 34 00 01 02 F0 49",
"timestamp": 26453.41257
},
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 57 68 34 00 10 27 00",
"timestamp": 26462.801669
},
"diagnostic_before_frame": {
"frame_id": "0x303",
"payload_size": 8,
"data_hex": "01 00 76 01 76 01 00 B0",
"timestamp": 26451.441787
},
"diagnostic_frame": {
"frame_id": "0x303",
"payload_size": 8,
"data_hex": "01 14 76 01 76 01 00 C1",
"timestamp": 26462.802815
},
"diagnostic_read_error": null,
"current_diagnostic": {
"sample_count": 113,
"valid_sample_count": 113,
"max_current_raw": 1353,
"max_current_delta_raw": 1351,
"high_current_seen": true,
"low_hall_seen": true,
"stall_overlap_seen": true,
"peak": {
"current_raw": 1353,
"current_baseline_raw": 2,
"current_delta_raw": 1351,
"stall_current_delta_threshold_raw": 500,
"current_sample_valid": true,
"current_baseline_valid": true,
"high_current": true,
"hall_activity_low": false,
"current_calibrating": false,
"frame": {
"frame_id": "0x304",
"payload_size": 8,
"data_hex": "01 07 49 05 02 00 F4 01",
"timestamp": 26461.7585
}
},
"latest": {
"current_raw": 1199,
"current_baseline_raw": 2,
"current_delta_raw": 1197,
"stall_current_delta_threshold_raw": 500,
"current_sample_valid": true,
"current_baseline_valid": true,
"high_current": true,
"hall_activity_low": true,
"current_calibrating": false,
"frame": {
"frame_id": "0x304",
"payload_size": 8,
"data_hex": "01 0F AF 04 02 00 F4 01",
"timestamp": 26462.798972
}
}
},
"error_type": "HardwareExecutionError",
"stop_all_attempted": true,
"simulated": false
},
"finished_at": "2026-08-01T14:53:48.119388Z",
"duration_ms": 11850
},
{
"id": "MODE-LEISURE",
"group": "mode",
"utterance": "副驾执行休闲躺椅模式",
"status": "safety_blocked",
"started_at": "2026-08-01T14:53:48.119450Z",
"finished_at": "2026-08-01T14:53:48.119452Z",
"duration_ms": 0,
"errors": [],
"safety_block": {
"axis": "cushion_tilt",
"target_pct": 30,
"minimum_safe_target_pct": 35,
"reason": "M1 near-direction mechanical obstruction: repeated Hall stop at 122/123 with zero pulses and high current; do not drive toward the near endpoint until the mechanism is inspected.",
"evidence": {
"hall_count": 122,
"pulse_count": 0,
"peak_current_delta_raw": 1205,
"stall_threshold_raw": 500
}
}
},
{
"id": "MODE-CALF",
"group": "mode",
"utterance": "副驾执行小腿解压悬浮模式",
"started_at": "2026-08-01T14:53:48.119461Z",
"status": "failed",
"errors": [
"T2G motor 0 TIMEOUT: task_state=7, Hall=499->499"
],
"http_status": 201,
"request_id": "req-20260801145348-bae676",
"failure_telemetry": {
"motor_selector": 0,
"motion_axis": "longitudinal",
"task_state": 7,
"motor_result": 6,
"motor_result_name": "TIMEOUT",
"position_valid": true,
"hall_before": 499,
"hall_after": 499,
"hall_delta": 0,
"endpoint_recovery_max_near_hall": 72,
"command_frame": {
"frame_id": "0x300",
"payload_size": 8,
"data_hex": "01 10 37 00 EC 13 30 75",
"timestamp": null
},
"ack_frame": {
"frame_id": "0x301",
"payload_size": 8,
"data_hex": "21 00 37 00 01 01 F0 41",
"timestamp": 26463.239675
},
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 67 28 37 00 10 27 00",
"timestamp": 26469.752618
},
"diagnostic_before_frame": {
"frame_id": "0x303",
"payload_size": 8,
"data_hex": "00 00 F3 01 F3 01 00 10",
"timestamp": 26463.237716
},
"diagnostic_frame": {
"frame_id": "0x303",
"payload_size": 8,
"data_hex": "00 05 F3 01 F3 01 00 20",
"timestamp": 26469.754985
},
"diagnostic_read_error": null,
"current_diagnostic": {
"sample_count": 65,
"valid_sample_count": 65,
"max_current_raw": 253,
"max_current_delta_raw": 250,
"high_current_seen": false,
"low_hall_seen": true,
"stall_overlap_seen": false,
"peak": {
"current_raw": 253,
"current_baseline_raw": 3,
"current_delta_raw": 250,
"stall_current_delta_threshold_raw": 500,
"current_sample_valid": true,
"current_baseline_valid": true,
"high_current": false,
"hall_activity_low": false,
"current_calibrating": false,
"frame": {
"frame_id": "0x304",
"payload_size": 8,
"data_hex": "00 03 FD 00 03 00 F4 01",
"timestamp": 26463.272395
}
},
"latest": {
"current_raw": 207,
"current_baseline_raw": 3,
"current_delta_raw": 204,
"stall_current_delta_threshold_raw": 500,
"current_sample_valid": true,
"current_baseline_valid": true,
"high_current": false,
"hall_activity_low": true,
"current_calibrating": false,
"frame": {
"frame_id": "0x304",
"payload_size": 8,
"data_hex": "00 0B CF 00 03 00 F4 01",
"timestamp": 26469.728393
}
}
},
"error_type": "HardwareExecutionError",
"stop_all_attempted": true,
"simulated": false
},
"finished_at": "2026-08-01T14:53:55.135955Z",
"duration_ms": 7017
},
{
"id": "MODE-BEACH",
"group": "mode",
"utterance": "副驾执行电感沙滩椅模式",
"status": "safety_blocked",
"started_at": "2026-08-01T14:53:55.136004Z",
"finished_at": "2026-08-01T14:53:55.136006Z",
"duration_ms": 0,
"errors": [],
"safety_block": {
"axis": "cushion_tilt",
"target_pct": 0,
"minimum_safe_target_pct": 35,
"reason": "M1 near-direction mechanical obstruction: repeated Hall stop at 122/123 with zero pulses and high current; do not drive toward the near endpoint until the mechanism is inspected.",
"evidence": {
"hall_count": 122,
"pulse_count": 0,
"peak_current_delta_raw": 1205,
"stall_threshold_raw": 500
}
}
},
{
"id": "MODE-NAP",
"group": "mode",
"utterance": "副驾执行小憩模式",
"started_at": "2026-08-01T14:53:55.136014Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801145355-391520",
"matched_modes": [
"nap"
],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 28 3A 00 10 27 00",
"timestamp": 26476.732654
}
},
"cushion_tilt": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 28 3B 00 10 27 00",
"timestamp": 26476.759174
}
},
"backrest_recline": {
"position_pct": 81,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 8103,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 08 3C 00 A7 1F 00",
"timestamp": 26476.785245
}
},
"legrest_height": {
"position_pct": 94,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 9397,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 08 3D 00 B5 24 00",
"timestamp": 26476.810211
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 26476.820464
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 26476.820464
}
},
"captured_at": "2026-08-01T14:54:01.990826Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T14:54:02.155719Z",
"duration_ms": 7020
},
{
"id": "MODE-ZERO-GRAVITY",
"group": "mode",
"utterance": "副驾执行零重力模式",
"started_at": "2026-08-01T14:54:02.155796Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801145402-f6ff8b",
"matched_modes": [
"zero_gravity"
],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 28 3F 00 10 27 00",
"timestamp": 26483.63127
}
},
"cushion_tilt": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 28 40 00 10 27 00",
"timestamp": 26483.657826
}
},
"backrest_recline": {
"position_pct": 81,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 8103,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 08 41 00 A7 1F 00",
"timestamp": 26483.682735
}
},
"legrest_height": {
"position_pct": 94,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 9397,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 08 42 00 B5 24 00",
"timestamp": 26483.708846
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 26483.717983
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 26483.717983
}
},
"captured_at": "2026-08-01T14:54:08.888287Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T14:54:08.963843Z",
"duration_ms": 6808
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风",
"started_at": "2026-08-01T14:54:08.963900Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801145408-c833b5",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"legrest_height": {
"position_pct": 94,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 9397,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 08 42 00 B5 24 00",
"timestamp": 26484.485071
}
},
"longitudinal": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 28 3F 00 10 27 00",
"timestamp": 26484.511148
}
},
"cushion_tilt": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 28 40 00 10 27 00",
"timestamp": 26484.537248
}
},
"backrest_recline": {
"position_pct": 81,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 8103,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 08 41 00 A7 1F 00",
"timestamp": 26484.562609
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 26484.572862
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 26484.572862
}
},
"captured_at": "2026-08-01T14:54:09.742991Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T14:54:09.821001Z",
"duration_ms": 857
},
"finished_at": "2026-08-01T14:54:09.821038Z",
"summary": {
"total": 9,
"passed": 2,
"failed": 3,
"safety_blocked": 4,
"executed": 5,
"final_state_passed": true
}
}
@@ -0,0 +1,240 @@
{
"suite": "t2g-seat-frontend-full-hil",
"started_at": "2026-08-01T14:55:16.839705Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801145516",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-M0-HOME",
"group": "motion",
"utterance": "把副驾座椅水平位置归零",
"started_at": "2026-08-01T14:55:16.839746Z",
"status": "failed",
"errors": [
"T2G motor 0 CALIBRATION_FAILED: task_state=7, Hall=499->499"
],
"http_status": 201,
"request_id": "req-20260801145516-496358",
"failure_telemetry": {
"motor_selector": 0,
"motion_axis": "longitudinal",
"task_state": 7,
"motor_result": 11,
"motor_result_name": "CALIBRATION_FAILED",
"position_valid": false,
"hall_before": 499,
"hall_after": 499,
"hall_delta": 0,
"endpoint_recovery_max_near_hall": 72,
"command_frame": {
"frame_id": "0x300",
"payload_size": 8,
"data_hex": "0B 10 44 00 52 4B 78 00",
"timestamp": null
},
"ack_frame": {
"frame_id": "0x301",
"payload_size": 8,
"data_hex": "51 00 44 00 0B 41 F0 4F",
"timestamp": 26552.027376
},
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 B7 00 44 00 FF FF 00",
"timestamp": 26555.266451
},
"diagnostic_before_frame": {
"frame_id": "0x303",
"payload_size": 8,
"data_hex": "00 00 F3 01 F3 01 00 C0",
"timestamp": 26552.016761
},
"diagnostic_frame": {
"frame_id": "0x303",
"payload_size": 8,
"data_hex": "00 88 F3 01 F3 01 00 00",
"timestamp": 26555.267587
},
"diagnostic_read_error": null,
"current_diagnostic": {
"sample_count": 36,
"valid_sample_count": 36,
"max_current_raw": 223,
"max_current_delta_raw": 220,
"high_current_seen": false,
"low_hall_seen": true,
"stall_overlap_seen": false,
"peak": {
"current_raw": 223,
"current_baseline_raw": 3,
"current_delta_raw": 220,
"stall_current_delta_threshold_raw": 500,
"current_sample_valid": true,
"current_baseline_valid": true,
"high_current": false,
"hall_activity_low": false,
"current_calibrating": true,
"frame": {
"frame_id": "0x304",
"payload_size": 8,
"data_hex": "00 13 DF 00 03 00 F4 01",
"timestamp": 26552.116307
}
},
"latest": {
"current_raw": 10,
"current_baseline_raw": 23,
"current_delta_raw": 0,
"stall_current_delta_threshold_raw": 500,
"current_sample_valid": true,
"current_baseline_valid": true,
"high_current": false,
"hall_activity_low": true,
"current_calibrating": false,
"frame": {
"frame_id": "0x304",
"payload_size": 8,
"data_hex": "00 0B 0A 00 17 00 F4 01",
"timestamp": 26555.246382
}
}
},
"error_type": "HardwareExecutionError",
"stop_all_attempted": true,
"simulated": false
},
"finished_at": "2026-08-01T14:55:20.627987Z",
"duration_ms": 3788
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风",
"started_at": "2026-08-01T14:55:20.628029Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801145520-65fe81",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 81,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 2,
"value_x100": 8103,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 30 08 45 00 A7 1F 00",
"timestamp": 26556.1968
}
},
"legrest_height": {
"position_pct": 94,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 3,
"value_x100": 9397,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 30 08 45 00 B5 24 00",
"timestamp": 26556.222629
}
},
"longitudinal": {
"position_pct": 100,
"position_valid": false,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 0,
"value_x100": 65535,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 30 00 45 00 FF FF 00",
"timestamp": 26556.248442
}
},
"cushion_tilt": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 1,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 30 28 45 00 10 27 00",
"timestamp": 26556.274646
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 26556.283681
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 26556.283681
}
},
"captured_at": "2026-08-01T14:55:21.452124Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T14:55:21.531805Z",
"duration_ms": 904
},
"finished_at": "2026-08-01T14:55:21.531835Z",
"summary": {
"total": 1,
"passed": 0,
"failed": 1,
"safety_blocked": 0,
"executed": 1,
"final_state_passed": true
}
}
@@ -0,0 +1,62 @@
{
"suite": "t2g-seat-frontend-full-hil",
"started_at": "2026-08-01T15:32:33.035150Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801153233",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-M0-HOME",
"group": "motion",
"utterance": "把副驾座椅水平位置归零",
"started_at": "2026-08-01T15:32:33.035187Z",
"status": "failed",
"errors": [
"ZCAN_SetValue(canfd_abit_baud_rate) failed"
],
"http_status": 201,
"request_id": "req-20260801153233-4d8760",
"failure_telemetry": {
"error_type": "CanGatewayError",
"stop_all_attempted": false,
"simulated": false
},
"finished_at": "2026-08-01T15:32:33.233128Z",
"duration_ms": 198
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风",
"started_at": "2026-08-01T15:32:33.233166Z",
"status": "failed",
"errors": [
"ZCAN_SetValue(canfd_abit_baud_rate) failed"
],
"http_status": 201,
"request_id": "req-20260801153233-dc02d8",
"failure_telemetry": {
"error_type": "CanGatewayError",
"stop_all_attempted": false,
"simulated": false
},
"finished_at": "2026-08-01T15:32:33.390312Z",
"duration_ms": 157
},
"finished_at": "2026-08-01T15:32:33.390330Z",
"summary": {
"total": 1,
"passed": 0,
"failed": 1,
"safety_blocked": 0,
"executed": 1,
"final_state_passed": false
}
}
@@ -0,0 +1,240 @@
{
"suite": "t2g-seat-frontend-full-hil",
"started_at": "2026-08-01T15:38:36.967401Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801153836",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-M0-HOME",
"group": "motion",
"utterance": "把副驾座椅水平位置归零",
"started_at": "2026-08-01T15:38:36.967442Z",
"status": "failed",
"errors": [
"T2G motor 0 CALIBRATION_FAILED: task_state=7, Hall=499->499"
],
"http_status": 201,
"request_id": "req-20260801153836-3cd030",
"failure_telemetry": {
"motor_selector": 0,
"motion_axis": "longitudinal",
"task_state": 7,
"motor_result": 11,
"motor_result_name": "CALIBRATION_FAILED",
"position_valid": false,
"hall_before": 499,
"hall_after": 499,
"hall_delta": 0,
"endpoint_recovery_max_near_hall": 72,
"command_frame": {
"frame_id": "0x300",
"payload_size": 8,
"data_hex": "0B 10 02 00 52 4B 78 00",
"timestamp": null
},
"ack_frame": {
"frame_id": "0x301",
"payload_size": 8,
"data_hex": "51 00 02 00 0B 41 E0 55",
"timestamp": 29165.165292
},
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 B7 00 02 00 FF FF 00",
"timestamp": 29168.401573
},
"diagnostic_before_frame": {
"frame_id": "0x303",
"payload_size": 8,
"data_hex": "00 00 F3 01 F3 01 00 20",
"timestamp": 29165.154003
},
"diagnostic_frame": {
"frame_id": "0x303",
"payload_size": 8,
"data_hex": "00 88 F3 01 F3 01 00 60",
"timestamp": 29168.402701
},
"diagnostic_read_error": null,
"current_diagnostic": {
"sample_count": 36,
"valid_sample_count": 36,
"max_current_raw": 238,
"max_current_delta_raw": 233,
"high_current_seen": false,
"low_hall_seen": true,
"stall_overlap_seen": false,
"peak": {
"current_raw": 236,
"current_baseline_raw": 3,
"current_delta_raw": 233,
"stall_current_delta_threshold_raw": 500,
"current_sample_valid": true,
"current_baseline_valid": true,
"high_current": false,
"hall_activity_low": false,
"current_calibrating": true,
"frame": {
"frame_id": "0x304",
"payload_size": 8,
"data_hex": "00 13 EC 00 03 00 F4 01",
"timestamp": 29165.251397
}
},
"latest": {
"current_raw": 12,
"current_baseline_raw": 36,
"current_delta_raw": 0,
"stall_current_delta_threshold_raw": 500,
"current_sample_valid": true,
"current_baseline_valid": true,
"high_current": false,
"hall_activity_low": true,
"current_calibrating": false,
"frame": {
"frame_id": "0x304",
"payload_size": 8,
"data_hex": "00 0B 0C 00 24 00 F4 01",
"timestamp": 29168.379476
}
}
},
"error_type": "HardwareExecutionError",
"stop_all_attempted": true,
"simulated": false
},
"finished_at": "2026-08-01T15:38:53.697878Z",
"duration_ms": 16730
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风",
"started_at": "2026-08-01T15:38:53.697934Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801153853-1d639f",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"cushion_tilt": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 1,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 30 28 03 00 10 27 00",
"timestamp": 29169.295418
}
},
"backrest_recline": {
"position_pct": 81,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 2,
"value_x100": 8103,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 30 08 03 00 A7 1F 00",
"timestamp": 29169.322276
}
},
"legrest_height": {
"position_pct": 94,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 3,
"value_x100": 9397,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 30 08 03 00 B5 24 00",
"timestamp": 29169.347323
}
},
"longitudinal": {
"position_pct": 100,
"position_valid": false,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 0,
"value_x100": 65535,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 30 00 03 00 FF FF 00",
"timestamp": 29169.374233
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 29169.380975
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 29169.380975
}
},
"captured_at": "2026-08-01T15:38:54.491848Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T15:38:54.576238Z",
"duration_ms": 878
},
"finished_at": "2026-08-01T15:38:54.576286Z",
"summary": {
"total": 1,
"passed": 0,
"failed": 1,
"safety_blocked": 0,
"executed": 1,
"final_state_passed": true
}
}
@@ -0,0 +1,363 @@
{
"suite": "t2g-seat-frontend-full-hil",
"started_at": "2026-08-01T15:43:36.160681Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801154336",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "THERM-H-OFF",
"group": "thermal",
"utterance": "关闭副驾座椅加热",
"started_at": "2026-08-01T15:43:36.160725Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801154336-0eefe8",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 81,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 2,
"value_x100": 8103,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 00 08 00 00 A7 1F 00",
"timestamp": 29463.233038
}
},
"legrest_height": {
"position_pct": 94,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 3,
"value_x100": 9397,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 00 08 00 00 B5 24 00",
"timestamp": 29463.259912
}
},
"longitudinal": {
"position_pct": 100,
"position_valid": false,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 0,
"value_x100": 65535,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 00 00 00 00 FF FF 00",
"timestamp": 29463.284973
}
},
"cushion_tilt": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 1,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 00 28 00 00 10 27 00",
"timestamp": 29463.311881
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 29463.319822
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 29463.319822
}
},
"captured_at": "2026-08-01T15:43:48.424601Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T15:43:48.512170Z",
"duration_ms": 12351
},
{
"id": "THERM-V-OFF",
"group": "thermal",
"utterance": "关闭副驾座椅通风",
"started_at": "2026-08-01T15:43:48.512241Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801154348-d8018c",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 81,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 2,
"value_x100": 8103,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 00 08 00 00 A7 1F 00",
"timestamp": 29464.079538
}
},
"legrest_height": {
"position_pct": 94,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 3,
"value_x100": 9397,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 00 08 00 00 B5 24 00",
"timestamp": 29464.105253
}
},
"longitudinal": {
"position_pct": 100,
"position_valid": false,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 0,
"value_x100": 65535,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 00 00 00 00 FF FF 00",
"timestamp": 29464.131102
}
},
"cushion_tilt": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 1,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 00 28 00 00 10 27 00",
"timestamp": 29464.157968
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 29464.165819
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 29464.165819
}
},
"captured_at": "2026-08-01T15:43:49.270734Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T15:43:49.336080Z",
"duration_ms": 824
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风",
"started_at": "2026-08-01T15:43:49.336131Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801154349-f42e7f",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"cushion_tilt": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 1,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 00 28 00 00 10 27 00",
"timestamp": 29464.904964
}
},
"backrest_recline": {
"position_pct": 81,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 2,
"value_x100": 8103,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 00 08 00 00 A7 1F 00",
"timestamp": 29464.931901
}
},
"legrest_height": {
"position_pct": 94,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 3,
"value_x100": 9397,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 00 08 00 00 B5 24 00",
"timestamp": 29464.95768
}
},
"longitudinal": {
"position_pct": 100,
"position_valid": false,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 0,
"value_x100": 65535,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 00 00 00 00 FF FF 00",
"timestamp": 29464.98386
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 29464.990659
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 29464.990659
}
},
"captured_at": "2026-08-01T15:43:50.095435Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T15:43:50.176751Z",
"duration_ms": 841
},
"finished_at": "2026-08-01T15:43:50.176781Z",
"summary": {
"total": 2,
"passed": 2,
"failed": 0,
"safety_blocked": 0,
"executed": 2,
"final_state_passed": true
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,250 @@
{
"suite": "t2g-seat-frontend-full-hil",
"started_at": "2026-08-01T17:39:16.430915Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801173916",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-ALL-ZERO",
"group": "motion",
"utterance": "把副驾水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-01T17:39:16.430950Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801173916-90206d",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 6D 01 00 00 00",
"timestamp": 36459.051975
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 6E 01 00 00 00",
"timestamp": 36459.077734
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 6F 01 00 00 00",
"timestamp": 36459.104324
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 6C 01 00 00 00",
"timestamp": 36459.129781
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 36459.136472
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 36459.136472
}
},
"captured_at": "2026-08-01T17:40:24.101369Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T17:40:24.299645Z",
"duration_ms": 67869
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风",
"started_at": "2026-08-01T17:40:24.299777Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801174024-2bef93",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 6C 01 00 00 00",
"timestamp": 36460.001759
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 6D 01 00 00 00",
"timestamp": 36460.028327
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 6E 01 00 00 00",
"timestamp": 36460.055218
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 6F 01 00 00 00",
"timestamp": 36460.08066
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 36460.087354
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 36460.087354
}
},
"captured_at": "2026-08-01T17:40:25.052281Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T17:40:25.130245Z",
"duration_ms": 830
},
"finished_at": "2026-08-01T17:40:25.130276Z",
"summary": {
"total": 1,
"passed": 1,
"failed": 0,
"safety_blocked": 0,
"executed": 1,
"final_state_passed": true
}
}
@@ -0,0 +1,823 @@
{
"suite": "t2g-seat-frontend-comprehensive-hil",
"started_at": "2026-08-01T22:06:10.662623Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801220610",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-M0-ABS-DECIMAL-ROUND",
"group": "motion",
"utterance": "副驾座椅水平位置调到50.5%",
"started_at": "2026-08-01T22:06:33.819391Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801220633-35a9ee",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 30 18 0B 00 00 00 00",
"timestamp": 52437.943305
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 30 18 0B 00 00 00 00",
"timestamp": 52437.968795
}
},
"longitudinal": {
"position_pct": 51,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 5110,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 08 0C 00 F6 13 00",
"timestamp": 52437.995098
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 30 18 0B 00 00 00 00",
"timestamp": 52438.021395
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52438.031724
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52438.031724
}
},
"captured_at": "2026-08-01T22:06:42.683267Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T22:06:42.768028Z",
"duration_ms": 8949
},
{
"id": "MOTION-M0-ABS-NEGATIVE-CLAMP",
"group": "motion",
"utterance": "副驾座椅水平位置调到-10%",
"started_at": "2026-08-01T22:06:42.768083Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801220642-ffc18b",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 30 18 0D 00 00 00 00",
"timestamp": 52448.169066
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 30 18 0D 00 00 00 00",
"timestamp": 52448.196
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 30 18 0D 00 00 00 00",
"timestamp": 52448.221821
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 0E 00 00 00 00",
"timestamp": 52448.247656
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52448.255615
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52448.255615
}
},
"captured_at": "2026-08-01T22:06:52.906777Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T22:06:52.966157Z",
"duration_ms": 10198
},
{
"id": "MOTION-M2-TIMED-ZERO-MIN-CLAMP",
"group": "motion",
"utterance": "副驾靠背向后移动0秒",
"started_at": "2026-08-01T22:06:52.966239Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801220652-ebe458",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 30 18 0F 00 00 00 00",
"timestamp": 52449.295516
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 30 18 0F 00 00 00 00",
"timestamp": 52449.321809
}
},
"backrest_recline": {
"position_pct": 1,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 120,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 08 10 00 78 00 00",
"timestamp": 52449.347017
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 30 18 0F 00 00 00 00",
"timestamp": 52449.37364
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52449.382777
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52449.382777
}
},
"captured_at": "2026-08-01T22:06:54.033862Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T22:06:54.110745Z",
"duration_ms": 1145
},
{
"id": "MODEL-FUZZY-COMFORT-ONLY",
"group": "model",
"utterance": "把座椅调舒服一点",
"started_at": "2026-08-01T22:06:54.110804Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801220654-5f0af4",
"provider_used": "openai:gpt-5.6-sol",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"legrest_height": {
"position_pct": 10,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 1005,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 08 15 00 ED 03 00",
"timestamp": 52491.95849
}
},
"longitudinal": {
"position_pct": 80,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 8016,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 08 12 00 50 1F 00",
"timestamp": 52491.984306
}
},
"cushion_tilt": {
"position_pct": 30,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 2995,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 08 13 00 B3 0B 00",
"timestamp": 52492.010881
}
},
"backrest_recline": {
"position_pct": 35,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 3501,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 08 14 00 AD 0D 00",
"timestamp": 52492.036223
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52492.046648
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52492.046648
}
},
"captured_at": "2026-08-01T22:07:36.697054Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T22:07:36.773665Z",
"duration_ms": 42663
},
{
"id": "MODEL-UNKNOWN-BOSS-MODE",
"group": "model",
"utterance": "打开老板模式",
"started_at": "2026-08-01T22:07:36.773730Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801220736-be8392",
"provider_used": "openai:gpt-5.6-sol",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 1A 00 00 00 00",
"timestamp": 52526.819003
}
},
"longitudinal": {
"position_pct": 20,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 2004,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 08 17 00 D4 07 00",
"timestamp": 52526.845094
}
},
"cushion_tilt": {
"position_pct": 30,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 2995,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 08 18 00 B3 0B 00",
"timestamp": 52526.87121
}
},
"backrest_recline": {
"position_pct": 10,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 1003,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 08 19 00 EB 03 00",
"timestamp": 52526.897575
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52526.90671
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52526.90671
}
},
"captured_at": "2026-08-01T22:08:11.556208Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T22:08:11.634298Z",
"duration_ms": 34861
}
],
"position_memory_sync": {
"id": "PREFLIGHT-POSITION-MEMORY-SYNC",
"group": "preflight",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-01T22:06:10.662651Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801220610-fe1cde",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 0A 00 00 00 00",
"timestamp": 52428.988603
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 07 00 00 00 00",
"timestamp": 52429.015565
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 08 00 00 00 00",
"timestamp": 52429.041376
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 09 00 00 00 00",
"timestamp": 52429.06754
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52429.075411
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52429.075411
}
},
"captured_at": "2026-08-01T22:06:33.726921Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T22:06:33.819288Z",
"duration_ms": 23157
},
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-01T22:08:11.634351Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801220811-9d1330",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 1D 00 00 00 00",
"timestamp": 52552.285415
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 1E 00 00 00 00",
"timestamp": 52552.311577
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 1F 00 00 00 00",
"timestamp": 52552.337346
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 1C 00 00 00 00",
"timestamp": 52552.364354
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52552.372264
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 52552.372264
}
},
"captured_at": "2026-08-01T22:08:37.021239Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T22:08:37.100192Z",
"duration_ms": 25466
},
"finished_at": "2026-08-01T22:08:37.100232Z",
"summary": {
"total": 5,
"passed": 5,
"failed": 0,
"safety_blocked": 0,
"executed": 5,
"position_memory_sync_passed": true,
"final_state_passed": true
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,364 @@
{
"suite": "t2g-seat-frontend-comprehensive-hil",
"started_at": "2026-08-01T20:30:03.347380Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801203003",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MODEL-FUZZY-CRAMPED-COMFORT",
"group": "model",
"utterance": "前舱空间太挤了,把座椅调整到舒服的位置",
"started_at": "2026-08-01T20:30:43.772650Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801203043-6dba03",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 35,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 3501,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 08 09 00 AD 0D 00",
"timestamp": 46720.941274
}
},
"legrest_height": {
"position_pct": 10,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 1005,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 08 0A 00 ED 03 00",
"timestamp": 46720.967852
}
},
"longitudinal": {
"position_pct": 80,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 8016,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 08 07 00 50 1F 00",
"timestamp": 46720.993263
}
},
"cushion_tilt": {
"position_pct": 30,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 2995,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 08 08 00 B3 0B 00",
"timestamp": 46721.019784
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 46721.030217
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 46721.030217
}
},
"captured_at": "2026-08-01T20:31:25.795596Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T20:31:25.863040Z",
"duration_ms": 42090
}
],
"position_memory_sync": {
"id": "PREFLIGHT-POSITION-MEMORY-SYNC",
"group": "preflight",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-01T20:30:03.347411Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801203003-f00e7a",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 03 00 00 00 00",
"timestamp": 46678.830874
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 04 00 00 00 00",
"timestamp": 46678.856952
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 05 00 00 00 00",
"timestamp": 46678.882795
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 02 00 00 00 00",
"timestamp": 46678.908649
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 46678.916532
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 46678.916532
}
},
"captured_at": "2026-08-01T20:30:43.683001Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T20:30:43.772568Z",
"duration_ms": 40425
},
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-01T20:31:25.863092Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801203125-a4af68",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 0C 00 00 00 00",
"timestamp": 46759.956435
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 0D 00 00 00 00",
"timestamp": 46759.982688
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 0E 00 00 00 00",
"timestamp": 46760.008938
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 0F 00 00 00 00",
"timestamp": 46760.041009
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 46760.053878
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 46760.053878
}
},
"captured_at": "2026-08-01T20:32:04.818553Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T20:32:04.895597Z",
"duration_ms": 39033
},
"finished_at": "2026-08-01T20:32:04.895635Z",
"summary": {
"total": 1,
"passed": 1,
"failed": 0,
"safety_blocked": 0,
"executed": 1,
"position_memory_sync_passed": true,
"final_state_passed": true
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,250 @@
{
"suite": "t2g-seat-frontend-full-hil",
"started_at": "2026-08-01T17:16:40.264559Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801171640",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-ALL-ZERO",
"group": "motion",
"utterance": "把副驾水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-01T17:16:40.264614Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801171640-4a5f1e",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 19 01 00 00 00",
"timestamp": 35105.608647
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 1A 01 00 00 00",
"timestamp": 35105.634423
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 17 01 00 00 00",
"timestamp": 35105.661016
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 18 01 00 00 00",
"timestamp": 35105.68652
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35105.692065
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35105.692065
}
},
"captured_at": "2026-08-01T17:17:50.683023Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T17:17:50.762718Z",
"duration_ms": 70498
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风",
"started_at": "2026-08-01T17:17:50.762772Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801171750-2f0f2f",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 19 01 00 00 00",
"timestamp": 35106.475011
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 1A 01 00 00 00",
"timestamp": 35106.500476
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 17 01 00 00 00",
"timestamp": 35106.526322
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 18 01 00 00 00",
"timestamp": 35106.552849
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35106.558466
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35106.558466
}
},
"captured_at": "2026-08-01T17:17:51.549417Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T17:17:51.636183Z",
"duration_ms": 873
},
"finished_at": "2026-08-01T17:17:51.636217Z",
"summary": {
"total": 1,
"passed": 1,
"failed": 0,
"safety_blocked": 0,
"executed": 1,
"final_state_passed": true
}
}
@@ -0,0 +1,363 @@
{
"suite": "t2g-seat-frontend-full-hil",
"started_at": "2026-08-01T16:40:47.172484Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801164047",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "THERM-H-OFF",
"group": "thermal",
"utterance": "关闭副驾座椅加热",
"started_at": "2026-08-01T16:40:47.172525Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801164047-8cddb4",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 00 18 00 00 00 00 00",
"timestamp": 32897.543083
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 00 18 00 00 00 00 00",
"timestamp": 32897.568506
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 00 18 00 00 00 00 00",
"timestamp": 32897.595022
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 00 18 00 00 00 00 00",
"timestamp": 32897.620753
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 32897.62524
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 32897.62524
}
},
"captured_at": "2026-08-01T16:41:02.659736Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T16:41:02.738362Z",
"duration_ms": 15566
},
{
"id": "THERM-V-OFF",
"group": "thermal",
"utterance": "关闭副驾座椅通风",
"started_at": "2026-08-01T16:41:02.738421Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801164102-401927",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 00 18 00 00 00 00 00",
"timestamp": 32898.36913
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 00 18 00 00 00 00 00",
"timestamp": 32898.394558
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 00 18 00 00 00 00 00",
"timestamp": 32898.421367
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 00 18 00 00 00 00 00",
"timestamp": 32898.446823
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 32898.453497
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 32898.453497
}
},
"captured_at": "2026-08-01T16:41:03.487981Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T16:41:03.570272Z",
"duration_ms": 832
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风",
"started_at": "2026-08-01T16:41:03.570317Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801164103-4efef7",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 00 18 00 00 00 00 00",
"timestamp": 32899.183035
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 00 18 00 00 00 00 00",
"timestamp": 32899.209498
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 00 18 00 00 00 00 00",
"timestamp": 32899.23527
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 0,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 00 18 00 00 00 00 00",
"timestamp": 32899.260679
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 32899.267388
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 32899.267388
}
},
"captured_at": "2026-08-01T16:41:04.301854Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T16:41:04.424088Z",
"duration_ms": 854
},
"finished_at": "2026-08-01T16:41:04.424118Z",
"summary": {
"total": 2,
"passed": 2,
"failed": 0,
"safety_blocked": 0,
"executed": 2,
"final_state_passed": true
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,250 @@
{
"suite": "t2g-seat-frontend-full-hil",
"started_at": "2026-08-01T17:32:24.627065Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801173224",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-ALL-ZERO",
"group": "motion",
"utterance": "把副驾水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-01T17:32:24.627106Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801173224-cedf76",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 30 01 00 00 00",
"timestamp": 36047.100786
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 31 01 00 00 00",
"timestamp": 36047.126273
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 32 01 00 00 00",
"timestamp": 36047.152829
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 33 01 00 00 00",
"timestamp": 36047.178304
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 36047.185019
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 36047.185019
}
},
"captured_at": "2026-08-01T17:33:32.157834Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T17:33:32.231664Z",
"duration_ms": 67605
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风",
"started_at": "2026-08-01T17:33:32.231720Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801173332-3d22e2",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 30 01 00 00 00",
"timestamp": 36047.928676
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 31 01 00 00 00",
"timestamp": 36047.954191
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 32 01 00 00 00",
"timestamp": 36047.980699
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 33 01 00 00 00",
"timestamp": 36048.006522
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 36048.013163
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 36048.013163
}
},
"captured_at": "2026-08-01T17:33:32.986103Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T17:33:33.067889Z",
"duration_ms": 836
},
"finished_at": "2026-08-01T17:33:33.067920Z",
"summary": {
"total": 1,
"passed": 1,
"failed": 0,
"safety_blocked": 0,
"executed": 1,
"final_state_passed": true
}
}
@@ -0,0 +1,250 @@
{
"suite": "t2g-seat-frontend-full-hil",
"started_at": "2026-08-01T17:26:35.994926Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801172635",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-ALL-ZERO",
"group": "motion",
"utterance": "把副驾水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-01T17:26:35.994963Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801172635-cf368d",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 23 01 00 00 00",
"timestamp": 35698.280073
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 24 01 00 00 00",
"timestamp": 35698.306668
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 21 01 00 00 00",
"timestamp": 35698.332116
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 22 01 00 00 00",
"timestamp": 35698.357889
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35698.36569
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35698.36569
}
},
"captured_at": "2026-08-01T17:27:43.345246Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T17:27:43.418173Z",
"duration_ms": 67423
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风",
"started_at": "2026-08-01T17:27:43.418231Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801172743-1f95ae",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 23 01 00 00 00",
"timestamp": 35699.098847
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 24 01 00 00 00",
"timestamp": 35699.124304
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 21 01 00 00 00",
"timestamp": 35699.150901
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 22 01 00 00 00",
"timestamp": 35699.176715
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35699.184476
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35699.184476
}
},
"captured_at": "2026-08-01T17:27:44.164137Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T17:27:44.276096Z",
"duration_ms": 858
},
"finished_at": "2026-08-01T17:27:44.276129Z",
"summary": {
"total": 1,
"passed": 1,
"failed": 0,
"safety_blocked": 0,
"executed": 1,
"final_state_passed": true
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,252 @@
{
"suite": "t2g-seat-frontend-full-hil",
"started_at": "2026-08-01T17:32:02.775803Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801173202",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MODE-ZERO-GRAVITY",
"group": "mode",
"utterance": "打开零重力模式",
"started_at": "2026-08-01T17:32:02.775839Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801173202-68d1da",
"matched_modes": [
"zero_gravity"
],
"state_http_status": 200,
"physical_state": {
"position": {
"cushion_tilt": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 28 2C 01 10 27 00",
"timestamp": 35964.438236
}
},
"backrest_recline": {
"position_pct": 81,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 8103,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 08 2D 01 A7 1F 00",
"timestamp": 35964.464297
}
},
"legrest_height": {
"position_pct": 94,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 9397,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 08 2E 01 B5 24 00",
"timestamp": 35964.490843
}
},
"longitudinal": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 28 2B 01 10 27 00",
"timestamp": 35964.51698
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35964.526089
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35964.526089
}
},
"captured_at": "2026-08-01T17:32:09.500643Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T17:32:09.582995Z",
"duration_ms": 6807
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风",
"started_at": "2026-08-01T17:32:09.583051Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801173209-29898b",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 28 2B 01 10 27 00",
"timestamp": 35965.246437
}
},
"cushion_tilt": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 28 2C 01 10 27 00",
"timestamp": 35965.27405
}
},
"backrest_recline": {
"position_pct": 81,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 8103,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 08 2D 01 A7 1F 00",
"timestamp": 35965.3002
}
},
"legrest_height": {
"position_pct": 94,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 9397,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 08 2E 01 B5 24 00",
"timestamp": 35965.326337
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35965.334306
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 35965.334306
}
},
"captured_at": "2026-08-01T17:32:10.308851Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T17:32:10.379863Z",
"duration_ms": 797
},
"finished_at": "2026-08-01T17:32:10.379894Z",
"summary": {
"total": 1,
"passed": 1,
"failed": 0,
"safety_blocked": 0,
"executed": 1,
"final_state_passed": true
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,825 @@
{
"suite": "t2g-seat-frontend-comprehensive-hil",
"started_at": "2026-08-07T18:17:38.577477Z",
"base_url": "http://127.0.0.1:8003",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260807181738",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MODE-ROCKING-HORSE-START",
"group": "mode",
"utterance": "开启木马模式",
"started_at": "2026-08-07T18:18:01.681906Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260807181801-e5096b",
"provider_used": "local_rules",
"matched_modes": [
"rocking_horse"
],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 2,
"position_valid": true,
"motion_state": "moving",
"fault": false,
"task_state": 2,
"motor_result": 1,
"motor_selector": 2,
"value_x100": 153,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 12 0D 35 00 99 00 5A",
"timestamp": 106973.993523,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"legrest_height": {
"position_pct": 2,
"position_valid": true,
"motion_state": "moving",
"fault": false,
"task_state": 2,
"motor_result": 1,
"motor_selector": 3,
"value_x100": 216,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 12 0D 35 00 D8 00 5A",
"timestamp": 106974.0196,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"longitudinal": {
"position_pct": 2,
"position_valid": true,
"motion_state": "moving",
"fault": false,
"task_state": 2,
"motor_result": 1,
"motor_selector": 0,
"value_x100": 240,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 12 0D 35 00 F0 00 5A",
"timestamp": 106974.045704,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"cushion_tilt": {
"position_pct": 6,
"position_valid": true,
"motion_state": "moving",
"fault": false,
"task_state": 2,
"motor_result": 1,
"motor_selector": 1,
"value_x100": 588,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 12 0D 35 00 4C 02 5A",
"timestamp": 106974.072431,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106974.092381,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106974.092381,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"captured_at": "2026-08-07T18:18:02.485490Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-07T18:18:02.550409Z",
"duration_ms": 869
},
{
"id": "MODE-ROCKING-HORSE-STOP",
"group": "mode",
"utterance": "关闭木马模式",
"started_at": "2026-08-07T18:18:02.552655Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260807181802-7609ee",
"provider_used": "local_rules",
"matched_modes": [
"rocking_horse"
],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 3,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 2,
"value_x100": 338,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 30 08 35 00 52 01 00",
"timestamp": 106974.915491,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"legrest_height": {
"position_pct": 5,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 3,
"value_x100": 541,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 30 08 35 00 1D 02 00",
"timestamp": 106974.942088,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"longitudinal": {
"position_pct": 5,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 0,
"value_x100": 541,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 30 08 35 00 1D 02 00",
"timestamp": 106974.968094,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"cushion_tilt": {
"position_pct": 11,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 1,
"value_x100": 1123,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 30 08 35 00 63 04 00",
"timestamp": 106974.993545,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106975.005142,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106975.005142,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"captured_at": "2026-08-07T18:18:03.397863Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-07T18:18:03.474083Z",
"duration_ms": 921
},
{
"id": "MODE-DYNAMIC-CRADLE-START",
"group": "mode",
"utterance": "开启动态摇篮模式",
"started_at": "2026-08-07T18:18:03.517741Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260807181803-e97616",
"provider_used": "local_rules",
"matched_modes": [
"dynamic_cradle"
],
"state_http_status": 200,
"physical_state": {
"position": {
"legrest_height": {
"position_pct": 8,
"position_valid": true,
"motion_state": "moving",
"fault": false,
"task_state": 2,
"motor_result": 1,
"motor_selector": 3,
"value_x100": 804,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 12 0D 38 00 24 03 5A",
"timestamp": 106975.856713,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"longitudinal": {
"position_pct": 8,
"position_valid": true,
"motion_state": "moving",
"fault": false,
"task_state": 2,
"motor_result": 1,
"motor_selector": 0,
"value_x100": 802,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 12 0D 38 00 22 03 5A",
"timestamp": 106975.881732,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"cushion_tilt": {
"position_pct": 17,
"position_valid": true,
"motion_state": "moving",
"fault": false,
"task_state": 2,
"motor_result": 1,
"motor_selector": 1,
"value_x100": 1684,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 12 0D 38 00 94 06 5A",
"timestamp": 106975.907916,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"backrest_recline": {
"position_pct": 6,
"position_valid": true,
"motion_state": "moving",
"fault": false,
"task_state": 2,
"motor_result": 1,
"motor_selector": 2,
"value_x100": 556,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 12 0D 38 00 2C 02 5A",
"timestamp": 106975.934169,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106975.955173,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106975.955173,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"captured_at": "2026-08-07T18:18:04.348455Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-07T18:18:04.413787Z",
"duration_ms": 896
},
{
"id": "MODE-DYNAMIC-CRADLE-STOP",
"group": "mode",
"utterance": "关闭动态摇篮模式",
"started_at": "2026-08-07T18:18:04.416034Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260807181804-bcf153",
"provider_used": "local_rules",
"matched_modes": [
"dynamic_cradle"
],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 11,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 0,
"value_x100": 1122,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 30 08 38 00 62 04 00",
"timestamp": 106976.740494,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"cushion_tilt": {
"position_pct": 22,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 1,
"value_x100": 2246,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 30 08 38 00 C6 08 00",
"timestamp": 106976.76544,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"backrest_recline": {
"position_pct": 7,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 2,
"value_x100": 742,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 30 08 38 00 E6 02 00",
"timestamp": 106976.792049,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"legrest_height": {
"position_pct": 11,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 0,
"motor_result": 3,
"motor_selector": 3,
"value_x100": 1144,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 30 08 38 00 78 04 00",
"timestamp": 106976.817508,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106976.829112,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106976.829112,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"captured_at": "2026-08-07T18:18:05.221617Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-07T18:18:05.302650Z",
"duration_ms": 887
}
],
"position_memory_sync": {
"id": "PREFLIGHT-POSITION-MEMORY-SYNC",
"group": "preflight",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-07T18:17:38.579391Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260807181738-c1fa94",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 31 00 00 00 00",
"timestamp": 106973.120321,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 32 00 00 00 00",
"timestamp": 106973.146175,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 2F 00 00 00 00",
"timestamp": 106973.171397,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 30 00 00 00 00",
"timestamp": 106973.198366,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106973.204067,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106973.204067,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"captured_at": "2026-08-07T18:18:01.596265Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-07T18:18:01.678120Z",
"duration_ms": 23099
},
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-07T18:18:05.303817Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260807181805-8f6d46",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 3C 00 00 00 00",
"timestamp": 106996.774961,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 3D 00 00 00 00",
"timestamp": 106996.800164,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 3A 00 00 00 00",
"timestamp": 106996.826407,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 3B 00 00 00 00",
"timestamp": 106996.852753,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106996.861946,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 106996.861946,
"channel": 0,
"is_fd": false,
"bitrate_switch": false
}
},
"captured_at": "2026-08-07T18:18:25.255987Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-07T18:18:25.336490Z",
"duration_ms": 20033
},
"finished_at": "2026-08-07T18:18:25.336534Z",
"summary": {
"total": 4,
"passed": 4,
"failed": 0,
"safety_blocked": 0,
"executed": 4,
"position_memory_sync_passed": true,
"final_state_passed": true
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,174 @@
{
"suite": "t2g-seat-frontend-comprehensive-hil",
"started_at": "2026-08-09T14:41:51.089381Z",
"base_url": "http://127.0.0.1:8003",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260809144151",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-M3-20-LEGREST",
"group": "motion",
"utterance": "副驾腿托调到20%",
"started_at": "2026-08-09T14:41:52.650112Z",
"status": "failed",
"errors": [
"M3运动反馈未达到目标"
],
"http_status": 201,
"request_id": "req-20260809144152-1c844d",
"provider_used": "local_rules",
"failure_telemetry": {
"transport": "zcanpro_shared_bridge",
"hardware_feedback": false,
"simulated": false,
"bridge_result": {
"details": {
"command_id": "t2g_move_passenger_legrest_height_20pct",
"stop_all_attempted": true,
"summary": "M3运动反馈未达到目标",
"target": 2000,
"terminal": null,
"tolerance": 100
},
"log_dir": "D:\\huang.xuewei\\Git\\Cognitive_Agent\\artifacts\\self-repair\\hardware\\20260809_224152_db5620",
"report_path": "D:\\huang.xuewei\\Git\\Cognitive_Agent\\artifacts\\self-repair\\hardware\\20260809_224152_db5620\\report.json",
"request_id": "SEAT_ORCH_1786286512679_db5620",
"result": "FAIL",
"summary": "M3运动反馈未达到目标"
},
"error_type": null,
"stop_all_attempted": true
},
"finished_at": "2026-08-09T14:41:54.700435Z",
"duration_ms": 2050
}
],
"position_memory_sync": {
"id": "PREFLIGHT-POSITION-MEMORY-SYNC",
"group": "preflight",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-09T14:41:51.089407Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809144151-bb6620",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "off",
"level": 0
},
"heating": {
"state": "off",
"level": 0
},
"captured_at": "2026-08-09T14:41:52.648514Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T14:41:52.650041Z",
"duration_ms": 1561
},
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-09T14:41:54.700479Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809144154-f4ad43",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "off",
"level": 0
},
"heating": {
"state": "off",
"level": 0
},
"captured_at": "2026-08-09T14:41:59.460250Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T14:41:59.460811Z",
"duration_ms": 4760
},
"finished_at": "2026-08-09T14:41:59.460848Z",
"summary": {
"total": 1,
"passed": 0,
"failed": 1,
"safety_blocked": 0,
"executed": 1,
"position_memory_sync_passed": true,
"final_state_passed": true
}
}
@@ -0,0 +1,358 @@
{
"suite": "t2g-seat-frontend-comprehensive-hil",
"started_at": "2026-08-09T10:04:15.082291Z",
"base_url": "http://127.0.0.1:8003",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260809100415",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-M0-25-HORIZONTAL",
"group": "motion",
"utterance": "把副驾座椅水平位置调到25%",
"started_at": "2026-08-09T10:04:16.311200Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809100416-4da1f3",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 25,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "off",
"level": 0
},
"heating": {
"state": "off",
"level": 0
},
"captured_at": "2026-08-09T10:04:21.364491Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T10:04:21.365063Z",
"duration_ms": 5054
},
{
"id": "MOTION-M1-20-PAN",
"group": "motion",
"utterance": "把副驾坐盆调到20%",
"started_at": "2026-08-09T10:04:21.365115Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809100421-b0b99e",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 25,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 20,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "off",
"level": 0
},
"heating": {
"state": "off",
"level": 0
},
"captured_at": "2026-08-09T10:04:24.207471Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T10:04:24.208128Z",
"duration_ms": 2843
},
{
"id": "COMBINED-ALL",
"group": "combined",
"utterance": "打开副驾加热1档、通风1档,座椅水平到30%,坐盆到40%,靠背到37%,腿托到42%",
"started_at": "2026-08-09T10:04:24.208183Z",
"status": "failed",
"errors": [
"M3运动反馈未达到目标"
],
"http_status": 201,
"request_id": "req-20260809100424-27194b",
"provider_used": "local_rules",
"failure_telemetry": {
"transport": "zcanpro_shared_bridge",
"hardware_feedback": false,
"simulated": false,
"bridge_result": {
"details": {
"command_id": "t2g_move_passenger_legrest_height_42pct",
"stop_all_attempted": true,
"summary": "M3运动反馈未达到目标",
"target": 4200,
"terminal": {
"active": false,
"direction": 0,
"driver_fault": false,
"duty": 0,
"far": false,
"motor": 3,
"near": false,
"position": 2349,
"position_valid": true,
"result": 6,
"sequence": 50339,
"stall": false,
"task": 7
},
"tolerance": 100
},
"log_dir": "D:\\huang.xuewei\\Git\\Cognitive_Agent\\artifacts\\self-repair\\hardware\\20260809_180424_546250",
"report_path": "D:\\huang.xuewei\\Git\\Cognitive_Agent\\artifacts\\self-repair\\hardware\\20260809_180424_546250\\report.json",
"request_id": "SEAT_ORCH_1786269864212_546250",
"result": "FAIL",
"summary": "M3运动反馈未达到目标"
},
"error_type": null,
"stop_all_attempted": true
},
"finished_at": "2026-08-09T10:04:47.676002Z",
"duration_ms": 23468
},
{
"id": "MODE-EASY-OPEN",
"group": "mode",
"utterance": "打开轻松进出模式",
"started_at": "2026-08-09T10:04:47.676048Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809100447-c855cc",
"provider_used": "local_rules",
"matched_modes": [
"easy_entry_exit"
],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "on",
"level": 1
},
"heating": {
"state": "on",
"level": 1
},
"captured_at": "2026-08-09T10:05:18.547335Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T10:05:18.548156Z",
"duration_ms": 30872
}
],
"position_memory_sync": {
"id": "PREFLIGHT-POSITION-MEMORY-SYNC",
"group": "preflight",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-09T10:04:15.082316Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809100415-146708",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "off",
"level": 0
},
"heating": {
"state": "off",
"level": 0
},
"captured_at": "2026-08-09T10:04:16.310470Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T10:04:16.311124Z",
"duration_ms": 1229
},
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-09T10:05:18.548210Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809100518-e21b3f",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "off",
"level": 0
},
"heating": {
"state": "off",
"level": 0
},
"captured_at": "2026-08-09T10:05:36.941483Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T10:05:36.942155Z",
"duration_ms": 18394
},
"finished_at": "2026-08-09T10:05:36.942191Z",
"summary": {
"total": 4,
"passed": 3,
"failed": 1,
"safety_blocked": 0,
"executed": 4,
"position_memory_sync_passed": true,
"final_state_passed": true
}
}
@@ -0,0 +1,363 @@
{
"suite": "t2g-seat-frontend-comprehensive-hil",
"started_at": "2026-08-09T10:09:27.978007Z",
"base_url": "http://127.0.0.1:8003",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260809100927",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-M0-25-HORIZONTAL",
"group": "motion",
"utterance": "把副驾座椅水平位置调到25%",
"started_at": "2026-08-09T10:09:29.207379Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809100929-f3faee",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 25,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "off",
"level": 0
},
"heating": {
"state": "off",
"level": 0
},
"captured_at": "2026-08-09T10:09:34.257766Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T10:09:34.258318Z",
"duration_ms": 5051
},
{
"id": "MOTION-M1-20-PAN",
"group": "motion",
"utterance": "把副驾坐盆调到20%",
"started_at": "2026-08-09T10:09:34.258367Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809100934-e7b1ff",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 25,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 20,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "off",
"level": 0
},
"heating": {
"state": "off",
"level": 0
},
"captured_at": "2026-08-09T10:09:37.186209Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T10:09:37.186800Z",
"duration_ms": 2928
},
{
"id": "COMBINED-ALL",
"group": "combined",
"utterance": "打开副驾加热1档、通风1档,座椅水平到30%,坐盆到40%,靠背到37%,腿托到42%",
"started_at": "2026-08-09T10:09:37.186855Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809100937-a7f166",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 30,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 40,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 37,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 42,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "on",
"level": 1
},
"heating": {
"state": "on",
"level": 1
},
"captured_at": "2026-08-09T10:09:58.061243Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T10:09:58.061831Z",
"duration_ms": 20875
},
{
"id": "MODE-EASY-OPEN",
"group": "mode",
"utterance": "打开轻松进出模式",
"started_at": "2026-08-09T10:09:58.061892Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809100958-e2d7f8",
"provider_used": "local_rules",
"matched_modes": [
"easy_entry_exit"
],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "on",
"level": 1
},
"heating": {
"state": "on",
"level": 1
},
"captured_at": "2026-08-09T10:10:30.421120Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T10:10:30.421790Z",
"duration_ms": 32360
}
],
"position_memory_sync": {
"id": "PREFLIGHT-POSITION-MEMORY-SYNC",
"group": "preflight",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-09T10:09:27.978032Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809100927-fbc991",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "off",
"level": 0
},
"heating": {
"state": "off",
"level": 0
},
"captured_at": "2026-08-09T10:09:29.206596Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T10:09:29.207187Z",
"duration_ms": 1229
},
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-09T10:10:30.421849Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260809101030-196c5e",
"provider_used": "local_rules",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped"
}
},
"ventilation": {
"state": "off",
"level": 0
},
"heating": {
"state": "off",
"level": 0
},
"captured_at": "2026-08-09T10:10:48.779417Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-09T10:10:48.780316Z",
"duration_ms": 18358
},
"finished_at": "2026-08-09T10:10:48.780363Z",
"summary": {
"total": 4,
"passed": 4,
"failed": 0,
"safety_blocked": 0,
"executed": 4,
"position_memory_sync_passed": true,
"final_state_passed": true
}
}
@@ -0,0 +1,250 @@
{
"suite": "t2g-seat-frontend-comprehensive-hil",
"started_at": "2026-08-01T18:19:38.370275Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801181938",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MOTION-ALL-ZERO",
"group": "motion",
"utterance": "把副驾水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-01T18:19:38.370320Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801181938-22b770",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 2A 01 00 00 00",
"timestamp": 38880.446998
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 2B 01 00 00 00",
"timestamp": 38880.472823
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 28 01 00 00 00",
"timestamp": 38880.498667
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 29 01 00 00 00",
"timestamp": 38880.524482
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 38880.532693
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 38880.532693
}
},
"captured_at": "2026-08-01T18:20:45.450814Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T18:20:45.533084Z",
"duration_ms": 67163
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-01T18:20:45.533139Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801182045-0ea6d9",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 30 01 00 00 00",
"timestamp": 38903.567521
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 2D 01 00 00 00",
"timestamp": 38903.593343
}
},
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 2E 01 00 00 00",
"timestamp": 38903.619184
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 2F 01 00 00 00",
"timestamp": 38903.646408
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 38903.653213
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 38903.653213
}
},
"captured_at": "2026-08-01T18:21:08.570962Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T18:21:08.651237Z",
"duration_ms": 23118
},
"finished_at": "2026-08-01T18:21:08.651275Z",
"summary": {
"total": 1,
"passed": 1,
"failed": 0,
"safety_blocked": 0,
"executed": 1,
"final_state_passed": true
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,252 @@
{
"suite": "t2g-seat-frontend-comprehensive-hil",
"started_at": "2026-08-01T18:23:33.171605Z",
"base_url": "http://127.0.0.1:8000",
"vehicle_id": "denza_n7",
"conversation_id": "conv-hil-full-20260801182333",
"runtime": {
"hardware_execution_allowed": true,
"firmware_profiles": [
"combined"
]
},
"results": [
{
"id": "MODE-ZERO-GRAVITY-OPEN",
"group": "mode",
"utterance": "打开零重力模式",
"started_at": "2026-08-01T18:23:33.171647Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801182333-ad87f6",
"matched_modes": [
"zero_gravity"
],
"state_http_status": 200,
"physical_state": {
"position": {
"cushion_tilt": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 28 33 01 10 27 00",
"timestamp": 39114.700574
}
},
"backrest_recline": {
"position_pct": 81,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 8103,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 08 34 01 A7 1F 00",
"timestamp": 39114.725999
}
},
"legrest_height": {
"position_pct": 94,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 9397,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 08 35 01 B5 24 00",
"timestamp": 39114.754159
}
},
"longitudinal": {
"position_pct": 100,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 10000,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 28 32 01 10 27 00",
"timestamp": 39114.780784
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 39114.790091
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 39114.790091
}
},
"captured_at": "2026-08-01T18:24:39.703780Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T18:24:39.790515Z",
"duration_ms": 66619
}
],
"final_state": {
"id": "FINAL-THERMAL-OFF",
"group": "cleanup",
"utterance": "关闭副驾座椅加热和通风,并把水平、坐盆、靠背、腿托四轴归零",
"started_at": "2026-08-01T18:24:39.790569Z",
"status": "passed",
"errors": [],
"http_status": 201,
"request_id": "req-20260801182439-328aa0",
"matched_modes": [],
"state_http_status": 200,
"physical_state": {
"position": {
"cushion_tilt": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 1,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "01 26 18 38 01 00 00 00",
"timestamp": 39185.409902
}
},
"backrest_recline": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 2,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "02 26 18 39 01 00 00 00",
"timestamp": 39185.435684
}
},
"legrest_height": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 3,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "03 26 18 3A 01 00 00 00",
"timestamp": 39185.461565
}
},
"longitudinal": {
"position_pct": 0,
"position_valid": true,
"motion_state": "stopped",
"fault": false,
"task_state": 6,
"motor_result": 2,
"motor_selector": 0,
"value_x100": 0,
"feedback_frame": {
"frame_id": "0x302",
"payload_size": 8,
"data_hex": "00 26 18 37 01 00 00 00",
"timestamp": 39185.487663
}
}
},
"ventilation": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 39185.496704
}
},
"heating": {
"state": "off",
"level": 0,
"feedback_value": 1,
"feedback_frame": {
"frame_id": "0x4FA",
"payload_size": 8,
"data_hex": "09 00 00 00 00 00 00 00",
"timestamp": 39185.496704
}
},
"captured_at": "2026-08-01T18:25:50.408971Z",
"source": "physical_can",
"target": {
"device": "seat",
"zone": "front_right",
"instance": "passenger"
},
"complete": true,
"missing": []
},
"finished_at": "2026-08-01T18:25:50.490639Z",
"duration_ms": 70700
},
"finished_at": "2026-08-01T18:25:50.490676Z",
"summary": {
"total": 1,
"passed": 1,
"failed": 0,
"safety_blocked": 0,
"executed": 1,
"final_state_passed": true
}
}
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
9136
@@ -0,0 +1,38 @@
environment: t2g_cabin_bench
platform: t2g_cabin_bench
execution:
mode: hil
hardware_enabled_env: COGNITIVE_AGENT_HARDWARE_EXECUTION_ENABLED
approval_token_required_env: COGNITIVE_AGENT_HARDWARE_APPROVAL_TOKEN_REQUIRED
approval_token_env: COGNITIVE_AGENT_HARDWARE_APPROVAL_TOKEN
seat_firmware_probe_timeout_ms: 3500
can_adapter:
backend: zlgcan
runtime_backend: standalone-zlg
device: USBCANFD-200U
device_type: 41
device_index: 0
ownership: one_bridge_process_opens_device_once
buses:
seat_can:
channel_env: COGNITIVE_AGENT_SEAT_CAN_CHANNEL
default_channel: 0
frame_format: classic_can_11_bit
bitrate: 500000
termination_enabled_env: COGNITIVE_AGENT_SEAT_CAN_TERMINATION_ENABLED
termination_enabled_default: true
body_can:
enabled_env: COGNITIVE_AGENT_VEHICLE_CAN_ENABLED
channel_env: COGNITIVE_AGENT_VEHICLE_CAN_CHANNEL
default_channel: 1
frame_format: can_fd_11_bit
arbitration_bitrate: 500000
data_bitrate: 2000000
iso: true
bitrate_switch: true
termination_enabled_env: COGNITIVE_AGENT_VEHICLE_CAN_TERMINATION_ENABLED
termination_enabled_default: false
safety:
channels_must_be_distinct: true
raw_can_passthrough: false
feedback_timeout_ms_env: COGNITIVE_AGENT_VEHICLE_CAN_FEEDBACK_TIMEOUT_MS
@@ -3,9 +3,11 @@ platform: t2g_seat_bench
execution:
mode: hil
hardware_enabled_env: COGNITIVE_AGENT_HARDWARE_EXECUTION_ENABLED
approval_token_required_env: COGNITIVE_AGENT_HARDWARE_APPROVAL_TOKEN_REQUIRED
approval_token_env: COGNITIVE_AGENT_HARDWARE_APPROVAL_TOKEN
allowed_domain: seat
allowed_target_zones: [front_left, front_right]
allowed_target_zones: [front_right]
allowed_seat_instances: [passenger]
physical_target_alias: t2g_primary_seat
can:
backend: zlgcan
@@ -17,13 +19,16 @@ firmware:
valid_profiles: [combined]
topology: one_board_unified_seat_controller
repository_project: firmware/t2g/Seat_Controller_demo/IAR/Seat_Controller_demo.ewp
identity_request: {frame_id: 0x304, data_hex: "53 45 41 54 01 00 00 00"}
identity_response: {frame_id: 0x305, data_hex: "53 45 41 54 01 01 00 3F"}
repository_vendor_dependencies: [firmware/t2g/common, firmware/t2g/tviibh8m]
verification: passive_301_302_303_304_305_306_4FA_revision_7_and_max_hall
expected_max_hall: [480, 374, 917, 647]
auto_flash_enabled_env: COGNITIVE_AGENT_SEAT_AUTO_FLASH_ENABLED
auto_flash_default_when_hardware_enabled: true
programmer: iar_cspy_cmsisdap
safety:
stop_all_on_motion_error: true
require_physical_feedback: true
longitudinal_motor3_enabled: false
cushion_tilt_enabled: false
shared_physical_target: true
passenger_only: true
auto_home_enabled_env: COGNITIVE_AGENT_SEAT_AUTO_HOME_ENABLED
auto_home_default: false
home_timeout_seconds_env: COGNITIVE_AGENT_SEAT_HOME_TIMEOUT_S
@@ -36,6 +36,6 @@ operations:
target_scope: passenger
operation: set
parameters:
position_pct: 92
position_pct: 100
angle_deg: 167
reason: 小腿解压悬浮模式腿托电机目标 72 度,按腾势 N7 显示夹角换算。
@@ -35,6 +35,6 @@ operations:
target_scope: passenger
operation: set
parameters:
position_pct: 49
position_pct: 53
angle_deg: 133
reason: 巡航沙发模式腿托电机目标 38 度,按腾势 N7 显示夹角换算。
@@ -0,0 +1,82 @@
id: dynamic_cradle
name: 动态摇篮模式
aliases:
- 动态摇篮
- 摇篮模式
- cradle
- dynamic cradle
description: >-
腾势 N7 固件原生位置闭环动态模式。Step 1先进入起始姿态;Step 2四轴同步启动并
以目标会合方式到达向前收拢姿态;Step 3四轴同步启动并会合返回起点,随后持续循环。
icon: waves
scope:
vehicle_ids:
- denza_n7
timeline:
repeat: until_stopped_or_timeout
max_runtime_ms: 600000
entry:
id: step1
name: 起始位置
transition: all_targets_reached
timeout_ms: 30000
targets:
longitudinal: {value: 172, unit: mm, hall_pulse: 391}
cushion_tilt: {value: 37.5, unit: percent, hall_pulse: 140}
backrest_recline: {value: 30, unit: degree_from_upright, hall_pulse: 405}
legrest_height: {value: 45, unit: degree, hall_pulse: 404}
phases:
- id: forward
name: Step 2 向前收拢
completion: all_targets_reached
timeout_ms: 30000
transition: synchronized_target_rendezvous
targets:
longitudinal: {value: 110, unit: mm, hall_pulse: 246}
cushion_tilt: {value: 75, unit: percent, hall_pulse: 281}
backrest_recline: {value: 52, unit: degree_from_upright, hall_pulse: 701}
legrest_height: {value: 55, unit: degree, hall_pulse: 494}
effects:
body_motion: {metaphor: cradle_rise, easing: smooth}
motion:
synchronized_start: true
synchronized_arrival: true
continuous_four_axis_cruise: true
cruise_duty_percent:
longitudinal: 50
cushion_tilt: 50
backrest_recline: 90
legrest_height: 50
final_approach_hall_pulses: 12
final_duty_percent: 50
- id: return
name: Step 3 向后回复
completion: all_targets_reached
timeout_ms: 30000
transition: synchronized_target_rendezvous
targets:
longitudinal: {value: 172, unit: mm, hall_pulse: 391}
cushion_tilt: {value: 37.5, unit: percent, hall_pulse: 140}
backrest_recline: {value: 30, unit: degree_from_upright, hall_pulse: 405}
legrest_height: {value: 45, unit: degree, hall_pulse: 404}
effects:
body_motion: {metaphor: cradle_sink, easing: smooth}
motion:
synchronized_start: true
synchronized_arrival: true
continuous_four_axis_cruise: true
cruise_duty_percent:
longitudinal: 50
cushion_tilt: 50
backrest_recline: 90
legrest_height: 50
final_approach_hall_pulses: 12
final_duty_percent: 50
operations:
- domain: seat
capability: seat.start_dynamic_mode
target_scope: passenger
operation: set
parameters:
mode_id: 2
reason: 启动 IAR revision 13 四轴全程联动位置闭环动态摇篮,循环至停止指令或十分钟上限。
@@ -36,7 +36,7 @@ operations:
target_scope: passenger
operation: set
parameters:
position_pct: 55
position_pct: 60
angle_deg: 138
reason: 电感沙滩椅腿托电机目标 43 度,按腾势 N7 显示夹角换算。
- domain: climate
@@ -35,7 +35,7 @@ operations:
target_scope: passenger
operation: set
parameters:
position_pct: 71
position_pct: 76
angle_deg: 150
reason: 休闲躺椅模式腿托电机目标 55 度,按腾势 N7 显示夹角换算。
- domain: climate
@@ -36,7 +36,7 @@ operations:
target_scope: passenger
operation: set
parameters:
position_pct: 54
position_pct: 58
angle_deg: 137
reason: 冥想空间模式腿托电机目标 42 度,按腾势 N7 显示夹角换算。
- domain: climate
+6 -6
View File
@@ -13,30 +13,30 @@ operations:
target_scope: passenger
operation: set
parameters:
position_pct: 0
position_pct: 100
reason: 小憩模式水平电机目标 0mm,按腾势 N7 215mm 行程换算。
- domain: seat
capability: seat.set_cushion_tilt
target_scope: passenger
operation: set
parameters:
position_pct: 0
position_pct: 100
reason: 小憩模式坐盆电机目标。
- domain: seat
capability: seat.set_backrest_recline
target_scope: passenger
operation: set
parameters:
position_pct: 0
angle_deg: 95
position_pct: 81
angle_deg: 150
reason: 小憩模式靠背电机目标 0 度,按腾势 N7 显示夹角换算。
- domain: seat
capability: seat.set_legrest_height
target_scope: passenger
operation: set
parameters:
position_pct: 0
angle_deg: 95
position_pct: 94
angle_deg: 163
reason: 小憩模式腿托电机目标 0 度,按腾势 N7 显示夹角换算。
- domain: climate
capability: climate.set_temperature
+1 -1
View File
@@ -35,7 +35,7 @@ operations:
target_scope: passenger
operation: set
parameters:
position_pct: 19
position_pct: 21
angle_deg: 110
reason: 办公模式腿托电机目标 15 度,按腾势 N7 显示夹角换算。
- domain: climate
@@ -36,7 +36,7 @@ operations:
target_scope: passenger
operation: set
parameters:
position_pct: 28
position_pct: 31
angle_deg: 117
reason: 女王副驾腿托电机目标 22 度,按腾势 N7 显示夹角换算。
- domain: climate
@@ -0,0 +1,103 @@
id: rocking_horse
name: 木马模式
aliases:
- 木马模式
- 木马
- 摇摇马
- 骑木马
- rocking horse
description: >-
腾势 N7 固件原生动态模式。座椅围绕中间姿态连续向前俯摆、向后仰摆,
坐盆使用增强上下行程,四电机在每个半周期同步启动并以位置会合方式到达,
形成可感知升降、无屏息、无末段追赶的木马节奏。
icon: waves
scope:
vehicle_ids:
- denza_n7
seat_tuning:
coordinate_space: hall_pulse
firmware_header: firmware/t2g/Seat_Controller_demo/Config/seat_dynamic_mode_config.h
calibrated_max_hall: [480, 374, 917, 647]
actual_bench_max_hall: [499, 374, 917, 647]
experience_tuning:
cushion_peak_to_peak_hall_pulses: 120
cushion_peak_to_peak_vertical_mm: 18.0
cushion_amplitude_gain_vs_revision_11: 2.0
diagonal_coupling_compensation:
cushion_opposing_horizontal_mm: 16.4
longitudinal_peak_to_peak_hall_pulses: 100
longitudinal_peak_to_peak_mm: 44.8
estimated_net_horizontal_mm: 28.4
customization_rules:
- 所有目标必须位于对应轴已标定 Hall 量程内
- 前后端点应围绕中心姿态分布,避免接近机械端点
- 四轴占空比不得低于台架已验证的可靠起动值
- 修改本文件后必须同步修改固件配置头并重新执行 IAR/HIL
timeline:
repeat: until_stopped_or_timeout
max_runtime_ms: 600000
entry:
id: center
name: 木马中心姿态
transition: all_targets_reached
timeout_ms: 30000
targets:
longitudinal: {value: 143, unit: mm, hall_pulse: 320}
cushion_tilt: {value: 50.8, unit: percent, hall_pulse: 190}
backrest_recline: {value: 37.1, unit: degree_from_upright, hall_pulse: 500}
legrest_height: {value: 47.9, unit: degree, hall_pulse: 430}
phases:
- id: rock_forward
name: 向前俯摆
completion: all_targets_reached
timeout_ms: 15000
transition: synchronized_target_rendezvous
targets:
longitudinal: {value: 121, unit: mm, hall_pulse: 270}
cushion_tilt: {value: 66.8, unit: percent, hall_pulse: 250}
backrest_recline: {value: 34.1, unit: degree_from_upright, hall_pulse: 460}
legrest_height: {value: 44.5, unit: degree, hall_pulse: 400}
effects:
body_motion: {metaphor: rocking_horse_nose_down, easing: smooth}
motion:
synchronized_start: true
synchronized_arrival: true
continuous_four_axis_cruise: true
cruise_duty_percent:
longitudinal: 90
cushion_tilt: 90
backrest_recline: 90
legrest_height: 50
final_approach_hall_pulses: 8
final_duty_percent: 50
- id: rock_backward
name: 向后仰摆
completion: all_targets_reached
timeout_ms: 15000
transition: synchronized_target_rendezvous
targets:
longitudinal: {value: 166, unit: mm, hall_pulse: 370}
cushion_tilt: {value: 34.8, unit: percent, hall_pulse: 130}
backrest_recline: {value: 40.0, unit: degree_from_upright, hall_pulse: 540}
legrest_height: {value: 51.2, unit: degree, hall_pulse: 460}
effects:
body_motion: {metaphor: rocking_horse_nose_up, easing: smooth}
motion:
synchronized_start: true
synchronized_arrival: true
continuous_four_axis_cruise: true
cruise_duty_percent:
longitudinal: 90
cushion_tilt: 90
backrest_recline: 90
legrest_height: 50
final_approach_hall_pulses: 8
final_duty_percent: 50
operations:
- domain: seat
capability: seat.start_dynamic_mode
target_scope: passenger
operation: set
parameters:
mode_id: 1
reason: 启动 IAR revision 13 带坐盆斜向耦合水平补偿的原生木马模式,循环至停止指令或十分钟上限。
@@ -38,6 +38,6 @@ operations:
target_scope: passenger
operation: set
parameters:
position_pct: 87
position_pct: 94
angle_deg: 163
reason: 零重力模式腿托电机目标 68 度,按腾势 N7 显示夹角换算。
@@ -0,0 +1,35 @@
apiVersion: cognitive-agent/v1alpha1
kind: CapabilityCatalog
metadata:
id: ambient-light-verified-native-can-capabilities
name: Verified CH1 ambient-light capabilities
version: 1.0.0
spec:
domain: ambient_light
capabilities:
- name: ambient_light.set_color_index
description: Set the verified vehicle color index through CH1 CAN FD.
target_devices: [ambient_light]
target_scopes: [vehicle]
parameters:
- name: color_index
type: integer
minimum: 1
maximum: 127
required: true
description: Vehicle-defined discrete ambient-light color index.
risk_level: low
confirmation_policy: on_ambiguity
- name: ambient_light.set_brightness_level
description: Set the verified discrete ambient-light brightness through CH1 CAN FD.
target_devices: [ambient_light]
target_scopes: [vehicle]
parameters:
- name: brightness_level
type: integer
minimum: 1
maximum: 5
required: true
description: Verified vehicle brightness level from 1 through 5.
risk_level: low
confirmation_policy: on_ambiguity
+37
View File
@@ -0,0 +1,37 @@
apiVersion: cognitive-agent/v1alpha1
kind: CapabilityCatalog
metadata:
id: door-native-can-capabilities
name: Door native CAN capabilities
version: 1.2.0
spec:
domain: door
capabilities:
- name: door.set_vehicle_lock
description: Observational only. Physical control is unsupported on the current CH1 because the matrix-defined 0x496 request produced no vehicle-lock or four-door transition during live smoke testing.
execution_support: observational_only
physical_control_supported: false
target_devices: [vehicle_door_lock]
target_scopes: [vehicle]
parameters:
- name: state
type: string
required: true
allowed_values: [lock, unlock]
description: Recognized whole-vehicle lock intent retained so the service can explicitly reject unsupported control requests.
risk_level: high
confirmation_policy: always
- name: door.set_rear_lock
description: Observational only and deprecated. Physical control is unsupported on the current CH1; legacy 0x32B is second-row-only and must not be treated as whole-vehicle locking.
execution_support: observational_only
physical_control_supported: false
target_devices: [rear_door_lock]
target_scopes: [rear]
parameters:
- name: state
type: string
required: true
allowed_values: [lock, unlock]
description: Legacy second-row intent retained only for explicit rejection and compatibility parsing.
risk_level: high
confirmation_policy: always
@@ -0,0 +1,110 @@
apiVersion: cognitive-agent/v1alpha1
kind: CapabilityCatalog
metadata:
id: driver-seat-native-can-capabilities
name: Driver seat native CAN capabilities
version: 1.0.0
spec:
domain: seat
capabilities:
- name: seat.set_driver_ventilation_native
description: >-
Control only the physical driver/front-left seat ventilation through the verified
CH1 body-CAN command on CAN FD ID 0x431. A fresh 0x4FA status frame is required
before execution is reported as successful.
target_devices: [driver_seat_ventilation]
target_scopes: [driver, front_left]
parameters:
- name: state
type: string
required: true
allowed_values: [on, off]
description: Absolute ventilation state.
- name: level
type: integer
required: false
minimum: 1
maximum: 2
allowed_values: [1, 2]
description: 1 is high and 2 is low; omitted on requests use the safer low level.
risk_level: high
confirmation_policy: on_ambiguity
- name: seat.set_driver_heating_native
description: >-
Control only the physical driver/front-left seat heating through the verified
CH1 body-CAN command on CAN FD ID 0x431. A fresh 0x4FA status frame is required
before execution is reported as successful.
target_devices: [driver_seat_heating]
target_scopes: [driver, front_left]
parameters:
- name: state
type: string
required: true
allowed_values: [on, off]
description: Absolute heating state.
- name: level
type: integer
required: false
minimum: 1
maximum: 2
allowed_values: [1, 2]
description: 1 is high and 2 is low; omitted on requests use the safer low level.
risk_level: high
confirmation_policy: on_ambiguity
- name: seat.set_driver_massage_native
description: >-
Control only the physical driver/front-left seat massage through the verified
CH1 body-CAN command on CAN FD ID 0x4C1, sub-ID 0x12. A fresh 0x4FA status
frame must match the requested mode or strength.
target_devices: [driver_seat_massage]
target_scopes: [driver, front_left]
parameters:
- name: action
type: string
required: true
allowed_values: [off, strength, mode]
description: Explicit massage operation; a generic on request is not accepted.
- name: strength
type: integer
required: false
minimum: 1
maximum: 3
allowed_values: [1, 2, 3]
description: Massage strength from weak to strong.
- name: mode
type: string
required: false
allowed_values: [wave, pulse, stretch, slack, relax]
description: Verified massage mode.
risk_level: high
confirmation_policy: on_ambiguity
- name: seat.set_driver_axis_native
description: >-
Move one physical driver/front-left seat axis through the verified CH1 body-CAN
command on CAN FD ID 0x4C1, sub-ID 0x05. Motion is limited to 100-2000 ms and
is always followed by three explicit stop frames. The 0x494 feedback reports a
fresh seat status frame but does not contain an absolute motor position.
target_devices: [driver_seat_axis]
target_scopes: [driver, front_left]
parameters:
- name: axis
type: string
required: true
allowed_values: [horizontal, height, backrest, basin]
description: Verified driver-seat adjustment axis.
- name: direction
type: string
required: true
allowed_values: [forward, backward, up, down, stop]
description: Axis-compatible direction or an explicit stop request.
- name: duration_ms
type: integer
required: false
minimum: 100
maximum: 2000
description: Bounded motion duration; omitted values default to 500 ms.
risk_level: high
confirmation_policy: on_ambiguity

Some files were not shown because too many files have changed in this diff Show More