docs: package EM observation dashboard
This commit is contained in:
@@ -213,6 +213,7 @@ dotnet run --project ClumsyPilot/tests/EMPlannerVerificationHost/EMPlannerVerifi
|
||||
```text
|
||||
plugins/
|
||||
├── ClumsyPilot.dll
|
||||
├── TrajectoryPlanningVisualization.dll
|
||||
├── osqp.dll
|
||||
└── licenses/
|
||||
├── OSQP-LICENSE.txt
|
||||
@@ -220,7 +221,11 @@ plugins/
|
||||
└── OSQP-VERSION.txt
|
||||
```
|
||||
|
||||
发布器会检查 64 位 PowerShell、原生 DLL 的 x64 PE 类型和固定 SHA-256。OSQP 加载器从托管程序集目录以绝对路径加载同级 `osqp.dll`;它不依赖 `PATH` 或当前工作目录。部署和执行职责的更多说明见 [TrajectoryExecution](../TrajectoryExecution/README.md)。
|
||||
发布器只从显式 `ManagedDll` 的同级目录解析 `TrajectoryPlanningVisualization.dll`,先复制完整包到 staging,
|
||||
再原子替换 `plugins` 目录;它不会搜索 `PATH` 或当前工作目录。发布器会检查 64 位 PowerShell、原生 DLL 的 x64 PE
|
||||
类型和固定 SHA-256,并保留既有恢复行为。OSQP 加载器从托管程序集目录以绝对路径加载同级 `osqp.dll`;它不依赖
|
||||
`PATH` 或当前工作目录。部署和执行职责的更多说明见 [TrajectoryExecution](../TrajectoryExecution/README.md),网页
|
||||
观察的开关、token URL、图表语义和停止清理见 [EM trajectory observation MovementTest](../tarjplanner_movementtest/README.md)。
|
||||
|
||||
## 常见错误(Common Errors)
|
||||
|
||||
|
||||
@@ -76,6 +76,30 @@ rejected before EM planning.
|
||||
and must never be forwarded directly to a vehicle motion interface. This MovementTest performs no coordinate conversion
|
||||
for driving and has no driving capability; any future execution mode requires a separate safety-reviewed design.
|
||||
|
||||
## 网页看板与可选 Painter
|
||||
|
||||
将 `EnableWebVisualization=true` 可启用本机网页看板;它只绑定 `127.0.0.1`,启动日志会给出完整的、带随机
|
||||
会话令牌的 URL。端口为 `0` 时由系统选择可用回环端口;浏览器必须使用该完整 URL,不能删掉 token。默认
|
||||
`AutoOpenWebVisualization=true` 会尝试打开默认浏览器;无桌面会话或打开失败只记录 URL,服务和观察循环继续运行。
|
||||
网页默认以 `10 Hz` 发布不可变动态快照,网页关闭、断开或慢客户端只会丢弃网页帧,绝不会阻塞、序列化等待或改变
|
||||
规划周期。
|
||||
|
||||
`EnableNativePainterVisualization=true` 才会为本会话创建 `TrajectoryObserver.World`、`LS`、`ST` Painter;默认关闭。
|
||||
网页与 Painter 可以同时开启,也可全部关闭:全部关闭时仍保留 `OBSERVE_ONLY` 规划、控制台和 UI 状态。网页的启动、
|
||||
快照或服务出现异常时会只记录一次中文诊断并熔断本次网页输出,不自动循环重启,也不会停止规划观察。
|
||||
|
||||
网页采用中文说明配合科研绘图约定:白底、细灰网格和细曲线;当前轨迹为蓝色实线,上一轮为灰色虚线,换向与交接点
|
||||
为橙色,红色仅表示实际越界或失败。路径总览把已完成方向段画为灰色细实线、活动段画为蓝色细实线、未来段画为浅灰
|
||||
虚线,并以深蓝覆盖当前规划视界。页面的 `ReferenceS (m)` 是将轨迹投影到**完整活动方向段**后的共享参考站;
|
||||
`PathS (m)` 是每轮 ST 求解使用、从该轮局部起点累计的实际路径弧长,二者不可互相替代或跨轮直接相减。
|
||||
|
||||
运动学页中 `j[i]` 仅表示真实区间 `[tᵢ, tᵢ₊₁)`,所以 jerk 只有 `N-1` 个样本;末点之后没有虚构的 `j=0`。
|
||||
状态页将滚动续航、接近停车边界和精确停车边界分别标为 `RollingContinuation`、
|
||||
`ApproachStopBoundary`、`ExactStopAtBoundary`:前两者允许非零末端速度,只有真实边界才是精确停车锚点。换向高亮
|
||||
仅会在投影位置满足容差、已连续停车保持 `GearSwitchStopHoldSeconds`,并取得
|
||||
`DirectionConfirmationSamples` 个满足 `DirectionConfirmationSpeedMetersPerSecond` 阈值的下一方向带符号速度样本后,
|
||||
严格从 `N -> N+1` 前进。
|
||||
|
||||
## Operator launch and stop checklist
|
||||
|
||||
The vehicle UI entry is `EM轨迹规划观察闭环测试`. It is an observation session only; it has no chassis,
|
||||
@@ -97,6 +121,8 @@ command is diagnostic information only and must not be copied into a vehicle-con
|
||||
|
||||
To stop, use the vehicle UI's normal MovementTest stop action. Confirm the status says
|
||||
`Observation stop requested; all observer layers were cleared.` The cancellation request stops observer work and clears
|
||||
all three layers. A current-session runtime fault also clears all three layers so stale active diagnostics are not left
|
||||
on screen; an intentional bootstrap failure preserves its diagnostic world view. Stopping, running, or starting this
|
||||
test must not issue chassis, motor, steering, brake, or gear output.
|
||||
an existing Painter, stops the web publisher/HTTP/SSE service, and releases its port. A current-session runtime fault
|
||||
also clears an existing Painter and stops the web session so stale diagnostics are not left on screen; an intentional
|
||||
bootstrap failure still reports through UI/console even when both visualization modes are off. Closing a browser tab does
|
||||
not stop the session; `TestStop()` owns final web and Painter cleanup. Stopping, running, or starting this test must not
|
||||
issue chassis, motor, steering, brake, or gear output.
|
||||
|
||||
@@ -47,6 +47,10 @@ if (Test-SamePath $outputDirectoryPath $workspaceRoot) {
|
||||
if (-not [System.IO.File]::Exists($managedDllPath)) {
|
||||
throw "Managed DLL does not exist: $managedDllPath"
|
||||
}
|
||||
$visualizationDll = Join-Path ([System.IO.Path]::GetDirectoryName($managedDllPath)) 'TrajectoryPlanningVisualization.dll'
|
||||
if (-not [System.IO.File]::Exists($visualizationDll)) {
|
||||
throw "Visualization DLL does not exist beside managed DLL: $visualizationDll"
|
||||
}
|
||||
if (-not [System.Environment]::Is64BitProcess) {
|
||||
throw 'Refusing to publish from a non-x64 PowerShell host.'
|
||||
}
|
||||
@@ -89,6 +93,7 @@ $movedExistingPlugins = $false
|
||||
try {
|
||||
[System.IO.Directory]::CreateDirectory((Join-Path $stagingDirectory 'licenses')) | Out-Null
|
||||
[System.IO.File]::Copy($managedDllPath, (Join-Path $stagingDirectory 'ClumsyPilot.dll'), $false)
|
||||
[System.IO.File]::Copy($visualizationDll, (Join-Path $stagingDirectory 'TrajectoryPlanningVisualization.dll'), $false)
|
||||
[System.IO.File]::Copy($nativeDll, (Join-Path $stagingDirectory 'osqp.dll'), $false)
|
||||
[System.IO.File]::Copy($license, (Join-Path $stagingDirectory 'licenses\OSQP-LICENSE.txt'), $false)
|
||||
[System.IO.File]::Copy($notice, (Join-Path $stagingDirectory 'licenses\OSQP-NOTICE.txt'), $false)
|
||||
|
||||
@@ -83,14 +83,20 @@ internal static class PluginPackagingChecks
|
||||
relativeFiles.Add(Path.GetRelativePath(packageRoot, files[index]).Replace('\\', '/'));
|
||||
relativeFiles.Sort(StringComparer.Ordinal);
|
||||
|
||||
Verification.Equal("plugins/ClumsyPilot.dll|plugins/licenses/OSQP-LICENSE.txt|plugins/licenses/OSQP-NOTICE.txt|" +
|
||||
"plugins/licenses/OSQP-VERSION.txt|plugins/osqp.dll", string.Join("|", relativeFiles),
|
||||
"plugin tree contains exactly the managed DLL, native DLL, and OSQP license files");
|
||||
Verification.Equal("plugins/ClumsyPilot.dll|plugins/TrajectoryPlanningVisualization.dll|" +
|
||||
"plugins/licenses/OSQP-LICENSE.txt|plugins/licenses/OSQP-NOTICE.txt|plugins/licenses/OSQP-VERSION.txt|" +
|
||||
"plugins/osqp.dll", string.Join("|", relativeFiles),
|
||||
"plugin tree contains exactly the managed DLLs, native DLL, and OSQP license files");
|
||||
|
||||
string managedPlugin = Path.Combine(pluginsDirectory, "ClumsyPilot.dll");
|
||||
AssemblyName managedAssembly = AssemblyName.GetAssemblyName(managedPlugin);
|
||||
Verification.True(!string.IsNullOrWhiteSpace(managedAssembly.Name), "packaged ClumsyPilot.dll is managed");
|
||||
|
||||
string visualizationPlugin = Path.Combine(pluginsDirectory, "TrajectoryPlanningVisualization.dll");
|
||||
AssemblyName visualizationAssembly = AssemblyName.GetAssemblyName(visualizationPlugin);
|
||||
Verification.Equal("TrajectoryPlanningVisualization", visualizationAssembly.Name,
|
||||
"packaged visualization DLL has the expected managed assembly name");
|
||||
|
||||
string nativePlugin = Path.Combine(pluginsDirectory, "osqp.dll");
|
||||
Verification.Equal((ushort)0x8664, ReadPeMachine(nativePlugin), "packaged OSQP binary is x64");
|
||||
Verification.Equal(ReadExpectedOsqpHash(repositoryRoot), GetSha256(nativePlugin),
|
||||
|
||||
Reference in New Issue
Block a user