457918434a
删除未被读取的 expected 配置,避免误认为拓扑已受保护。配置检查、manifest 测试及文档检查通过。
438 lines
22 KiB
Markdown
438 lines
22 KiB
Markdown
# `design.yaml` 参数说明
|
||
|
||
本文是 `sensors/<sensor>/r01/design.yaml` 的详细说明,主要面向传感器研发工程师。
|
||
|
||
|
||
本文重点解释两个命令:
|
||
|
||
- `texture_patch`:在普通 UV 展开图上生成一整张标记图案;
|
||
- `texture_patch_views`:把同一套图案拆成多个相机投影视图,并决定每个视图负责印刷哪一部分。
|
||
|
||
例子:`orisys-design texture-views .\sensors\finger\r01 --grayscale`
|
||
|
||
## 1. 总览
|
||
|
||
传感器设计工具依赖开源3维绘图软件blender以及自带的Python API 开发,需要传感器3维CAD模型、镜头FOV参数、cmos的尺寸。目前主要用于摄像头位置和标记点的设计,后续会加入光源优化。
|
||
|
||
摄像头位置的设计主要是确保在镜头FOV限制下,可以完全覆盖传感的表面,分为感知面积最大化和死区清除两部分。
|
||
|
||
标记点设计目的是:
|
||
* 算法上要导出unwarp conformal的平面图,把3维变形映射到2维计算同时降低畸变。
|
||
* 生产上要在不可展曲面上印刷/雕刻标记点,程序需要导出曲面在加工平面上投影的平面图,格式包括 PNG、SVG 或 PDF。
|
||
|
||
导出的图片类型一览:
|
||
```text
|
||
Blender 三维传感表面 (sensing surface)
|
||
├─ `export` conformal UV 展开 → 计算用
|
||
│
|
||
├─ `texture` 单相机投影(projected from view) UV 展开 → 生产用,一张图覆盖整个表面
|
||
│
|
||
└─ `texture-views` 多个相机投影视图 + 分割 → 生产用,每张图只印自己负责的区域
|
||
```
|
||
设计参数放置在`sensors/<sensor>/r01/design.yaml`里面,具体设计资源参考现有传感器的文件树。
|
||
|
||
### 1.1 基础原理
|
||
|
||
叠动视触觉传感器基于单色光技术,标记图案要具备高密度纹理信息,用于光流追踪,目前采用随机彩色方格矩阵纹理设计和UV打印生产,对于平面传感器可以简单密铺,对于Finger曲面传感器需要考虑曲面畸变、镜头透视误差、可视区域、可生产性等等,要在3维层面进行设计,与三维绘图的呈现方式类似。考虑到代码兼容性、价格、功能等因素,采用开源的三维绘图软件Blender和配套的python进行程序开发,可以从相机、模型、图案、光源4个部分独立和耦合设计。
|
||
|
||
设计流程是:1. 结构传感器曲面设计;2.模型导入Blender摄像头位置摆放;3.曲面不可视区域去除;4.结构曲面修改;5.模型导入Blender和标记图案设计;6.生产摄像头位置摆放和图案生产文件导出。
|
||
|
||
曲面结构除了标品外,要根据客户灵巧手可释放的空间来设计,但一般有一个非触觉版本的模型,可以作为基准来修改,考虑塑料壳、硅胶层的厚度,得出一个初步的感知曲面形状和位置。然后导入Blender进入详细设计,在结构和摄像头FOV的约束下,选择合适的摄像头摆放位置来达到可视区域的最大化,再根据摄像头FOV去除曲面的不可视区域,然后反馈结构进行修改。最后根据修改后的摄像头位置、曲面结构,生成计算用和生产用标记点图案。
|
||
|
||
计算用标记点图案作用是把在三维空间的曲面投影到二维的平面上,方便通过过去用于平面的算法计算,投影方法目前采用conformal投影,未来可以尝试其他方法。三维到二维的投影通过Blender里面在实际摄像头位置的透视投影相机,和感知曲面的模型获取,并通过`export`指令导出图案和投影矩阵。生产用图案是通过Blender的正交投影相机模拟在传感器治具正上方,由加工设备(UV打印机或激光雕刻机)看到的形状/投影,从而把我们在曲面上的目标图案,从三维空间投影到生产的二维平面上,支持多角度生产和重复部分去除功能。
|
||
|
||
通过Bleder Python API,在具备视触觉传感器结构和材料特性下可以进行物理准确的仿真,是本设计和模拟工具的核心支撑。
|
||
|
||
|
||
### 1.2 Blender 使用
|
||
以下文档基于Blender 5.0 版本 (5.0.1)编写,如非必要不进行版本更新。
|
||
|
||

