Files
Robot_Arm/.workbuddy/memory/2026-10-03.md
T

26 KiB
Raw Blame History

2026-10-03 工作日志

P06 大臂骨架减重窗取消(视觉整改)

问题:用户实机视点反馈,J4 关节正上方 P06 大臂骨架(青绿色)顶部的"帐篷形减重窗" 正面看是一个贯通的矩形黑洞,位于整机最显眼的落脚点,非常不雅观。 该窗是 2026-10-02 减重改造时开的(XZ 轮廓 X337 沿 Y 切穿,Z362374)。

处理:在 src/arm_model.py 加开关 P06_HOLLOW_WIN = False,p_upper_bone() 5c 处 改为条件 cut,该段恢复实心。保留 P06_WIN_XZ 轮廓与全部设计注释,改开关即可复原。

结果:

  • P06 体积 161.1 -> 183.3 cm3(与减重前的 183 一致),+22cm3 / 约 +27g PLA
  • 碰撞检测 8 组接触面全部零干涉
  • 强度校核 0 处不合格;z=365 剖面 SF=101.23(该段本就不缺强度,减重收益纯锦上添花)
  • 已同步更新 BOM 说明、src/strength_check.py 剖面名("大臂骨架减重窗 @z=365" -> "大臂骨架过渡块 @z=365",保留为该高度的安全裕度监控点)
  • 重新导出 STEP/STL,重跑 scratch/make_3mf.py 打包 3MF,查看器已刷新

备份:backups/20261003_p06_fill/arm_model.py.bak

结论/偏好:减重窗不是越多越好。P04 立柱槽与 P07 顶板槽是朝上敞开的(不破坏外观) 故保留;P06 这个沿 Y 贯通、直接开在外观面上的窗属于"减重减出负面观感",已回退。 以后开减重腔要先问一句:会不会在外露面上形成可见的洞。

J3(M3) 电机前端压盖 —— 补齐 roll 关节的"电机两端固定"

定位:用户截图里红圈标的电机裸露端 = J3 大臂自转电机 M3 的前端盖。 红圈周围两个零件:P05 大臂旋转座(绿 0x059669,抱紧 M3 的holder)与 P06 大臂骨架(青 0x0d9488,被 M3 驱动的 driven)。M3 前端盖外端面在 Z=389, 原来只有 P05 后端板 4xM3x10(S02)单面锁死 —— 与 2026-10-02 已做完的 J2/J4/J5(M2/M4/M5)三处相比是唯一还缺前端夹紧的 pitch/roll 关节。

统一配方(复用,不重复实现):arm_model.motor_front_clamp 改成轴向无关 — axis="Y"(J2/J4/J5 旧路径,几何逐位不变)/ axis="Z"(J3 roll,轴向 -Z)。 新增 CLAMP_CLOCK_LOCAL(= 72.2°+90k 的关节局部相位):trs() 里 y = z×x, 两个轴向换算到全局都是"全局相位 = −局部相位",所以 Y 轴仍是原来的 17.8°+90k, Z 轴同一组数落在全局 (x,y) 平面 —— 全机 BCD55 孔位约定不变,改一处必须同步另一处。

代价(关键):J3 的从动件 P06 毂面原本在 Z=388.5,与 M3 前端盖只差 0.5mm, 放不下 5mm 压盖。按 Y 轴三处的老办法让位:z_top 388.5→383.0、直锁凸台 59.5→65.0(+CLAMP_BACKOFF=5.5 = 压盖 5.0 + 动间隙 1.0 − 原基准 0.5)。 凸台同步加长后 3xS01 的头面台阶(s=58)/杆长/咬合量与 J3 直锁关系一律不变。 P05 侧 roll_clamp=True 开关在 make_pitch_to_roll_bracket(P05/P08 共用), P08 传 False —— J6/M6 的前端压盖还没做,要从动件 P09 工具法兰让位(改直锁凸台)。

