recording.platform describes the body the recording comes from: its class (kind), its model
(embodiment), its size, and in spec 1.1 its parts. Every embodiment uses the same small
vocabulary:
platform
kind
kind is the body class only. What the body has (arms, hands, a gripper) comes from its parts, and
cameras that are not on the body (e.g. a third-person view, see
Cameras) never change it.
Rules:
embodimentMAY be declared on any kind, MUST be a non-empty string, and MUST be omitted on a sensor-only recording.body_dimensionsMAY be declared on any kind with a moving base (every kind exceptmanipulator). It takes exactlylength(along x),width(along y) andheight(along z), each greater than 0 and less than 1000 metres.ego_platformMAY be declared on avehicleonly.partsMUST NOT be declared on a sensor-only recording.
Recognised embodiments
embodiment is free text, so any model name is accepted. These values have a defined joint
convention; when you declare one, publish its data in that convention:
To have a new embodiment recognised, contact us with its URDF and joint order.
Parts
Each part is one entry inplatform.parts:
Name sided parts
<side>_<type>, e.g. left_hand, right_leg. A hand’s side is read from its
name, and a hand is paired with the arm of the same side (left_hand with left_arm).
Slots
A part carries any of five data slots. Each slot has exactly one form, so there is never a convention to negotiate.
Rules that apply to every slot:
- A slot’s
signalMUST name a signal declared insignalsby itsname, with the type and unit the slot requires. - One signal feeds one slot. Two parts MUST NOT share a signal.
- A slot’s
channelMUST exist in the file, carry the slot’s message schema (protobuf), and not be declared anywhere else in the overlay (as a view, signal, point cloud or another part’s slot). - A part SHOULD have at least one of
joints,end_poseorkeypoints. These put the part on a timeline; a part with onlygriporforceis accepted with a warning. - A part’s
end_poseis the part’s pose, never the body pose.
Force
force points at a declared vector signal in one of three forms:
For example, five fingertip wrenches are
dim: 30 with components thumb_fx … thumb_tz, index_fx … little_tz; five fingertip normal forces are dim: 5, unit: "N", components
["thumb", "index", "middle", "ring", "little"].
Keypoints
Publish 3D keypoints (hand or body tracking) as onenomadic.Skeleton channel per part, one
message per frame:
keypoints slot, not in every message:
nameslists the joints in message order: non-empty, unique strings.parents[i]is the index of jointi’s parent, or-1for a root.parentsMUST have one entry per name and form a forest: every entry an integer in-1 … len(names) − 1, no joint its own parent, at least one root, no cycles. Several roots are allowed (e.g. detached fingertips).- Every message MUST carry exactly one position per declared joint. Messages with the wrong count are skipped.
confidenceis either empty in every message or has one value per joint in[0, 1].- Positions are metres, right-handed, z up, in the frame named by
frame_id. See Frames for poses and keypoints. - A hand SHOULD have at least 5 keypoints (a wrist and one joint per finger).
- The part’s
end_pose, when present, is the wrist pose with its orientation. Without one, the root joint is the wrist position. - Publish a message only when the part is tracked. Do not publish placeholder zeros for a hand
out of view; omit the message, and publish
confidenceif your tracker has it.
Spec 1.0: mount
Spec 1.0 names the body with mount, which is required in 1.0, and has no kind, parts or
body_dimensions:
In 1.0,
embodiment is allowed only on robot_arm and heavy_equipment, and vehicle_dimensions
only on vehicle. In a 1.1 overlay, mount is still accepted, with a warning, when it agrees with
kind; a mount that contradicts kind is rejected. A 1.0 overlay that uses a 1.1 field is
rejected with a rule naming the version it needs (e.g. platform.parts.requires_spec_1_1).