feat: 增加组合折叠姿态干涉扫描、力矩实测与结构强度复核数据

This commit is contained in:
cbb
2026-10-02 12:06:23 +08:00
parent 6fe97fc643
commit b593e47c76
21 changed files with 1587 additions and 1030 deletions
+23 -8
View File
@@ -23,8 +23,13 @@
- 预剪枝:按关节轴计算每对零件的轴向/径向区间,区间不相交的零件对在该关节的
任何角度都不可能碰撞,直接跳过(对单关节扫描是精确安全的)。
台架(P01 立柱 / P02 底盘)代表躯干与机身的连接界面,默认【参与】碰撞计算——臂撞立柱
就是臂撞躯干,是真约束。--no-stand 仅用于诊断:排除台架后重扫,给出"不含躯干约束"的
自由空间行程,用来分辨某个限位是臂自身折叠产生的还是躯干挡的(台架位置本身是假设,
改它等于改测试工装,不等于改设计)。
运行:python src/sweep_v2.py [--workers 20] [--step 2] [--combo-step 6]
[--no-combos] [--joints J2,J4] [--no-gjk]
[--no-combos] [--joints J2,J4] [--no-gjk] [--no-stand]
"""
import json
import math
@@ -44,6 +49,7 @@ import multiprocessing as mp
import arm_build as AB
import cadquery as cq
import human_layout as HL
from armcore import place, bb, DOCS
VOL_MIN = 2.0 # mm3,超过即计为干涉
@@ -61,6 +67,7 @@ MOUNT_PAIRS = {
MESH_TOL = 0.5 # mm,零件网格化容差
MESH_MARGIN = 0.8 # mm,凸包安全外扩(> MESH_TOL 保证网格内缩不致漏判)
USE_GJK = True # 进程内全局;工作进程由 initializer 传入
INCLUDE_FIXTURE = True # True=把 P01 立柱/P02 底盘(代表躯干)算进碰撞;--no-stand 置 False
# ---------------------------------------------------------------- 网格化 + GJK
@@ -165,11 +172,15 @@ def _do_simplex(s):
# ---------------------------------------------------------------- 模型与上下文
def load_model():
def load_model(include_fixture=True):
"""include_fixture=False 时把 P01 立柱 / P02 底盘(固定测试台架,非本体)排除在
碰撞配对之外——用来得到真机工作空间而不是台架工作空间。见 human_layout.FIXTURE_PREFIX。"""
import arm_model as AM
JS = AM.build()
parts = []
for p in AB.PARTS:
if not include_fixture and HL.is_fixture(p["name"]):
continue
g = CHAIN.index(AB.GRP.get(p["name"], "root"))
lo, hi = bb(p["shape"])
corners = [(x, y, z) for x in (lo[0], hi[0]) for y in (lo[1], hi[1]) for z in (lo[2], hi[2])]
@@ -212,8 +223,8 @@ def axis_intervals(parts, rear, d):
return out
def make_ctx():
parts, joints = load_model()
def make_ctx(include_fixture=True):
parts, joints = load_model(include_fixture)
impossible = {}
for k in range(1, len(CHAIN)):
rear, d = joints[CHAIN[k]]
@@ -395,10 +406,10 @@ _POOL = None
_WORKERS = 4
def _init_worker(use_gjk=True):
def _init_worker(use_gjk=True, include_fixture=True):
global _CTX, USE_GJK
USE_GJK = bool(use_gjk)
_CTX = make_ctx()
_CTX = make_ctx(include_fixture)
def _task(task):
@@ -410,7 +421,7 @@ def get_pool(workers):
global _POOL, _WORKERS
_WORKERS = workers
if _POOL is None and workers > 1:
_POOL = mp.Pool(workers, initializer=_init_worker, initargs=(USE_GJK,))
_POOL = mp.Pool(workers, initializer=_init_worker, initargs=(USE_GJK, INCLUDE_FIXTURE))
return _POOL
@@ -448,7 +459,7 @@ def eval_angles(angles_list, workers, chunk=None, label="姿态"):
def _ctx_single():
global _CTX
if _CTX is None:
_CTX = make_ctx()
_CTX = make_ctx(INCLUDE_FIXTURE)
return _CTX
@@ -555,6 +566,9 @@ def main():
if "--no-gjk" in sys.argv:
global USE_GJK
USE_GJK = False
if "--no-stand" in sys.argv:
global INCLUDE_FIXTURE
INCLUDE_FIXTURE = False
# 内存感知的默认进程数:每个工作进程预留 ~2.5GB 峰值(建模+布尔瞬时开销)
avail_gb = 16.0
try:
@@ -691,6 +705,7 @@ def main():
open(DOCS + "/travel.json", "w", encoding="utf-8"), ensure_ascii=False, indent=1)
detail = dict(generated=time.strftime("%Y-%m-%d %H:%M:%S"),
vol_min=VOL_MIN, step=step, combo_step=combo_step, workers=workers,
fixture_included=INCLUDE_FIXTURE,
singles={t: dict(lo=round(singles[t]["lo"], 2), hi=round(singles[t]["hi"], 2),
jams={str(a): v for a, v in singles[t]["jams"].items()})
for t in singles},