Skip to content

Repository files navigation

PlotJuggler Unitree SDK2 Plugin

中文 | English

PlotJuggler Unitree SDK2 Plugin.

This repository provides two plugins:

  • Unitree SDK2 DDS: a DataStreamer plugin that subscribes to DDS topics through unitree_sdk2 and flattens strongly typed messages into numeric PlotJuggler series.
  • Unitree Robot View: a Toolbox plugin that renders Unitree robot posture from lowstate IMU and motor position series already loaded into PlotJuggler.

Usage

1. Download the Plugin

Download the Linux x86_64 bundle from GitHub Releases:

plotjuggler-unitree-sdk2-<version>-linux-x86_64.tar.gz

Extract it to any directory, for example:

mkdir -p ~/plotjuggler_plugins
tar -xzf plotjuggler-unitree-sdk2-<version>-linux-x86_64.tar.gz \
  -C ~/plotjuggler_plugins

The extracted directory is the plugin folder that PlotJuggler should load:

~/plotjuggler_plugins/plotjuggler-unitree-sdk2-<version>-linux-x86_64/

2. Add the Plugin Folder in PlotJuggler

Open PlotJuggler, open Preferences, select the Plugins tab, click Add in the Plugin folders list, choose the extracted directory, confirm, and restart PlotJuggler.

After restart, you should see:

  • Unitree SDK2 DDS in the Streaming panel
  • Unitree Robot View in the Tools menu

You can also load the plugin folder temporarily from the command line without changing Preferences:

plotjuggler --plugin_folders "$HOME/plotjuggler_plugins/plotjuggler-unitree-sdk2-<version>-linux-x86_64"

3. Stream Unitree DDS Data

In the PlotJuggler Streaming panel, select Unitree SDK2 DDS. Use the gear button to configure DDS network interface, domain id, queue length, joystick field mode, and data enhancement.

Unitree SDK2 DDS settings dialog

Press Start to scan DDS publications and select topics from the discovered list. Supported types are sorted first and selected by default. If the robot or DDS publisher starts later, press Refresh to scan again. After confirmation, the plugin subscribes to the selected topics and writes PlotJuggler series.

Joystick fields defaults to Parsed structure. In this mode, Unitree joystick data is decoded into fields such as wireless_remote/buttons/*, wireless_remote/axes/*, joystick/buttons/*, and joystick/axes/* instead of only exposing raw bytes or key bitmasks.

Data enhancement provides three independent checkboxes:

  • PD torque (tau_des): checked by default. Combines LowCmd and LowState to calculate total torque and its P/D terms.
  • Flatten: unchecked by default. Retains original motor_state and motor_cmd fields and adds field-first series under the top-level motorstate* and motorcmd* groups, such as lowstate/motor_state/00/qmotorstate*/q/00 and lowcmd/motor_cmd/00/kpmotorcmd*/kp/00. Values, timestamps, and motor indices are preserved. Nested arrays such as motor_state/00/temperature/1 become motorstate*/temperature/00/1.
  • Joint power (des, est): unchecked by default. Calculates desired and estimated power for each joint (signed mechanical power in watts), independently of the PD torque output option.

With PD torque checked and both LowCmd and LowState subscribed, three series are appended per motor:

lowstate/motor_state/NN/tau_des_p* = kp * (q_cmd - q_state)
lowstate/motor_state/NN/tau_des_d* = kd * (dq_cmd - dq_state)
lowstate/motor_state/NN/tau_des*   = tau_cmd + tau_des_p + tau_des_d

The trailing * marks calculated torque fields. Checking PD torque and Flatten also adds motorstate*/tau_des*/00, motorstate*/tau_des_p*/00, and motorstate*/tau_des_d*/00. Each state sample produces one set of torques, preferring the sibling lowcmd topic; when it is absent, a single unambiguous command topic is used.

