GELLO Franka FR3 ROS2 环境搭建与开发指南

参考:https://github.com/wuphilipp/gello_software/blob/main/ros2/README.md

适用:Franka FR3 机械臂 + GELLO 遥操作手臂

robot_known_configuration.jpg 

1. 项目概述

本项目提供 GELLO 遥操作手臂 与 Franka FR3 机械臂 之间的完整 ROS2 接口。

核心功能

功能模块

说明

GELLO 状态发布

读取 Dynamixel 舵机角度,发布为 ROS2 话题

关节阻抗控制

订阅 GELLO 状态,转换为 FR3 力矩指令

夹爪管理

支持 Franka Hand 和 Robotiq 2F-85 两种夹爪

硬件组成

GELLO 单臂版:

  ├─ 7 个 Dynamixel XL330-M288 舵机(7 DOF)

  ├─ U2D2 或 OpenRB-150 通信板

  └─ Franka Hand 或 Robotiq 2F-85 夹爪

GELLO 双臂版(Duo):

  ├─ 2 × 7 = 14 个 Dynamixel 舵机

  ├─ 2 个通信板

  └─ 双臂协同控制

硬件连线:单臂版本

硬件连线-1.png

2. 环境搭建

方式一:VS Code Dev Container(⭐ 推荐)

最适合:快速上手,环境一致,避免依赖地狱。

步骤

1. 打开项目
VS Code 打开 gello_software 仓库中的 ros2/ 子文件夹
   (注意:不是整个 gello_software 文件夹)

2. 启动容器
   - 如果弹出提示:「Reopen in Container」 → 点击确认
   - 如果没有提示:按 Ctrl+Shift+P → 输入 Dev Containers: Reopen in Container

contant-1.png

3. 等待构建
   - 第一次构建需要几分钟(自动安装所有依赖)

contant-2.png   - 构建完成后,终端自动进入容器环境

⚠️ 注意事项

● 版本匹配:Dev Container 中的libfranka、franka_ros2、franka_description版本需要与你的 Franka 机器人系统版本匹配。

● 修改版本:如果需要调整版本,编辑ros2/.devcontainer/Dockerfile中的版本参数。

● 兼容性文档:参考Franka 官方兼容性表

方式二:本地安装

最适合:需要深度定制,或无法使用 Docker 的环境。

前置依赖

依赖项

安装指南

ROS2 Humble Desktop

官方安装教程

libfranka

Franka 官方文档

franka_ros2

同上(注意版本匹配)

ros2_robotiq_gripper

GitHub 仓库

Cyclone DDS

ROS2 RMW 文档

安装示例(参考 Dockerfile)

# 这些命令可以从 ros2/.devcontainer/Dockerfile 中复制

# 根据你的系统环境调整路径和版本

# 示例:安装 libfranka

cd ~

git clone --branch 0.15.0 https://github.com/frankarobotics/libfranka.git

cd libfranka

mkdir build && cd build

cmake .. -DCMAKE_BUILD_TYPE=Release

make -j$(nproc)

sudo make install

# 安装 franka_ros2

mkdir -p ~/franka_ws/src

cd ~/franka_ws/src

git clone --branch humble https://ghfast.top/https://github.com/frankarobotics/franka_ros2.git

cd ..

rosdep install --from-paths src --ignore-src -r -y

colcon build --symlink-install

安装工作区依赖

# 进入 ros2 工作区

cd ~/projects/ros2Gello/gello_software/ros2

# 运行依赖安装脚本

bash install_workspace_dependencies.bash

▎ 提示:如果添加了新依赖,记得更新 requirements.txt、requirements_dev.txt 或 package.xml,然后重新运行脚本。

3. 快速开始

场景 A:预组装 Franka GELLO 单臂版(带 Franka Hand)

配置步骤

1. 修改配置文件
   - franka_gello_single.yaml → 设置 com_port
   - example_fr3_config_franka_hand.yaml → 设置 com_port
   - example_fr3_config.yaml → 设置 robot_ip

2. 启动命令

