Two workspace documents described the multi-view ownership decision by
overlapping each other and had both gone stale: neither matched the shipped
code, and the architecture document was referenced by nothing at all. They are
archived in the workspace, and this repo now carries the parts that belong to
it.
New: docs/geometry-measurements.md. Measured properties of the r01 sensing
surface, the sensing camera, the UV layouts, the printed cell pitch and the
runtime unroll domain - topology (1032 v / 1974 t), 355.77 mm2 area with 38.1%
near-vertical wall, the off-origin centroid, 94.5% inward-facing normals, the
0.516 x 0.714 mm measured pitch against a wrong 0.205 x 0.3556 mm nominal cell,
75.6% runtime coverage, and incidence over that region (p50 55.6 deg, invariant
to adding views). Merge-mode agreement is included, with an explicit note that
these values are camera-specific and expire when a camera moves - the Xynova
surface already needs 70 deg where r01 ships 62 deg.
Wiring:
- README.md points at the measurements and says they expire.
- design-parameters.md section 4 keeps the key semantics and now links to the
workspace record for rationale and to the measurements for data, instead of
restating either.
- design.yaml: replace a self-referential comment pointing back at the same
document with the keys location and the rationale location.
No behaviour change: the YAML edit is a comment, and no source file is touched.
# Measured geometry, camera and runtime facts (`sensors/finger/r01`)
Reference measurements of the finger `r01` sensing surface, the sensing camera, and the runtime
unroll domain. These are properties of the physical part, not of any one design, so they live
here rather than in a decision record and are reused by the multi-view ownership work, the probe
bench and the optics model.
Every row states how it was obtained. Anything not re-derivable is marked as such.
## 1. Method
Read-only, never saved. Blender 5.0.1, invoked as `blender -b -P <script>` against
`sensors/finger/r01/source/geometry.blend`. The probe scripts lived in
`orisys-sensor-design/.scratch/multiview-arch/`, which is scratch and has been removed — so the
numbers below are **not re-derivable by re-running a stored script**. Anything you need to trust
today must be re-measured from the mesh, from the runtime asset named in each row, or from the
recorded blend hash.
Recorded blend hash for the 2026-09-27 measurement set: `61093B1A…`.
## 2. Sensing surface
| Fact | Value | Note |
|---|---|---|
| Topology | 1032 verts / 1974 polys, **all triangles**, 5922 loops, no modifiers | The mesh is pre-triangulated, which is what makes the loop-triangle index a valid stable key |
| Dimensions | 15.81 × 15.0 × 7.5 mm bbox | |
| Surface area | **355.77 mm²** | 1.5× the bbox footprint |
| Area distribution | **38.1 % near-vertical wall, 0 % flat top** | The cap has a 15 mm-deep circular end, so almost half the surface faces sideways |
| Position | x ∈ [−15.81, −1.77] mm; area-weighted centroid ≈ **(−8.13, 0.00, 3.14) mm** | **The surface is not centred on the origin.** Any view aimed at the origin misses it |
| Face normals | **94.5 % inward-facing** (`normal.z < 0`), `normal.z ∈ [−0.9999, +0.6755]` | Winding is not trustworthy on this mesh; see §5 |
`design.yaml` declares `expected.sensing_triangles: 1974`, but **nothing validates it** — the
value is a comment, not a gate.
## 3. UV layouts
| Fact | Value |
|---|---|
| Maps | exactly two: `produce` and `compute`, 5922 loops each; `compute` is active |
| `compute` extent | u ∈ [0.00009, 1.0], v ∈ [0.1425, 0.85742] — the empty v-band is the shipped map's domain shape, not a defect |
| Texel density uniformity | per-polygon (UV area / world area): `compute` min 2.5e-4, p05 1.1e-3, **median 1.391e-3**, p95 1.872e-3, max 4.061e-3 → **spread 2.92×** |
| `produce` density | min **0.0** — **degenerate zero-area UV faces exist**, median 2.131e-3, max 4.216e-3 |
The unwrap's non-uniformity across the surface (2.92×) is **larger** than the axis-aligned
anisotropy `docs/xynova-texture-investigation.md` measured (1.17×) — that earlier figure was taken
at the centre point, which is the good case.
`compute` is the **runtime contract**: the shipped `unroll_map_uv_s0.4.npz` was built from this
mesh and this UV layout, so changing `compute` invalidates that asset and is a release event, not
a build side effect.
## 4. Sensing camera (`cam_sensor`)
| Fact | Value | Note |
|---|---|---|
| Type and lens | PERSP, effective lens 3.5 mm | |
| Sensor width | `sensor_width` 1.794 × object scale **6.009** = 10.78 mm | The 6.009 object scale must be divided out by anything that derives a view from this camera, or the pitch is wrong by 6× |
| Position | origin 4.62 mm above the surface | |
| H-FOV | ≈ **114°** | Extremely wide and very close: foreshortening is unavoidable |
| Coverage | 1887/1974 triangles inside the frustum (**95.6 %**), **0 occluded**, **0 triangles beyond 75° incidence** | The camera is not edge-on-limited |
| Incidence over the surface | p50 **42.1°** | Intrinsic to a 355.8 mm² cap with 38 % near-vertical wall |
## 5. Printed cell pitch (measured on the surface)
| Fact | Value | Note |
|---|---|---|
| Adjacent camera-cell pitch | median **0.516 mm horizontal × 0.714 mm vertical**; horizontal spread 0.449–0.568 mm | The cell pitch is *finer vertically than horizontally on the surface* |
| `design.yaml` nominal cell | `vector.width_mm/nx = 0.205`, `vector.height_mm/ny = 0.3556` | **Wrong as a physical cell size.** The vector page (16.4 × 16.0 mm) was sized to the bbox, not to the camera's 80×45 grid |
| Consumers of the wrong value | `cli.py:521` (`cmd_inspect`'s `nominal_cell_mm`), `cli.py:751` (`pitch_mm = vector_width_mm / nx`) | `pitch_mm` feeds `sample_stack`, and therefore the thickness/contact numbers in the optics model |
| Grid vs surface | 80 cells × 0.516 mm = 41 mm of surface pitch across a 14.0 mm-wide surface | A cell spans ~13 surface fragments; the patch colour table is indexed by camera cell, so colour varies much faster than the cell pitch suggests |
| Page scale | `3280/3200 = 1.025 = 16.4/16.0`, exactly 200 px/mm both axes | Any change to `nx`/`ny` or the page must preserve this, or `_warn_if_page_aspect_differs` fires and `analyse_map` returns `inconclusive` |
The optics model currently derives the printed cell from the page arithmetic above. Replacing it
with the measured 0.516 mm changes the reported thickness/contact numbers, so the two must move
together.
## 6. Runtime unroll domain
From `orisys-sdk/sensors/finger/assets/30fps-0703/unroll_map_uv_s0.4.npz`:
pattern_camera:cam_sensor # the ink source; a pair's `camera` only decides ownership
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.