2026-07-21 15:25:16 +08:00
2026-07-21 15:25:16 +08:00
2026-07-20 10:48:48 +08:00
2026-06-30 10:42:11 +08:00
2026-06-30 10:42:11 +08:00
2026-06-30 10:42:11 +08:00
2026-06-30 10:42:11 +08:00

1. LinkerFFG Glove

1.1 Product Introduction

For specific product introduction, please refer to the calibration example description contained within Attachment 1: Linker FFG (FFG01) Product Instruction Manual

1.2 Software Usage

This product provides ROS1 and ROS2 SDK packages under Ubuntu, working together with Linkerhand's ROS1 SDK and ROS2 SDK to achieve teleoperation actions For specific usage, please jump to Chapter 4: Teleoperation Retargeting System

1.3 Communication Protocol

For specific product introduction, please refer to Attachment 2: Linker FFG (FFG01) Communication Protocol


2. Teleoperation SDK System

2.1 System Introduction

This system's retargeting program is developed based on the ROS1/ROS2 platform, consisting of one node, four publisher topics, and two subscription topics The Linker FFG glove pushes data to the retargeting program via serial port protocol

2.1.1 Download Address

https://github.com/linker-bot/linkerhand-ros-teleo Please contact customer service to obtain the latest SDK

2.1.2 Installing the Teleoperation Retargeting Program

The teleoperation retargeting program is provided in src form, therefore requiring users to compile it themselves for use on different platforms. The teleoperation retargeting program provides a ROS2 version; the ROS1 version is still under development

Copy src to the workspace, then compile

colcon build --symlink-install

There may be permission issues during the process preventing execution; use the following command

chmod 777 -R *

2.1.3 Program Configuration

Enter the ls command in this directory

cd src/linkerhand_retarget/linkerhand_retarget/config
ls -1

After entering the above command, you should normally enter the config directory. After ls -1, you should see the following list

base_config.yml
body_custom_pose.yml
body_unity_pose.yml
hand_config.yml
human_hand_info.yml
linker_hand_info.yml
model_config.yml
retarget_config.yml
speed_config.yml

The only configuration file we need to modify is base_config.yml; other configuration files must not be modified.

The following is an introduction to the configuration content in base_config.yml:

1. Configure Robot Hand Type

robotname_r: l10
robotname_l: l10
  • LinkerHand_L10 series hands should be configured as: l10
  • LinkerHand_L20 series hands should be configured as: l20
  • LinkerHand_O7 series hands should be configured as: o7
  • LinkerHand_T25 series hands should be configured as: t25
  • LinkerHand_L25 series hands should be configured as: l25
  • LinkerHand_L6 series hands should be configured as: l6
  • LinkerHand_O6 series hands should be configured as: o6

Note: All the above must be in lowercase; uppercase will not be correctly recognized.

2. Configure Data Printing

debug:
  joint_pub_debug: false
  joint_motor_debug_r: true
  joint_motor_debug_l: false
  • joint_pub_debug: Set to true to print the content after Topic Pub, refresh rate is slow, can display left and right hands simultaneously
  • joint_motor_debug_r: Set to true to quickly refresh the output data of the right hand, range 255-0, representing the change from open to closed
  • joint_motor_debug_l: Set to true to quickly refresh the output data of the left hand, range 255-0, representing the change from open to closed

3. Configure Data Source

motion_type: linkerforce
  • motion_type: When using the LinkerFFG glove, set to linkerforce, motion_device does not need to be set

2.1.4 Program Launch (ROS2 Version)

Next, execute the following command to confirm the USB device list on your device. Then insert the 2 force-feedback gloves, execute the command again, and confirm the refreshed USB device numbers. Take /dev/ttyUSB0 and /dev/ttyUSB1 as examples:

ls /dev/ttyUSB*
sudo chmod 666 /dev/ttyUSB0
sudo chmod 666 /dev/ttyUSB1

Then execute

# There are two launch modes,
# One with calibration. Must be executed for the first time without calibration
ros2 run linkerhand_retarget handretarget --ros-args -p calibration := True
# One normal launch, calibration not executed by default
ros2 run linkerhand_retarget handretarget 

