Skip to main content

HEX FLOW NODE DATA

      


📖 Overview

What is hex_flow_node_data

hex_flow_node_data provides hex-flow nodes for recording and replaying robot data. It currently supports two operations: recording — subscribing to robot state, camera color, and camera depth topics, and writing them to Foxglove MCAP files via hex_util_data; and replay — reading MCAP files and publishing recorded data back onto the network. The record node is toggle-controlled by a boolean message on the record topic, enabling episode-based data collection.

What problem it solves

  • Episode-based data collection: Supports multiple recording episodes, each written as a separate episode_NNNNNN.mcap file, making it easy to organize training data for imitation learning or model-based RL.
  • Dynamic topic discovery: Automatically classifies topics by suffix (*state, *color, *depth) from the HEX_FLOW_REMAP JSON configuration, so the same binary works with any robot configuration — no code changes needed.
  • Foxglove-native format: Writes MCAP files compatible with Foxglove Studio for visualization and analysis.
  • Flexible recording control: Start/stop recording via a dedicated record topic; integrates with keyboard teleoperation or any other trigger source.
  • Integrated testing: Ships with a test node that publishes predefined control commands and toggles recording on the S key — no additional tools needed.
  • Simulation & real-robot support: Example launch configurations demonstrate integration with both MuJoCo simulation and real Archer Y6 robots with cameras.

Target users

  • Engineers collecting demonstration data from HEXFELLOW robot systems for imitation learning or behavior cloning.
  • Researchers running data acquisition pipelines (teleoperation → recording) before training policies.
  • Developers building on the hex-flow framework who need a working data recording and replay layer.

Nodes

Node Description Publishes Subscribes
hex-flow-data-record Records robot state and camera data to MCAP — {side}_arm_state, {side}_grip_state, obj_pose, {cam}_color, {cam}_depth, record
hex-flow-data-record-test Terminal-based test control for recording {side}_arm_ctrl, {side}_grip_ctrl, record keys
hex-flow-data-replay Replays MCAP data back onto the network {side}_arm_state, {side}_grip_state, obj_pose, {cam}_color, {cam}_depth —

📦 Installation

Requirements

  • Python >= 3.10
  • OS: Ubuntu (or other Linux)
  • Core dependencies:
    • hex_flow_core >= 0.0.0, < 0.1.0
    • hex_util_data >= 0.0.0, < 0.1.0
    • hex_util_msg >= 0.0.0, < 0.1.0
    • hex_util_runtime >= 0.0.0, < 0.1.0
    • hex_util_robot >= 0.0.0, < 0.1.0

Install hex-flow-cli

For Ubuntu or any Debian-based system, install Zenoh and hex-flow CLI:

sudo apt update
sudo apt install -y curl gpg

curl -L https://download.eclipse.org/zenoh/debian-repo/zenoh-public-key | sudo gpg --dearmor --yes --output /etc/apt/keyrings/zenoh-public-key.gpg
echo "deb [signed-by=/etc/apt/keyrings/zenoh-public-key.gpg] https://download.eclipse.org/zenoh/debian-repo/ /" | sudo tee -a /etc/apt/sources.list > /dev/null
sudo apt update
sudo apt install zenoh curl

curl -fsSL https://raw.githubusercontent.com/hexfellow/hex-flow/main/install.sh | sh

For other systems, please install zenohd yourself, then run the install script.

Install hex-flow-node-data from PyPI

pip install hex_flow_node_data

Install hex-flow-node-data from source

We provide a venv.sh script to create a virtual environment with all dependencies installed. However, you need to install uv first. For uv installation, please refer to uv official installation guide.

curl -LsSf https://astral.sh/uv/install.sh | sh

Then you can use venv.sh to create a virtual environment with all dependencies installed:

git clone https://github.com/hexfellow/hex_flow_node_data.git
cd hex_flow_node_data
./venv.sh

📑 Python Config API

The package provides helper functions that return NodeConfig objects for easy integration into your LaunchConfig.

from hex_flow_core import LaunchConfig
from hex_flow_node_data import (
    default_data_record_node,
    default_data_record_test_node,
    default_data_replay_node,
)

default_data_record_node

