FCI手册(中文版)目录

备注

该软件及其文档支持两种不同的机器人,即 Franka Research 3 (FR3) 和较旧的 Franka Robotics Robot(FER 或 Panda)。

备注

此页面为 官方英文版 的中文翻译非官方版本。

该中文版本由 Embodied Force 维护,如有歧义或更新延迟,请以英文原版为准。本文件依据 Apache 2.0 许可证授权使用,转载请注明内容来自 Franka Robotics,中文翻译由 Embodied Force 提供。

如有机器人相关咨询,请联系:

联系人:WANG CHAO

座机: +86 185 8843 3689

电话:+86 185 8843 3689


Franka 控制接口(FCI)可以通过我们在 GitHub 上提供的几个开源组件访问。我们欢迎开源贡献和改进建议。

这些组件是:

本文档的源代码也可 在线获取

重要

在开始使用 FCI 之前,请仔细阅读机器人附带的文件和 最低系统和网络要求 章节。

备注

使用系统版本为 4.2.0 或更高版本的机器人需要主动启用 FCI 模式。如需启用,请打开 Desk -> 扩展侧边栏的菜单 -> 点击‘Activate FCI’。关于单点控制 Single Point of Control (SPoC) 的更多信息,可在机器人随附的手册中找到。

综述

_images/fci-architecture.png

架构示意图概述

Franka控制接口(FCI)允许与手臂和抓手进行快速直接的底层双向连接。它能提供机器人的当前状态,并通过以太网连接的外部工作站 PC 实现其直接控制。通过使用我们的开源 C++ 接口 libfranka,可以使用 5 种不同的接口以 1kHz 的频率发送实时控制值:

  • 带重力和摩擦力补偿的关节扭矩命令

  • 关节角度或速度命令

  • 笛卡尔位姿或速度命令

同时,可以访问 1kHz 测量值:

  • 测量的关节数据,例如角度、角速度和连杆侧扭矩传感器信号

  • 估算的外部施加的扭矩和力

  • 各种碰撞和接触信息

还可以访问机器人模型库 model library,该库提供:

  • 所有机器人关节的正向运动学

  • 所有机器人关节的雅可比矩阵

  • 动力学方面:惯性矩阵、科式力项和离心矢量项和重力矢量项

此外,franka_ros 将 Franka Robotics 科研版机器人与整个 ROS 生态系统连接起来。它将 libfranka 集成到 ROS Control 中。此外,它还包括我们的机器人和末端执行器的 URDF 模型和详细 3D 网格,允许实现可视化(例如 RViz)和运动学模拟。MoveIt! 集成使移动机器人和控制夹爪变得容易,提供的示例程序展示了如何使用 ROS 控制机器人。

重要

数据以 1kHz 的频率通过网络发送,因此,良好的网络连接是必要的!

重要

当 FCI 处于激活状态时,可以完全、独占地控制手臂和抓手。这意味着不能在使用 FCI 的同时使用 Desk 或 Apps。

最低系统和网络要求

此页面仅指定了运行 Franka 控制接口(FCI)的要求。其他要求在收到的机器人文档中指定。

工作站PC

最低系统要求

操作系统

带抢占补丁 PREEMPT_RT 内核的 Linux

网卡

100BASE-TX

由于机器人以 1kHz 的频率发送数据,因此将工作站 PC 配置为尽可能低延迟是很重要的。例如,我们建议 禁用CPU频率缩放。其他可能的优化将取决于特定系统。

网络

如果可能,请将工作站 PC 直接连接到控制器 Control 的 LAN 端口,即避免任何中间设备,如交换机。

重要

通过 FCI 给机器人发布指令的工作站 PC 必须始终连接到控制器的 LAN 口(shop floor network) 而不是 连接到机械臂的 LAN 口                      (robot network)。

中间有中继可能会导致延迟、抖动或数据包丢失。这会降低控制器的性能或使其无法使用。

提示

当直接连接到控制器 Control 的 LAN 端口时,可以实现最佳的性能。这需要预先在 DESK 管理员界面中为车间网络(shop floor network)设置一个静态 IP。请参见 设置网络

为了控制机器人,必须保证以下时间测量之和小于 1ms:

  • 工作站 PC 与 FCI 之间的往返时间(Round trip time [RTT])

  • 运动生成器(motion generator)或控制环路(control loop)的执行时间

  • 机器人处理数据和步进内部控制器所需的时间

小心

如果在一个周期内违反 < 1ms 约束,则 FCI 会丢弃接收到的数据包。在连续丢弃 20 个数据包后,机器人将停止通信并抛出 communication_constraints_violation                      错误。当前的通信质量测量可以从 RobotState::control_command_success_rate                      字段读取。

如果一个 运动生成器命令包被丢弃 ,机器人将采用之前的路径点,并对丢失的时间步长执行线性外插法(保持加速度恒定来积分)。如果连续丢失或丢弃超过 20                    个数据包,机器人将停止工作。

如果 控制器命令数据包被丢弃,FCI 将复用最后一个成功接收数据包的扭矩值。同样,超过 20 个连续丢失或丢弃的数据包将导致机器人停止

提示

预先测量网络的性能(参见 网络带宽、延迟和抖动测试)和控制或运动生成器环路。

版本兼容

与 libfranka 的兼容性

有各种版本的兼容组件可供选择。下表提供了概览,并建议尽可能使用最新版本。符号“>=”表示尚未测试与较新机器人系统版本的兼容性,这意味着兼容性无法保证(例如,libfranka 0.2.0 可能与机器人系统版本 4.0.0 不兼容)。

机器人系统版本 2.x.x 未在下表中列出,但它们包含在与机器人系统版本 >= 1.3.0 兼容的情况下。因此,它们也与 0.4.0 和 0.5.0 版本的 libfranka 兼容。

Robot System Versionlibfranka VersionRobot/Gripper Server                              Ubuntu   franka_ros2 (Humble)franka_ros2 (Jazzy)franka_ros Version
>= 5.9.0>= 0.18.010 / 322.04v2.0.2 < v3.0.0v3.0.0>=>= 0.10.0
>= 5.7.2>= 0.15.09 / 322.04v2.0.2 < v3.0.0v3.0.0>=>= 0.10.0
>= 5.7.0>= 0.14.1 to < 0.15.08 / 322.04v0.1.15 < v2.0.0N/A>= 0.10.0
>= 5.5.0>= 0.13.3 to < 0.14.17 / 322.04v0.1.15 < v2.0.0N/A>= 0.10.0
>= 5.2.0>= 0.10.0 to < 0.13.36 / 322.04>= v0.1.0 to >= v0.1.8N/A>= 0.10.0

与内核的兼容性

不同的内核兼容不同的 Ubuntu 系统版本。下表给出了推荐的内核概览。

内核版本

Ubuntu

Pro Kernel

22.04 (Jammy Jellyfish)

5.9.1

20.04 (Focal Fossa)

5.4.19

18.04 (Bionic)

4.14.12

16.04 (Xenial Xerus)

在 Linux 上安装

本章介绍如何安装 libfrankafranka_ros,它们既可以作为二进制包安装也可以从源代码构建( 两种方法任选一种即可 ),以及如何安装实时Linux内核。franka_ros 仅当想使用 ROS 平台控制机器人时才需要。

备注

虽然 libfranka 这些 franka_ros 软件包应该适用于不同的Linux发行版,但目前仅对下列发行版提供官方支持:

  • Ubuntu 18.04 LTS Bionic Beaver和 ROSMelodic Morenia(至少需要 libfranka 0.6.0)

  • Ubuntu 20.04 LTS Focal Fossa和 ROSNoetic Ninjemys(至少需要 libfranka 0.8.0)

以下示例基于 Ubuntu 20.04 LTS 系统和 ROS Noetic Ninjemys加以说明。它们仅在受支持的环境中工作。

警告

我们不再为 Ubuntu 16.04 LTSXenial Xerus和 ROSKinetic Kame提供支持,因为它们已结束生命周期。

从 ROS 存储库安装(方法一)

提示

这些包可能并不总是最新的,因为它们仅在特定时间间隔同步到存储库。阅读 https://frankarobotics.github.io 上的变更日志,了解特定机器人软件版本所需的 libfranka 版本。如果软件版本与存储库中的 ros-noetic-libfranka 版本不匹配,则需要 从源码构建

可从 ROS 存储库获得 libfrankafranka_ros 的二进制包。在 安装完成 ROS Noetic 之后,执行:

sudo apt install ros-noetic-libfranka ros-noetic-franka-ros

从源代码构建(方法二)[推荐]

首先需要构建libfranka ,请参阅libfranka的 README.md 文件操作

构建ROS包

设置实时内核

为了使用 libfranka 控制的机器人,工作站 PC 上的控制器程序必须以实时优先级运行在 PREEMPT_RT 内核下。本节介绍如何给内核打补丁以支持 PREEMPT_RT 和创建安装包的过程。

备注

NVIDIA驱动在 PREEMPT_RT 内核上没有官方支持,但通过将环境变量 IGNORE_PREEMPT_RT_PRESENCE=1 传递给安装命令,安装可能仍然可以正常工作。

首先,安装必要的依赖项:

sudo apt-get install build-essential bc curl debhelper dpkg-dev devscripts fakeroot libssl-dev libelf-dev bison flex cpio kmod rsync libncurses-dev

然后,必须决定使用哪个内核版本。要查找当前使用的那个,请使用命令 uname -r 。实时补丁仅适用于选定的内核版本,请参阅 https://www.kernel.org/pub/linux/kernel/projects/rt/ 。我们建议选择与当前使用的版本匹配(如不能严格匹配则应选择最接近的)的版本。如果选择不同的版本,只需替换数字即可。确定版本后,使用 curl 下载源文件:

备注

对于使用内核版本 4.14.12 测试通过的 Ubuntu 16.04:

curl -LO https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.14.12.tar.xzcurl -LO https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.14.12.tar.signcurl -LO https://www.kernel.org/pub/linux/kernel/projects/rt/4.14/older/patch-4.14.12-rt10.patch.xzcurl -LO https://www.kernel.org/pub/linux/kernel/projects/rt/4.14/older/patch-4.14.12-rt10.patch.sign

备注

对于使用内核版本 5.4.19 测试通过的 Ubuntu 18.04:

curl -LO https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.4.19.tar.xzcurl -LO https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.4.19.tar.signcurl -LO https://www.kernel.org/pub/linux/kernel/projects/rt/5.4/older/patch-5.4.19-rt10.patch.xzcurl -LO https://www.kernel.org/pub/linux/kernel/projects/rt/5.4/older/patch-5.4.19-rt10.patch.sign

备注

对于使用内核版本 5.9.1 测试通过的 Ubuntu 20.04:

curl -LO https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.9.1.tar.xzcurl -LO https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.9.1.tar.signcurl -LO https://www.kernel.org/pub/linux/kernel/projects/rt/5.9/patch-5.9.1-rt20.patch.xzcurl -LO https://www.kernel.org/pub/linux/kernel/projects/rt/5.9/patch-5.9.1-rt20.patch.sign

备注

对于 Ubuntu 22.04,我们建议使用 Ubuntu Pro 实时内核 。启用后,您可以直接跳转到 允许用户为其进程设置实时权限。如果您不想使用 Ubuntu Pro,您可以按照其他版本的方式继续操作(已在内核版本 6.8.0 下测试):

curl -LO https://www.kernel.org/pub/linux/kernel/v6.x/linux-6.8.tar.xzcurl -LO https://www.kernel.org/pub/linux/kernel/v6.x/linux-6.8.tar.signcurl -LO https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patch-6.8-rt8.patch.xzcurl -LO https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patch-6.8-rt8.patch.sign

并使用以下命令解压缩它们:

xz -d *.xz

验证文件完整性

备注

