franka_ros2

franka_bringup

安装

请参考 README.md


包概览

该包包含示例的启动文件以及基本的 franka.launch.py 启动文件,可用于在没有任何控制器的情况下启动机器人。

当你启动机器人时:

ros2 launch franka_bringup franka.launch.py arm_id:=fr3 robot_ip:=<fci-ip> use_rviz:=true

除了 joint_state_broadcaster 外,没有其他控制器在运行。但仍然可以与机器人建立连接,并在 RViz 中可视化当前机器人位姿。在此模式下,当用户按下停止按钮时可以引导机器人。然而,一旦启动使用 effort_command_interface 的控制器,机器人将使用 libfranka 的力矩接口。例如,可以通过运行以下命令启动 gravity_compensation_example_controller:

ros2 control load_controller --set-state active  gravity_compensation_example_controller

这相当于运行 Gravity Compensation 中提到的 gravity_compensation_example_controller 示例。

当控制器停止时:

ros2 control set_controller_state gravity_compensation_example_controller inactive

机器人将停止力矩控制,仅通过 FCI 发送其当前状态。

现在你可以选择再次启动相同的控制器:

ros2 control set_controller_state gravity_compensation_example_controller active

或者加载并启动不同的控制器:

ros2 control load_controller --set-state active joint_impedance_example_controller

启用命名空间的启动文件

为了演示如何在指定命名空间内启动机器人,我们提供了位于 franka_bringup/launch/example.launch.py 的示例启动文件。

默认情况下,example.launch.py 配置为从位于 franka_bringup/launch/ 目录的 YAML 文件 franka.ns-config.yaml 中读取机器人基本配置。你也可以通过命令行指定路径来使用不同的 YAML 文件。

franka.ns-config.yaml 文件指定关键参数,包括:

  • 机器人的 URDF 文件路径。

  • 机器人实例使用的命名空间。

  • 机器人实例的其他特定配置细节。

example.launch.py “包含” franka.ns-launch.py,该文件定义了机器人操作所需的核心节点。

franka.ns-launch.py 文件依赖于 ns-controllers.yaml 来配置 ros2_controller 框架。该配置确保控制器以与命名空间无关的方式加载,支持跨多个命名空间的一致行为。

ns-controllers.yaml 文件设计为可容纳零个或多个命名空间,前提是所有命名空间共享相同的节点配置参数。

每个配置和启动文件(franka.ns-config.yaml、example.launch.py、franka.ns-launch.py 和 ns-controllers.yaml)都包含详细的内联文档,指导用户理解其结构和使用方法。有关 ROS 2 中命名空间的更多信息,请参考 ROS 2 文档

要执行 ns-controllers.yaml 中定义的任意示例控制器,可以使用 example.launch.py 启动文件,并通过命令行参数指定所需的控制器名称。

首先 - 根据你的设置修改 franka.ns-config.yaml

然后,例如,要运行 move_to_start_example_controller,使用以下命令:

ros2 launch franka_bringup example.launch.py controller_name:=move_to_start_example_controller

非实时机器人参数设置

非实时机器人参数设置可以通过 ROS 2 服务完成。这些服务在机器人硬件初始化后被发布。

服务名称如下:

* /service_server/set_cartesian_stiffness
* /service_server/set_force_torque_collision_behavior
* /service_server/set_full_collision_behavior
* /service_server/set_joint_stiffness
* /service_server/set_load
* /service_server/set_parameters
* /service_server/set_parameters_atomically
* /service_server/set_stiffness_frame
* /service_server/set_tcp_frame

服务消息说明如下。

  • franka_msgs::srv::SetJointStiffness 指定内部控制器的关节刚度(阻尼由刚度自动导出)。

  • franka_msgs::srv::SetCartesianStiffness 指定内部控制器的笛卡尔刚度(阻尼由刚度自动导出)。

  • franka_msgs::srv::SetTCPFrame 指定从 <arm_id>_EE(末端执行器)到 <arm_id>_NE(名义末端执行器)坐标系的变换。从法兰到末端执行器坐标系的变换分为两个部分:<arm_id>_EE 到 <arm_id>_NE 坐标系,以及 <arm_id>_NE 到 <arm_id>_link8 坐标系。<arm_id>_NE 到 <arm_id>_link8 坐标系的变换只能通过管理员接口设置。

  • franka_msgs::srv::SetStiffnessFrame 指定从 <arm_id>_K 到 <arm_id>_EE 坐标系的变换。

  • franka_msgs::srv::SetForceTorqueCollisionBehavior 设置外部笛卡尔力旋量的阈值,以配置碰撞反应。

  • franka_msgs::srv::SetFullCollisionBehavior 设置笛卡尔空间和关节层面的外部力阈值,以配置碰撞反应。

  • franka_msgs::srv::SetLoad 设置外部负载以进行补偿(例如抓取物体的重量)。