Notes: For customer convenience, a startup script is provided in the same directory as src, named startup_linkerforce.sh

#!/bin/bash
# LinkerForce Glove Teleoperation Startup Script

# Set serial port permissions
sudo chmod 666 /dev/ttyUSB0
sudo chmod 666 /dev/ttyUSB1

# source ROS workspace (please enter the correct directory)
source ~/project/linkerhand_telop_ws/ros2/v2.8.7/install/setup.bash

# Launch program (forced calibration)
ros2 run linkerhand_retarget handretarget --ros-args -p calibration:=True

# Launch without calibration
# ros2 run linkerhand_retarget handretarget 

After editing, launch it like this

./startup_linkerforce.sh
# If you encounter Tab not recognized, grant permissions
sudo chmod a+x ./startup_linkerforce.sh

2.1.5 Program Launch (ROS1 Version)

Next, execute the following command to confirm the USB device list on your device. Then insert the 2 force-feedback gloves, execute the command again, and confirm the refreshed USB device numbers. Take /dev/ttyUSB0 and /dev/ttyUSB1 as examples:

ls /dev/ttyUSB*
sudo chmod 666 /dev/ttyUSB0
sudo chmod 666 /dev/ttyUSB1

Then execute

# There are two launch modes,
# One with calibration. Must be executed for the first time without calibration
rosrun ros_linkerhand_retarget handretarget.py _calibrate:=true
# One normal launch, calibration not executed by default
rosrun ros_linkerhand_retarget handretarget.py

Notes: For customer convenience, a startup script is provided in the same directory as src, named startup_linkerforce.sh

#!/bin/bash
# LinkerForce Glove Teleoperation Startup Script

# Set serial port permissions
sudo chmod 666 /dev/ttyUSB0
sudo chmod 666 /dev/ttyUSB1

# source ROS workspace (please enter the correct directory)
source ~/linkerhand_telop/ros1/v2.8.6/install/setup.bash

# Launch program (forced calibration)
rosrun ros_linkerhand_retarget handretarget.py _calibrate:=true

# Launch without calibration
# rosrun ros_linkerhand_retarget handretarget.py

After editing, launch it like this

./startup_linkerforce.sh
# If you encounter Tab not recognized, grant permissions
sudo chmod a+x ./startup_linkerforce.sh

2.2 Topic Description

The working principle of the SDK is to clean and organize the data transmitted from the upper computer, then distribute the data uniformly via Topics. Therefore, Topics are the data transfer stations and an important basis for judging whether the teleoperation is working properly.

  • ROS1 command: rostopic list
  • ROS2 command: ros2 topic list

1. ROS2 command:

ros2 topic echo /cb_left_hand_control_cmd
# or
ros2 topic echo /cb_right_hand_control_cmd

Data Description

L25 Robotic Hand (21 DOF)

Joint Finger Action Default Value
joint1 Thumb Proximal Flexion 255
joint2 Index Proximal Flexion 255
joint3 Middle Proximal Flexion 255
joint4 Ring Proximal Flexion 255
joint5 Pinky Proximal Flexion 255
joint6 Thumb Abduction 255
joint7 Index Abduction 128
joint8 Middle Abduction 128
joint9 Ring Abduction 128
joint10 Pinky Abduction 128
joint11 Thumb Rotation 255
joint12 Reserved - -
joint13 Reserved - -
joint14 Reserved - -
joint15 Reserved - -
joint16 Thumb Distal Flexion 255
joint17 Index Distal Flexion 255
joint18 Middle Distal Flexion 255
joint19 Ring Distal Flexion 255
joint20 Pinky Distal Flexion 255
joint21 Thumb Tip Flexion 255
joint22 Index Tip Flexion 255
joint23 Middle Tip Flexion 255
joint24 Ring Tip Flexion 255
joint25 Pinky Tip Flexion 255

L20 Robotic Hand (16 DOF)