|
||
|
||
Blender的资源树在右上方,不同集合(Collection)分别代表不同的资源:
|
||
|
||
| 集合 | 种类 | 作用 | 导出 |
|
||
| --- | --- | --- |--- |
|
||
| ASSEMBLY| mesh、摄像头 | 外壳模型、生产视角摄像头 |所有网格物体,cam_uv_**x** |
|
||
| EXCLUDE | 非导出物体 | 文件暂存 |无|
|
||
| EXPORT_COMPUTE| mesh | 感知曲面 |sensing_surface|
|
||
| FRAMES| empty | 原点定义 |origin_sensor |
|
||
| DESIGN_SIM| 摄像头、光源 | 视场设计仿真 |cam_sensor |
|
||
|
||
|
||
|
||
|
||
---
|
||
# 下方文档是AI生成,待整理
|
||
---
|
||
|
||
### 1.1 初学者需要知道的几个词
|
||
|
||
|术语|简单解释|
|
||
|---|---|
|
||
|UV|把三维表面的点映射到二维平面的坐标。`U`、`V` 类似图像中的 `x`、`y`|
|
||
|UV 展开(unwrap)|像展开纸盒一样,把弯曲表面摊到二维平面;允许人为安排接缝和布局|
|
||
|Project from View (Bounds)|从指定相机看向物体,把画面投影到 UV,并缩放到 `[0,1]²`|
|
||
|pattern camera|定义标记图案从哪个方向投到表面,即“图案来源”|
|
||
|region camera|判断一个区域由哪个印刷视图负责,即“区域分工”|
|
||
|ownership|某个三角形最终归哪一个视图打印|
|
||
|hole|没有任何视图负责的表面区域,会形成漏印或“秃斑”|
|
||
|seam|Blender 中标记的接缝,用于把表面分区|
|
||
|page|输出 SVG/PDF 对应的实际物理尺寸,单位为毫米|
|
||
|raster|PNG 的像素尺寸,例如 `3700 × 3280 px`|
|
||
|
||
### 1.2 阅读参数时遵守三条规则
|
||
|
||
1. **每一个测量值都必须说明失效条件。** 例如相机移动后,以旧相机位置测出的覆盖率就不能
|
||
继续使用。
|
||
2. **测量条件是结果的一部分。** 涉及区域相机时,必须同时记录相机位姿,因为位姿就是算法
|
||
输入。
|
||
3. **文件哈希只代表测量当时的文件。** `geometry.blend` 会持续修改。引用旧哈希前必须重新
|
||
计算,不能把历史哈希当成当前状态。
|
||
|
||
本文最重要的目的,是防止一个过期数值继续显得“很合理”。只把说明写在 YAML 注释里,没有
|
||
自动失败路径;参数失效后程序仍可能正常运行,却生成错误结果。因此本文会明确写出每个关键
|
||
数值的来源、失效条件和重测方法。
|
||
|
||
## 2. 两种纹理命令的区别
|
||
|
||
|项目|`texture`|`texture-views`|
|
||
|---|---|---|
|
||
|YAML 配置块|`texture_patch`|`texture_patch_views`|
|
||
|输出定义|`uv_outputs`:名称到文件名的映射|`pairs[]`:视图 ID、相机、UV map|
|
||
|二维布局|普通 UV 展开,不是相机投影|由相机拟合到边界的投影视图|
|
||
|物理页面|`fixed`:读取 `texture_patch.vector` 中声明的毫米尺寸|`auto`:从相机图像平面推导,并验证它确实是投影视图|
|
||
|区域归属|不需要,一张图覆盖整个表面|必须,每个 pair 都包含完整表面,但只打印归自己负责的部分|
|
||
|任务格式|`texture-job-v3`|`texture-job-multiview-v1`|
|
||
|Blender 驱动|`blender/scripts/random_patch_dd02c.py`|`blender/scripts/random_patch_multiview.py`|
|
||
|
||
`texture_patch_views` 会从 `texture_patch` 继承以下“图案本身”的设置:
|
||
|
||
- 栅格尺寸 `width`、`height`;
|
||
- 网格数量 `nx`、`ny`;
|
||
- 随机种子 `seed`;
|
||
- 固定页面备用值 `vector`;
|
||
- 颜色配置;
|
||
- `edge_sample_grid`。
|
||
|
||
代码入口是 `texture_views.resolve_views_settings(...)`,内部调用
|
||
`resolve_texture_settings(...)`。它不会继承 `uv_outputs`、`merge`、`seam` 或 `print`,
|
||
因为这些字段分别属于单图输出或多视图分区。
|
||
|
||
继承方向只有一个:`texture_patch` 是页面、颜色和图案随机性的基础配置;
|
||
`texture_patch_views` 在此基础上增加投影视图和区域分工。
|
||
|
||
> 为什么不合并两个配置块?在 `texture_patch` 中,页面是人工声明的输入,例如
|
||
> `18.5 × 16.4 mm`;在 `texture_patch_views` 中,页面是经过验证后从相机投影推导出的
|
||
> 结果。合并后,`page.mode` 的含义会依赖旁边是否出现某个键,还会削弱当前严格的未知键
|
||
> 检查,使拼错的配置可能被静默忽略。如果未来出现第三个消费者,或者 `uv_1`、`uv_2`
|
||
> 不再是边界投影,再重新评估公共配置结构。
|
||
|
||
## 3. `texture_patch`:在普通 UV 展开图上生成图案
|
||
|
||
命令会为 `uv_outputs` 中的每个 UV map 各生成一套 PNG、SVG 和 PDF。所有输出共用相同的
|
||
随机颜色和页面设置,仅 UV 布局不同。
|
||
|
||
UV 展开必须预先在 Blender GUI 中完成并保存在 `source_blend`。无界面运行只读取已有 UV
|
||
map,不会自动创建或重新展开 UV。
|
||
|
||
### 3.1 `uv_outputs` 的顺序不能随意调整
|
||
|
||
程序通过下面的方式构造输出列表:
|
||
|
||
```python
|
||
block["uv_outputs"].items()
|
||
```
|
||
|
||
因此 YAML mapping 的顺序会进入 `texture-job-v3` 的 `outputs[]`。目前四个测试固定要求顺序
|
||
为:
|
||
|
||
```text
|
||
["produce", "compute"]
|
||
```
|
||
|
||
仅从生成像素来看,调换顺序不会改变颜色,因为 `patch_colors` 在遍历各 UV 前只计算一次。
|
||
但任务文件数组顺序会改变并导致测试失败,所以不要为了“整理”而重排。
|
||
|
||
### 3.2 为什么有的配置是 `nx == ny`,有的是 `80 × 45`
|
||
|
||
`nx`、`ny` 表示相机空间中的图案网格数量。`finger-xynova/r01` 的 `cam_sensor` 是正方形
|
||
画幅,所以 `nx == ny` 可以让相机空间中的单元接近正方形。
|
||
|
||
`finger/r01` 使用 `80 × 45`,来自 16:9 相机。这个比例对它自己的相机是合理的,不能因为
|
||
另一个型号采用方形网格就统一修改。
|
||
|
||
### 3.3 `width`、`height` 与 `vector` 的关系
|
||
|
||
- `width`、`height`:PNG 栅格尺寸,单位是像素;
|
||
- `vector.width_mm`、`vector.height_mm`:SVG/PDF 对应的物理页面尺寸,单位是毫米。
|
||
|
||
当前两个 revision 都使用 200 px/mm:
|
||
|
||
```text
|
||
3280 / 16.4 = 200
|
||
3200 / 16.0 = 200
|
||
3700 / 18.5 = 200
|
||
```
|
||
|
||
维护时应满足:
|
||
|
||
```text
|
||
raster pixels = px_per_mm × physical millimetres
|
||
```
|
||
|
||
`_warn_if_page_aspect_differs` 会比较栅格长宽比与物理页面长宽比。如果不一致,SVG/PDF
|
||
填满页面时会沿某一方向被拉伸。保持上述关系,警告就不会出现。
|
||
|
||
### 3.4 `seed` 是整个物理图案的随机种子
|
||
|
||
固定 `seed` 是为了让同一配置反复运行得到相同的图案。同一次生成中的 PNG、SVG、PDF 和
|
||
所有 UV map 共用一套颜色。
|
||
|
||
`texture-views` 里的每个 pair 也必须使用相同 seed,因为它们打印的是同一个物理表面的
|
||
不同部分。如果每个视图使用 `seed + i`,两个印刷文件会在同一个表面上产生不同图案。
|
||
|
||
> 已知文档缺陷:`orisys-design texture-views --seed` 的帮助文字声称“第 i 个 pair 使用
|
||
> `seed + i`”,但实际代码让所有 pair 使用 `settings.seed`。实际代码行为是正确的,CLI
|
||
> 帮助文字需要另行修正。
|
||
|
||
## 4. `texture_patch_views`:多个投影视图和区域分工
|
||
|
||
本节说明**每个键的语义**。为什么这样设计——为什么所有权在生成之前决定、为什么单位是三角形、
|
||
以及两种 seam 模式各自的适用条件——见
|
||
`D:\orisys_ws\docs\workflow\multiview-ownership-decision.md`。测量数据(拓扑、相机、入射角、
|
||
cell pitch)见 [`geometry-measurements.md`](geometry-measurements.md)。
|
||
|
||
这个流程较容易混淆,因为它同时使用三类信息。
|
||
|
||
### 4.1 三种角色
|
||
|
||
1. **图案相机 `pattern_camera`**:决定标记图案从哪个方向投到传感表面。所有视图共用一个
|
||
图案来源,默认是 `cam_sensor`。
|
||
2. **区域相机 `pairs[].camera`**:决定该视图适合负责哪些三角形。它只参与区域分工,不是
|
||
图案来源。
|
||
3. **`pairs[].uv_map`**:决定该视图最终写入哪个二维布局。
|
||
|
||
可以把它们理解成:pattern camera 决定“印什么”,region camera 决定“谁来印”,UV map
|
||
决定“印刷文件中的坐标”。区分这三者,也能解释为什么片段数量和三角形数量不是同一个概念。
|
||
|
||
### 4.2 `merge.incidence_limit_deg`
|
||
|
||
区域归属以 loop triangle 为单位。一个三角形只有同时满足以下条件,才可能归某个视图负责:
|
||
|
||
- 区域相机能看到它;
|
||
- 相机视线与表面法向的夹角不超过 `incidence_limit_deg`;
|
||
- 投影面积达到要求。
|
||
|
||
没有任何视图能够负责的三角形就是 hole,会造成漏印。
|
||
|
||
在 `finger-xynova/r01` 上,使用真正的 `assign_ownership` 和本次运行生成的 ground truth,
|
||
测得:
|
||
|
||
|`incidence_limit_deg`|hole fraction|相对 `max_hole_fraction: 0.02`|
|
||
|---|---|---|
|
||
|62°|**0.0480**|**失败**|
|
||
|65°|0.0130|通过|
|
||
|**70°**|**0.0001**|通过|
|
||
|
||
这里 `min_triangle_coverage` 不是限制因素:把它从 0.60 放宽到 0,在 62° 和 70° 下都不改变
|
||
结果。
|
||
|
||
这组测量对应以下区域相机位姿:
|
||
|
||
|相机|方位角|仰角|距离|
|
||
|---|---:|---:|---:|
|
||
|`cam_uv_1`|308.26°|−24.46°|32.62 mm|
|
||
|`cam_uv_2`|231.74°|−24.46°|32.62 mm|
|
||
|
||
**只要移动区域相机,这张表就立即失效。** `incidence_limit_deg` 描述的是“特定相机位姿与
|
||
特定表面”的组合,不是传感器型号自身永远不变的属性。重新调整相机后必须重跑扫描。
|
||
|
||
> 已撤回的旧结论:早期 `design.yaml` 曾写过“默认 62° 时 hole 面积为 0.100 mm²、比例
|
||
> 0.0002”,以及“4960/5007 个三角形有归属,输出 20454 + 21483 个片段”。这些数据在
|
||
> 相机移动前成立,现在已经失效。保留这段记录,是为了说明为什么相机相关数据必须写明
|
||
> 重测触发条件。
|
||
|
||
不要删除 YAML 中显式设置的 `incidence_limit_deg: 70.0`。代码中
|
||
`texture_views.MERGE_DEFAULTS` 和 `blender/scripts/texture_merge.py` 的默认值都是 62.0,
|
||
并有测试要求两处一致。但对当前 Xynova 表面,62° 会产生 4.8% hole;删除覆盖值会静默恢复
|
||
错误默认值。
|
||
|
||
### 4.3 `max_hole_fraction` 是阻断门槛
|
||
|
||
当 hole fraction 超过 `max_hole_fraction` 时,命令会失败并报告:
|
||
|
||
- 实际 hole fraction;
|
||
- 未覆盖的三角形数量;
|
||
- 可能原因。
|
||
|
||
它不是普通警告。这项检查是在一次 4.8% 漏印被静默输出之后增加的,目的是让“表面有秃斑”
|
||
从肉眼发现的问题变成自动失败。
|
||
|
||
### 4.4 `page.mode: auto` 与 `fixed`
|
||
|
||
`auto` 只适合使用 Blender **Project from View (Bounds)** 生成的布局。这种布局把相机图像
|
||
平面映射到 `[0,1]²`,程序可通过最小二乘仿射拟合反推出页面的实际尺寸。
|
||
|
||
程序不会因为写了 `auto` 就盲目信任 UV。它会验证:
|
||
|
||
- 最大拟合残差不超过 `1e-5`;
|
||
- UV 边界位于 `[0,1]²`。
|
||
|
||
真实投影视图的拟合误差大约为 `1.2e-7`;普通 UV 展开的误差约为 0.17–0.70,因此会被拒绝。
|
||
`auto` 不会在失败时悄悄退回固定页面。
|
||
|
||
`fixed` 使用 `texture_patch.vector` 中的页面尺寸。`produce` 和 `compute` 是真正的普通 UV
|
||
展开,必须使用 `fixed`;从相机反推它们的页面没有物理意义。
|
||
|
||
自动页面最终按整数像素确定:
|
||
|
||
```text
|
||
page size = rounded raster pixels / px_per_mm
|
||
```
|
||
|
||
这样页面和栅格的长宽比天然一致。200 px/mm 下,舍入导致的尺寸误差最多为 0.0025 mm,
|
||
远低于当前 0.1 mm 对位公差。
|
||
|
||
已经测得的页面尺寸:
|
||
|
||
|revision|view|对应测量位姿下的页面|
|
||
|---|---|---|
|
||
|`finger/r01`|`uv_1`|17.510 × 15.975 mm|
|
||
|`finger/r01`|`uv_2`|17.510 × 15.980 mm|
|
||
|`finger-xynova/r01`|`uv_1` / `uv_2`|17.670 × 23.565 mm|
|
||
|
||
这些数值会随相机位置改变,正是使用 `auto` 的原因。Xynova 相机重新定位后,页面从
|
||
21.200 × 23.200 mm 自动更新为 17.670 × 23.565 mm。引入自动推导前,固定共享页面在
|
||
`finger/r01` 上误差为 6.9%,在 `finger-xynova/r01` 上误差达到 23%,而且横竖方向相反。
|
||
|
||
### 4.5 `seam.boundary`、`pins` 与 `gap`
|
||
|
||
`boundary: use_seam` 表示使用 Blender 中人工标记的 seam 作为区域边界。图案生成阶段不会
|
||
读取 seam;`patch_projection.py` 只读取 `loop_triangles` 和 `uv_layers`。seam 由后续
|
||
ownership 步骤使用。
|
||
|
||
`pins` 用于在自动分配不符合设计意图时,强制某个连通区域归指定视图。默认留空,让覆盖率
|
||
指标决定归属。每次增加 pin 都应写清原因,避免把几何或相机错误隐藏成“人工设置”。
|
||
|
||
如果启用 gap,总间隙宽度是 `alignment_tolerance_mm` 的两倍。原因是两次独立印刷都可能
|
||
产生最大对位误差;每一侧退让一个公差,最坏情况下仍不会重叠。
|
||
|
||
- `apply: post_process`:将 UV 多边形裁剪到 seam 偏移后的半平面,生成物理宽度准确的直边;
|
||
- `apply: geometry_trim`:丢弃整个片段,会产生锯齿边,仅保留作比较。
|
||
|
||
> 当前仍可看到的阶梯形状来自按三角形分配的 ownership 边界,而不是 gap 自身。gap 只是
|
||
> 从这条阶梯边界向内退让。要得到平滑边界,需要支持三角形内部的更细粒度分区。
|
||
|
||
### 4.6 `print.base_fill`
|
||
|
||
`base_fill: owned` 会把本视图负责的三角形填成白色,其余区域填黑。这样白色底层也已经沿
|
||
seam 分开,两张印刷文件不会在同一位置重复打印白底。
|
||
|
||
## 5. 常用参数速查
|
||
|
||
|参数|当前值|来源/测量条件|什么时候失效|怎样重测|
|
||
|---|---:|---|---|---|
|
||
|Xynova `incidence_limit_deg`|70.0|第 4.2 节记录的相机位姿|移动区域相机或修改表面|对新 ground truth 运行 `assign_ownership`,扫描 62/65/70/75°|
|
||
|自动页面|见第 4.4 节|对应区域相机位姿|移动相机或修改网格|重跑 `texture-views`,读取 `_print_views.json`|
|
||
|`px_per_mm`|200|设计选择|修改栅格或页面尺寸|计算 `width / vector.width_mm` 和 `height / vector.height_mm`|
|
||
|`alignment_tolerance_mm`|0.1 mm|当前印刷与对位能力假设|更换打印、夹具或对位工艺|通过实际计量重新评估,不由本仓库推断|
|
||
|
||
### 内置默认值不适合当前表面的键
|
||
|
||
|键|内置默认值|为什么必须保留在 YAML 中|
|
||
|---|---:|---|
|
||
|Xynova `incidence_limit_deg`|62.0|当前表面会产生 4.8% hole;显式 70.0 是必要配置|
|
||
|
||
## 6. 已知几何漂移
|
||
|
||
仓库中的历史资料对 Xynova sensing surface 的描述互不一致:
|
||
|
||
|来源|记录值|
|
||
|---|---|
|
||
|`probe-pipeline.md`|2508 vertices / 4834 polygons|
|
||
|`xynova-texture-investigation.md`|4818 triangles + 16 quads|
|
||
|当前实际测量|2584 vertices / 5007 triangles|
|
||
|
||
`build/probe/finger-xynova/r01/probe_frames.npz` 来自 2508 顶点的
|
||
`sensing_surface_918_s`,而当前带 seam、`uv_1` 和 `uv_2` 的表面有 2584 顶点。因此
|
||
`tests/test_render.py::test_end_to_end_render_manifest` 会在顶点数量检查处失败。
|
||
|
||
这是过期 fixture,不是纹理生成错误。修复方式需要先决定哪个表面才是该 revision 的唯一权威
|
||
表面,然后选择其中一种方案:
|
||
|
||
1. 为当前权威表面重新生成 probe frames;或
|
||
2. 把 seam 和 UV 布局制作到已经生成 probe frames 的那个表面上。
|
||
|
||
当前 revision 包含六个 sensing-surface 变体:
|
||
|
||
```text
|
||
sensing_surface
|
||
sensing_surface_0
|
||
sensing_surface_0918
|
||
sensing_surface_0928
|
||
sensing_surface_45
|
||
sensing_surface_918_s
|
||
```
|
||
|
||
其中 `_0928` 与 `sensing_surface` 位于相同位置,是重合副本。`EXCLUDE` collection 的
|
||
`exclude=False` 表明它只是名称叫 EXCLUDE,并没有在 view layer 中真正排除。射线检测会先
|
||
击中这个副本,随后把所有片段判为不可用。
|
||
|
||
目前 `_0928` 已隐藏;`texture-views` 现在也会在发生遮挡时失败,并指出拦截射线的对象,
|
||
不会继续生成空白纹理。
|
||
|
||
## 7. 两个 revision 的差异
|
||
|
||
|项目|`finger/r01`|`finger-xynova/r01`|
|
||
|---|---|---|
|
||
|栅格尺寸|3280 × 3200|3700 × 3280|
|
||
|固定页面|16.4 × 16.0 mm|18.5 × 16.4 mm|
|
||
|`nx`, `ny`|80, 45(16:9 相机)|80, 80(方形相机)|
|
||
|seam 边数|32|45|
|
||
|自身 hole|0.049 mm²(0.0001)|0.092 mm²(0.00015)|
|
||
|`incidence_limit_deg`|62.0;对应旧相机位姿,移动后必须重测|70.0|
|
||
|`optics` 配置|无|有|
|
||
|
||
不能为了让两个 revision 的 YAML 看起来一致,就统一这些值。分辨率、页面、网格比例、相机
|
||
位姿和入射角门槛都是各自设计与测量条件的一部分。
|
||
|
||
## 8. 新同事修改参数时的建议步骤
|
||
|
||
1. 先确认正在修改哪个 sensor 和 revision,不要把 `finger` 的参数复制到
|
||
`finger-xynova` 后直接使用。
|
||
2. 判断改动属于“图案”“UV 布局”“相机位姿”“印刷工艺”还是“几何”。
|
||
3. 根据第 5 节查找被改动失效的测量值。
|
||
4. 如果移动区域相机,重测 ownership、hole fraction 和自动页面。
|
||
5. 如果修改网格,核对拓扑、UV、seam、probe fixture 和 field-domain 相关输出。
|
||
6. 如果修改栅格或物理页面,重新计算两个方向的 `px_per_mm`,不能只检查宽度。
|
||
7. 运行对应测试并查看生成任务中的 manifest,不要只凭最终图片看起来正常。
|
||
8. 将新数值、测量条件、结果和下次失效条件一起更新到本文。
|
||
|
||
遇到结果异常时,可以按以下顺序排查:
|
||
|
||
```text
|
||
输出为空
|
||
→ 是否有重合/遮挡对象
|
||
→ region camera 是否能看到表面
|
||
→ UV map 名称和对象是否正确
|
||
|
||
表面有漏印
|
||
→ 查看 hole fraction
|
||
→ 检查 incidence_limit_deg
|
||
→ 检查相机位姿和 footprint 条件
|
||
|
||
页面比例不对
|
||
→ 确认 UV 是 unwrap 还是 Project from View (Bounds)
|
||
→ unwrap 使用 fixed;投影视图才使用 auto
|
||
→ 检查 raster / px_per_mm / page 的关系
|
||
|
||
接缝呈阶梯形
|
||
→ 先区分 ownership 边界与 gap
|
||
→ gap 使用 post_process 只能让退让边变直
|
||
→ 平滑 ownership 需要更细的分区算法
|
||
```
|
||
|
||
最后,不要删除“已知缺陷”“撤回结论”和失效条件。这些内容不是历史包袱,而是防止同类问题
|
||
再次以合理外观进入生产输出的工程约束。
|