Files
Cognitive_Agent/apps/web-console/index.html
T

626 lines
41 KiB
HTML
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="color-scheme" content="light" />
<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-16" />
<link rel="stylesheet" href="/console-v2.css?v=delivery-state-43" />
<link rel="stylesheet" href="/self-extension.css?v=gscu-tcp-39" />
<link rel="stylesheet" href="/speech-input.css?v=sensevoice-4" />
<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-2" defer></script>
<script src="/app.js?v=dual-seat-109" defer></script>
<script src="/speech-input.js?v=sensevoice-6" defer></script>
<script type="module" src="/gesture-control.js?v=android-pad-9"></script>
<script src="/pwa.js?v=android-pad-3" defer></script>
<script src="/console-v2.js?v=delivery-state-50" defer></script>
<script src="/self-extension.js?v=gscu-tcp-40" defer></script>
</head>
<body class="console-v2">
<div class="v2-boot-screen" id="v2BootScreen" role="status" aria-live="polite">
<span class="v2-boot-mark" aria-hidden="true"><i></i><i></i><i></i></span>
<strong>511工程-智能座舱</strong>
<small>正在加载车机控制与实时状态</small>
</div>
<div class="workspace">
<aside class="command-panel">
<div class="panel-heading">
<span class="section-kicker">NATURAL CABIN CONTROL</span>
<h2>说一句,就调好了</h2>
<p class="panel-intro">座椅、空调、天幕与氛围灯,一句话联动完成。</p>
</div>
<div class="mode-rail" aria-label="快捷功能模式">
<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>
<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>
<form id="requestForm">
<div class="field-label-row">
<label for="utterance">自然语言指令</label>
<button class="context-reset" id="newConversation" type="button" title="开始新会话" aria-label="开始新会话">
<i data-lucide="message-square-plus"></i>
</button>
</div>
<div class="command-composer">
<textarea id="utterance" name="utterance" maxlength="1000" placeholder="例如:有点热,把副驾驶调舒服些,再把天幕调暗">进入观影状态:空调24度、风量2档,天幕调暗,氛围灯换成暖橙色</textarea>
<button class="speech-dictation" id="speechDictationButton" type="button" aria-label="开始语音听写" aria-pressed="false" title="语音听写(自动识别说话结束)">
<i class="speech-mic-icon" data-lucide="mic" aria-hidden="true"></i>
<span class="speech-waveform" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i></span>
<span class="speech-visually-hidden">开始语音听写</span>
</button>
<span class="speech-status" id="speechDictationStatus" role="status" aria-live="polite"></span>
<span class="composer-hint">Enter 执行 · Shift + Enter 换行</span>
</div>
<div class="field-group">
<span class="field-label">意图解析器</span>
<div class="segmented" role="group" aria-label="意图解析器">
<button type="button" class="segment active" data-provider="openai">
<i data-lucide="sparkles"></i>GPT
</button>
<button type="button" class="segment" data-provider="local">
<i data-lucide="braces"></i>本地规则
</button>
</div>
<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 execution-mode-options" role="group" aria-label="执行目标">
<button type="button" class="mode-option" data-execution-mode="dry_run">
<i data-lucide="flask-conical"></i>虚拟 CAN
</button>
<button type="button" class="mode-option active" id="hardwareMode" data-execution-mode="hardware">
<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>
</div>
<div class="field-group" id="vehicleTransportField">
<span class="field-label">车辆连接方式</span>
<div class="segmented vehicle-transport-options" role="group" aria-label="车辆连接方式">
<button type="button" class="mode-option active" data-control-transport="wired_can">
<i data-lucide="cable"></i>有线 CAN
</button>
<button type="button" class="mode-option" data-control-transport="wireless_mqtt">
<i data-lucide="wifi"></i>无线 CAN
</button>
</div>
<p class="provider-note" id="vehicleTransportNote">正在检查车辆连接</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">
<label class="field-label" for="vehicleSelect">车型配置</label>
<div class="vehicle-select-control">
<i data-lucide="car-front"></i>
<select id="vehicleSelect" name="vehicle_id" aria-label="选择车型配置">
<option value="">加载车型配置</option>
</select>
</div>
<p class="provider-note" id="vehicleNote">正在读取座椅量程与角度标定</p>
</div>
<button class="primary-action" id="runButton" type="submit" aria-label="执行车舱控制指令">
<i data-lucide="play"></i>
<span>生成并执行</span>
</button>
</form>
</aside>
<main class="main-panel">
<section class="request-header">
<div>
<span class="section-kicker">ORCHESTRATION RUN</span>
<div class="request-title-row">
<h2 id="resultTitle">等待请求</h2>
<span class="run-status idle" id="runStatus">IDLE</span>
</div>
<p id="requestMeta">Cabin / reference_vehicle / dry-run</p>
</div>
<div class="matrix-stat">
<i data-lucide="table-properties"></i>
<div><strong id="matrixCount">10 / 57</strong><span>报文 / 信号</span></div>
</div>
</section>
<section class="cabin-band" aria-labelledby="cabinStateTitle">
<div class="section-title-row cabin-heading">
<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>
</div>
<div class="domain-grid">
<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>CMD 0x1DE · FB 0x404 · CH1</small></div>
<span class="device-state" id="climatePower">UNKNOWN</span>
</header>
<p class="domain-capability-line"><span>可控参数</span>电源 · 温度 · 风量/风向</p>
<div class="climate-display">
<div class="zone-temperature">
<span>主驾</span><strong id="driverTemperature">--<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">--<sup>℃</sup></strong>
<small>风向<b id="passengerAirDirection">-</b></small>
</div>
</div>
<dl class="domain-readouts">
<div><dt>风量</dt><dd id="fanLevel">未知</dd></div>
<div><dt>循环</dt><dd id="cycleMode">未知</dd></div>
<div><dt>A/C</dt><dd id="acState">未知</dd></div>
<div><dt>前除霜</dt><dd id="defrostState">未知</dd></div>
</dl>
</article>
<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>CMD 0x431 · FB 0x41A · CH1</small></div>
<span class="device-state" id="roofState">UNKNOWN</span>
</header>
<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="shadePositionValue">未知</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" data-device-channel="ch1">
<header>
<span class="domain-icon"><i data-lucide="lamp-ceiling"></i></span>
<div><strong>车内灯光</strong><small>INTERIOR / AMBIENT · CH1</small></div>
<span class="device-state" id="ambientPower">UNKNOWN</span>
</header>
<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 id="ambientMode">未知</dd></div>
<div><dt>室内/阅读灯</dt><dd id="interiorLightPower">未知</dd></div>
<div><dt>氛围亮度</dt><dd id="ambientBrightness">- / -</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">UNKNOWN</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">未知</dd></div>
<div><dt>右前窗</dt><dd id="frontRightWindow">未知</dd></div>
<div><dt>左后窗</dt><dd id="rearLeftWindow">未知</dd></div>
<div><dt>右后窗</dt><dd id="rearRightWindow">未知</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>FB 0x38A · CH1</small></div>
<span class="device-state" id="frontLightState">UNKNOWN</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 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">
<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="通过模型动画展示 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>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>
</div>
<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">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>
</div>
<div class="twin-thermal-row" aria-label="座椅热舒适状态">
<span data-twin-function="ventilation" data-level="0">
<i data-lucide="wind"></i>
<span class="twin-thermal-copy"><small>通风</small><b>关闭</b></span>
<span class="twin-level-meter" aria-hidden="true"><i></i><i></i><i></i></span>
</span>
<span data-twin-function="heating" data-level="0">
<i data-lucide="flame"></i>
<span class="twin-thermal-copy"><small>加热</small><b>关闭</b></span>
<span class="twin-level-meter" aria-hidden="true"><i></i><i></i><i></i></span>
</span>
</div>
</aside>
<div class="twin-fallback" id="twinFallback"><i data-lucide="loader-circle"></i><span>正在加载整车参考模型</span></div>
</div>
</section>
<section class="state-band">
<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">CH0 / CH1 FEEDBACK</span>
</div>
<div class="seat-grid">
<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="motion-state-grid" aria-live="polite"></div>
</article>
<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>
</div>
</div>
<div class="coverage-section">
<span class="section-kicker">MATRIX COVERAGE</span>
<h3>当前控制边界</h3>
<dl>
<div><dt>空调 18–32℃ / 0–7 档</dt><dd class="available">可编译</dd></div>
<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>
</section>
<section class="detail-section result-workspace" aria-labelledby="resultWorkspaceTitle">
<header class="result-workspace-heading">
<div><span class="section-kicker">ORCHESTRATION WORKSPACE</span><h3 id="resultWorkspaceTitle">编排结果工作台</h3><p>四类结果在同一页面连续呈现,也可以通过下方入口快速定位。</p></div>
<span class="result-workspace-badge"><i data-lucide="route"></i>REQUEST → CONFIG → CAN → RESULT</span>
</header>
<nav class="tabs result-nav" aria-label="结果快速导航">
<button class="tab active" type="button" data-tab="trace"><span class="tab-index">01</span><i data-lucide="list-tree"></i><span class="tab-copy"><strong>决策轨迹</strong><small id="traceNavMeta">等待请求</small></span><i data-lucide="arrow-down"></i></button>
<button class="tab" type="button" data-tab="config"><span class="tab-index">02</span><i data-lucide="layout-grid"></i><span class="tab-copy"><strong>配置卡片</strong><small id="configNavMeta">等待生成</small></span><i data-lucide="arrow-down"></i></button>
<button class="tab" type="button" data-tab="plan"><span class="tab-index">03</span><i data-lucide="binary"></i><span class="tab-copy"><strong>CAN 计划</strong><small id="planNavMeta">等待编译</small></span><i data-lucide="arrow-down"></i></button>
<button class="tab" type="button" data-tab="result"><span class="tab-index">04</span><i data-lucide="circle-check-big"></i><span class="tab-copy"><strong>执行结果</strong><small id="resultNavMeta">尚未执行</small></span><i data-lucide="arrow-down"></i></button>
</nav>
<div class="tab-panel active" id="panel-trace" role="tabpanel">
<div class="workspace-panel-title"><div><span class="section-kicker">01 · DECISION TRACE</span><h3>决策轨迹与校验</h3><p>从自然语言识别到领域路由,集中查看每一步决策依据。</p></div><span class="workspace-panel-state" id="tracePanelState">IDLE</span></div>
<div class="trace-layout">
<div>
<div class="detail-heading"><h3>可审计决策摘要</h3><span id="providerUsed">--</span></div>
<ol class="decision-list" id="decisionList"><li>提交请求后显示识别目标、能力选择和约束来源。</li></ol>
</div>
<div>
<div class="detail-heading"><h3>阶段事件</h3><span id="traceDuration">0 ms</span></div>
<div class="trace-list" id="traceList"><div class="empty-line">暂无执行事件</div></div>
</div>
</div>
<div class="validation-block">
<div class="detail-heading"><h3>校验结果</h3><span id="validationCount">0 条</span></div>
<div id="validationList" class="validation-list"><div class="empty-line">等待配置生成</div></div>
</div>
</div>
<div class="tab-panel config-panel" id="panel-config" role="tabpanel">
<div class="config-panel-heading">
<div><span class="section-kicker">02 · INSTRUCTION → HARDWARE</span><h3>指令配置与硬件映射</h3><p>每张卡片对应一个控制对象,依次展示目标参数和最终硬件计划。</p></div>
<div class="config-actions"><button class="config-action" type="button" data-copy="config"><i data-lucide="copy"></i>复制 YAML</button><button class="config-action" type="button" data-download="config"><i data-lucide="download"></i>下载配置</button></div>
</div>
<div class="config-card-grid" id="configCards">
<div class="config-empty"><i data-lucide="panel-top-dashed"></i><strong>等待生成配置</strong><span>提交车舱控制指令后,这里会显示控制对象、目标参数和硬件信号。</span></div>
</div>
<details class="config-source-details">
<summary><span><i data-lucide="braces"></i>查看原始配置</span><small id="configFileName">functions/seat.yaml</small></summary>
<pre id="configCode"><code># 等待生成 FunctionConfig</code></pre>
</details>
</div>
<div class="tab-panel plan-panel" id="panel-plan" role="tabpanel">
<div class="workspace-panel-title plan-panel-heading"><div><span class="section-kicker">03 · CAN COMMAND PLAN</span><h3>CAN 编译计划</h3><p>快速核对帧数量、首帧载荷、反馈帧和执行模式。</p></div><button class="config-action" type="button" data-copy="plan"><i data-lucide="copy"></i>复制计划</button></div>
<div class="frame-summary" id="frameSummary"><span>Frame ID</span><b>--</b><span>Payload</span><code>--</code><span>Mode</span><b>DRY-RUN</b></div>
<details class="config-source-details plan-source-details">
<summary><span><i data-lucide="binary"></i>查看原始 CAN 计划</span><small id="planFileName">command-plans/seat.yaml</small></summary>
<pre id="planCode"><code># 等待 CAN 编译</code></pre>
</details>
</div>
<div class="tab-panel result-panel" id="panel-result" role="tabpanel">
<div class="workspace-panel-title"><div><span class="section-kicker">04 · EXECUTION RESULT</span><h3>执行结果与硬件回读</h3><p>汇总每个领域的执行状态、CAN 回读和失败原因。</p></div><span class="workspace-panel-state" id="resultPanelState">IDLE</span></div>
<div class="execution-summary" id="executionSummary">
<i data-lucide="circle-dashed"></i><div><strong>尚未执行</strong><span>运行结果将在此处显示</span></div>
</div>
<div class="result-list" id="resultList"></div>
</div>
</section>
</main>
</div>
<aside class="gesture-drawer" id="gestureDrawer" aria-hidden="true" aria-labelledby="gestureDrawerTitle">
<header class="gesture-drawer-header">
<div>
<span class="section-kicker">VISION CONTROL</span>
<h2 id="gestureDrawerTitle">手势控制</h2>
<p>本机识别,动作通过当前编排链路执行。</p>
</div>
<button class="gesture-close" id="gestureCloseButton" type="button" aria-label="关闭手势控制"><i data-lucide="x"></i></button>
</header>
<div class="gesture-status-strip">
<span class="gesture-state-pill idle" id="gestureStatePill"><i></i><b>未启动</b></span>
<span id="gestureSafetyText">摄像头尚未开启</span>
</div>
<div class="gesture-camera-stage">
<video id="gestureVideo" playsinline muted></video>
<canvas id="gestureCanvas"></canvas>
<div class="gesture-camera-empty" id="gestureCameraEmpty">
<span><i data-lucide="scan-face"></i></span>
<strong>用手势控制副驾驶座椅</strong>
<p>画面只在本机处理,不上传视频。</p>
</div>
<div class="gesture-live-badge" id="gestureLiveBadge" hidden><i></i>LIVE</div>
</div>
<div class="gesture-now">
<div><span>当前手势</span><strong id="gestureDetected">—</strong></div>
<i data-lucide="arrow-right"></i>
<div><span>期望动作</span><strong id="gestureExpected">等待启动</strong></div>
</div>
<div class="gesture-progress"><i id="gestureProgressBar"></i></div>
<div class="gesture-actions">
<button class="gesture-primary" id="gestureStartButton" type="button"><i data-lucide="camera"></i><span>开启摄像头</span></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-map-grid" id="gestureMapGrid"></div>
<div class="gesture-customize" id="gestureCustomizePanel" hidden>
<div><span>识别到</span><strong id="gestureCustomizeToken">请先摆出手势</strong></div>
<select id="gestureActionSelect" aria-label="选择座椅动作"></select>
<button id="gestureBindButton" type="button">绑定当前手势</button>
<button id="gestureResetMapping" type="button">恢复默认</button>
</div>
</section>
<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="mode-editor-backdrop" id="modeEditorBackdrop" hidden>
<section class="mode-editor" role="dialog" aria-modal="true" aria-labelledby="modeEditorTitle" aria-describedby="modeEditorDescription">
<div class="mode-editor-setup">
<header class="mode-editor-header">
<div>
<span>MODE WORKFLOW</span>
<h2 id="modeEditorTitle">编辑功能模式</h2>
<p id="modeEditorDescription">复用主页自然语言解析流程生成控制指令;此步骤不会执行设备。</p>
</div>
<button id="modeEditorClose" type="button" aria-label="关闭模式编辑器"><i data-lucide="x"></i></button>
</header>
<div class="mode-editor-inputs">
<label class="mode-editor-field mode-editor-name-field" for="modeEditorName">
<span>模式名称</span>
<input id="modeEditorName" maxlength="64" autocomplete="off" placeholder="输入模式名称" />
</label>
<label class="mode-editor-field mode-editor-instruction-field" for="modeEditorInstruction">
<span>自然语言指令</span>
<textarea id="modeEditorInstruction" maxlength="1000" rows="3" placeholder="例如:空调24度、风量2档,打开遮阳帘"></textarea>
</label>
</div>
</div>
<section class="mode-editor-flow" aria-live="polite">
<header>
<span><i data-lucide="workflow"></i>控制指令流</span>
<div class="mode-editor-flow-tools">
<b id="modeEditorFlowCount">尚未生成</b>
<button id="modeEditorFlowExpand" type="button" aria-expanded="false" aria-label="展开控制指令区域" title="展开控制指令区域">
<i data-lucide="maximize-2"></i>
</button>
</div>
</header>
<div class="mode-editor-flow-preview empty" id="modeEditorFlowPreview">
<p>点击“生成指令”后,这里会显示由后端解析、校验并编译的控制指令流。</p>
</div>
</section>
<p class="mode-editor-status" id="modeEditorStatus">修改自然语言后需要重新生成指令,才能点击完成永久保存。</p>
<footer class="mode-editor-actions">
<button id="modeEditorCancel" type="button">取消</button>
<button class="mode-editor-execute" id="modeEditorExecute" type="button"><i data-lucide="wand-sparkles"></i><span>生成指令</span></button>
<button class="mode-editor-complete" id="modeEditorComplete" type="button" disabled><i data-lucide="save"></i><span>完成</span></button>
</footer>
</section>
</div>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
</body>
</html>