此步骤是可选的,但推荐! (根据经验,该验证过程容易出错,如果能确保下载过程的文件完整,也可直接跳过本节不做,至下一小节《编译内核》继续)

这些 .sign 文件可用于验证下载的文件没有损坏或篡改。此处显示的步骤改编自 Linux内核存档,有关该过程的更多详细信息,请参阅链接页面。

可以使用 gpg2 来验证 .tar 存档:

gpg2 --verify linux-*.tar.signgpg2 --verify patch-*.patch.sign

如果输出类似于以下内容:

$ gpg2 --verify linux-*.tar.sign
gpg: assuming signed data in 'linux-4.14.12.tar'
gpg: Signature made Fr 05 Jan 2018 06:49:11 PST using RSA key ID 6092693E
gpg: Can't check signature: No public key

必须首先下载签署上述文件的人的公开密钥。从上面的输出中可以看出,它具有 ID 6092693E。可以从密钥服务器获取它:

gpg2  --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 6092693E

对补丁也类似:

gpg2 --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2872E4CC

请注意,其他内核版本的密钥可能具有不同的 ID,必须相应地进行匹配调整。

下载密钥后,现在可以验证来源。以下是正确输出的示例:

$ gpg2 --verify linux-*.tar.sign
gpg: assuming signed data in 'linux-4.14.12.tar'
gpg: Signature made Fr 05 Jan 2018 06:49:11 PST using RSA key ID 6092693E
gpg: Good signature from "Greg Kroah-Hartman <gregkh@linuxfoundation.org>" [unknown]
gpg:                 aka "Greg Kroah-Hartman <gregkh@kernel.org>" [unknown]
gpg:                 aka "Greg Kroah-Hartman (Linux kernel stable release signing key) <greg@kroah.com>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 647F 2865 4894 E3BD 4571  99BE 38DB BDC8 6092 693E

有关警告的更多信息,请参阅 Linux内核存档

编译内核

一旦确定文件下载正确,就可以提取源代码并应用补丁:

tar xf linux-*.tarcd linux-*/patch -p1 < ../patch-*.patch

接下来复制当前启动的内核配置作为新实时内核的默认配置:

cp -v /boot/config-$(uname -r) .config

从内核文件中去除调试信息以节省空间:

scripts/config --disable DEBUG_INFOscripts/config --disable DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULTscripts/config --disable DEBUG_KERNEL

禁用系统范围内的受信密钥环(Ring of Trusted Keys):

scripts/config --disable SYSTEM_TRUSTED_KEYSscripts/config --disable SYSTEM_REVOCATION_LIST

激活完全可抢占内核(实时):

scripts/config --disable PREEMPT_NONEscripts/config --disable PREEMPT_VOLUNTARYscripts/config --disable PREEMPTscripts/config --enable PREEMPT_RT

现在可以使用此配置作为默认配置来配置构建:

make olddefconfig

之后,就可以编译内核了。由于这是一个漫长的过程,请将多线程选项 -j 设置为 CPU 核心数量,也可以直接使用下面的命令:

make -j$(nproc) deb-pkg

最后,您准备好安装新创建的包了。确切的包名称取决于您的环境,但要查找的是不带 dbg 后缀的 headersimages 包。要安装,请执行:

sudo IGNORE_PREEMPT_RT_PRESENCE=1 dpkg -i ../linux-headers-*.deb ../linux-image-*.deb

验证新内核

重新启动系统。Grub 启动菜单现在应该允许选择新安装的内核。选好启动项登录成功后,如果要查看当前正在使用的是不是前面步骤安装的实时内核,请查看 uname -a 命令的输出。它应该包含选择的 PREEMPT RT 字符串和版本号。此外, /sys/kernel/realtime 应该存在,并包含数字1

备注

如果遇到无法引导新内核的错误,请参阅 由于 “Invalid Signature(无效签名)” 无法引导实时内核

允许用户为其进程设置实时权限

在安装 PREEMPT_RT 内核并成功运行后,添加一个名为realtime的组 ,并将控制的机器人的用户添加到该组中:

sudo addgroup realtime
sudo usermod -a -G realtime $(whoami)

然后,将以下限制添加到在 /etc/security/limits.conf 文件中的realtime

@realtime soft rtprio 99@realtime soft priority 99@realtime soft memlock 102400@realtime hard rtprio 99@realtime hard priority 99@realtime hard memlock 102400

这些限制将在 注销 并再次 登录 后得以应用。

入门指南

在为 Linux 设置所需的软件后,是时候连接到机器人并通过使用 FCI 读取当前机器人状态来测试整个设置了。

操作机器人

在继续之前,这里有一些安全注意事项。在给机器人通电之前,请务必检查以下事项:

  1. 确保手臂已安装在稳定的底座上并且不会翻倒,即使在执行快速运动或突然停止时也不会翻倒。

小心

仅支持桌面安装,即手臂必须垂直于地面安装!其他安装将 使失去保修,并 可能导致机器人损坏

  1. 确保连接机械臂和控制器的电缆在两侧牢固连接。

  2. 将外部激活设备(灰色按钮)连接到机械臂的底座 X3 口并将其放置在身边,以便能够随时停止机器人。

提示

激活外部激活设备(即按下灰色按钮)将使机械臂脱离控制。关节电机控制器将保持其当前位置。 外部激活设备不是紧急停止装置!

这份清单并不详尽!机器人随附的手册中有一章专门介绍安全。请仔细阅读并按照说明进行操作。该手册也可以在我们的 Franka World Hub 中找到。

重要

使用 FCI 给机器人发送命令的工作站 PC 必须始终连接到控制器的 LAN 端口(shop floor network),而 不是 连接到机械臂(robot network)的 LAN 端口。

安装 FCI Feature

为了能够通过 Franka 控制接口(FCI)操作机器人,需要在设备上安装相应的 Feature。如果它已经安装到控制器上,它将在 DESK -> Settings -> System -> Installed Features 下列出。如果尚未安装 FCI,可以将其从 Franka World 帐户同步到控制器。因此,公司/学校帐户中必须有可用的 FCI 许可证,并且控制器必须在此帐户中注册。软件(离线/在线)同步过程在 Franka World 用户手册 中有更详细的描述。(对于中国的用户,您的机器人可能被统一账户管理,可以联系您的服务商了解更多详情)


设置网络

使用 FCI 控制机器人时,良好的网络性能至关重要。因此强烈建议在工作站 PC 和机器人控制器之间选择(网线)直接连接。本节将介绍如何为此例配置网络。

_images/control.png

通过 FCI 控制机器人时使用控制器的网口。不要连接到机械臂底座的网口。

控制器和工作站必须配置在同一网段上。实现这一目标的最简单方法是使用静态 IP 地址。同一网段上的任何两个地址都可以使用,但本教程将使用以下值:


工作站 PC

控制器

IP 地址

172.16.0.1

172.16.0.2

网络掩码

24

24

控制器的 IP 地址(172.16.0.2)在后面的章节中会被以 <fci-ip> 调用。

提示

使用此网络配置,可以通过 https://<fci-ip> 访问            Desk,尽管会在浏览器中看到证书警告。

配置过程包括两个步骤:

  • 配置控制器的网络设置。

  • 配置工作站的网络设置。

控制器网络配置

对于这一步,需要安装和测试机器人。 在继续下一步之前,请通读机器人随附的文档并按照设置说明进行操作!

系统版本 >= 5.5.0 时,可以在设置界面中配置控制器的网络。在此步骤期间,可以通过机器人基座中的端口连接到机器人。有关详细信息,请参阅机器人随附的手册中的连接用户界面设备章节。

_images/FrankaUI_Settings_Bar.png

通过 Desk 进入 Franka 的设置界面。

要设置静态地址,请在Network部分输入以下值:

FrankaUI_Settings_Network.png

为控制器的 LAN 端口(Shop Floor network)设置静态 IP。取消选择 DHCP 客户端选项。

按下Apply。成功应用设置后,将工作站的网口连接到机器人的控制器。

Linux 工作站网络配置

本节介绍如何使用 GUI 在 Ubuntu 16.04 上设置静态 IP 地址。如果更喜欢使用命令行,请遵循官方 Ubuntu 指南

小心

以下步骤将修改网络设置。如有疑问,请联系网络管理员。

首先,打开网络连接(Network Connection)小控件。选择要使用的有线连接,然后单击编辑。

_images/edit-connections.png

在以太网部分编辑连接。

接下来,单击 IPv4 设置选项卡,将方法设置为手动,然后输入以下值:

_images/static-ip-ubuntu.png

为工作站 PC 设置静态 IP。方法设置为手动。

提示

此步骤将禁用 DHCP 服务,这意味着在连接到 DHCP 服务器时将不再获得地址,例如机械臂基座中的服务器。当不再使用 FCI 时,可以将方法更改回Automatic (DHCP)

保存更改,然后关闭网络连接窗口。从下拉菜单中单击连接名称。现在应该可以从工作站连接到机器人。要验证这一点,请执行  网络带宽、延迟和抖动测试。从现在开始,还可以在浏览器中通过此地址访问 Desk。

在 Desk 中为使用 FCI 的机器人做准备

为了验证连接,需要在 Desk 中解锁机器人的抱闸并释放激活装置(灰色按钮),以便机器人准备好执行蓝色 LED 模式(运行模式)指示的操作。


激活 FCI 模式

要激活 FCI 模式,请打开 Desk,然后解锁机器人抱闸,并展开顶栏中的菜单。最后,点击 ‘Activate FCI’ 。

_images/FrankaUI_System_ActivateFCI.png

在 Desk 顶栏菜单中激活 FCI 模式(系统版本 >= 5.5.0)

验证连接

上一节描述了如何设定控制器 LAN 端口的 IP 地址。在后文中,该地址称为 <fci-ip>

为了验证一切设置是否正确,请确保 在 Desk 中为使用 FCI 的机器人做准备 。并从 libfranka 运行示例 echo_robot_state。如果决定从 ROS 存储库安装 franka_roslibfranka,可以改为阅读 在ros中可视化机器人 的说明 。

切换到构建目录 libfranka 并执行示例:

./examples/echo_robot_state <fci-ip>

该程序会将机器人的当前状态打印到控制台并在几次迭代后终止。在 机器人状态 RobotState 中解释了这些字段的含义。

示例输出:

{
"O_T_EE": [0.998578,0.0328747,-0.0417381,0,0.0335224,-0.999317,0.0149157,0,-0.04122,-0.016294,
             -0.999017,0,0.305468,-0.00814133,0.483198,1],
  "O_T_EE_d": [0.998582,0.0329548,-0.041575,0,0.0336027,-0.999313,0.0149824,0,-0.0410535,
               -0.0163585,-0.999023,0,0.305444,-0.00810967,0.483251,1],
  "F_T_EE": [0.7071,-0.7071,0,0,0.7071,0.7071,0,0,0,0,1,0,0,0,0.1034,1],
  "EE_T_K": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
  "m_ee": 0.73, "F_x_Cee": [-0.01,0,0.03], "I_ee": [0.001,0,0,0,0.0025,0,0,0,0.0017],
  "m_load": 0, "F_x_Cload": [0,0,0], "I_load": [0,0,0,0,0,0,0,0,0],
  "m_total": 0.73, "F_x_Ctotal": [-0.01,0,0.03], "I_total": [0.001,0,0,0,0.0025,0,0,0,0.0017],
  "elbow": [-0.0207622,-1], "elbow_d": [-0.0206678,-1],
  "tau_J": [-0.00359774,-5.08582,0.105732,21.8135,0.63253,2.18121,-0.0481953],
  "tau_J_d": [0,0,0,0,0,0,0],
  "dtau_J": [-54.0161,-18.9808,-64.6899,-64.2609,14.1561,28.5654,-11.1858],
  "q": [0.0167305,-0.762614,-0.0207622,-2.34352,-0.0305686,1.53975,0.753872],
  "dq": [0.00785939,0.00189343,0.00932415,0.0135431,-0.00220327,-0.00492024,0.00213604],
  "q_d": [0.0167347,-0.762775,-0.0206678,-2.34352,-0.0305677,1.53975,0.753862],
  "dq_d": [0,0,0,0,0,0,0],
  "joint_contact": [0,0,0,0,0,0,0], "cartesian_contact": [0,0,0,0,0,0],
  "joint_collision": [0,0,0,0,0,0,0], "cartesian_collision": [0,0,0,0,0,0],
  "tau_ext_hat_filtered": [0.00187271,-0.700316,0.386035,0.0914781,-0.117258,-0.00667777,
                           -0.0252562],
  "O_F_ext_hat_K": [-2.06065,0.45889,-0.150951,-0.482791,-1.39347,0.109695],
  "K_F_ext_hat_K": [-2.03638,-0.529916,0.228266,-0.275938,0.434583,0.0317351],
  "theta": [0.01673,-0.763341,-0.0207471,-2.34041,-0.0304783,1.54006,0.753865],
  "dtheta": [0,0,0,0,0,0,0],
  "current_errors": [], "last_motion_errors": [],
  "control_command_success_rate": 0, "robot_mode": "Idle", "time": 3781435
}