结果:13/13 单实体 ✓;P05 155.0 cm³(Z 384..525)、P06 166.5 cm³; 碰撞 8 组全零干涉(P05×P06 = 0.00 mm³);4xM3x8 与压盖零干涉(各自 0.00 mm³); 螺钉 S12 12→16 颗(docs/screws.json + screw_mesh.py 同步,实例数自洽断言通过); 3MF 重打包(P05 切片高 136→141mm)。改前改后对比图 docs/shots/cmp_j3_before_after.png。

教训:J3/J6 这类 roll 关节的"电机前端盖外侧"就是从动件的毂面, 加压盖前必须先量从动件到前端盖的轴向净空(Y 轴是 1.0mm,Z 轴只有 0.5mm)。

电机轴向厚度公差 2mm —— 全机 5 个夹紧关节的承压面让空

用户提问:"类似这种安装电机的地方是否考虑了 2mm 的电机厚度公差"。

审计结论:完全没考虑,而且比"没留量"更糟 —— +2mm 的电机根本装不进去。 轴向链是「后端板 4×M3x10 顶住电机尾端面 + 前端 R35 压盖 4×M3x8 压住前端盖」两个刚性面。 螺钉头一旦坐在沉孔台阶上就不能再进给(螺钉只能进不能退),所以两端都是硬约束,长度必须 对上。实测窗口:承压面在 s=-0.6 时,电机只能 L ≤ 56.6(长边 +0.6mm);L=58 时前端盖越位 1.4mm 直接撞压盖本体。

关键设计判断:公差不能靠"拧紧"消化,只能靠垫片位。 曾评估过三条路:

  • 加长压盖/让关节长 2mm → 从动毂面让位要再动 5 个零件的轮毂间距,且关节轴向全链 +2mm;
  • 一端改径向夹紧 → 要重做后端接口;
  • 后端承压面让空成垫片位(选中) —— 几何只改一处数,关节长度不变,全机统一。

实现(单一事实源):

  • armcore.MOTOR_TOL = 2.0(现场口径),arm_build.REAR_SEAT = 0.6 + MOTOR_TOL = 2.6;
  • Joint.pocket() 的 PCB 腔底(电机尾端面承压面)从 -0.6 让到 -2.6 → 覆盖 J3/J4/J5/J6;
  • P04 走自带刀具 c_m2(没调 Joint.pocket),同步改成 -AB.REAR_SEAT → 覆盖 J2;
  • roll 关节 rear_mount_holes(t_plate) 7.0→8.0:让空 2mm 后承压面到螺钉沉孔台阶只剩 t_plate - cb_depth - REAR_SEAT,给到 8 才保住 1.4mm 膜厚(给 7 会退化成 0.4mm); 连带 z_plate = z_r + 7 → z_r + 8(P05 杯顶 452→453,J2 让位圆柱底在 454.5,仍有余量)。
  • 装配配方写进 README 与 docs/screws.json S02:T = 58.6 − L,量程 0~2.6mm,M3 平垫组合。

验证:scratch/motor_tol_window.py(窗口换算,改前 +0.6 → 改后 +2.6); scratch/motor_tol_check.py(真实电机包络 R30/R30.15 布尔)5 个夹紧关节 × ΔL∈{-2,0,+2} 全部 0.0mm³ 干涉且前端盖面压间隙 0.0;13/13 单实体;碰撞 8 组全零;3MF 重打包。

教训(比结论更重要):两个刚性夹持面 = 固定长度,零公差。想吃公差必须有一个面变成 "可垫可让"的软面,否则再大的公差也换不来行程 —— 这条同样适用于以后任何"双面夹紧"改法。 另:J1/M1 天然免疫(P03 是 Ø60.7 直通长孔,比电机长 3mm),所以公差只需要改 J2~J6。

承压面让位 2mm 的"残留凸台"—— 排查结论:消不掉,是承压面下沉的必然结果