# 【重要】如果使用 Dev Container,/workspace/ 就是 ros2/ 文件夹

# 本地安装请把 /workspace/ 替换成你的 gello_software 路径

# Step 1: 进入工作区,构建,加载环境

cd ~/projects/ros2Gello/gello_software/

colcon build

source install/setup.bash

# Step 2: 启动 GELLO 节点(读取手柄状态)

ros2 launch franka_gello_state_publisher main.launch.py config_file:=franka_gello_single.yaml

# Step 3: 启动 Franka Hand 夹爪节点

ros2 launch franka_gripper_manager franka_gripper_client.launch.py config_file:=example_fr3_config_franka_hand.yaml

# Step 4: 启动机器人控制器

# 【注意】先握住 GELLO 手柄,放在舒适位置(距离底座一定距离)

# 启动后机器人会直接同步到 GELLO 的当前位置

# 同步过程中不要突然移动 GELLO,避免机器人剧烈动作

ros2 launch franka_fr3_arm_controllers franka_fr3_arm_controllers.launch.py robot_config_file:=example_fr3_config.yaml

场景 B:预组装 Franka GELLO Duo 双臂版(带 Robotiq 夹爪)

配置步骤

1. 修改配置文件
   - franka_gello_duo.yaml → 设置 com_port(两个手柄需要两个端口)
   - example_fr3_duo_config_robotiq.yaml → 设置 com_port
   - example_fr3_duo_config.yaml → 设置 robot_ip

2. 启动命令

cd ~/projects/ros2Gello/gello_software/ros2/

colcon build

source install/setup.bash

# 启动两个 GELLO 手柄

ros2 launch franka_gello_state_publisher main.launch.py config_file:=franka_gello_duo.yaml

# 启动 Robotiq 夹爪

ros2 launch franka_gripper_manager robotiq_gripper_controller_client.launch.py config_file:=example_fr3_duo_config_robotiq.yaml

# 启动机器人控制器(双臂)

# 【注意】双手握住 GELLO 手柄,放在舒适位置

ros2 launch franka_fr3_arm_controllers franka_fr3_arm_controllers.launch.py robot_config_file:=example_fr3_duo_config.yaml

4. 详细启动流程

4.1 启动 GELLO 发布器

Step 1:确定通信端口 ID

# 插入 U2D2 或 OpenRB-150 后运行

ls /dev/serial/by-id

输出示例:

# U2D2:

usb-FTDI_USB__-__Serial_Converter_FT7WBG6

# OpenRB-150:

usb-ROBOTIS_OpenRB-150_2B375CB3503059384C2E3120FF053624-if00

记录这个 ID,后面要填到配置文件中。

Step 2:校准装配偏移(仅自制 GELLO 需要)

▎ ⚡ 跳过此步骤的条件:
- 使用官方预组装的 "Franka GELLO" 或 "Franka GELLO Duo"
- 严格按照官方组装指南装配

▎ 满足以上条件,可以直接用 franka_gello_state_publisher/config/ 里的默认配置文件。

如果是自己组装的 GELLO,需要确定以下参数:

参数

说明

默认值(官方组装)

joint_signs

每个关节的方向符号(1 或 -1)

1 -1 1 -1 1 1 1

assembly_offsets

装配偏移(由于 Dynamixel 法兰有 4 种安装方向,可能需要 ±90° 偏移)

0 0 0 0 0 0 0

gripper_range_rad

夹爪开合对应的关节角度范围

根据组装确定

使用校准脚本:

# 进入脚本目录

cd ~/projects/ros2Gello/gello_software/ros2/src/franka_gello_state_publisher/scripts/

# 单臂 GELLO 校准

python3 get_offsets.py \
    --start-joints 0 0 0 -1.57 0 1.57 0 \
    --joint-signs 1 -1 1 -1 1 1 1 \
    --port /dev/serial/by-id/<你的端口ID>

# 双臂左臂校准

python3 get_offsets.py \
    --start-joints -1.57 -0.80 1.80 -3.00 1.40 1.50 -2.10 \
    --joint-signs 1 -1 1 -1 1 1 1 \
    --port /dev/serial/by-id/<你的端口ID>

