490 lines
32 KiB
HTML
Executable File
490 lines
32 KiB
HTML
Executable File
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<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-23" defer></script>
|
||
<script type="module" src="/gesture-control.js?v=gesture-core-3"></script>
|
||
</head>
|
||
<body>
|
||
<header class="topbar">
|
||
<div class="brand-block">
|
||
<span class="brand-mark" aria-hidden="true"><i data-lucide="brain-circuit"></i></span>
|
||
<div>
|
||
<h1>Cognitive Agent</h1>
|
||
<p>CABIN ORCHESTRATION <span>/</span> MULTI-DOMAIN</p>
|
||
</div>
|
||
</div>
|
||
<div class="runtime-badges" aria-label="运行环境">
|
||
<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" 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>
|
||
<button class="status-badge auth-logout" id="logoutButton" type="button" title="退出登录" aria-label="退出登录" hidden>
|
||
<i data-lucide="log-out"></i>
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<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"><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>
|
||
<div class="save-mode-composer" id="saveModeComposer" hidden>
|
||
<input id="saveModeName" maxlength="24" placeholder="给当前模式起个名字" />
|
||
<button id="saveModeConfirm" type="button">保存</button>
|
||
</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>
|
||
<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">
|
||
<span class="field-label">执行目标</span>
|
||
<div class="segmented" 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>
|
||
</div>
|
||
<p class="provider-note" id="hardwareNote">正在检查 CAN 适配器与 IAR 固件配置</p>
|
||
<p class="provider-note" id="hardwareAliasNote">所有座椅能力仅控制副驾实体电机、加热与通风执行器</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>
|
||
|
||
<div class="field-group approval-field" id="approvalField" hidden>
|
||
<label class="field-label" for="approvalToken">硬件执行授权令牌</label>
|
||
<input id="approvalToken" name="approval_token" type="password" maxlength="128" autocomplete="off" spellcheck="false" placeholder="请输入服务端配置令牌" />
|
||
<p class="provider-note">仅在服务端启用令牌门禁时显示;令牌不会写入日志、会话或执行制品。</p>
|
||
<p class="provider-note" id="autoFlashNote">正在检查自动烧录配置</p>
|
||
</div>
|
||
|
||
<button class="primary-action" id="runButton" type="submit">
|
||
<i data-lucide="play"></i>
|
||
<span>生成并执行</span>
|
||
</button>
|
||
</form>
|
||
|
||
<div class="example-group">
|
||
<span class="field-label">示例请求</span>
|
||
<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>
|
||
<button type="button" class="example-command" data-example="天幕透光率调到30%,遮阳帘打开一半">
|
||
<i data-lucide="panels-top-left"></i><span>天幕透光 30% · 遮阳帘 50%</span><i data-lucide="chevron-right"></i>
|
||
</button>
|
||
<button type="button" class="example-command" data-example="打开氛围灯,调成冰蓝色,亮度60%">
|
||
<i data-lucide="lamp-ceiling"></i><span>冰蓝氛围灯 · 亮度 60%</span><i data-lucide="chevron-right"></i>
|
||
</button>
|
||
<button type="button" class="example-command featured-example" data-example="进入观影状态:副驾调整为舒适观影姿态,空调24度、风量2档,天幕调暗,氛围灯换成暖橙色">
|
||
<i data-lucide="clapperboard"></i><span>跨域观影场景</span><i data-lucide="chevron-right"></i>
|
||
</button>
|
||
<button type="button" class="example-command" data-example="副驾有点热,有点闷">
|
||
<i data-lucide="wind"></i><span>副驾有点热,有点闷</span><i data-lucide="chevron-right"></i>
|
||
</button>
|
||
<button type="button" class="example-command" data-example="副驾靠背向后移动5度">
|
||
<i data-lucide="move-horizontal"></i><span>副驾靠背向后 5°</span><i data-lucide="chevron-right"></i>
|
||
</button>
|
||
<button type="button" class="example-command" data-example="副驾调整为零重力模式,要求靠背座椅夹角128度,坐垫脚托夹角133度">
|
||
<i data-lucide="compass"></i><span>副驾零重力精确夹角</span><i data-lucide="chevron-right"></i>
|
||
</button>
|
||
<button type="button" class="example-command" data-example="将当前状态保存为零重力模式">
|
||
<i data-lucide="bookmark-plus"></i><span>保存当前座椅姿态</span><i data-lucide="chevron-right"></i>
|
||
</button>
|
||
<button type="button" class="example-command warning-example" data-example="副驾座椅加热开到三档">
|
||
<i data-lucide="triangle-alert"></i><span>三档请求(档位虚拟)</span><i data-lucide="chevron-right"></i>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="safety-strip" id="safetyStrip">
|
||
<i data-lucide="shield-check"></i>
|
||
<div>
|
||
<strong id="safetyTitle">虚拟执行边界</strong>
|
||
<span id="safetyText">四域 CAN 均为 dry-run,实车发送被强制关闭。</span>
|
||
</div>
|
||
</div>
|
||
</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="pipeline" aria-label="执行链路">
|
||
<div class="pipeline-step" data-stage="intent_parse"><span>01</span><i data-lucide="message-square-text"></i><b>意图抽取</b></div>
|
||
<i class="pipeline-arrow" data-lucide="chevron-right"></i>
|
||
<div class="pipeline-step" data-stage="function_generate"><span>02</span><i data-lucide="file-code-2"></i><b>配置生成</b></div>
|
||
<i class="pipeline-arrow" data-lucide="chevron-right"></i>
|
||
<div class="pipeline-step" data-stage="domain_validate"><span>03</span><i data-lucide="badge-check"></i><b>双层校验</b></div>
|
||
<i class="pipeline-arrow" data-lucide="chevron-right"></i>
|
||
<div class="pipeline-step" data-stage="compile"><span>04</span><i data-lucide="binary"></i><b>CAN 编译</b></div>
|
||
<i class="pipeline-arrow" data-lucide="chevron-right"></i>
|
||
<div class="pipeline-step" data-stage="safety_check"><span>05</span><i data-lucide="shield-check"></i><b>安全门禁</b></div>
|
||
<i class="pipeline-arrow" data-lucide="chevron-right"></i>
|
||
<div class="pipeline-step" data-stage="execute"><span>06</span><i data-lucide="radio-tower"></i><b id="executeStageLabel">虚拟执行</b></div>
|
||
</section>
|
||
|
||
<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>
|
||
<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">
|
||
<header>
|
||
<span class="domain-icon"><i data-lucide="fan"></i></span>
|
||
<div><strong>空调</strong><small>CLIMATE · 0x064</small></div>
|
||
<span class="device-state" id="climatePower">OFF</span>
|
||
</header>
|
||
<div class="climate-display">
|
||
<div class="zone-temperature">
|
||
<span>主驾</span><strong id="driverTemperature">24<sup>℃</sup></strong>
|
||
</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>
|
||
</div>
|
||
</div>
|
||
<dl class="domain-readouts">
|
||
<div><dt>风量</dt><dd id="fanLevel">0 档</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 roof-panel" data-domain-panel="roof">
|
||
<header>
|
||
<span class="domain-icon"><i data-lucide="panels-top-left"></i></span>
|
||
<div><strong>智能天幕</strong><small>ROOF · 0x4C1 / 0x3E6</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>
|
||
</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>
|
||
</dl>
|
||
</article>
|
||
|
||
<article class="domain-panel ambient-panel" data-domain-panel="ambient_light">
|
||
<header>
|
||
<span class="domain-icon"><i data-lucide="lamp-ceiling"></i></span>
|
||
<div><strong>氛围灯</strong><small>AMBIENT · RGB 16.8M</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>
|
||
</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>
|
||
</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>
|
||
<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>
|
||
<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>
|
||
<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="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">front_right</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="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">SIMULATED 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>front_right</span></div></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>
|
||
</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>真实台架 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>
|
||
|
||
<div class="gesture-backdrop" id="gestureBackdrop" hidden></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="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-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="toast" id="toast" role="status" aria-live="polite"></div>
|
||
</body>
|
||
</html>
|