Commit Graph

101 Commits

Author SHA1 Message Date
ykcheungab c37efd7a44 Lint the commits being pushed and scope overlay failures per sensor
The pre-push gate linted only the dirty tree, so the commits about to be pushed went
unchecked; and every failed overlay projection was sticky, which cost a finger result its
overlay over one bad frame while box results were retried nowhere. gate.ps1 now takes
-LintBase (default origin/main, exit 2 on an unknown ref), the projector declares whether
its own failures are permanent, and serve_stored_view decides before it sets the view.
Verified with gate.ps1 (PASS: 569 studio + 485 shared tests, 632 ui_check checks) and the
two round-2 red samples kept in scratch.
2026-10-18 21:17:03 +08:00
ykcheungab 0998009ec3 refactor: 拆出 Studio 状态显示并记录分步迁移计划
让状态显示独立于主窗口,保留录制快照注入入口。验证结果和完整门禁限制见 docs/architecture/studio-window-refactor-plan.zh.md。
2026-10-18 20:32:32 +08:00
ykcheungab 433b76e43c 修复 Studio 失败测试并新增合并门禁
把丢失的 box 录像放回 apps/studio/tests/data/,修掉第 3 节 3–10 号与两处过时测试桩,
注册 timing 标记并让根目录收集零错误;新增 tools/gate.ps1 与可选的 pre-push 钩子。
验证:studio 524 通过 19 跳过、shared 467 通过 18 跳过、ui_check 632 项 0 失败、gate.ps1 退出码 0。
细节见 docs/test-repair-plan.zh.md。
2026-10-18 19:24:31 +08:00
ykcheungab 85d0b396e3 修正 Studio 力曲线原点、运行不可用提示与禁用按钮样式
FN 轴视图留 8% 余量使 0 刻度与静止曲线离开边框;实时视图在轨道上直接写出运行不可用的原因;禁用按钮改为虚线无填充,复选框加勾,单选框选中不再变方,并放大勾选框、微调框箭头、滚动条与菜单行以便触屏操作。另修 ui_check 桩 worker 签名与英文回放提示。在 Linux 离屏环境对比未改动的 HEAD 验证:studio 失败集合为 HEAD 的子集,ui_check 结果一致。
2026-10-18 14:39:13 +08:00
ykcheungab f94b51e2de fix(studio): 统一 Box/Mini 箭头网格与强度着色 2026-10-10 16:07:26 +08:00
ykcheungab 48de5b74e6 在单位回退时就近提示缺少可用标定
让实时和回放的原始单位回退原因出现在力曲线单位按钮旁。相关定向测试与 lint gate 通过。
2026-10-10 15:05:09 +08:00
ykcheungab cf86bd0702 Merge branch 'main' of ssh://892887cvmk08.aicp.io:24928/orisys-tech/orisys-app 2026-10-10 14:16:54 +08:00
ykcheungab d4b66c65a1 Unify 2D arrows on the shared painter.
Drop orisys.util.draw_arrows; box live and replay both use
_paint_shared_flow_arrows with sdk_box_policy when no policy is passed.
Recovered box flow uses the same inverse as finger. Verified with
shared/tests/test_image_backend.py arrow/idle/recovered cases.
2026-10-09 13:34:10 +08:00
ykcheungab 091d0fda35 三维未激活采样显示灰点,二维增加深度叠箭头。
分析对话框默认使用传感器对话框保存的标定,关闭按钮改为保存。框选曲线时数值卡片仍显示光标读数。相关单测通过。
2026-10-08 17:04:30 +08:00
ykcheungab 3d2fb0c4eb 让直播标定文件从传感器对话框进入打开链路。
对话框可选配置默认、原始力或浏览文件,并按配置条目写入 prefs;点运行时把 cal_path(Finger 含 device_id)交给 worker,采集中则热更新。对话框与打开链路单测通过。
2026-10-08 16:37:26 +08:00
ykcheungab 19ae1f4968 三维显示与二维共用深度色标,配置名改为 Finger
箭头阈值写入设置;去掉网格告警。三维色标改为立刻采用二维量程(不再 P5/P95 缓变)。选择器显示 Finger。已用 pane UI、shared-scale 与 catalog 单测验证。
2026-10-08 16:10:58 +08:00
ykcheungab f2d7b3e83c 三维设置加箭头阈值,静默处理网格冲突
对话框写回 flow_on_px(二维三维共用),去掉 analysis_grid_mismatch 告警,缩短 UV/形变等工程腔文案并认 source=analysis。已用 pane UI 与 controller 单测验证。
2026-10-08 16:01:15 +08:00
ykcheungab f2bbab76a6 缩短 Studio 叠字与重复说明,色标只保留量程
去掉 depth_empty 与无用选区峰值文案,并修正「视图 → 分析视频」。已用 locale 单测与 depth_scale_text 核对;含证据录制的 wiring 用例本机跳过。
2026-10-08 15:41:30 +08:00
ykcheungab 48624dec99 让 Finger 视频分析使用所选的力标定文件。
分析链不再在打开前拒绝标定,而是把文件作为 cal_path 交给 FingerRuntime,并用操作者确认的设备编号核对文件里的 SN。标定传递测试与对话框 SN 校验通过。
2026-10-08 15:12:08 +08:00
ykcheungab 7afd3169fd 把 Studio 2D 画面与深度色标抽到 FrameView。
深度闩、域掩码与 _show_image_frame 离开主窗口;ImageSink 方法名保留为转发。朝向与深度闩测试、以及 monkeypatch render_image 的画面测试通过。
2026-10-08 10:39:40 +08:00
ykcheungab 3e45ecdc3c 把分析视频和分析设置挪到独立的「分析」菜单。
菜单栏为文件 | 采集 | 分析 | 视图 | 帮助。提示里指向这两项的路径已改成「分析」。
2026-10-07 21:36:13 +08:00
ykcheungab 154a84ddae 把运行/预览/暂停等采集控制挪到「采集」菜单。
菜单栏顺序为文件 | 采集 | 视图 | 帮助;复位视图、主题与语言仍在视图。快捷键不变。
2026-10-07 21:31:02 +08:00
ykcheungab 92e6de6913 收紧绘图设置为两页,并把 FN 牛顿下限固定为 0。
手指 2D 方向改到 ArrowPanel 设置对话框;归零阈值不变。已用 display_prefs、finger_2d_orientation 与绘图对话框相关 smoke 测试验证。
2026-10-07 20:48:48 +08:00
ykcheungab b1cd37148c 删掉回放的五个转发、重复的空格快捷键与重复的等待循环。
回放调用点直接走 replay_ctl,场景工具的路径引导收敛到 _paths,panel_snapshot
复用 panel_check 的 _wait_for,report_from 收成模块私有的 _report_from。
2026-10-07 12:25:48 +08:00
ykcheungab 86996694b4 统一力值阈值处理并保留原始采样
移除自动显示基线,使逐轴阈值统一作用于曲线、读数与记录输出,标定拟合继续使用原始采样。
共享层全量测试和相关 Studio 测试通过。
2026-10-07 12:25:12 +08:00
ykcheungab 6194778a6f 收起复用与完成态分析横幅。
来源栏已显示结果状态,横幅约 1.5 秒后只隐藏控件并保留 state()。已用 apps/studio/tests/test_analysis_progress.py 验证。
2026-10-07 09:37:08 +08:00
ykcheungab 97e80d3d38 为二维与三维深度色标增加每帧自适应选项。
默认仍锁定本会话首帧,勾选后两视图按当前帧有效深度共用同一范围。已用深度色标与显示设置测试验证。
2026-10-07 09:34:57 +08:00
ykcheungab 425f0dc9e2 统一 2D/3D 深度色条为同一量程。
将 2D 闩锁的深度色彩区间推给 3D 自动着色,固定量程仍跟旋钮。用 test_shared_depth_scale 与深度闩锁冒烟用例验证。
2026-10-06 21:31:53 +08:00
ykcheungab 829d2c1b53 回放叠加改用展开底图,并统一 2D/3D 投递。
箭头/采集图像与 live 的 processed_frame 对齐;deliver_measurement 先画 2D 再提交同一包给 3D。已用 overlay、scene3d 与 replay 相关测试验证。
2026-10-06 21:21:37 +08:00
ykcheungab 321e52f47a 改善 Studio 回放布局与传感器切换体验
缩短界面提示,保存上次视频目录,并防止旧结果绘入 Finger 3D。针对性测试及可见界面复测通过。
2026-10-06 20:18:50 +08:00
ykcheungab 425fa0d44d Fix replay 2D black canvas and journey UX clarity
Stored analysis overlays now use the decoded frame; latch resets and draw failures surface. Verified with bare-video, replay-wiring, visual_policy, and analysis-progress tests.
2026-10-06 16:26:47 +08:00
ykcheungab d11441cd79 Show only the bundle's name in the sensor configuration row
The row carried the origin, the calibration selection and the SDK's verdict, which a 30 px
line cannot explain; it is now the descriptor's display_name, else the folder name, and the
sensor dialog states the rest under the selector — name and folder, profile, shape, root,
verdict, calibration and every finding — with a suffix only where two rows would otherwise
read alike. Verified with the studio suite, the catalog tests in shared/tests, ui_check and
the lint gate.
2026-10-05 17:01:42 +08:00
ykcheungab 92b2f2fcd7 裸视频可分析:生成工作区、设置提示、逐帧力与按来源选画笔
pass 只认 frames.csv 与 session.json,裸视频此前因此只能播放;现在为它在应用自己的目录里生成
这两份文件并复用既有链路,链路重算的力按帧存入结果并标注为「重算」,box 的空白箭头画布改按帧
来源走共享画笔。
apps/studio/tests 497 项、shared/tests 471 项(2 个已知墙钟失败)、autocal 358 项、ui_check 634 项
均 0 失败,lint_gate 与 doc_lint 无发现;真实 GL 快照见 .scratch/bare-video/snapshots。
2026-10-05 16:57:02 +08:00
ykcheungab c0a10e6adb Present replay 3D with the cursor and open Analyze on a remembered video
Replay left the 3D pane on the rest mesh or a sparse overlay, and Analyze skipped the setup dialog unless the file was re-picked. Live Run no longer starts a chain on a video path. Verified with Studio tests for flush, overlay mask, Analyze open, live-video refusal, and locales.
2026-10-05 16:52:27 +08:00
ykcheungab 3433eb0fec Record the live box arrow grid so replay matches live paint
Box analysis used the finger sample grid, so replay packed arrows into the contact zone. The pass now stores draw_arrows cells; stale box caches miss and re-run. Verified with shared and Studio tests, including a live-vs-replay canvas check.
2026-10-05 15:01:48 +08:00
ykcheungab 28e955a817 把 Studio 主机协议改成单向端口,并让「从视频重算」走分析入口
控制器经 AcquireGate / ImageSink / ShellNotes 与信号接线,采集 tick 用 acquire_presenter 上屏;三维测试证明分析结果已喂 3D 后,重算并入 on_analysis_requested。
验证:apps/studio 下相关 pytest 与 tools/ui_check.py(634 checks)通过。
2026-10-05 14:00:24 +08:00
ykcheungab 25ccffd814 Discover sensor bundles from the SDK catalog, not a product list
The picker listed a hard-coded product list and treated any *.json beside sensor.json as a
configuration, so a folder of stray JSON could be offered as a sensor. Discovery now scans the
shipped root and a writable user root beside it, keeps the SDK's verdict for every entry
(listing rejected ones with their reason) and flags duplicate profile_ids instead of shadowing
them; verified by shared/tests and apps/studio/tests.
2026-10-05 09:30:04 +08:00
ykcheungab a92a2ba237 Read the analysis cache before refusing a pass, and own the cache root
Opening a recording while the session that recorded it was still live never reached
``stored_result()``, so the panel reported no result over a recording whose result was on
disk. The guard now follows the cache read, results move to the app's derived-data root
(swept at startup, the old in-recording root ignored), and the panel states which of the
four no-result states it is in, with the pass's own reason.
Verified: apps/studio 462/0/18, shared 431/0/1, autocal 358, ui_check 628/0, both gates
clean, real-GL snapshots per state.
2026-10-04 16:53:50 +08:00
ykcheungab 1aa454311f Make the cached analysis views reachable over a recording
Replay moved the cursor onto the result's timeline, so the recording's own
picture was not offered at all and ``use_recording()`` had no caller. Adopting a
result now keeps the cursor on the recording, opens the panel on a derived view,
and serves scrubs, playback and display changes from the cache (Part B §9).
Verified: apps/studio 455 items / 0 failed / 18 skipped, shared 427 / 0 / 1,
autocal 358, ui_check 628 checks / 0 failures, lint gate clean.
2026-10-04 16:04:02 +08:00
ykcheungab 9e20fd0277 Store the depth channel in an analysis result and serve it to the 2D depth view
A replay could draw arrows but not depth, and the recording view said there was
nothing to draw even when a result existed. Depth is now quantised per frame
(14 B empty, 486 B at the worst frame seen), read from the cache by the same
draw path live uses, and the raw-recording note appears only when no result
exists. Format version 2; see apps/studio/docs/replay-analysis.md.
2026-10-04 14:11:22 +08:00
ykcheungab cf49b0836e Serve replay playback from a cached analysis result
Replay re-ran the SDK chain on every seek; Part A's pass stores the flow
samples once. Opening a recording now reuses a compatible result or runs the
pass behind a progress/cancel surface, and one cursor with two modes
(recorded CSV, analysed) feeds the charts, the 2D canvas and the 3D pane by
frame id. A threshold, colour or idle-dot change redraws from the stored
frames and writes nothing; a cancelled pass is reported and never played.

