Skip to content

Neutree/otter-motion-format

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OMF: otter-motion-format

中文 | English

Introduction

A standardized format for robot motion data, designed for data collection, training, logging, and related applications. It helps unify data representation and supports conversion between common file formats.

Data Format

Robot data generally contains two major categories:

  1. Target: Target data used for data collection and training, such as desired joint angles and frame rates.
  2. Actual: Actual sensor data, such as measured motor angles, temperatures, and frame rates.

The data may include, but is not limited to:

  • Robot information, such as model / number of joints / joint names
  • Pose in the world coordinate system (translation and rotation)
  • Joint angle / velocity / acceleration / torque / temperature for each joint
  • Pose / linear velocity / angular velocity for each link
  • Sensor data, such as IMU orientation and even images
  • Data frame rate / execution time

Based on these requirements, we define the following format:

Top level:

version: 1    # Protocol version
format: omf   # Format identifier, used to verify that this is an OMF file
basic:        # Basic and shared information, such as data name and robot information
target:       # Desired motion data
actual:       # Actual recorded motion data, used for logs

basic:

version: 1
format: omf
basic:
    name: walk stright
    robot: agibot_x2 # Recommended format: manufacturer + model
    date: 2026-05-13T00:00:00.000 # %Y%m%dT%H:%M:%S.%f
    joint_names: ["left_hip_pitch", ..., "waist_yaw"] # Joint names; all subsequent data strictly follows this order
    joint_dims: [1, ...., 1] # joints' dim, for actuator is 1, for person body joint is 3
    link_names: ["left_ankle_link"]
    imu_names: ["base", "torso"]
    time_names: ["dt", "model_run"]
    data_names: ["target", "model_target", "actual"]

target/model_target/actual data can contain multiple data groups according to data_names:

target/model_target/actual: # same as basic.data_names, recommend use target and actual first.
    fps: 50
    length: 600 # Total number of frames
    root_pos: [[0.0, 0.0, 0.0], ...] # Root position in the world coordinate system, in meters
    root_rot: [[x, y, z, w], ...]    # Root rotation in the world coordinate system, quaternion in xyzw order
    joint:
        pos:
            - [1.0, ...] # Joint angles; the number of values for each joint corresponds to dof_dim
            - [1.1, ...] # Contains `length` arrays
        vel: [] # Same format as joint.pos, joint velocities
        acc: [] # Same format as joint.pos, joint accelerations
        tau: [] # Same format as joint.pos, joint torques
        temp: [] # Same format as joint.pos, joint temperature
    link:
        pos: []     # shape: (length, len(link_names), 3(xyz)) Position in the world coordinate system
        rot: []     # shape: (length, len(link_names), 4(xyzw)) Rotation in the world coordinate system
        lin_vel: [] # shape: (length, len(link_names), 3(xyz)) Linear velocity in the world coordinate system
        ang_vel: [] # shape: (length, len(link_names), 3(wx,wy,wz)) Angular velocity in the world coordinate system
    imu:
        pos: []     # shape: (length, len(imu_names), 3(xyz)) Position in the world coordinate system
        rot: []     # shape: (length, len(imu_names), 4(xyzw)) Rotation in the world coordinate system
        gyro: []    # shape: (length, len(imu_names), 3(xyz)) Gyroscope angular velocity
        acc: []     # shape: (length, len(imu_names), 3(xyz)) Acceleration
        lin_vel: [] # shape: (length, len(imu_names), 3(xyz)) Linear velocity, optional
    time: [] # shape: (length, len(time_names)); typically used to record execution timings

Storage Formats

There are several common ways to store data:

  • JSON/YAML text files: easy to read, but relatively large in size
  • Pickle: directly stores Python variables, convenient but may be incompatible across library versions and is not suitable for long-term storage
  • MessagePack: a binary version of JSON, producing smaller files; not directly human-readable but can be inspected using tools

The primary storage format chosen is MessagePack, which offers small file size, fast read/write performance, and broad software support across many programming languages. YAML and JSON are also supported, with file extensions .msgpack, .yaml, and .json.

Supported Operations

This library is a Python package and can be installed in several ways:

  • pip install otter-motion-format: core read/write functionality only, without visualization dependencies
  • pip install "otter-motion-format[viz]": includes curve visualization dependencies
  • pip install "otter-motion-format[all]": installs all dependencies; currently the same as viz

Supports loading, visualization, and saving:

import otter_motion_format as omf

motion = omf.load("walk.msgpack")
motion.summary()                        # Print a summary of the data in the terminal
motion.show_chart(["target.joint.pos"]) # By default, all curves are shown. You can select curves in the GUI or pass specific curve names.
                                        # Rotations are automatically converted to rotation vectors and Euler angles.

motion.save("walk.yaml")

Adding data:

import otter_motion_format as omf
import numpy as np

robot_joint_names = ["left_hip_pitch", "right_hip_pitch"] # Define your robot joint names
motion = omf.OMF(name="walk",
                 robot="agibot_x2",
                 joint_names=robot_joint_names,
                 joint_dims=[1] * len(robot_joint_names),
                 data_names=["target", "model_target", "actual"]
                )

for i in range(100):
    # Directly manipulate the dictionary
    motion.target["joint"]["pos"].append([1.0, 1.0 + i * 0.01])
    motion.target["joint"]["vel"].append(np.array([0.1, 0.1]))
motion.save("test_motion.msgpack")

Visualization Features

As mentioned earlier, motion.show_chart() can be used to display curves in a GUI. You can also open files directly from the command line:

otter-motion-format "path/to/data_file.msgpack"

Note that you need to install the visualization dependencies first using pip install "otter-motion-format[viz]" or pip install "otter-motion-format[all]".

The curve viewer currently supports:

  • Saving multiple data types simultaneously, such as target and actual, with separate tabs for each
  • Searching for curve names
  • All / None / Invert quick selection
  • Left mouse button to pan, right mouse button to zoom quickly, mouse wheel to zoom
  • Viewing the value at the current cursor position
  • Customizing curve colors

LICENSE

Apache License 2.0

In short: Feel free to use this project and share suggestions for improvement. Commercial use is allowed and please keep LICENSE file. If you fork and modify it, please document your changes. Pull requests are welcome.

About

otter robot motion format convention and load save gui tool

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages