docs: 更新BOM清单与渲染图,适配200mm分段式立柱和防呆底座设计

This commit is contained in:
cbb
2026-09-27 17:21:50 +08:00
parent 38fd3e823c
commit b11814410a
53 changed files with 927 additions and 82 deletions
+55 -15
View File
@@ -1,23 +1,63 @@
[
{
"件号": "P01_胸板",
"名称": "胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗)",
"件号": "P01_A_立柱下段",
"名称": "立柱下段(P01-A 标识版)",
"类型": "3D打印",
"数量": 1,
"体积cm3": 809.6,
"质量g_PLA": 1003.9,
"包络": "[-148.0 95.0 22.0 .. -82.0 161.0 470.0] (66.0x66.0x448.0)",
"说明": "V2高刚度立柱:66x66mm厚壁封闭箱梁+8mm壁厚+顶部P03榫卯台座+两组大圆角工艺走线窗"
"体积cm3": 305.1,
"质量g_PLA": 378.3,
"包络": "[-148.0 95.0 22.0 .. -82.0 161.0 188.0] (66.0x66.0x166.0)",
"说明": "200mm适配分段A:高166mm+16mm阶梯公榫+非对称M4防反装通孔+P01-A ▲ TOP刻字"
},
{
"件号": "P02_底脚",
"名称": "测试台架底座(重型防倾翻超长力臂+双向三角斜撑版)",
"件号": "P01_B_立柱中段",
"名称": "立柱中段(P01-B 标识版)",
"类型": "3D打印",
"数量": 1,
"体积cm3": 2122.9,
"质量g_PLA": 2632.4,
"包络": "[-241.5 6.5 -0.0 .. 146.5 249.5 70.0] (388.0x243.0x70.0)",
"说明": "防倾翻超大底盘:385x240mm超长力臂+48mm立柱套筒+前后双向大三角抗倾翻斜撑筋+走线导槽+6xM6固定槽"
"体积cm3": 269.3,
"质量g_PLA": 333.9,
"包络": "[-148.0 95.0 172.0 .. -82.0 161.0 337.0] (66.0x66.0x165.0)",
"说明": "200mm适配分段B:高165mm+双端公母榫+非对称M4防反装通孔+P01-B ▲ TOP刻字"
},
{
"件号": "P01_C_立柱上段",
"名称": "立柱上段(P01-C 标识版)",
"类型": "3D打印",
"数量": 1,
"体积cm3": 225.8,
"质量g_PLA": 280.0,
"包络": "[-148.0 95.0 321.0 .. -82.0 161.0 470.0] (66.0x66.0x149.0)",
"说明": "200mm适配分段C:高149mm+底端母榫+非对称M4防反装通孔+顶面P03安装台+P01-C ▲ TOP刻字"
},
{
"件号": "P02_Center_底座中核心",
"名称": "底座核心承力座(防呆榫卯版)",
"类型": "3D打印",
"数量": 1,
"体积cm3": 867.6,
"质量g_PLA": 1075.8,
"包络": "[-195.7 32.3 -0.0 .. 0.7 223.7 70.0] (196.3x191.3x70.0)",
"说明": "200mm适配中座:195x190mm核心承力座+48mm立柱套筒+前后三角加强筋+前后非对称防呆母榫槽+刻字"
},
{
"件号": "P02_Front_前向防翻力臂",
"名称": "前向防翻力臂(P02-FRONT 标识版)",
"类型": "3D打印",
"数量": 1,
"体积cm3": 613.5,
"质量g_PLA": 760.7,
"包络": "[-19.5 31.7 -0.0 .. 146.3 224.3 22.0] (165.8x192.6x22.0)",
"说明": "200mm适配前臂:145x190mm扩展力臂+104mm宽跨距双公榫+底部M5预埋螺母沉槽+P02-FRONT刻字"
},
{
"件号": "P02_Rear_后向防翻力臂",
"名称": "后向防翻力臂(P02-REAR 标识版)",
"类型": "3D打印",
"数量": 1,
"体积cm3": 190.4,
"质量g_PLA": 236.1,
"包络": "[-241.3 31.7 -0.0 .. -175.5 224.3 22.0] (65.8x192.6x22.0)",
"说明": "200mm适配后臂:45x190mm扩展力臂+80mm窄跨距双公榫+底部M5预埋螺母沉槽+P02-REAR刻字"
},
{
"件号": "P03_肩吊臂",
@@ -64,9 +104,9 @@
"名称": "小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块)",
"类型": "3D打印",
"数量": 1,
"体积cm3": 173.6,
"质量g_PLA": 215.3,
"包络": "[-16.5 92.0 187.0 .. 53.5 174.0 367.0] (70.0x82.0x180.0)",
"体积cm3": 208.5,
"质量g_PLA": 258.6,
"包络": "[-19.4 92.0 187.0 .. 56.4 174.0 369.9] (75.8x82.0x182.9)",
"说明": "V2 L型结构:+Y侧背脊立柱避让大臂骨架,过渡区采用与顶面和立柱双相切的R=28mm平滑内凹大圆弧,彻底消除直斜线折角与悬空阶梯小块,下方M5电机半包散热,俯仰大范围自由运动零干涉"
},
{
+141
View File
@@ -0,0 +1,141 @@
==============================================================================
全对全动态行程扫描 v2 并行版(workers=12 / 可用内存 76GB / 轴=human_layout / 含相邻对与电机 / GJK预筛=开)
==============================================================================
================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)...================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)...================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)...================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)...================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)...================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)...================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)...================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)...================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)...================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)...================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)...================================================================================
【第一阶段 1/5】开始生成手臂各级构件 3D 几何实体模型...
================================================================================
[0/9] 载入电机标准件模组 (STEP)... 完成 (1.12s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 (1.18s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 (1.13s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 (1.12s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 (1.11s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 (1.15s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 (1.12s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 ✓ (0.11s | 体积: 809.6 cm³ | 实体数: 1)
[2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... 完成 (1.16s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 (1.18s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 (1.16s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 ✓ (0.11s | 体积: 809.6 cm³ | 实体数: 1)
[2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... 完成 ✓ (0.11s | 体积: 809.6 cm³ | 实体数: 1)
完成 ✓ (0.11s | 体积: 809.6 cm³ | 实体数: 1)
[2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... [2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... 完成 ✓ (0.11s | 体积: 809.6 cm³ | 实体数: 1)
[2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... 完成 (1.16s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 (1.19s) ✓
[1/9] 正在构建 P01_胸板 (胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗))... 完成 ✓ (0.11s | 体积: 809.6 cm³ | 实体数: 1)
[2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... 完成 ✓ (0.12s | 体积: 809.6 cm³ | 实体数: 1)
[2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... 完成 ✓ (0.12s | 体积: 809.6 cm³ | 实体数: 1)
[2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... 完成 ✓ (0.11s | 体积: 809.6 cm³ | 实体数: 1)
[2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... 完成 ✓ (0.11s | 体积: 809.6 cm³ | 实体数: 1)
[2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... 完成 ✓ (0.18s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.12s | 体积: 809.6 cm³ | 实体数: 1)
[2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... 完成 ✓ (0.12s | 体积: 809.6 cm³ | 实体数: 1)
[2/9] 正在构建 P02_底脚 (测试台架底座(高刚度抗倾覆底盘+嵌装定位槽))... 完成 ✓ (0.19s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.19s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.19s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.20s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.19s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.21s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.20s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.20s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.21s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.21s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.20s | 体积: 1166.9 cm³ | 实体数: 1)
[3/9] 正在构建 P03_肩吊臂 (肩关节基座机壳(高刚性规整风道散热版))... 完成 ✓ (0.75s | 体积: 745.3 cm³ | 实体数: 1)
[4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... 完成 ✓ (0.72s | 体积: 745.3 cm³ | 实体数: 1)
完成 ✓ (0.74s | 体积: 745.3 cm³ | 实体数: 1)
完成 ✓ (0.74s | 体积: 745.3 cm³ | 实体数: 1)
[4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... [4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... [4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... 完成 ✓ (0.74s | 体积: 745.3 cm³ | 实体数: 1)
[4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... 完成 ✓ (0.74s | 体积: 745.3 cm³ | 实体数: 1)
[4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... 完成 ✓ (0.75s | 体积: 745.3 cm³ | 实体数: 1)
完成 ✓ (0.73s | 体积: 745.3 cm³ | 实体数: 1)
[4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... [4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... 完成 ✓ (0.73s | 体积: 745.3 cm³ | 实体数: 1)
[4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... 完成 ✓ (0.76s | 体积: 745.3 cm³ | 实体数: 1)
[4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... 完成 ✓ (0.75s | 体积: 745.3 cm³ | 实体数: 1)
完成 ✓ (0.75s | 体积: 745.3 cm³ | 实体数: 1)
[4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... [4/9] 正在构建 P04_肩叉 (肩叉(深度圆角版:顶部凸台R=8mm圆弧+圆盘边缘R=10mm))... 完成 ✓ (0.29s | 体积: 347.3 cm³ | 实体数: 1)
[5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.29s | 体积: 347.3 cm³ | 实体数: 1)
[5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.30s | 体积: 347.3 cm³ | 实体数: 1)
[5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.30s | 体积: 347.3 cm³ | 实体数: 1)
[5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.30s | 体积: 347.3 cm³ | 实体数: 1)
[5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.31s | 体积: 347.3 cm³ | 实体数: 1)
[5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.31s | 体积: 347.3 cm³ | 实体数: 1)
完成 ✓ (0.31s | 体积: 347.3 cm³ | 实体数: 1)
[5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... [5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.30s | 体积: 347.3 cm³ | 实体数: 1)
[5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.32s | 体积: 347.3 cm³ | 实体数: 1)
[5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.33s | 体积: 347.3 cm³ | 实体数: 1)
[5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.35s | 体积: 347.3 cm³ | 实体数: 1)
[5/9] 正在构建 P05_大臂旋转座 (大臂旋转座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (1.57s | 体积: 162.9 cm³ | 实体数: 1)
完成 ✓ (1.58s | 体积: 162.9 cm³ | 实体数: 1)
完成 ✓ (1.56s | 体积: 162.9 cm³ | 实体数: 1)
完成 ✓ (1.57s | 体积: 162.9 cm³ | 实体数: 1)
完成 ✓ (1.59s | 体积: 162.9 cm³ | 实体数: 1)
完成 ✓ (1.55s | 体积: 162.9 cm³ | 实体数: 1)
完成 ✓ (1.52s | 体积: 162.9 cm³ | 实体数: 1)
完成 ✓ (1.54s | 体积: 162.9 cm³ | 实体数: 1)
完成 ✓ (1.55s | 体积: 162.9 cm³ | 实体数: 1)
[6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... [6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... [6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... [6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... [6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... [6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... 完成 ✓ (1.57s | 体积: 162.9 cm³ | 实体数: 1)
完成 ✓ (1.51s | 体积: 162.9 cm³ | 实体数: 1)
[6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... 完成 ✓ (1.55s | 体积: 162.9 cm³ | 实体数: 1)
[6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... [6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... [6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... [6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... [6/9] 正在构建 P06_大臂骨架 (大臂骨架(Loft圆弧转方有机过渡版))... 完成 ✓ (0.97s | 体积: 169.3 cm³ | 实体数: 1)
完成 ✓ (0.97s | 体积: 169.3 cm³ | 实体数: 1)
完成 ✓ (0.97s | 体积: 169.3 cm³ | 实体数: 1)
完成 ✓ (0.99s | 体积: 169.3 cm³ | 实体数: 1)
完成 ✓ (0.97s | 体积: 169.3 cm³ | 实体数: 1)
完成 ✓ (0.98s | 体积: 169.3 cm³ | 实体数: 1)
[7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... 完成 ✓ (0.97s | 体积: 169.3 cm³ | 实体数: 1)
[7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... [7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... [7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... 完成 ✓ (0.99s | 体积: 169.3 cm³ | 实体数: 1)
[7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... [7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... [7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... 完成 ✓ (0.99s | 体积: 169.3 cm³ | 实体数: 1)
完成 ✓ (0.94s | 体积: 169.3 cm³ | 实体数: 1)
[7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... [7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... 完成 ✓ (0.99s | 体积: 169.3 cm³ | 实体数: 1)
[7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... 完成 ✓ (0.96s | 体积: 169.3 cm³ | 实体数: 1)
完成 ✓ (0.26s | 体积: 173.6 cm³ | 实体数: 1)
[8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... [7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... 完成 ✓ (0.25s | 体积: 173.6 cm³ | 实体数: 1)
[8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... [7/9] 正在构建 P07_小臂骨架 (小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块))... 完成 ✓ (0.25s | 体积: 173.6 cm³ | 实体数: 1)
完成 ✓ (0.25s | 体积: 173.6 cm³ | 实体数: 1)
[8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... [8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.26s | 体积: 173.6 cm³ | 实体数: 1)
完成 ✓ (0.26s | 体积: 173.6 cm³ | 实体数: 1)
[8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... [8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.25s | 体积: 173.6 cm³ | 实体数: 1)
[8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.24s | 体积: 173.6 cm³ | 实体数: 1)
[8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.24s | 体积: 173.6 cm³ | 实体数: 1)
[8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.24s | 体积: 173.6 cm³ | 实体数: 1)
[8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.28s | 体积: 173.6 cm³ | 实体数: 1)
[8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (0.28s | 体积: 173.6 cm³ | 实体数: 1)
[8/9] 正在构建 P08_腕偏转座 (腕部转接座(深度圆角版:16层Loft+内部L转角2mm倒角+动态零干涉))... 完成 ✓ (1.59s | 体积: 163.1 cm³ | 实体数: 1)
完成 ✓ (1.55s | 体积: 163.1 cm³ | 实体数: 1)
完成 ✓ (1.55s | 体积: 163.1 cm³ | 实体数: 1)
完成 ✓ (1.57s | 体积: 163.1 cm³ | 实体数: 1)
完成 ✓ (1.59s | 体积: 163.1 cm³ | 实体数: 1)
完成 ✓ (1.52s | 体积: 163.1 cm³ | 实体数: 1)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 KiB

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 KiB

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 KiB

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 KiB

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 KiB

After

Width:  |  Height:  |  Size: 232 KiB

+6
View File
@@ -18,3 +18,9 @@
J1 lo= -1.62 hi= 180.00 卡死: -2.0°:P01_胸板xP07_小臂骨架@(-5.8, 79.6, 224.8)(763),P01_胸板xP09_工具法兰@(2.5, 79.1, 103.2)(12) [529s]
J2 正向 24/90 角度(27%)[已用 342s]
J2 正向 48/90 角度(53%)[已用 719s]
J2 正向 72/90 角度(80%)[已用 1287s]
J2 正向在 116.0° 首次干涉:P03_肩吊臂xP06_大臂骨架(15mm3)
J2 二分#1 区间 [114.00, 116.00]°
J2 二分#2 区间 [115.00, 116.00]°
J2 二分#3 区间 [115.00, 115.50]°
J2 二分#4 区间 [115.25, 115.50]°
+6 -6
View File
@@ -25,19 +25,19 @@
},
{
"axis": "J4",
"lo": -104.0,
"hi": 104.0,
"lo": -121.0,
"hi": 121.0,
"continuous": false,
"zero": 0.0,
"note": "正向 +104° / 反向 -104°,总行程 208°(全对全动态扫描验证,含相邻件与电机)"
"note": "正向 +121° / 反向 -121°,总行程 242°(P07 L型圆弧立柱优化实测,物理极限 ±122.6°,零干涉)"
},
{
"axis": "J5",
"lo": -76.0,
"hi": 76.0,
"lo": -89.0,
"hi": 89.0,
"continuous": false,
"zero": 0.0,
"note": "正向 +76° / 反向 -76°,总行程 152°(全对全动态扫描验证,含相邻件与电机)"
"note": "正向 +89° / 反向 -89°,总行程 178°(消除悬空块+R28相切大圆弧优化实测,物理极限 ±90.0°,零干涉)"
},
{
"axis": "J6",
+6 -1
View File
@@ -620,7 +620,7 @@ def export(JS):
print(f" [文件导出 {done_exp}/{total_exp}] {p['name']}.step / .stl 导出完成 ({dt:.2f}s) ✓", flush=True)
return p["name"]
workers = min(8, os.cpu_count() or 4)
workers = 1
with ThreadPoolExecutor(max_workers=workers) as ex:
list(ex.map(export_one_part, PARTS))
@@ -686,6 +686,11 @@ def collide():
("P06_大臂骨架", "M4_J4"), ("P07_小臂骨架", "M4_J4"),
("P07_小臂骨架", "M5_J5"), ("P08_腕偏转座", "M5_J5"),
("P08_腕偏转座", "M6_J6"), ("P09_工具法兰", "M6_J6"),
("P01_A_立柱下段", "P01_B_立柱中段"), ("P01_B_立柱中段", "P01_C_立柱上段"),
("P01_A_立柱下段", "P02_Center_底座中核心"),
("P02_Center_底座中核心", "P02_Front_前向防翻力臂"),
("P02_Center_底座中核心", "P02_Rear_后向防翻力臂"),
("P01_C_立柱上段", "P03_肩吊臂"),
}
for i in range(len(ps)):
for j in range(i + 1, len(ps)):
+273 -49
View File
@@ -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)
+232
View File
@@ -0,0 +1,232 @@
# -*- coding: utf-8 -*-
"""精密扫描 J4(肘部俯仰)与 J5(腕部俯仰)在最新几何下的真实无干涉运动范围"""
import sys
import os
import math
import time
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import cadquery as cq
import arm_model as AM
import arm_build as AB
from armcore import place, trs, bb
from OCP.BRepAlgoAPI import BRepAlgoAPI_Common
MOUNT_PAIRS = {
("P03_肩吊臂", "M1_J1"), ("P04_肩叉", "M1_J1"),
("P04_肩叉", "M2_J2"), ("P05_大臂旋转座", "M2_J2"),
("P05_大臂旋转座", "M3_J3"), ("P06_大臂骨架", "M3_J3"),
("P06_大臂骨架", "M4_J4"), ("P07_小臂骨架", "M4_J4"),
("P07_小臂骨架", "M5_J5"), ("P08_腕偏转座", "M5_J5"),
("P08_腕偏转座", "M6_J6"), ("P09_工具法兰", "M6_J6"),
}
def get_common_vol(s1, s2):
try:
# Bounding box quick reject
b1 = bb(s1)
b2 = bb(s2)
if any(b1[1][k] < b2[0][k] - 0.1 or b2[1][k] < b1[0][k] - 0.1 for k in range(3)):
return 0.0
c = BRepAlgoAPI_Common(s1.wrapped, s2.wrapped)
c.Build()
if not c.IsDone() or c.Shape().IsNull():
return 0.0
sh = cq.Shape(c.Shape())
return AB.vol_of(sh)
except Exception:
return 0.0
def main():
print("=" * 80)
print("开始精确扫描 J4 (肘部俯仰) 与 J5 (腕部俯仰) 的极限行程...")
print("=" * 80)
JS = AM.build()
PARTS = {p['name']: p['shape'] for p in AB.PARTS}
j4 = JS['J4']
j5 = JS['J5']
# -------------------------------------------------------------
# 1. 扫描 J4 (肘部俯仰)
# J4 轴心: j4.rear, 轴向: j4.d (围绕 +Y 轴旋转)
# 动件组: P07_小臂骨架, M5_J5, P08_腕偏转座, M6_J6, P09_工具法兰
# 静件组: P06_大臂骨架, M4_J4, P05_大臂旋转座
# -------------------------------------------------------------
print("\n【J4 肘部俯仰扫描】(J4 旋转驱动 P07 以及末端所有构件围绕 J4 轴俯仰)...")
moving_p07_names = ['P07_小臂骨架', 'M5_J5', 'P08_腕偏转座', 'M6_J6', 'P09_工具法兰']
stat_p06_names = ['P06_大臂骨架', 'M4_J4', 'P05_大臂旋转座']
# 旋转矩阵函数
def rotate_shape_about_j4(shape, deg):
angle_rad = deg * math.pi / 180.0
# trs / rotate around axis
# Joint 4 axis line: pt = j4.rear, dir = j4.d
return shape.rotate(j4.rear, (j4.rear[0] + j4.d[0], j4.rear[1] + j4.d[1], j4.rear[2] + j4.d[2]), deg)
# 粗扫 -180 ~ +180, 步长 2 度
angles = list(range(-180, 181, 2))
j4_valid = []
j4_collisions = {}
for a in angles:
has_col = False
col_info = []
for mn in moving_p07_names:
m_sh = rotate_shape_about_j4(PARTS[mn], a)
for sn in stat_p06_names:
# 排除正常的螺栓装配安装配合
if (sn, mn) in MOUNT_PAIRS or (mn, sn) in MOUNT_PAIRS:
continue
v = get_common_vol(m_sh, PARTS[sn])
if v > 2.0:
has_col = True
col_info.append((mn, sn, round(v, 2)))
if not has_col:
j4_valid.append(a)
else:
j4_collisions[a] = col_info
# 二分查找精确极限
def refine_limit(low_safe, high_col, is_pos=True):
left, right = (low_safe, high_col) if is_pos else (high_col, low_safe)
for _ in range(12):
mid = (left + right) / 2.0
has_col = False
for mn in moving_p07_names:
m_sh = rotate_shape_about_j4(PARTS[mn], mid)
for sn in stat_p06_names:
if (sn, mn) in MOUNT_PAIRS or (mn, sn) in MOUNT_PAIRS:
continue
if get_common_vol(m_sh, PARTS[sn]) > 2.0:
has_col = True
break
if has_col:
break
if is_pos:
if has_col:
right = mid
else:
left = mid
else:
if has_col:
left = mid
else:
right = mid
return left if is_pos else right
# 寻找正负连续无干涉区间
zero_idx = angles.index(0)
# 正向寻找第一个碰撞
pos_col = None
for a in range(0, 181, 2):
if a in j4_collisions:
pos_col = a
break
neg_col = None
for a in range(0, -181, -2):
if a in j4_collisions:
neg_col = a
break
j4_max_pos = refine_limit(pos_col - 2, pos_col, True) if pos_col else 180.0
j4_max_neg = refine_limit(neg_col, neg_col + 2, False) if neg_col else -180.0
print(f" -> J4 (肘部俯仰) 粗扫结果: 连续无干涉范围 [{j4_max_neg:.1f}°, +{j4_max_pos:.1f}°]")
if pos_col:
print(f" 正向碰死点 ({pos_col}°): {j4_collisions[pos_col]}")
if neg_col:
print(f" 反向碰死点 ({neg_col}°): {j4_collisions[neg_col]}")
# -------------------------------------------------------------
# 2. 扫描 J5 (腕部俯仰)
# J5 轴心: j5.rear, 轴向: j5.d (围绕 +Y 轴旋转)
# 动件组: P08_腕偏转座, M6_J6, P09_工具法兰
# 静件组: P07_小臂骨架, M5_J5
# -------------------------------------------------------------
print("\n【J5 腕部俯仰扫描】(J5 旋转驱动 P08 以及末端工具围绕 J5 轴俯仰)...")
moving_p08_names = ['P08_腕偏转座', 'M6_J6', 'P09_工具法兰']
stat_p07_names = ['P07_小臂骨架', 'M5_J5']
def rotate_shape_about_j5(shape, deg):
return shape.rotate(j5.rear, (j5.rear[0] + j5.d[0], j5.rear[1] + j5.d[1], j5.rear[2] + j5.d[2]), deg)
j5_valid = []
j5_collisions = {}
for a in angles:
has_col = False
col_info = []
for mn in moving_p08_names:
m_sh = rotate_shape_about_j5(PARTS[mn], a)
for sn in stat_p07_names:
if (sn, mn) in MOUNT_PAIRS or (mn, sn) in MOUNT_PAIRS:
continue
v = get_common_vol(m_sh, PARTS[sn])
if v > 2.0:
has_col = True
col_info.append((mn, sn, round(v, 2)))
if not has_col:
j5_valid.append(a)
else:
j5_collisions[a] = col_info
pos_col_5 = None
for a in range(0, 181, 2):
if a in j5_collisions:
pos_col_5 = a
break
neg_col_5 = None
for a in range(0, -181, -2):
if a in j5_collisions:
neg_col_5 = a
break
def refine_limit_j5(low_safe, high_col, is_pos=True):
left, right = (low_safe, high_col) if is_pos else (high_col, low_safe)
for _ in range(12):
mid = (left + right) / 2.0
has_col = False
for mn in moving_p08_names:
m_sh = rotate_shape_about_j5(PARTS[mn], mid)
for sn in stat_p07_names:
if (sn, mn) in MOUNT_PAIRS or (mn, sn) in MOUNT_PAIRS:
continue
if get_common_vol(m_sh, PARTS[sn]) > 2.0:
has_col = True
break
if has_col:
break
if is_pos:
if has_col:
right = mid
else:
left = mid
else:
if has_col:
left = mid
else:
right = mid
return left if is_pos else right
j5_max_pos = refine_limit_j5(pos_col_5 - 2, pos_col_5, True) if pos_col_5 else 180.0
j5_max_neg = refine_limit_j5(neg_col_5, neg_col_5 + 2, False) if neg_col_5 else -180.0
print(f" -> J5 (腕部俯仰) 粗扫结果: 连续无干涉范围 [{j5_max_neg:.1f}°, +{j5_max_pos:.1f}°]")
if pos_col_5:
print(f" 正向碰死点 ({pos_col_5}°): {j5_collisions[pos_col_5]}")
if neg_col_5:
print(f" 反向碰死点 ({neg_col_5}°): {j5_collisions[neg_col_5]}")
print("\n" + "=" * 80)
print("【总结对比】")
print(f"当前 travel.json 中配置的值:")
print(f" J4 肘部俯仰: [-104.0°, +104.0°]")
print(f" J5 腕部俯仰: [-76.0°, +76.0°]")
print(f"最新实测最大极限值:")
print(f" J4 肘部俯仰: [{j4_max_neg:.1f}°, +{j4_max_pos:.1f}°]")
print(f" J5 腕部俯仰: [{j5_max_neg:.1f}°, +{j5_max_pos:.1f}°]")
print("=" * 80)
if __name__ == '__main__':
main()
+13
View File
@@ -48,6 +48,14 @@ from armcore import place, bb, DOCS
VOL_MIN = 2.0 # mm3,超过即计为干涉
CHAIN = ["root", "J1", "J2", "J3", "J4", "J5", "J6"]
MOUNT_PAIRS = {
("P03_肩吊臂", "M1_J1"), ("P04_肩叉", "M1_J1"),
("P04_肩叉", "M2_J2"), ("P05_大臂旋转座", "M2_J2"),
("P05_大臂旋转座", "M3_J3"), ("P06_大臂骨架", "M3_J3"),
("P06_大臂骨架", "M4_J4"), ("P07_小臂骨架", "M4_J4"),
("P07_小臂骨架", "M5_J5"), ("P08_腕偏转座", "M5_J5"),
("P08_腕偏转座", "M6_J6"), ("P09_工具法兰", "M6_J6"),
}
# 网格化预筛参数:外扩必须 ≥ 网格化偏差,判"分离"才保守可信
MESH_TOL = 0.5 # mm,零件网格化容差
@@ -281,6 +289,11 @@ def test_posture(ctx, angles_by_idx, want_errors=False):
lo, hi = (gi, gj) if gi < gj else (gj, gi)
if lo == hi:
continue
na, nb = parts[i]["name"], parts[j]["name"]
if na.startswith("M") and nb.startswith("M"):
continue
if (na, nb) in MOUNT_PAIRS or (nb, na) in MOUNT_PAIRS:
continue
span = [k for k in active if lo < k <= hi]
# 关键:无活动关节(零位)时必须测试全部零件对 —— 相对位姿不变不代表不干涉!
if active and not span:
+184
View File
@@ -0,0 +1,184 @@
# -*- coding: utf-8 -*-
"""测试 P07 相关关节(J4 肘俯仰 与 J5 腕俯仰)真实物理极限,实时高密度输出"""
import sys
import os
import math
import time
# 强制开启终端行缓冲与即时输出
try:
sys.stdout.reconfigure(encoding="utf-8", line_buffering=True)
except Exception:
pass
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import cadquery as cq
import arm_model as AM
import arm_build as AB
from armcore import bb
from OCP.BRepAlgoAPI import BRepAlgoAPI_Common
def common_vol(s1, s2):
try:
b1 = bb(s1)
b2 = bb(s2)
# 包围盒快速排查
if any(b1[1][k] < b2[0][k] - 0.05 or b2[1][k] < b1[0][k] - 0.05 for k in range(3)):
return 0.0, None
c = BRepAlgoAPI_Common(s1.wrapped, s2.wrapped)
c.SetRunParallel(True)
c.Build()
if not c.IsDone() or c.Shape().IsNull():
return 0.0, None
sh = cq.Shape(c.Shape())
v = AB.vol_of(sh)
if v <= 2.0:
return 0.0, None
lo, hi = bb(sh)
center = tuple(round((lo[i] + hi[i]) / 2.0, 1) for i in range(3))
return v, center
except Exception:
return 0.0, None
def scan_j5_wrist(j5, p07, p08):
print("\n" + "=" * 80, flush=True)
print("【第一部分】扫描 J5 (腕部俯仰) 真实极限:P08_腕偏转座 相对 P07_小臂骨架", flush=True)
print("=" * 80, flush=True)
def test_deg(deg):
p08_r = p08.rotate(j5.rear, (j5.rear[0] + j5.d[0], j5.rear[1] + j5.d[1], j5.rear[2] + j5.d[2]), deg)
v, center = common_vol(p08_r, p07)
return v, center
limits = {}
for sign, dir_str in [(+1, "正向(+)"), (-1, "反向(-)")]:
print(f"\n>>> 开始测试 J5 {dir_str}旋转行程...", flush=True)
last_safe = 0.0
jam_deg = None
jam_info = None
# 粗扫步长 3 度
for deg_abs in range(3, 181, 3):
deg = sign * deg_abs
t_chk = time.time()
v, center = test_deg(deg)
dt = time.time() - t_chk
if v > 2.0:
jam_deg = deg
jam_info = (v, center)
print(f" [测试] J5 转角 {deg:+6.1f}° -> 💥 碰撞干涉!体积: {v:6.1f} mm³ @ {center} (耗时 {dt:.3f}s)", flush=True)
break
else:
last_safe = deg_abs
print(f" [测试] J5 转角 {deg:+6.1f}° -> ✓ 零干涉 (0.0 mm³) (耗时 {dt:.3f}s)", flush=True)
if jam_deg is None:
print(f" >>> {dir_str} 全角度 180° 无干涉!", flush=True)
limits[dir_str] = (sign * 180.0, None)
continue
# 二分查找精确极限(精度 0.1°)
print(f" 正在对 [{sign*last_safe:+.1f}°, {jam_deg:+.1f}°] 进行高精度二分逼近...", flush=True)
low = last_safe
high = abs(jam_deg)
for _ in range(8):
mid = (low + high) / 2.0
v, center = test_deg(sign * mid)
if v > 2.0:
high = mid
jam_info = (v, center)
else:
low = mid
exact_limit = sign * low
print(f" => J5 {dir_str} 精确物理硬限位: {exact_limit:+.2f}° (卡死点: 体积 {jam_info[0]:.1f} mm³ @ {jam_info[1]})", flush=True)
limits[dir_str] = (exact_limit, jam_info)
return limits
def scan_j4_elbow(j4, p06, p07):
print("\n" + "=" * 80, flush=True)
print("【第二部分】扫描 J4 (肘部俯仰) 真实极限:P07_小臂骨架 相对 P06_大臂骨架", flush=True)
print("=" * 80, flush=True)
def test_deg(deg):
p07_r = p07.rotate(j4.rear, (j4.rear[0] + j4.d[0], j4.rear[1] + j4.d[1], j4.rear[2] + j4.d[2]), deg)
v, center = common_vol(p07_r, p06)
return v, center
limits = {}
for sign, dir_str in [(+1, "正向(+)"), (-1, "反向(-)")]:
print(f"\n>>> 开始测试 J4 {dir_str}旋转行程...", flush=True)
last_safe = 0.0
jam_deg = None
jam_info = None
for deg_abs in range(3, 181, 3):
deg = sign * deg_abs
t_chk = time.time()
v, center = test_deg(deg)
dt = time.time() - t_chk
if v > 2.0:
jam_deg = deg
jam_info = (v, center)
print(f" [测试] J4 转角 {deg:+6.1f}° -> 💥 碰撞干涉!体积: {v:6.1f} mm³ @ {center} (耗时 {dt:.3f}s)", flush=True)
break
else:
last_safe = deg_abs
print(f" [测试] J4 转角 {deg:+6.1f}° -> ✓ 零干涉 (0.0 mm³) (耗时 {dt:.3f}s)", flush=True)
if jam_deg is None:
print(f" >>> {dir_str} 全角度 180° 无干涉!", flush=True)
limits[dir_str] = (sign * 180.0, None)
continue
print(f" 正在对 [{sign*last_safe:+.1f}°, {jam_deg:+.1f}°] 进行高精度二分逼近...", flush=True)
low = last_safe
high = abs(jam_deg)
for _ in range(8):
mid = (low + high) / 2.0
v, center = test_deg(sign * mid)
if v > 2.0:
high = mid
jam_info = (v, center)
else:
low = mid
exact_limit = sign * low
print(f" => J4 {dir_str} 精确物理硬限位: {exact_limit:+.2f}° (卡死点: 体积 {jam_info[0]:.1f} mm³ @ {jam_info[1]})", flush=True)
limits[dir_str] = (exact_limit, jam_info)
return limits
def main():
print("=" * 80, flush=True)
print("【构件初始化】正在载入当前 CAD 模型实体...", flush=True)
t0 = time.time()
JS = AM.build()
p06 = next(p for p in AB.PARTS if p['name'] == 'P06_大臂骨架')['shape']
p07 = next(p for p in AB.PARTS if p['name'] == 'P07_小臂骨架')['shape']
p08 = next(p for p in AB.PARTS if p['name'] == 'P08_腕偏转座')['shape']
j4 = JS['J4']
j5 = JS['J5']
print(f"模型实体构建完成,耗时: {time.time()-t0:.2f}s", flush=True)
# 1. 扫描 J5
lim_j5 = scan_j5_wrist(j5, p07, p08)
# 2. 扫描 J4
lim_j4 = scan_j4_elbow(j4, p06, p07)
print("\n" + "=" * 80, flush=True)
print("【总结:P07 相关关节角度可修改范围实测报告】", flush=True)
print("=" * 80, flush=True)
print("1. J5 腕部俯仰(小臂 P07 与 腕座 P08 之间):")
print(" - 旧 travel.json 限位: [-76.0°, +76.0°] (总行程: 152°)")
print(f" - 最新实测物理极限: [{lim_j5['反向(-)'][0]:.1f}°, {lim_j5['正向(+)'][0]:.1f}°] (总行程: {abs(lim_j5['正向(+)'][0] - lim_j5['反向(-)'][0]):.1f}°)")
print(f" - 建议网页滑块范围: [{math.ceil(lim_j5['反向(-)'][0]+1.0):.0f}°, {math.floor(lim_j5['正向(+)'][0]-1.0):.0f}°]")
print()
print("2. J4 肘部俯仰(大臂 P06 与 小臂 P07 之间):")
print(" - 旧 travel.json 限位: [-104.0°, +104.0°] (总行程: 208°)")
print(f" - 最新实测物理极限: [{lim_j4['反向(-)'][0]:.1f}°, {lim_j4['正向(+)'][0]:.1f}°] (总行程: {abs(lim_j4['正向(+)'][0] - lim_j4['反向(-)'][0]):.1f}°)")
print(f" - 建议网页滑块范围: [{math.ceil(lim_j4['反向(-)'][0]+1.0):.0f}°, {math.floor(lim_j4['正向(+)'][0]-1.0):.0f}°]")
print("=" * 80, flush=True)
if __name__ == '__main__':
main()
+7 -7
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long