OST Calibration
Node ID: ostCalibration · Role: Sink · Realtime config: no
Description
SPAAM-style optical see-through display calibration for the LPVIZ driver. The user aligns a tracked stylus tip with crosshairs at known pixel positions on the display; the solve recovers per-eye projection FOV, IPD, and the head-to-tracker pose. Wire the stylus optical stream and, preferably, the HMD body’s raw optical stream (HMD Optical) - it drops out visibly when tracking is lost, so stale poses are rejected instead of silently captured. The FusedPose input is an alternative when no raw stream is available.
Inputs / Outputs
- Inputs:
Optical- Stylus,HmdOptical(Optical) - HMD Optical,HmdPose(FusedPose) - HMD Pose - Outputs: (none)
Properties
The following fields are exposed in the node’s Properties panel in the UI. Types map to UI widgets (e.g. string → text input, number → numeric, boolean → toggle, select → dropdown, json → JSON editor).
| Key | Label | Type | Default | Description / Notes |
|---|---|---|---|---|
tipOffset | Stylus Tip Offset | vector3 | {"x":0.0,"y":0.0,"z":0.0} | Offset from the tracked stylus body origin to its physical tip, in the body frame (m). Solve it with the pivot calibration in the Point Alignment view. |
captureWindowMs | Capture Window (ms) | number | 750 | hidden in UI |
Example node definition
A full node definition in config.json looks like the block below. Paste it under the sinks key of your config, keyed by the node’s instance name (any identifier; it doesn’t have to match the node ID).
{
"sinks": {
"ostCalibration": {
"inputEndpoints": [
"inproc://optical_data",
"inproc://hmdOptical_data",
"inproc://hmdPose_data"
],
"inputDataFilter": [
"Optical",
"Optical",
"FusedPose"
],
"settings": {
"captureWindowMs": 750,
"tipOffset": {
"x": 0.0,
"y": 0.0,
"z": 0.0
}
}
}
}
}
Field reference
| Field | Purpose |
|---|---|
inputEndpoints | List of upstream endpoints this node connects to (outEndpoint / dataEndpoint values from upstream nodes). |
inputDataFilter | Optional whitelist of data types. Messages whose type isn’t in the list are dropped at the subscriber. |
settings | All user-configurable fields — see the Properties table above. |
Connections can also be declared at the top-level
connectionsarray whensettings.explicitConnectionsistrue, as an alternative to fillinginputEndpointson each node.