提示

如果此时出现错误,请执行 ping 测试 并确保机器人的故障保护安全锁止系统已打开。机器人随附的手册中提供了更多信息。


libfranka

在继续阅读本章之前,请为 Linux 安装或编译 libfranka。

最新版本的 libfranka 的 API 文档可在以下网址找到:https://frankarobotics.github.io/libfranka

Libfranka 更新日志可在 CHANGELOG.md 中查看。

_images/libfranka-architecture.png

示意图概述

libfranka 是 FCI 客户端的 C++ 实现。它处理与 Control 的网络通信并提供接口以易化

  • 执行 非实时命令 来控制夹爪和配置臂参数。

  • 执行 实时命令 以运行 1kHz 控制回路。

  • 读取 机器人状态 以获取 1kHz 的传感器数据。

  • 访问 模型库 以计算期望的运动学和动力学参数。

在操作过程中,可能还会遇到一些 错误,我们在本节末尾详细介绍了这些错误。

非实时命令

非实时命令是阻塞的、基于 TCP/IP 的,并且总是在任何实时控制循环之外执行。它们包含所有的夹爪命令和一些与臂 的配置相关的命令。

_images/fci-architecture-non-realtime.png

臂和夹爪的非实时命令。

与夹爪最相关的是

  • homing 校准夹爪的最大抓取宽度。

  • move, graspstop, 用夹爪移动或抓取。

  • readOnce,读取夹爪状态。

关于臂,一些有用的非实时命令是:

  • setCollisionBehavior 它设置接触和碰撞检测阈值。

  • setCartesianImpedancesetJointImpedance 为内部笛卡尔阻抗和内部关节阻抗控制器设置阻抗参数。

  • setEE 设置从名义末端执行器到末端执行器坐标系的变换 NE_T_EE。从法兰坐标系到末端执行器坐标系的变换 F_T_EE 被分为两个变换: F_T_NENE_T_EE。从法兰坐标系到名义末端执行器坐标系的变换 F_T_NE 只能通过管理员界面进行设置。

  • setK 设置从末端执行器坐标系到刚度坐标系的变换 EE_T_K

  • setLoad 设置负载的动力学参数。

  • automaticErrorRecovery 清除之前在机器人中发生的任何命令或控制异常。

对于完整且详尽的列表,请查看 Robot类Gripper类 的 API 文档 。

臂或夹爪上的所有操作(非实时或实时)分别通过 franka::Robotfranka::Gripper 对象执行 。创建对象时,将建立与臂/夹爪的连接:

#include <franka/robot.h>
#include <franka/gripper.h>
...
franka::Gripper gripper("<fci-ip>");
franka::Robot robot("<fci-ip>");

该地址可以作为主机名或 IP 地址传递。如果出现任何错误,无论是由于网络还是库版本冲突,franka::Exception 类型的异常都会被抛出。同时使用多个机器人时,只需创建多个具有适当 IP 地址的对象即可。

要运行特定命令,只需调用相应的方法,例如

gripper.homing();
robot.automaticErrorRecovery();

实时命令

实时命令基于 UDP,需要 1kHz 连接到 Control。有两种类型的实时接口:

  • 运动生成器,它定义了关节或笛卡尔空间中的机器人运动。

  • 控制器,定义要发送到机器人关节的扭矩。

有 4 种不同类型的外部运动生成器和 3 种不同类型的控制器(1 个外部和 2 个内部),如下图所示:

_images/rt-interfaces.png

实时接口:运动生成器和控制器。

可以使用单个接口或组合两种不同的类型。具体来说,可以给出命令:

  • 只有一个运动生成器,因此使用两个内部控制器之一来跟随命令的运动。

  • 只有一个外部控制器,而忽略任何运动生成器信号,即仅转矩控制。

  • 一个运动生成器和一个外部控制器,可在外部控制器中使用 Control 的逆运动学。

所有实时循环(运动生成器或控制器)都由一个回调函数定义,该函数接收机器人状态和最后一个循环的持续时间(除非发生数据包丢失,否则为 1ms) 并返回接口的特定类型。然后 franka::Robot 类的 control 方法将通过以 1kHz        的频率执行回调函数来运行控制循环,如本例所示

std::function<franka::Torques(const franka::RobotState&, franka::Duration)>   my_external_controller_callback;// Define my_external_controller_callback...std::function<franka::JointVelocities(const franka::RobotState&, franka::Duration)>    my_external_motion_generator_callback;// Define my_external_motion_generator_callback...try {  franka::Robot robot("<fci-ip>");  // only a motion generator  robot.control(my_external_motion_generator_callback);  // only an external controller  robot.control(my_external_controller_callback);  // a motion generator and an external controller  robot.control(my_external_motion_generator_callback, my_external_controller_callback);} catch (franka::Exception const& e) {  std::cout << e.what() << std::endl;  return -1;}  return 0;}

当实时命令 motion_finished 的标志设置为 true 时,表示所有控制循环就完成了。此处展示了 libfranka            示例 中包含的 generate_joint_velocity_motion 示例的代码片段

robot.control(     [=, &time](const franka::RobotState&, franka::Duration period) -> franka::JointVelocities {       time += period.toSec();       double cycle = std::floor(std::pow(-1.0, (time - std::fmod(time, time_max)) / time_max));       double omega = cycle * omega_max / 2.0 * (1.0 - std::cos(2.0 * M_PI / time_max * time));       franka::JointVelocities velocities = {{0.0, 0.0, 0.0, omega, omega, omega, omega}};       if (time >= 2 * time_max) {         std::cout << std::endl << "Finished motion, shutting down example" << std::endl;         return franka::MotionFinished(velocities);       }       return velocities;     });

在这种情况下,回调函数直接在 robot.control( ... )        函数的调用中定义。它使用关节速度运动生成器接口,因为它返回一个 franka::JointVeloities        对象。它命令最后四个关节的关节速度并将它们移动大约 +/-12 度。在 2 * time_max        秒后,回调函数将返回一个 motion_finished 标志,通过        franka::MotionFinished 方法将它设置为 true        ,则控制循环将停止。

请注意,如果仅使用运动生成器,则默认控制器是内部关节阻抗控制器。但是,可以通过设置控制函数的可选参数来使用内部笛卡尔阻抗控制器,例如

// Set joint impedance (optional)robot.setJointImpedance({{3000, 3000, 3000, 3000, 3000, 3000, 3000}});// Runs my_external_motion_generator_callback with the default joint impedance controllerrobot.control(my_external_motion_generator_callback);// Identical to the previous line (default franka::ControllerMode::kJointImpedance)robot.control(my_external_motion_generator_callback, franka::ControllerMode::kJointImpedance);// Set Cartesian impedance (optional)robot.setCartesianImpedance({{2000, 2000, 2000, 100, 100, 100}});// Runs my_external_motion_generator_callback with the Cartesian impedance controllerrobot.control(my_external_motion_generator_callback, franka::ControllerMode::kCartesianImpedance);

为了编写控制器,还使用了 franka::Robot::control        函数。以下示例显示了一个简单的控制器,它为每个关节发出零扭矩命令。重力项已由机器人补偿。

robot.control([&](const franka::RobotState&, franka::Duration) -> franka::Torques {      return {{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}};    });

您可以在 Libfranka 示例程序        中找到所有接口及控制回路组合的示例。在运行示例之前,请验证机器人是否有足够的自由空间来移动而不会发生碰撞。然后,例如对于 generate_joint_velocity_motion 示例,从        libfranka 构建(build)目录执行以下命令:

./examples/generate_joint_velocity_motion <fci-ip>

警告

要编写自己的运动生成器或控制器,向机器人传递平滑信号至关重要。非平滑信号很容易产生不连续性错误,甚至使机器人不稳定。开始前需 检查 接口规范

信号处理

为了便于在非理想网络连接下控制机器人,libfranka 包括信号处理函数,这些函数将修改用户命令的值,使其符合 接口限制。所有实时控制回路中都包含两个 可选功能

  • 一阶低通滤波器 low-pass filter,用于平滑用户命令信号。

  • 一个速率限制器 rate limiter,它使用户命令值的时间导数饱和。

  • 从版本 0.5.0 开始,libfranka 包括一个低通滤波器 low-pass filter,用于 默认运行 的所有实时接口,截止频率为 100Hz。滤波器平滑命令信号以提供更稳定的机器人运动,但不能防止违反 接口限制

  • 从版本 0.4.0 开始,所有实时接口的 速率限制器 (rate limiters) 默认运行 。速率限制器 (rate limiters) ,也称为安全控制器 (safe controllers),将限制用户发送的信号的变化率,以防止违反 接口限制。. 对于运动生成器,它将限制加速度和加加速度,而对于外部控制器,它将限制扭矩变化率。它们的主要目的是提高控制回路的稳健性。在数据包丢失的情况下,即使发送的信号符合接口限制,Control 也可能检测到违反速度、加速度或加加速度限制的情况。速率限制将调整命令以确保不会发生这种情况。有关更多详细信息,请查看 不合规错误部分

    小心

    速率限制将确保除了逆向运动学之后的关节限制之外没有任何限制被违反,其违反会产生以 cartesian_motion_generator_joint_* 开头的一系列错误。有关更多详细信息,请查看 不合规错误部分

    提示

    速率限制器中使用的限制在 franka/rate_limiting.h 定义并被设置到接口限制中。如果这会产生急动或不稳定的行为,可以将限制设置为较低的值,激活低通滤波器或降低其截止频率。

为了控制信号处理函数,所有 robot.control() 函数调用都有两个额外的可选参数。第一个是启用或停用速率限制器的标志,而第二个指定一阶低通滤波器的截止频率。如果达到截止频率 >=1000.0,滤波器将被停用。例

// Set Cartesian impedance (optional)
robot.setCartesianImpedance({{2000, 2000, 2000, 100, 100, 100}});
// Runs my_external_motion_generator_callback with the Cartesian impedance controller,
// rate limiters on and low-pass filter with 100 Hz cutoff
robot.control(my_external_motion_generator_callback, franka::ControllerMode::kCartesianImpedance);
// Identical to the previous line (default true, 100.0 Hz cutoff)
robot.control(my_external_motion_generator_callback, franka::ControllerMode::kCartesianImpedance, true, 100.0);
// Runs my_external_motion_generator_callback with the Cartesian impedance controller,
// rate limiters off and low-pass filter off
robot.control(my_external_motion_generator_callback, franka::ControllerMode::kCartesianImpedance, false, 1000.0);

或类似的外部控制器

