Units
All frames are right-handed. Convert your source’s units and handedness once, in your
converter. Nothing is converted at read time.
The vehicle frame
Point clouds and sensor extrinsics are expressed relative to one frame named vehicle:
- x forward, y left, z up, right-handed;
- origin = the body’s reference point projected onto the ground plane, so z = 0 is the ground and a roof-mounted sensor has a positive z.
vehicle is the site’s frame with the
same axes and its origin on the ground.
Transforms
Publish each sensor extrinsic as afoxglove.FrameTransform message:
- Transforms are static: publish each one once, at
t0_ns. - Every camera and point cloud carries a
frame_idin its messages; each SHOULD have aFrameTransformwhosechild_frame_idmatches. - There is deliberately no matrix or Euler-angle alternative. Convert your extrinsic to translation
plus quaternion in your converter with whatever your toolkit provides
(e.g.
scipy.spatial.transform.Rotation.from_matrix(R).as_quat(), which returnsx, y, z, w).
Frames for poses and keypoints
Poses (foxglove.PoseInFrame) and keypoints (nomadic.Skeleton) carry a frame_id. Which frame
to use depends on the body:
- All part poses and keypoints in a recording MUST use the same
frame_idfor the whole recording. A part in another frame is left out, and a message whoseframe_iddiffers from the first one on its channel is skipped. - World frames MUST be right-handed with z up. Convert y-up sources in your converter. For a
right-handed y-up world (ARKit, OpenXR), rotate +90° about x: a position
(x, y, z)becomes(x, −z, y), and the same rotation is applied to every orientation.
Body pose
The body’s own pose over time (the “ego pose”: a car’s pose, a mobile robot’s base, a humanoid’s pelvis, a person’s head) is afoxglove.PoseInFrame channel that is not declared in the
overlay. It is found by its schema.
- Every
PoseInFramechannel that no part’send_posereferences is read as the body pose, so a recording SHOULD have at most one such channel. - A part’s
end_pose(a gripper, a wrist, a foot) is that part’s pose and is never used as the body pose. Do not reuse one channel for both. - Position in metres, orientation a unit quaternion, in the static world frame above.
- A fixed-base
manipulatorhas no body pose.
Orientation in signals
Orientation in messages is always a quaternion. When you also publish orientation as signals (e.g. from an IMU), publish derived angles (yaw,
pitch, roll in rad), not raw quaternion components.