Joint Finger Action Default Value
joint1 Thumb Proximal Flexion 255
joint2 Index Proximal Flexion 255
joint3 Middle Proximal Flexion 255
joint4 Ring Proximal Flexion 255
joint5 Pinky Proximal Flexion 255
joint6 Thumb Abduction 255
joint7 Index Abduction 128
joint8 Middle Abduction 128
joint9 Ring Abduction 128
joint10 Pinky Abduction 128
joint11 Thumb Rotation 255
joint12 Reserved - -
joint13 Reserved - -
joint14 Reserved - -
joint15 Reserved - -
joint16 Thumb Tip Flexion 255
joint17 Index Tip Flexion 255
joint18 Middle Tip Flexion 255
joint19 Ring Tip Flexion 255
joint20 Pinky Tip Flexion 255

L10 Robotic Hand (10 DOF)

Joint Finger Action Default Value
joint1 Thumb Proximal Flexion 255
joint2 Thumb Abduction 128
joint3 Index Proximal Flexion 255
joint4 Middle Proximal Flexion 255
joint5 Ring Proximal Flexion 255
joint6 Pinky Proximal Flexion 255
joint7 Index Abduction 128
joint8 Ring Abduction 128
joint9 Pinky Abduction 128
joint10 Thumb Rotation 255

O7 Robotic Hand (7 DOF)

Joint Finger Action Default Value
joint1 Thumb Proximal Flexion 255
joint2 Thumb Abduction 128
joint3 Index Proximal Flexion 255
joint4 Middle Proximal Flexion 255
joint5 Ring Proximal Flexion 255
joint6 Pinky Proximal Flexion 255
joint7 Thumb Rotation 255

O6/L6 Robotic Hand (7 DOF)

Joint Finger Action Default Value
joint1 Thumb Proximal Flexion 255
joint2 Thumb Abduction 128
joint3 Index Proximal Flexion 255
joint4 Middle Proximal Flexion 255
joint5 Ring Proximal Flexion 255
joint6 Pinky Proximal Flexion 255

2.3 Troubleshooting Self-Check

2.3.1 Network Issues

The teleoperation and control devices are connected via the network. Network abnormalities can cause devices to malfunction. First, check if the network cable connections are correct, ensure that both IPs can ping each other, and confirm that the corresponding ports are open on the firewall.

2.3.2 Topic Anomalies

Under normal network conditions, you can confirm whether topics exist on other network devices using commands. Refer to section 2.2 Topic Description for details.

2.4 Mapping Parameter Settings

2.4.1 Principle

The mapping system has 3 modes

Mapping Mode English Equivalent Chinese Equivalent Applicable Scenario
Three-State Mapping origin-opose-fist Open Hand-O Pose-Fist Aims to balance the maximum range of the robotic hand while satisfying pinch gestures. Suitable for most mapping requirements.
Dual-End Mapping origin-fist Open Hand-Fist Maximizes the full range of the robotic hand to the greatest extent.
Pinch Mapping origin-opose- Open Hand-O Pose Targets pinch gestures primarily, aiming to improve granularity for grasping actions.

2.4.2 Configuration Files

This mapping system configures parameter binding for the robotic hand. The mapping configuration directory is located at:

~/src/linkerhand_retarget/linkerhand_retarget/motion/linkerforce/config

Currently provided mapping parameter packages are as follows:

g20_config.py
l10_config.py
l20_config.py
l6_config.py
o6_config.py
o7_config.py

2.4.3 Configuration Introduction

The following uses l6_config.py as an example.

2.4.3.1 Finger Configuration Constant FINGER_CONFIGS

2.4.3.1.1 Common Constant Table

(Content omitted)

2.4.3.1.2 reverse_motion Attribute

Reverse signal: Default is False

2.4.3.1.3 dynamic_weight Attribute

Dynamic weight: Used for detailed expression within intervals. Default is None, not enabled in this version.

2.4.3.1.4 extended_mapping Attribute

Extended mapping configuration

'extended_mapping': {    # New extended mapping configuration
    'enabled': True,
    'scale_factor': 1.2,  # Scaling factor, default 1.0
    'extended_exp_factor': 80  # New: Extension index parameter
}
  • enabled: Enabled only for pinch mapping; False means disabled.
  • scale_factor: Scaling factor, used to quickly lock onto the O-Pose position.
  • extended_exp_factor: Extension parameter, used for continuation actions after the O-Pose. A smaller value makes it harder to reach the mechanical limits of the robotic hand, allowing for more detailed expression of grasping. A larger value makes it easier to quickly reach the drive joint limit positions.

