refactor(layout): src/ 收成顶层包 arm/,入口统一 python -m;提升承担构建的 scratch 脚本
单文件约束取消后,Python 侧没必要再靠 16 处 sys.path.insert 维持扁平模块互认。
现在按职责分包:
arm/paths.py 路径唯一来源(含新增 CACHE、TPL)
arm/constants.py 实测接口数值(原 armcore 的 M/C/CLR/FIT/MOTOR_TOL 段)
arm/cad/{helpers,arm_build,part_tools,parts/} 几何与装配
arm/kinematics.py(原 human_layout.py,唯一运动学事实源)
arm/analysis/{sweep_v2,strength_check,torque_balance,finalize_travel,ws_sweep,gen_env_mesh}
arm/dataio/{screw_mesh,draw_sheet} arm/viewer/{build_viewer,shot}
arm/build_model.py(原 arm_model.py)
顺带修掉的既有缺陷(都是实测撞出来的,不是预防性改动):
- arm_model 第二次 sys.path 跳到 gitignore 的 scratch/ 去 import 构建必需的包络脚本:
ws_sweep/gen_env_mesh 提升进 arm/analysis/,缓存挪到 data/cache/(gitignore,可重生成)。
- finalize_travel / draw_sheet 顶层就是"算完写文件",一次 importlib 冒烟测试就把
docs/travel.json 重写了一遍;现在被 import 直接抛错。
- strength_check 用 OUT.replace("/out","/web") 靠字符串形状推路径,改成直接用 WEB。
- build_viewer 里 WORKSPACE 使用点漏改导致 NameError —— 已由构建关卡抓到并修掉。
os._exit 的处置与计划里的假设相反:实测光是 `python -c "import arm.cad.helpers"`
就会在解释器退出时段错误(exit 139,OCC 静态析构),全流程跑完也一样。所以入口
脚本尾部保留 flush + os._exit,并把原因写进注释;被 import 时不生效。
关卡(tests/):
- verify.py 一条命令跑三层:产物 md5、IK 数值 exact 段、截图。
- 截图基线重做并分级:同一构建连跑两轮实测 102 张逐字节可复现(要求 md5 相同),
3 张线束 x-ray 不可复现(mean<=0.0017、无像素差>8)改为与参考像素比容差;
这 3 张不再入库,免得每次跑关卡都脏 git。
- 新增 ?view=sheet / ?sheet=N / ?theme / ?guide=N 四个 URL 参数:工程图与装配向导
占了约一半 CSS 和 700 行 JS,原先没有任何截图覆盖,拆它们等于没有关卡。
- 关卡灵敏度已验:改坏 IK 基线一个数 -> FAIL;换旧版求解器 -> 5 处 exact 差异。
实测:python -m arm.build_model 退出码 0,全部产物 md5 与基线一致,
105 视图截图全过,IK exact 段逐字节一致。
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""P09 工具法兰:末端法兰盘与 J6 直锁 hub。"""
|
||||
import math
|
||||
from arm.cad.helpers import cyl
|
||||
from arm.cad.arm_build import D2R
|
||||
from arm.kinematics import PLATE_T, X_ARM, Y_AXIS, Z_HUB6
|
||||
from arm.cad.part_tools import CHAMFER_EDGE, CLAMP_BACKOFF, FILLET_SMALL, FILLET_TINY, make_direct_hub
|
||||
|
||||
def p_tool_flange(j6):
|
||||
"""P09_工具法兰_螺旋体30%_墙4底5_竖打 深度圆角优化版
|
||||
关键改进:
|
||||
1. 外轮廓全圆角(R=4mm)
|
||||
2. 法兰面倒角(2mm)
|
||||
3. 螺孔边缘倒角(1.5mm)
|
||||
"""
|
||||
z_bot = Z_HUB6 - PLATE_T - 9.0
|
||||
s = cyl(35.0, z_bot, Z_HUB6, X_ARM, Y_AXIS)
|
||||
P09_M4 = []
|
||||
|
||||
# 4x M4螺栓孔
|
||||
#
|
||||
# 分布圆半径 20 -> 22(BCD 40 -> 44):R20 与 3xS01 输出螺钉的 Ø5.6 螺丝刀通道
|
||||
# (make_direct_hub 里 cyl(2.8, 58.0, z_out+40) 在 BCD29=R14.5、相位 351.4/232.3/112.1°)
|
||||
# 咬穿沉孔。0° 那个孔中心 (39.5,128) 到 351.4° 通道中心 (33.84,125.83) 只有 6.06mm,
|
||||
# 而两孔半径之和是 3.5+2.8=6.30 —— 差 0.24mm,Ø7.0 沉孔壁被啃掉一块,
|
||||
# 完整圆柱面(88mm²)裂成 45.7+35.4 两片,即用户截图里的月牙孔。
|
||||
# 该相位差只有 8.6°,转动 M4 孔相位无法躲开(0/90/180/270 与 45 度错开全部仍 <6.30),
|
||||
# 只能加大分布圆半径:R22 时最小中心距 7.96mm,余量 1.66mm。
|
||||
# 边壁仍充足:R35 法兰外径 - (R22 + 沉孔 3.5) = 9.5mm。
|
||||
for a in (0, 90, 180, 270):
|
||||
rad = 22.0
|
||||
u = rad * math.cos(a * D2R)
|
||||
v = rad * math.sin(a * D2R)
|
||||
# 实际切割推迟到 make_direct_hub 之后(见下)。这里只算出 4 个孔位。
|
||||
P09_M4.append((X_ARM + u, Y_AXIS + v))
|
||||
|
||||
# 定位止口 + 走线孔
|
||||
pilot = cyl(10.0, z_bot - 1.0, z_bot + 2.5, X_ARM, Y_AXIS)
|
||||
thru = cyl(5.0, z_bot - 1.0, Z_HUB6 + 1.0, X_ARM, Y_AXIS)
|
||||
s = s.cut(pilot).cut(thru)
|
||||
|
||||
# 直连法兰
|
||||
# 【2026-10-03】M6 补上前端压盖后,J6 毂面必须让位 CLAMP_BACKOFF=5.5
|
||||
# (详见 make_direct_hub 的 backoff)。P09 的法兰本体 z_bot/Z_HUB6 一个字没动,
|
||||
# 让位的只是伸进 J6 腔里的那圈毂面 —— 圆盘下移后仍与法兰本体在局部 65..79.5
|
||||
# 大面积交叠,熔接不受影响;工具端点 Z_TIP=93 也随之不变。
|
||||
s = make_direct_hub(s, j6, r_disc=35.0, z_out=74.0, backoff=CLAMP_BACKOFF)
|
||||
|
||||
# 4x M4 孔(必须在 make_direct_hub 之后切)
|
||||
#
|
||||
# 直连法兰那步 fuse 了 R35 圆盘(局部 z=56.5..74 -> 全局 z=102..121 一侧),
|
||||
# 会把先切的孔重新填死:分段求交显示 z=97..102 无干涉、z=102 以上整根杆都埋在料里
|
||||
# (每段 12.57 mm^3 = pi*2^2*1,全截面被埋)。
|
||||
#
|
||||
# 孔径与深度同时修正:旧值 Ø3.7 比 M4 杆 Ø4.0 还细,且只到 z=105,
|
||||
# 而 M4x16 头面在 z=97、杆要走到 z=113 —— 杆尾 8mm 无处可去(干涉 147.3 mm^3)。
|
||||
# Ø4.4 是 M4 标准间隙孔(ISO 273 medium ≈ Ø4.3)。
|
||||
# 孔顶要盖过 M4x16 的杆尾:头面 z=97 + 杆长 16 = z=113,故开到 Z_HUB6+4=115,
|
||||
# 比杆尾多留 2mm(实测开到 112 时最后 1mm 杆尾仍撞料 37.7mm³)。
|
||||
for (fx, fy) in P09_M4:
|
||||
s = s.cut(cyl(2.2, z_bot - 1.0, Z_HUB6 + 4.0, fx, fy))
|
||||
s = s.cut(cyl(3.5, z_bot - 1.0, z_bot + 4.0, fx, fy))
|
||||
|
||||
# ========== 关键圆角优化 ==========
|
||||
try:
|
||||
# 外轮廓圆角
|
||||
s = s.edges("|Z").fillet(FILLET_SMALL)
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
# 法兰面倒角
|
||||
s = s.edges("<Z").chamfer(CHAMFER_EDGE)
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
# 顶部边缘圆角
|
||||
s = s.edges(">Z").fillet(FILLET_TINY)
|
||||
except:
|
||||
pass
|
||||
|
||||
return s
|
||||
|
||||
|
||||
JOINT = 'J6'
|
||||
|
||||
|
||||
def specs(JS):
|
||||
"""本件的 (件号, 中文名, 构建 thunk, 配色, 说明) 清单;顺序即 BOM 顺序。"""
|
||||
j6 = JS["J6"]
|
||||
return [
|
||||
("P09_工具法兰_螺旋体30%_墙4底5_竖打", "末端工具法兰", lambda: p_tool_flange(j6), 0xdc2626,
|
||||
"V2圆角:外轮廓R=3mm,法兰面倒角2mm;【2026-10-02】打印填充由100%降到30%:该截面安全系数288是全机裕度最大的件,满填充纯属浪费(件号同步改为P09_工具法兰_螺旋体30%)"),
|
||||
]
|
||||
Reference in New Issue
Block a user