A full ROS Noetic stack with 200 Hz RS-485 hardware driver, kinematic calibration, sim-to-real mirror, and teleoperation — open source.
Ubuntu 20.04, ROS Noetic, Python ≥ 3.9.
git clone https://github.com/thejerrycheng/IRIS.git cd IRIS/meng_ws rosdep install --from-paths src --ignore-src -r -y catkin_make && source devel/setup.bash
ls /dev/ttyUSB* sudo usermod -aG dialout $USER sudo chmod 666 /dev/ttyUSB0
roslaunch unitree_arm_ros iris_bringup.launch
# verify
rostopic echo /joint_statesrosrun unitree_arm_ros calibrate_home_state.py rosrun unitree_arm_ros calibrate_joint_states.py
All components live in unitree_arm_ros. The hardware driver is the core — everything else communicates over standard ROS topics.
IRIS ROS node communication graph
Hardware driver. 200 Hz RS-485 loop, publishes /joint_states, subscribes /arm/command.
Applies encoder offsets from calibration.yaml and handles differential wrist coupling for joints 5 & 6.
IK-based keyboard control. Move end-effector in Cartesian space with WASD + arrow keys.
Joint-space keyboard teleoperation. Direct joint angle control for calibration and collision testing.
Streams real joint states into MuJoCo in real time. Enables live sim–real visual comparison during operation.
Kinesthetic teaching. Guide the arm by hand to record a trajectory, then replay at any speed.
| Topic | Type | Description |
|---|---|---|
| /joint_states | sensor_msgs/JointState | Raw encoder positions, velocities, torques @ 200 Hz |
| /joint_states_calibrated | sensor_msgs/JointState | Calibrated joint states with offsets applied |
| /arm/command | sensor_msgs/JointState | Target joint positions, velocities, feed-forward torques |
| /camera/color/image_raw | sensor_msgs/Image | RGB frames from RealSense D435 |
| /camera/depth/image_rect_raw | sensor_msgs/Image | Depth frames from RealSense D435 |
Any motion on the physical arm is reflected instantly in the MuJoCo viewer. Use it to validate calibration before running autonomy.
# 1. Start hardware driver roslaunch unitree_arm_ros iris_bringup.launch # 2. Open MuJoCo mirror rosrun unitree_arm_ros mujoco_visualizer_calibrated.py
Requires calibrated states on /joint_states_calibrated.
Maps encoder counts to joint angles and corrects differential wrist coupling. Results stored in calibration.yaml.
rosrun unitree_arm_ros calibrate_home_state.py
# Move to zero pose → press Enter to recordRecords absolute encoder values at mechanical home. Run once after assembly.
rosrun unitree_arm_ros calibrate_joint_states.py
# Applies offsets, corrects differential wristThe differential wrist (joints 5 & 6) requires coupling correction — handled automatically.
# config/calibration.yaml joint_offsets: [0.0, -1.5708, 1.5708, 0.0, 0.0, 0.0] # radians differential_wrist: joint5_gain: 0.5 joint6_gain: 0.5 home_encoder_counts: [2048, 2048, 2048, 2048, 2048, 2048]
Synchronized joint states, RGB, and depth captured as ROS bags. Episodes are extracted and structured for training.
# Record a demonstration bash ~/IRIS/meng_ws/record_data.sh -O EPISODE_NAME # Process bag → episode format cd ~/IRIS/bag_reader/scripts python process_rosbag.py \ --bag /path/to/demo.bag \ --out /path/to/processed_data
Kinesthetic recording
Semi-autonomous mode
Processed episodes: episode_XXXX/rgb/, episode_XXXX/depth/, episode_XXXX/robot/joint_states.csv.
See the Learning page for dataset details.