Files
2026-06-30 10:42:11 +08:00

419 lines
16 KiB
Markdown

# 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
```bash
colcon build --symlink-install
```
There may be permission issues during the process preventing execution; use the following command
```bash
chmod 777 -R *
```
### 2.1.3 Program Configuration
Enter the ls command in this directory
```bash
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**
```yaml
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**
```yaml
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**
```yaml
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:
```bash
ls /dev/ttyUSB*
sudo chmod 666 /dev/ttyUSB0
sudo chmod 666 /dev/ttyUSB1
```
Then execute
```bash
# 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`
```bash
#!/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
```bash
./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:
```bash
ls /dev/ttyUSB*
sudo chmod 666 /dev/ttyUSB0
sudo chmod 666 /dev/ttyUSB1
```
Then execute
```bash
# 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`
```bash
#!/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
```bash
./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:**
```bash
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
```python
'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
```python
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.
```python
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.
```python
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:
```python
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:
```python
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.