用户反馈:P05/P06/P07/P08 后端都有凸台,是之前给电机预留 2mm 时"削掉了一些" 造成的;认为应该"通过减薄面"而不是"掏掉",没掏干净所以残留了凸台。

实测确认现象(scratch 里用双 Common 相减法量,band z=-2.6..0 内、64.4 方柱之外): P05 759 / P06 1089 / P07 3139 / P08 721 mm3。成因确认无误:REAR_SEAT 从 0.6 抬到 2.6 时只把 64.4 方形腔加深(纯掏腔),腔壁以外 z=-2.6..0 的 R35 料没动, 相对新承压面(-2.6)凸起 2.6mm。

两条消除路线都实测失败(重要,别再重复试):

  • A. 整段全截面切 z=-2.6..0 -> P05/P08 碎成 2~3 块。这圈 R35 料连同承压环 是"电机尾端安装板"与"臂身"之间唯一的轴向连接,切掉就断。
  • B. 沿腔口做让位斜面(方形放样 taper_rect 与圆锥 taper_round 都试了) -> 余料只降约 20%,且 P05/P08 仍碎 2 块。因为这圈料在 z>0 是杯体本体 (继续往上长),斜面一刀切下去等于削臂身。

结论:这不是"没掏干净"。承压面下沉 2mm 与"腔壁保持原 0.6mm 直壁"在几何上 互斥 —— 台阶是下沉的必然产物。它不顶到电机(电机尾端面在腔内、四周已让空), 只是外观上的一道台阶。要彻底消掉必须改承压面方案本身(承压环整体下沉 / R35 座 改短),那属于关节轴向长度调整,不在"预留 2mm 公差"这件事的范围内。

本次改动:Joint.pocket 与 P04 c_m2 的几何未动(体积与改前逐件一致, 13/13 单实体),只把上述实测结论写进 Joint.pocket 的 docstring 与 arm_build.py 常量区注释;armcore.py 新增 REAR_LAND / R35_SEAT 两个具名 常量把"0.6 原台肩"和"R35 外壁"显式化,避免以后再靠注释里的裸数字。

教训(方法论,比结论更重要):

  1. 这次我在错误的坐标系上浪费了大量时间 —— map_pt(jp.t, ...) 必须用 被抱电机所属关节的变换(P06 用 J4,不是驱动它的 J3),用错关节算出来的 footprint 全是错的 U 形,还误导我把余料误判成"Loft 方棱"。
  2. 布尔测量不要用 BRepAlgoAPI_Common(shape, slab.cut(sq)) 这种嵌套 cut —— 结果不可靠(我因此得到过 bbox 跨 86mm 的荒谬值)。用两个独立 Common 相减: vol(∩slab) - vol(∩sq)。
  3. 结论前先确认工具本身对不对:中途 HALF, SEAT = AB.PCB_W/2.0, AB.REAR_SEAT 之后又被覆盖,导致打印出 SEAT=32.2 这种自相矛盾的值,我却继续解读了好几轮。

承压面悬空凸台 —— 已彻底解决(用户第二次指出,我第一次判断错了)

用户纠正(重要):上一轮我结论是"凸台消不掉,是承压面下沉的必然产物",错了。 用户明确指出:① 不是去掉整个地方,只消掉一部分凸台;② 凸台本身不起任何作用; ③ 正确做法是把上面的厚度改成下面的厚度,或用更大半径的电机做布尔把面弄平; ④ 现状不好 3D 打印(需更多支撑、公差打不好)。

真正的根因(这次用正确坐标系统一量就清楚了): Joint.pocket 原来用 64.4 方腔从 -0.6 加深到 -2.6 掏出垫片位。64.4 方腔的 内切圆半径恰好 = 32.2,所以方腔在 45° 方向已吃穿到 r=45.5,R35 壁只剩 四条边中点附近的料 —— 定量实测 r=34 处材料沿 z 的区间(承压面 -2.6):

  • 0°/180°/260°/280°:-8.0..12.0(贯通,属臂身本体 = 承力桥)
  • 80°/100°:-8.0..-0.0(只比承压面多 2.6mm,这段就是凸台)
  • 其余 20~160°:-8.0..-2.6(承压环本体,齐平)

