D
DreamLake

Views

PoseView

6-DoF pose readout — position (xyz) + orientation (quaternion, scalar-last).

Compatible dtypes: pose_6dof

Purpose

Display an object's pose over time with correct quaternion interpolation. Position uses lerp; orientation uses slerpQuat to stay on the unit hypersphere.

Props

PropTypeDefaultDescription
srcstringm3u8 playlist URL
clockTimelineClock | nullcontextFalls back to <ClockProvider>
classNamestringWrapper class
fpsnumber30React render rate

Data Schema

import type { PoseSample } from '@vuer-ai/vuer-m3u';
 
type PoseSample = {
  ts: number;
  data: [number, number, number, number, number, number, number];
  //      x        y        z        qx       qy       qz       qw
};
FieldUnitNotes
tssecondsAbsolute playlist time
data[0..2]meters (convention)Position
data[3..6]unitlessUnit quaternion, scalar last (qw at index 6)

Source data must store unit quaternions — the view assumes |q|1. Shortest-arc interpolation is handled internally. Recommended source rate: 30–120 Hz.

Example

End-effector pose at 60 Hz, first four rows:

{"ts": 0.0000, "data": [0.300,  0.000, 0.000, 0.0000, 0.0000, 0.0000, 1.0000]}
{"ts": 0.0167, "data": [0.299,  0.005, 0.003, 0.0000, 0.0000, 0.0042, 0.9999]}
{"ts": 0.0333, "data": [0.299,  0.010, 0.005, 0.0000, 0.0000, 0.0083, 0.9999]}
{"ts": 0.0500, "data": [0.298,  0.015, 0.008, 0.0000, 0.0000, 0.0125, 0.9999]}

Quaternion is scalar-last: [qx, qy, qz, qw]. scipy.spatial.transform.Rotation.as_quat() already matches this convention; for libraries that use scalar-first you must reorder on write.

Usage

Loading demo...
import {
  useTimeline,
  ClockProvider,
  TimelineController,
  PoseView,
} from '@vuer-ai/vuer-m3u'

const POSE_URL = '/vuer-m3u-demo/pose/playlist.m3u8'

export function PoseViewDemo() {
  const { clock, state, play, pause, seek, setPlaybackRate, setLoop } = useTimeline()

  return (
    <ClockProvider clock={clock}>
      <PoseView src={POSE_URL} />
      <TimelineController
        state={state}
        onPlay={play}
        onPause={pause}
        onSeek={seek}
        onSpeedChange={setPlaybackRate}
        onLoopChange={setLoop}
      />
    </ClockProvider>
  )
}

Under the Hood

The view calls useMergedTrack with a custom Normalizer that splits every 7-tuple into two columnar tracks:

  • "position" — stride 3, sampled with lerp
  • "orientation" — stride 4, sampled with slerpQuat

This pattern is the reference example for how to combine interpolators in a custom view — see Custom Views.