Files
ParkingRobot/dailywork_report/pathsmoothing_rep/03-local-g2-curvature-excursion-feasibility-visualization.html
T

617 lines
20 KiB
HTML

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Local G2 最小曲率越界可行性验证|结果可视化</title>
<style>
:root {
color-scheme: light;
--ink: #172a36;
--muted: #62727b;
--paper: #f4f7f6;
--panel: #ffffff;
--line: #c8d4d5;
--teal: #126d70;
--teal-pale: #e0f1ef;
--green: #257a4d;
--green-pale: #e7f4eb;
--amber: #9b5f13;
--amber-pale: #fff1dc;
--red: #b1373e;
--red-pale: #fbe9ea;
--slate: #596b75;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--paper);
color: var(--ink);
font: 16px/1.6 system-ui, -apple-system, "Segoe UI", sans-serif;
}
main {
width: min(1120px, 100%);
margin: 0 auto;
padding: 32px 24px 48px;
}
header {
border-bottom: 2px solid var(--ink);
padding-bottom: 22px;
}
.eyebrow {
margin: 0 0 6px;
color: var(--teal);
font-weight: 800;
}
h1, h2, h3, p { margin-top: 0; }
h1 {
margin-bottom: 10px;
font-size: 2.25rem;
line-height: 1.18;
}
h2 {
margin-bottom: 12px;
font-size: 1.45rem;
line-height: 1.3;
}
h3 {
margin-bottom: 6px;
font-size: 1.05rem;
line-height: 1.35;
}
.subtitle {
max-width: 780px;
margin-bottom: 16px;
color: var(--muted);
font-size: 1.03rem;
}
.badges {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.badge {
border: 1px solid currentColor;
border-radius: 6px;
padding: 4px 9px;
font-size: 0.9rem;
font-weight: 800;
}
.badge.red { color: var(--red); background: var(--red-pale); }
.badge.green { color: var(--green); background: var(--green-pale); }
.badge.teal { color: var(--teal); background: var(--teal-pale); }
.report-nav {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 8px;
margin: 24px 0 0;
}
button {
min-height: 44px;
border: 1px solid var(--line);
border-radius: 6px;
padding: 9px 12px;
color: var(--ink);
background: var(--panel);
font: inherit;
font-weight: 700;
cursor: pointer;
}
button:hover { border-color: var(--teal); }
button:focus-visible { outline: 3px solid #f0b535; outline-offset: 2px; }
button[aria-pressed="true"] { border-color: var(--teal); color: #ffffff; background: var(--teal); }
.visual-band {
margin-top: 16px;
border-top: 1px solid var(--line);
border-bottom: 1px solid var(--line);
background: var(--panel);
}
.view-copy {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 20px;
align-items: end;
padding: 22px 22px 12px;
}
.view-copy p {
margin-bottom: 0;
color: var(--muted);
}
.view-state {
margin: 0;
color: var(--teal);
font-weight: 800;
text-align: right;
}
.visual-stage { padding: 0 22px 24px; }
.visual-view { display: none; }
[data-view="funnel"] .visual-view[data-view="funnel"],
[data-view="gates"] .visual-view[data-view="gates"],
[data-view="performance"] .visual-view[data-view="performance"] { display: block; }
.funnel {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
align-items: stretch;
gap: 10px;
padding: 0;
margin: 0;
list-style: none;
}
.funnel li {
position: relative;
min-height: 142px;
border: 1px solid var(--line);
border-top: 5px solid var(--slate);
border-radius: 6px;
padding: 16px 12px;
background: #fbfcfc;
}
.funnel li:not(:last-child)::after {
position: absolute;
top: 58px;
right: -9px;
z-index: 1;
width: 17px;
color: var(--muted);
background: var(--panel);
content: "→";
font-size: 1.25rem;
text-align: center;
}
.funnel li.physical { border-top-color: var(--green); }
.funnel li.blocked { border-top-color: var(--red); }
.funnel li.final { border-top-color: var(--slate); }
.metric {
display: block;
margin-bottom: 4px;
color: var(--ink);
font-size: 2.25rem;
font-weight: 800;
line-height: 1;
}
.funnel strong, .funnel small { display: block; }
.funnel small { margin-top: 4px; color: var(--muted); }
.gate-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
}
.gate {
min-height: 154px;
border: 1px solid var(--line);
border-radius: 6px;
padding: 16px;
background: #fbfcfc;
}
.gate .step {
display: block;
margin-bottom: 8px;
color: var(--muted);
font-weight: 800;
}
.gate p { margin-bottom: 0; color: var(--muted); }
.gate.accepted { border-top: 5px solid var(--green); }
.gate.blocked { border-top: 5px solid var(--red); }
.gate.measurement { border-top: 5px solid var(--amber); }
.gate.output { border-top: 5px solid var(--slate); }
.gate-result {
display: inline-block;
margin-top: 12px;
border-radius: 5px;
padding: 3px 7px;
font-size: 0.9rem;
font-weight: 800;
}
.gate-result.green { color: var(--green); background: var(--green-pale); }
.gate-result.red { color: var(--red); background: var(--red-pale); }
.gate-result.amber { color: var(--amber); background: var(--amber-pale); }
.gate-result.slate { color: var(--slate); background: #e9eef0; }
.measurement-note {
margin: 14px 0 0;
border-left: 4px solid var(--amber);
padding: 10px 12px;
color: #6e4915;
background: var(--amber-pale);
}
.performance-layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 250px;
gap: 28px;
align-items: stretch;
}
.timing-list {
display: grid;
gap: 14px;
}
.timing-row {
display: grid;
grid-template-columns: 132px minmax(0, 1fr);
gap: 12px;
align-items: center;
}
.timing-label { font-weight: 800; }
.timing-bar {
display: grid;
grid-template-columns: var(--median) var(--worst) 1fr;
min-height: 40px;
overflow: hidden;
border: 1px solid var(--line);
border-radius: 5px;
background: #f6f8f8;
}
.timing-bar span {
display: grid;
place-items: center;
min-width: 0;
padding: 3px;
color: #ffffff;
font-size: 0.78rem;
font-weight: 800;
white-space: nowrap;
}
.timing-bar .median { background: var(--teal); }
.timing-bar .worst { background: var(--green); }
.timing-bar .remaining { color: var(--muted); background: #edf2f1; }
.determinism {
display: grid;
align-content: center;
border-left: 1px solid var(--line);
padding-left: 24px;
}
.determinism strong {
display: block;
color: var(--teal);
font-size: 2.85rem;
line-height: 1;
}
.determinism p { margin: 8px 0 0; color: var(--muted); }
.section {
padding: 30px 0;
border-bottom: 1px solid var(--line);
}
.section-intro {
max-width: 780px;
color: var(--muted);
}
.facts {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
}
.fact {
border-left: 4px solid var(--teal);
padding: 4px 0 4px 14px;
}
.fact:nth-child(2) { border-left-color: var(--red); }
.fact:nth-child(3) { border-left-color: var(--amber); }
.fact p { margin-bottom: 0; color: var(--muted); }
table {
width: 100%;
border-collapse: collapse;
background: var(--panel);
}
th, td {
border-bottom: 1px solid var(--line);
padding: 11px 12px;
vertical-align: top;
text-align: left;
}
th { color: var(--muted); font-size: 0.9rem; }
tr:last-child td { border-bottom: 0; }
.actions {
display: grid;
gap: 10px;
padding: 0;
margin: 0;
list-style: none;
counter-reset: action;
}
.actions li {
counter-increment: action;
position: relative;
padding-left: 42px;
}
.actions li::before {
position: absolute;
left: 0;
width: 28px;
height: 28px;
border: 1px solid var(--line);
border-radius: 50%;
color: var(--teal);
background: var(--panel);
content: counter(action);
font-weight: 800;
line-height: 26px;
text-align: center;
}
footer {
padding-top: 24px;
color: var(--muted);
font-size: 0.9rem;
}
@media (max-width: 760px) {
main { padding: 24px 14px 38px; }
h1 { font-size: 1.85rem; }
.report-nav, .facts { grid-template-columns: 1fr; }
.view-copy, .performance-layout { grid-template-columns: 1fr; }
.view-state { text-align: left; }
.funnel, .gate-grid { grid-template-columns: 1fr; }
.funnel li:not(:last-child)::after {
top: auto;
right: auto;
bottom: -16px;
left: calc(50% - 9px);
content: "↓";
}
.determinism {
border-top: 1px solid var(--line);
border-left: 0;
padding-top: 20px;
padding-left: 0;
}
.timing-row { grid-template-columns: 1fr; gap: 5px; }
}
</style>
</head>
<body>
<main id="excursion-report" data-view="funnel">
<header>
<p class="eyebrow">离线结果可视化 · Local G2</p>
<h1>最小曲率越界探测:没有新的可采纳路径</h1>
<p class="subtitle">固定 SingleTurn 场景中,候选搜索、性能和确定性验证均已完成;但严格接纳条件下没有候选通过,预平滑管线保持原样。</p>
<div class="badges" aria-label="结论状态">
<span class="badge red">QUALITY_RED</span>
<span class="badge green">性能通过</span>
<span class="badge teal">生产 evaluator 不变</span>
</div>
</header>
<nav class="report-nav" aria-label="选择结果视图">
<button type="button" class="view-button" data-view="funnel" aria-pressed="true">候选结果漏斗</button>
<button type="button" class="view-button" data-view="gates" aria-pressed="false">质量门阻断链路</button>
<button type="button" class="view-button" data-view="performance" aria-pressed="false">性能与确定性</button>
</nav>
<section class="visual-band" aria-live="polite">
<div class="view-copy">
<div>
<h2 id="view-title">候选已经生成,但没有进入最终输出</h2>
<p id="view-description">6 个候选中有 3 个达到车辆物理约束层;严格 raw 曲率范围合格数仍为 0,因此不能把任何候选当作可发布的平滑路径。</p>
</div>
<p id="view-state" class="view-state">结果:Unchanged</p>
</div>
<div class="visual-stage">
<div class="visual-view" data-view="funnel">
<ol class="funnel" aria-label="候选审核结果漏斗">
<li><span class="metric">6</span><strong>已生成候选</strong><small>30 次 solver 调用</small></li>
<li class="physical"><span class="metric">3</span><strong>物理约束合格</strong><small>基础几何层</small></li>
<li class="blocked"><span class="metric">0</span><strong>严格范围合格</strong><small>raw 曲率范围</small></li>
<li class="blocked"><span class="metric">0</span><strong>越界合格</strong><small>无最小值可报告</small></li>
<li class="final"><span class="metric">0</span><strong>替换输出</strong><small>管线 Unchanged</small></li>
</ol>
</div>
<div class="visual-view" data-view="gates">
<div class="gate-grid" aria-label="严格与测量路径的质量门状态">
<article class="gate accepted">
<span class="step">步骤 1</span>
<h3>候选生成</h3>
<p>局部替换曲线被构造并进入审核。</p>
<span class="gate-result green">6 个候选</span>
</article>
<article class="gate blocked">
<span class="step">步骤 2</span>
<h3>Strict raw 曲率范围</h3>
<p>严格路径首先判定候选是否保持原有接纳语义。</p>
<span class="gate-result red">0 个严格合格</span>
</article>
<article class="gate measurement">
<span class="step">步骤 3</span>
<h3>Measurement trace</h3>
<p>只为取证而继续记录后续质量门,不改变 Strict 结论。</p>
<span class="gate-result amber">一次性测量路径</span>
</article>
<article class="gate output">
<span class="step">步骤 4</span>
<h3>净空与最终输出</h3>
<p>3 个物理约束合格候选在净空门阻断,未被接受。</p>
<span class="gate-result slate">原路径保持</span>
</article>
</div>
<p class="measurement-note">Measurement 的作用是把阻断位置记录完整,不是放宽生产质量门。它不能授权修改 evaluator,也不能让候选进入正式输出。</p>
</div>
<div class="visual-view" data-view="performance">
<div class="performance-layout">
<div class="timing-list" aria-label="性能汇总,单位为毫秒">
<div class="timing-row">
<span class="timing-label">Solver 中位 / 限制</span>
<div class="timing-bar" style="--median: 49%; --worst: 0%;">
<span class="median">4.94 ms</span>
<span class="worst"></span>
<span class="remaining">限制 10 ms</span>
</div>
</div>
<div class="timing-row">
<span class="timing-label">Solver 最坏 / 限制</span>
<div class="timing-bar" style="--median: 31%; --worst: 0%;">
<span class="median">7.74 ms</span>
<span class="worst"></span>
<span class="remaining">限制 25 ms</span>
</div>
</div>
<div class="timing-row">
<span class="timing-label">Region 中位 / 限制</span>
<div class="timing-bar" style="--median: 40%; --worst: 0%;">
<span class="median">10.09 ms</span>
<span class="worst"></span>
<span class="remaining">限制 25 ms</span>
</div>
</div>
<div class="timing-row">
<span class="timing-label">Region 最坏 / 限制</span>
<div class="timing-bar" style="--median: 46%; --worst: 0%;">
<span class="median">23.22 ms</span>
<span class="worst"></span>
<span class="remaining">限制 50 ms</span>
</div>
</div>
</div>
<aside class="determinism">
<strong>1</strong>
<p>个确定性签名<br>5 次预热 + 30 次测量<br>性能超限:False</p>
</aside>
</div>
</div>
</div>
</section>
<section class="section">
<h2>如何理解“平滑方案效果”</h2>
<p class="section-intro">本次结果不是“完全没有曲线”,也不能直接写成“所有候选曲率都比原路径更大”。真正的结论是,候选在不同质量层的状态不同,且没有一个最终满足现有严格接纳条件。</p>
<div class="facts">
<article class="fact">
<h3>候选层确实执行</h3>
<p>系统生成了 6 个局部候选,并对它们完成了有界搜索和账本审计。</p>
</article>
<article class="fact">
<h3>严格接纳没有通过</h3>
<p>raw 曲率范围严格合格数为 0,因此不能把任何候选写成可发布的路径平滑结果。</p>
</article>
<article class="fact">
<h3>输出没有变化</h3>
<p>Measurement 继续记录后,候选仍被净空门阻断;管线最终保持 Unchanged。</p>
</article>
</div>
</section>
<section class="section">
<h2>本轮修改边界</h2>
<table>
<thead>
<tr><th>范围</th><th>改动</th><th>结论</th></tr>
</thead>
<tbody>
<tr><td>一次性 probe core</td><td>候选搜索、账本、严格审计与证据生成。</td><td>只用于验证,不回写生产源码。</td></tr>
<tr><td>Measurement root</td><td>LocalG2CandidateEvaluator.cs 的测量延续与 trace 捕获。</td><td>只用于取证,不是生产 evaluator 变更。</td></tr>
<tr><td>共享分支</td><td>发布正式证据报告。</td><td>没有提交 probe 源码,也没有修改 evaluator。</td></tr>
<tr><td>本日报目录</td><td>新增本页及对应 Markdown 摘要。</td><td>仅整理事实与证据入口,不改变路径平滑行为。</td></tr>
</tbody>
</table>
</section>
<section class="section">
<h2>后续边界</h2>
<ol class="actions">
<li>保持 QUALITY_RED 对应的授权结论:不把 Measurement 改动复制到生产 evaluator。</li>
<li>不为了得到绿色结果而放宽 raw 曲率范围、净空或其他质量门。</li>
<li>继续按已有优先级处理基线复验、窗口长度语义与多区域弧长定位风险。</li>
<li>新的几何策略或场景范围需要独立计划和新的验收证据,不能从本次 SingleTurn 结果直接推导发布结论。</li>
</ol>
</section>
<footer>
对应主报告:03-local-g2-curvature-excursion-feasibility-report.md。数据来源:docs/superpowers/reports/2026-08-01-local-g2-minimum-curvature-excursion-feasibility-report.md。单文件离线 HTML,无外部资源依赖。
</footer>
</main>
<script>
'use strict';
const views = Object.freeze({
funnel: Object.freeze({
title: '候选已经生成,但没有进入最终输出',
description: '6 个候选中有 3 个达到车辆物理约束层;严格 raw 曲率范围合格数仍为 0,因此不能把任何候选当作可发布的平滑路径。',
state: '结果:Unchanged'
}),
gates: Object.freeze({
title: '严格路径阻断,测量路径只补全证据',
description: 'Strict 保持共享 evaluator 语义并在 raw 曲率范围处拒绝候选。Measurement 仅为追踪后续质量门,不能改变严格结论或生产代码。',
state: '授权:不修改 evaluator'
}),
performance: Object.freeze({
title: '时间预算与结果确定性均通过',
description: '5 次预热和 30 次测量均在既定性能阈值内完成,且只产生 1 个确定性签名;这些结果不覆盖严格接纳失败。',
state: '性能超限:False'
})
});
const buttons = Array.from(document.querySelectorAll('.view-button'));
function selectView(viewId) {
const view = views[viewId];
if (!view) return;
const root = document.getElementById('excursion-report');
root.dataset.view = viewId;
document.getElementById('view-title').textContent = view.title;
document.getElementById('view-description').textContent = view.description;
document.getElementById('view-state').textContent = view.state;
buttons.forEach((button) => button.setAttribute('aria-pressed', String(button.dataset.view === viewId)));
}
buttons.forEach((button) => button.addEventListener('click', () => selectView(button.dataset.view)));
selectView('funnel');
</script>
</body>
</html>