Build a MuJoCo + ROS2 Robotic Arm Workflow for Embodied AI

MuJoCo Simulation and ROS2 Control Workflow | Piper Robotic Arm for Embodied AI

This project is a MuJoCo-based simulation foundation for the Piper robotic arm. It is designed to provide a general-purpose MuJoCo simulation environment for the Piper arm, with support for robot control testing and simulation workflow development.

Project has already completed

  • the launch of the C++ based simulation environment
  • control testing of the simulated robot using a test ROS 2 control plugin

Recommended Environment

  • Operating System: Ubuntu 22.04 or compatible Linux distribution
  • ROS Version: ROS 2 Humble
  • Compiler: C++17 or later

Reference & Resources

  • Reference Project: https://github.com/unitreerobotics/unitree_mujoco
  • PiPER robotic arm platform: https://global.agilex.ai/products/piper

The following sections provide step-by-step guidance for building the current version of the Piper MuJoCo simulation environment and using the ROS 2 test plugin to control the robot in simulation.

2026-05-06 15-21-26


1.Project File Structure

agilex@agilex-Bellator-N176B:~/project/agilex_arm_mujoco$ tree -L 3
β”œβ”€β”€ agilex_arm
β”‚   └── agilex_piper
β”‚       β”œβ”€β”€ assets
β”‚       β”œβ”€β”€ piper_body.xml
β”‚       β”œβ”€β”€ piper.png
β”‚       β”œβ”€β”€ piper.xml
β”‚       └── scene.xml
β”œβ”€β”€ images
β”‚   β”œβ”€β”€ mujoco_piper.png
β”‚   └── piper.png
β”œβ”€β”€ README_EN.md
β”œβ”€β”€ readme.md
└── simulate
    β”œβ”€β”€ CMakeLists.txt
    β”œβ”€β”€ config.yaml
    β”œβ”€β”€ mujoco
    β”‚   β”œβ”€β”€ bin
    β”‚   β”œβ”€β”€ include
    β”‚   β”œβ”€β”€ lib
    β”‚   β”œβ”€β”€ model
    β”‚   β”œβ”€β”€ sample
    β”‚   β”œβ”€β”€ simulate
    β”‚   └── THIRD_PARTY_NOTICES
    └── src
        β”œβ”€β”€ lodepng
        β”œβ”€β”€ main.cc
        β”œβ”€β”€ param.h
        β”œβ”€β”€ plugin_manager.cc
        β”œβ”€β”€ plugin_manager.h
        β”œβ”€β”€ ros2_control_plugin.cc
        β”œβ”€β”€ ros2_control_plugin.h
        └── sim_plugin.h

2.Project Setup & Build

2.1 Build the agilex_arm_mujoco Project

The build process for the agilex_arm_mujoco project follows the same workflow as the unitree_mujoco project.
This section provides a step-by-step guide to setting up the simulation base, including optional instructions for enabling the ROS 2 control plugin.

Step 1.Clone the Repository

First, create a working directory and clone the project repository:

mkdir agilex_arm && cd agilex_arm
git clone https://github.com/yanyuze1/agilex_arm_mujoco.git

By default, the project includes MuJoCo 3.3.0 for ROS 2 control testing.
If you want to use a different MuJoCo version, download and replace it manually before building.

Step 2. Two Build Modes

The agilex_arm_mujoco project supports two build modes:

  • Option 1: Build without the ROS 2 plugin
  • Option 2: Build with the ROS 2 plugin enabled

Choose the mode based on your development needs.

Option 1: Without the ROS 2 Plugin

  • Step 1: Edit agilex_mujoco/simulate/CMakeLists.txt, change the default enabled ros2 plugin mode to OFF
# from
option(AGILEX_ENABLE_ROS2_CONTROL "Build ROS2 control plugin" ON)
# change to
option(AGILEX_ENABLE_ROS2_CONTROL "Build ROS2 control plugin" OFF)
  • Step 2: Build the Project. After editing the file, build the simulation base:
cd agilex_arm_mujoco/simulate
mkdir build && cd build
cmake ..
make -j4

Option 2: With the ROS 2 Plugin Enabled

If you want to test robot control through the ROS 2 plugin, keep the default configuration and build the required ROS 2 dependencies first.

  • Step 1: Clone the Dependency Workspace
    Create or enter the agilex_arm directory and clone the repository:
cd agilex_arm
git clone https://github.com/yanyuze1/agilex_ws.git
  • Step 2: Build ROS 2 Dependencies
    Build the required packages in the ROS 2 workspace:
cd agilex_ws
colcon build --symlink-install --packages-up-to mujoco_ros2_control agilex_piper_mujoco
source install/setup.bash
  • Step 3: Build the Simulation Base
    After the dependency build is complete, compile the simulation project:
cd agilex_mujoco/simulate
mkdir build && cd build
cmake ..
make -j4

2.2 Run the agilex_arm_mujoco Project

The agilex_arm_mujoco project provides two runtime modes:

  • Start the simulation base only
  • Start the simulation base with the ROS 2 plugin enabled