Go2 and HG messages are paired by SDK family, topic namespace, and motor index. Series use the actual state topic path under motor_state/NN/. LowState drives sampling: after the first LowCmd arrives, torques are computed only on each LowState, using that state's local receive time. LowCmd uses a zero-order hold: the latest received command is reused until replaced. Command updates only refresh the cache; they do not append torque samples or recompute past states. Calculations requiring a paired command pause if multiple LowState topics arrive in one namespace; HG mode_pr values must also match. Like joystick parsing, all three checkboxes are saved independently in default settings and layout XML and take effect during streaming. The legacy data enhancement setting restores the PD torque choice. Disabling any option stops appending its data and retains existing curves. Re-enabling calculations after both PD torque and joint power were off, or restarting the stream, clears the command pairing cache and waits for fresh commands.

With joint power checked, each LowState produces power using its measured velocity:

lowstate/motor_state/NN/power_des* = tau_des * dq_state
lowstate/motor_state/NN/power_est* = tau_est * dq_state

tau_des includes feed-forward, P, and D terms, computed internally even with PD torque output unchecked. It uses the held LowCmd and the existing pairing rules. power_est* depends only on LowState, without waiting for a command. Both powers use the state's timestamp and retain their sign rather than taking an absolute value; stationary joints have zero mechanical power. Checking Flatten also adds the top-level motorstate*/power_des*/NN and motorstate*/power_est*/NN series.

Leading unitree/ and rt/ topic path components are removed from series names, for example:

lowstate/imu_state/rpy/0
lowstate/motor_state/00/q
sportmodestate/velocity/0

The time axis is local elapsed seconds from the moment streaming starts.

4. Open the Robot Posture View

First stream lowstate data with Unitree SDK2 DDS, then open Tools / Unitree Robot View. Robot View does not subscribe to DDS by itself; it consumes the time series already loaded into PlotJuggler.

Unitree Robot View showing a G1 posture replay