启动 franka_bringup/franka.launch.py 文件以初始化机器人硬件:

ros2 launch franka_bringup franka.launch.py robot_ip:=<fci-ip>

下面是一个最小示例:

ros2 service call /service_server/set_joint_stif
fness franka_msgs/srv/SetJointStiffness "{joint_stiffness: [1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0]}"

重要

非实时参数设置仅可在机器人硬件处于idle模式时进行。如果控制器处于活动状态并占用命令接口,机器人将进入move模式。在move模式下无法进行非实时参数设置。

重要

<arm_id>_EE 坐标系表示可配置末端执行器坐标系的一部分,可以在运行时通过franka_ros进行调整。<arm_id>_K 坐标系表示内部笛卡尔阻抗的中心,也作为外部力旋量的参考坐标系。<arm_id>_EE 和 <arm_id>_K 都不包含在 URDF 中,因为它们可以在运行时更改。默认情况下,<arm_id> 设置为 “panda”。


../../../_images/frames1.svg

末端执行器坐标系概览。


非实时 ROS 2 操作

非实时 ROS 2 操作可以通过ActionServer执行。提供以下操作:

  • /action_server/error_recovery - 自动从机器人错误中恢复。

使用的消息如下:

  • franka_msgs::action::ErrorRecovery - 无参数。

示例用法::

ros2 action send_goal /action_server/error_recovery franka_msgs/action/ErrorRecovery {}


已知问题

  • 当在 MoveIt 中使用 fake_hardware 时,需要一些时间才能应用默认位置。

franka_example_controllers

该软件包包含了一些用于展示如何在 ROS 2 中编写控制器的示例控制器。目前,控制器只能访问测量到的关节位置和关节速度。基于这些信息,控制器可以发送力矩指令。目前尚不支持使用其他接口,例如关节位置接口。


示例控制器

该仓库附带了一些示例控制器,位于 franka_example_controllers 软件包中。

以下启动文件默认会启用夹爪。如果未安装夹爪,可以在启动文件中通过 load_gripper:=false 来禁用夹爪。


移动至起始位置

该控制器将机器人移动到其初始构型。

ros2 launch franka_bringup example.launch.py controller_name:=move_to_start_example_controller


重力补偿

这是最简单的控制器,也是编写自定义控制器的良好起点。它向所有关节发送零力矩指令,意味着机器人仅补偿自身的重力。

ros2 launch franka_bringup example.launch.py controller_name:=gravity_compensation_example_controller


夹爪示例

演示如何使用 Franka 动作接口(Action Interface) 控制 Franka Hand(即夹爪)。控制器会发送 目标(Goals),使夹爪以设定的抓取尺寸(包含公差 epsilon)反复执行闭合和张开操作。系统会根据物体的尺寸及设定的公差来判断抓取是否成功。

ros2 launch franka_bringup example.launch.py controller_name:=gripper_example_controller


关节阻抗示例

该示例以较高的顺应性周期性地驱动第 4 和第 5 个关节。在运行时,用户可以尝试手动移动这些关节。

ros2 launch franka_bringup example.launch.py controller_name:=joint_impedance_example_controller


带逆解(IK)的关节阻抗示例

该示例使用 MoveIt 服务中的 LMA-Orocos 求解器计算期望位姿对应的关节位置。期望位姿使末端执行器在 X 和 Z 方向上周期性移动。可以在franka_fr3_moveit_config软件包中的kinematics.yaml文件中更改运动学求解器。

ros2 launch franka_bringup joint_impedance_with_ik_example_controller.launch.py


模型示例控制器

这是一个只读控制器,会输出科氏力向量、重力向量、第 4 关节的位姿矩阵、第 4 关节的刚体雅可比矩阵,以及相对于基坐标系的末端执行器雅可比矩阵。

ros2 launch franka_bringup example.launch.py controller_name:=model_example_controller


关节位置示例

该示例周期性地向机器人发送位置指令。

ros2 launch franka_bringup example.launch.py controller_name:=joint_position_example_controller

关节速度示例

该示例周期性地向机器人的第 4 与第 5 个关节发送速度指令。

ros2 launch franka_bringup example.launch.py controller_name:=joint_velocity_example_controller

笛卡尔位姿示例

该示例使用笛卡尔位姿接口向机器人周期性发送位姿指令。

ros2 launch franka_bringup example.launch.py controller_name:=cartesian_pose_example_controller

