XLeRobot · 机器人头 · 2026-09-09

V13 骨架 frame · 图纸、渲染,以及文件里到底有什么

这一页上的每个数字都是从下面那个可下载的 STL 实测出来的,不是从 .scad 源码读的。 这个区别很要紧:源码里有个 assert 保证眼睛走线口至少 20×10 mm,而导出的文件里那个口子根本不存在。

先说结论

能不能用?能 —— 当试装肋笼用。 单一连通体,201.67 cm³,包围盒 123.73 × 128.00 × 155.87 mm。肋笼、耳罩安装台、后梁接口、眼圈这几处几何都在,尺寸与设计一致。

坏在哪:这个文件里没有眼窝背板。 显示窗、24×14 屏幕沉槽、排线槽、22×12 中央走线口、两个 Ø8 穿线孔,源码里全都写了,STL 里一个都没有。中央整块 Ø48 是空气。这是布尔实测的结论,不是看图猜的 —— 见第五节。

cost 查出来花了约 40 分钟探针。修法已经找到并用布尔验证过 —— 是两个必须同时做的改动,因为最显然的一行改法会让情况更糟。刻意没有落地:眼睛还要不要屏幕是个设计决定。第五节有数字。

另外要知道 frame 这里实测 201.67 cm³,那边标 245.73;quarter2 实测 52.28,那边标 88.98。同一套算法把 cam_frame 的 53.32 完全复现,所以不是算法问题,是那批数字属于另一次导出。第七节有完整对照。

一、下载

v13_frame.stl
2 551 925 B · ASCII STL · 14 196 tri · 201.67 cm³
下载 STL

它和仓库里 02-hardware/robot-head/v13-frame-first/stl/frame.stl 逐字节相同 —— md5 都是 33bfc8b6a7a1e676d79ffb7b50de4af9。仓库那份是源,这份是发布副本。

工程图(SVG 矢量)
v13f_drawing.svg · 325 KB
原尺寸打开

打印前先看 frame 是整只不分块的,本来就不是拿来打的 —— 它用来看整体。真正要打的是 quarter0..3。见第六节。

二、工程图

第一角投影,单位 mm。每个尺寸都由 measure.py 从 STL 实测,没有一个是抄 .scad 常量的。轮廓线是从网格提取的轮廓边加折边。

V13 frame engineering drawing

v13f_drawing.svg · front / right / top + eye socket section A–A

实测尺寸

项实测源码标称怎么测的
总宽 X123.73124.0STL 包围盒
总深 Y128.00—STL 包围盒
总高 Z155.87—STL 包围盒,z 42.00..197.87
眼睛通光孔 Ø48.148 EYE_Dy=30 切片,过中心扫描
眼圈外径59.960 EYE_D+2·RIM同一切片,实体外边界
眼睛中心高 Z104.0104 EYE_ZC通光孔竖直跨度
耳罩安装面x = ±57—x=56 有料、x=58 空
体积201.67 cm³—全部三角形散度定理

三、六视图

全部用正交 z-buffer 直接从 frame.stl 渲染,共用同一比例尺,各视图可以互相比对。不经过 OpenSCAD —— 它们显示的是文件里有什么,不是源码说应该有什么。

front view

Front · 正面(眼睛这一面)

back view

Back · 背面(后梁接口)

left view

Left · 左视(耳罩台)

right view

Right · 右视

top view

Top · 俯视

bottom view

Bottom · 仰视(立柱开口)

轴测

iso

Iso · 前左上

iso rear

Iso rear · 后右上

eye iso

Eye · 眼窝方向

看正面图和眼窝图:能透过眼圈直接看到背景。那就是第五节的发现,不用测也看得见。

四、这个件上有什么

特征STL 里有没有说明
拱肋笼(4 个经线平面 = 8 条肋)OK每个视图都看得到
耳罩安装台,左右各一OK面在 x=±57,环形(中间通)
后梁接口OK见背面图
眼圈 + 镜筒OK外径 Ø59.9,孔 Ø48.1
眼圈侧面挂载孔(8× M3 底孔)OK在凸出的 4mm 上,外面够得到
眼窝背板(Ø54 × 5)只剩外环只剩 3mm 宽的环;中央 Ø48 是空的
显示窗 18×9没有这四项都在缺失的 Ø48 那块里
屏幕沉槽 24×14×2.6没有
中央走线口 22×12没有
两个 Ø8 穿线孔没有
网格封闭性2 条非流形边没有开放边界;21 290 条边是流形的,2 条是 4 度边。切片软件能处理;OpenSCAD 的 CGAL 拒绝导入。

五、眼睛接线口检查

这是点名要查的,所以把整条证据链摆出来,而不是只给个结论。

源码承诺了什么

generate_head_v13.scad 里写着操作者的要求,还有一条 assert 强制它:

EYE_PORT_W  = 22;     // 宽(>= 20)
EYE_PORT_H  = 12;     // 高(>= 10)
assert(EYE_PORT_W >= 20 && EYE_PORT_H >= 10,
       str("中央走线口 ", EYE_PORT_W, "x", EYE_PORT_H, " 小于操作者要求的 20x10"));

这条 assert 是通过的。它证明的是【常量】合规 —— 完全没有说那个开口能不能活到导出的实体里。

第一步 —— 在背板该在的位置切开 STL

背板占 y 17..22。在其中四个平面上做射线投射占据判定,看眼睛正中那个点(x=0, z=104):

y = 17.3   centre solid? false    背板最前
y = 18.0   centre solid? false    沉槽下方 2.4mm 实心区
y = 19.5   centre solid? false
y = 21.5   centre solid? false

每一层都报出一个 48.00 × 48.00 mm 的洞,面积 1805.28 mm²。π·24² = 1809.6。那就是通光孔,占满了背板本该填的整个空间。

第二步 —— 布尔求证,从源码重算,不经过 STL

射线投射理论上可能被那两条非流形边骗到,所以把结论用另一条路重新推了一遍:拿重算的实体和背板标称包络求交:

intersection(){ head_frame(); cylinder(d=54, h=5) at y17..22 }  =   2.427 cm³
intersection(){ head_frame(); cylinder(d=48, h=5) at y17..22 }  =   0.024 cm³

对照(纯几何算)
∅54×5 整块背板                                              =  11.451 cm³
∅48..∅54 × 5 外环                                          =   2.403 cm³
∅48×5 中央(屏幕/沉槽/走线口都该在这块里)                   =   9.048 cm³

2.427 对纯外环的 2.403。背板就是个环,别的什么都没有。本该承载全部开口的那 9.048 cm³ 中央区实测 0.024 cm³ —— 那是 Ø48 圆柱面离散化的残渣。

第三步 —— 为什么

两个独立的错误叠在一起。