// With rate limiting and filter
robot.control(my_external_controller);
// Identical to the previous line (default true, 100.0 Hz cutoff)
robot.control(my_external_controller, true, 100.0);
// Without rate limiting but with low-pass filter (100.0 Hz)
robot.control(my_external_controller, false);
// Without rate limiting and without low-pass filter
robot.control(my_external_controller, false, 1000.0);

危险

低通滤波器和速率限制器是用来针对数据包丢失的稳健性功能,在已经设计了平滑运动生成器或控制器 之后 使用。对于新控制回路的首次测试,我们强烈建议停用这些功能。过滤和限制非平滑信号的速率会产生不稳定性或意外行为。太多的数据包丢失也会产生不稳定的行为。通过监控 control_command_success_rate 机器人状态信号来检查通信质量。

内部逻辑

到目前为止,我们已经介绍了在客户端(即自己的工作站 PC)上运行的接口的详细信息。包括实时接口的控制端在内的完整控制回路的行为如下图所示

_images/rt-loop.png

实时循环:从控制命令到机器人期望的关节扭矩。

运动生成器 :用户发送的所有运动生成器命令都有下标c,代表 ‘commanded’。当发送运动生成器时,机器人运动学完备块Robot Kinematics completion将计算用户命令信号的正向/逆向运动学,产生期望信号,下标d。如果使用内部控制器,它将产生必要的扭矩 τd 跟踪相应的计算d信号(内部关节阻抗控制器将跟踪关节信号 qd,q˙d 和内部笛卡尔阻抗控制器将跟踪末端笛卡尔信号 OTEE,d,OP˙EE,d)并将它们发送到机器人关节。图中控制侧的所有变量,即最后接收到的c值(在低通滤波器和由于数据包丢失导致的外插 extrapolation 之后,阅读下面的解释)、计算出的d值及其时间导数被作为机器人状态(的一部分)发送回用户。通过这种方式,可以在自己的外部控制器中利用逆运动学,同时,它将提供完全透明的信息:用户将始终知道机器人在上一个采样中接收和跟踪的确切值和导数。

提示

当使用 关节 运动生成器时,机器人运动学完备块不会修改命令中的  关节 值,因此 qd,q˙d,q¨dqc,q˙c,q¨c 是等价的。请注意,此时只会在机器人状态下找到(下标为)d信号。如果使用 笛卡尔 运动生成器,机器人运动学完备块可能会修改用户命令的值以避免奇异点,从而所需的信号 OTEE,d,OP˙EE,d 和命令的信号 OTEE,c,OP˙EE,c,OP¨EE,c 可能不同。此时会在机器人状态中找到(下标为)dc信号。

外部控制器:如果发送外部控制器,则用户命令的已经额外补偿重力与摩擦力的期望关节扭矩 τd 将直接送入机器人关节。得到以下方程:

τc=τd+τf+τg

其中:

  • τd 是 libfranka 用户输入的期望扭矩,

  • τc 是有效控制关节的扭矩,

  • τf 是补偿电机摩擦的扭矩,

  • τg 是补偿整个运动学链重力所需的扭矩。

请注意,在控制端,有两件事可以修改信号:

  • 数据包丢失,如果:

    在这种情况下,Control 假设一个恒定加速度模型或一个恒定扭矩来推断信号。如果 >=20 个数据包连续丢失,则控制循环将停止,并伴随 communication_constraints_violation 异常的抛出。

    • 由于 PC 和 网卡的性能,没有很好的网络连接。

    • 控制回路计算时间太长(取决于网卡和 PC 配置,剩下大约 < 300 μs 的时间用于自己的控制回路)。

提示

如果不确定信号是否被过滤或外插,可以随时检查发送的最后一个命令值,并将它们与在下一个采样中在机器人状态中接收到的值进行比较。还可以在异常发生后在 franka::ControlException::log 成员中找到这些值 。

机器人状态

机器人状态以 1kHz 的速率提供机器人传感器读数和估计值。它提供:

  • 关节层级信号:电机和估计的关节角度及其导数、关节扭矩及其导数、估计的外部扭矩、关节碰撞/接触。

  • 笛卡尔层级信号:笛卡尔位姿、配置的末端执行器和负载参数、作用在末端执行器上的外部力旋量、笛卡尔碰撞

  • 接口信号:上一小节中解释的最后的命令和期望值及其导数值。

如需完整列表,请查看 franka::RobotState API 。如上一小节所示,机器人状态始终是控制循环的所有回调函数的输入。但是,如果希望只读取机器人状态而不对其进行控制,则可以使用功能 readreadOnce 来收集它,例如用于记录或可视化目的。

通过合法连接,可以使用以下函数 readOnce 读取 机器人的单次采样状态

franka::RobotState state = robot.readOnce();

下一个示例显示如何使用 read 函数和回调连续读取机器人状态。返回 false 会在回调中停止循环。下面显示了 echo_robot_state 示例的代码片段:

size_t count = 0;
robot.read([&count](const franka::RobotState& robot_state) {
  // Printing to std::cout adds a delay. This is acceptable for a read loop such as this,
  // but should not be done in a control loop.
  std::cout << robot_state << std::endl;
  return count++ < 100;
});

Model 库

机器人模型库提供

  • 所有机器人关节的正向运动学。

  • 所有机器人关节的体雅可比矩阵和零雅可比矩阵。

  • 动力学参数:惯性矩阵、科式力和离心力矢量和重力矢量。

请注意,加载模型库后,您可以计算任意机器人状态的运动学和动力学参数,而不仅仅是当前状态。您还可以以非实时方式使用模型库,例如在优化循环中。libfranka 示例包括用于 打印关节位姿计算雅可比和动力学参数 的示例代码。


错误

使用 FCI 时,可能会遇到一些错误,这些错误可能是由于用户发送的命令不合规、通信问题或机器人行为造成的。以下小节详细介绍了最相关的内容。如需完整列表,请查看 Errors

提示

请注意,在发生错误后,可以自动清除它并使用 franka::Robot::automaticErrorRecovery() 命令继续运行程序,而无需用户干预。在进一步操作前检查异常字符串,以确保错误不是严重错误。

也可以通过切换外部激活设备或使用 Desk 中的错误恢复按钮手动清除某些错误。

由于不合规的命令值而导致的错误

如果用户发送的 指令值 不符合 接口要求 ,则会出现以下错误之一:

  • 由于 运动生成器的错误初始值(wrong initial values of a motion generator) 而导致的错误:

  • joint_motion_generator_start_pose_invalid

  • cartesian_position_motion_generator_start_pose_invalid

  • cartesian_motion_generator_start_elbow_invalid

  • cartesian_motion_generator_elbow_sign_inconsistent

这些错误表明当前机器人值与用户发送的初始值之间存在差异。要修复这些错误,请确保控制回路从机器人状态中观察到的最后一个命令值开始。例如,对于关节位置接口

double time{0.0};
robot.control(
 [=, &time](const franka::RobotState& robot_state, franka::Duration period) -> franka::JointPositions {
   time += period.toSec();
   if (time == 0) {
     // Send the last commanded q_c as the initial value
     return franka::JointPositions(robot_state.q_c);
   } else {
     // The rest of your control loop
     ...
   }
 });
  • 由于使用关节位置/速度运动生成器违反 位置限制 而导致的错误,这将产生 joint_motion_generator_position_limits_violation 报错. 解决此错误应该很简单:确保发送的值在 限制 范围内。笛卡尔接口对逆运动学计算之后得到的关节信号也有限制:如果 Control 的逆运动学求解器产生超出限制的某个关节配置,cartesian_motion_generator_joint_position_limits_violation 将被触发。

  • 由于违反 速度(velocity) 的限制产生的错误和不连续的错误,其指的违反 加速度(acceleration) 和/或 加加速度 (jerk) 的限制。如果使用关节运动生成器,则可能的错误是

  • joint_motion_generator_velocity_limits_violation

  • joint_motion_generator_velocity_discontinuity (违反加速度限制)

  • joint_motion_generator_acceleration_discontinuity (违反加加速度限制)

如果使用的是笛卡尔运动生成器,错误可能是

  • 笛卡尔限制

    • cartesian_motion_generator_velocity_limits_violation

    • cartesian_motion_generator_velocity_discontinuity (违反加速度限制)

    • cartesian_motion_generator_acceleration_discontinuity (违反加加速度限制)

  • 逆运动学解算后的关节限制

    • cartesian_motion_generator_joint_velocity_limits_violation

    • cartesian_motion_generator_joint_velocity_discontinuity (违反加速度限制)

    • cartesian_motion_generator_joint_acceleration_discontinuity (违反加加速度限制)

要减少速度不合规或不连续性错误,请确保命令的信号不违反 限制 。对于每个运动生成器,Control 都会使用反向欧拉法区分用户发送的信号。例如,如果使用关节位置运动生成器,在时间 k 用户发送命令 qc,k,由此产生的速度、加速度和加加速度将是

  • 速度 q˙c,k=qc,kqc,k1Δt

  • 加速度 q¨c,k=q˙c,kq˙c,k1Δt

  • 加加速度/急动度 qc,k=q¨c,kq¨c,k1Δt

这里 Δt=0.001. 注意 qc,k1,q˙c,k1 和  q˙c,k1 总是作为机器人状态(的一部分)发送回用户作为 qd,q˙dq¨d。因此,即使在数据包丢失的情况下,也可以提前计算结果的导数。有关更多详细信息,请查看 关于控制端接口的细节部分

最后,对于扭矩接口,违反 扭矩速率限制 torque rate 会触发错误

  • controller_torque_discontinuity

Control 还使用反向欧拉法(backwards Euler)计算扭矩变化率,即 τ˙d,k=τd,kτd,k1Δt. 用户先前期望的扭矩也在机器人状态下作为 τd 发回。因此,即使在数据包丢失的情况下,也可以提前计算产生的扭矩率。

提示

libfranka 版本中包含的速率限制器从 0.4.0 版本起修改用户发送的信号,使它们符合所有这些限制,除了逆向运动学之后的关节限制。可以查看 include/franka/rate_limiting.hsrc/rate_limiting.cpp 以获取有关如何计算由此限制的所有接口的速度、加速度和加加速度的示例代码。我们再次强调,在不连续信号上使用速率限制很容易产生不稳定行为,因此在启用此 稳健性 robustness 功能之前,请确保信号足够平滑。

通讯问题导致的错误

如果在实时循环中 Control 在 20 个周期(即 20ms)内没有收到任何数据包,将收到 communication_constraints_violation 错误消息。请注意,如果连接间歇性丢包,它可能不会停止,但即使源信号符合接口规范,它也可能触发不连续性错误。在这种情况下,请查看我们的 故障排除部分 并考虑启用 信号处理功能 以提高控制回路的稳健性。


行为错误

警告

这些监控功能并不符合任何安全规范,也不保证对用户的任何安全。他们的目的只是帮助研究人员开发和测试他们的控制算法。

  • 反射性错误 Reflex errors。如果估计的外部扭矩 τ^ext 或力 OF^ext 超过配置的阈值,将分别触发 cartesian_reflexjoint_reflex 错误。可以使用 franka::Robot::setCollisionBehavior 非实时命令配置阈值。

    提示

    如果希望机器人与环境接触,必须将碰撞阈值设置为更高的值。否则,一旦抓住一个物体或推向一个表面,就会触发反射错误。此外,如果阈值较低,在没有接触的情况下非常快速或突然的运动可能会触发反射错误;外部扭矩和力只是 估计值,根据机器人配置它们可能不准确,尤其是在高加速阶段。可以监视它们的值通过观察机器人状态中的 τ^extOF^ext

  • 自碰撞避免 Self-collision avoidance。如果机器人达到接近自碰撞的配置,则会触发 self_collision_avoidance_violation 错误。

    警告

    此错误并不能保证机器人在任何配置和速度下都能防止自碰撞。如果使用扭矩接口以全速驱动机器人,机器人可能会发生自我碰撞。

  • 如果达到 扭矩传感器限制tau_j_range_violation 错误将被触发。这并不能保证传感器在任何高扭矩相互作用或运动后不会损坏,但旨在防止其中一些。

  • 如果达到 最大允许功率power_limit_violation 错误将触发。它将阻止机器人移动并阻止控制循环继续。

  • 如果达到关节或笛卡尔极限,将分别得到一个 joint_velocity_violation 或一个 cartesian_velocity_violation 错误。

