Files
orisys-sensor-design/sensors/finger-xynova/r01/design.yaml
T
ykcheungab c377c14474 1. added blender deformation probe for marker size picking and optimization
2. added unwarp map export in current cli, don't need to generate by precompute in sensor running
2026-09-25 15:44:44 +08:00

177 lines
7.5 KiB
YAML

sensor: finger-xynova
revision: r01
status: draft
# Authoring unit in Blender (mm). Export converts using meters_per_source_unit.
authoring_unit: mm
meters_per_source_unit: 0.001
source_blend: source/geometry.blend
# Expected sensing surface topology for r01 (from shipped 30fps-0703 runtime).
# First exports from geometry.blend may differ until topology is locked.
expected:
sensing_vertices: 2595
sensing_triangles: 5005
frames:
sensor: origin_sensor
objects:
sensing_surface: sensing_surface
cam_sensor: cam_sensor
origin_sensor: origin_sensor
# Headless colored-patch texture generation (`orisys-design texture`).
# UV unwrapping is still done in the Blender GUI: the headless run consumes the
# UV maps already stored in source_blend and never creates or unwraps one.
# One PNG/SVG/PDF set is written per UV map below. All maps and formats share
# the settings and patch colours, so they differ only by UV layout.
# These are the revision defaults; CLI flags override every value.
texture_patch:
mesh: sensing_surface
camera: cam_sensor
uv_outputs:
produce: patch_texture_produce.png # hardware production layout
compute: patch_texture_compute.png # compute/runtime layout
width: 3700 # 1850*2
height: 3280 # 1640*2
# Camera frame is square (1000x1000), so equal counts make camera-space
# elements square. The original 80x45 grid was copied from a 16:9 camera.
nx: 80
ny: 80
color_r: 0.05
edge_sample_grid: 5
seed: 7 # fixed so PNG/SVG/PDF share one reproducible colour set
vector:
width_mm: 18.5 # editable SVG/PDF production page width
height_mm: 16.4 # editable SVG/PDF production page height
cross:
enabled: true
length_px: 40
thickness_px: 3
color: [1.0, 0.0, 0.0, 1.0] # red reference cross
# Post-generation printability inspection (`orisys-design inspect`). Advisory
# only: it reports a verdict but never blocks generation or changes exit codes.
# Millimetres are measured on the vector page declared above.
printability:
printer_dpi: 600 # target UV printer resolution
min_dots: 2 # printer dots required across the smallest feature
min_feature_mm: 0.10 # smallest acceptable feature width
min_edge_mm: 0.05 # shortest acceptable polygon edge
max_sliver_ratio: 4.0 # longest edge / minimum width
min_patch_area_mm2: 1.0e-4 # area above which a polygon is a material feature
# Optical stack above the markers, ordered from the camera inward.
# The markers sit on the sensing surface underneath these layers, so their image
# is displaced relative to the straight-line pinhole model.
#
# ior values are LITERATURE ASSUMPTIONS, not measurements - that is what
# ior_source records, so an assumed index can never pass for a measured one.
# Replace them with measured values when available; nothing else needs to change.
optics:
marker_surface: sensing_surface
layers:
# Solids, not surface pairs: `shell` and `rubber-1` are each one closed mesh,
# so the ray enters and leaves the same object.
# Stack: camera > shell > rubber-1 > sensing_surface > rubber-2.
# rubber-2 is BEHIND the markers, so it does not refract camera light and is
# deliberately not a layer.
- name: plastic_shell
solid: shell
ior: 1.59
ior_source: assumed_pc_literature
- name: clear_rubber
solid: rubber-1
ior: 1.43
ior_source: assumed_silicone_literature
# Probe sensitivity bench (`orisys-design deform|render|track|sensitivity|optimise`).
# Deforms the vertices of `group` through known x/y/z displacements expressed in a
# local probe-average basis (normal force along z, shear along x/y), renders what
# `camera` sees, and measures DIS optical flow against the zero-displacement frame.
#
# Contract: docs/probe-pipeline.md. The `.blend` is never written by the pipeline.
probe:
mesh: sensing_surface
camera: cam_sensor
group: probe
uv_map: compute
texture: patch_texture_compute.png
# Proportional falloff radius for the outer rubber. Note this mesh has a median
# edge of 0.63 mm, so 0.5 mm reaches only the probe's immediate neighbours; the
# deform report prints how many vertices actually move rather than hiding it.
radius_mm: 0.5
falloff: smooth
step_mm: 0.01
max_mm: 0.10
axes: [x, y, z]
# Frames are rendered at the revision's real camera resolution. Keep this in step with
# the camera in source/geometry.blend: the pipeline overrides the scene resolution from
# here, so a blend edited to a different size is silently ignored otherwise.
#
# Single scale on purpose. The ROI radius is radius_mm x the probe-local px/mm, so at
# 125x125 it would be 1.66 px against an 8 px DIS window: the estimator measures its own
# regulariser, not the displacement. See docs/probe-findings.md section 2.
resolution: [250, 250]
process_resolution: [250, 250]
# Mirrors the SDK sensor tracker keys (orisys-sdk config/finger.json), EXCEPT
# dis_mode. The estimator window is 8 * 2**dis_mode input px (16 at dis_mode=1, 8 at 0)
# and the moving region is ~6.6 px across at 250x250, so the shipped dis_mode=1 gives
# window/moving = 2.42: DIS's smoothness pulls the estimate toward zero and the measured
# response drops ~3x (1.42 -> 4.30 px/mm at the matched cell). dis_mode=0 gives 1.21,
# the same ratio as 500x500 with dis_mode=1, which recovers to ~73%.
# See docs/probe-findings.md section 2.
# If the deployed tracker is fixed at dis_mode=1, run the bench at 500x500 instead.
tracker:
algorithm: dis
dis_preset: medium
dis_mode: 0
# Standard (not AgX) and denoise off: a filmic view transform silently distorts
# the marker values the tracker is supposed to measure.
render:
engine: CYCLES
samples: 16
denoise: false
view_transform: Standard
interpolate: Closest
seed: 0
# Noise calibration and the injected noise model.
#
# The estimator's `floor_px` is measured as reference vs a re-render at seed+1, which
# is Cycles antialiasing jitter, NOT sensor noise: on this data it differs by ~5 grey
# levels RMS on half the pixels and scales with edge contrast. Ranking patterns by
# gain/that-floor is unsound - the ordering reverses under additive noise, and it
# understates the real idle floor measured from the footage below, coarse patterns
# most. So the render-seed floor is kept only as a reproducibility diagnostic and the
# score is anchored to the injected model plus this measured calibration.
noise:
# Real idle (no-contact) footage, relative to the repo root. Measured: floor
# ~0.23 px at 1280x720 (short baseline == long baseline, so it is white noise and
# the clip is genuinely idle), dominant marker period ~25 px, i.e. ~0.0093 floor
# per period. That is 2-6x the simulated render-seed floor per cell.
idle_footage: ../data/dd02-0703/190.mp4
roi_fraction: 0.18
max_frames: 120
# Additive white Gaussian in grey levels. Defaults are deliberately small: each
# sigma costs a full DIS pass, and the process scale is a resample of the render
# one, so only the render scale is evaluated unless asked.
sigmas: [4.0, 16.0]
draws: 1
seed: 0
models: [render_seed, injected]
scales: [render]
collections:
frames: FRAMES
export_compute: EXPORT_COMPUTE
assembly: ASSEMBLY
design_sim: DESIGN_SIM
exclude: EXCLUDE
notes: |
Canonical source is geometry.blend with named collections and objects.
Compute export uses sensing_surface + cam_sensor relative to origin_sensor.
Studio observation cameras are derived from mesh bounds; no cam_viz required.