Hadabot是软件工程师学习ROS2和机器人技术的机器人套件。我们距离Hadabot套件的测试版还有一周左右的时间。我们将在本文末尾披露有关如何注册的更多信息。
新的Hadabot套件完全支持ROS2。除了硬件套件外,Hadabot软件环境将主要基于Web浏览器,以最大程度地减少用户体验的跨平台差异。为了大大减少用户在设置和库管理方面的挫败感,我们使用 Docker 将 ROS2 系统创建为一堆 Docker 容器,从单个命令轻松启动。Docker还将帮助我们从您的主机系统对所有ROS2库进行沙盒处理,并使您的Hadabot可以从主机系统移植到主机系统。
在这篇文章中,我们将通过实施和学习我们的 Hadabot 的机器人里程计来开始深入研究机器人导航的概念,Hadabot 是一种差速器驱动机器人。我们将使用在Web浏览器中运行的Visual Studio Code(VSCode)将测程图编程为ROS2组件(即ROS2节点)。
由于整个ROS2系统,Hadabot模块,甚至VSCode都在Hadabot的Docker容器堆栈中运行,因此您无需设置或安装VSCode或ROS2。只需启动 Docker 堆栈并开始黑客攻击!
您 需要了解一些C++但您不需要物理 Hadabot 套件来跟随这篇文章。具体而言,我们将:
了解差速驱动机器人测程法。
了解 ROS 和 ROS2 如何处理计量数据。
设置基于哈达机器人浏览器的VSCode。
使用我们基于浏览器的 VSCode 编译和调试 ROS2 C++里程计节点。
了解ROS2项目(即工作区)结构和ROS包数据文件。
一起浏览里程计C++代码。
除了实现里程计的示例代码外,我们还将提供一个半实现的变体,供您尝试自己实现里程计代码。
按照示例阅读这篇文章应该需要 30 到 45 分钟。
机器人测程法是估计机器人状态和姿势的过程。对于像我们的哈达机器人这样的差速驱动机器人,我们使用车轮如何转动的知识来估计哈达机器人的运动和姿势 - 稍后会详细介绍为什么它是估计。
运动需要我们的哈达机器人前进的速度,即速度(我们将使用米每秒)以及我们的哈达机器人转动的速度(以弧度每秒为单位) - 由这对表示 .
ROS2 使用右手坐标系。在 2D 空间中只考虑轮式机器人是相当常见的,其中绘制的 x 轴指向右,y 轴指向上方,(通常未使用的)z 轴指向我们的脸。因此,正旋转意味着在从上到下(即沿着 z 轴向下)观察我们的 Hadabot 时逆时针旋转。
姿势是(x,y) 我们的 Hadabot 的 2D 位置以及 (即航向角) 表示θ 在某些坐标空间中。
当机器人第一次通电时,将其初始姿势视为 和 .机器人指向某个坐标图的原点的右侧。
对于我们的差速器驱动 Hadabot,测程法成为估算的一种练习 和θ 根据我们对每个轮子旋转速度的测量。
我们用车轮编码器传感器测量哈达机器人的车轮旋转速度(弧度每秒)。用尺子物理测量车轮的半径(以米/弧度为单位)后,我们可以轻松计算出每个车轮的距离速度(米/秒) 和 - 用用简单的数学。
在连续的时间里,里程计变成了一个整合过程,这可能是非常讨厌的。但对我们来说幸运的是,我们可以在小的离散时间块中采样,即:Δt,这使得数学变得更加简单。我不太擅长微分方程,但我很擅长总结数字!
一旦你拥有 和,您可以计算每个车轮行进的距离(以米为单位):
测程练习变为使用以下输入:
...要计算这些输出,请执行以下操作:
我们将自由地跳过一些推导,但最重要的中间计算是:
它是左右车轮中心之间的测量距离,以米为单位。下图——
.但实际上,你可以用使用尺子的物理哈达机器人来衡量这一点。
如果左右轮以相同的速度旋转,哈达机器人就会沿着一条直线移动。但是,如果一个轮子碰巧比另一个轮子旋转得快,那么每个轮子的路径就会变成围绕某个旋转中心的弧形。P 在我们的坐标图中。每个弧的距离为和分别针对每个车轮。和 是车轮之间弧形路径的长度。
我们知道哈达博特以前的定位是θ 在我们的坐标图中。我们正在尝试计算新的方向θ′ .
直观 φ=θ′−θ 新方向和以前方向之间的差异。在数学上,您可以计算φ 使用上面的推导方程。
上述方程的推导在本篇关于差分驱动里程计的论文中有明确的描述。推导是直截了当的,依于找出旋转中心,P ,并使用一些基本的三角函数来推导其余部分。
通过中间计算和我们的当前状态,特别是φ , ,(x,y,θ) ,我们可以计算新的姿势,(x′,y′,θ′) ,我们的机器人具有以下等式:
我们的哈达机器人的新线性和角速度是:
ROS机器人系统由许多ROS节点组成,通过发布和订阅主题消息与每个节点进行通信。
在计算Hadabot的新姿势和速度后,我们将使用nav_msgs/msg/Odomemeter消息将这些新估计发布到ROS系统。
在里程计消息中,有 4 个主要字段 - 标题、child_frame_id、姿势和扭转。
我们将在扭曲字段中发布新的速度估计值,并在姿势字段中发布新的姿势估计值:
由于 Hadabot 差速器驱动机器人在具有 2 个自由度的 3D 平面地图空间上运行 - 沿 x、沿 y 移动并沿 z 旋转(即偏航旋转)——完整 3D 地图的许多字段,6 个自由度被忽略。对于偏航方向 ω′ ,ROS 将角方向表示为四元数。所以在我们存储方向之前,我们需要转换偏航方向角 ω′ ,连同零滚动角和俯仰角,形成四元数。
此外,测程法消息中还有许多其他字段被我们忽略了 - 标题、child_frame_id以及姿势和扭曲中的协方差子字段。
标题字段包含此消息的时间戳数据,以及一个地图框字段,用于指定姿势数据的坐标地图框 - 即(x,y) 在地球上、局部区域地图上坐标等?
该child_frame_id与header.frame_id字段类似,将数据与地图框相关联,即速度。
协方差场表示我们对各自扭曲和姿势测量的不确定性。请记住,我们说过我们的里程计只是估计值。这是因为车轮可能会打滑,编码器传感器有噪音并且不准确,并且还可能存在采样误差(当机器人连续移动时,我们仅在 Δ t间隙采样一次)。所有这些都会导致误差,这些误差应该以某种方式在协方差字段中表示。
对于当前的测程示例,为了简单起见,我们可以安全地忽略时间戳、frame_id和协方差。但是为了稳健地执行机器人导航,我们将需要它们,并且肯定会在以后的帖子中涉及它们。
你们中的许多人可能听说过一个名为Visual Studio Code(VSCode)的IDE。Hadabot将广泛使用VSCode来指导、编译和展示我们共同实现的各种ROS2代码和机器人概念。
我 们的VSCode将作为Hadabot Docker堆栈中的本地Docker容器运行。此外,我们将从 Web 浏览器使用 VSCode,以获得独立于主机系统操作系统的一致用户体验。
除了编辑代码外,VSCode 还支持基于浏览器的集成界面,以便:
注意:对于那些关注过去帖子的人来说,Hadabot web-bash是从Hadabot Docker堆栈中的Portainer容器启动的。由于VSCode还提供了具有更简单界面的web-bash功能,因此我们消除了对Portainer的需求,并将其从堆栈中完全删除。
在运行示例之前,我们需要按照步骤 2a 更新您的 Hadabot Git 存储库,重新启动 Hadabot Docker 堆栈。
请按照以下步骤操作:
启动特定于本文的基于浏览器的VSCode工作区(此链接指向您的本地主机,因此一切都在本地系统上安全运行)。
在“VSCode 资源管理器”面板中,右键单击 README.md 文件 ->“打开预览”。
按照自述文件中的说明编译、运行和调试 ROS2 测程代码。
ROS2使用工作区和包的概念来组织实现机器人系统的各种架构模块。工作区由一组包组成。一个包通常实现一个功能模块,如导航或机器人控制,所以它由源代码组成,实现可以作为可执行文件启动的ROS节点。
我们不会详细介绍如何创建 ROS2 工作区或包,因为在线上有关于如何创建 ROS2 工作区以及如何在工作区中创建 ROS2 包的教程。
为了简化这篇文章,我们预先创建了一个hadabot_ws ROS2工作区。在其中,我们创建了一个 ROS2 包 hadabot_driver,它有一个源文件hadabot_odom.cpp(2 个源文件 - hadabot_odom_diy.cpp我们现在将忽略它,稍后解释它的用法)。
ROS2 使用一个名为 colcon 的工具在工作区中构建 ROS2 包。
colcon 工具从我们的hadabot_driver包构建源文件,以创建一个hadabot_odom ROS2 节点。
一旦我们获取了 ROS2 hadabot_ws/install/setup.bash 环境,我们就hadabot_odom可以使用命令 ros2 run 或专门 .通过采购 setup.bash,我们设置了终端环境以查找 ros2 工具,并能够自动按 Tab 键完成包中的包和节点名称。ros2 run hadabot_driver hadabot_hadabot_odom
ROS2有一个概念,称为“bags”,它是预先保存的ROS消息的目录结构。
在我们的示例中,我们有一个名为 rosbag2_wheel_rotational_velocity_data 的文件夹,其中包含我们从正在运行的 Hadabot 机器人预先保存的大量 ROS2 消息。当 Hadabot 的车轮转动时,它发布了 /hadabot/wheel_radps_right 和 /hadabot/wheel_radps_left ROS2 主题的车轮旋转速度测量值,我们将其保存到rosbag2_data中。
为了播放(以及保存)消息,我们调用 ros2 包 ,如果您已经浏览了示例,您已经完成了此操作。
通过回放保存的袋子数据,我们可以测试我们的测程节点,而无需物理 Hadabot 在场。
测程代码位于 hadabot_ws_/src/hadabot_driver/src/hadabot_odom.cpp 文件中。正如这个简单的 ROS2 C++ 节点教程中所解释的,cpp 文件包含一些必要的 ROS2 库并定义了一个 main(...) 函数。
在高级别上,会发生以下情况:
我们创建了 2 个订阅者,radps_left_sub_ 和 radps_right_sub__,以捕获车轮旋转速度消息并保存相应车轮的当前旋转速度。
我们创建一个触发回调的计时器,publish_odometry(...)_,每隔一段时间就发布出当前的里程计。
我们创建了一个计时器,可以更频繁地触发回调update_odometry(...),以更新给定每个 Hadabot 轮子的最新旋转速度的当前测程法。
update_odometry(...) 函数是我们实现上面描述的测程方程的地方。计算结果存储在pose_变量中。
我们将更新与里程计的发布分开,因为我们可能希望更新里程计的速度比发布速度快。这使我们能够减少δ吨Δ�无需用测程消息淹没我们的 ROS2 系统。
通过使用内置的 GDB 调试器单步执行代码,可以更好地理解实现的更精细细节。有关如何启动调试器的所有易于遵循的说明都由您之前在基于浏览器的 VSCode 环境中打开的自述文件标记描述。
您可能还注意到hadabot_driver_包中另一个名为 hadabot_odom_diy.cpp 的C++源文件。此文件与_hadabot_odom.cpp文件几乎相同,只是它只有用于 update_odometry(...) 函数定义的基架代码。
做比阅读更好,所以我们欢迎你自己实现测程方程,充实update_odometry(...)函数定义,并将你的结果与我们的结果进行比较。也许我们的代码中有一个错误。=)
感谢您关注这篇关于机器人测程法的文章。我们做了以下工作:
学习了如何计算差速驱动机器人(如 Hadabot)的测程。
运行一个示例来编译计算测程的 ROS2 节点。
使用我们基于浏览器的 VSCode 环境再次运行调试器,该节点针对 ROS2 包数据编译。
我们将在以后的帖子中继续沿着机器人导航线程。
至于哈达博特的进展 - 我们有测试版哈达博特套件的零件库存!!请注册以保持联系,以表明您对抢先体验我们套件的兴趣。当我们最终确定细节时,我们将有一个明确的成本,但它将在 100 到 120 美元左右。
像往常一样,如果您有建议,有意见,或者只是想打个招呼,请随时与我们联系 - 你好AT hadabot DOT com。
请与其他软件工程师黑客和机器人专家分享Hadabot。杰克“哈达机器人制造者”