我上一轮失败的原因:一直以为"整圈 R35 料是承压板与臂身之间唯一连接", 所以任何整段切都试过。实际上 0/90 方向那条桥在 z>0 是臂身本体(r=34 贯通到 z=12), 不是承压环的一部分。是我没量清楚才下了错误结论。

修法(一刀,不做角度分区):承压面所在的 z=-REAR_SEAT..+SEAT_TOP 段, 腔口从 64.4 方改成 R35 圆(新增常量 arm_build.SEAT_R=35.0 / SEAT_TOP=1.0); z=0 以上的 PCBA 腔仍保持 64.4 方(PCB 是方的必须方腔)。整圈一次挖到承压面高度, 凸台零残留。P04 走自己的 c_m2 圆柱刀具,同步加 cyl(AB.SEAT_R, -AB.REAR_SEAT, AB.SEAT_TOP)。 SEAT_TOP=1.0 顺带清掉 roll 关节半包薄壁(R32.2..35 的 0.05cm3 残片)。

连带好处:承压环从"方腔内切 32.2 − 沉孔外缘 30.25 = 1.95mm 窄环" 变成"完整 R35 圆环 4.75mm",受压面积 383 → 974 mm²(2.5 倍)。

验证:13/13 单实体 ✓;静态干涉 8 组全零 ✓;motor_tol_check.py 5 关节 × ±2mm 共 15 组全部 0.0mm³ 且面压间隙 0.0 ✓(±2mm 公差未受影响); 4xS02 沉孔残余 0.0(未被 R35 圆腔侵占)✓。

方法论教训(比结论重要):

  1. 上一轮我因为在错误坐标系里反复兜圈(map_pt 用了驱动关节而非电机所属关节), 得出了"消不掉"的错误结论。遇到"改不动"的几何,先确认坐标系对不对, 再考虑方案 —— 坐标系错了会把可解的问题判成无解。
  2. 区分"桥"和"悬空料"要靠轴向区间实测(固定半径 r=34 扫 z), 而不是靠体积或目测。体积法(P05 759 / P07 3139 mm3)会让人误以为整圈都是残留。
  3. solids_of 会把 <0.01cm3 的布尔退化薄片也算成独立实体,判单实体时要设阈值, 否则会误报"碎块"。

修复:R35 圆腔切断连接壁 —— 肩叉顶部"没连上"(我 10-04 的改法有错)

用户反馈:最上面的蓝色肩叉(P04)顶部有一道缝,没连接上,要求连上。

根因(几何实测):上一轮为了消"悬空凸台",我把承压面段(z=-2.6..0)的让位腔 从 64.4 方腔改成 R35 圆腔(arm_build.SEAT_R=35.0, SEAT_TOP=1.0)。这是错的 —— R35 恰好等于后端板外壁半径,等于把 r=32.2..35 那圈 2.8mm 厚的连接壁整圈挖穿。 实测(scratch/_rad.py 逐方位径向扫描,P04 电机局部系):

z 0°/45°/90°/135°/180° 225° 270°
-3.0(承压面下) 28.0-35.0 有料 有料 有料
-2.4 .. +0.8 全空 35.0-35.5(0.5mm 薄片) 35.0-56.0

即:后端法兰(R35 圆盘,z=-8..-2.6)与杯壁(z>=+1.0)之间被切出一条 3.6mm 宽、 360° 全通的环槽,只剩 240~320° 方位靠臂身本体相连,225° 还留了一片 0.5mm 厚的 孤立薄片 —— 打印出来就是你截图里那道缝。单实体校验查不出来(13/13 仍通过, 因为臂身本体兜住了),只有逐方位测轴向材料区间才看得见。

