Contour Specificationv1.0

The open standard for tactile data.

One schema for tactile data. Contour proposes how any touch sensor, glove, hand, gripper, skin, or array, describes what it feels, so the data can mean the same thing everywhere.

The frame

The atom of Contour is the frame: one snapshot of contact at one instant. A stream is an ordered sequence of frames on a shared clock. Every field is sensor-agnostic, a 548-taxel glove and a 2-pad gripper produce the same shape of object, differing only in N.

Fields

FieldType
taxelsreq

Normalized contact pressure per sensing element, in [0, 1].

float32[N]
geometryreq

Position of each taxel in the sensor frame, in meters.

float32[N,3]
posereq

Sensor pose, position (x, y, z) and orientation quaternion (w, x, y, z).

float32[7]
normalopt

Surface normal at each taxel, unit vectors in the sensor frame.

float32[N,3]
shearopt

Tangential (shear) force per taxel, when the device reports it.

float32[N,2]
timestampreq

Seconds on a monotonic clock, shared across all sensors in a session.

float64
devicereq

Device profile id, the entry in the Atlas this frame was encoded from.

string
schemareq

Contour version tag, e.g. "contour/1.0".

string

Encoding

A Contour frame serializes to a flat, self-describing record. The reference client reads and writes it identically across devices, you consume the same object regardless of source.

frame.py
import contour

device = contour.connect("wuji_glove")
frame = next(device.stream())

frame.taxels.shape      # (548,)      normalized pressure
frame.geometry.shape    # (548, 3)    taxel positions (m)
frame.pose              # (7,)        xyz + quaternion
frame.timestamp         # 1.7203e9    shared clock
frame.schema            # "contour/1.0"

Device profiles

A profile maps a physical sensor into Contour: how its raw readings normalize, where its taxels sit in space, and what it can and can't report. Profiles live in the Atlas. Add a profile once, and every Contour tool and dataset understands your device.

Versioning

Contour versions are tagged contour/MAJOR.MINOR. Minor versions add optional fields and stay backward-compatible; major versions may change required semantics. Every frame carries its schema, so readers always know exactly what they're holding.