D
DreamLake

Views

JointAngleView

N-DoF joint-angle display — numeric readout plus per-joint signed bar chart.

Compatible dtypes: joint_angles

Purpose

Visualize a robot's joint state over time, continuously interpolated. useMergedTrack merges the current chunk with its contiguous neighbors; useTrackSample with lerp gives the value at the current clock.

Props

PropTypeDefaultDescription
srcstringm3u8 playlist URL
clockTimelineClock | nullcontextFalls back to <ClockProvider>
classNamestringWrapper class
fpsnumber15React render rate
jointNamesstring[]J0J{N-1}Labels for each DoF
rangenumberMath.PISoft limit used for bar scaling

Data Schema

import type { JointAngleSample } from '@vuer-ai/vuer-m3u';
 
type JointAngleSample = {
  ts: number;          // seconds on playlist timeline
  data: number[];      // length = DoF count; order = jointNames order
};
FieldUnitNotes
tssecondsAbsolute playlist time
dataradians (convention)One value per joint; must be consistent across the whole playlist

Stride is inferred from the first sample — keep data.length constant across every chunk. Recommended source rate: 30–250 Hz.

Example

7-DoF arm, first four rows:

{"ts": 0.000, "data": [ 0.00, -1.57,  0.00,  1.57,  0.00,  0.00,  0.00]}
{"ts": 0.010, "data": [ 0.00, -1.56,  0.01,  1.56,  0.00, -0.01,  0.00]}
{"ts": 0.020, "data": [ 0.01, -1.55,  0.01,  1.54,  0.01, -0.01,  0.01]}
{"ts": 0.030, "data": [ 0.01, -1.54,  0.02,  1.52,  0.01, -0.02,  0.01]}

Usage

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

const JOINTS_URL = '/vuer-m3u-demo/joints/playlist.m3u8'

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

  return (
    <ClockProvider clock={clock}>
      <JointAngleView
        src={JOINTS_URL}
        jointNames={[
          'shoulder_pan',
          'shoulder_lift',
          'elbow',
          'wrist_1',
          'wrist_2',
          'wrist_3',
          'gripper',
        ]}
      />
      <TimelineController
        state={state}
        onPlay={play}
        onPause={pause}
        onSeek={seek}
        onSpeedChange={setPlaybackRate}
        onLoopChange={setLoop}
      />
    </ClockProvider>
  )
}

Under the Hood

Reads the "data" track from useMergedTrack(engine).tracks and samples it with useTrackSample(track, time, lerp). See Custom Views — continuous data for a hand-rolled mini version.