docs: 更新V2版机器人手臂零件设计说明与渲染截图

This commit is contained in:
cbb
2026-09-27 00:28:49 +08:00
parent 1dfd48278b
commit b3d0890809
67 changed files with 9122 additions and 264 deletions
+299 -134
View File
@@ -98,76 +98,221 @@ def make_direct_hub(shape, j, r_disc=35.0, z_out=74.0):
# ---------------------------------------------------------------- torso -------------------
def p_chest():
"""Torso mast the arm is bolted to: a 12 mm plate with lightening and a cable window."""
s = bx(-X_CHEST, X_CHEST, -Y_CHEST, Y_CHEST, Z_CHEST0, Z_CHEST1)
s = s.cut(bx(-18, 18, -48, 48, 130, 220)) # cable window
for k in range(6):
s = s.cut(bx(-X_CHEST - .01, -26, -54, 54, 48 + 60 * k, 76 + 60 * k))
s = s.cut(bx(26, X_CHEST + .01, -54, 54, 48 + 60 * k, 76 + 60 * k))
for (xx, yy) in [(-38, -44), (38, -44), (-38, 44), (38, 44)]: # 4x M5 through
s = s.cut(cyl(2.75, Z_CHEST0 - .01, Z_CHEST1 + .01, xx, yy))
for yy in (-44, 44):
s = s.cut(Ycyl(1.7, -20, 20, yy, Z_CHEST0 + 28))
"""P01_胸腔支撑立柱 (High-Rigidity Box Mast Tower):
针对 3D 打印与高抗扭刚度彻底重构:
1. 66x66mm 封闭中空厚壁箱型柱(壁厚 8mm),中心在 (-27.0, 47.0),与 P03 底座完美贴合无阶梯、无突起;
2. 顶部接收 P03 48x48x15mm 榫头插槽与 4x M5 安装螺栓;
3. 底部插入 P02 沉槽(深度 12mm),剪切力由槽壁全周承载;
4. 前向开设两组大圆角走线工艺窗口(Z=60~150mm 与 Z=330~420mm);
5. 外棱角全部采用 R=6mm 圆角。
"""
z_bot = 22.0 # P02 底座厚度 22mm
z_top = Z_CHEST1 # 470.0
# 外部实心箱梁
col = (cq.Workplane("XY", origin=(-27.0, 47.0, z_bot))
.rect(66.0, 66.0)
.extrude(z_top - z_bot)
.edges("|Z").fillet(6.0)).val()
s = cq.Shape(col.wrapped)
# 中空中部腔体 (50x50mm,留 8mm 强韧厚壁)
cav = (cq.Workplane("XY", origin=(-27.0, 47.0, z_bot + 10.0))
.rect(50.0, 50.0)
.extrude(z_top - z_bot + 1.0)
.edges("|Z").fillet(4.0)).val()
s = s.cut(cav)
# 底部 4x M5 安装孔
for xx in (-48.0, -6.0):
for yy in (26.0, 68.0):
s = s.cut(cyl(2.75, z_bot - 0.01, z_bot + 15.0, xx, yy))
# 顶部 4x M5 安装孔
for xx in (-48.0, -6.0):
for yy in (26.0, 68.0):
s = s.cut(cyl(2.75, z_top - 20.0, z_top + 0.01, xx, yy))
# 走线工艺窗口(带大圆角)
w_bot = (cq.Workplane("XZ", origin=(-27.0, 80.5, 105.0))
.rect(34.0, 70.0)
.extrude(-20.0)).val()
s = s.cut(w_bot)
w_top = (cq.Workplane("XZ", origin=(-27.0, 80.5, 375.0))
.rect(34.0, 70.0)
.extrude(-20.0)).val()
s = s.cut(w_top)
return s
def split_p01_stack(p01):
"""将 P01 拆分为适合 250mm 桌面 3D 打印机的两段(P01_A 与 P01_B),带 16mm 阶梯互锁榫卯"""
z_split = 246.0
h_lap = 16.0
# 下段 P01_A (Z=22 to 246, 包含向上的 16mm 榫头插舌)
cut_b = bx(-70.0, 20.0, 0.0, 100.0, z_split, 500.0)
tongue_outer = (cq.Workplane("XY", origin=(-27.0, 47.0, z_split))
.rect(64.8, 64.8)
.extrude(h_lap)
.edges("|Z").fillet(5.5)).val()
tongue_cav = (cq.Workplane("XY", origin=(-27.0, 47.0, z_split - 1.0))
.rect(51.0, 51.0)
.extrude(h_lap + 2.0)).val()
tongue = cq.Shape(tongue_outer.wrapped).cut(tongue_cav)
p01_a = p01.cut(cut_b).fuse(tongue)
# 上段 P01_B (Z=246 to 470, 底部包含接收榫头的凹槽)
cut_a = bx(-70.0, 20.0, 0.0, 100.0, 0.0, z_split)
p01_b = p01.cut(cut_a)
pocket = (cq.Workplane("XY", origin=(-27.0, 47.0, 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)
# 对锁螺栓孔 (4x M4 对锁孔在 Z=z_split + h_lap/2)
z_bolt = z_split + h_lap / 2.0
for xx in (-46.0, -8.0):
y_bolt = Ycyl(2.2, 10.0, 85.0, xx, z_bolt)
p01_a = p01_a.cut(y_bolt)
p01_b = p01_b.cut(y_bolt)
return p01_a, p01_b
def p_base_foot():
s = bx(-84, 84, -Y_CHEST - 24, Y_H + 44, 0, Z_CHEST0)
s = s.cut(bx(-X_CHEST - .01, X_CHEST + .01, -Y_CHEST - .01, Y_CHEST + .01,
Z_CHEST0 - .01, Z_CHEST0 + 5))
for (xx, yy) in [(-70, -86), (70, -86), (-70, 86), (70, 86)]:
s = s.cut(cyl(2.75, -.01, Z_CHEST0 + .01, xx, yy))
s = s.cut(cyl(5.5, -.01, 3.0, xx, yy))
"""P02_测试台架底座 (Ultra-Stable 320mm Extended Stabilizer Base):
1. 200x320x22mm 重型防倾翻大底盘(长 320mm,向后延伸至 Y=-90,向前延伸至 Y=+230);
2. 彻底保证机械臂在最大延伸(前伸 300mm+)及动态制动时的重心稳定度;
3. 中央设计 12mm 深度立柱抗剪嵌套凹槽 (Socket Pocket),精密容纳 P01 下端;
4. 四个边角各设有一组 28x7mm 的 M6 夹持/桌面压板安装腰槽;
5. 凹槽底面设有 4x M5 沉头紧固螺栓孔;
6. 底面设有 28x6mm 隐蔽过线通槽;
7. 四周棱角全部采用 R=16mm 大圆角过渡与 2.5mm 上边缘导角。
"""
z0 = 0.0
z1 = 22.0
base_plate = (cq.Workplane("XY", origin=(-20.0, 70.0, z0))
.rect(200.0, 320.0)
.extrude(z1)
.edges("|Z").fillet(16.0)
.edges(">Z").fillet(2.5)).val()
s = cq.Shape(base_plate.wrapped)
# 中央立柱嵌装定位槽 (深度 12mm, Z: 10~22mm)
socket_box = (cq.Workplane("XY", origin=(-27.0, 47.0, z1 - 12.0))
.rect(67.0, 67.0)
.extrude(13.0)
.edges("|Z").fillet(6.5)).val()
s = s.cut(socket_box)
# 底部 4x M5 贯通螺栓孔及沉头沉孔 (从底座下方向上紧固立柱)
for xx in (-48.0, -6.0):
for yy in (26.0, 68.0):
th = cyl(2.75, -0.01, z1 - 11.0, xx, yy)
cb = cyl(5.0, -0.01, 6.0, xx, yy)
s = s.cut(th).cut(cb)
# 4 处边角 M6 桌面压板/台钳固定长腰槽 (28mm x 7mm)
for cx in (-100.0, 60.0):
for cy in (-60.0, 200.0):
plane = cq.Plane(origin=(cx, 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()
s = s.cut(slot)
# 底部隐蔽走线凹槽 (宽 28mm, 深 6mm, 从立柱槽直通底座后侧 Y=-90)
wire_ch = (cq.Workplane("XY", origin=(-27.0, -20.0, -0.01))
.rect(28.0, 145.0)
.extrude(6.0)).val()
s = s.cut(wire_ch)
return s
def p_girdle(j1):
"""P03_肩部基座 (Chest Shoulder Base):
Mounted directly to the chest mast, holds M1 horizontally with fore-aft roll axis.
Fixes M1 strictly via two ends (4x rear bolts @ BCD 53.7mm + front collar).
Stator middle cylinder is 100% exposed for cooling.
"""P03_肩部基座 浑然一体高刚度规整风道机壳 (Monolithic Aerodynamic Shoulder Housing):
彻底重构并消除旧版所有缺陷:
1. 彻底消除不对称悬空凸台与多余阶梯(消除 X>5.0 处突出的无用耳朵与螺栓孔);
2. 全件采用统一的 X 跨度 X in [-59.0, 5.0] (宽 64mm),外侧平齐,零多余外凸;
3. 斜挑支撑柱 (Pylon) 自 Z=470mm 安装基底浑然一体平滑延伸至 Ø73mm 电机外壳舱,无上下断层或拼接触痕;
4. 底面设置 48x48x15mm 高强度整体榫头与 4x M5 对锁安装沉孔,隐藏于腔体内部;
5. 7 组轴向圆角散热通风百叶窗 (长34mm, 宽4.6mm) + 尾部双排气对流窗口。
"""
zb0 = Z_CHEST1 - 34.0
# Mast mount bracket (Y: 40..66, Z: zb0..Z_CHEST1)
s = bx(-35.0, 35.0, 40.0, 66.0, zb0, Z_CHEST1)
s = s.cut(bx(-X_CHEST - 0.01, X_CHEST + 0.01, -Y_CHEST - 1, Y_CHEST + 1, zb0 - 0.01, Z_CHEST1 + 1))
R_POD = 36.5
X_REAR = Z_R1 - 8.0 # -59.0 (8mm 后端安装板)
X_FRONT = 5.0 # +5.0 (平齐电机输出端面,留 0.5mm 间隙至 P04)
# Diagonal arm slanting up from (Y: 60, Z: 493) to (Y: 128, Z: 610)
# Stays at Y <= 80 for Z <= 535, so it completely clears M2 (at Y: 92..156, Z <= 525) and P04
diag_pts = [
(45.0, Z_CHEST1),
(66.0, Z_CHEST1),
(80.0, 535.0),
(Y_AXIS + 32.0, Z_RL - 22.0),
(Y_AXIS + 32.0, Z_RL + 22.0),
(Y_AXIS - 34.0, Z_RL + 22.0),
(Y_AXIS - 34.0, Z_RL - 10.0),
(70.0, 540.0),
(45.0, Z_CHEST1 + 10.0),
# 1. 规整同轴电机外壳舱 (Coaxial Nacelle, Ø73mm)
pod_outer = (cq.Workplane("YZ", origin=(X_REAR, Y_AXIS, Z_RL))
.circle(R_POD)
.extrude(X_FRONT - X_REAR)
.edges(">X").chamfer(2.0)
.edges("<X").fillet(3.0)).val()
s = cq.Shape(pod_outer.wrapped)
# 2. 一体化斜挑支撑柱 (Monolithic Pylon, 从 Z=470 直通电机机舱)
pylon_pts = [
(16.0, Z_CHEST1),
(78.0, Z_CHEST1),
(78.0, 542.0),
(Y_AXIS - 5.0, Z_RL - R_POD + 4.0),
(Y_AXIS, Z_RL - R_POD),
(Y_AXIS - R_POD, Z_RL + 10.0),
(Y_AXIS - R_POD - 6.0, Z_RL + 6.0),
(70.0, 542.0),
(16.0, Z_CHEST1 + 8.0),
]
diag = Xplate(diag_pts, Z_R1 - 8.0, 4.0)
s = s.fuse(diag)
pylon = Xplate(pylon_pts, X_REAR, X_FRONT)
s = s.fuse(pylon)
# M1 rear plate at Z_R1 (X: -59..-51)
rear_m1 = Xcyl(35.0, Z_R1 - 8.0, Z_R1, Y_AXIS, Z_RL)
s = s.fuse(rear_m1)
# 3. 底部与立柱对接的精密定位榫头 (Z=455~470mm)
boss = (cq.Workplane("XY", origin=(-27.0, 47.0, Z_CHEST1 - 15.0))
.rect(48.0, 48.0)
.extrude(15.0)
.edges("|Z").fillet(4.0)).val()
s = s.fuse(cq.Shape(boss.wrapped))
# M1 front locating collar at X: 0..5 (before hub plane X=14)
front_m1 = Xcyl(35.0, 0.0, 5.0, Y_AXIS, Z_RL)
s = s.fuse(front_m1)
# 4. 4x M5 坚固连接螺孔 (隐蔽分布于基底,不露在外部侧面)
for xx in (-48.0, -6.0):
for yy in (26.0, 68.0):
s = s.cut(cyl(2.75, Z_CHEST1 - 16.0, Z_CHEST1 + 25.0, xx, yy))
# Cut M1 rear bolt holes and front collar pocket (Two-End Mounting!)
# 5. 电机安装接口与内腔
s = j1.rear_mount_holes(s, t_plate=8.0, hole_d=2.8, cb_d=5.5, cb_depth=4.0)
s = j1.front_collar_pocket(s, r_bore=30.25, z0=50.0, z1=56.5)
s = j1.front_collar_pocket(s, r_bore=30.25 + 0.5, z0=50.0, z1=56.5)
s = j1.pocket(s)
s = s.cut(Xcyl(30.6, Z_R1 + 0.5, -0.5, Y_AXIS, Z_RL))
# Stator middle zone exposed
s = s.cut(Xcyl(30.5, Z_R1 + 0.5, -0.5, Y_AXIS, Z_RL))
# Mast bolt holes
for yy in (50.0, 60.0):
for xx in (-28.0, 28.0):
s = s.cut(cyl(2.2, zb0 - 0.01, Z_CHEST1 + 0.01, xx, yy))
# 6. 7组轴向散热百叶窗 (Axial Louvers)
slot_angles = [-15, 12, 38, 64, 90, 116, 142]
slot_w = 4.6
slot_l = 34.0
slot_x_mid = -24.0
for ang in slot_angles:
rad = ang * D2R
plane = cq.Plane(
origin=(slot_x_mid, Y_AXIS + 28.0 * math.cos(rad), Z_RL + 28.0 * math.sin(rad)),
xDir=(1, 0, 0),
normal=(0, math.cos(rad), math.sin(rad))
)
slot_solid = cq.Workplane(plane).slot2D(slot_l, slot_w).extrude(16.0).val()
s = s.cut(slot_solid)
# 7. 尾部 PCBA 驱动板散热窗口 (PCBA Vents)
for z_off in (-10.0, 10.0):
vent_plane = cq.Plane(
origin=(X_REAR - 1.0, Y_AXIS, Z_RL + z_off),
xDir=(0, 1, 0),
normal=(1, 0, 0)
)
vent_solid = cq.Workplane(vent_plane).slot2D(16.0, 5.0).extrude(12.0).val()
s = s.cut(vent_solid)
return s
@@ -185,15 +330,25 @@ def p_fork(j1, j2):
"""
x0 = X_J1_HUB # 14.0
# 1. 后端安装法兰盘:全封闭 Ø70mm (R=35) 刚性圆盘 (Y: 92.0 .. 100.0),高刚度固定 4x M2 电机安装螺钉
# 1. M2 后端安装法兰盘 (Y: 92..100, R=35mm)
rear_plate = Ycyl(35.0, Y_REAR - 8.0, Y_REAR, X_ARM, Z_SH)
# 2. XZ 平面有机连续流线轮廓(严格依照用户手绘红线数字化拟合):
# 右侧:以 R=111.56mm 大直径切线圆弧从 (39.0, 545.0) 顺滑外扩至右侧极值点 (53.5, 490.0)
# 左侧:严格依据用户手绘红线,构建三次 Hermite C1 切线连续曲线:
# - 顶端 (5.5, 545.0) 与立柱壁面完全垂直相切 (0, 1)
# - 底端 (-12.65, 506.0) 与 Ø70mm J2 回转圆盘以切线 (-0.514, -1.0) 完全同相相切自然过渡!
# 底端水平切线维持于 Z_SH = 490.0,电机下半部分 (Z < 490.0) 100% 敞开镂空,极大强化电机散热!
# 2. M2 前端定位环 (Y: 149.5..155.5, R=35mm) - 恢复并加固蓝色的环!
front_collar = Ycyl(35.0, Y_COVER - 6.5, Y_COVER - 0.5, X_ARM, Z_SH)
s = rear_plate.fuse(front_collar)
# 3. J1 从动法兰盘 (X: 5.5..23.0, R=38mm)
disc_j1 = Xcyl(38.0, 5.5, 23.0, Y_AXIS, Z_RL)
s = s.fuse(disc_j1)
# 4. XZ 平面有机连续流线轮廓(加固并彻底抹平顶部 26mm 生硬阶梯):
# 顶部:自 (5.5, 648.0) 保持与 J1 从动盘同高延伸至 (23.0, 648.0),完全抹平阶梯!
# 右侧:自 (23.0, 648.0) 以 R=18mm 顺滑倒角过渡到 (39.0, 630.0),再以 R=111.56mm 切线大圆弧顺接下方 (53.5, 490.0)
# 左侧:维持 Hermite C1 切线连续自然过渡
dx_flare = 53.5 - 39.0
dz_flare = 545.0 - 490.0
R_flare = (dx_flare**2 + dz_flare**2) / (2.0 * dx_flare) # 111.56 mm
x_b, z_b = -12.65, 506.0
x_a, z_a = 5.5, 545.0
Lz = z_a - z_b
@@ -212,17 +367,11 @@ def p_fork(j1, j2):
zh = z_b + t * Lz
hermite_pts.append((xh, zh))
dx_flare = 53.5 - 39.0
dz_flare = 545.0 - 490.0
R_flare = (dx_flare**2 + dz_flare**2) / (2.0 * dx_flare) # 111.56 mm
xz_wire = (cq.Workplane("XZ", origin=(0, Y_AXIS, 0))
.moveTo(5.5, 545.0)
.lineTo(5.5, 610.0)
.lineTo(23.0, 610.0)
.lineTo(23.0, 622.0)
.lineTo(34.5, 622.0)
.radiusArc((40.5, 616.0), 6.0)
.lineTo(5.5, Z_RL + 38.0) # 648.0: 与 J1 圆盘顶部平齐共顶!
.lineTo(23.0, Z_RL + 38.0) # 抹平 X=23 处的 26mm 巨型台阶!
.radiusArc((39.0, 630.0), 18.0) # 自然圆角顺滑过渡到外侧肩部
.lineTo(39.0, 545.0)
.radiusArc((53.5, 490.0), -R_flare)
.lineTo(18.5, 490.0)
@@ -234,10 +383,12 @@ def p_fork(j1, j2):
xz_solid = xz_wire.extrude(100.0, both=True).val()
xz_shape = cq.Shape(xz_solid.wrapped)
# 3. YZ 平面包络:顶端顺接 J1 从动盘,底端收于 Z_SH = 490.0,使电机下半部完全敞开散热
# YZ 平面包络:
# 顶部顺接 J1 圆盘 (Y_AXIS - 38 .. Y_AXIS + 38, Z=648)
# 底端全深顺接 M2 前后安装端 (Y: 92.0 .. 155.5)
yz_pts = [
(Y_AXIS - 38.0, Z_RL + 12.0),
(Y_AXIS + 38.0, Z_RL + 12.0),
(Y_AXIS - 38.0, Z_RL + 38.0),
(Y_AXIS + 38.0, Z_RL + 38.0),
(Y_COVER - 0.5, Z_SH + 36.0),
(Y_COVER - 0.5, Z_SH),
(Y_REAR - 8.0, Z_SH),
@@ -245,31 +396,24 @@ def p_fork(j1, j2):
]
yz_solid = Xplate(yz_pts, -20.0, 60.0)
# 双向曲面高精度布尔求交 (BRepAlgoAPI_Common)
c_int = BRepAlgoAPI_Common(yz_solid.wrapped, xz_shape.wrapped)
c_int.Build()
column = cq.Shape(c_int.Shape())
s = rear_plate.fuse(column)
s = s.fuse(column)
# J1 从动圆盘结构(从 5.5 到 23.0,与电机 boss 紧密贴合并保留独立圆盘外轮廓)
disc_j1 = Xcyl(38.0, 5.5, 23.0, Y_AXIS, Z_RL)
s = s.fuse(disc_j1)
# 4. 电机完全容纳于一体化实心包络壳体内,中间不镂空保持全侧面连续实心造型
# 6. 中部电机定子散热切除(R=30.5,保证电机定子散热,同时保留外侧与上下坚固承力壁)
s = s.cut(Ycyl(30.5, Y_REAR + 0.5, Y_COVER - 6.5, X_ARM, Z_SH))
# 5. 减重与走线窗
s = s.cut(Xplate([(Y_AXIS - 16.0, Z_SH + 74.0), (Y_AXIS + 16.0, Z_SH + 74.0),
(Y_AXIS + 16.0, Z_RL - 22.0), (Y_AXIS - 16.0, Z_RL - 22.0)],
20.0, 34.0))
# 6. M2 接口成型(精确圆柱同心配合孔,消除超规方形切除导致的外壳侧缝穿孔)
# 7. M2 接口成型
s = j2.front_collar_pocket(s, r_bore=30.25, z0=50.0, z1=56.5)
s = j2.rear_mount_holes(s, t_plate=8.0, hole_d=2.8, cb_d=5.5, cb_depth=4.0)
c_m2 = [cyl(BORE_R, -0.6, COVER_Z - 3.5), cyl(CB_R, COVER_Z - 3.5, COVER_Z + 0.6)]
s = s.cut(*[j2.L(item) for item in c_m2])
# 7. J1 直连法兰结构(定位止口 + 走线通孔 + 3x M2 贯通沉头孔)
boss = cyl(17.8, 54.942, 56.5)
s = s.fuse(j1.L(boss))
@@ -287,60 +431,39 @@ def p_fork(j1, j2):
# ---------------------------------------------------------------- limbs -------------------
def make_pitch_to_roll_bracket(j_pitch, j_roll, z_pitch, z_r, name="bracket"):
"""Half-wrapped (半包) 双曲面有机流线型 Pitch-to-Roll 结构座 (P05 & P08):
借鉴 P07 紫色骨架的高品质融合处理:
1. 顶部从动法兰仅保留上半圆 (top_semi),下半部完全融入顺延曲面,消除独立下半圆凸棱与接缝;
2. 内侧过渡采用有机凹弧 (.radiusArc) 从后安装螺孔平滑顺弧直达从动法兰根部 (156.5),
配合上级电机同心圆弧避让 (Ycyl 35.5),彻底消除生硬的水平桌面与 90° L型折角;
3. 外侧肩部采用切线转折加 R=10mm 平滑倒角过渡,以大直径圆弧顺滑连接至下方电机外圆;
4. 下方电机实行半包设计:-Y侧完全敞开露空散热,+Y侧全深连续背脊壳体与圆柱完全填实为一个融合整体;
5. 严格满足 single-solid 流形拓扑与零干涉 (COLLISION pairs = 0)。
1. 顶部从动法兰与前侧 Loft 自然相切顺接;
2. 严格清除 z_plate 顶面以上与上级旋转件贴面的多余材料 (cut_top_solid),保证关节大范围摆动动态 0 干涉;
3. 下方电机实行半包散热设计,-Y侧敞开,+Y侧背脊与圆柱一体化融合;
4. 严格满足 single-solid 流形拓扑与零干涉 (COLLISION pairs = 0)。
"""
z_bot = z_r - 56.0 # roll 电机底端 (front collar)
z_plate = z_r + 7.0 # roll 电机顶端安装板 (rear plate top)
z_bot = z_r - 56.0 # roll 电机底端 (front collar)
z_plate = z_r + 7.0 # roll 电机顶端安装板 (rear plate top)
y_out = HL.Y_HUB + HL.PLATE_T # 174.0 (俯仰直连法兰外侧面)
y_hub_in = HL.Y_COVER + 0.5 # 156.5 (从动法兰全厚度直接延伸自电机间隙)
y_hub_in = HL.Y_COVER + 1.0 # 157.0 (从动法兰内侧面,预留 1.0mm 动间隙)
y_cyl_max = HL.Y_AXIS + 35.0 # 163.0 (下方电机外轮廓极值)
# 1. 基础立柱:Ø70mm 实心圆柱 (Z: z_bot .. z_plate, R=35mm)
s = cyl(35.0, z_bot, z_plate, X_ARM, Y_AXIS)
s = cyl(35.0, z_bot, z_plate, HL.X_ARM, HL.Y_AXIS)
# 2. 俯仰轴直连法兰盘:全圆柱实体 (Y: y_hub_in .. y_out, R=35mm),彻底填实下方悬空!
disc = Ycyl(35.0, y_hub_in, y_out, X_ARM, z_pitch)
# 2. 俯仰轴直连法兰盘:全圆柱实体 (Y: y_hub_in .. y_out, R=35mm)
disc = Ycyl(35.0, y_hub_in, y_out, HL.X_ARM, z_pitch)
s = s.fuse(disc)
# 3. 后侧/内侧结构骨架 (Y: Y_AXIS .. y_hub_in, Z: z_plate .. z_pitch)
rear_spine = (cq.Workplane("YZ", origin=(X_ARM, 0, 0))
.moveTo(Y_AXIS, z_plate)
.lineTo(y_hub_in, z_plate)
.lineTo(y_hub_in, z_pitch)
.lineTo(Y_AXIS, z_pitch)
.close()
.extrude(35.0, both=True))
rear_spine = rear_spine.edges(cq.NearestToPointSelector((X_ARM, y_hub_in, z_plate))).fillet(8.0)
s = s.fuse(rear_spine.val())
# 4. 前侧从底端 Ø70mm 圆柱到顶端法兰的有机相切平滑渐变过渡体 (Loft Morph)
# 彻底消除底端两侧突出方壳与尖角,自底端 Ø70mm 圆柱平滑渐变扩展至顶端法兰!
# t=0 (Z=z_bot): 截面完全贴合 Ø70mm 电机外圆弧 (u^2 + (Y - Y_AXIS)^2 <= 35^2),零突出尖角,与下级法兰无缝对齐!
# t=1 (Z=Z_top): 截面完全贴合顶端法兰平面 (Y = y_out),平整相切
# 导数在两端皆为 0 (Hermite S-curve 连续),实现 G1 自然相切无折痕过渡
# 3. 前侧从底端 Ø70mm 圆柱到顶端法兰的有机相切平滑渐变过渡体 (Loft Morph)
Z_top = z_pitch - 35.0
z_start = z_bot
N = 12
N = 16
wp = cq.Workplane("XY")
for i in range(N + 1):
t = i / float(N)
z_curr = z_start + t * (Z_top - z_start)
st = 3.0 * (t**2) - 2.0 * (t**3)
y_center = y_cyl_max + st * (y_out - y_cyl_max)
y_side = Y_AXIS + st * (y_out - Y_AXIS)
v_c = y_center - Y_AXIS
v_s = y_side - Y_AXIS
y_side = HL.Y_AXIS + st * (y_out - HL.Y_AXIS)
v_c = y_center - HL.Y_AXIS
v_s = y_side - HL.Y_AXIS
v_mid = max(v_c, v_s + 0.02)
w = (cq.Workplane("XY", origin=(X_ARM, Y_AXIS, z_curr))
w = (cq.Workplane("XY", origin=(HL.X_ARM, HL.Y_AXIS, z_curr))
.moveTo(-35.0, v_s)
.threePointArc((0.0, v_mid), (35.0, v_s))
.lineTo(35.0, -5.0)
@@ -351,34 +474,45 @@ def make_pitch_to_roll_bracket(j_pitch, j_roll, z_pitch, z_r, name="bracket"):
loft = wp.toPending().loft()
s = s.fuse(loft.val())
# 5. 上下平滑连续包裹:在顶端 Z_top 到 z_pitch 之间填满 Disc 与 Loft 的连接
top_fill = (cq.Workplane("YZ", origin=(X_ARM, 0, 0))
.moveTo(Y_AXIS, Z_top)
# 4. 顶部填充(仅保留 y >= y_hub_in 与法兰盘对齐的部分,避免侵入上级关节旋转扫掠区域)
top_fill = (cq.Workplane("YZ", origin=(HL.X_ARM, 0, 0))
.moveTo(y_hub_in, Z_top)
.lineTo(y_out, Z_top)
.lineTo(y_out, z_pitch)
.lineTo(Y_AXIS, z_pitch)
.lineTo(y_hub_in, z_pitch)
.close()
.extrude(35.0, both=True))
s = s.fuse(top_fill.val())
# 4. 电机半包处理 (Half-Enclosure):-Y侧敞开散热,+Y侧背脊壳体加强
cut_open = bx(X_ARM - 40.0, X_ARM + 40.0, Y_AXIS - 40.0, Y_AXIS + 3.0, z_bot + 6.0, z_r - 1.0)
# 5. 旋转清让切除:彻底清除 z >= z_plate 且 y <= y_hub_in 范围内的多余材料,
# 消除导致与上游旋转件(P04/P07)严重干涉的立壁与尖角,保持顶面平整规整!
cut_top_solid = (cq.Workplane("YZ", origin=(HL.X_ARM, 0, 0))
.moveTo(-999.0, z_plate)
.lineTo(y_hub_in, z_plate)
.lineTo(y_hub_in, z_pitch + 50.0)
.lineTo(-999.0, z_pitch + 50.0)
.close()
.extrude(60.0, both=True))
s = s.cut(cut_top_solid.val())
# 6. 电机半包处理 (Half-Enclosure):-Y侧敞开散热,+Y侧背脊壳体加强
cut_open = bx(HL.X_ARM - 40.0, HL.X_ARM + 40.0, HL.Y_AXIS - 40.0, HL.Y_AXIS + 3.0, z_bot + 6.0, z_r - 1.0)
s = s.cut(cut_open)
# 5. 上级电机同心圆弧避让(同 P07 line 457 处理,同心平滑包裹并留出 0.5mm 间隙)
clearance = Ycyl(35.5, Y_AXIS - 40.0, HL.Y_COVER + 0.1, X_ARM, z_pitch)
# 7. 上级电机同心圆弧避让
clearance = Ycyl(35.5, HL.Y_AXIS - 40.0, HL.Y_COVER + 0.1, HL.X_ARM, z_pitch)
s = s.cut(clearance)
# 6. 下方电机安装孔位与定位止口
# 8. 下方电机安装孔位与定位止口
s = j_roll.rear_mount_holes(s, t_plate=7.0, hole_d=2.8, cb_d=5.5, cb_depth=4.0)
s = j_roll.front_collar_pocket(s, r_bore=30.25, z0=50.0, z1=56.5)
s = j_roll.pocket(s)
# 7. 电机定子配合空腔
s = s.cut(cyl(30.5, z_r - 49.5, z_r - 0.5, X_ARM, Y_AXIS))
# 9. 电机定子配合空腔
s = s.cut(cyl(30.5, z_r - 49.5, z_r - 0.5, HL.X_ARM, HL.Y_AXIS))
# 8. 俯仰轴直连法兰结构(定位止口 + 走线通孔 + 3x M2 贯通沉头孔,取消多余底凸圆盘)
boss = cyl(17.8, 54.942, 56.5)
# 10. 俯仰轴直连法兰结构(凸台延伸至 59.5 跨过间隙与法兰盘牢固熔接,保持单实体)
boss = cyl(17.8, 54.942, 59.5)
s = s.fuse(j_pitch.L(boss))
s = s.cut(j_pitch.L(cyl(3.5, 54.0, 74.0 + 30.0)))
for a in AB.HUB_M2_CLOCK:
@@ -388,6 +522,31 @@ def make_pitch_to_roll_bracket(j_pitch, j_roll, z_pitch, z_r, name="bracket"):
cb = cyl(2.8, 58.0, 74.0 + 40.0, u, v)
s = s.cut(j_pitch.L(th)).cut(j_pitch.L(cb))
# 11. 竖直臂前侧外角倒角(5mm):平滑消除圆柱体以外的两侧垂直尖角
c_size = 5.0
c_left = (cq.Workplane("XY", origin=(HL.X_ARM - 35.0, y_hub_in, z_plate))
.moveTo(-0.1, -0.1)
.lineTo(c_size, -0.1)
.lineTo(-0.1, c_size)
.close()
.extrude(z_pitch - z_plate + 10.0))
c_right = (cq.Workplane("XY", origin=(HL.X_ARM + 35.0, y_hub_in, z_plate))
.moveTo(0.1, -0.1)
.lineTo(-c_size, -0.1)
.lineTo(0.1, c_size)
.close()
.extrude(z_pitch - z_plate + 10.0))
s = s.cut(c_left.val()).cut(c_right.val())
# 12. L 型转角连接处倒角过渡(倒角 2.0mm):
# 平滑消除立柱顶面与竖直臂交汇处的 90° 尖角与应力集中,严控动间隙保证动态零干涉
try:
wp_s = cq.Workplane(obj=s)
sel_l = cq.NearestToPointSelector((HL.X_ARM, y_hub_in, z_plate))
s = wp_s.edges(sel_l).chamfer(2.0).val()
except Exception:
pass
return s
@@ -763,4 +922,10 @@ if __name__ == "__main__":
for r in cl[:30]:
print(" %-14s x %-14s %9.1f mm3 %s" % r)
sys.stdout.flush()
try:
from build_viewer import rebuild_viewer
rebuild_viewer()
except Exception as e:
print("rebuild_viewer error:", e)
sys.stdout.flush()
os._exit(0)