您要"看过程",那我把中间翻车的都摆出来——最后这版之所以对,是因为前三版被自己的截图打回了。
本机 FreeCAD 1.1.3,Part / Mesh / Import / Draft 可用;缺 importDAE、importOBJ、OfflineRendering。路线定为:Part 内核建实体 → Mesh 出 OBJ/STL → Import 出 STEP,彩图渲染交浏览器(不在无头 FreeCAD 里硬啃)。
底座 R140 / 肩高 250 / 大臂 520 / 小臂 480 / 腕 130 / 夹爪 90(mm)。
plate = Part.makeCylinder(base_r, 20) # 底板
for ang in (45,135,225,315): # 4 个地脚螺栓孔
plate = plate.cut(cyl(6, 30, (x, y, -5)))
arm.rotate(Vector(0,0,0), Vector(0,1,0), -deg) # 大臂按仰角旋转
arm.translate(Vector(0,0,shoulder_z))
第一个疑点:整机包围盒 ZMin = -385.9。底座在 Z=0 的地面上,怎么会有零件跑到地面下 386mm?说明有东西放反了。
无头 FreeCAD 没有出图接口,我把每条 Edge 采样后正交投影成 SVG,再用 Chrome 无头截图看。
抓到的错:大臂用了 -62°,但旋转正负号跟 FreeCAD 右手系相反 → 大臂朝下扎进地里;小臂 -8° 同样往下掉。整个模型"看着像个机器人",实际是倒着长的。
修法:仰角改 +62°、小臂改 +10° 下倾,并把每个关节坐标改成显式算出来:
a_t = radians(62)
j3 = Vector(L1*cos(a_t), 0, shoulder_z + L1*sin(a_t)) # J3 肘心
j5 = Vector(j3.x + L2*cos(a_f), 0, j3.z + L2*sin(a_f)) # J5 腕心
tcp = Vector(fl.x + ax4.x*L4, 0, fl.z + ax4.z*L4) # 末端 TCP
J2 肩轴: [0, 0, 250] J3 肘: [244.1, 709.1]
J5 腕: [697.1, 629.3] TCP: [918.7, 590.2]
最大水平伸展 918.7 mm TCP 高度 590.2 mm
整机体积 21.78 L 零件 11 个
| 坑 | 症状 | 根因 |
|---|---|---|
| ① 面板串扰 | 前视/侧视缩成一个点挤在角落 | 四面板共用一套缩放,被俯视 1106mm 宽度拉爆,只有 280mm 宽的前视被压没 |
| ② 投影退化 | 俯视图只剩下一条线 | 视线 (0,0,-1) 与上方向 (0,0,1) 平行,右向量叉乘趋零 |
| ③ 上方向写反 | 图整体上下颠倒 | 写成 u = r × d,正确是 u = d × r |
最终修法:整机包围盒求中心 → 每面板独立算投影包围盒 → 独立 scale → 独立居中;上方向显式传参(俯视传 Y)。
CEN = 整机包围盒中心 # [412.9, 0.0, 382.4]
r = upw × d ; u = d × r # 正交基,叉乘顺序不能反
scale = min((PW-pad)/w, (PH-padtop-padbot)/h) # 每面板独立计算
左=修之前(俯视只剩一条线、前视缩成小点);右=修之后(四张图都饱满居中)。
按运动学层级挂零件,六个角度的数值实时显示。点按钮去看:preview/
J1(绕竖直轴)→ 腰部/立柱
└ J2(绕 Y,肩)→ 大臂 + J3 肘
└ J3(绕 Y,肘)→ 小臂 + J4/J5
└ J4(沿臂轴自转)
└ J5(绕 Y,腕)
└ J6(沿臂轴自转)→ 法兰 + 夹爪
预览也翻过一次:JS 里变量名 el 与 const el = viewer 撞了,页面整段脚本抛 SyntaxError: Identifier 'el' has already been declared,白屏只剩"加载中"。是浏览器控制台报错抓出来的,改名 elev 后正常加载 11/11。
| 项目 | 数值 | 说明 |
|---|---|---|
| 自由度 | 6(J1~J6) | 腰回转 / 肩俯仰 / 肘俯仰 / 腕滚转 / 腕俯仰 / 法兰自转 |
| 大臂 L1 | 520 mm | J2 肩轴 → J3 肘轴 |
| 小臂 L2 | 460 mm | J3 肘轴 → J5 腕轴 |
| 腕 L3 | 130 mm | J5 → 法兰面 |
| 末端 L4 | 95 mm | 法兰 → 夹爪 TCP |
| 最大伸展 | 918.7 mm | 水平到 TCP |
| 整机高度 | 764.9 mm | 零位姿态 |
| 底座 | φ280 × 150 | 4×φ7 地脚孔 |
| 关节直径 | φ136 / φ88 | 大关节 / 腕关节 |
| 末端法兰 | ISO 9409-1-50-4-M6 | φ100,4×M6 PCD60 |
| 整机体积 | 21.78 L | 实体体积(不是包围盒) |
| 估算自重 | 约 58 kg | 按铝合金 2.7 g/cm³ 实心等效 |
这是什么:外形与运动结构正确的六轴机械臂三维模型,参数可改,能导出 STEP 给下游。
这不是什么:
# 1. 改参数:打开 build_v2.py 顶部 D 字典
D = dict(base_r=140, shoulder_z=250, L1=520, L2=460, L3=130, L4=95, ...)
# 2. 重新建模(约 4 秒出全套)
/Applications/FreeCAD.app/Contents/Resources/bin/freecadcmd build_v2.py
# 3. 重新出四视图
/Applications/FreeCAD.app/Contents/Resources/bin/freecadcmd views6.py
# 4. 改涂装:改 add() 的颜色
add("J2_腰部", waist, "#e8b923")
也可以直接用 FreeCAD 图形界面打开 robot_arm.FCStd,每个零件是独立 Part::Feature,可单独编辑。
| 环节 | 工具 | 为什么 |
|---|---|---|
| 实体建模 | FreeCAD 1.1.3(Part 内核) | 开源、可脚本化、STEP 导出规范 |
| 无头执行 | freecadcmd | 不开界面 4 秒出全套,可进 CI |
| 2D 出图 | 自写正交投影 → SVG | 无头模式没有出图接口,自己算最可靠 |
| 看图验收 | Chrome headless 截图 | 每版都截图自查,肉眼挑错 |
| 3D 预览 | three.js r140(本地) | 手机电脑都能拖,演示真关节运动 |
| 格式 | Mesh / Import | STL 打印、OBJ 网页、STEP 下游 |