笛卡尔姿态示例

该示例使用笛卡尔姿态接口,使机器人的末端执行器围绕 X 轴周期性地改变姿态。

ros2 launch franka_bringup example.launch.py controller_name:=cartesian_orientation_example_controller

笛卡尔位姿肘部示例

该示例在保持末端执行器位姿不变的情况下,周期性地发送肘部控制指令。

ros2 launch franka_bringup example.launch.py controller_name:=cartesian_elbow_example_controller


笛卡尔速度示例

该示例使用笛卡尔速度接口向机器人周期性发送速度指令。

ros2 launch franka_bringup example.launch.py controller_name:=cartesian_velocity_example_controller

笛卡尔肘部示例

该示例使用笛卡尔肘部接口,在保持末端执行器速度恒定的情况下周期性地发送肘部控制指令。

ros2 launch franka_bringup example.launch.py controller_name:=elbow_example_controller

编写自定义控制器

franka_ros 相比,目前仅提供了较少的控制器接口:

  • 关节位置

  • 关节速度

  • 测量力矩

  • Franka 机器人状态

  • Franka 机器人模型

重要

Franka 机器人状态由 franka_robot_state_broadcaster 软件包发布到主题/franka_robot_state_broadcaster/robot_state

重要

建议通过 franka_semantic_components 类来访问 Franka 机器人状态和 Franka 机器人模型。它们在state_interface中以双指针形式存储,并在franka_semantic_component类中被还原为原始对象。

使用franka_model的示例可在franka_example_controllers软件包中找到:model_example_controller

可以基于本软件包中的示例控制器编写自定义控制器。若需计算机器人的运动学与动力学量,可以结合关节状态与机器人 URDF 文件,使用例如 KDL 等库(该库也提供 ROS 2 版本)。

franka_hardware

重要

自 0.1.14 版本起发生重大变更:franka_hardware 的 robot_state 和 robot_model 将添加 arm_id 前缀。

  • panda/robot_model  -> ${arm_id}/robot_model

  • panda/robot_state  -> ${arm_id}/robot_state

状态接口和命令接口的命名方式未发生变化。它们仍以前缀形式对应 URDF 中的关节名称。

软件包概述

该软件包包含适用于 ros2_controlfranka_hardware 插件。该插件从机器人 URDF 中加载,并通过机器人描述传递给控制器管理器。

硬件接口

硬件插件为每个关节提供以下接口:

  • position state interface:包含测量得到的关节位置。

  • velocity state interface:包含测量得到的关节速度。

  • effort state interface:包含测量得到的连杆侧关节扭矩。

  • initial_position state interface:包含机器人的初始关节位置。

  • effort command interface:包含期望的关节扭矩(不含重力补偿)。

  • position command interface:包含期望的关节位置。

  • velocity command interface:包含期望的关节速度。

附加状态接口

除了关节接口外,硬件插件还提供:

  • franka_robot_state:包含机器人状态信息,详见 franka_robot_state

  • franka_robot_model_interface:包含模型对象的指针。

重要

franka_robot_statefranka_robot_model_interface 状态接口不应直接从硬件状态接口中调用,而应通过 franka_semantic_components 接口使用。

配置

机器人的 IP 地址将通过 URDF 中的参数读取。

与控制器的配合使用

控制器可通过标准的 ros2_control 框架访问这些接口。有关接口在实际中的使用示例,请参阅 franka_example_controllers 软件包。

franka_semantic_components

该软件包包含 franka_robot_model、franka_robot_state 和笛卡尔命令类。这些类用于转换存储在 hardware_state_interface 中的 franka_robot_model 对象和 franka_robot_state 对象(以双指针形式存储)。

有关如何使用这些类的更多参考,请参见:Franka Robot State BroadcasterFranka 示例控制器 (model_example_controller)

笛卡尔位姿接口

笛卡尔位姿接口

该接口用于通过借用的命令接口向机器人发送笛卡尔位姿命令。FrankaSemanticComponentInterface 类负责处理借用的命令接口和状态接口。在启动笛卡尔位姿接口时,用户需要向构造函数传递一个布尔标志,以指示该接口是否用于肘部。

auto is_elbow_active = false;CartesianPoseInterface 
cartesian_pose_interface(is_elbow_active);

该接口允许用户读取由 franka 硬件接口设置的当前位姿命令接口值。

std::array pose;
pose = cartesian_pose_interface.getInitialPoseMatrix();

用户还可以以 Eigen 格式读取四元数和位移值。

Eigen::Quaterniond quaternion;
Eigen::Vector3d translation;
std::tie(quaternion, translation) = cartesian_pose_interface.getInitialOrientationAndTranslation();