修法(一处数值):SEAT_R: 35.0 -> PCB_W/2.0 = 32.2、SEAT_TOP: 1.0 -> 0.0。 32.2 = 64.4 方腔的内切圆半径,正好只挖掉悬空凸台、保留 r=32.2..35 整圈连接壁, 且在0/90/180/270 方向与上方方腔壁齐平、45° 方向比方腔多留料把四角补实。 同步改 P04 的 c_m2(走自己的圆柱刀具)+ 5 处 BOM 说明 + screws.json S02 备注。

验证:

  • 改前/改后对照(scratch 布尔复现两版):改前连接壁 36/36 方位全断, 改后 360° 整圈连续
  • 5/5 件(P04~P08)连接壁整圈连续、单实体、4xS02 沉孔残余 0.00mm³
  • 13/13 单实体 ✓;静态干涉 8 组全零 ✓
  • motor_tol_check.py 5 关节 × ±2mm 共 15 组全部 0.0mm³、面压间隙 0.0 ✓(公差未受影响)
  • 体积回归:P04 280.1 -> 282.1 cm³(补回了被误挖的料)

教训(补上一轮的方法论空白):

  1. 单实体 + 零干涉不代表结构对。这次13/13 全过、8 组零干涉,但零件内部被切出一条 360° 通槽 —— 因为臂身本体在另一侧兜住了连接。"是否连通"必须单独验证: 固定半径(如 r=33.6)逐方位扫 z,找材料轴向区间是否连续。
  2. "把面弄平"不等于"把料全挖到外壁"。用户说"用更大半径的电机做布尔把面弄平", 正确解读是"挖到能让表面齐平的那个半径",即方腔内切圆 32.2,而不是外壁 R35。 选刀半径前必须先确认哪一圈料是承力连接,不能只看凸台本身。
  3. 改完要回头验上一轮修过的所有件,不能只验当前这件。P05~P08 是共享 pocket() 自动受益,但 P04 走自己的 c_m2,是最容易漏的一处 —— 本次两处都改了。

压盖"拼接痕"视觉整改:四处前端压盖外缘倒 R4(新增 blend_clamp_seam)

用户反馈:给了两张 P04/M2 压盖的截图 —— 第一张红圈里能看到一圈硬棱("圆盘贴在 臂身上"的接缝),第二张是圆润连续的过渡。要求"两面的都变成第二张一样圆润的"。

定位(几何实测,不是目测):

  1. 先怀疑是压盖 R35 圆柱面本身的棱 -> 枚举同心 R35 圆边,发现 Y157 以上压盖外表面 完全暴露(四周 r>35.2 无料),R35 圆柱面上根本没有任何棱边。
  2. 又怀疑压盖圆盘被叉板切出缺口 -> 扫 Y=161.0 截面每个方位的 Rmax,全周都是 35.00,完整圆盘无缺口。
  3. 最后按"轴向坐标 ≈ 压盖前端面 且 到轴距离 34~36.5"筛棱边,命中唯一一条 弧长 219.9mm 的样条边(Y=161.0 平面、r 恒 35.0)—— 这就是拼接缝: 压盖是 s.fuse(fp) 直接熔接的圆盘,前缘落在臂身曲面上,交角处留硬棱。
  4. 沿 Y 的 Rmax 剖面佐证:Y<=156.5 时 R@90=60(叉板圆柱),Y>=157.5 时 R@90=35 —— 台阶高 25mm,圆角正是要把它化开。

修法:新增 blend_clamp_seam(shape, px, py, pz, s_face, axis, r, tag), 按"轴向坐标 ≈ 前端面 且 半径 ≈ R35"定位缝边并倒圆;倒圆失败只打印提示、退回原形状 (一个装饰性圆角绝不能毁掉整件)。CLAMP_SEAM_FILLET = 4.0(实测 R4 可行、R5 报 BRep_API 失败)。四处统一调用:P04/M2、P05/M3(roll-Z)、P06/M4、P07/M5。 必须放在各自零件的最后一步布尔之后 —— 缝边是压盖与臂身相交才产生的,中途任何 一刀都可能改变它。