# 双臂右臂校准

python3 get_offsets.py \
    --start-joints 1.57 -0.80 -1.80 -3.00 -1.40 1.50 2.10 \
    --joint-signs 1 -1 1 -1 1 1 1 \
    --port /dev/serial/by-id/<你的端口ID>

校准姿势参考:

单臂:参见

robot_known_configuration.jpg

双臂:参见 

franka_gello_duo_v05_annotated.jpg

脚本输出:会显示 assembly_offsets 和 gripper_range_rad 的建议值。

应用校准结果:
1. 打开你的配置文件(在 franka_gello_state_publisher/config/ 目录)
2. 更新 assembly_offsets 和 gripper_range_rad 字段
3. 重新构建工作区:

cd ~/projects/ros2Gello/gello_software/ros2

colcon build

Step 3:启动 GELLO 发布器节点

创建或编辑配置文件:
- 位置:src/franka_gello_state_publisher/config/your_config.yaml
- 或者直接使用提供的示例文件

配置参数说明:

参数

说明

示例

com_port

通信端口 ID

/dev/serial/by-id/usb-FTDI_USB...

namespace

ROS2 命名空间(需与机器人和夹爪一致)

franka

num_joints

关节数量(Franka FR3 = 7)

7

joint_signs

关节方向符号

[1, -1, 1, -1, 1, 1, 1]

gripper

是否使用 GELLO 夹爪状态

true

assembly_offsets

装配偏移

[0, 0, 0, 0, 0, 0, 0]

gripper_range_rad

夹爪角度范围

[0.0, 1.0]

dynamixel_torque_enable

是否使能力矩

[1, 1, 0, 1, 0, 0, 0]

dynamixel_goal_position

目标位置(脉冲,4095 = 360°)

[2048, ...]

dynamixel_kp_p

比例增益(虚拟弹簧刚度)

[280, ...]

dynamixel_kp_i

积分增益(建议为 0)

[0, ...]

dynamixel_kd_d

微分增益(虚拟阻尼)

[50, ...]

启动命令:

ros2 launch franka_gello_state_publisher main.launch.py config_file:=your_config.yaml

▎ 注意:config_file 参数是可选的。如果不提供,默认使用 example_single.yaml。

虚拟弹簧与阻尼配置(关键)

GELLO 的核心优势之一是手感优化,通过 Dynamixel 内置的 PID 控制器实现"虚拟弹簧"和"虚拟阻尼"效果。

原理

每个 Dynamixel 舵机可以配置为"基于电流的位置控制"模式:

  - 虚拟弹簧:目标位置 ≠ 当前位置 → 产生恢复力矩

  - 虚拟阻尼:移动速度快 → 产生阻力矩

效果:

  - 关节不会"软塌塌"(弹簧支撑)

  - 不会"甩太快"(阻尼缓冲)

  - 手感接近真实机械臂的惯性

配置参数详解

参数

说明

推荐值

dynamixel_torque_enable

是否使能力矩(1=开启,0=关闭)

需要虚拟弹簧的关节设为 1

dynamixel_goal_position

目标位置(脉冲值,4095 = 360°)

校准姿势对应的脉冲值

dynamixel_kp_p

比例增益(弹簧刚度)

0 ~ 1000,推荐 280

dynamixel_kp_i

积分增益

推荐 0(所有关节)

dynamixel_kd_d

微分增益(阻尼系数)

0 ~ 1000,下盘关节用更强阻尼

推荐起始值(参考官方配置)

dynamixel_torque_enable: [1, 1, 0, 1, 0, 0, 0]

dynamixel_goal_position: [2048, 2048, 2048, 2048, 2048, 2048, 2048]

dynamixel_kp_p: [280, 280, 0, 150, 0, 0, 0]  # 关节1、2、4加弹簧

dynamixel_kd_d: [50, 100, 150, 200, 100, 50, 0]  # 下盘阻尼更强

物理意义

