docs: 更新BOM清单与渲染图,适配200mm分段式立柱和防呆底座设计
This commit is contained in:
+273
-49
@@ -121,38 +121,219 @@ def p_chest():
|
||||
return s
|
||||
|
||||
|
||||
def split_p01_stack(p01):
|
||||
"""将 P01 拆分为适合 250mm 桌面 3D 打印机的两段(P01_A 与 P01_B),带 16mm 阶梯互锁榫卯"""
|
||||
z_split = 246.0
|
||||
def split_p01_poka_yoke(p01):
|
||||
"""拆分 P01 为 A/B/C 三段(严格适配 200x200mm 打印机,竖直免支撑打印):
|
||||
带 16mm 阶梯互锁榫卯、非对称 M4 横向对锁穿钉孔(物理防反装防呆)、以及本体 3D 凹刻朝向标识。
|
||||
"""
|
||||
z_bot = 22.0
|
||||
z_s1 = 172.0
|
||||
z_s2 = 321.0
|
||||
z_top = 470.0
|
||||
h_lap = 16.0
|
||||
|
||||
cut_b = bx(X_COL - 45.0, X_COL + 45.0, Y_COL - 45.0, Y_COL + 45.0, z_split, 500.0)
|
||||
tongue_outer = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_split))
|
||||
.rect(64.8, 64.8)
|
||||
.extrude(h_lap)
|
||||
.edges("|Z").fillet(5.5)).val()
|
||||
tongue_cav = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_split - 1.0))
|
||||
.rect(51.0, 51.0)
|
||||
.extrude(h_lap + 2.0)).val()
|
||||
tongue = cq.Shape(tongue_outer.wrapped).cut(tongue_cav)
|
||||
# 非对称对锁孔位(相对立柱中心偏心 -16mm 与 +22mm,偏心差 6mm,反装无法穿入螺栓)
|
||||
xx_bolts = (X_COL - 16.0, X_COL + 22.0)
|
||||
|
||||
p01_a = p01.cut(cut_b).fuse(tongue)
|
||||
# --- 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(64.8, 64.8).extrude(h_lap)
|
||||
.edges("|Z").fillet(5.5).edges(">Z").chamfer(1.5)).val()
|
||||
tongue1_cav = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s1 - 1.0))
|
||||
.rect(51.0, 51.0).extrude(h_lap + 2.0)).val()
|
||||
tongue1 = cq.Shape(tongue1_outer.wrapped).cut(tongue1_cav)
|
||||
p01_a = p01_a_base.fuse(tongue1)
|
||||
|
||||
cut_a = bx(X_COL - 45.0, X_COL + 45.0, Y_COL - 45.0, Y_COL + 45.0, 0.0, z_split)
|
||||
p01_b = p01.cut(cut_a)
|
||||
pocket = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_split - 0.1))
|
||||
.rect(65.6, 65.6)
|
||||
.extrude(h_lap + 0.5)
|
||||
.edges("|Z").fillet(6.0)).val()
|
||||
p01_b = p01_b.cut(pocket)
|
||||
|
||||
z_bolt = z_split + h_lap / 2.0
|
||||
for xx in (X_COL - 19.0, X_COL + 19.0):
|
||||
y_bolt = Ycyl(2.2, Y_COL - 38.0, Y_COL + 38.0, xx, z_bolt)
|
||||
p01_a = p01_a.cut(y_bolt)
|
||||
p01_b = p01_b.cut(y_bolt)
|
||||
z_bolt1 = z_s1 + h_lap / 2.0 # 180.0
|
||||
for xx in xx_bolts:
|
||||
p01_a = p01_a.cut(Ycyl(2.2, Y_COL - 40.0, Y_COL + 40.0, xx, z_bolt1))
|
||||
|
||||
return p01_a, p01_b
|
||||
label_a = (cq.Workplane("YZ", origin=(-82.0, Y_COL, 120.0))
|
||||
.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 - 10.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(65.4, 65.4).extrude(h_lap + 0.6).edges("|Z").fillet(5.8)).val()
|
||||
p01_b_base = p01_b_base.cut(pocket1)
|
||||
|
||||
tongue2_outer = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s2))
|
||||
.rect(64.8, 64.8).extrude(h_lap)
|
||||
.edges("|Z").fillet(5.5).edges(">Z").chamfer(1.5)).val()
|
||||
tongue2_cav = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_s2 - 1.0))
|
||||
.rect(51.0, 51.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 = p01_b.cut(Ycyl(2.2, Y_COL - 40.0, Y_COL + 40.0, xx, z_bolt1))
|
||||
p01_b = p01_b.cut(Ycyl(2.2, Y_COL - 40.0, Y_COL + 40.0, xx, z_bolt2))
|
||||
|
||||
label_b = (cq.Workplane("YZ", origin=(-82.0, Y_COL, 240.0))
|
||||
.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 - 10.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(65.4, 65.4).extrude(h_lap + 0.6).edges("|Z").fillet(5.8)).val()
|
||||
p01_c = p01_c_base.cut(pocket2)
|
||||
for xx in xx_bolts:
|
||||
p01_c = p01_c.cut(Ycyl(2.2, Y_COL - 40.0, Y_COL + 40.0, xx, z_bolt2))
|
||||
|
||||
label_c = (cq.Workplane("YZ", origin=(-82.0, Y_COL, 390.0))
|
||||
.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
|
||||
|
||||
|
||||
def make_p02_poka_yoke():
|
||||
"""将 P02 拆分为三件模块化组件(均严格 <= 195x190mm,适配 200x200mm 打印床):
|
||||
1. P02_Center (底座中核心): 195x190x70mm,完整容纳立柱套筒与前后三角斜撑筋,核心应力区无接缝;
|
||||
2. P02_Front (前向力臂): 145x190x22mm,宽跨距 104mm 双榫头 + 预埋 M5 螺母槽;
|
||||
3. P02_Rear (后向力臂): 45x190x22mm,窄跨距 80mm 双榫头(跨距差达 24mm 物理防呆,绝不混装)。
|
||||
"""
|
||||
z0 = 0.0
|
||||
z1 = 22.0
|
||||
y_width = 190.0
|
||||
|
||||
f_tenon_w = 44.0
|
||||
f_tenon_y_span = 52.0
|
||||
r_tenon_w = 32.0
|
||||
r_tenon_y_span = 40.0
|
||||
|
||||
# 1. P02_Center (X = -195.0 .. 0.0, 195x190mm)
|
||||
x_c_min = -195.0
|
||||
x_c_max = 0.0
|
||||
x_c_len = x_c_max - x_c_min
|
||||
x_c_mid = (x_c_min + x_c_max) / 2.0
|
||||
|
||||
c_plate = (cq.Workplane("XY", origin=(x_c_mid, Y_COL, z0))
|
||||
.rect(x_c_len, y_width).extrude(z1)
|
||||
.edges("|Z and <X").fillet(8.0).edges("|Z and >X").fillet(8.0)
|
||||
.edges(">Z").fillet(2.0)).val()
|
||||
p02_c = cq.Shape(c_plate.wrapped)
|
||||
|
||||
# Socket collar (Z: 22..70mm)
|
||||
z_collar_top = 70.0
|
||||
collar_outer = (cq.Workplane("XY", origin=(X_COL, Y_COL, z1))
|
||||
.rect(80.0, 80.0).extrude(z_collar_top - z1)
|
||||
.edges("|Z").fillet(8.0).edges(">Z").chamfer(2.0)).val()
|
||||
p02_c = p02_c.fuse(cq.Shape(collar_outer.wrapped))
|
||||
|
||||
# Front & Rear triangular gusset ribs
|
||||
f_pts = [(-75.0, z1), (-15.0, z1), (-15.0, z1 + 4.0), (-75.0, 68.0)]
|
||||
f_rib = (cq.Workplane("XZ", origin=(0, Y_COL, 0)).polyline(f_pts).close().extrude(19.0, both=True)).val()
|
||||
p02_c = p02_c.fuse(cq.Shape(f_rib.wrapped))
|
||||
|
||||
r_pts = [(-155.0, z1), (-195.0, z1), (-195.0, z1 + 14.0), (-155.0, 70.0)]
|
||||
r_rib = (cq.Workplane("XZ", origin=(0, Y_COL, 0)).polyline(r_pts).close().extrude(19.0, both=True)).val()
|
||||
p02_c = p02_c.fuse(cq.Shape(r_rib.wrapped))
|
||||
|
||||
# Front wire guide
|
||||
wg_pts = [(-75.5, z1 + 1.0), (-14.0, z1 + 1.0), (-14.0, z1 + 4.0), (-75.5, 68.5)]
|
||||
wire_guide = (cq.Workplane("XZ", origin=(0, Y_COL, 0)).polyline(wg_pts).close().extrude(9.0, both=True)).val()
|
||||
p02_c = p02_c.cut(wire_guide)
|
||||
|
||||
# Column socket
|
||||
socket = (cq.Workplane("XY", origin=(X_COL, Y_COL, 10.0))
|
||||
.rect(66.6, 66.6).extrude(z_collar_top - 10.0 + 1.0).edges("|Z").fillet(6.3)).val()
|
||||
p02_c = p02_c.cut(socket)
|
||||
|
||||
# Vertical M5 base bolts
|
||||
for xx in (X_COL - 21.0, X_COL + 21.0):
|
||||
for yy in (Y_COL - 21.0, Y_COL + 21.0):
|
||||
p02_c = p02_c.cut(cyl(2.75, -0.01, 10.5, xx, yy)).cut(cyl(5.0, -0.01, 6.0, xx, yy))
|
||||
|
||||
# Center clamp slots
|
||||
for cy in (Y_COL - 75.0, Y_COL + 75.0):
|
||||
plane = cq.Plane(origin=(x_c_mid, cy, -0.01), xDir=(0, 1, 0), normal=(0, 0, 1))
|
||||
slot = cq.Workplane(plane).slot2D(28.0, 7.0).extrude(z1 + 1.0).val()
|
||||
p02_c = p02_c.cut(slot)
|
||||
|
||||
p02_c = p02_c.cut((cq.Workplane("XY", origin=(X_COL, Y_COL - 70.0, -0.01)).rect(28.0, 80.0).extrude(6.0)).val())
|
||||
|
||||
# Front mortise pockets
|
||||
for sign in (-1, 1):
|
||||
yy = Y_COL + sign * f_tenon_y_span
|
||||
front_mortise = (cq.Workplane("XY", origin=(-10.0, yy, 4.8))
|
||||
.rect(21.0, f_tenon_w + 0.8).extrude(12.6).edges("|Z and <X").fillet(3.0)).val()
|
||||
p02_c = p02_c.cut(front_mortise)
|
||||
p02_c = p02_c.cut(cyl(2.75, -0.01, z1 + 1.0, -10.0, yy))
|
||||
p02_c = p02_c.cut(cyl(5.0, z1 - 5.0, z1 + 1.0, -10.0, yy))
|
||||
|
||||
# Rear mortise pockets
|
||||
for sign in (-1, 1):
|
||||
yy = Y_COL + sign * r_tenon_y_span
|
||||
rear_mortise = (cq.Workplane("XY", origin=(-185.0, yy, 4.8))
|
||||
.rect(21.0, r_tenon_w + 0.8).extrude(12.6).edges("|Z and >X").fillet(3.0)).val()
|
||||
p02_c = p02_c.cut(rear_mortise)
|
||||
p02_c = p02_c.cut(cyl(2.75, -0.01, z1 + 1.0, -185.0, yy))
|
||||
p02_c = p02_c.cut(cyl(5.0, z1 - 5.0, z1 + 1.0, -185.0, yy))
|
||||
|
||||
# Debossed text on P02_Center top face
|
||||
txt_c_f = (cq.Workplane("XY", origin=(-35.0, Y_COL, z1)).text("▲ FRONT (前向) ▲", 9.0, -0.8)).val()
|
||||
txt_c_r = (cq.Workplane("XY", origin=(-165.0, Y_COL, z1)).text("▲ REAR (后向) ▲", 9.0, -0.8)).val()
|
||||
p02_c = p02_c.cut(cq.Shape(txt_c_f.wrapped)).cut(cq.Shape(txt_c_r.wrapped))
|
||||
|
||||
# 2. P02_Front (X = 0.0 .. 145.0, 145x190mm)
|
||||
x_f_len = 145.0
|
||||
x_f_mid = 72.5
|
||||
f_plate = (cq.Workplane("XY", origin=(x_f_mid, Y_COL, z0))
|
||||
.rect(x_f_len, y_width).extrude(z1)
|
||||
.edges("|Z and >X").fillet(16.0).edges(">Z").fillet(2.0)).val()
|
||||
p02_f = cq.Shape(f_plate.wrapped)
|
||||
|
||||
for cy in (Y_COL - 70.0, Y_COL + 70.0):
|
||||
plane = cq.Plane(origin=(120.0, cy, -0.01), xDir=(0, 1, 0), normal=(0, 0, 1))
|
||||
slot = cq.Workplane(plane).slot2D(28.0, 7.0).extrude(z1 + 1.0).val()
|
||||
p02_f = p02_f.cut(slot)
|
||||
|
||||
for sign in (-1, 1):
|
||||
yy = Y_COL + sign * f_tenon_y_span
|
||||
tongue = (cq.Workplane("XY", origin=(-9.5, yy, 5.25))
|
||||
.rect(20.0, f_tenon_w - 0.2).extrude(11.5).edges("|Z and <X").fillet(2.5).edges("<X").chamfer(1.5)).val()
|
||||
p02_f = p02_f.fuse(cq.Shape(tongue.wrapped))
|
||||
p02_f = p02_f.cut(cyl(2.75, -0.01, z1 + 1.0, -10.0, yy))
|
||||
nut_pocket = (cq.Workplane("XY", origin=(-10.0, yy, -0.01)).polygon(6, 9.2).extrude(5.0)).val()
|
||||
p02_f = p02_f.cut(nut_pocket)
|
||||
|
||||
txt_f = (cq.Workplane("XY", origin=(60.0, Y_COL, z1)).text("P02-FRONT [前向防倾翻力臂] ◀ JOIN", 9.0, -0.8)).val()
|
||||
p02_f = p02_f.cut(cq.Shape(txt_f.wrapped))
|
||||
|
||||
# 3. P02_Rear (X = -240.0 .. -195.0, 45x190mm)
|
||||
x_r_len = 45.0
|
||||
x_r_mid = -217.5
|
||||
r_plate = (cq.Workplane("XY", origin=(x_r_mid, Y_COL, z0))
|
||||
.rect(x_r_len, y_width).extrude(z1)
|
||||
.edges("|Z and <X").fillet(16.0).edges(">Z").fillet(2.0)).val()
|
||||
p02_r = cq.Shape(r_plate.wrapped)
|
||||
|
||||
for cy in (Y_COL - 70.0, Y_COL + 70.0):
|
||||
plane = cq.Plane(origin=(-215.0, cy, -0.01), xDir=(0, 1, 0), normal=(0, 0, 1))
|
||||
slot = cq.Workplane(plane).slot2D(28.0, 7.0).extrude(z1 + 1.0).val()
|
||||
p02_r = p02_r.cut(slot)
|
||||
|
||||
for sign in (-1, 1):
|
||||
yy = Y_COL + sign * r_tenon_y_span
|
||||
tongue = (cq.Workplane("XY", origin=(-185.5, yy, 5.25))
|
||||
.rect(20.0, r_tenon_w - 0.2).extrude(11.5).edges("|Z and >X").fillet(2.5).edges(">X").chamfer(1.5)).val()
|
||||
p02_r = p02_r.fuse(cq.Shape(tongue.wrapped))
|
||||
p02_r = p02_r.cut(cyl(2.75, -0.01, z1 + 1.0, -185.0, yy))
|
||||
nut_pocket = (cq.Workplane("XY", origin=(-185.0, yy, -0.01)).polygon(6, 9.2).extrude(5.0)).val()
|
||||
p02_r = p02_r.cut(nut_pocket)
|
||||
|
||||
txt_r = (cq.Workplane("XY", origin=(-215.0, Y_COL, z1)).text("P02-REAR ▶ JOIN", 7.5, -0.8)).val()
|
||||
p02_r = p02_r.cut(cq.Shape(txt_r.wrapped))
|
||||
|
||||
return p02_c, p02_f, p02_r
|
||||
|
||||
|
||||
def p_base_foot():
|
||||
@@ -713,7 +894,7 @@ def p_forearm_bone(j4, j5, half=None):
|
||||
y_hub_in = HL.Y_COVER + 0.5 + CLEARANCE_GAP # 158.5
|
||||
y_front = Y_COVER - 0.5 # 155.5
|
||||
y_rear = Y_REAR - 8.0 # 92.0
|
||||
z_top_housing = Z_WR + 35.0 # 257.0
|
||||
z_top_housing = Z_WR + 39.0 # 261.0 (顶面加厚 4.0mm,消除过薄破面问题)
|
||||
|
||||
# 1. J5 电机前后安装环
|
||||
collar_front = Ycyl(35.0, HL.Y_COVER - 6.0, HL.Y_COVER - 0.5, X_ARM, Z_WR)
|
||||
@@ -772,7 +953,7 @@ def p_forearm_bone(j4, j5, half=None):
|
||||
s = j5.front_collar_pocket(s, r_bore=30.25 + CLEARANCE_GAP, z0=50.0, z1=56.5)
|
||||
s = j5.rear_mount_holes(s, t_plate=8.0, hole_d=2.8, cb_d=5.5, cb_depth=4.0)
|
||||
s = j5.pocket(s)
|
||||
s = s.cut(Ycyl(30.5 + CLEARANCE_GAP, y_rear + 0.5, y_front - 6.0, X_ARM, Z_WR))
|
||||
s = s.cut(Ycyl(30.5 + CLEARANCE_GAP, HL.Y_REAR - 0.5, y_front - 6.0, X_ARM, Z_WR))
|
||||
|
||||
# 半包散热设计:-Z底部电机定子通风口
|
||||
vent_cut = bx(X_ARM - 40.0, X_ARM + 40.0, y_rear + 8.0, y_front - 6.0, Z_WR - 40.0, Z_WR - 25.0)
|
||||
@@ -796,26 +977,36 @@ def p_forearm_bone(j4, j5, half=None):
|
||||
|
||||
# ========== 关键圆角优化 ==========
|
||||
try:
|
||||
s = s.edges("|X").chamfer(CHAMFER_EDGE)
|
||||
except:
|
||||
pass
|
||||
# 后侧顶板外边缘倒角(平滑消除水平顶板与后部垂直端面交汇处的 90° 尖角)
|
||||
wp_s = cq.Workplane(obj=s)
|
||||
sel_rear = cq.selectors.BoxSelector(
|
||||
(X_ARM - 40, y_rear - 1.0, z_top_housing - 1.0),
|
||||
(X_ARM + 40, y_rear + 1.0, z_top_housing + 1.0)
|
||||
)
|
||||
s = wp_s.edges(sel_rear).chamfer(CHAMFER_EDGE).val()
|
||||
except Exception as e:
|
||||
print(f"P07 顶板后边缘倒角异常: {e}")
|
||||
|
||||
try:
|
||||
# 圆润化 J4 圆盘外沿
|
||||
s = s.edges(cq.selectors.BoxSelector(
|
||||
wp_s = cq.Workplane(obj=s)
|
||||
sel_disc = cq.selectors.BoxSelector(
|
||||
(X_ARM - 40, y_out - 2, Z_EL - 40),
|
||||
(X_ARM + 40, y_out + 2, Z_EL + 40)
|
||||
)).fillet(FILLET_SMALL)
|
||||
except:
|
||||
)
|
||||
s = wp_s.edges(sel_disc).fillet(FILLET_SMALL).val()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
# 圆润化垂直立柱外侧边棱
|
||||
s = s.edges(cq.selectors.BoxSelector(
|
||||
wp_s = cq.Workplane(obj=s)
|
||||
sel_leg = cq.selectors.BoxSelector(
|
||||
(X_ARM - 37, y_out - 2, z_top_housing),
|
||||
(X_ARM + 37, y_out + 2, Z_EL + 40)
|
||||
)).fillet(FILLET_SMALL)
|
||||
except:
|
||||
)
|
||||
s = wp_s.edges(sel_leg).fillet(FILLET_SMALL).val()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return s
|
||||
@@ -905,14 +1096,30 @@ def build():
|
||||
for t in ("J1", "J2", "J3", "J4", "J5", "J6"):
|
||||
AB.GRP[motor_of[t]] = par[t]
|
||||
AB.GRP[driven[t]] = t
|
||||
AB.GRP.update({"P01_胸板": "root", "P02_底脚": "root", "P03_肩吊臂": "root"})
|
||||
AB.GRP.update({
|
||||
"P01_A_立柱下段": "root", "P01_B_立柱中段": "root", "P01_C_立柱上段": "root",
|
||||
"P02_Center_底座中核心": "root", "P02_Front_前向防翻力臂": "root", "P02_Rear_后向防翻力臂": "root",
|
||||
"P03_肩吊臂": "root"
|
||||
})
|
||||
AB.JAW = {}
|
||||
|
||||
p01_full = p_chest()
|
||||
p01_a, p01_b, p01_c = split_p01_poka_yoke(p01_full)
|
||||
p02_c, p02_f, p02_r = make_p02_poka_yoke()
|
||||
|
||||
parts_to_build = [
|
||||
("P01_胸板", "胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗)", lambda: p_chest(), 0x4b5563,
|
||||
"V2高刚度立柱:66x66mm厚壁封闭箱梁+8mm壁厚+顶部P03榫卯台座+两组大圆角工艺走线窗"),
|
||||
("P02_底脚", "测试台架底座(重型防倾翻超长力臂+双向三角斜撑版)", lambda: p_base_foot(), 0x374151,
|
||||
"防倾翻超大底盘:385x240mm超长力臂+48mm立柱套筒+前后双向大三角抗倾翻斜撑筋+走线导槽+6xM6固定槽"),
|
||||
("P01_A_立柱下段", "立柱下段(P01-A 标识版)", lambda: p01_a, 0x0284c7,
|
||||
"200mm适配分段A:高166mm+16mm阶梯公榫+非对称M4防反装通孔+P01-A ▲ TOP刻字"),
|
||||
("P01_B_立柱中段", "立柱中段(P01-B 标识版)", lambda: p01_b, 0x2563eb,
|
||||
"200mm适配分段B:高165mm+双端公母榫+非对称M4防反装通孔+P01-B ▲ TOP刻字"),
|
||||
("P01_C_立柱上段", "立柱上段(P01-C 标识版)", lambda: p01_c, 0x1d4ed8,
|
||||
"200mm适配分段C:高149mm+底端母榫+非对称M4防反装通孔+顶面P03安装台+P01-C ▲ TOP刻字"),
|
||||
("P02_Center_底座中核心", "底座核心承力座(防呆榫卯版)", lambda: p02_c, 0x475569,
|
||||
"200mm适配中座:195x190mm核心承力座+48mm立柱套筒+前后三角加强筋+前后非对称防呆母榫槽+刻字"),
|
||||
("P02_Front_前向防翻力臂", "前向防翻力臂(P02-FRONT 标识版)", lambda: p02_f, 0xe11d48,
|
||||
"200mm适配前臂:145x190mm扩展力臂+104mm宽跨距双公榫+底部M5预埋螺母沉槽+P02-FRONT刻字"),
|
||||
("P02_Rear_后向防翻力臂", "后向防翻力臂(P02-REAR 标识版)", lambda: p02_r, 0xd97706,
|
||||
"200mm适配后臂:45x190mm扩展力臂+80mm窄跨距双公榫+底部M5预埋螺母沉槽+P02-REAR刻字"),
|
||||
("P03_肩吊臂", "肩关节安装悬臂(高强多肋+前置电机锁紧法兰版)", lambda: p_girdle(j1), 0x4b5563,
|
||||
"高强多肋机架:10mm后置法兰+双侧8mm大三角加强筋+下腹12mm抗弯龙骨筋+前向电机全包托架与前置止脱锁紧法兰(4xM3止脱螺孔)+双侧大散热窗与对流槽"),
|
||||
("P04_肩叉", "肩叉(加长避让顺滑流线版)", lambda: p_fork(j1, j2), 0x2563eb,
|
||||
@@ -929,8 +1136,9 @@ def build():
|
||||
"V2圆角:外轮廓R=3mm,法兰面倒角2mm"),
|
||||
]
|
||||
|
||||
total_parts = len(parts_to_build)
|
||||
for idx, (name, cn, fn, color, note) in enumerate(parts_to_build, 1):
|
||||
print(f" [{idx}/9] 正在构建 {name} ({cn})...", end="", flush=True)
|
||||
print(f" [{idx}/{total_parts}] 正在构建 {name} ({cn})...", end="", flush=True)
|
||||
t0 = time.time()
|
||||
sh = fn()
|
||||
dt = time.time() - t0
|
||||
@@ -955,15 +1163,30 @@ SEP = 74.0
|
||||
|
||||
|
||||
def explode_chain(p, JS, cents, gmean):
|
||||
"""爆炸图偏移:每个链接关节链逐级下移,电机沿自身轴拉出"""
|
||||
"""爆炸图偏移:立柱垂直阶梯拉开,底座前后防呆拉开,电机沿轴拉出,机械臂整体随上段分离"""
|
||||
nm = p["name"]
|
||||
if nm == "P01_A_立柱下段":
|
||||
return [0.0, 0.0, 0.0]
|
||||
if nm == "P01_B_立柱中段":
|
||||
return [0.0, 0.0, 60.0]
|
||||
if nm == "P01_C_立柱上段":
|
||||
return [0.0, 0.0, 120.0]
|
||||
if nm == "P02_Center_底座中核心":
|
||||
return [0.0, 0.0, 0.0]
|
||||
if nm == "P02_Front_前向防翻力臂":
|
||||
return [65.0, 0.0, 0.0]
|
||||
if nm == "P02_Rear_后向防翻力臂":
|
||||
return [-65.0, 0.0, 0.0]
|
||||
if nm == "P03_肩吊臂":
|
||||
return [0.0, 0.0, 120.0]
|
||||
|
||||
grp = AB.GRP.get(p["name"], "root")
|
||||
if grp == "root":
|
||||
return [0.0, 0.0, 0.0]
|
||||
k = CHAIN.index(grp)
|
||||
off = [0.0, 0.0, -SEP * k]
|
||||
off = [0.0, 0.0, 120.0 - SEP * k]
|
||||
j = JS.get(grp)
|
||||
if j:
|
||||
nm = p["name"]
|
||||
w = 0.0
|
||||
if "半联轴器" in nm or "抱箍" in nm:
|
||||
w = 34.0 * (1.0 if ("A" in nm[-1:]) else -1.0)
|
||||
@@ -982,14 +1205,15 @@ if __name__ == "__main__":
|
||||
print("=" * 80, flush=True)
|
||||
bad = 0
|
||||
printed_list = [p for p in PARTS if p["printed"]]
|
||||
total_pr = len(printed_list)
|
||||
for idx, p in enumerate(printed_list, 1):
|
||||
n = len(solids_of(p["shape"]))
|
||||
if n != 1:
|
||||
bad += 1
|
||||
status = "单实体 ✓" if n == 1 else f"异常 ({n} 个实体) ❌"
|
||||
print(f" [{idx}/9] {p['name']:<14} : 体积 {p['vol']/1000.0:6.1f} cm³ | {status}", flush=True)
|
||||
print(f" [{idx}/{total_pr}] {p['name']:<14} : 体积 {p['vol']/1000.0:6.1f} cm³ | {status}", flush=True)
|
||||
if bad == 0:
|
||||
print("-> 单实体检查全部通过!9/9 构件均为完美单一流形拓扑 ✓\n", flush=True)
|
||||
print(f"-> 单实体检查全部通过!{total_pr}/{total_pr} 构件均为完美单一流形拓扑 ✓\n", flush=True)
|
||||
else:
|
||||
print(f"-> 发现 {bad} 个非单实体构件!\n", flush=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user