踩的坑:near_face() 里我把 Y 轴关节的面坐标写成了 p.z(应为 p.y), 导致函数一条边都找不到、静默"保持原样"(幸好有打印,否则会以为改好了)。 教训:几何选择器写错时的默认行为是"什么都不做",必须让它打印命中数量, 否则"没报错"会被误读成"已生效"。调试手段:先用独立脚本按同样条件验证选择器 能命中 1 条,再进源码。

验证:4/4 命中并倒圆;13/13 单实体 ✓;静态干涉 8 组全零 ✓; motor_tol_check.py 5 关节 × ±2mm 共 15 组仍 0.0mm³ ✓(沉孔在 BCD27.5, 离 R35 外缘还有 7.5mm,倒圆完全不涉及螺钉孔)。

方法论:定位"视觉棱线"要按几何条件筛边(轴向坐标 + 半径区间), 不要靠渲染图目测猜是哪条棱。我这次先猜了两次圆柱面、一次缺口,三次都错, 第四次用条件筛选才一次命中。

撤回:压盖"拼接痕"R4 圆角(我误判,用户纠正)

用户反馈(两次纠正):

  1. 我把圆角加到了 J2/J3/J4/J5 四处压盖 -> 用户:"我说的是同个零件的两边, 只改我发你图片的部分"。已把 P05/P06/P07 的调用撤回。
  2. 我又改回只做 P04 一处 -> 用户:"不是圆角,而是你要把拼接的痕迹去掉, 现在另外一边是中间有个面,两边会凸出出来的"。

已全部撤回:删掉 blend_clamp_seam() 函数、CLAMP_SEAM_FILLET 常量、 P04 的调用、P04 BOM 里的说明、screws.json S12 的圆角备注。 grep blend_clamp_seam|CLAMP_SEAM_FILLET src/arm_model.py = 0。 重跑构建:13/13 单实体、8 组零干涉,代码回到加圆角之前的状态。

为什么撤回(我的诊断是错的): 用户描述的目标是"去掉拼接的痕迹"(几何问题),我却理解成"在缝上加圆角" (装饰问题)。这两件事完全不同:加圆角不改变"这里是两个零件熔接出来的"这个事实, 只是把锐边磨圆;用户要的是让它们本来就长成一个连续曲面。

我实测到的(可能有用,但结论未定):

  • 压盖本体在 Y=158 沿径向的最大材料半径全周恒为 35.00,是完整 R35 圆筒、 没有任何切削或缺口 -> 第一张图里那条"竖直直棱 + 右侧平面"不是压盖本体。
  • 那个"中间有个面"实测是 P04 上Z=526..646.5 / X=2.8..46.1 / Y=155.5..164.5 的 4048mm² 平面(法向 (0,1,-0.07),带 4° 斜度),位于电机上方 36mm 处, 由 p_fork 第 5 步 Xplate(yz_pts, -20.0, 60.0) 的轮廓线段与 XZ loft 求交切出。
  • 两侧"凸出的弧"最可能是 X=45.0 平面(5697mm²,法向 +X)与 R=164 圆柱 @(209,128,545) 的交接,以及立柱减重槽的两片腹板(X=23.0 / X=35.0 两面)。
  • 减重槽参数 P04_CH = x0=23, x1=35, y0=102, y1=154, z_floor=525。

教训(比这次的错更重要):

  1. "视觉缺陷"先分辨是几何问题还是表面质量问题。用户的措辞 ("去掉痕迹""两边凸出来")指向形状本身不对;我却直接跳到"加个圆角_smooth 一下" —— 这是用装饰手段掩盖几何问题,既没解决需求,也白改了四个零件。
  2. "两边"是拓扑位置,不是"多处"。用户说"同个零件的两边"指同一个零件上 对称的两个侧面,我却推广成了"全机四处"。改动范围要严格贴着用户指的地方, 有歧义就问(我第一次就该问,而不是先改了四处再撤回)。
  3. 定位不准时该早点问。我换了 6~7 种测量方式(面枚举、边枚举、截面扫、 径向扫、剪影投影)都没能确定那个面,就该停下来问,而不是继续猜下去。