● kp_p = 280→ 弹簧常数约 0.25 Nm/rad(与 GELLO 机械结构中的物理扭簧相当)

● 最大偏转角:约 48° 时达到电流限制(600mA)

● 舵机规格:XL330-M288 堵转扭矩 0.52 Nm(5V,1.47A),但持续大电流会过热。推荐使用 600mA 电流限制。

在线调整

启动后可以用 rqt 工具实时调整:

# 安装 rqt_reconfigure(如果还没装)

sudo apt install ros-humble-rqt-reconfigure

# 启动 rqt

rqt

# 然后:Plugins → Configuration → Dynamic Reconfigure

# 选择 franka_gello_state_publisher 节点,调整参数

⚠️ 重要警告(OpenRB-150 用户)

如果使用 OpenRB-150 通信板:

【危险操作】:

  - 不要在没有外接 5V 电源的情况下使能力矩!

  - 仅靠 USB 供电驱动力矩模式会烧坏你的电脑 USB 端口!

外接电源1.png

【正确操作】:

  1. 给 OpenRB-150 的电源端子接上 5V 外接电源

  2. 把跳线帽设为 "VIN(DXL)"

  3. 确认电源指示灯亮起后,再使能力矩

参考:OpenRB-150 手册

https://emanual.robotis.com/docs/en/parts/controller/openrb-150/#when-running-5v-dynamixel-with-the-usb-power

4.2 启动关节阻抗控制器

功能说明

● 订阅话题:/gello/joint_states(来自 GELLO 发布器)

● 发布指令:发送给 Franka FR3 的力矩控制接口

● 控制算法:关节阻抗控制(Joint Impedance Control)

配置文件

● 位置:src/franka_fr3_arm_controllers/config/your_config.yaml

● 或直接使用示例:example_fr3_config.yaml

启动命令

ros2 launch franka_fr3_arm_controllers franka_fr3_arm_controllers.launch.py robot_config_file:=your_config.yaml

▎ 注意:robot_config_file 参数是可选的。如果不提供,默认使用 example_fr3_config.yaml。

配置参数(详见 franka.launch.py 第 16 行起)

参数

说明

robot_ip

Franka 机器人的 IP 地址

namespace

ROS2 命名空间

阻抗控制参数

刚度、阻尼、前馈力矩等

4.3 启动夹爪管理器

支持两种夹爪

夹爪类型

启动命令

Franka Hand(Franka 原装)

franka_gripper_client.launch.py

Robotiq 2F-85(第三方)

robotiq_gripper_controller_client.launch.py

Franka Hand 启动示例

ros2 launch franka_gripper_manager franka_gripper_client.launch.py config_file:=example_fr3_config_franka_hand.yaml

配置参数:
- namespace:ROS2 命名空间(需与 GELLO 和机器人一致)
- 其他参数详见配置文件

Robotiq 2F-85 启动示例

ros2 launch franka_gripper_manager robotiq_gripper_controller_client.launch.py config_file:=example_fr3_config_robotiq.yaml

 配置参数:
- namespace:ROS2 命名空间
- com_port:Robotiq 夹爪的串口 ID(通过 ls /dev/serial/by-id 确定)

5. 软件包说明

5.1 franka_fr3_arm_controllers

功能:为 Franka FR3 提供关节阻抗控制器。

核心特性:
- 实现 JointImpedanceController,直接发送力矩指令
- 订阅 /gello/joint_states 话题获取 GELLO 状态

启动文件:
- franka.launch.py:启动 Franka 机器人的 ROS 接口
- franka_fr3_arm_controllers.launch.py:启动关节阻抗控制器

5.2 franka_gello_state_publisher

功能:读取 GELLO 手柄的 Dynamixel 舵机角度,发布为 sensor_msgs/msg/JointState 消息。

核心特性:
- 发布话题:/gello/joint_states
- 可选:配置 Dynamixel 内部控制参数(虚拟弹簧/阻尼)

启动文件:
- main.launch.py:启动 GELLO 发布器节点

5.3 franka_gripper_manager

功能:管理连接到 Franka 机器人的夹爪。