Verified: apps/studio/tests 440 items / 0 failed / 18 skipped (15 new, no
existing assertion changed); shared 417 / 0 / 1; autocal 358.
2026-10-04 13:38:03 +08:00
ykcheungab 6fb2f72c6e Make the rail reset zero the sensor in live and the display in replay
The replay view disabled a control whose display reset is exactly what an
operator wants there, and the bare "Reset" hid that the live one zeroes the
sensor tracker; the label, tooltip and status line now name the target, and
Ctrl+R follows the view. Verified with the studio suite, ui_check (628
checks) and real-GL rail snapshots of both views.
2026-10-04 11:09:22 +08:00
ykcheungab dda6c74fb7 fix the finger 2D canvas orientation and the 3D arrow size
The unrolled canvas put the finger's +x where the 3D default view puts screen-left,
and the 3D flow arrows rasterised as 0.23 px hairlines because their stroke was 2 %
of their own sub-millimetre length. The 2D presentation is now the derived half turn
(persisted, set from the plot-settings dialog) and the 3D stroke is one canvas pixel
— the width the 2D canvas draws — verified numerically and with real-GL snapshots.
2026-10-04 10:04:51 +08:00
ykcheungab 9b1a3fb922 state the finger 3D camera presets in the design export's frame
The default view came from the mesh's own face normal and sat 24.6 degrees off the
design export's frame; re-applying any preset also adopted its baked distance, so the
part overflowed the viewport (measured 2.16 x 2.12 of it). Presets are now the frame's
own views, every preset is reframed through the pane's existing fit, and that fit
projects the model's bounds instead of a bounding sphere. Verified: the frame axes map
to screen up, left and viewer to 1e-6, the model fills 0.60-0.95 of the viewport at two
sizes, and the recompiled package keeps its geometry, domain and source-geometry ids.
2026-10-01 16:56:36 +08:00
ykcheungab eb70ac7638 add the Studio element manifest and its window-matching test
ui-layout.md named the arrangement's owners but nothing knew which elements exist, so a
view switch could silently take a running session's tracker reset away: docs/ui-elements.json
now states all 195 by region, pane and view, ui/elements.py loads it, and
tools/ui_elements_dump.py drafts it.
Verified: apps/studio 393 items (13 new) and ui_check 600/0, autocal 358, shared 390 with its
2 known wall-clock failures, lint and doc gates clean; a removed element, a renamed
objectName and a new named widget each fail the suite.
2026-10-01 15:18:16 +08:00
ykcheungab e0156a14c6 fix Studio reset, 3D base colour and arrow-trigger defects
The tracker reset was decided by which panel was on screen rather than by the
session, the automatic colour range moved the 3D surface's base colour on the first
press, and the 2D canvas and the 3D overlay applied different flow thresholds (622
arrows against 432 on a real recording). ui_check 600/0; apps/studio 380 items and
shared 390 items with no failures; real-GL 18 items, only the pre-existing
colour-scale failure; AutoCal 358 passed; both views now select identical arrows on
all 42 frames of a real video.
2026-10-01 14:40:33 +08:00
ykcheungab 720bd81031 fixed window flashing bug 2026-09-28 21:17:26 +08:00
ykcheungab fa2703968e added ruff test 2026-09-27 19:20:43 +08:00
ykcheungab bcab2790bf modify 3d view to sync / identical to 2d view 2026-09-27 10:42:38 +08:00
ykcheungab 3daee6d407 fixed display problem 2026-09-25 17:53:07 +08:00
ykcheungab 12781854ca fixed commetn from songxiao 2026-09-25 17:46:37 +08:00
ykcheungab ccedb9ddd9 migrate pyqt5 to pyside6 2026-09-21 09:34:56 +08:00
ykcheungab e276b5de0f autocal layout first design 2026-09-20 21:15:39 +08:00
ykcheungab c538dbf074 fixed label under 3d view 2026-09-15 21:50:37 +08:00
ykcheungab c2293d4d41 界面:三维可选「深度响应 / 光流幅值」上色(默认深度),并加一个「诊断信息」开关收拾面板脚下的文字
- What(颜色来源): `DisplaySettings` 增 `field`(`"depth"` 默认 / `"flow"`),随显示设置持久化
  (`scene3d/prefs.py`:新增 `FIELD_CHOICES`/`DEFAULT_FIELD`,手改文件里的非法值修回默认)。
  `FingerFrameAdapter` 按所选字段先试、失败再用另一个,并把"换了量"这件事记在
  `last_substitution`(新诊断码 `field_substituted`,info 级);两个字段都拿不到时,
  `last_diagnostic` 取**信息量最大**的那条(域不符/过期/未声明 > 没这个字段),而不是"所选字段"的
  那条空话。设置对话框新增「颜色来源」下拉,下面一行 `field_note` 直接写"这一帧画的是 X,不是所选的 Y";
  图例(`legend_label`)永远标注**实际**画出来的量,所以设定与画面不一致时两处都能看出来。
  深度响应 `[1]`、光流幅值 `[px]`,两者都是 `approximate`——代码与文案都不把它们说成毫米。