A通光孔从背板的近端面开始挖,不是远端面
module eye_cut() {
    y1 = EYE_BP_Y;      // 背板前表面 17 —— 往前 4mm 就收
    translate([0, y1, EYE_ZC]) rotate([-90,0,0])
        cylinder(d = EYE_D, h = (HEAD_YC + HEAD_R + 40) - y1);

注释把 y=17 叫作「背板前表面」。它不是 —— eye_backplate() 放在 y=17 然后往 +y 拉伸 5mm,所以 17 是板开始的地方。从 17 往前挖 Ø48,正好把板的整个中央挖掉。

B一根实心镜筒在开口被挖之前就把它们填平了
module eye_barrel() {              // ∅60 × 23 实心圆柱,y 17..40
    translate([0, HEAD_YC + HEAD_R - EYE_DEPTH - 10, EYE_ZC]) rotate([-90, 0, 0])
        cylinder(d = EYE_D + 2*EYE_RIM, h = EYE_DEPTH + 12, $fn = 96);
}
module eye_solid() { union() { eye_ring(); eye_barrel(); eye_backplate(); } }

eye_backplate() 仔细地把窗、槽、口、孔都 difference 掉了 —— 然后 union() 往上直接叠了一根横跨 y 17..40 的 Ø60 实心柱。所有开口在 head_frame() 还没跑的时候就被填回去了。

第四步 —— 显然的那个改法没用

错误 A 看着像一行就能修:把通光孔起点从 EYE_BP_Y 挪到 EYE_BP_Y + BP_T。这个改法做出来测了:

中央 ∅48×5 区域内的料
修前                    0.024 cm³   ← 等于没有背板
一行改法之后            9.046 cm³   ← 等于实心一块,开口还是没有
理论满料                9.048 cm³

板回来了,开口一个都还是没有,因为错误 B 没动:实心镜筒还在填。对一块职责就是过线的板来说,从「没有板」变成「一块没有孔的板」不算改进。

第五步 —— 管用的那个改法

两个错误必须一起改:挪通光孔起点,同时把背板的开口从 eye_backplate() 里提成独立 module,好在 head_frame() 的 union 之后再减 —— 那时实心镜筒已经填不掉它们了。做出来测了:

中央 ∅48×5 区域内的料
修前                       0.024 cm³   ← 没有背板
只改通光孔起点             9.046 cm³   ← 实心一块,开口还是没有
两个一起改             5.798 cm³   ← 背板回来了,开口也在

校验
开口实体总体积(单独导出)  3.337 cm³
9.048 − 3.337          =  5.711 cm³   对 5.798,差 0.087 —— 排线槽有一段伸到 ∅48 之外,不计入中央区

跑测过 这个修法是布尔验证过的,不是讲道理讲出来的。但刻意没有落到仓库里:眼睛到底还要不要屏幕是个设计决定,而这一页发布的 STL 就是当前磁盘上的那一份。

实际意味着什么

六、装配

frame 是整只,看用的。真正打印的是四块,切在 45°/135°/225°/315°,这样没有一条缝落在接口上 —— 耳罩台在 0° 和 180°,眼睛在 90°,后梁在 270°。

q0眼睛 q1左耳 q2后梁 q3右耳 前 / FRONT 0° 后 / REAR 180° 45°135° 225°315° 装配顺序 / order 1. q0 先打这块 — 含眼睛,最复杂 2. q1 插销对齐 → 拧 M3 3. q2 同上 4. q3 最后一条缝自然闭合 每条缝 3 处:先销后螺丝 销孔单边配合 0.175 mm 热熔螺母装在「结束面」一侧 螺丝从加厚垫的远端面进刀 — 那一面朝着笼子空当,够得到

分缝图:45/135/225/315 刻意避开全部四个接口

quarter0

quarter0 · 55.66 cm³ · 眼睛

quarter1

quarter1 · 43.74 cm³ · 左耳罩台

quarter2

quarter2 · 52.28 cm³ · 后梁板

quarter3

quarter3 · 44.51 cm³ · 右耳罩台

装在里面的两个件

cam_frame_fitted

cam_frame_fitted · 78.22 cm³ · 相机框(领结)。出线口是 24×12 的封闭通孔,不是外部可见的缺口 —— 翅膀为此做成中脊 30 / 上下缘 12,前后各留 3 mm 壁。与骨架+皮肤干涉实测 0.0000。打印用 2 层墙 + 10% 填充。

core_link

core_link · 22.13 cm³ · 内部承力链,整个头挂在它上面

装配流程

1先打 quarter0

它带眼睛,是最复杂的一块。先打它,在给另外三块投料之前先验证销孔配合。

另外:quarter0 正是第五节那个背板缺陷影响到的件。如果修复落地,要重打的就是它。

2打其余三块前先试销

单边配合 0.175 mm。太紧就调大 PIN_FIT 重打一块。别硬敲。

3按 q0 → q1 → q2 → q3 装

每条缝 3 处。先插销对齐,再拧 M3。热熔螺母装在「结束面」那一侧。螺丝从加厚垫的远端面进刀 —— 那一面朝着笼子的空当,螺丝刀伸得进去。最后一条缝自然闭合。

4装 core_link,再装 cam_frame

core_link 是承力链:相机 → 云台耳板 → 后横梁 → 后盖内侧。整个头挂在它上面,所以它要在任何造型件之前装。

5改过任何尺寸就重跑 check_parts.py

它能抓住渲染图看不出的悬空碎片:一块 0.16 cm³ 悬在空中的销,和长在本体上的销,在图上一模一样。

有必要直说:check_parts.py 查的是连通性。它抓不到缺失的背板,因为一个圆环是完美连通的。连通和完整是两个问题。

七、体积:这个文件 对 旧页面

旧的 头部 V13 · 定稿 页上列了各件体积。对当前磁盘上的文件测同一个量,复现不出来。

件现在实测旧页面差
frame201.67245.73−44.06
quarter055.6663.07−7.41
quarter143.7443.84−0.10
quarter252.2888.98−36.70
quarter344.5144.60−0.09
cam_frame53.3253.320.00
core_link22.1322.45−0.32

cam_frame 完全复现,说明测法没问题。frame 和 quarter2 差了几十 cm³,那是另一个模型,不是舍入。旧页面的体积那一列按过期处理;磁盘上的文件才是这一页测的东西。

另外 quarter0..3 合计 196.19,frame 是 201.67,差 5.48 cm³。方向和量级都符合拼缝间隙加销孔的预期,所以四块和整只是自洽的。

八、每个数字是怎么来的

结论证据等级出处
包围盒、体积、三角数跑测过measure.py · stlview.volume_cm3
通光孔 Ø48.1、眼圈 Ø59.9、中心 z=104.0跑测过measure.py · 射线投射占据图
背板中央四个平面全空跑测过inspect_eye_port.py
外环 2.427 cm³、中央 0.024 cm³跑测过OpenSCAD 布尔,从源码重算
一行改法得到 9.046 cm³ 实心跑测过对改过的 .scad 副本做 OpenSCAD 布尔
两个改法一起得到 5.798 cm³ 带孔背板跑测过对改过的副本做 OpenSCAD 布尔;开口单独导出交叉校验
修法没有落到仓库里刻意如此要先做设计决定;发布的 STL 就是磁盘上那份
2 条非流形边,无开放边界跑测过合并顶点后统计边的度数
渲染图与工程图跑测过stlview.py · render_views.py · drawing.py

全部脚本在 02-hardware/robot-head/v13-frame-first/。它们只读 STL 文件,别的都不读 —— 这正是关键:一个去读 .scad 的脚本会报告走线口是存在的。

九、接下来做什么

2026-09-09 对 2026-08-24 05:16 的 stl/frame.stl 实测,md5 33bfc8b6a7a1e676d79ffb7b50de4af9。 渲染图和工程图都由同一个文件生成;除引用的代码片段外,这一页没有任何内容取自 .scad 源码。