Parameter Type Default Description
name str "data_record" Node name
record_path str "./hex_record_data" Directory path for MCAP file output
foxglove_host str "127.0.0.1" Foxglove WebSocket server host
foxglove_port int 8765 Foxglove WebSocket server port
start_cnt int 0 Starting episode count for file naming
required bool True Required for launch
hidden bool False Hidden from TUI display
remap_dict dict None Custom remap; auto-generated if None
sensor_source str "mujoco_e3_desktop" Sensor node name for auto-remap topic prefix

default_data_record_test_node

Parameter Type Default Description
name str "data_record_test" Node name
rate_hz float 10.0 Control command publish rate (Hz)
arm_ctrl_mode str "pos" Arm control mode ("mit", "pos")
grip_ctrl_mode str "pos" Gripper control mode ("mit", "pos")
required bool False Required for launch
hidden bool False Hidden from TUI display
remap_dict dict None Custom remap; auto-generated if None
sensor_source str "mujoco_e3_desktop" Sensor node name for auto-remap of control topics
keys_source str "teleop_keyboard" Keyboard node name for auto-remap of keys topic

default_data_replay_node

Parameter Type Default Description
name str "data_replay" Node name
mcap_path str "~/hex_record_data" Path to MCAP file or directory
enable_color bool False Enable color image replay
enable_depth bool False Enable depth image replay
color_encoding str "bgr8" Color image encoding
depth_encoding str "mono16" Depth image encoding
rate_hz float 500.0 Replay publish rate (Hz)
state_topics list ["left_arm_state", "right_arm_state", "left_grip_state", "right_grip_state", "obj_pose"] State topic names to replay
color_topics list ["head_color"] Color image topic names to replay
depth_topics list ["head_depth"] Depth image topic names to replay
required bool True Required for launch
hidden bool False Hidden from TUI display
remap_dict dict None Custom remap; auto-generated if None

💡 Examples

Ready-to-run config scripts are provided in the example/ directory. Each script prints a launch YAML to stdout, intended for use with hexflow run:

Simulation-based recording (E3 Desktop)

# Records robot state and camera data from a simulated E3 Desktop
# Toggle recording with the S key (keyboard teleoperation)
hexflow run example/sim_record_test.launch.py

Real-robot recording (Dual Archer Y6)

# Records robot state and camera data from real Archer Y6 arms
# with Berxel depth camera and USB cameras
hexflow run example/real_record_test.launch.py

YAML Examples

Simulated recording (E3 Desktop)

nodes:
  - name: data_record
    build: pip install hex_flow_node_data
    run: hex-flow-data-record
    required: false
    hidden: true
    remap:
      left_arm_state: mujoco_e3_desktop/left_arm_state
      right_arm_state: mujoco_e3_desktop/right_arm_state
      left_grip_state: mujoco_e3_desktop/left_grip_state
      right_grip_state: mujoco_e3_desktop/right_grip_state
      head_color: mujoco_e3_desktop/head_color
      left_color: mujoco_e3_desktop/left_color
      right_color: mujoco_e3_desktop/right_color
      head_depth: mujoco_e3_desktop/head_depth
      left_depth: mujoco_e3_desktop/left_depth
      right_depth: mujoco_e3_desktop/right_depth
      record: data_record_test/record
    env:
      RECORD_PATH: "./record_data"
      FOXGLOVE_HOST: "127.0.0.1"
      FOXGLOVE_PORT: "8765"
      START_CNT: "0"

  - name: data_record_test
    build: pip install hex_flow_node_data
    run: hex-flow-data-record-test
    required: true
    hidden: true
    remap:
      left_arm_ctrl: mujoco_e3_desktop/left_arm_ctrl
      right_arm_ctrl: mujoco_e3_desktop/right_arm_ctrl
      left_grip_ctrl: mujoco_e3_desktop/left_grip_ctrl
      right_grip_ctrl: mujoco_e3_desktop/right_grip_ctrl
      record: data_record_test/record
      keys: teleop_keyboard/teleop_keyboard
    env:
      RATE_HZ: "100"
      ARM_CTRL_MODE: "pos"
      GRIP_CTRL_MODE: "pos"

Real-robot recording (Dual Archer Y6)