franka_ros

备注

Windows 不支持 franka_ros

在继续本章之前,请先 安装或编译 franka_ros

您可以通过 此链接  访问 franka_ros 的更新日志。

_images/ros-architecture.png

franka_ros 示意图概述

franka_ros 元包将 libfranka 集成到 ROS 和 ROS control中。在这里,我们不仅介绍了它的包,我们还给出了一个简短的操作方法,如何 编写自己的控制器

本节中传递给 launch 文件的所有参数都带有默认值,因此如果使用默认网络地址和 ROS 命名空间,则可以省略它们。确保使用来自工作区的设置脚本调用 source 命令:

source /path/to/catkin_ws/devel/setup.sh

franka_description

该包包含运动学、关节限制、视觉表面和碰撞空间对我们的机器人和末端执行器的描述。碰撞空间是视觉描述的一个简化版本,用于提高碰撞检查的性能。该描述是基于按照 URDF XML 文档 的URDF格式。

如果您想仿真 FR3 机器人,您可以将 gazebo 参数传递给 XACRO 文件。 franka_description  包含所有 Franka Robotics 机器人模型的文件。

xacro $(rospack find franka_description)/robots/fr3/fr3.urdf.xacro gazebo:=true

同样适用于 FER(Panda):

xacro $(rospack find franka_description)/robots/panda/panda.urdf.xacro gazebo:=true

碰撞体积

URDF 定义了两种碰撞类型:

  • Fine(精细):这些碰撞体积由凸面网格构成,这些凸面网格是每个连杆的视觉网格 (.dae) 的近似和大幅简化的版本。精细体积应用于仿真 Gazebo 中的机器人碰撞。

  • Coarse(粗糙): 这些碰撞体积是简单的胶囊体(一个有两个半球形端盖的圆柱体),连接到每个连杆,并按一定的安全距离膨胀。这些体积的计算效率更高,并在机器人内部使用以避免自碰撞。当规划运动时,例如使用 MoveIt 时,请使用这些几何图形。

可视化模型

碰撞模型(精细)

碰撞模型(粗糙)

_images/visual.png_images/collision-fine.png_images/collision-coarse.png

为了区分以上两种类型的碰撞模型,在 URDF 中插入了带有 *_sc 后缀的人为添加的连杆(用于自碰撞):

panda_link0

├─ panda_link0_sc

└─ panda_link1

├─ panda_link1_sc

└─ panda_link2

├─ panda_link2_sc

└─ panda_link3

├─ panda_link3_sc

└─ panda_link4

├─ panda_link4_sc

└─ panda_link5

├─ panda_link5_sc

└─ panda_link6

├─ panda_link6_sc

└─ panda_link7

├─ panda_link7_sc

└─ panda_link8

├─ panda_link8_sc

└─ panda_hand

├─ panda_leftfinger

├─ panda_rightfinger

├─ panda_hand_sc

└─ panda_hand_tcp

可以通过 gazebo XACRO 参数控制哪个碰撞模型加载到 URDF 中:

  • xacro ... panda.urdf.xacro gazebo:=false: 这将 同时 使用精细和粗略碰撞模型。如果完全省略 arg 参数,这也是默认设置。如果要使用 MoveIt,请使用此选项。

  • xacro ... panda.urdf.xacro gazebo:=true: 这将 使用精细碰撞模型。当想要一个可仿真的 URDF(即用于 Gazebo)时使用它。当使用粗略碰撞模型时,机器人当然会不断地与下一个连杆的胶囊体发生碰撞。

franka_gripper

这个包实现了 franka_gripper_node 节点,用于来自 ROS 的夹爪进行交互。该节点发布夹爪的状态并提供以下actions servers

  • franka_gripper::MoveAction(width, speed):以定义的 speed 移动到目标 width

  • franka_gripper::GraspAction(width, epsilon_inner, epsilon_outer, speed, force):尝试在以给定 speed 闭合的同时以所需的 force 在所需的 width 处抓取。如果夹爪指间的距离 d 为以下范围之内时: widthϵinner<d<width+ϵouter,则该操作是成功的。

  • franka_gripper::HomingAction(): 将夹爪归零并根据已安装的手指更新最大宽度。

  • franka_gripper::StopAction(): 中止正在运行的 action。这可以是用于在抓取后停止施加力。

  • control_msgs::GripperCommandAction(width, max_effort): MoveIt! 识别的一个标准夹爪 action。如果参数 max_effort 大于零,则夹爪将尝试抓取所期望 width 处的对象。另一方面,如果 max_effort 等于零 (max_effort<14),夹爪将尝试移动到所期望的 width 处。

备注

只在抓取对象时使用参数 max_effort,否则,夹爪将关闭并忽略 width 参数。

可以启动 franka_gripper_node 节点通过:

roslaunch franka_gripper franka_gripper.launch robot_ip:=<fci-ip>

提示

franka_ros 0.6.0 开始,为 roslaunch franka_control franka_control.launch 指定 load_gripper:=true,也将启动 franka_gripper_node 节点。

franka_hw

该包包含基于 libfranka API 的 ROS control 控制框架的机器人硬件抽象。硬件类 franka_hw::FrankaHW 在这个包中实现,为控制器提供以下接口:

接口

功能

hardware_interface::JointStateInterface

读取关节状态

hardware_interface::VelocityJointInterface

给关节速度指令并读取关节状态。

hardware_interface::PositionJointInterface

给关节角度指令并读取关节状态。

hardware_interface::EffortJointInterface

给关节级扭矩指令并读取关节状态。

franka_hw::FrankaStateInterface

读取整个机器人状态

franka_hw::FrankaPoseCartesianInterface

给笛卡尔位姿指令并读取整个机器人状态

franka_hw::FrankaVelocityCartesianInterface

给笛卡尔速度指令并读取整个机器人状态

franka_hw::FrankaModelInterface

读取机器人的动力学和运动学模型

要使用 ROS control 控制接口,必须通过名称检索资源句柄:

接口

资源句柄名称

hardware_interface::JointStateInterface

“<arm_id>_joint1” 到 “<arm_id>_joint7”

hardware_interface::VelocityJointInterface

“<arm_id>_joint1” 到 “<arm_id>_joint7”

hardware_interface::PositionJointInterface

“<arm_id>_joint1” 到 “<arm_id>_joint7”

hardware_interface::EffortJointInterface

“<arm_id>_joint1” 到 “<arm_id>_joint7”

franka_hw::FrankaStateInterface

“<arm_id>_robot”

franka_hw::FrankaPoseCartesianInterface

“<arm_id>_robot”

franka_hw::FrankaVelocityCartesianInterface

“<arm_id>_robot”

franka_hw::FrankaModelInterface

“<arm_id>_robot”

提示

默认情况下, <arm_id> 被设置为 “panda”.

franka_hw::FrankaHW 类还实现了控制器的启动、停止和切换。

FrankaHW 类还用作 FrankaCombinableHW 的基类,FrankaCombinableHW 是一个硬件类,可以与其他类结合以从单个控制器控制多个机器人。由任意数量的,基于为 ROS control 框架 https://github.com/ros-controls/ros_control 设计的 FrankaCombinableHW 类的 Panda 机器人的组合(数量由参数配置),在 FrankaCombinedHW 类中得到实现。 FrankaHWFrankaCombinedHW 之间的主要区别在于后者仅支持扭矩控制。

重要

FrankaCombinableHW 类从 0.7.0 版开始提供,仅允许扭矩控制。

ROS 参数服务器用于在运行时确定在组合类中加载了哪些机器人。有关如何在相应硬件节点中配置 FrankaCombinedHW 的示例,请参阅 franka_control

备注

FrankaHW 的方法最适合控制单个机器人。因此,我们建议仅将 FrankaCombinableHW/FrankaCombinedHW 类用于控制多个机器人。

FrankaCombinableHW/FrankaCombinedHW 类提供的接口如下:

接口

功能

hardware_interface::EffortJointInterface

给关节级扭矩指令并读取关节状态。

hardware_interface::JointStateInterface

读取关节状态

franka_hw::FrankaStateInterface

读取整个机器人状态

franka_hw::FrankaModelInterface

读取机器人的动力学和运动学模型

唯一可接受的命令接口声明是 EffortJointInterface,它可以与任何一组只读接口(FrankaModelInterfaceJointStateInterfaceFrankaStateInterface)结合使用。所有接口提供的资源句柄均按名称声明,并遵循与 FrankaHW 所述相同的命名约定。FrankaCombinableHW 的每个实例都提供完整的 service 和 action 接口集(请参阅 franka_control )。

备注

FrankaCombinedHW 类在控制节点命名空间中提供了一个额外的动作服务器来恢复所有机器人。如果任何一个机器人发生反射 reflex 或错误 error,所有机器人的控制回路都会停止,直到它们恢复。

重要

FrankaHW 利用 ROS joint_limits_interface执行位置、速度和力度的安全限制。下面列出了使用的接口:

  • joint_limits_interface::PositionJointSoftLimitsInterface

  • joint_limits_interface::VelocityJointSoftLimitsInterface

  • joint_limits_interface::EffortJointSoftLimitsInterface

接近极限将导致(未经宣布的)修改命令。

franka_control

ROS 节点 franka_control_nodefranka_combined_control_node 是用于 ROS control 的硬件节点,它们使用 franka_hw 中的相应硬件类。他们提供了各种 ROS 服务,以在 ROS 生态系统中公开完整的 libfranka API。它提供以下服务:

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

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

  • franka_msgs::SetEEFrame 指定从 <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::SetKFrame 指定从 <arm_id>_K 到 <arm_id>_EE 坐标系的变换。

  • franka_msgs::SetForceTorqueCollisionBehavior 为外部笛卡尔力旋量设置阈值以配置碰撞反射。

  • franka_msgs::SetFullCollisionBehavior 在笛卡尔和关节层级上设置外力阈值以配置碰撞反射。

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

  • std_srvs::Trigger 服务允许连接和断开硬件节点(从 0.8.0 开始可用)。当没有活动(命令)控制器在运行时,可以断开硬件节点,为非 fci 应用程序释放相应的机器人,例如基于 Desk 桌面的操作。一旦想恢复 fci 操作,可以调用 connect 并再次启动基于 ros_control 的控制器

重要

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

_images/frames.svg

末端执行器坐标系概览。

要在机器人处于反射模式时从错误和反射中恢复,可以使用 Franka_msgs::ErrorRecoveryAction。这可以通过 action 客户端或通过在 action 目标主题上发布来实现。

rostopic pub -1 /franka_control/error_recovery/goal franka_msgs/ErrorRecoveryActionGoal "{}"

恢复后,franka_control_node 重新启动正在运行的控制器。这是可能的,因为当触发机器人反射或发生错误时,节点不会死亡。所有这些功能都由 franka_control_node 提供,其可以使用以下命令启动:

roslaunch franka_control franka_control.launch 
robot_ip:=<fci-ip> # mandatory 
load_gripper:=<true|false> # default: true 
robot:=<panda|fr3> # default: panda

除了加载 franka_control_node 之外,launch 文件还会启动 franka_control::FrankaStateController 来读取和发布机器人状态,包括外部力旋量、可配置的变换和使用 rivz 进行可视化所需的关节状态。出于可视化目的,一个 robot_state_publisher 节点已启动。

