Skip to main content
After connecting the device through wuji_hand2_driver, you can read joint and sensor state, view the model in RViz, and control the device through joint commands and services.

Installation

Use Ubuntu 26.04 (resolute) with ROS 2 Lyrical installed, on x86_64 or aarch64. The commands below fetch the source, load ROS, install dependencies and Hand 2 descriptions, and build the workspace. The build downloads and verifies the Wuji SDK C package for the host architecture.
  • The description installer requires /etc/apt/sources.list.d/ros2.sources. If it is missing, configure the Lyrical package source using the official ROS 2 installation steps, then rerun the script.
  • If rosdep has never been initialized on the computer, run sudo rosdep init once before rosdep update. The sudo commands require administrator access.
  • If the SDK download fails, download and extract wuji-sdk-c-2026.10.12-x86_64-linux-gnu.tar.gz or wuji-sdk-c-2026.10.12-aarch64-linux-gnu.tar.gz from Wuji SDK v2026.10.12, matching your host architecture. Confirm that the extracted directory contains include/wuji_sdk.h, lib/libwuji_sdk_c.so, and LICENSE. Replace /path/to/sdk with the absolute path to that directory, then run this command from wuji-ros2 instead of the default build command:
  • CMake does not validate the SDK version when WUJI_SDK_ROOT is set. Use the release package specified above.
In each new terminal, enter the workspace and load ROS and the built packages:

Select a Device

Follow the User Notice to secure the hand and prepare power and networking. Then scan for devices:
Record the target device’s required serial_number and hand_side. If connecting by address, also record its optional endpoint.

View the Model and State

Run the Validation

1. Start the Driver and View the Model Replace HAND_SERIAL_NUMBER and HAND_SIDE with the serial number and hand side recorded in Select a Device. Run hand2_view.launch.py from the built wuji_bringup package to start the driver, robot_state_publisher, and RViz:
To connect by the endpoint shown in the scan, replace HAND_ENDPOINT with that IP:port address and use this command:
The driver waits up to 10 seconds for the device to connect by default. Append connect_timeout:=20.0 to the launch command to extend the connection wait to 20 seconds. Launch arguments are read only at startup. Boolean arguments accept only lowercase true / false.
This launch file requires serial_number and fixes auto_enable to false. It doesn’t enable joints at startup or disable a hand that was already enabled. When the launch stops, the driver calls the disable API for all joints. If the call fails, it logs a warning and continues to exit. Confirm that the device has actually stopped. model_revision:=1 selects wuji_hand2_1_description. Selecting a model doesn’t change the firmware. Data and control capabilities still depend on the SDK resources served by the device. The model root is l_mount for the left hand or r_mount for the right hand, and RViz uses that root frame. The parent application must provide the transform from the mount to its robot or world frame. 2. Check State Data Keep the launch running. Open a new terminal, enter the workspace, and load ROS and the built packages before checking state data:
The example observes joint_states, joint_diagnostics, and imu for 10 seconds by default and reports frame counts and average receive rates. It succeeds after receiving at least one joint state with 20 positions, one joint diagnostic message with 20 entries, and one IMU message. This check doesn’t validate motion control or every sensor. The demo reports PASS/FAIL after the full observation period. To observe for 30 seconds, run:
If the driver connects but RViz shows No tf data or the status example receives no data, first check namespaces, ROS_DOMAIN_ID, and QoS across terminals. If the problem persists, try another ROS 2 middleware. Install Cyclone DDS:
Stop the current launch. Run this command in each terminal used for steps 1 and 2:
Then rerun the commands in steps 1 and 2. Set the same ROS 2 middleware in any new terminals you open later.

State and Sensor Topics

The driver publishes joint states, joint diagnostics, and IMU data on the topics below. Subscribe using the listed message types. Topic names are relative: with namespace:=hand, joint_states resolves to /hand/joint_states.
For field definitions, see wuji_msgs/msg/JointDiagnosticsArray.msg and wuji_msgs/msg/JointDiagnostics.msg in the wuji-ros2 repository, and the ROS 2 JointState.msg and Imu.msg definitions. After sourcing the workspace, run ros2 interface show wuji_msgs/msg/JointDiagnosticsArray to inspect the custom message and its nested fields.

Control the Device

The driver sends position, velocity, and current-proxy targets without switching control modes. Motion depends on the device’s current control mode and parameters.

Send Joint Commands

1. Start the driver Stop the view launch started in 1. Start the Driver and View the Model. Secure the unloaded hand and keep people clear of moving parts. Start control with the same serial number and hand side:
auto_enable:=true enables all joints after startup. It doesn’t send motion targets yet. 2. Check the current positions Keep the driver running. Open a new terminal.
If the driver uses Cyclone DDS, configure the same ROS 2 middleware in this terminal:
Run these commands to load ROS and read joint positions:
The wave demo sends zero targets immediately. Before running it, confirm that the path from the current position to zero is safe. The joints may move quickly toward zero. 3. Run the wave demo In the terminal with the ROS environment loaded, run:
The wave demo publishes zero targets to /hand/joint_commands for one second, then publishes wave commands at 100 Hz. Thumb and abduction targets stay at 0 rad. The other four fingers move between 0 and 1.0 rad with a 0.5 Hz cosine wave. Observe the hand and joint position changes. 4. Stop and disable Press Ctrl+C to stop the wave demo, then disable all joints:
Confirm the response contains success: true before stopping the driver launch, and verify that the hand has stopped.
The driver has no command watchdog. Stopping the publisher doesn’t send zeros, trigger an emergency stop, or disable the hand. When the launch stops, the driver calls the disable API for all joints. If the call fails, it logs a warning and continues to exit. Confirm that the device has actually stopped. If the disable request fails, don’t assume that exiting the launch or losing the connection has disabled the hand.

Joint Command Format

Publish sensor_msgs/msg/JointState messages to joint_commands. The publisher fills the name, position, velocity, and effort fields. They aren’t launch arguments. Named commands: When writing a publisher, put joint names published in joint_states in name, and provide position values in the same order. You can specify a subset of joints in any order. The driver fills targets for unlisted joints with zero, so explicitly include any joints whose targets you want to preserve. Fixed-order commands: Leave name empty and provide all 20 position values in the order below. The wave demo above uses this format. Prefix the listed joint names with l_ or r_ for the selected hand. Fixed-length services use the same order. In either format, empty velocity and effort arrays are filled with zeros. Nonempty arrays must match the number of commanded joints. Unknown, duplicate, or opposite-side names, invalid lengths, nonfinite values, and values outside the float32 range reject the complete command.

Call Control Services

Services use reliable QoS and the same namespace. Check both the success flag and error information in the response. An all-false mask changes no joints. Fixed-length services require all 20 entries and don’t accept joint names or partial arrays. Current limits, kp, and kd must be finite and nonnegative. kp and kd retain their SDK definitions without additional physical units. Rejected joint commands produce rate-limited ERROR logs in the driver terminal, with no result topic. Failed service calls return success: false and error information. The driver keeps running. To request an emergency stop, call:
The driver doesn’t latch the emergency-stop state. After the call, the controlling application must stop publishing joint commands, or later commands may still take effect.