在设置好笛卡尔接口后,需要在控制器中调用 assign_loaned_command_interfacesassign_loaned_state_interfaces。这些操作应在控制器的 on_activate() 函数中完成。示例可参见 分配借出的命令接口示例

cartesian_pose_interface.assign_loaned_command_interfaces(command_interfaces_);
cartesian_pose_interface.assign_loaned_state_interfaces(state_interfaces_);

在控制器的 update 函数中,可以向机器人发送位姿命令。

std::array pose;
pose = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.5, 0, 0.5, 1};
cartesian_pose_interface.setCommanded(pose);

或者,可以以 Eigen 格式发送四元数和位移值。

Eigen::Quaterniond quaternion(1, 0, 0, 0);
Eigen::Vector3d translation(0.5, 0, 0.5);
cartesian_pose_interface.setCommand(quaternion, translation);

笛卡尔速度接口

该接口用于通过借用的命令接口向机器人发送笛卡尔速度命令。FrankaSemanticComponentInterface 类负责管理这些借用的命令和状态接口。

auto is_elbow_active = false;
CartesianVelocityInterface cartesian_velocity_interface(is_elbow_active);

要向机器人发送速度命令,需要在自定义控制器中调用 assign_loaned_command_interface。

cartesian_velocity_interface.assign_loaned_command_interface(command_interfaces_);

在控制器的 update 函数中,可以向机器人发送笛卡尔速度命令。

std::array cartesian_velocity;
cartesian_velocity = {0, 0, 0, 0, 0, 0.1};
cartesian_velocity_interface.setCommand(cartesian_velocity);

机器人状态与模型访问

语义组件提供对存储在硬件接口中的机器人状态和模型对象的安全访问。这种方式在控制器中使用这些复杂对象时,能够确保正确的类型转换和内存管理。

franka_gripper

该软件包包含用于与 Franka Hand 通信的 franka_gripper_node 节点。

动作与服务

franka_gripper_node 提供以下动作:

  • homing - 复位夹爪,并根据安装的手指更新最大张开宽度。

  • move - 以设定速度移动至目标宽度。

  • grasp - 以给定的速度闭合夹爪,并在目标宽度和目标力下尝试抓取。当夹爪两指间的距离 d 满足 width - epsilon.inner < d < width + epsilon.outer 时,抓取被认为成功。

  • gripper_action - 为 MoveIt 提供的专用抓取动作。

此外,还提供 stop 服务,用于中止夹爪动作并停止抓取。

使用方法

使用以下启动文件启动夹爪::

ros2 launch franka_gripper gripper.launch.py robot_ip:=

在另一个终端标签页中,可以执行复位操作并发送抓取命令::

ros2 action send_goal /fr3_gripper/homing franka_msgs/action/Homing {}
ros2 action send_goal -f /fr3_gripper/grasp franka_msgs/action/Grasp "{width: 0.00, speed: 0.03, force: 50}"

默认情况下,内外侧的 epsilon 均为 0.005 米。您也可以显式设置 epsilon 值::

ros2 action send_goal -f /fr3_gripper/grasp franka_msgs/action/Grasp "{width: 0.00, speed: 0.03, force: 50, epsilon: {inner: 0.01, outer: 0.01}}"

要停止抓取,可使用 stop 服务::

ros2 service call /fr3_gripper/stop std_srvs/srv/Trigger {}

与 franka_ros 的差异

  • 此前所有的主题与动作均以 franka_gripper 为前缀。该前缀已更名为 panda_gripper,以便未来可以基于 arm_id 来统一命名,从而轻松支持多机械臂配置。

  • 由于 stop 动作不可被抢占,因此现在将其实现为服务类型的动作。

  • gripper_action 外,所有动作均会返回当前夹爪宽度作为反馈。

franka_robot_state_broadcaster

该软件包包含只读的 franka_robot_state_broadcaster 控制器。

功能说明

该广播器将 franka_robot_state 发布到主题 /franka_robot_state_broadcaster/robot_state。该控制器节点由 franka_bringup 中的 franka_launch.py 启动。因此,所有包含 franka_launch.py 的示例都会发布 robot_state 主题。

使用方法

当您使用以下命令启动机器人时,机器人状态广播器将自动启动:

ros2 launch franka_bringup franka.launch.py robot_ip:=

已发布的主题

  • /franka_robot_state_broadcaster/robot_state (消息类型:franka_msgs/FrankaRobotState):包含完整的机器人状态信息,包括关节状态、笛卡尔位姿以及其他与机器人相关的数据。

集成说明

