ROS2 package for SO-ARM101 robot VR controller
| VR Teleoperation | Dual Arm Control | Chassis Control |
|---|---|---|
![]() | ![]() | ![]() |
| VR Control Robot |
|---|
![]() |
This ROS2 package provides a comprehensive VR-based teleoperation system for the SO-ARM101 robotic arm. It enables intuitive robot control through VR controllers by mapping VR headset and controller transforms to robot end-effector poses and joint commands.
Key Features:
- VR Teleoperation: Real-time transformation from VR controller poses to robot end-effector positions using inverse kinematics, with VR trigger-based gripper control and dynamic calibration system
- Dual Arm Control: Support for single arm (left/right) or simultaneous dual arm operation with independent topic remapping and synchronized control
- Chassis Control: Integrated mobile base control through VR joystick inputs for coordinated arm-chassis manipulation tasks
Architecture:
The system consists of three main components:
- VR TF Receiver: Subscribes to VR transforms and joystick inputs, performs IK solving
- Robot Control Interface: Manages motor commands with queue-based execution and state monitoring
- Chassis Controller: Handles mobile base motion commands
Supported Hardware:
- SO-ARM101 robotic arm with STS3215 servo motors
- VR headsets with 6-DOF tracking (tested with common VR platforms)
- Optional mobile chassis with differential drive
- Operating System: Ubuntu 22.04 LTS
- ROS Version: ROS2 Humble Hawksbill
- Compiler: C++17 compatible compiler (GCC 9.0+, Clang 5.0+)
- Python: Python 3.10+
sudo apt update sudo apt install -y \ libnlopt-dev \ libyaml-cpp-dev \ nlohmann-json3-dev \ liborocos-kdl-devInstall required ROS2 packages:
sudo apt install -y \ ros-humble-rclcpp \ ros-humble-std-msgs \ ros-humble-sensor-msgs \ ros-humble-geometry-msgs \ ros-humble-tf2 \ ros-humble-tf2-ros \ ros-humble-tf2-geometry-msgs \ ros-humble-tf2-kdl \ ros-humble-urdf \ ros-humble-robot-state-publisher \ ros-humble-joint-state-publisher \ ros-humble-joint-state-publisher-gui \ ros-humble-rviz2 \ ros-humble-xacro \ ros-humble-kdl-parserUse colcon to build the package:
colcon build --packages-select lerobot_vr_controllerSingle Arm Control (Left Arm):
ros2 launch lerobot_vr_controller vr_controller.launch.py arm_side:=leftSingle Arm Control (Right Arm):
ros2 launch lerobot_vr_controller vr_controller.launch.py arm_side:=rightDual Arm Control:
ros2 launch lerobot_vr_controller vr_controller.launch.py arm_side:=bothWith Custom Configuration Files:
You can override default configuration files using additional parameters:
ros2 launch lerobot_vr_controller vr_controller.launch.py \ arm_side:=left \ chassis_config_file:=/path/to/custom/chassis_config.yamlAvailable Parameters:
arm_side: Arm side selection (left,right, orboth). Default:righturdf_file: Path to the URDF model filejoint_motor_config_file: Path to joint motor configuration filemotor_calibration_file: Path to motor calibration JSON filechassis_config_file: Path to chassis configuration file
Display Robot Model in RViz:
ros2 launch lerobot_vr_controller display_robot.launch.pyFile Location: config/left_vr_to_arm.yaml / config/right_vr_to_arm.yaml
This configuration file defines the mapping between VR controller frames and robot arm links, kinematics solver parameters, and joint control settings.
Key Parameters:
vr_to_arm_tf: wrist_link: wrist_left # Maps robot wrist link to VR controller frame gripper_world_frame: base_link # Robot base frame vr_world_frame: world_vr # VR world reference frame end_effector_frame: gripper_frame_link # End effector frame name kinematics: solver_type: "xlerobot" # IK solver type timeout: 0.005 # IK solver timeout (seconds) ik_tolerances: position_tolerance: 0.03 # Position tolerance (meters) orientation_tolerance: 0.02 # Orientation tolerance (radians) max_reach: 0.4 # Maximum reachable distance (meters) joy_config: trigger_config: trigger_to_gripper_scale: 0.0068 # Trigger to gripper position scale joint_name: gripper # Gripper joint name axes_config: z_advance_scale: -0.0015 # Z-axis movement scale (meters) z_clockwise_rotate_scale: -0.03 # Z-axis rotation scale (radians) joint_pose: home_pose: joint_name: [shoulder_pan, shoulder_lift, elbow_flex, wrist_flex, wrist_roll, gripper] position: [-0.019, -0.955, 1.0, 0.0, -0.021, 0.0] # Home position for each joint joint_filter: alpha: 0.5 # Low-pass filter coefficient for joint smoothing enable_human_arm: false # Enable human arm kinematics constraintsFile Location: config/chassis_config.yaml
Configuration for mobile chassis control parameters.
Key Parameters:
linear_vel_rate: 0.2 # Linear velocity scaling factor angular_vel_rate: -0.2 # Angular velocity scaling factor (negative for inverted control) vel_cmd_topic: "/vr/cmd_vel" # Velocity command topic nameUsage Notes:
linear_vel_rate: Multiplier for VR joystick Y-axis input to linear velocityangular_vel_rate: Multiplier for VR joystick X-axis input to angular velocity- Negative values invert the control direction
File Location: config/motor/so101_follower/joint_motor_config.yaml
Defines the mapping between joint positions (radians) and motor encoder positions for STS3215 servos.
Key Parameters:
joint_motor_pos_mapping: shoulder_pan: motor_pos: 2047 # Motor encoder position at zero joint angle joint_pos: 0 # Joint angle in radians # ... (similar for other joints) joint_to_motor_scale: shoulder_pan: 651.89 # Conversion factor: 1 radian = 651.89 motor ticks # ... (similar for other joints)Calibration Notes:
- Motor center position is typically 2047 (12-bit encoder: 0-4095 range)
- Scale factor 651.89 is derived from: 4096 / (2π) ≈ 651.89 ticks/radian
- Adjust
motor_posvalues during calibration to match actual zero positions
Calibration File: config/motor/so101_follower/motor_calibration.json
Stores motor-specific calibration offsets. This file is generated/updated by the calibration process.
File Location: config/left_arm_remapping.yaml / config/right_arm_remapping.yaml
Used for dual-arm setups to remap topics with arm-specific namespaces.
Key Parameters:
topic: /vr_controller/joint_cmd: /left/vr_controller/joint_cmd /joint_states: /left/joint_states /robot_control/motor_cmd: /left/robot_control/motor_cmd /robot_control/motor_state: /left/robot_control/motor_state /tf: /left/tf /vr/controller_right/joy: /vr/controller_left/joy node: left_lerobot_vr_controller # Node name for remapped instanceUsage:
- Automatically loaded when
arm_side:=bothin launch file - Left arm uses
left_arm_remapping.yamlwith/leftnamespace - Right arm uses
right_arm_remapping.yamlwith/rightnamespace - Enables independent control of two arms without topic conflicts
File Location: config/left_reply_vr_tf.yaml / config/right_reply_vr_tf.yaml
Configuration for VR transform republishing script used in replay/playback scenarios.
- Kaho
- Issac Sim
- Ryan
- Qi Liu
This project is sponsored by MakerMods.