nodes:
  - name: data_record
    build: pip install hex_flow_node_data
    run: hex-flow-data-record
    required: false
    hidden: true
    remap:
      left_arm_state: left_archer_y6/arm_state
      right_arm_state: right_archer_y6/arm_state
      left_grip_state: left_archer_y6/grip_state
      right_grip_state: right_archer_y6/grip_state
      head_color: head_berxel/color
      head_depth: head_berxel/depth
      left_color: left_cam_usb/color
      record: data_record_test/record
    env:
      RECORD_PATH: "./record_data"
      FOXGLOVE_HOST: "127.0.0.1"
      FOXGLOVE_PORT: "8765"
      START_CNT: "0"

  - name: data_record_test
    build: pip install hex_flow_node_data
    run: hex-flow-data-record-test
    required: true
    hidden: true
    remap:
      left_arm_ctrl: left_archer_y6/arm_ctrl
      right_arm_ctrl: right_archer_y6/arm_ctrl
      left_grip_ctrl: left_archer_y6/grip_ctrl
      right_grip_ctrl: right_archer_y6/grip_ctrl
      record: data_record_test/record
      keys: teleop_keyboard/teleop_keyboard
    env:
      RATE_HZ: "100"
      ARM_CTRL_MODE: "pos"
      GRIP_CTRL_MODE: "pos"

Topics

Record Node — Subscribed Topics

The record node discovers topics dynamically from the HEX_FLOW_REMAP JSON env var, classifying by suffix:

Suffix Message Type Description
*state HexArmState / HexGripState / HexPoseState Robot joint/pose state
*color HexImgSimple (encoding bgr8) Color camera frames
*depth HexImgSimple (encoding mono16) Depth camera frames
record raw bytes (1-byte boolean) Start/stop recording (non-zero = start)

State topics — HexArmState

Field Type Description
ts_ns int64 Timestamp in nanoseconds
jnt_pos [float64] Joint position array
jnt_vel [float64] Joint velocity array
jnt_eff [float64] Joint effort/torque array
pose_pos [float64] End-effector position (x, y, z)
pose_quat [float64] End-effector orientation (w, x, y, z)

Schema: msgs/msg_robot/arm_state.fbs

State topics — HexGripState

Field Type Description
ts_ns int64 Timestamp in nanoseconds
jnt_pos [float64] Gripper joint position
jnt_vel [float64] Gripper joint velocity
jnt_eff [float64] Gripper joint effort

Schema: msgs/msg_robot/grip_state.fbs

State topics — HexPoseState

Field Type Description
ts_ns int64 Timestamp in nanoseconds
pose_pos [float64] Object position (x, y, z)
pose_quat [float64] Object orientation (w, x, y, z)

Schema: msgs/msg_robot/pose_state.fbs

Camera topics — HexImgSimple

Field Type Description
ts_ns int64 Timestamp in nanoseconds
encoding HexImgEncoding Image encoding (bgr8 or mono16)
width uint16 Image width
height uint16 Image height
data [uint8] Raw image pixel data (flattened)

Schema: msgs/msg_image/img_simple.fbs

Record Test Node — Published Topics

Topic Message Type Description
{side}_arm_ctrl HexArmCtrl Arm control command
{side}_grip_ctrl HexGripCtrl Gripper control command
record raw bytes (1-byte boolean) Start/stop recording command

{side}_arm_ctrl — HexArmCtrl

Field Type Description
ts_ns int64 Timestamp in nanoseconds
ctrl_mode HexArmCtrlMode Control mode enum (mit=0, pos=2)
jnt_pos [float64] Joint position target
jnt_vel [float64] Joint velocity target
jnt_eff [float64] Joint effort target
mit_tau [float64] MIT mode torque feedforward
mit_kp [float64] MIT mode stiffness gains
mit_kd [float64] MIT mode damping gains
lim_err [float64] Position error limit for safety

Schema: msgs/msg_robot/arm_ctrl.fbs

{side}_grip_ctrl — HexGripCtrl

Field Type Description
ts_ns int64 Timestamp in nanoseconds
ctrl_mode HexGripCtrlMode Control mode enum (mit=0, pos=2)
jnt_pos [float64] Gripper joint position target
jnt_vel [float64] Gripper joint velocity target
jnt_eff [float64] Gripper joint effort target
mit_tau [float64] MIT mode torque feedforward
mit_kp [float64] MIT mode stiffness gains
mit_kd [float64] MIT mode damping gains
lim_err [float64] Position error limit for safety

Schema: msgs/msg_robot/grip_ctrl.fbs

Environment Variables

All Nodes

Variable Type Default Description
HEX_FLOW_NODE_NAME str constructor arg Overrides node name (handled by hex_flow_core)
HEX_FLOW_REMAP str {} JSON dict for topic remapping (handled by hex_flow_core)
RUST_LOG str info Log level for envlog