2.4.3.2 Mapping Order MAPPING_ORDER

Taking L6 as an example, indicates the priority order of processed joints

MAPPING_ORDER = [
    'thumb_abduction', 'thumb_flexion', 
    'index', 'middle', 'ring', 'pinky'
]

2.4.3.3 State Configuration STATE_CONFIG (Not Enabled)

2.4.3.4 Robotic Hand OPOSE Calibration Position: ROBOT_OPOSE_LEFT

Taking the L6 configuration as an example, the following angles correspond to the OPOSE position of the left robotic hand. Note that the following order corresponds to the URDF sequence.

ROBOT_OPOSE_LEFT = [
    1.4, 0.54, 0.0, 0.38, 0.0, 0.38, 0.0, 0.38, 0.0, 0.38, 0.0
]

2.4.3.5 Robotic Hand OPOSE Calibration Position: ROBOT_OPOSE_RIGHT

Taking the L6 configuration as an example, the following angles correspond to the OPOSE position of the right robotic hand. Note that the following order corresponds to the URDF sequence.

ROBOT_OPOSE_RIGHT = [
    1.4, 0.54, 0.0, 0.38, 0.0, 0.38, 0.0, 0.38, 0.0, 0.38, 0.0
]

2.4.4 Robotic Hand Calibration

Sections 2.4.3.4 and 2.4.3.5 introduced the OPOSE calibration positions for the left and right robotic hands respectively. These are used to handle discrepancies between the current robotic hand position and the URDF. When using for the first time, modifications need to be made in the following code.

Path: ./src/linkerhand_retarget/linkerhand_retarget/motion/linkerforce/hand

Taking the L6 robotic hand as an example, after opening linkerforce_l6.py, around line 149:

if self.calibrationoriginal is not None 
and self.calibrationfistpose is not None 
and self.calibrationopose is not None:
    # for i in range(20):
    #     self.multi_state_mapper.debug_value[i] = joint_arc[i]
    # arc_value = self.multi_state_mapper.map_glove_to_robot(joint_arc)   # Comment out
    arc_value = ROBOT_OPOSE_RIGHT          # Enable calibration
    qpos[17] = self.g_jointpositions_arc[1] = arc_value[0]
    qpos[20] = self.g_jointpositions_arc[0] = arc_value[1]
    qpos[1] = self.g_jointpositions_arc[2] = arc_value[3]
    qpos[9] = self.g_jointpositions_arc[3] = arc_value[5]
    qpos[13] = self.g_jointpositions_arc[4] = arc_value[7]
    qpos[5] = self.g_jointpositions_arc[5] = arc_value[9]

Rewrite it as shown in the example above to enable calibration for the right robotic hand. After launching, the robotic hand will be fixed at the current angle according to the mapped angle.

The corresponding section for the left hand is around line 360:

if self.calibrationoriginal is not None and self.calibrationfistpose is not None and self.calibrationopose is not None:
    # for i in range(20):
    #     self.multi_state_mapper.debug_value[i] = joint_arc[i]
    # arc_value = self.multi_state_mapper.map_glove_to_robot(joint_arc) # Comment out
    # Enable calibration
    arc_value = ROBOT_OPOSE_LEFT
    qpos[17] = self.g_jointpositions_arc[1] = arc_value[0]
    qpos[20] = self.g_jointpositions_arc[0] = arc_value[1]
    qpos[1] = self.g_jointpositions_arc[2] = arc_value[3]
    qpos[9] = self.g_jointpositions_arc[3] = arc_value[5]
    qpos[13] = self.g_jointpositions_arc[4] = arc_value[7]
    qpos[5] = self.g_jointpositions_arc[5] = arc_value[9]

Rewrite it as shown in the example above to enable calibration for the right robotic hand. After launching, the robotic hand will be fixed at the current angle according to the mapped angle.

Once both left and right hands have reached the desired pinch position, you can restore the original state and use the teleoperation system normally.

S
Description
No description provided
Readme 118 MiB
Languages
Python 100%