# -*- coding: utf-8 -*- """P01 立柱三段(A/B/C):躯干承力柱 + 阶梯榫卯与防反装对锁孔。""" import cadquery as cq from arm.cad.helpers import cyl from arm.cad.arm_build import Ycyl, bx from arm.kinematics import Y_AXIS, Z_CHEST1 from arm.cad.part_tools import Xcyl # ========== 躯干部分 ========== # ========== 躯干/测试台架部分 (后置防倾翻高刚性机架) ========== X_COL = -115.0 Y_COL = Y_AXIS # 128.0 Z_LOCK = 463.0 # 横向防脱锁紧螺钉高度(立柱后壁 → 榫头,M4x16 自攻) def p_chest(): """P01_胸腔支撑立柱 (High-Rigidity Box Mast Tower - 后置台架立柱): 1. 66x66mm 封闭中空厚壁箱型柱(壁厚 11mm,内腔 44x44),中心在 (-115.0, 128.0),位于手臂正后方; 2. 顶部接收 P03 43.4x43.4x15mm 定位榫头(44x44 R4 内腔)、4x 竖向安装孔 + 1x 横向防脱锁紧孔 (全部 Ø3.9 直孔:M4x16 从外部直接拧入自攻成型,无过孔/无沉孔/无预埋); 3. 底部 50x50x12mm 阶梯榫头插入 P02 榫座:环形台肩(66->50)面承载轴向力,槽壁全周承载剪切; 4. 前向开设两组大圆角走线工艺窗口(Z=60~150mm 与 Z=330~420mm); 5. 外棱角全部采用 R=6mm 圆角。 """ z_bot = 22.0 z_top = Z_CHEST1 # 470.0 col = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_bot)) .rect(66.0, 66.0) .extrude(z_top - z_bot) .edges("|Z").fillet(6.0)).val() s = cq.Shape(col.wrapped) cav = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_bot + 10.0)) .rect(44.0, 44.0) .extrude(z_top - z_bot + 1.0) .edges("|Z").fillet(4.0)).val() s = s.cut(cav) # 底部阶梯榫头:插入 P02 榫座后环形台肩坐实,轴向力走面压而非 M5 螺纹 tenon = (cq.Workplane("XY", origin=(X_COL, Y_COL, 10.0)) .rect(50.0, 50.0).extrude(z_bot - 10.0) .edges("|Z").fillet(4.0)).val() s = s.fuse(tenon) # 底部 M5 夹紧孔(贯通榫头):X 向非对称 (−20/+16) 与榫座孔位配对防反装/防转 90° for xx in (X_COL - 20.0, X_COL + 16.0): for yy in (Y_COL - 18.0, Y_COL + 18.0): s = s.cut(cyl(2.75, 9.99, z_bot + 15.0, xx, yy)) # 顶部 4x 安装孔:统一 Ø3.9 直孔(M4x16 直接拧入自攻成型;只打这一个孔,无过孔/无沉孔),深 20mm # 位于 66x66 顶环 11mm 实体壁内(内腔 22 → 外壁 33),避开 44x44 内腔与 R4 内腔圆角; for xx in (X_COL - 27.5, X_COL + 27.5): for yy in (Y_COL - 13.5, Y_COL + 13.5): s = s.cut(cyl(1.95, z_top - 20.0, z_top + 0.01, xx, yy)) # 横向防脱锁紧孔(后壁 → 榫头):Ø3.9 贯穿 11mm 后壁 + 榫头同径(M4x16 拧入自攻) s = s.cut(Xcyl(1.95, X_COL - 34.0, X_COL - 20.0, Y_COL, Z_LOCK)) w_bot = (cq.Workplane("YZ", origin=(X_COL + 33.5, Y_COL, 105.0)) .rect(34.0, 70.0) .extrude(-20.0)).val() s = s.cut(w_bot) w_top = (cq.Workplane("YZ", origin=(X_COL + 33.5, Y_COL, 375.0)) .rect(34.0, 70.0) .extrude(-20.0)).val() s = s.cut(w_top) return s def split_p01_poka_yoke(p01): """拆分 P01 为 A/B/C 三段(严格适配 200x200mm 打印机,竖直免支撑打印): 带 16mm 阶梯互锁榫卯(外套筒壁 3.6 + 公榫壁 6.9,内腔收窄 51->44 换取双厚壁, 单边配合间隙 0.5)、以及统一 Ø3.9 直孔的分段对锁孔(M4x16 从外面直接拧入自攻成型, 母口壁与公榫壁同径,无过孔/沉孔/预埋,前后两面对称各一颗); 孔位相对立柱中心 −16 / +22 非对称(物理防反装防呆);本体 3D 凹刻朝向标识。 """ z_bot = 22.0 z_s1 = 172.0 z_s2 = 321.0 z_top = 470.0 h_lap = 16.0 # 非对称对锁孔位(相对立柱中心偏心 -16mm 与 +22mm,偏心差 6mm,反装无法穿入螺栓) xx_bolts = (X_COL - 16.0, X_COL + 22.0) # 分段对锁孔:统一 Ø3.9 直孔(M4x16 从外面直接拧入自攻成型;母口壁与公榫壁同径, # 没有过孔/沉孔等其它孔),前后两面对称;杆尖伸过榫壁的一段在内腔侧留 Ø4.5 让位。 def _seam_holes(part, xx, z): return (part.cut(Ycyl(1.95, Y_COL - 33.6, Y_COL - 21.4, xx, z)) .cut(Ycyl(1.95, Y_COL + 21.4, Y_COL + 33.6, xx, z)) .cut(Ycyl(2.25, Y_COL - 21.7, Y_COL - 15.5, xx, z)) .cut(Ycyl(2.25, Y_COL + 15.5, Y_COL + 21.7, xx, z))) # --- P01_A (下段) --- cut_above_s1 = bx(X_COL - 50.0, X_COL + 50.0, Y_COL - 50.0, Y_COL + 50.0, z_s1, z_top + 10.0) p01_a_base = p01.cut(cut_above_s1) tongue1_outer = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s1)) .rect(57.8, 57.8).extrude(h_lap) .edges("|Z").fillet(3.4).edges(">Z").chamfer(1.5)).val() tongue1_cav = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s1 - 1.0)) .rect(44.0, 44.0).extrude(h_lap + 2.0)).val() tongue1 = cq.Shape(tongue1_outer.wrapped).cut(tongue1_cav) p01_a = p01_a_base.fuse(tongue1) z_bolt1 = z_s1 + h_lap / 2.0 # 180.0 for xx in xx_bolts: p01_a = _seam_holes(p01_a, xx, z_bolt1) # A-B 缝对锁孔(Ø3.9,前后两面) # Engrave the front (-Y) flat face, reading VERTICALLY bottom-to-top along # the column (user request): local +X = world +Z, local +Y = world -X, so # the trailing "▶" glyph renders pointing world-up (+Z). front_label_plane_a = cq.Plane( origin=(X_COL, Y_COL - 33.0, 120.0), xDir=(0, 0, 1), normal=(0, -1, 0), ) label_a = (cq.Workplane(front_label_plane_a) .text("P01-A TOP ▶", 9.0, -0.8)).val() p01_a = p01_a.cut(cq.Shape(label_a.wrapped)) # --- P01_B (中段) --- cut_below_s1 = bx(X_COL - 50.0, X_COL + 50.0, Y_COL - 50.0, Y_COL + 50.0, z_bot - 14.0, z_s1) cut_above_s2 = bx(X_COL - 50.0, X_COL + 50.0, Y_COL - 50.0, Y_COL + 50.0, z_s2, z_top + 10.0) p01_b_base = p01.cut(cut_below_s1).cut(cut_above_s2) pocket1 = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s1 - 0.1)) .rect(58.8, 58.8).extrude(h_lap + 0.6).edges("|Z").fillet(3.9)).val() p01_b_base = p01_b_base.cut(pocket1) tongue2_outer = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s2)) .rect(57.8, 57.8).extrude(h_lap) .edges("|Z").fillet(3.4).edges(">Z").chamfer(1.5)).val() tongue2_cav = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s2 - 1.0)) .rect(44.0, 44.0).extrude(h_lap + 2.0)).val() tongue2 = cq.Shape(tongue2_outer.wrapped).cut(tongue2_cav) p01_b = p01_b_base.fuse(tongue2) z_bolt2 = z_s2 + h_lap / 2.0 # 329.0 for xx in xx_bolts: p01_b = _seam_holes(p01_b, xx, z_bolt1) # A-B 缝对锁孔(Ø3.9,前后两面) p01_b = _seam_holes(p01_b, xx, z_bolt2) # B-C 缝对锁孔(Ø3.9,前后两面) front_label_plane_b = cq.Plane( origin=(X_COL, Y_COL - 33.0, 240.0), xDir=(0, 0, 1), normal=(0, -1, 0), ) label_b = (cq.Workplane(front_label_plane_b) .text("P01-B TOP ▶", 9.0, -0.8)).val() p01_b = p01_b.cut(cq.Shape(label_b.wrapped)) # --- P01_C (上段) --- cut_below_s2 = bx(X_COL - 50.0, X_COL + 50.0, Y_COL - 50.0, Y_COL + 50.0, z_bot - 14.0, z_s2) p01_c_base = p01.cut(cut_below_s2) pocket2 = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s2 - 0.1)) .rect(58.8, 58.8).extrude(h_lap + 0.6).edges("|Z").fillet(3.9)).val() p01_c = p01_c_base.cut(pocket2) for xx in xx_bolts: p01_c = _seam_holes(p01_c, xx, z_bolt2) # B-C 缝对锁孔(Ø3.9,前后两面) front_label_plane_c = cq.Plane( origin=(X_COL, Y_COL - 33.0, 390.0), xDir=(0, 0, 1), normal=(0, -1, 0), ) label_c = (cq.Workplane(front_label_plane_c) .text("P01-C TOP ▶", 9.0, -0.8)).val() p01_c = p01_c.cut(cq.Shape(label_c.wrapped)) return p01_a, p01_b, p01_c JOINT = 'root' def specs(JS): """本件的 (件号, 中文名, 构建 thunk, 配色, 说明) 清单;顺序即 BOM 顺序。""" p01_a, p01_b, p01_c = split_p01_poka_yoke(p_chest()) return [ ("P01_A_立柱下段_三角形30%_墙4底5_竖打", "立柱下段", lambda: p01_a, 0x0284c7, "200mm适配分段A:高166mm+16mm阶梯公榫+顶端 2x Ø3.9 对锁孔(M4x16 自攻)+底部50x50x12榫头+P01-A 竖排TOP刻字"), ("P01_B_立柱中段_三角形30%_墙4底5_竖打", "立柱中段", lambda: p01_b, 0x2563eb, "200mm适配分段B:高165mm+双端公母榫+两端各 2x Ø3.9 对锁孔(M4x16 自攻,非对称孔位防反装)+P01-B 竖排TOP刻字"), ("P01_C_立柱上段_三角形30%_墙4底5_竖打", "立柱上段", lambda: p01_c, 0x1d4ed8, "200mm适配分段C:高149mm+底端母榫+底端 2x Ø3.9 对锁孔(非对称孔位防反装)+顶面P03安装台(4x Ø3.9 安装孔 + 1x Ø3.9 横向锁紧孔)+P01-C 竖排TOP刻字"), ]