核心特性:
- 订阅话题:/gripper/gripper_client/target_gripper_width_percent
- 支持夹爪开合控制和回零(homing)操作

启动文件:
- franka_gripper_client.launch.py:启动 Franka Hand 夹爪管理节点
- robotiq_gripper_controller_client.launch.py:启动 Robotiq 2F-85 夹爪管理节点

6. 构建与测试

6.1 构建项目

# 【重要】所有命令必须在 ros2/ 目录下执行

cd ~/projects/ros2Gello/gello_software/ros2

# 构建(带 clang-tidy 检查)

colcon build --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCHECK_TIDY=ON

6.2 运行测试

# 运行所有测试用例

colcon test

# 查看测试结果

colcon test-result --all

7. 故障排查

错误 1:串口无法打开

错误信息:

SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg))

可能原因:
1. 端口路径错误:必须使用完整路径(如 /dev/serial/by-id/usb-FTDI_***)
2. 容器启动后插入设备:重新打开 VS Code Dev Container
3. 权限不足:检查用户是否在 dialout 组

解决方法:

# 检查端口是否存在

ls -la /dev/serial/by-id/

# 如果是容器问题,重新打开容器

# VS Code → 左下角 → 重新打开容器

# 如果是权限问题

sudo usermod -a -G dialout $USER

# 注销后重新登录

错误 2:libfranka 版本不兼容

错误信息:

libfranka: Incompatible library version (server version: X, library version: Y)

原因:libfranka 版本与 Franka 机器人系统版本不匹配。

解决方法:
1. 查看 Franka 兼容性表
2. 修改 ros2/.devcontainer/Dockerfile 中的版本参数:
LIBFRANKA_VERSION=0.15.0
   FRANKA_ROS2_VERSION=0.15.0
   FRANKA_DESCRIPTION_VERSION=0.15.0
3. 重新构建 Dev Container

错误 3:机器人运动卡顿

现象:从臂运动不流畅,或者频繁报"力阈值超限"错误。

原因:USB 延迟过高(默认 16ms)。

解决方法(临时):

# 1. 确定你的 U2D2/OpenRB-150 对应的 tty 设备

ls -la /dev/serial/by-id/

# 假设输出显示它映射到 ttyUSB0

# 2. 降低 USB 延迟(16ms → 1ms)

echo 1 | sudo tee /sys/bus/usb-serial/devices/ttyUSB0/latency_timer

解决方法(永久):

# 创建 udev 规则文件

sudo nano /etc/udev/rules.d/99-gello.rules

 # 写入以下内容(针对 U2D2 和 OpenRB-150)

# 降低延迟定时器(1ms 代替默认的 16ms)并修复权限

ACTION=="add", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="0666", RUN+="/bin/sh -c 'echo 1 > /sys/bus/usb-serial/devices/$kernel/latency_timer'"

ACTION=="add", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", MODE="0666", RUN+="/bin/sh -c 'echo 1 > /sys/bus/usb-serial/devices/$kernel/latency_timer'"

 # 重新加载 udev 规则

sudo udevadm control --reload-rules

sudo udevadm trigger

 附录:话题与接口

GELLO 发布的话题

话题名称

消息类型

说明

/gello/joint_states

sensor_msgs/msg/JointState

GELLO 手柄的关节角度

控制器订阅的话题

话题名称

消息类型

说明

/gello/joint_states

sensor_msgs/msg/JointState

GELLO 状态输入

夹爪控制话题

话题名称

消息类型

说明

/gripper/gripper_client/target_gripper_width_percent

std_msgs/msg/Float32

夹爪开合指令(0~100%)


附录:参考资源

资源

链接

GELLO 论文

arXiv:2310.13018

Franka 官方文档

https://frankarobotics.github.io/docs/index.html

ROS2 Humble 文档

https://docs.ros.org/en/humble/

Dynamixel XL330 规格

https://emanual.robotis.com/docs/en/dxl/x/xl330-m288/

VS Code Dev Containers

https://code.visualstudio.com/docs/devcontainers/containers