- What(诊断信息开关): 视图菜单新增 `诊断信息`(可勾选、持久化 `show_diagnostics`、**默认关**,
  由 `DisplayPrefsController` 持有并推给两个面板)。关掉后:2D 面板只留"画面 + 计划说明 + 深度色标",
  三条解释流水线的标签(箭头按位移放大、原始图像 → 算法输出、全部帧)隐藏;3D 面板只留
  色条 + 一行图例 + 来源,info 级诊断隐藏。**永不隐藏**:warning/error 级诊断(测量是否过期、
  字段是否本帧的、是否与设备核对过——`geometry_unverified` 虽然是 info 也白名单保留)与
  深度色标。3D 图例改成 `ShrinkableLabel`(一行、裁切 + tooltip,不再折行),色标数值从 4 位有效数字
  收到 3 位("0.0334 – 0.899")。设置对话框控件宽度 88 → 108 px(不再需要迁就 240 px 面板)。
- What(取景脚本): `tools/ui_snapshot.py --scene flow3d` 现在同时给 flow 与 depth(各带 provenance),
  所以「颜色来源」开关有东西可切;再加 `.repro/shot_variants.py` 一次出四张图
  (深度版 / 光流版 / 诊断开 / 设置对话框)。
- What(测试): `test_scene3d_adapters.py` 增 3 项(默认深度、换量时给出 `field_substituted` 并在恢复后
  清掉、depth 不在场景栅格时按 `field_domain_mismatch` 拒绝而不是缩放);`test_scene3d_view.py` 增
  1 项(field 的持久化与修复,并把 `field in FIELD_CHOICES` 加进"手改文件会被修复"的参数化);
  `test_scene3d_pane_ui.py` 增 3 项(两种量可选 + 说明行 + 恢复的偏好会移动下拉;诊断开关只隐藏 info、
  保留 warning 与"未核对";2D 脚注三标签的显隐与窗口开关一致);`test_display_prefs.py` 增 1 项
  (开关推到两个面板、写偏好)。`test_ui_smoke.py` 与 `tools/ui_check.py` 里"箭头图例可见"的四条断言
  改为按新规则检查(默认隐藏、开诊断后可见、关掉再隐藏)。
- Why: ①"深度"比"光流"更贴近操作员口中的"压得多深",但两者都只是近似量,所以做成开关而不是替换——
  并且换量必须说出来(否则画面会被读成所选的量)。②面板脚下的解释文字是"内部管线"而不是"画面是什么",
  拍视频与日常看都只需要后者;用一个开关收起,比做一个滚动日志面板诚实(这些是每帧状态,不是事件)。
- Verification: pytest shared/tests apps/studio/tests(offscreen)658 passed / 0 failed / 15 skipped;
  真 GL 组(gl_smoke + view + pane_ui)70 passed / 0 failed / 1 skipped;
  `tools/ui_check.py` 590 项检查 0 失败;`.repro/locale_check.py` 0 缺失(新增 7 个 key 双语齐备)。
  目视验收:同一批合成数据渲染的四张图(深色主题)——深度版(默认)、光流版、诊断打开、设置对话框。
- Not in this change: 不改采集/记录/契约之外的三维渲染;不做页签容器与窄窗口回退;曲线量程仍是出厂 ±20 N。
  真机待验证:手指路径上 `packet.depth` 的栅格是否就是场景的 300×280(若不是,面板会写明并回退到光流)。
2026-09-15 21:23:18 +08:00