视觉整改(成功):P04 电机上方 4048mm2 大平面 -> Hermite 弧面

用户反馈(第三次纠正后终于对题):给了标注红线的截图 —— "在电机上方的地方, 是一整个非常大的面,需要做成弧形面",并确认"平顶面需要匹配两边突出的弧度"。

定位(面枚举法,一次命中):枚举 P04 所有平面中「法向 +Y、Z>=520」且面积最大的面:

面积 4048mm²  法向 (0.00, 1.00, -0.07)  X 2.8..46.1  Y 155.5..164.5  Z 526.0..646.5

就是它。成因是 p_fork 第 5 步 yz_pts 里这一段直线:

(Y_AXIS+36.5, Z_RL+36.5)=(164.5,646.5)→ (Y_COVER-0.5, Z_SH+36.0)=(155.5,526)

沿 X 拉成平板,法向 (0,1,-0.07) 的 4° 斜度就是这么来的。两侧"鼓"的是 xz_wire 的 R18 圆弧((28,646.5)→(44,630) 那段 radiusArc(18.0))。

为什么不能用单段圆弧:起点 A=(155.5,526) 处切线须沿 Y(接 Y=155.5 竖直段), 终点 B=(164.5,646.5) 处切线须沿 Z(接 Z=646.5 顶段)—— 解圆心得 R=9 与 R=120.5 互相矛盾,单个圆弧无法同时满足。故用三次 Hermite(与 P05/P06 的 Loft 过渡同款): m0 = -0.5·d·0.35(沿 -Y),m1 = 0.5·d·0.5(沿 +Z),12 段采样。 中部向 +Y 外凸约 3mm,弧度观感与两侧 R18 协调。

踩的坑(重要):第一次实现把曲线采样成 y_a → y_b,而原列表是 y_b → y_a —— 顶点绕序反了,多边形自交,布尔后零件 碎成 3 块、体积从 282 掉到 48.7cm³。 改回原绕序立刻恢复单实体、体积 274.27cm³。 教训:改动多边形顶点序列时必须保持原有绕序,否则自交会让布尔结果彻底失真, 而症状(体积暴跌 + 碎块)看起来像"刀切掉了大量料",极易误判方向。 这次是体积对不上基准(差 233cm³)才立刻回头查绕序。

验证:13/13 单实体 ✓;静态干涉 8 组全零 ✓; motor_tol_check.py 5 关节 × ±2mm 共 15 组仍 0.0mm³ ✓; 面枚举确认 4048mm2 平面已消失,原位置变成 R=18 圆柱面 1447mm²(Z 630..646.5); 体积 282.07 → 274.27 cm³(弧面替代平面削掉 7.8cm³,符合预期)。

方法论(这次做对了的地方):不再靠截图目测猜,而是按几何条件筛面 (法向 +Y + Z 下界 + 面积最大),第一轮就锁定了目标面及其成因代码行。 前两轮失败(改圆角、改范围)都是因为没先定位清楚就开始动手。

承压面"围挡"消除:SEAT_R 必须是 R35(用户第三次指出,我前两次都错在"取值方向"上)

