docs: 更新BOM清单与渲染图,适配200mm分段式立柱和防呆底座设计
@@ -1,23 +1,63 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"件号": "P01_胸板",
|
"件号": "P01_A_立柱下段",
|
||||||
"名称": "胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗)",
|
"名称": "立柱下段(P01-A 标识版)",
|
||||||
"类型": "3D打印",
|
"类型": "3D打印",
|
||||||
"数量": 1,
|
"数量": 1,
|
||||||
"体积cm3": 809.6,
|
"体积cm3": 305.1,
|
||||||
"质量g_PLA": 1003.9,
|
"质量g_PLA": 378.3,
|
||||||
"包络": "[-148.0 95.0 22.0 .. -82.0 161.0 470.0] (66.0x66.0x448.0)",
|
"包络": "[-148.0 95.0 22.0 .. -82.0 161.0 188.0] (66.0x66.0x166.0)",
|
||||||
"说明": "V2高刚度立柱:66x66mm厚壁封闭箱梁+8mm壁厚+顶部P03榫卯台座+两组大圆角工艺走线窗"
|
"说明": "200mm适配分段A:高166mm+16mm阶梯公榫+非对称M4防反装通孔+P01-A ▲ TOP刻字"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"件号": "P02_底脚",
|
"件号": "P01_B_立柱中段",
|
||||||
"名称": "测试台架底座(重型防倾翻超长力臂+双向三角斜撑版)",
|
"名称": "立柱中段(P01-B 标识版)",
|
||||||
"类型": "3D打印",
|
"类型": "3D打印",
|
||||||
"数量": 1,
|
"数量": 1,
|
||||||
"体积cm3": 2122.9,
|
"体积cm3": 269.3,
|
||||||
"质量g_PLA": 2632.4,
|
"质量g_PLA": 333.9,
|
||||||
"包络": "[-241.5 6.5 -0.0 .. 146.5 249.5 70.0] (388.0x243.0x70.0)",
|
"包络": "[-148.0 95.0 172.0 .. -82.0 161.0 337.0] (66.0x66.0x165.0)",
|
||||||
"说明": "防倾翻超大底盘:385x240mm超长力臂+48mm立柱套筒+前后双向大三角抗倾翻斜撑筋+走线导槽+6xM6固定槽"
|
"说明": "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_肩吊臂",
|
"件号": "P03_肩吊臂",
|
||||||
@@ -64,9 +104,9 @@
|
|||||||
"名称": "小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块)",
|
"名称": "小臂骨架(L型圆弧加强版:R=28mm双相切内凹大圆弧+消除悬空块)",
|
||||||
"类型": "3D打印",
|
"类型": "3D打印",
|
||||||
"数量": 1,
|
"数量": 1,
|
||||||
"体积cm3": 173.6,
|
"体积cm3": 208.5,
|
||||||
"质量g_PLA": 215.3,
|
"质量g_PLA": 258.6,
|
||||||
"包络": "[-16.5 92.0 187.0 .. 53.5 174.0 367.0] (70.0x82.0x180.0)",
|
"包络": "[-19.4 92.0 187.0 .. 56.4 174.0 369.9] (75.8x82.0x182.9)",
|
||||||
"说明": "V2 L型结构:+Y侧背脊立柱避让大臂骨架,过渡区采用与顶面和立柱双相切的R=28mm平滑内凹大圆弧,彻底消除直斜线折角与悬空阶梯小块,下方M5电机半包散热,俯仰大范围自由运动零干涉"
|
"说明": "V2 L型结构:+Y侧背脊立柱避让大臂骨架,过渡区采用与顶面和立柱双相切的R=28mm平滑内凹大圆弧,彻底消除直斜线折角与悬空阶梯小块,下方M5电机半包散热,俯仰大范围自由运动零干涉"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 181 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 253 KiB After Width: | Height: | Size: 242 KiB |
|
Before Width: | Height: | Size: 202 KiB After Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 221 KiB |
|
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 197 KiB |
|
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 181 KiB |
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 179 KiB |
|
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 179 KiB |
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 222 KiB |
|
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 214 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 168 KiB |
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 229 KiB |
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 232 KiB |
|
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 209 KiB After Width: | Height: | Size: 206 KiB |
|
Before Width: | Height: | Size: 201 KiB After Width: | Height: | Size: 201 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 227 KiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 175 KiB |
|
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 183 KiB |
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 248 KiB |
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 177 KiB |
|
Before Width: | Height: | Size: 255 KiB After Width: | Height: | Size: 255 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 185 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 189 KiB |
|
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 187 KiB |
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 259 KiB |
|
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 229 KiB After Width: | Height: | Size: 232 KiB |
@@ -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]
|
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 正向 24/90 角度(27%)[已用 342s]
|
||||||
J2 正向 48/90 角度(53%)[已用 719s]
|
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]°
|
||||||
|
|||||||
@@ -25,19 +25,19 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"axis": "J4",
|
"axis": "J4",
|
||||||
"lo": -104.0,
|
"lo": -121.0,
|
||||||
"hi": 104.0,
|
"hi": 121.0,
|
||||||
"continuous": false,
|
"continuous": false,
|
||||||
"zero": 0.0,
|
"zero": 0.0,
|
||||||
"note": "正向 +104° / 反向 -104°,总行程 208°(全对全动态扫描验证,含相邻件与电机)"
|
"note": "正向 +121° / 反向 -121°,总行程 242°(P07 L型圆弧立柱优化实测,物理极限 ±122.6°,零干涉)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"axis": "J5",
|
"axis": "J5",
|
||||||
"lo": -76.0,
|
"lo": -89.0,
|
||||||
"hi": 76.0,
|
"hi": 89.0,
|
||||||
"continuous": false,
|
"continuous": false,
|
||||||
"zero": 0.0,
|
"zero": 0.0,
|
||||||
"note": "正向 +76° / 反向 -76°,总行程 152°(全对全动态扫描验证,含相邻件与电机)"
|
"note": "正向 +89° / 反向 -89°,总行程 178°(消除悬空块+R28相切大圆弧优化实测,物理极限 ±90.0°,零干涉)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"axis": "J6",
|
"axis": "J6",
|
||||||
|
|||||||
@@ -620,7 +620,7 @@ def export(JS):
|
|||||||
print(f" [文件导出 {done_exp}/{total_exp}] {p['name']}.step / .stl 导出完成 ({dt:.2f}s) ✓", flush=True)
|
print(f" [文件导出 {done_exp}/{total_exp}] {p['name']}.step / .stl 导出完成 ({dt:.2f}s) ✓", flush=True)
|
||||||
return p["name"]
|
return p["name"]
|
||||||
|
|
||||||
workers = min(8, os.cpu_count() or 4)
|
workers = 1
|
||||||
with ThreadPoolExecutor(max_workers=workers) as ex:
|
with ThreadPoolExecutor(max_workers=workers) as ex:
|
||||||
list(ex.map(export_one_part, PARTS))
|
list(ex.map(export_one_part, PARTS))
|
||||||
|
|
||||||
@@ -686,6 +686,11 @@ def collide():
|
|||||||
("P06_大臂骨架", "M4_J4"), ("P07_小臂骨架", "M4_J4"),
|
("P06_大臂骨架", "M4_J4"), ("P07_小臂骨架", "M4_J4"),
|
||||||
("P07_小臂骨架", "M5_J5"), ("P08_腕偏转座", "M5_J5"),
|
("P07_小臂骨架", "M5_J5"), ("P08_腕偏转座", "M5_J5"),
|
||||||
("P08_腕偏转座", "M6_J6"), ("P09_工具法兰", "M6_J6"),
|
("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 i in range(len(ps)):
|
||||||
for j in range(i + 1, len(ps)):
|
for j in range(i + 1, len(ps)):
|
||||||
|
|||||||
@@ -121,38 +121,219 @@ def p_chest():
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def split_p01_stack(p01):
|
def split_p01_poka_yoke(p01):
|
||||||
"""将 P01 拆分为适合 250mm 桌面 3D 打印机的两段(P01_A 与 P01_B),带 16mm 阶梯互锁榫卯"""
|
"""拆分 P01 为 A/B/C 三段(严格适配 200x200mm 打印机,竖直免支撑打印):
|
||||||
z_split = 246.0
|
带 16mm 阶梯互锁榫卯、非对称 M4 横向对锁穿钉孔(物理防反装防呆)、以及本体 3D 凹刻朝向标识。
|
||||||
|
"""
|
||||||
|
z_bot = 22.0
|
||||||
|
z_s1 = 172.0
|
||||||
|
z_s2 = 321.0
|
||||||
|
z_top = 470.0
|
||||||
h_lap = 16.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)
|
# 非对称对锁孔位(相对立柱中心偏心 -16mm 与 +22mm,偏心差 6mm,反装无法穿入螺栓)
|
||||||
tongue_outer = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_split))
|
xx_bolts = (X_COL - 16.0, X_COL + 22.0)
|
||||||
.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)
|
|
||||||
|
|
||||||
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)
|
z_bolt1 = z_s1 + h_lap / 2.0 # 180.0
|
||||||
p01_b = p01.cut(cut_a)
|
for xx in xx_bolts:
|
||||||
pocket = (cq.Workplane("XY", origin=(X_COL, Y_COL, z_split - 0.1))
|
p01_a = p01_a.cut(Ycyl(2.2, Y_COL - 40.0, Y_COL + 40.0, xx, z_bolt1))
|
||||||
.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)
|
|
||||||
|
|
||||||
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():
|
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_hub_in = HL.Y_COVER + 0.5 + CLEARANCE_GAP # 158.5
|
||||||
y_front = Y_COVER - 0.5 # 155.5
|
y_front = Y_COVER - 0.5 # 155.5
|
||||||
y_rear = Y_REAR - 8.0 # 92.0
|
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 电机前后安装环
|
# 1. J5 电机前后安装环
|
||||||
collar_front = Ycyl(35.0, HL.Y_COVER - 6.0, HL.Y_COVER - 0.5, X_ARM, Z_WR)
|
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.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.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 = 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底部电机定子通风口
|
# 半包散热设计:-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)
|
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:
|
try:
|
||||||
s = s.edges("|X").chamfer(CHAMFER_EDGE)
|
# 后侧顶板外边缘倒角(平滑消除水平顶板与后部垂直端面交汇处的 90° 尖角)
|
||||||
except:
|
wp_s = cq.Workplane(obj=s)
|
||||||
pass
|
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:
|
try:
|
||||||
# 圆润化 J4 圆盘外沿
|
# 圆润化 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),
|
||||||
(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
|
pass
|
||||||
|
|
||||||
try:
|
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_top_housing),
|
||||||
(X_ARM + 37, y_out + 2, Z_EL + 40)
|
(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
|
pass
|
||||||
|
|
||||||
return s
|
return s
|
||||||
@@ -905,14 +1096,30 @@ def build():
|
|||||||
for t in ("J1", "J2", "J3", "J4", "J5", "J6"):
|
for t in ("J1", "J2", "J3", "J4", "J5", "J6"):
|
||||||
AB.GRP[motor_of[t]] = par[t]
|
AB.GRP[motor_of[t]] = par[t]
|
||||||
AB.GRP[driven[t]] = 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 = {}
|
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 = [
|
parts_to_build = [
|
||||||
("P01_胸板", "胸腔支撑立柱(高刚性箱型梁+榫卯台座+走线窗)", lambda: p_chest(), 0x4b5563,
|
("P01_A_立柱下段", "立柱下段(P01-A 标识版)", lambda: p01_a, 0x0284c7,
|
||||||
"V2高刚度立柱:66x66mm厚壁封闭箱梁+8mm壁厚+顶部P03榫卯台座+两组大圆角工艺走线窗"),
|
"200mm适配分段A:高166mm+16mm阶梯公榫+非对称M4防反装通孔+P01-A ▲ TOP刻字"),
|
||||||
("P02_底脚", "测试台架底座(重型防倾翻超长力臂+双向三角斜撑版)", lambda: p_base_foot(), 0x374151,
|
("P01_B_立柱中段", "立柱中段(P01-B 标识版)", lambda: p01_b, 0x2563eb,
|
||||||
"防倾翻超大底盘:385x240mm超长力臂+48mm立柱套筒+前后双向大三角抗倾翻斜撑筋+走线导槽+6xM6固定槽"),
|
"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,
|
("P03_肩吊臂", "肩关节安装悬臂(高强多肋+前置电机锁紧法兰版)", lambda: p_girdle(j1), 0x4b5563,
|
||||||
"高强多肋机架:10mm后置法兰+双侧8mm大三角加强筋+下腹12mm抗弯龙骨筋+前向电机全包托架与前置止脱锁紧法兰(4xM3止脱螺孔)+双侧大散热窗与对流槽"),
|
"高强多肋机架:10mm后置法兰+双侧8mm大三角加强筋+下腹12mm抗弯龙骨筋+前向电机全包托架与前置止脱锁紧法兰(4xM3止脱螺孔)+双侧大散热窗与对流槽"),
|
||||||
("P04_肩叉", "肩叉(加长避让顺滑流线版)", lambda: p_fork(j1, j2), 0x2563eb,
|
("P04_肩叉", "肩叉(加长避让顺滑流线版)", lambda: p_fork(j1, j2), 0x2563eb,
|
||||||
@@ -929,8 +1136,9 @@ def build():
|
|||||||
"V2圆角:外轮廓R=3mm,法兰面倒角2mm"),
|
"V2圆角:外轮廓R=3mm,法兰面倒角2mm"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
total_parts = len(parts_to_build)
|
||||||
for idx, (name, cn, fn, color, note) in enumerate(parts_to_build, 1):
|
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()
|
t0 = time.time()
|
||||||
sh = fn()
|
sh = fn()
|
||||||
dt = time.time() - t0
|
dt = time.time() - t0
|
||||||
@@ -955,15 +1163,30 @@ SEP = 74.0
|
|||||||
|
|
||||||
|
|
||||||
def explode_chain(p, JS, cents, gmean):
|
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")
|
grp = AB.GRP.get(p["name"], "root")
|
||||||
if grp == "root":
|
if grp == "root":
|
||||||
return [0.0, 0.0, 0.0]
|
return [0.0, 0.0, 0.0]
|
||||||
k = CHAIN.index(grp)
|
k = CHAIN.index(grp)
|
||||||
off = [0.0, 0.0, -SEP * k]
|
off = [0.0, 0.0, 120.0 - SEP * k]
|
||||||
j = JS.get(grp)
|
j = JS.get(grp)
|
||||||
if j:
|
if j:
|
||||||
nm = p["name"]
|
|
||||||
w = 0.0
|
w = 0.0
|
||||||
if "半联轴器" in nm or "抱箍" in nm:
|
if "半联轴器" in nm or "抱箍" in nm:
|
||||||
w = 34.0 * (1.0 if ("A" in nm[-1:]) else -1.0)
|
w = 34.0 * (1.0 if ("A" in nm[-1:]) else -1.0)
|
||||||
@@ -982,14 +1205,15 @@ if __name__ == "__main__":
|
|||||||
print("=" * 80, flush=True)
|
print("=" * 80, flush=True)
|
||||||
bad = 0
|
bad = 0
|
||||||
printed_list = [p for p in PARTS if p["printed"]]
|
printed_list = [p for p in PARTS if p["printed"]]
|
||||||
|
total_pr = len(printed_list)
|
||||||
for idx, p in enumerate(printed_list, 1):
|
for idx, p in enumerate(printed_list, 1):
|
||||||
n = len(solids_of(p["shape"]))
|
n = len(solids_of(p["shape"]))
|
||||||
if n != 1:
|
if n != 1:
|
||||||
bad += 1
|
bad += 1
|
||||||
status = "单实体 ✓" if n == 1 else f"异常 ({n} 个实体) ❌"
|
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:
|
if bad == 0:
|
||||||
print("-> 单实体检查全部通过!9/9 构件均为完美单一流形拓扑 ✓\n", flush=True)
|
print(f"-> 单实体检查全部通过!{total_pr}/{total_pr} 构件均为完美单一流形拓扑 ✓\n", flush=True)
|
||||||
else:
|
else:
|
||||||
print(f"-> 发现 {bad} 个非单实体构件!\n", flush=True)
|
print(f"-> 发现 {bad} 个非单实体构件!\n", flush=True)
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
@@ -48,6 +48,14 @@ from armcore import place, bb, DOCS
|
|||||||
|
|
||||||
VOL_MIN = 2.0 # mm3,超过即计为干涉
|
VOL_MIN = 2.0 # mm3,超过即计为干涉
|
||||||
CHAIN = ["root", "J1", "J2", "J3", "J4", "J5", "J6"]
|
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,零件网格化容差
|
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)
|
lo, hi = (gi, gj) if gi < gj else (gj, gi)
|
||||||
if lo == hi:
|
if lo == hi:
|
||||||
continue
|
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]
|
span = [k for k in active if lo < k <= hi]
|
||||||
# 关键:无活动关节(零位)时必须测试全部零件对 —— 相对位姿不变不代表不干涉!
|
# 关键:无活动关节(零位)时必须测试全部零件对 —— 相对位姿不变不代表不干涉!
|
||||||
if active and not span:
|
if active and not span:
|
||||||
|
|||||||
@@ -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()
|
||||||