Choose the mode according to your development and testing needs.

2.2.1 Start the Simulation Base Only

If you only want to launch the simulation environment without ROS 2 integration, use the following command:

./agilex_mujoco -h
./agilex_mujoco -r piper -s scene.xml
./agilex_mujoco -r piper -s scene.xml -p ros2_control

After successful execution, the MuJoCo simulation environment will launch automatically, displaying the Piper robotic arm in the MuJoCo simulation scene.

2.2.2 Start the Simulation Base with the ROS 2 Plugin Enabled

If you only want to launch the simulation environment with ROS 2 integration, use the following command:

cd agilex_ws
source install/setup.bash
ros2 launch agilex_piper_mujoco bringup_agilex_mujoco_cartesian_motion_controller.launch.py   agilex_mujoco_exec:=/home/agilex/project/piper/agilex_mujoco/simulate/build/agilex_mujoco   # The current project uses absolute paths. Please modify them according to your own local path.

When the launch is successful, a MuJoCo simulation window will open and display the Piper robotic arm in the simulation environment.

Once the environment is fully loaded, you can start sending ROS 2 control commands.

Usage Situation

1. Send a Target End-Effector Pose
Use the following command to publish a target pose for the end effector:

ros2 topic pub --once /agilex_piper_cartesian_motion_controller/target_frame \
  geometry_msgs/msg/PoseStamped "{
    header: {frame_id: 'base_link'},
    pose: {
      position: {x: 0.2, y: 0.0, z: 0.2},
      orientation: {x: 0.0, y: 1.0, z: 0.0, w: 0.0}
    }
  }"

2026-05-06 16-15-04

2. Control the Gripper

# Open the Gripper
ros2 topic pub --once /agilex_piper_gripper_position_controller/commands \
  std_msgs/msg/Float64MultiArray "{data: [0.035, -0.035]}"

# Close the Gripper
ros2 topic pub --once /agilex_piper_gripper_position_controller/commands \
  std_msgs/msg/Float64MultiArray "{data: [0.0, 0.0]}"

2026-05-06 16-17-31

3. Check the Robot State
To view the current end-effector pose, use:

ros2 topic echo /agilex_piper_cartesian_motion_controller/current_pose

3.Afterword

This project is built upon and integrated from several open-source repositories. The main credit goes to the original authors and the open-source community.

We would like to sincerely thank the open-source community for making these technologies accessible through shared code and practical experience.

:speech_balloon: MuJoCo + ROS2 Robotic Manipulation FAQ

1. Why use MuJoCo for the Piper robotic arm instead of Gazebo or Isaac Sim?

MuJoCo provides a lightweight and high-performance physics simulation workflow, making it ideal for rapid robotics prototyping, control validation, and future reinforcement learning research. Compared with heavier simulators, it can run efficiently on more accessible hardware.

2. Can this simulation workflow be transferred to a real Piper robotic arm?

Yes. The ROS2 control architecture is designed to align simulation and real hardware interfaces, making future sim-to-real deployment more practical.

3. Why build a custom MuJoCo + ROS2 workflow instead of using existing robotics simulators?

This project focuses on providing a simpler and more flexible robotics development workflow with lower hardware requirements and easier customization for developers and researchers.

4. Is this MuJoCo robotic arm project suitable for reinforcement learning (RL)?

Yes. The simulation framework can serve as a foundation for reinforcement learning workflows such as PPO training, imitation learning, grasping policy development, and sim-to-real robotic manipulation research.

5. How does ROS2 Control work with MuJoCo simulation?

The project integrates ROS2 Control plugins into the MuJoCo simulation environment, allowing developers to send ROS2 motion commands directly to the simulated robotic arm and receive real-time robot state feedback.

Still Have Question?

If you encounter any issues with environment installation, parameter configuration, or RL training, feel free to leave your questions for further discussion.

1 Like

Are you aware of mujoco_ros2_control? It integrates directly as a hardware_interface::SystemInterface into the ros2_control stack. With the MuJoCo models that you provide in unitree_mujoco/unitree_robots at main Β· unitreerobotics/unitree_mujoco Β· GitHub, you should be able to replicate this natively in the ROS 2 control stack.

2 Likes

Thank you for pointing out this! We will review your suggestion and work on further improvements.

It seems this repo uses an older version from Google Summer of Code:

Copied from GitHub - moveit/mujoco_ros2_control Β· GitHub

2 Likes

FYI, Gazebo is also adding support for MuJoCo as part of this year’s roadmap. Tracking issue: MuJoCo physics engine plugin Β· Issue #299 Β· gazebosim/gz-physics Β· GitHub

3 Likes

Thanks for pointing that out! While this repo builds on the older GSoC version of mujoco_ros2_control, we’ve adapted and tested it thoroughly for our use case, and it has no significant impact on core functionality or simulation behavior.

The mujoco_ros2_control should be pretty much direct to integrate, similar to the other simulations. Moreover, they are also available as binaries from Humble to Rolling.

1 Like

Thanks for posting! I’ve got ROS2 control with MuJoCo on my radar as a skill I need to learn.

1 Like