发布 SDK 0.6.0 并补充场标定使用说明
支持不带前缀的版本标签,保留 Finger 资产随 wheel 交付。发布工具 97 项回归及 SDK 自带资产的场标定录像验证通过。
This commit is contained in:
@@ -192,6 +192,7 @@ def _cmd_github(argv: list[str]) -> int:
|
|||||||
help="actually mutate the release repo, push, and create the release",
|
help="actually mutate the release repo, push, and create the release",
|
||||||
)
|
)
|
||||||
parser.add_argument("--notes-file", type=Path, default=None, help="release notes markdown")
|
parser.add_argument("--notes-file", type=Path, default=None, help="release notes markdown")
|
||||||
|
parser.add_argument("--tag", default=None, help="release tag: <version> or v<version> (default)")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--attach-preflight",
|
"--attach-preflight",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@@ -218,6 +219,7 @@ def _cmd_github(argv: list[str]) -> int:
|
|||||||
version=args.version,
|
version=args.version,
|
||||||
apply=args.apply,
|
apply=args.apply,
|
||||||
notes_file=args.notes_file,
|
notes_file=args.notes_file,
|
||||||
|
tag=args.tag,
|
||||||
attach_preflight=args.attach_preflight,
|
attach_preflight=args.attach_preflight,
|
||||||
allow_dirty_release=args.allow_dirty_release,
|
allow_dirty_release=args.allow_dirty_release,
|
||||||
skip_fetch=args.skip_fetch,
|
skip_fetch=args.skip_fetch,
|
||||||
|
|||||||
+11
-4
@@ -8,7 +8,7 @@
|
|||||||
3. sync the open-source subset of this checkout into ``orisys-sdk-release``
|
3. sync the open-source subset of this checkout into ``orisys-sdk-release``
|
||||||
(``tools/sync_downstreams.py`` + the manifest's ``checks``)
|
(``tools/sync_downstreams.py`` + the manifest's ``checks``)
|
||||||
4. stage ``SDK/<version>/*.whl`` into ``orisys-sdk-release/release/<version>/``
|
4. stage ``SDK/<version>/*.whl`` into ``orisys-sdk-release/release/<version>/``
|
||||||
5. commit, tag ``v<version>``, push branch + tag
|
5. commit, tag (default ``v<version>``), push branch + tag
|
||||||
6. create the GitHub Release with the wheels attached, then verify the assets
|
6. create the GitHub Release with the wheels attached, then verify the assets
|
||||||
|
|
||||||
Nothing mutates anything unless ``--apply`` is passed: the default is a dry run
|
Nothing mutates anything unless ``--apply`` is passed: the default is a dry run
|
||||||
@@ -48,6 +48,7 @@ class Options:
|
|||||||
skip_fetch: bool = False
|
skip_fetch: bool = False
|
||||||
skip_checks: bool = False
|
skip_checks: bool = False
|
||||||
skip_release_upload: bool = False
|
skip_release_upload: bool = False
|
||||||
|
tag: str | None = None
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -131,7 +132,7 @@ def build_github_steps(
|
|||||||
tag,
|
tag,
|
||||||
"--verify-tag",
|
"--verify-tag",
|
||||||
"--title",
|
"--title",
|
||||||
title or f"v{version}",
|
title or tag,
|
||||||
"--latest",
|
"--latest",
|
||||||
]
|
]
|
||||||
if notes_file is not None:
|
if notes_file is not None:
|
||||||
@@ -242,6 +243,10 @@ def _stage_wheels(wheels: list[Path], asset_dir: Path) -> None:
|
|||||||
|
|
||||||
def publish(options: Options) -> int:
|
def publish(options: Options) -> int:
|
||||||
version = options.version
|
version = options.version
|
||||||
|
tag = options.tag or f"v{version}"
|
||||||
|
if tag not in {version, f"v{version}"}:
|
||||||
|
print(f"[FAIL] tag must be {version!r} or {'v' + version!r}")
|
||||||
|
return 1
|
||||||
mode = "APPLY" if options.apply else "DRY RUN"
|
mode = "APPLY" if options.apply else "DRY RUN"
|
||||||
print(f"=== release github: orisys {version} ({mode}) ===")
|
print(f"=== release github: orisys {version} ({mode}) ===")
|
||||||
|
|
||||||
@@ -287,8 +292,10 @@ def publish(options: Options) -> int:
|
|||||||
return 1
|
return 1
|
||||||
print(f"[ok ] release repo: {repo} ({branch}) clean={not dirty}")
|
print(f"[ok ] release repo: {repo} ({branch}) clean={not dirty}")
|
||||||
|
|
||||||
tag = f"v{version}"
|
|
||||||
existing = _existing_release_tags(repo, version)
|
existing = _existing_release_tags(repo, version)
|
||||||
|
if existing and tag not in existing:
|
||||||
|
print(f"[FAIL] version already has tag(s) {existing}; refusing a second tag {tag}")
|
||||||
|
return 1
|
||||||
# A tag that exists without a GitHub Release means a previous run got as far
|
# A tag that exists without a GitHub Release means a previous run got as far
|
||||||
# as pushing the tag and then failed (or the upload was left manual). That is
|
# as pushing the tag and then failed (or the upload was left manual). That is
|
||||||
# exactly the resumable state, so continue instead of refusing.
|
# exactly the resumable state, so continue instead of refusing.
|
||||||
@@ -383,7 +390,7 @@ def publish(options: Options) -> int:
|
|||||||
_git(repo, "add", "-A")
|
_git(repo, "add", "-A")
|
||||||
pending = _git(repo, "status", "--porcelain")
|
pending = _git(repo, "status", "--porcelain")
|
||||||
if pending:
|
if pending:
|
||||||
_git(repo, "commit", "-m", f"release {version}")
|
_git(repo, "commit", "-m", f"发布 SDK {version}")
|
||||||
print(f"[ok ] committed {len(pending.splitlines())} change(s) in {repo}")
|
print(f"[ok ] committed {len(pending.splitlines())} change(s) in {repo}")
|
||||||
else:
|
else:
|
||||||
print("[ok ] nothing new to commit in the release repo")
|
print("[ok ] nothing new to commit in the release repo")
|
||||||
|
|||||||
@@ -8,10 +8,37 @@
|
|||||||
## 定位与边界
|
## 定位与边界
|
||||||
|
|
||||||
从现有多点增益生成空间图,对 HHD 无旋向量场做加权求和,作为 FN 的实验估计。
|
从现有多点增益生成空间图,对 HHD 无旋向量场做加权求和,作为 FN 的实验估计。
|
||||||
不依赖深度、接触中心、最大光流点或单接触判定;实时入口尚未接入,必须显式拒绝。
|
不依赖深度、接触中心、最大光流点或单接触判定。SDK 的 `FingerRuntime` 可直接加载模型、
|
||||||
|
声明加权空载窗口并逐帧推断;处理来源可以是录像或相机。尚未接入的是 Studio 实时采集界面,
|
||||||
|
其应用入口仍显式拒绝场模型,不是 SDK 的来源限制。
|
||||||
现有增益对应各加载位置的整场响应,不是已验证的局部系数。交付证明软件契约与可复现估计,
|
现有增益对应各加载位置的整场响应,不是已验证的局部系数。交付证明软件契约与可复现估计,
|
||||||
不宣称局部压力、多接触力可加性或精度改善。负的基线差保留;显示阈值只由显示层决定。
|
不宣称局部压力、多接触力可加性或精度改善。负的基线差保留;显示阈值只由显示层决定。
|
||||||
|
|
||||||
|
SDK 使用示例(配置、资产、模型和设备身份须匹配):
|
||||||
|
|
||||||
|
```python
|
||||||
|
from orisys.finger import FingerRuntime
|
||||||
|
|
||||||
|
runtime = FingerRuntime.open(
|
||||||
|
config="sensor.json", export_dir="assets", video="input.mp4",
|
||||||
|
cal_path="force_calibration.field.json", device_id="YOUR-SENSOR-SN",
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
# 仅在传感器无载时声明;video 也可以传相机编号。
|
||||||
|
runtime.declare_unloaded_reference("unloaded-1")
|
||||||
|
with runtime.pipeline(contact=False, include=()) as pipe:
|
||||||
|
while (snapshot := pipe.wait()) is not None:
|
||||||
|
if snapshot.calibration_status.get("fn") == "ok":
|
||||||
|
print(snapshot.normal_force)
|
||||||
|
finally:
|
||||||
|
runtime.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
模型前 30 个有效处理帧用于建立零点;订阅者可能跳过中间快照,不能以收到的快照数判断就绪。
|
||||||
|
运行中换模型必须由调用方在处理线程的帧边界执行,随后重新声明空载窗口;不能与运行中的
|
||||||
|
pipeline 并发调用切换接口。当前独立验证覆盖录像的同步处理和 pipeline 软件链,
|
||||||
|
不等于已验证相机实机精度、吞吐或延迟。
|
||||||
|
|
||||||
## 文件字段
|
## 文件字段
|
||||||
|
|
||||||
`model.type` 为 `field_gain/1`,`input_profile` 为 `hhd_normal_l1_field/1`,`outputs` 仅 `["fn"]`。
|
`model.type` 为 `field_gain/1`,`input_profile` 为 `hhd_normal_l1_field/1`,`outputs` 仅 `["fn"]`。
|
||||||
|
|||||||
@@ -106,6 +106,10 @@ Release. See the launcher help and [build/README.md](../build/README.md) for the
|
|||||||
exact flags. A published version cannot be overwritten, so do not treat a rerun as
|
exact flags. A published version cannot be overwritten, so do not treat a rerun as
|
||||||
a way to replace bad wheels.
|
a way to replace bad wheels.
|
||||||
|
|
||||||
|
GitHub tags default to `v<version>`. Pass `--tag <version>` for a tag without the
|
||||||
|
prefix; both forms must match the certified version. Use `--notes-file <path>`
|
||||||
|
to publish reviewed release notes.
|
||||||
|
|
||||||
The release order is build all candidates, commit source changes, run the clean
|
The release order is build all candidates, commit source changes, run the clean
|
||||||
preflight, preview both publishers, then execute the authorized publications.
|
preflight, preview both publishers, then execute the authorized publications.
|
||||||
GitHub attaches all certified wheels and generates notes naming their actual
|
GitHub attaches all certified wheels and generates notes naming their actual
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ A Python library for processing and analyzing optical tactile sensor data,
|
|||||||
including image stitching, optical flow tracking, and deformation decomposition.
|
including image stitching, optical flow tracking, and deformation decomposition.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = "0.5.4"
|
__version__ = "0.6.0"
|
||||||
__author__ = "Orisys"
|
__author__ = "Orisys"
|
||||||
|
|
||||||
from . import calibration, capture, configs, finger, signal_processing, util
|
from . import calibration, capture, configs, finger, signal_processing, util
|
||||||
|
|||||||
@@ -338,7 +338,8 @@ def test_publish_dry_run_resumes_when_tag_already_exists(tmp_path, monkeypatch,
|
|||||||
assert "gh release create v1.2.3" in output
|
assert "gh release create v1.2.3" in output
|
||||||
|
|
||||||
|
|
||||||
def test_publish_dry_run_creates_tag_when_absent(tmp_path, monkeypatch, capsys):
|
@pytest.mark.parametrize("tag", [None, "1.2.4"])
|
||||||
|
def test_publish_dry_run_creates_tag_when_absent(tmp_path, monkeypatch, capsys, tag):
|
||||||
sdk, release, wheel = _synthetic_publish_layout(tmp_path, "1.2.4", tag_exists=False)
|
sdk, release, wheel = _synthetic_publish_layout(tmp_path, "1.2.4", tag_exists=False)
|
||||||
monkeypatch.setattr(github, "REPO_ROOT", sdk)
|
monkeypatch.setattr(github, "REPO_ROOT", sdk)
|
||||||
monkeypatch.setattr(github, "MANIFEST_PATH", sdk / "tools" / "downstream_sync_manifest.json")
|
monkeypatch.setattr(github, "MANIFEST_PATH", sdk / "tools" / "downstream_sync_manifest.json")
|
||||||
@@ -346,11 +347,18 @@ def test_publish_dry_run_creates_tag_when_absent(tmp_path, monkeypatch, capsys):
|
|||||||
monkeypatch.setattr(github, "_release_exists", lambda repo, tag: False)
|
monkeypatch.setattr(github, "_release_exists", lambda repo, tag: False)
|
||||||
|
|
||||||
exit_code = github.publish(
|
exit_code = github.publish(
|
||||||
github.Options(version="1.2.4", apply=False, skip_fetch=True)
|
github.Options(version="1.2.4", apply=False, skip_fetch=True, tag=tag)
|
||||||
)
|
)
|
||||||
output = capsys.readouterr().out
|
output = capsys.readouterr().out
|
||||||
assert exit_code == 0
|
assert exit_code == 0
|
||||||
assert "git tag v1.2.4" in output
|
expected_tag = tag or "v1.2.4"
|
||||||
|
assert f"git tag {expected_tag}" in output
|
||||||
|
assert f"gh release create {expected_tag} --verify-tag --title {expected_tag}" in output
|
||||||
|
|
||||||
|
|
||||||
|
def test_publish_rejects_tag_for_another_version(capsys):
|
||||||
|
assert github.publish(github.Options(version="1.2.4", tag="1.2.5")) == 1
|
||||||
|
assert "tag must be" in capsys.readouterr().out
|
||||||
|
|
||||||
|
|
||||||
def test_publish_refuses_when_release_already_exists(tmp_path, monkeypatch, capsys):
|
def test_publish_refuses_when_release_already_exists(tmp_path, monkeypatch, capsys):
|
||||||
|
|||||||
Reference in New Issue
Block a user