Record Node (hex-flow-data-record)

Variable Type Default Description
RECORD_PATH str "../hex_record_data" Directory path for MCAP file output
FOXGLOVE_HOST str "127.0.0.1" Foxglove WebSocket server host
FOXGLOVE_PORT int 8765 Foxglove WebSocket server port
START_CNT int 0 Starting episode count for file naming

Record Test Node (hex-flow-data-record-test)

Variable Type Default Description
RATE_HZ float 10.0 Control command publish rate (Hz)
ARM_CTRL_MODE str "pos" Arm control mode ("mit", "pos")
GRIP_CTRL_MODE str "pos" Gripper control mode ("mit", "pos")

Replay Node (hex-flow-data-replay)

Variable Type Default Description
MCAP_PATH str "~/hex_record_data" Path to MCAP file or directory
ENABLE_COLOR bool false Enable color image replay
ENABLE_DEPTH bool false Enable depth image replay
COLOR_ENCODING str "bgr8" Color image encoding
DEPTH_ENCODING str "mono16" Depth image encoding
RATE_HZ float 500.0 Replay publish rate (Hz)

Architecture

The data recording pipeline follows a modular, decoupled design:

  1. Dynamic topic discovery — The record node reads the HEX_FLOW_REMAP JSON environment variable at startup and classifies all remapped topics by their suffix: *state topics (arm/gripper/pose states), *color topics (color camera images), and *depth topics (depth camera images). This allows the same binary to work with any robot configuration.

  2. Type-specific callbacks — For each discovered topic, the node creates a dedicated callback that subscribes via hex_flow_core.Node.create_sub(). State topics are parsed using parse_hex_arm_state, parse_hex_grip_state, or parse_hex_pose_state; image topics use parse_color_msg and parse_depth_msg. All parsed data is forwarded to a HexMcapWriter instance connected to a Foxglove WebSocket server.

  3. Episode-based recording — The node listens on the record topic for a single-byte boolean payload. On a rising edge (non-zero byte), it starts a new recording episode — incrementing the episode counter and creating a new episode_NNNNNN.mcap file at the configured RECORD_PATH. On a falling edge (zero byte), it stops the current episode. This enables seamless episode-level data collection.

  4. MCAP output format — Data is written to Foxglove MCAP files, a standard robotics binary log format that supports schemas, multiple topics, and efficient streaming. MCAP files can be visualized directly in Foxglove Studio for inspection and analysis.

  5. Decoupled test node — The hex-flow-data-record-test node is an independent process that publishes constant arm and gripper control commands at a configurable rate. It also listens for keyboard events and toggles the record topic when the S key is pressed (with rising-edge detection to avoid double-toggle). This provides a complete recording pipeline that works with both simulation (sim_record_test.launch.py) and real hardware (real_record_test.launch.py).

This decoupling allows the high-frequency control loop to run independently from the recording system, ensuring that data collection does not interfere with real-time control.

📄 License

Apache License 2.0. See LICENSE.

🌟 Star History

Star History Chart

👥 Contributors

Metadata

Release files for hex-flow-node-data 0.0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hex-flow-node-data 0.0.2.1
File Size Uploaded
hex_flow_node_data-0.0.2.1.tar.gz 20.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hex-flow-node-data 0.0.2.1
File Interpreter ABI Platform
hex_flow_node_data-0.0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 36.0 kB

Release files / hex_flow_node_data-0.0.2.1.tar.gz

Download URL hex_flow_node_data-0.0.2.1.tar.gz
Size 20.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0fb47ac9ff6cfefa8dd3f29d607f2856799bdafeb0db663d7c46a690cbed0b35
BLAKE2b-256 checksum
How to use checksums
5eb0f9990c41698eff9ddc0afc8d8d9056656e5e326f685baa1c281dd5528d99
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.12

Release files / hex_flow_node_data-0.0.2.1-py3-none-any.whl

Download URL hex_flow_node_data-0.0.2.1-py3-none-any.whl
Size 16.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bc92f1afe297ad12f4431c76fee01fd29826f54b112f8e96101211a71b2cc730
BLAKE2b-256 checksum
How to use checksums
e76c34997735ab3d2d1e719afc8eb6d96b08ed1f0efb01e0486a9723413bc816
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.12

Release history Release notifications | RSS feed

This release

0.0.2.1 This release

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page