这个包还实现了 franka_combined_control_node,一个基于 franka_hw::FrankaCombinedHW 类的 ros_control 的硬件节点。加载的机器人组是通过 ROS 参数服务器配置的。这些参数必须在硬件节点的命名空间中(参见 franka_combined_control_node.yaml 作为参考),如下所示:

robot_hardware:
  - panda_1
  - panda_2
  # (...)
panda_1:
  type: franka_hw/FrankaCombinableHW
  arm_id: panda_1
  joint_names:
    - panda_1_joint1
    - panda_1_joint2
    - panda_1_joint3
    - panda_1_joint4
    - panda_1_joint5
    - panda_1_joint6
    - panda_1_joint7
  # Configure the threshold angle for printing joint limit warnings.
  joint_limit_warning_threshold: 0.1 # [rad]
  # Activate rate limiter? [true|false]
  rate_limiting: true
  # Cutoff frequency of the low-pass filter. Set to >= 1000 to deactivate.
  cutoff_frequency: 1000
  # Internal controller for motion generators [joint_impedance|cartesian_impedance]
  internal_controller: joint_impedance
  # Configure the initial defaults for the collision behavior reflexes.
  collision_config:
    lower_torque_thresholds_acceleration: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    upper_torque_thresholds_acceleration: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    lower_torque_thresholds_nominal: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    upper_torque_thresholds_nominal: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    lower_force_thresholds_acceleration: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    upper_force_thresholds_acceleration: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    lower_force_thresholds_nominal: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    upper_force_thresholds_nominal: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
panda_2:
  type: franka_hw/FrankaCombinableHW
  arm_id: panda_2
  joint_names:
    - panda_2_joint1
    - panda_2_joint2
    - panda_2_joint3
    - panda_2_joint4
    - panda_2_joint5
    - panda_2_joint6
    - panda_2_joint7
  # Configure the threshold angle for printing joint limit warnings.
  joint_limit_warning_threshold: 0.1 # [rad]
  # Activate rate limiter? [true|false]
  rate_limiting: true
  # Cutoff frequency of the low-pass filter. Set to >= 1000 to deactivate.
  cutoff_frequency: 1000
  # Internal controller for motion generators [joint_impedance|cartesian_impedance]
  internal_controller: joint_impedance
  # Configure the initial defaults for the collision behavior reflexes.
  collision_config:
    lower_torque_thresholds_acceleration: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    upper_torque_thresholds_acceleration: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    lower_torque_thresholds_nominal: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    upper_torque_thresholds_nominal: [20.0, 20.0, 18.0, 18.0, 16.0, 14.0, 12.0]  # [Nm]
    lower_force_thresholds_acceleration: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    upper_force_thresholds_acceleration: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    lower_force_thresholds_nominal: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
    upper_force_thresholds_nominal: [20.0, 20.0, 20.0, 25.0, 25.0, 25.0]  # [N, N, N, Nm, Nm, Nm]
# (+ more robots ...)

备注

请务必选择唯一且一致的 arm_id 参数。 ID 必须与关节名称中的前缀匹配,并且应该根据加载到控制节点命名空间的机器人描述。

关于基于参数加载硬件类的更多信息,请参考 https://github.com/ros-controls/ros_controlcombined_robot_hw::CombinedRobotHW 的官方文档。

第二个重要的参数文件(参见 franka_ros/franka_control/config/default_combined_controllers.yaml作为参考)配置了一组默认控制器,可以通过硬件节点启动。控制器必须与启动的硬件相匹配。提供的默认参数化(此处为 2 个机器人)如下所示:

panda_1_state_controller:
  type: franka_control/FrankaStateController
  arm_id: panda_1
  joint_names:
    - panda_1_joint1
    - panda_1_joint2
    - panda_1_joint3
    - panda_1_joint4
    - panda_1_joint5
    - panda_1_joint6
    - panda_1_joint7
  publish_rate: 30  # [Hz]
panda_2_state_controller:
  type: franka_control/FrankaStateController
  arm_id: panda_2
  joint_names:
    - panda_2_joint1
    - panda_2_joint2
    - panda_2_joint3
    - panda_2_joint4
    - panda_2_joint5
    - panda_2_joint6
    - panda_2_joint7
  publish_rate: 30  # [Hz]
# (+ more controllers ...)

我们提供了一个 launch 启动文件来运行 franka_combined_control_node,其中包含用户指定的硬件和控制器配置文件,默认配置为 2 个机器人。用以下命令启动它:

roslaunch franka_control franka_combined_control.launch 
    robot_ips:=<your_robot_ips_as_a_map>                 # mandatory
    robot:=<path_to_your_robot_description> 
    args:=<xacro_args_passed_to_the_robot_description>  # if needed
    robot_id:=<name_of_your_multi_robot_setup> 
    hw_config_file:=<path_to_your_hw_config_file>       # includes the robot ips!
    controllers_file:=<path_to_your_default_controller_parameterization>
    controllers_to_start:=<list_of_default_controllers_to_start>
    joint_states_source_list:=<list_of_sources_to_fuse_a_complete_joint_states_topic>

这个 launch 启动文件可以被参数化以运行任意数量的机器人。为此,只需以 franka_control/config/franka_combined_control_node.yaml 和 franka_ros/franka_control/config/default_combined_controllers.yaml 的样式编写自己的配置文件。

重要

请务必将机器人的正确 IP 作为映射传递给franka_combined_control.launch。这看起来像:{<arm_id_1>/robot_ip: <my_ip_1>, <arm_id_2>/robot_ip: <my_ip_2>, …}

franka_visualization

该包包含连接到机器人并发布机器人和夹爪关节状态以在 RViz 中进行可视化的发布者。要运行此包启动:

roslaunch franka_visualization franka_visualization.launch robot_ip:=<fci-ip>   
load_gripper:=<true|false> robot:=<panda|fr3>

这纯粹是为了可视化 - 没有向机器人发送命令。它对检查与机器人的连接情况很有用。

重要

只有一个 franka::Robot 实例可以连接到机器人。这意味着,例如 franka_joint_state_publisher 不能与 franka_control_node 并行运行。这也意味着不能在运行控制器的单独程序时同时执行可视化示例。


franka_example_controllers

在这个包中,实现了一组用于通过 ROS 控制机器人的示例控制器。控制器描述了 franka_hw::FrankaHW 类提供的各种接口以及相应的用法。每个示例都带有一个独立的启动文件,用于启动机器人上的控制器并对其进行可视化。

要启动关节阻抗示例,请执行以下命令:

roslaunch franka_example_controllers joint_impedance_example_controller.launch   
robot_ip:=<fci-ip> load_gripper:=<true|false> robot:=<panda|fr3>

其他单个 Panda 示例以相同方式启动。

dual_arm_cartesian_impedance_example_controller 展示了对两个基于 FrankaCombinedHW 类的 Panda 机器人的控制,使用一个实时控制器通过基于阻抗的控制方法完成笛卡尔任务。示例控制器能以以下命令启动

roslaunch franka_example_controllers     
    dual_arm_cartesian_impedance_example_controller.launch     
    robot_id:=<name_of_the_2_arm_setup>     
    robot_ips:=<your_robot_ips_as_a_map>     
    rviz:=<true/false> rqt:=<true/false>

该示例假设机器人配置符合dual_panda_example.urdf.xacro,其中两个 Panda 以 1 米的距离安装在一个盒子顶部。随意用与实际设置相匹配的描述替换此机器人描述。rviz选项允许选择是否应启动可视化。使用rqt,用户可以选择启动 rqt-gui,它允许在运行时通过动态参数重新调整来在线适配渲染的末端效应器阻抗。

franka_gazebo

该包允许在 Gazebo 中仿真我们的机器人。这是可能的,因为 Gazebo 能够通过 gazebo_ros 包集成到 ROS control 框架中。

重要

该包从 0.8.0 开始提供


拾放示例

让我们深入研究并仿真将石头从 A 运输到 B。运行以下命令以启动伴有 Panda 和示例 world 的 Gazebo。

roslaunch franka_gazebo panda.launch x:=-0.5     
world:=$(rospack find franka_gazebo)/world/stone.sdf     
controller:=cartesian_impedance_example_controller     
rviz:=true

这将打开 Gazebo GUI,可以在其中看到带有石头和 RViz 的环境,可以用它来控制机器人的末端执行器位姿。

_images/franka-gazebo-example.png

取放示例的 Gazebo GUI(左)和 RViz(右)

要打开夹爪,只需向 move action 发送一个目标,类似于真正的 franka_gripper 的工作方式。让我们将夹爪以 10cms 移动到手指之间的宽度为 8cm:

rostopic pub --once /franka_gripper/move/goal franka_gripper/MoveActionGoal "goal: { width: 0.08, speed: 0.1 }"

由于我们使用 franka_example_controllers 的笛卡尔阻抗控制器启动了我们的机器人,因此可以使用 RViz 中的交互式标记 Gizmo 移动末端执行器,就像在现实中一样。移动机器人,使白色石头位于夹爪的手指之间,准备好被捡起。

备注

如果机器人的肘部移动很奇怪,这是因为笛卡尔阻抗示例控制器的默认零空间刚度设置为低。如有必要,启动 Dynamic Reconfigure 并调整 panda > cartesian_impedance_example_controller > nullspace_stiffness

为了拾取物体,这次我们使用 grasp action,因为我们想在抓握后施加一个力,使物体不掉落。石头宽约 3cm,重 50g 。让我们用 5N 来抓取它:

rostopic pub --once /franka_gripper/grasp/goal 
             franka_gripper/GraspActionGoal 
                          "goal: { width: 0.03, epsilon:{ inner: 0.005, outer: 0.005 }, speed: 0.1, force: 5.0}"

备注

在 Gazebo 的顶部菜单中,转到 View > Contacts 以可视化接触点和力

如果抓取成功,手指现在将把石头固定到位。如果不是,则可能是目标公差(内部和外部 epsilon)太小并且 action 失败。现在将物体轻轻地移到红色的落点区域。

_images/franka-gazebo-example-grasp.png

把石头从蓝色运到红色区域

将其轻轻放在红色垫子上后,通过夹爪的 stop action 停止抓握:

rostopic pub --once /franka_gripper/stop/goal franka_gripper/StopActionGoal {}

请注意,接触力现在消失了,因为不再施加力了。或者,也可以使用 move action。

定制化

franka_gazebo 的启动文件包含许多参数,可以使用这些参数自定义仿真的行为。例如,要在一次仿真中生成两只 panda 臂,可以使用以下命令:

<?xml version="1.0"?>
<launch>
  <include file="$(find gazebo_ros)/launch/empty_world.launch" >
    <!-- Start paused, simulation will be started, when Pandas were loaded -->
    <arg name="paused" value="true"/>
    <arg name="use_sim_time" value="true"/>
  </include>
  <group ns="panda_1">
    <include file="$(find franka_gazebo)/launch/panda.launch">
      <arg name="arm_id"     value="panda_1" />
      <arg name="y"          value="-0.5" />
      <arg name="controller" value="cartesian_impedance_example_controller" />
      <arg name="rviz"       value="false" />
      <arg name="gazebo"     value="false" />
      <arg name="paused"     value="true" />
    </include>
  </group>
  <group ns="panda_2">
    <include file="$(find franka_gazebo)/launch/panda.launch">
      <arg name="arm_id"     value="panda_2" />
      <arg name="y"          value="0.5" />
      <arg name="controller" value="force_example_controller" />
      <arg name="rviz"       value="false" />
      <arg name="gazebo"     value="false" />
      <arg name="paused"     value="false" />
    </include>
  </group>
</launch>

备注

要查看支持哪些参数,请使用: roslaunch franka_gazebo panda.launch --ros-args

FrankaHWSim

