Drive UR Dual-Arm Robots in with Exoskeleton Controller : A Better Alternative to VR Joysticks

The myController S570 is a werable lightweight exoskeleton with 14 joints, 2 joysticks and 2 buttons, it is well-suited for remote operation and data acquisition of unmanned tasks , making it an ideal tool for industrial automation, workstation tasks and humanoid robots control .

This article uses a UR5 dual-arm for a fast and intuitive remote control case in ROS RViz.

image

微信图片_20250205152618

Steps for Building the Project

Using Exoskeleton to Quickly Control UR5 Dual-Arm in ROS

This example is built on Ubuntu 20.04 + ROS Noetic + Miniconda with a Python 3.8 virtual environment.

To avoid unresolved errors, please set up the project according to the specified requirements.

1. Create a ROS Python 3.8 Environment

2. Build the ROS Workspace then Clone the Third-Party and Main Project

bash

cd ~mkdir myController_ws && mkdir myController_ws/src && cd myController_ws/src

git clone https://github.com/THU-DA-Robotics/Universal_Robots_ROS_Driver.git

git clone -b noetic_devel https://github.com/THU-DA-Robotics/robotiq.git

git clone https://github.com/THU-DA-Robotics/dual_ur.git

git clone -b mycontroller_s570 https://github.com/elephantrobotics/mycobot_ros.git

3. Catkin_make and Open Rviz

bashcd ..  catkin_make 

source devel/setup.bash 

 roslaunch mycontroller_s570 test.launch

You will see the myController S570 exoskeleton model in rviz.

4. Connect myController S570 to PC.

Please follow the gitbook.

5. Check the Serial Name and Test Data Transmission

bash

conda activate ros_py38 
 ( you can add this line to ~/.bashrc to avoid repeated operations )

ls /dev/tty*

cd /home/u184/controller_ws/src/mycobot_ros/mycontroller_s570/scripts

gedit test.py

Close Gedit, create a new terminal to run the scripts.

bash

cd /home/u184/controller_ws/src/mycobot_ros/mycontroller_s570/scripts

python3 test.py

You will see the exoskeleton model in Rviz move with the real one.

6. Control UR5 Dual-Arm in Rviz

In this part of step, we should modify the launch file that starts Rviz for the robot, adjusting the node names, message types, etc., so that the joint transformation information of the robot model matches the messages published by the myController S570**.**

6.1 Create a New Launch File

<launch>
  <arg name="model" ></arg>

  <include file = "$(find dual_ur_description)/launch/load_dual_ur5.launch"></include>

  <node
    name="joint_state_publisher_gui"
    pkg="joint_state_publisher_gui"
    type="joint_state_publisher_gui" ></node>

  <node
    name="robot_state_publisher"
    pkg="robot_state_publisher"
    type="robot_state_publisher" ></node>

    <!-- start RViz -->
    <node name="rviz" pkg="rviz" type="rviz" args="-d $(find dual_ur_description)/rviz/visualize_urdf.rviz" required="true"></node>

    <!-- transform of joints -->
    <node pkg="tf2_ros" type="static_transform_publisher" name="virtual_joint_broadcaster_0" args="0 0 0 0 0 0 world dual_base"></node>

</launch>

6.2 Modify Pyhon Script to Ensure the Pubilished Joints Name

#!/usr/bin/env python

"""
This package need `pymycobot`.
This file for test the API if right.

Just can run in Linux.
"""
from exoskeleton_api import Exoskeleton, ExoskeletonSocket
import rospy
from math import pi
import time
from sensor_msgs.msg import JointState
from std_msgs.msg import Header
import rosnode
import os
import subprocess

os.system("sudo chmod 777 /dev/ttyACM*")

obj = Exoskeleton(port="/dev/ttyACM3")

def shutdown_ros_node(node_name):
    try:
        subprocess.run(['rosnode', 'kill', node_name])
        print(f"Node {node_name} has been shutdown.")
    except subprocess.CalledProcessError as e:
        print(f"Error: {e}")

# init ROS node
rospy.init_node('dual_arm_joint_state_publisher')

shutdown_ros_node('joint_state_publisher_gui')

# create publisher
pub = rospy.Publisher('/joint_states', JointState, queue_size=10)

rate = rospy.Rate(100) # 100Hz

joint_state = JointState()

while not rospy.is_shutdown():
    joint_state.header = Header()
    
    joint_state.header.stamp = rospy.Time.now()
    
    # origin
    #joint_state.name = ['joint1', 'joint2', 'joint3','joint4', 'joint5', 'joint6','joint7','joint8','joint9','joint10',
    #                    'joint11','joint12','joint13','joint14']
    # new for dual-arm
    joint_state.name =[
            'arm_0_shoulder_pan_joint', 
            'arm_0_shoulder_lift_joint', 
            'joint3',
            'arm_0_elbow_joint', 
            'arm_0_wrist_2_joint',
            'arm_0_wrist_1_joint', 
            'arm_0_wrist_3_joint', 
            'arm_1_shoulder_pan_joint', 
            'arm_1_shoulder_lift_joint', 
            'joint10', 
            'arm_1_elbow_joint',
            'arm_1_wrist_2_joint', 
            'arm_1_wrist_1_joint', 
            'arm_1_wrist_3_joint',
        ]
    l_angle = obj.get_arm_data(1)
    l_angle = l_angle[:7]
    l_angle = [int(x) for x in l_angle]
    print("l:",l_angle)
    r_angle = obj.get_arm_data(2)
    r_angle = r_angle[:7]
    r_angle = [int(y) for y in r_angle]
    print("r:",r_angle)
    angles = l_angle + r_angle 

    angle = [a/180*pi for a in angles]

    # Rotation relation mapping from exoskeleton to robot joint
    angle[0]-=3.14
    angle[3]+=0.52
    angle[4]-=1.57


    angle[10]+=0.52
    angle[11]-=1.57
    angle[12]=-angle[12]-1.57


    
    joint_state.position = angle
    joint_state.effort = []
    joint_state.velocity = []

    pub.publish(joint_state)
    rospy.loginfo('successfully published')
    rate.sleep()

the names should match with ur5 dual-arm urdf model

the names should match with ur5 dual-arm urdf model

6.3 Open 2 New Terminals to Test Dual-Arm Robotic Control

Open one terminal to launch rviz.

bash

cd ~/controller_wssource devel/setup.sh

roslaunch dual_ur_description control_dual_ur5.launch

Open another terminal to run test.py to start the exoskeleton and test motion control.

bash

conda activate ros_py38

cd /home/u204/myController_ws/src/mycobot_ros/mycontroller_s570/scripts

python3 test.py

Outlook for Secondary Development

For connecting this demo to a real robot for testing, you should refer to the wiki by another author of the dual-arm-robotq project.

In case of using other robots for simulation tasks, the same steps related to myController S570 installation and launch files modification in this project can be referenced. During development, the following points should be considered:

  • Redundant degree-of-freedom handling.
  • Joints angle mapping adjustments between the exoskeleton controller and the robot accroding to the DH models.

new (6)

2 Likes