把当前控制栈收成一份可克隆的源码:腕部看不见时用顶视一次定到基座,二阶段对孔和手外标定跟着进同一份树。

现场 site.yaml、权重和编译产物仍不入库;模板只留占位符。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
arm_dev
2026-10-09 14:51:03 +08:00
parent 16d2912a9a
commit 7d22f777c8
67 changed files with 8597 additions and 409 deletions
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env python3
"""确定性复现「工件被推走 ⇒ 规没进孔」:在 k1 之后把工件挪 25mm。
为什么需要它:这个故障在自然运行里是**随机**的(实测三跑坏一跑),
靠碰运气验证判据不可靠。这里改成主动制造:等流程走到 S10(离开 k1、去 k2),
就把工件沿 +Y 推 25mm —— 而 k2 的孔位是 S05 一次性定下的,于是必然失配。
判据(要看的就是这个):S07 必须报「规没有进孔」(HOLE_LOST),
**不是** 之前那句把人引去查工具系的「转轴偏差」。
"""
from __future__ import annotations
import pathlib
import subprocess
import sys
import time
ROOT = pathlib.Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "src" / "arm_sim_gazebo"))
LOG = pathlib.Path("/tmp/sim_guard.log")
WORLD = "assembly"
SHIFT_M = -0.020 # 与 2026-09-28 自然失效同向同量级(工件 y: 0.000 → -0.0206)
def _shift() -> None:
from arm_sim_gazebo.sim_pose_service import set_model_pose
# 工件当前在 (0.520, 0.000, 0.400),沿 +Y 挪 25mm(远超孔半径,必然错过)
ok, out = set_model_pose(WORLD, "workpiece", (0.520, SHIFT_M, 0.400), (0.0, 0.0, 0.0, 1.0))
print(f"[driver] 推工件 {SHIFT_M * 1000:.0f}mm -> {'成功' if ok else '失败'}: {out[:160]}")
def main() -> int:
LOG.write_text("")
proc = subprocess.Popen(
["bash", "scripts/run_gauge_assembly.sh", "--arm", "sim", "--sim"],
cwd=str(ROOT), stdout=LOG.open("w"), stderr=subprocess.STDOUT,
)
print(f"[driver] 流程已起 pid={proc.pid},等它走到 S10…")
shifted = False
t0 = time.monotonic()
while proc.poll() is None and time.monotonic() - t0 < 1500:
txt = LOG.read_text(errors="replace")
if not shifted and "S10_to_k2" in txt:
print("[driver] 检测到 S10_to_k2 —— 现在推工件")
_shift()
shifted = True
time.sleep(1.0)
proc.wait(timeout=30)
txt = LOG.read_text(errors="replace")
print(f"[driver] 流程退出码 = {proc.returncode}, 是否推过工件 = {shifted}")
for line in txt.splitlines():
if "规没有进孔" in line or "孔位失效" in line or "转轴偏差" in line:
print(" |", line.strip()[:150])
return 0
if __name__ == "__main__":
raise SystemExit(main())