默认情况下,Gazebo ROS 只能仿真具有 “标准” 硬件接口的关节,如关节状态接口Joint State Interfaces和关节命令接口Joint Command Interfaces。然而,我们的机器人与这种架构完全不同!除了这些特定于关节的接口之外,它还支持 特定于机器人 的接口,如 FrankaModelInterface (参见 franka_hw)。自然 gazebo 默认不理解这些自定义硬件接口。这就是 FrankaHWSim 插件的作用。

为了让机器人能够支持 Franka 接口,只需在 URDF 中声明一个自定义的 robotsSimType

<gazebo>
  <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
    <robotNamespace>${arm_id}</robotNamespace>
    <controlPeriod>0.001</controlPeriod>
    <robotSimType>franka_gazebo/FrankaHWSim</robotSimType>
  </plugin>
  <self_collide>true</self_collide>
</gazebo>

当使用 模型生成器 生成此机器人时,此插件将加载到 gazebo 节点中。它将扫描 URDF 并尝试查找支持的硬件接口。目前只支持 franka_hw 提供的部分接口:


接口

功能

hardware_interface::JointStateInterface

读取关节状态

hardware_interface::EffortJointInterface

给关节级扭矩指令并读取关节状态。

hardware_interface::VelocityJointInterface

给关节速度指令并读取关节状态。

hardware_interface::PositionJointInterface

给关节角度指令并读取关节状态。

franka_hw::FrankaStateInterface

读取整个机器人状态

franka_hw::FrankaModelInterface

读取机器人的动力学和运动学模型

franka_hw::FrankaPoseCartesianInterface

给笛卡尔位姿指令并读取整个机器人状态

franka_hw::FrankaVelocityCartesianInterface

给笛卡尔速度指令并读取整个机器人状态

重要

这意味着只能仿真那些要求这些支持的接口的控制器,而不是其他的!例如,笛卡尔阻抗示例控制器可以被仿真,因为它只需要 EffortJoint-、FrankaState- 和 FrankaModelInterface。然而,关节阻抗示例控制器不能被仿真,因为它需要尚不支持的 FrankaPoseCartesianInterface

除了实时硬件接口外,FrankaHWSim 插件支持 franka_control 支持的一些非实时命令:


服务 / 类型

解释

set_joint_impedance /SetJointImpedance

Gazebo 不仿真内部阻抗控制器,而是直接设置扭矩命令

set_cartesian_impedance /SetCartesianImpedance

Gazebo 不仿真内部阻抗控制器,而是直接设置扭矩命令

set_EE_frame /SetEEFrame

设置 NETEE,即从标称末端效应器到末端效应器的齐次变换。也可以通过设置 ROS 参数 /<arm_id>/NE_T_EE 来初始化它。通常会在 Desk 中设置 FTNE,但在 franka_gazebo 中,如果没有指定夹爪或定义围绕 Z 旋转 45° 和偏移 10.34cm (与抓手的 Desk 所示相同),则假定为与 Desk 中相同。始终可以通过手动设置 ROS 参数 /<arm_id>/NE_T_EE 来覆盖此值。

set_K_frame /SetKFrame

设置 EETK,即从末端执行器到刚度坐标系的齐次变换。

set_force_torque_collision_behavior /SetForceTorqueCollisionBehavior

设置阈值,高于该阈值外部力旋量被视为接触和碰撞。

set_full_collision_behavior /SetFullCollisionBehavior

尚未实现

set_load /SetLoad

设置外部负载以补偿其重力,例如抓取的物体。还可以通过分别设置对应质量、惯性张量和负载质心的 ROS 参数 /<arm_id>/{m_load,I_load,F_x_load} 来初始化它。

set_user_stop /std_srvs::SetBool(since 0.9.1)

这是一项仅在 franka_gazebo 中可用的特殊服务,用于仿真用户停止。按下用户停止(也就是通过此服务发布一个 true)将断开 disconnect 来自 ROS 控制器的馈送到关节的所有命令信号。要再次连接它们,请调用 error_recovery action。


FrankaGripperSim

这个插件仿真 Gazebo 中的 franka_gripper_node。这是为两个手指关节做的 ROS 控制器,带有位置和力控制器。它提供了与真正的夹爪节点相同的五个动作 action:

  • /<arm_id>/franka_gripper/homing

  • /<arm_id>/franka_gripper/stop

  • /<arm_id>/franka_gripper/move

  • /<arm_id>/franka_gripper/grasp

  • /<arm_id>/franka_gripper/gripper_action

重要

grasp action 有一个bug,如果让手指 open 到目标宽度,它既不会成功也不会中止。这是因为缺少关节限制接口,这让手指在其极限处摆动。现在只使用 grasp action 来 close 手指!

假设 URDF 包含两个可以力控制的手指关节,即有一个相应的 EffortJointInterface 传动声明。该控制器在其命名空间中需要以下参数:

  • type (string, required):应该是 franka_gazebo/FrankaGripperSim

  • arm_id (string, required):panda 的手臂 id,以推断出手指关节的名称

  • finger1/gains/p (double, required): 第一指位置-力控制器的比例增益

  • finger1/gains/i (double, default: 0): 第一指位置-力控制器的积分增益

  • finger1/gains/d (double, default: 0):第一指位置-力控制器的微分增益

  • finger2/gains/p (double, required): 第二指位置-力控制器的比例增益

  • finger2/gains/i (double, default: 0): 第二指位置-力控制器的积分增益

  • finger2/gains/d (double, default: 0): 第二指位置-力控制器的微分增益

  • move/width_tolerance (double, default 5mm): 当手指宽度低于此阈值时,move action 成功

  • grasp/resting_threshold (double, default 1mms): 低于该速度应检查目标宽度以中止或成功 grasp action

  • grasp/consecutive_samples (double, default: 3): 速度要连续低于阈值 resting_threshold 多少次才会被评估为抓取

  • gripper_action/width_tolerance (double, default 5mm): 当手指宽度低于此阈值时,夹爪 action 就(被认为)成功

  • gripper_action/speed (double, default 10cms): 在夹爪 action 中使用的速度

JointStateInterface

为了能够从 ROS 控制器访问关节状态接口,只需在 URDF 的任何传动标签中声明相应的关节。然后一个关节状态接口将自动可用。通常,为 EffortJointInterface 等命令接口声明传动标签。

备注

对于任何名为 <arm_id>_jointN (N 为整数)的关节,FrankaHWSim 将自动补偿其重力以模仿 libfranka 的行为。


EffortJointInterface

为了能够从控制器向一个关节发送扭矩命令,只需在 URDF 中为关节声明一个具有相应硬件接口类型的传动标签。

<transmission name="${joint}_transmission">
 <type>transmission_interface/SimpleTransmission</type>
 <joint name="${joint}">
   <hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
 </joint>
 <actuator name="${joint}_motor">
   <hardwareInterface>${transmission}</hardwareInterface>
 </actuator>
</transmission>
<gazebo reference="${joint}">
  <!-- Needed for ODE to output external wrenches on joints -->
  <provideFeedback>true</provideFeedback>
</gazebo>

备注

如果希望能够读取外力或扭矩,例如从碰撞中,确保将 <provideFeedback> 标记设置为 true

FrankaStateInterface

这是一个 机器人专用 接口,因此与普通硬件接口略有不同。为了能够从控制器访问 franka 状态接口,请在 URDF 中声明以下带有所有七个关节的传动标签:

<transmission name="${arm_id}_franka_state">
  <type>franka_hw/FrankaStateInterface</type>
  <joint name="${arm_id}_joint1"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint>
  <joint name="${arm_id}_joint2"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint>
  <joint name="${arm_id}_joint3"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint>
  <joint name="${arm_id}_joint4"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint>
  <joint name="${arm_id}_joint5"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint>
  <joint name="${arm_id}_joint6"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint>
  <joint name="${arm_id}_joint7"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></joint>
  <actuator name="${arm_id}_motor1"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator>
  <actuator name="${arm_id}_motor2"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator>
  <actuator name="${arm_id}_motor3"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator>
  <actuator name="${arm_id}_motor4"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator>
  <actuator name="${arm_id}_motor5"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator>
  <actuator name="${arm_id}_motor6"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator>
  <actuator name="${arm_id}_motor7"><hardwareInterface>franka_hw/FrankaStateInterface</hardwareInterface></actuator>
</transmission>

当您的控制器通过 FrankaStateInterface 访问 机器人状态 RobotState  时,它可以期望仿真出以下值:


区域

注释

O_T_EE


O_T_EE_d

尚不支持运动生成,字段将仅包含零

F_T_EE

可以通过参数 F_T_NENE_T_EE 和/或对 set_EE_frame 的服务调用进行配置

NE_T_EE

可以通过参数 EE_T_EE 和/或对 setEE_frame 的服务调用进行配置

EE_T_K

可以通过参数 EE_T_K 和/或对 set_K_frame 的服务调用进行配置

m_ee

如果可以找到抓手,将可以从 URDF 惯性标签中的质量来设置,否则为零。可以被参数 m_ee 覆盖

I_ee

如果可以找到抓手,将可以从 URDF 惯性标签中的惯量来设置,否则为零。可以被参数 I_ee 覆盖

F_x_Cee

如果可以找到抓手,将可以从 URDF 的惯性标签中的原点来设置,否则为零。可以被参数 F_x_Cee 覆盖

m_load

可以通过参数 m_load 和/或对 set_load 的服务调用进行配置

I_load

可以通过参数 I_load 和/或对 set_load 的服务调用进行配置

F_x_Cload

可以通过参数 F_x_Cload 和/或对 set_load 的服务调用进行配置

m_total


I_total


F_x_Ctotal


elbow


elbow_d


elbow_c


delbow_d


delbow_c


tau_J

直接来自 Gazebo

tau_J_d

扭矩控制器发送的值,否则为0

dtau_J

tau_J 的数值导数

q

直接来自 Gazebo

q_d

使用位置接口时的最后一个命令关节位置。当使用速度接口时与 q 相同。但是,使用扭矩接口时,该值不会更新。

dq

直接来自 Gazebo

dq_d

使用速度接口时的最后命令关节速度。当使用位置接口时与 dq 相同。但是,当使用扭矩接口时,该值将为零。

ddq_d

使用位置或速度接口时的当前加速度。但是,当使用扭矩接口时,该值将为零。

joint_contact

τ^ext∣>threslower 其中可以通过调用 set_force_torque_collision_behavior 设置阈值

joint_collision

τ^ext∣>thresupper 其中可以通过调用 set_force_torque_collision_behavior 设置阈值

cartesian_contact

KF^K,ext∣>threslower 其中可以通过调用 set_force_torque_collision_behavior 来设置阈值

cartesian_collision

KF^K,ext∣>thresupper 其中可以通过调用 set_force_torque_collision_behavior 来设置阈值

tau_ext_hat_filtered

τ^ext 即估计的末端执行器的外部扭矩和力,用指数移动平均滤波器 (EMA) 过滤。其过滤的 α 可以通过 ROS 参数进行配置。该字段不包含任何重力项,即 τext=τJτJdτgravity

O_F_ext_hat_K

OF^K,ext=JO+τ^ext

K_F_ext_hat_K

KF^K,ext=JK+τ^ext

O_dP_EE_d


ddq_d

将与 gravity_vector ROS 参数相同。默认为 {0,0,-9.8}

O_T_EE_c


O_dP_EE_c


O_ddP_EE_c


theta

q 相同,因为我们不在 Gazebo 中仿真软关节

dtheta

dq 相同,因为我们不在 Gazebo 中仿真软关节

current_errors

完全是假的,反射系统尚未实现

last_motion_errors

完全是假的,反射系统尚未实现

control_command_success_rate

总是 1.0

robot_mode

机器人模式切换和反射系统尚未实现

time

仿真中的当前 ROS 时间,来自 Gazebo

FrankaModelInterface