Input series:

  • lowstate/imu_state/rpy/* or lowstate/imu_state/quaternion/*
  • lowstate/motor_state/NN/q

Controls:

  • Drag with the left mouse button to rotate the camera.
  • Use the mouse wheel to zoom.
  • Double-click to reset the camera.
  • Click the top-right axis icon to align the view to an axis.
  • Keep Live checked to follow the latest data, or uncheck it and drag the timeline to replay older posture data.

Supported Messages

Topic support is determined by DDS type, not by fixed topic names. Built-in support covers top-level Unitree SDK2 IDL message types under:

  • unitree_go
  • unitree_hg
  • unitree_hg_doubleimu
  • ROS2-style std_msgs, geometry_msgs, sensor_msgs, and nav_msgs

Numeric fields are flattened recursively. Strings are exported as /length; if a string contains valid JSON, numeric and boolean JSON leaves are also exported under /json/.... Large variable-length sequences such as images, point clouds, and maps are size-limited to avoid flooding PlotJuggler.

To add new message types, update:

include/plotjuggler_unitree_sdk2/unitree_message_flatten.h

Robot View Models and Motor Order

Motor order follows Unitree SDK2 LowState.motor_state[], not URDF joint order. Go2 example:

FR_hip, FR_thigh, FR_calf,
FL_hip, FL_thigh, FL_calf,
RR_hip, RR_thigh, RR_calf,
RL_hip, RL_thigh, RL_calf

The current bundle supports A1, Aliengo, B1, B2, B2W, Go1, Go2, Go2W, G1 23DOF, G1 29DOF, G1-D, H1, H1-2, H2, R1, and R1 AIR.

Dependency Policy

The repository tracks project source, CI configuration, and required dependency declarations only. Build trees, install trees, generated bundles, deb caches, local sysroots, and PlotJuggler source checkouts are ignored.

Required dependencies:

  • third_party/unitree_sdk2: Git submodule for Unitree SDK2, DDS type definitions, and DDS runtime libraries.
  • third_party/unitree_ros_assets: Git submodule for Robot View URDF and mesh assets.
  • Qt: system development package dependency.
  • PlotJuggler: build-time development prefix dependency. It must provide plotjugglerConfig.cmake and plotjuggler_base; it is not a repository submodule.

Local Development

1. Install System Dependencies

On Ubuntu 22.04/24.04:

scripts/install_ubuntu_deps.sh

This installs CMake, Ninja, Qt5, PlotJuggler build dependencies, and the base development packages used by CI.

2. Initialize Submodules

git submodule update --init --depth 1 \
  third_party/unitree_sdk2 \
  third_party/unitree_ros_assets

3. Prepare a PlotJuggler Development Prefix

If the Snap PlotJuggler package is available, reuse its development prefix:

export PLOTJUGGLER_PREFIX=/snap/plotjuggler/current/usr/local

If no development prefix is available, build PlotJuggler 3.17.2 into .deps/plotjuggler-3.17.2:

scripts/build_plotjuggler_dev.sh
export PLOTJUGGLER_PREFIX="$PWD/.deps/plotjuggler-3.17.2"

4. Configure, Build, and Test

Recommended local build:

scripts/build_local_bundle.sh

Equivalent CMake preset commands:

cmake --preset dev
cmake --build --preset dev --parallel 4
ctest --preset dev

Build only the message flattener smoke test, without Qt or PlotJuggler:

cmake --preset smoke
cmake --build --preset smoke --parallel 4
ctest --preset smoke

5. Common CMake Options

  • UNITREE_SDK2_ROOT=/path/to/unitree_sdk2: override the default submodule.
  • PJ_UNITREE_BUNDLE_DIRECTORY=/path/to/bundle: choose the runtime bundle output directory.
  • PJ_UNITREE_BUILD_BUNDLE=OFF: build the shared libraries only, without copying the runtime bundle.
  • PJ_UNITREE_COPY_ROBOT_ASSETS=OFF: skip URDF/mesh copying, useful when working only on the DDS plugin.
  • PJ_PLUGIN_INSTALL_DIRECTORY=/path/to/plugin_dir: install plugins to a specific PlotJuggler plugin directory with cmake --install.

Build Outputs

Raw build outputs:

build/dev/libplotjuggler_unitree_sdk2.so
build/dev/libplotjuggler_unitree_robot_view.so

Default runtime bundle:

bundle/plotjuggler_unitree_sdk2/
  libplotjuggler_unitree_sdk2.so
  libplotjuggler_unitree_robot_view.so
  libddsc.so
  libddsc.so.0
  libddscxx.so
  libddscxx.so.0
  assets/robots/
  licenses/

The bundle uses $ORIGIN RPATH for the DDS runtime libraries copied from Unitree SDK2. Qt and PlotJuggler libraries are intentionally not bundled; runtime users should rely on their installed PlotJuggler distribution.

Packaging and Releases

Create a release package after building:

scripts/package_bundle.sh 0.1.0

Outputs:

dist/plotjuggler-unitree-sdk2-0.1.0-linux-x86_64.tar.gz
dist/plotjuggler-unitree-sdk2-0.1.0-linux-x86_64.tar.gz.sha256

GitHub Actions:

  • .github/workflows/ci.yml: builds with the ci preset, runs tests, and uploads a bundle artifact. CI uses a Release build and 2 parallel compile jobs to match the standard ubuntu-22.04 GitHub-hosted runner resource profile.
  • .github/workflows/release.yml: builds and publishes a GitHub Release when a v* tag is pushed.

Release:

git tag v0.1.0
git push origin v0.1.0

Licenses

Project source code is licensed under the permissive MIT License; see LICENSE. It allows copying, modification, redistribution, and commercial use, provided that the copyright and license notice are retained.

Unitree SDK2 and Unitree ROS assets are BSD-3-Clause licensed. The release bundle copies:

  • licenses/unitree_sdk2_LICENSE
  • licenses/unitree_sdk2_thirdparty/
  • licenses/unitree_ros_LICENSE

About

Plotjuggler plugin for subscription and visualization for unitree sdk2

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages