55 Commits

Author SHA1 Message Date
ykcheungab e9710e140b 精简 Finger 示例的标定启动参数
从配置包读取几何资源,并提供显式无载荷启动置零。30 项测试、静态检查及现有录像验证通过。
2026-10-18 13:10:45 +08:00
ykcheungab ff7614a6a0 接入力标定 schema 3 与多点空间增益模型
保留旧格式和 cal_path,校验 SN、特征身份及坐标附件,按帧返回逐轴状态。相关测试 263 项通过,已核对存量预测并实测 180 帧录像。
2026-10-18 12:56:40 +08:00
ykcheungab 9c951e9d3c fix: 将 ARM64 wheel 纳入发布校验和上传流程
补齐全部架构的运行证据、GitHub 发布说明和 PyPI 逐文件下载核验。已通过 161 项测试、代码和文档门禁、九个 wheel 的本地索引下载核验,以及 ARM 三个 ABI 的 40 帧 CPU 检查。
2026-10-15 21:39:31 +08:00
ykcheungab bb15b750fb feat: 添加 ARM64 manylinux wheel 构建选项
复用现有 Docker 和 Nuitka 流程,隔离架构镜像并支持 aarch64 标签。已通过 47 项测试、代码及文档门禁,并完成 Python 3.10 ARM64 wheel 构建、隔离导入与内容审计。
2026-10-14 16:08:54 +08:00
ykcheungab 120b8c2cf6 为采集帧绑定主机时间与来源信息
采集时间随图像穿过处理队列,并修正未读帧的丢帧计数。通过采集与流水线针对性测试。
2026-10-11 12:48:34 +08:00
ykcheungab 34cb83d4a4 修正示例中的三轴力单位显示
避免未标定读数被示例标成 N,并让 Finger 示例读取 SDK 的每轴单位。已通过相关测试和语法检查。
2026-10-05 13:10:58 +08:00
ykcheungab 38d3e67b00 固定 HHD 下采样并标记三轴力单位
避免运行中改变 HHD 测量配置,并明确部分标定时各轴单位。已通过 SDK 与共享层测试。
2026-10-05 12:56:29 +08:00
ykcheungab 80f7da5a20 添加按设备 ID 选择和校验标定文件
避免多台传感器误用默认标定,缺文件时保持 raw。已通过 SDK 回归测试和文档检查。
2026-10-05 12:21:04 +08:00
ykcheungab 230b04a79d Add a sensor bundle contract separating family, backend and profile
Product name decided the pipeline: Mini worked live but replay refused it. A bundle descriptor now declares profile_id, product_family and processing_backend, with computational and visualization assets kept apart, and one resolver serves live and recorded input. Legacy bundles load through a documented adapter that never guesses a backend from a folder name.
2026-10-04 20:55:39 +08:00
ykcheungab 6e3d509239 Add pipeline pause and resume at two levels
Pause now holds the pipeline without tearing it down: CAPTURE_ONLY keeps the camera
streaming so a live sensor stays converged while the flow and HHD stages stop, and BOTH stops
the read as well. Resume rebases the tracker, because a held reference frame would otherwise
report the hold itself as deformation.

Verified with tests/test_pipeline_pause.py: 10 passed across three consecutive runs.
2026-10-04 20:55:35 +08:00
ykcheungab 333fa8fcff added pause/wait functions for stream 2026-09-30 21:23:08 +08:00
ykcheungab b5d7533e24 examples: make StreamPipeline the recommended entry, archive the manual loop
The two canonical examples taught the advanced path: they sequenced
get_img() -> compute_deformation() -> compute_contact() -> read_info() by hand
and unpacked a 13-element tuple positionally, which is what led developers to
reach for the compute backend, the capture queue and the stitch mode. The
managed alternative already existed and was documented nowhere.

Library (add-only, nothing removed):

- FrameSnapshot.image_size_raw carries the capture resolution, so a caller can
  compare it with the processed frame instead of reaching into Sensor.
- StreamPipeline.reset() resets the tracker and force filters *safely*. It is
  queued and applied by the flow stage before its next frame, never inline:
  Sensor.reset rebases initial_img on the current Sensor.img, which the flow
  stage is reading concurrently, so a caller-thread reset would capture a
  half-written reference frame. Idempotent.
- TactileProcessor.pipeline(produce) and FingerRuntime.pipeline() build a
  pipeline without the caller naming a backend concept; the latter is
  `with runtime.pipeline(contact=True) as pipe`.

Examples:

- examples/basic_pipeline.py and examples/finger_pipeline.py rewritten onto
  StreamPipeline + FrameSnapshot: one object, one call per frame, no tuple, and
  no compute backend, queue or stitch setting in sight.
- examples/archive/basic_pipeline_manual.py and _finger_pipeline_manual.py keep
  the previous versions byte-for-byte apart from a supersede header, so code
  copied from them keeps working. The finger header also records the archived
  --show defect (store_true with default=True, so it could never be disabled).
- examples/_display.py holds the shared display helpers, so an example no longer
  hand-rolls depth normalisation and colormap application.
- examples/README.md leads with the recommended pair and documents the manual
  form as still-supported, and states that examples/gui/ is moving to
  orisys-studio.

Tests: three added to tests/test_pipeline.py, covering the reset queue (it must
not run on the caller's thread and must land before the first compute_flow),
image_size_raw, and the None case when a producer reports no size. Verified the
reset test fails when reset() is made inline, so it discriminates.

Verified end-to-end against real media: basic_pipeline on data/sample/s1_480p.mp4
(box) reaches ~113 FPS and exits 0; finger_pipeline on data/dd02-0703/1.mp4
(finger) reaches ~140 FPS with mask coverage 0.41 and exits 0. Both archived
manual versions still run. tests/test_pipeline.py: 20 passed. Full suite:
342 passed, 3 failed - all three failures reproduce on the pristine tree
(import precedence, longrun timing, and a stale ruff version literal in
docs/code-review.md) and are unrelated to this change.
2026-09-30 17:09:02 +08:00
ykcheungab e2ac36269c added ruff code reivew 2026-09-27 19:21:55 +08:00
ykcheungab 0e903792bd fix test sample s1.mp4 missing 2026-09-20 11:46:03 +08:00
ykcheungab 153f51df11 change sample s1_480.mp4 to s1.mp4 2026-09-20 11:39:02 +08:00
ykcheungab 2e7b65298b fixed test_signal_processing error 2026-09-20 11:36:30 +08:00
ykcheungab e2b906a640 fix preflight config path check 2026-09-20 11:20:47 +08:00
ykcheungab 1cf78c9d71 fixed calibration data not loading due to path 2026-09-20 11:00:33 +08:00
ykcheungab 11962cdc34 配置没写的滤波键等于"关",不再回落到会滤波的默认值 - What: DEFAULT_FORCE_MEDIAN_WINDOW 3 -> 1、DEFAULT_FLOW_EMA_ALPHA 0.5 -> 1.0(DEFAULT_FORCE_LOWPASS_HZ 本就是 0.0),并把注释改成"配置文件没写的键就是关,而不是我们觉得合理的那一档"——原因写在注释里:否则设备会去滤一个没人要求滤的测量,而文件里没有任何线索;实测的延迟/降噪数据保留在注释中,作为 balanced/low_noise 预设的依据。docs/filters.md 第 2 节增加"缺省 = 关"这一条并说明没有 filters 段的配置什么都不滤,预设表里 balanced 的用途由"默认建议"改为"建议起步档"(它不再是默认值)。examples/filters/README.md 补一句"整段删掉等价于 off"。tests/test_filter_presets.py 新增 test_a_config_with_no_filters_block_filters_nothing:把 box bundle 的 filters 段整段删掉后构造真实 Sensor,断言 filters_state() 报 ema 1.0 / median 1 / cutoff 0.0 且 any_stage_applied 为 False。 - Why: 上一版只把"非法值"改成回落到关,但"键根本不写"仍会走 DEFAULT_* 从而把 EMA 0.5 + 中值 3 打开——这与"配置自描述、文件说什么就跑什么、出厂默认全关"矛盾,且现实里存在大量没有 filters 段的手写配置(例如 _perf/cfg_res_280x300.json),它们会在无人察觉的情况下继续滤波。缺省开是这条链上最后一个隐藏默认值。 - Verification: 删掉 filters 段后实测 filters_state() = (1.0, 1, 0.0) 且 any_stage_applied=False,出厂 box/mini/finger 三份同样为全关;pytest tests/test_filter_presets.py + tests/test_calibration.py → 33 passed;SDK 全量 336 passed / 15 skipped(唯一失败仍是需要 1200 帧而样例只有 577 帧的 longrun 测试);app 侧 studio 85 项与 shared 142 项测试、ui_check 554 项检查在升级后的 0.5.2 下全绿。 - Not in this change: 出厂 bundle 的三个显式值未动(本来就全关);_perf 的两个校验脚本不在仓库内,已就地补上显式 filters 段(balanced)以保持"开 vs 关"对照仍有意义;app 侧 wrapper/齿轮/CSV 17 列未动。 2026-09-14 10:53:33 +08:00
ykcheungab 7f8e5d0975 四个滤波预设落成机器可读的配置文件,并加上防漂移测试 - What: 新增 examples/filters/filters_{off,low_latency,balanced,low_noise}.json —— 每个都是完整可整块替换的 filters 段(五键齐全:flow_ema_alpha / force_median_window / force_lowpass_cutoff_hz / force_lowpass_order / force_lowpass_sample_rate_hz),数值即 FILTER_PRESETS 展开后的结果;examples/filters/README.md 说明这四份副本的存在与用途;新增 tests/test_filter_presets.py(12 项):预设名恰为四个、每个示例文件 == 默认块叠加该预设(改预设或改文件都会红)、每份都是含三个开关键的真实 filters 段、三个出厂 bundle(box/mini/finger)的 filters 段仍为全关、且用 external-frame 模式构造真实 Sensor 核对 filters_state() 报的也是全关(文件与设备必须一致)。 - Why: 之前的实现计划里写的是"四个 sensor_<preset>.json 整机配置",但整机配置要按传感器各复制一份、且必然随 bundle 漂移;README 里内嵌的 JSON 又无法被测试覆盖,等于把"建议用哪档滤波"这句话留在了一处会过时的散文里。改成"filters 片段 + 断言与 FILTER_PRESETS 逐值一致的测试",既不谎称是完整配置,也不会静默过时。 - Verification: pytest tests/test_filter_presets.py → 12 passed;SDK 全量 335 passed / 15 skipped(唯一失败仍是需要 1200 帧而样例只有 577 帧的 longrun 测试)。 - Not in this change: 未生成按传感器复制的整机配置;docs/filters.md 的预设表未纳入测试(只有这四个文件与代码常量对齐);app 侧未动。 2026-09-14 10:44:07 +08:00
ykcheungab 35190562e5 标定指纹改读生效值并按测量/读数分组 - What: calibration.py 新增 FILTER_MEASUREMENT_KEYS(flow_ema_alpha)与 FILTER_READOUT_KEYS(中值窗口、低通截止/阶数/采样率/rate_auto)、filters_fingerprint()(把 Sensor.filters_state() 归一化成 {measurement, readout, preset, source}:非法值丢弃、来源没写的键不出现而不是补默认、空映射返回 {} 表示"无记录")、filter_mismatches()(按组判读差异)与 _filters_from_config / _flat_filters_from(扁平旧格式与 preset 展开的兼容解析,显式键优先);pipeline_from_sensor_json() 新增 filters_state= 关键字——传了生效值就用生效值,否则读文件的 filters 段并标注 source="sensor.json.filters",返回结构化 filters 键,删除原先会凭空补出 0.5/3/10 的扁平键与 enabled 覆盖逻辑;Calibration.to_dict() 写 meta.filters(同时保留扁平键供旧读者按名取用);parse() 把 filters 读回 pipeline(此前 to_dict 写进 meta 的滤波键在读回时被整段丢弃,指纹实际是"只写不读");check() 改用 filter_mismatches 分开报告——measurement 组差异进 warnings 且措辞含 not comparable,readout 组差异进新增字段 CheckResult.notes(只记录、不拦截);build(extra_meta=…) 把 filters 与扁平滤波键折进结构化组。tests/test_calibration.py 新增 11 项测试(分组、preset 展开与显式键优先、enabled:false 全关、非法值为空而非默认、写入-读回往返、旧扁平文档读回、生效值压过文件、四个预设逐档核对)。docs/filters.md 新增第 7 节。 - Why: 用户决策 B 要求"Sensor.filters_state() 作为唯一生效值出口,calibration.py 指纹与 session.json 都读它、不读配置文件,指纹分 measurement/readout 两组";动手时确认旧实现三个问题叠加:来源错(读文件、被 filters.enabled 覆盖、文件没写就补默认 0.5/3/10),写进 meta 的指纹在读回时被丢弃,check() 因此永远比不出滤波差异——审计链是断的,不是不精确。 - Verification: SDK 全量 pytest 335 passed / 15 skipped,唯一失败 test_vnormal_longrun_no_outlier_jumps 需要 1200 帧而 data/sample/s1_480p.mp4 只有 577 帧(环境/数据,与本改动无关);external-frame 模式逐预设构造真实 Sensor,filters_fingerprint(filters_state()) 得 off(1.0,1,0.0) / low_latency(1.0,3,0.0) / balanced(0.5,3,0.0) / low_noise(0.3,3,10.0);写入→读回往返后 measurement/readout/preset 完整保留且 to_dict 幂等;旧扁平 meta 文档仍读回同一指纹;.repro/verify_cal_filters.py 50 项全绿。 - Not in this change: 未动 app(app 的 meta_from_sensor_json 只取 4 个键,不受影响);未升级 venv 内 SDK;examples/filters 的四个机器可读预设片段与 app 侧 wrapper/齿轮/CSV 17 列未动。 2026-09-14 10:43:58 +08:00
ykcheungab 514874e2f4 added 5 sensors multi-stream support, 5 finger reach > 100 fps stable using .mp4 video 2026-09-13 12:18:27 +08:00
ykcheungab 5f78115429 fix pypi cannot check after upload 2026-09-12 17:43:40 +08:00
ykcheungab 488c8b0bc1 fixed testpypi upload 2026-09-12 17:34:46 +08:00
ykcheungab 94f38bc389 fix github release 2026-09-12 17:01:35 +08:00
ykcheungab 174bceabc4 automate publishing: release github + release pypi 2026-09-12 16:50:55 +08:00
ykcheungab 388f34ca85 faster linux build 2026-09-12 16:36:59 +08:00
ykcheungab 35af74f639 exclude docs from wheel; harden bundle item handling; single-source version 2026-09-12 16:19:34 +08:00
ykcheungab 57bef85e32 fix preflight 2026-09-12 16:00:40 +08:00
ykcheungab 9537cf91a1 added preflight check 2026-09-12 15:49:28 +08:00
ykcheungab 96f4428230 added calibration data handling functions 2026-09-10 21:47:36 +08:00
ykcheungab ad680b77dc 0.5.1 2026-09-02 21:47:51 +08:00
ykcheungab 5be2d9759a hotfix/camera not connected error 2026-09-02 21:37:40 +08:00
ykcheungab 32823a7666 test if optical flow integration error: not significant for Mems 2026-09-01 21:27:10 +08:00
ykcheungab 8a4be5f8f2 update to 0.5.0 2026-08-26 20:20:37 +08:00
ykcheungab 577e3fe528 update pip install .copy manifest for developments 2026-08-26 20:04:40 +08:00
ykcheungab d59e1cb7fb fix path errors 2026-08-26 19:22:37 +08:00
ykcheungab ab97efe039 refractor stitcher class into module 2026-08-23 16:24:53 +08:00
ykcheungab 8a7760f12b refractor capture to a module 2026-08-23 15:53:02 +08:00
ykcheungab 2e09c9360e included low pass filter in package and add to plot_data example 2026-08-17 22:11:17 +08:00
ykcheungab 9a69f01278 reorganized build directory 2026-08-03 22:14:19 +08:00
ykcheungab d7c5845646 finished docker manylinux compliation for pypi 2026-08-03 17:07:54 +08:00
ykcheungab 8b2f76c76f prepare for dd03 shipping 2026-08-03 14:20:30 +08:00
ykcheungab 2e3d0a0609 added dd06 test support, organized 2d viewer and 3d viewer code organization. 2026-07-26 17:03:44 +08:00
ykcheungab 11a747a771 added camera search and select, auto preference saving and version tag to 0.4.2 2026-07-15 15:08:59 +08:00
ykcheungab a9c26fd1fb Merge branch 'feature/finger_docs' into dev 2026-07-14 20:07:43 +08:00
ykcheungab 30f9deb5b2 dd02 setting tune + change Class name from UVUnrollFrameProcessor to FrameUnwarper 2026-07-14 20:00:40 +08:00
zhangyijian 3d1039b52c Merge pull request 'Feature/dd02 0703' (#3) from feature/dd02-0703 into dev
Reviewed-on: http://100.106.67.31:3000/orisys-tech/orisys-sdk/pulls/3
2026-07-09 14:14:38 +08:00
ykcheungab c77a64ffe7 update version tag to 0.4.1 2026-07-09 13:59:19 +08:00
cheng edc6e42191 Update FFC files 2026-07-02 16:53:08 +08:00