这是一个机器人专用 robot-specific 接口,因此与普通硬件接口略有不同。为了能够从控制器访问 franka 模型接口,请在 URDF 中声明以下带有传动链的根部(例如 panda_joint1)和尖端(例如 panda_joint8)的传动标签:

<transmission name="${arm_id}_franka_model">
  <type>franka_hw/FrankaModelInterface</type>
  <joint name="${root}">
    <role>root</role>
    <hardwareInterface>franka_hw/FrankaModelInterface</hardwareInterface>
  </joint>
  <joint name="${tip}">
    <role>tip</role>
    <hardwareInterface>franka_hw/FrankaModelInterface</hardwareInterface>
  </joint>
  <actuator name="${root}_motor_root"><hardwareInterface>franka_hw/FrankaModelInterface</hardwareInterface></actuator>
  <actuator name="${tip}_motor_tip"  ><hardwareInterface>franka_hw/FrankaModelInterface</hardwareInterface></actuator>
</transmission>

模型函数本身是用 KDL 实现的。这从 URDF 中获取运动学结构和惯性属性来计算模型属性,如雅可比矩阵或质量矩阵。


摩擦

为了使对象(例如手指和对象)之间具有适当的摩擦力,需要在 URDF 中调整一些 Gazebo 参数。对于关节 panda_finger_joint1panda_finger_joint2 我们建议设置以下参数:

<gazebo reference="${link}">
  <collision>
    <max_contacts>10</max_contacts>
    <surface>
      <contact>
        <ode>
          <!-- These two parameter need application specific tuning. -->
          <!-- Usually you want no "snap out" velocity and a generous -->
          <!-- penetration depth to keep the grasping stable -->
          <max_vel>0</max_vel>
          <min_depth>0.003</min_depth>
        </ode>
      </contact>
      <friction>
        <ode>
          <!-- Rubber/Rubber contact -->
          <mu>1.16</mu>
          <mu2>1.16</mu2>
        </ode>
      </friction>
      <bounce/>
    </surface>
  </collision>
</gazebo>

备注

请参阅 Gazebo Friction 文档

franka_msgs

该包包含消息、服务和动作类型,主要用于包 franka_hwfranka_control 来发布机器人状态或在 ROS 生态系统中公开 libfranka API。有关此包中提供的服务和动作的更多信息,请参阅 franka_control


panda_moveit_config

备注

此包已移至存储库 ros_planning

有关更多详细信息、文档和教程,请查看 MoveIt!教程网站

编写自己的控制器

示例控制器包 中的所有示例控制器都派生自 controller_interface::MultiInterfaceController 类,该类允许在一个控制器实例中声明多达四个接口。类的声明看起来如下所示:

class NameOfYourControllerClass : controller_interface::MultiInterfaceController <
                              my_mandatory_first_interface,
                              my_possible_second_interface,
                              my_possible_third_interface,
                              my_possible_fourth_interface> {
  bool init (hardware_interface::RobotHW* hw, ros::NodeHandle& nh);  // mandatory
  void update (const ros::Time& time, const ros::Duration& period);  // mandatory
  void starting (const ros::Time& time)   // optional
  void stopping (const ros::Time& time);  // optional
  ...
}

franka_hw 小节描述了可用的接口。

重要

请注意,命令接口的可声明组合受到限制,因为例如同时命令关节位置和笛卡尔位姿等没有意义。只读接口,如 JointStateInterfaceFrankaStateInterfaceFrankaModelInterface 始终可以声明并且不受限制。

命令接口的可能声明是:

franka_hw::FrankaHW

franka_combinable_hw::FrankaCombinableHW

  • 所有可能的单一接口声明

  • EffortJointInterface +PositionJointInterface

  • EffortJointInterface +VelocityJointInterface

  • EffortJointInterface +FrankaCartesianPoseInterface

  • EffortJointInterface +FrankaCartesianVelocityInterface

  • EffortJointInterface

  • EffortJointInterface +FrankaCartesianPoseInterface

  • EffortJointInterface +FrankaCartesianVelocityInterface

结合运动生成器接口提供 EffortJointInterface 背后的想法是向用户公开内部运动生成器。计算出的与运动生成器命令相对应的期望关节位姿在一个时间步后的机器人状态中可用。这种组合的一个用例是使用自己的关节层级扭矩控制器跟随笛卡尔轨迹。在这种情况下,将声明 EffortJointInterface + FrankaCartesianPoseInterface 的组合,将轨迹传输到 FrankaCartesianPoseInterface,并根据从机器人状态得到的期望关节位姿 (q_d) 计算关节层级扭矩命令。这允许使用机器人的内置逆运动学,而不必自己解决。

要实现功能齐全的控制器,必须至少实现继承的虚函数 initupdate。初始化 - 例如启动位姿 - 应该在 starting 函数中完成,因为在重新启动控制器时会调用 starting,而在加载控制器时只调用一次 initstopping 方法应包含与关闭相关的功能(如果需要)。

重要

在关闭控制器之前,始终给命令来温和地减速。使用速度接口时,不要在 stopping 时简单地命令速度为零。因为它可能在机器人仍在移动时被调用,所以它相当于命令速度跳跃导致非常高的关节层级扭矩。在这种情况下,保持相同的速度并停止控制器,比发送零值并让机器人处理减速更好。

控制器类必须通过 pluginlib 正确导出,这需要添加:

#include <pluginlib/class_list_macros.h>
// Implementation ..
PLUGINLIB_EXPORT_CLASS(name_of_your_controller_package::NameOfYourControllerClass,
                       controller_interface::ControllerBase)

.cpp 文件的末尾。此外,需要定义一个包含以下内容的 plugin.xml 文件:

<library path="lib/lib<name_of_your_controller_library>">
  <class name="name_of_your_controller_package/NameOfYourControllerClass"
         type="name_of_your_controller_package::NameOfYourControllerClass"
         base_class_type="controller_interface::ControllerBase">
    <description>
      Some text to describe what your controller is doing
    </description>
  </class>
</library>

通过添加导出:

<export>
  <controller_interface plugin="${prefix}/plugin.xml"/>
</export>

到 package.xml。此外,需要至少将控制器名称与控制器类型结合加载到 ROS 参数服务器。此外,可以包括需要的其他参数。一个示例 configuration.yaml 文件可能看起来如下所示:

your_custom_controller_name:
  type: name_of_your_controller_package/NameOfYourControllerClass
  additional_example_parameter: 0.0
  # ..

现在,可以使用 ROS control 中的 controller_spawner 节点或通过 hardware_manager 提供的服务调用来启动控制器。只要确保 controller_spawnerfranka_control_node 在同一个命名空间中运行。有关更多详细信息,请查看 franka_example_controllers package 包或 ROS control 教程

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 软件包之间的通信接口保持一致。

Franka Toolbox for MATLAB

版本兼容

系统要求

安装

入门指南

Franka Simulink 库-参考

Franka MATLAB 库-参考

故障排除

Franka Toolbox for MATLAB 更新日志

3.0.0 (16-05-2025)

2.0.0 (20-11-2024)

1.0.0 (11-03-2024)

0.3.1 (23-03-2023)

0.3.0 (20-09-2022)

0.2.1 (29-04-2022)

0.2.0 (31-05-2021)

0.1.1 (01-07-2020)

0.1.0 (21-01-2020)

机器人与接口规范

FR3 认证备注

恭喜您获得了全新的 Franka Research 3。作为包装的一部分,您应该收到了包括 产品手册-Franka Production 3 (110010/1.5/EN) 在内的文档。 尽管它的标题表明它适用于另一款 Franka 机械臂 - FP3,但它通常也适用于 Franka Research 3。我们建议在使用机器人之前阅读本产品手册。 请注意,特别是在使用 FCI 和 研究应用中的一般用例时, 可能与本手册有一些偏差。因此,请查阅下表,其中说明了适用性,并查阅参考文档,如数据表。

章节

内容

适用于 FR3

注解

1

关于 Franka Robotics

完全适用

2

使用权和财产权

完全适用

2.1

总则

完全适用

2.2

标识

完全适用

3

公司声明和证书

3.1

公司声明

不适用

根据第 1 条第 2(h) 款,研究用途不在该范围内

3.2

证书

完全适用

3.3

进一步声明

不适用

由于预期的用途,部分适用于 RoHS 指令 2011/65/EU 第 2 条第 4(j) 款。有关电池指令的内容完全适用。

3.4

设备上的标签

完全适用

4

安全

4.1

安全指示和一般提示

完全适用

4.2

法律责任通知

完全适用

4.3

预期用途

根据备注完全适用

随着研究应用的扩展

4.4

误用

完全适用

4.5

操作机器人时可能存在的一般危险和安全措施

完全适用

4.6

与应用相关的可能存在的危险和安全措施

完全适用

4.7

安全外围设备安装

完全适用

4.8

故障保护锁止系统

完全适用

4.9

手动移动臂架

完全适用

4.10

安全理念

完全适用

4.11

安全功能

对于 FCI 使用有限制

如数据手册 Franka Research 3 (120020) 中所述

4.12

安全设置和 Watchman

完全适用

5

角色和人物

完全适用

6

交付范围和配件

完全适用

6.1

设备概述

完全适用

6.2

交付范围和附加设备

根据备注完全适用

如 FCI 参考单(120070) 中提到的那样

6.3

可用备件和附件

完全适用

7

技术规格

部分适用

数据表由 Franka Research 3 数据表取代 - 安全声明仍然有效

8

运输和装卸

完全适用

8.1

交付及运输的环境条件

完全适用

9

固定和安装

完全适用

9.1

拆开设备包装

完全适用

9.2

正确的安装场所

完全适用

9.3

准备安装场所

完全适用

9.4

安装臂架

完全适用

9.5

放置控制器

完全适用

9.6

布线和电气安装

完全适用

9.7

安装末端执行器

完全适用

9.8

Franka Production 3 的使用与放置实用提示

完全适用

9.9

臂架重新包装

完全适用

10

操作

根据备注完全适用

如 FCI 文档所述

10.1

开启

完全适用

10.2

Franka Production 3 安全相关测试

根据备注完全适用

如 FCI 文档所述

10.3

连接用户接口设备

完全适用

10.4

软件设定

根据备注完全适用

如 FCI 文档所述

10.5

关机和重启

完全适用

11

与 FRANKA PRODUCTION 3 一起工作

根据备注完全适用

如 FCI 文档所述

11.1

机器人基础知识

完全适用

11.2

Franka 用户界面

根据备注完全适用

如 FCI 文档所述

11.3

应用软件

完全适用

11.4

操作模式

根据备注完全适用

如 FCI 文档所述

11.5

单点控制

根据备注完全适用

如 FCI 文档所述

11.6

示教任务

完全适用

11.7

测试和点动

完全适用

11.8

工作

根据备注完全适用

如 FCI 文档所述

11.09

故障排除

根据备注完全适用

如 FCI 文档所述

12

管理 FRANKA PRODUCTION 3

完全适用

12.1

Franka World

完全适用

12.2

管理 App 和更新

完全适用

12.3

Hub(枢纽)

完全适用

12.4

更新

完全适用

13

保养和废置

完全适用

13.1

保养

完全适用

13.2

清洁

完全适用

13.3

系统寿命

完全适用

13.4

废置

完全适用

14

服务和支持

完全适用

15

附录

完全适用

15.1

制动时间和制动距离

完全适用

15.2

响应时间

完全适用

15.3

安全定位精度

完全适用

16

术语表

完全适用

17

索引

完全适用

故障排除


技术咨询

联系人:WANG CHAO

座机: +86 185 8843 3689

电话:+86 185 8843 3689


常见问题解答 (FAQ)

我们有一个由用户和开发人员组成的强大而活跃的社区,他们随时准备帮助您解决任何问题。

问题咨询:

联系人:WANG CHAO

座机: +86 185 8843 3689

电话:+86 185 8843 3689