该广播器与 franka_semantic_components 软件包集成,为控制器和其他节点提供安全的机器人状态信息访问接口。

franka_fr3_moveit_config

该软件包包含 MoveIt2 的配置文件。

运动组(Move Groups)

新增了一个名为 panda_manipulator 的运动组,其末端位于夹爪两指之间,并将 Z 轴旋转 -45 度,使得 X 轴朝向前方,从而更方便使用。原有的 panda_arm 运动组仍可用以保持向后兼容,但新应用推荐使用新的 panda_manipulator 运动组。

../../../_images/move-groups.png

旧版与新版运动组的可视化对比

使用方法

要验证一切是否正常,可在机器人上运行 MoveIt 示例:

ros2 launch franka_fr3_moveit_config moveit.launch.py robot_ip:=<fci-ip>

然后在 RViz 中启用 MotionPlanning 显示。

如果没有实体机器人,也可以在虚拟硬件上测试配置:

ros2 launch franka_fr3_moveit_config moveit.launch.py robot_ip:=dont-care use_fake_hardware:=true

等待终端中出现 MoveIt 的绿色提示信息 You can start planning now!。然后关闭 PlanningScene,再重新打开,最后启用 MotionPlanning

配置文件

该软件包包括以下内容:

  • FR3 机器人的运动规划配置

  • 关节限制与安全设置

  • 规划组与连杆配置

  • 运动学求解器配置(kinematics.yaml)

对于“关节阻抗 + 逆运动学示例 (Joint Impedance With IK Example)”控制器,可以在本软件包的 kinematics.yaml 文件中修改所使用的运动学求解器。

franka_gazebo

重要

franka_description 的最低版本要求为 0.3.0。你可以从 https://github.com/frankarobotics/franka_description 克隆该包。

一个将 Franka ROS 2 与 Gazebo 仿真器集成的项目。

启动 RViz + Gazebo

启动一个示例,同时打开 RViz 和 Gazebo 并显示机器人:

ros2 launch franka_gazebo_bringup visualize_franka_robot.launch.py

如果想显示另一台机器人,可以定义 arm_id:

ros2 launch franka_gazebo_bringup visualize_franka_robot.launch.py arm_id:=fp3

如果想启动包含 franka_hand 的仿真:

ros2 launch franka_gazebo_bringup visualize_franka_robot.launch.py load_gripper:=true franka_hand:='franka_hand'

Gazebo 中的关节速度控制示例

在开始之前,请确保已构建 franka_example_controllersfranka_description 包。franka_description 的最低版本要求为 0.3.0。

colcon build --packages-select franka_example_controllers

现在可以使用 Gazebo 仿真器启动速度控制示例。

ros2 launch franka_gazebo_bringup gazebo_joint_velocity_controller_example.launch.py load_gripper:=true franka_hand:='franka_hand'

请注意,夹爪关节在使用关节速度控制器时存在 bug。如果你需要控制夹爪,请改用关节位置接口。

Gazebo 中的关节位置控制示例

要运行关节位置控制示例,需要先安装关节速度控制章节中列出的必要软件。

然后可以使用以下命令运行。

ros2 launch franka_gazebo_bringup gazebo_joint_position_controller_example.launch.py load_gripper:=true franka_hand:='franka_hand'

Gazebo 中的关节阻抗控制示例

要运行力矩控制示例,需要编译位于 franka_gazebo 下的 franka_ign_ros2_control 包。可以使用以下命令进行编译。

colcon build --packages-select franka_ign_ros2_control

然后加载你的工作空间环境。

source install/setup.sh

接着可以运行阻抗控制示例。

ros2 launch franka_gazebo_bringup gazebo_joint_impedance_controller_example.launch.py load_gripper:=true franka_hand:='franka_hand'

故障排查

如果遇到 Gazebo 无法找到模型文件的情况,请尝试将工作空间路径加入环境变量。例如:

export GZ_SIM_RESOURCE_PATH=${GZ_SIM_RESOURCE_PATH}:/workspaces/src/

franka_msgs

此包包含不同夹爪动作和机器人状态消息的定义。

消息类型

此包为 Franka 机器人提供专用的 ROS 2 消息、服务和动作定义:

动作(Action)定义:
  • 夹爪控制动作(回零、移动、抓取)

  • 错误恢复动作

服务(Service)定义:
  • 机器人参数设置服务

  • 碰撞行为配置

  • 刚度与负载配置

消息(Message)定义:
  • 机器人状态消息

  • 夹爪状态与反馈消息

使用方法

这些消息定义在整个 franka_ros2 生态系统中被广泛使用:

这些消息定义确保所有 Franka ROS 2 软件包之间的通信接口保持一致。