用户反馈(第三次纠正):"之前削平面的时候还是不对,凸台还是在的,你加了一圈围挡, 这不是正确做法,需要把凸台、围挡一起弄平,做成和电机两头齐平一起的平面。" 截图是 P08(#d97706 橙色)M6 电机后端,能看到 R35 端面上有一圈凸起的环。

根因(一行公式,之前两次都没想透):

只要 SEAT_R < R35,外壁与刀半径之间那圈环墙就必然存在,
且相对承压面凸起 (R35 − SEAT_R),把电机尾端面围在中间。
  • 我第一次取 64.4 方腔 -> 四角被吃穿,残留 4 段弧 = "凸台"
  • 我第二次取 32.2 = 方腔内切圆(想"保住连接壁")-> 32.2 与 35 之间那圈 2.8mm 宽环墙完整保留,承压面只挖到 32.2,于是环墙凸起 2.6mm = "围挡" (P08 实测该圈1536.9 mm³) 两次都不是"残留",而是取值的必然产物。用户第三次要求"一起弄平"就是指这个。

正确改法(一处数值):SEAT_R: 32.2 -> 35.0(= 外壁 R35)、SEAT_TOP: 0.0 -> 1.0。 承压面段整圈挖到外壁 -> 承压面变成完整 R35 平圆盘,凸台与围挡同时消失。 SEAT_TOP=+1.0 是为了吃掉半包开口(Y93.0~95.8)那截 0.052cm³ 残片 (取 0 时它脱空成独立碎块,P05/P08 各多一块)。

为什么不重演 2026-10-04 的"肩叉顶部没连上": 那版切 R35 但 SEAT_TOP=0,在 z=0..1.0 残留一截薄片 + 承力桥判定失误。 这次实测:band 段(z=-2.4..+0.8)r33.5 处围挡残留 0/36, r36..58(臂身)有料方位 P04 10/36、其余各 15/36,其余方位靠 z>+1.0 杯体连接, 无整圈通槽。关键差别是 SEAT_TOP 抬到 +1.0,不是改回 32.2。

连带好处:承压环由「方腔内切 32.2 − 沉孔外缘 30.25 = 1.95mm 窄环」 变为「完整 R35 圆环 4.75mm」,受压面积 383 -> 974 mm²(2.5 倍)。

验证:

  • 13/13 单实体 ✓(P04 272.3 / P05 151.4 / P06 158.8 / P07 222.6 / P08 138.1 cm³)
  • 静态干涉 8/8 零 ✓
  • motor_tol_check.py 5 关节 × ΔL∈{−2,0,+2} 共 15 组全部 0.0mm³、面压间隙 0.0 ✓
  • 4×S02 沉孔残余 0.00mm³(沉孔 z=-8..-4 与圆腔 z=-2.6..+1.0 不重叠)✓

踩的坑(重要):

  1. 自己写的光栅化投影渲染器(从 mesh_arm.json 三角网格直接光栅)完全不能用 —— 深度缓冲/背面剔除/缩放全错,出一堆三角形碎面。排查这个问题花掉十几轮。 教训:项目已有 src/shot.py(headless Edge)就是唯一可靠的渲染链路,别自己造。
  2. src/shot.py 并发渲染会随机 FAIL —— 根因是没加 --user-data-dir, 多个 Edge 实例抢同一个默认 profile 的锁。已修:每次 tempfile.mkdtemp() 建独立 profile,收尾 shutil.rmtree。加上之后 4 视图并发 100% 成功。
  3. 写 BOM 说明时在 " 引号字符串里放了未转义的中文引号 "一圈围挡" —— 直接 SyntaxError 把 109KB 的 arm_model.py 写坏。已从 .bak/ 备份恢复。 教训:批量替换长中文注释时,别把双引号文本塞进 Python 双引号字符串。 已建立 .bak/arm_model.py.bak20261005 / arm_build.py.bak20261005。

方法论教训(第三次了): "改不动 / 消不掉"的几何问题,先想清楚是不是某个取值的必然结果, 而不是急着找"残留料"去切。SEAT_R 这个旋钮从 64.4 方腔 -> 32.2 -> 35.0, 每次换取值都改变了"环墙是否存在",而我一直只在 32.2 这一档里找原因。 参数化几何里,"某段料消失"几乎总是某个半径/长度取值的函数,不是布尔残留。