真机落地实测修的三处:参数类型不一致导致节点启动即崩、权重目录判据、相机日志

1) site.yaml 的整数把节点写死(ros_node.TolerantNode)
   现场 site.yaml 写 `ae_limit_us: 8000`(YAML 整数),脚本按 `-p ae_limit_us:=8000`
   传参,而节点 declare 的是 double —— rclpy 严格比对类型,节点**启动即崩**:

     InvalidParameterTypeException: Trying to set parameter 'ae_limit_us'
     to '8000' of type 'INTEGER', expecting type 'DOUBLE'

   现场看到的只是「顶置 D435 起不来」,报错里一个字都没提 site.yaml,而
   `8000` 与 `8000.0` 在运维眼里是同一个数。同一族的雷还有 width 848.0→int、
   emitter_enabled 1→bool、带不带引号的序列号。
   修法是新增应用层统一基类 TolerantNode:在**声明阶段**把覆盖值的类型按
   声明类型收敛(异常就发生在声明阶段,所以 `float(...)` 这种事后 cast 救不了)。
   全部应用节点改继承它;补 test_ros_node.py。

2) 权重目录判据(weights_layout)
   模型文件「在不在、名字对不对」以前散在几处各判一半,缺文件时的现象是
   推理静默退回随机权重。收成 weights_layout.py 一条判据 + scripts/weights.py 调用。

3) 相机日志:USB 降速要说清怎么办
   realsense_color_pub 协商到 USB 2.1 / 480Mbps 时只打一行速率,没人知道该做什么;
   现在直接给可执行的处置(换线/换口/SuperSpeed 不复用)。realsense_view 同步。

4) stage2_locate:接上 hover_z_guard 与 tool_tip_below_flange_m
   悬停高度必须让工具尖端留在工件面上方(09-24 的教训:悬停时尖端已钻进工件
   25mm,S05 横向对准把工件拖走 92mm)。step2 侧也按同一判据兜住,且工具长
   允许由启动参数覆盖(仿真上料后实测得到)。

5) config/site.example.yaml 与 site.yaml 重新同步
   上一批给夹爪加了 auto_init: false,模板没跟着重跑,TestExampleParity 因此失败。
   重跑 scripts/gen_site_example.py 同步(模板是生成物,不手改)。

测试:全仓库 1085 passed(此前 1 failed)。
This commit is contained in:
arm_dev
2026-09-28 10:17:16 +08:00
parent c1cd862eea
commit 0a2a28a355
22 changed files with 811 additions and 94 deletions
+6 -2
View File
@@ -76,6 +76,7 @@ from arm_application.weights_layout import ( # noqa: E402
discover,
find_model,
groups,
infer_group,
model_labels,
plan_conversion,
staging_dir,
@@ -479,11 +480,14 @@ def cmd_convert(args) -> int:
_err(bad)
return 2
group = args.group
group = args.group or infer_group(root, src)
chain, _outs = plan_conversion(root, src, name=name, group=group, target=args.to)
print(f"输入: {src}")
print(f"输出: {root / group}/{name}.<ext>")
if args.group is None:
print(f" (没给 --group:沿用输入文件所在分组 {group}/;"
f"engine 必须和 site.yaml 指的 .onnx **同级**,分家等于没转)")
print(f"计划: {chain.describe()}")
print(f"尺寸: imgsz={_imgsz(args)}")
if args.to != "all":
@@ -806,7 +810,7 @@ def build_parser() -> argparse.ArgumentParser:
s = sub.add_parser("convert", help="转换权重并归位")
s.add_argument("input", help="输入文件(可以是 staging/ 里的相对名)")
s.add_argument("--name", help="输出模型名(默认沿用输入文件名主干)")
s.add_argument("--group", default="yolo", help="输出分组子目录(默认 yolo)")
s.add_argument("--group", help="输出分组子目录(默认沿用输入文件所在分组;staging/外来文件默认 yolo)")
s.add_argument("--to", default="all", choices=["all", "onnx", "engine"], help="产出目标")
s.add_argument("--imgsz", type=int, help="输入尺寸(默认取 site.yaml 的 yolo.imgsz)")
s.add_argument("--labels", help='顺带写标签,如 "工件,通止规"')