使用在 Web 浏览器中运行的 VSCode 实现 ROS2 测程法

news2024/9/21 16:43:13

一、说明

                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 套件来跟随这篇文章。具体而言,我们将:

  1. 了解差速驱动机器人测程法。

  2. 了解 ROS 和 ROS2 如何处理计量数据。

  3. 设置基于哈达机器人浏览器的VSCode。

  4. 使用我们基于浏览器的 VSCode 编译和调试 ROS2 C++里程计节点。

  5. 了解ROS2项目(即工作区)结构和ROS包数据文件。

  6. 一起浏览里程计C++代码。

        除了实现里程计的示例代码外,我们还将提供一个半实现的变体,供您尝试自己实现里程计代码。

        按照示例阅读这篇文章应该需要 30 到 45 分钟。


二、 差速驱动机器人测程法

        机器人测程法是估计机器人状态和姿势的过程。对于像我们的哈达机器人这样的差速驱动机器人,我们使用车轮如何转动的知识来估计哈达机器人的运动和姿势 - 稍后会详细介绍为什么它是估计

        运动需要我们的哈达机器人前进的速度,即速度(我们将使用米每秒)以及我们的哈达机器人转动的速度(以弧度每秒为单位) - 由这对表示(v,\omega ) .

        ROS2 使用右手坐标系。在 2D 空间中只考虑轮式机器人是相当常见的,其中绘制的 x 轴指向右,y 轴指向上方,(通常未使用的)z 轴指向我们的脸。因此,正旋转意味着在从上到下(即沿着 z 轴向下)观察我们的 Hadabot 时逆时针旋转。

        姿势是(x,y) 我们的 Hadabot 的 2D 位置以及 (即航向角) 表示θ 在某些坐标空间中。

        当机器人第一次通电时,将其初始姿势视为(x_0,y_0)=( 0,0)\theta _0=0 .机器人指向某个坐标图的原点的右侧。

        对于我们的差速器驱动 Hadabot,测程法成为估算的一种练习(v, \omega ), (x,y) 和θ 根据我们对每个轮子旋转速度的测量。

        我们用车轮编码器传感器测量哈达机器人的车轮旋转速度(弧度每秒)。用尺子物理测量车轮的半径(以米/弧度为单位)后,我们可以轻松计算出每个车轮的距离速度(米/秒)v_{left}  和v_{right}  - 用用简单的数学。

        在连续的时间里,里程计变成了一个整合过程,这可能是非常讨厌的。但对我们来说幸运的是,我们可以在小的离散时间块中采样,即:Δt,这使得数学变得更加简单。我不太擅长微分方程,但我很擅长总结数字!

        一旦你拥有v_{left} 和v_{right},您可以计算每个车轮行进的距离(以米为单位):

        测程练习变为使用以下输入:

  •  d_{left}, d_{right} 
  • 机器人的前瞬位置(x,y) 和前瞬取向θ

        ...要计算这些输出,请执行以下操作:

  • 新的线性和角速度(v′,ω′)
  • 新姿势(x′,y′)和θ′

        我们将自由地跳过一些推导,但最重要的中间计算是:

 2.1 什么是d_{WHEELBASE} ?

        它是左右车轮中心之间的测量距离,以米为单位。下图——

         .但实际上,你可以用使用尺子的物理哈达机器人来衡量这一点。

        2.2 什么是d_center?

        如果左右轮以相同的速度旋转,哈达机器人就会沿着一条直线移动。但是,如果一个轮子碰巧比另一个轮子旋转得快,那么每个轮子的路径就会变成围绕某个旋转中心的弧形。P 在我们的坐标图中。每个弧的距离为d_{left}d_{right}分别针对每个车轮。和 d_{center}是车轮之间弧形路径的长度。

        2.3 什么φ?

             我们知道哈达博特以前的定位是θ 在我们的坐标图中。我们正在尝试计算新的方向θ′ .

        直观 φ=θ′−θ  新方向和以前方向之间的差异。在数学上,您可以计算φ 使用上面的推导方程。

        上述方程的推导在本篇关于差分驱动里程计的论文中有明确的描述。推导是直截了当的,依于找出旋转中心,P ,并使用一些基本的三角函数来推导其余部分。

        通过中间计算和我们的当前状态,特别是φ , d_{center},(x,y,θ) ,我们可以计算新的姿势,(x′,y′,θ′) ,我们的机器人具有以下等式:

        我们的哈达机器人的新线性和角速度是:

三. ROS,ROS2上的里程计

        ROS机器人系统由许多ROS节点组成,通过发布和订阅主题消息与每个节点进行通信。

        在计算Hadabot的新姿势和速度后,我们将使用nav_msgs/msg/Odomemeter消息将这些新估计发布到ROS系统。

        在里程计消息中,有 4 个主要字段 - 标题、child_frame_id、姿势和扭转。

        我们将在扭曲字段中发布新的速度估计值,并在姿势字段中发布新的姿势估计值:

  • odometry.twist.twist.linear.x = v′ 
  • odometry.twist.twist.angular.z = ω′ 
  • odometry.pose.pose.position.x = x′ 
  • odometry.pose.pose.position.y = y′ 
  • odometry.pose.pose.orientation = quaternion_from_roll_pitch_yaw(0, 0, ω′ )

        由于 Hadabot 差速器驱动机器人在具有 2 个自由度的 3D 平面地图空间上运行 - 沿 x、沿 y 移动并沿 z 旋转(即偏航旋转)——完整 3D 地图的许多字段,6 个自由度被忽略。对于偏航方向        ω′ ,ROS 将角方向表示为四元数。所以在我们存储方向之前,我们需要转换偏航方向角        ω′ ,连同零滚动角和俯仰角,形成四元数。

        此外,测程法消息中还有许多其他字段被我们忽略了 - 标题、child_frame_id以及姿势和扭曲中的协方差子字段。

  • 标题字段包含此消息的时间戳数据,以及一个地图框字段,用于指定姿势数据的坐标地图框 - 即(x,y) 在地球上、局部区域地图上坐标等?

  • 该child_frame_id与header.frame_id字段类似,将数据与地图框相关联,即速度。

  • 协方差场表示我们对各自扭曲和姿势测量的不确定性。请记住,我们说过我们的里程计只是估计值。这是因为车轮可能会打滑,编码器传感器有噪音并且不准确,并且还可能存在采样误差(当机器人连续移动时,我们仅在 Δ t间隙采样一次)。所有这些都会导致误差,这些误差应该以某种方式在协方差字段中表示。

        对于当前的测程示例,为了简单起见,我们可以安全地忽略时间戳、frame_id和协方差。但是为了稳健地执行机器人导航,我们将需要它们,并且肯定会在以后的帖子中涉及它们。


四、 在浏览器上使用VSCode编译、运行测程ROS2节点

        你们中的许多人可能听说过一个名为Visual Studio Code(VSCode)的IDE。Hadabot将广泛使用VSCode来指导、编译和展示我们共同实现的各种ROS2代码和机器人概念。

我        们的VSCode将作为Hadabot Docker堆栈中的本地Docker容器运行。此外,我们将从 Web 浏览器使用 VSCode,以获得独立于主机系统操作系统的一致用户体验。

        除了编辑代码外,VSCode 还支持基于浏览器的集成界面,以便:

  • 文件系统
  • 一个bash终端 - 我们偶尔称之为web-bash。
  • 查看渲染的降价以阅读指导说明

        注意:对于那些关注过去帖子的人来说,Hadabot web-bash是从Hadabot Docker堆栈中的Portainer容器启动的。由于VSCode还提供了具有更简单界面的web-bash功能,因此我们消除了对Portainer的需求,并将其从堆栈中完全删除。

4.1 设置哈达机器人在线开发环境

在运行示例之前,我们需要按照步骤 2a 更新您的 Hadabot Git 存储库,重新启动 Hadabot Docker 堆栈。

4.2 通过测程 ROS2 节点编译运行调试器

        请按照以下步骤操作:

  1. 启动特定于本文的基于浏览器的VSCode工作区(此链接指向您的本地主机,因此一切都在本地系统上安全运行)。

  2. 在“VSCode 资源管理器”面板中,右键单击 README.md 文件 ->“打开预览”。

  3. 按照自述文件中的说明编译、运行和调试 ROS2 测程代码。


五、 源代码的结构 - 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


六. 什么是ROS袋?

        ROS2有一个概念,称为“bags”,它是预先保存的ROS消息的目录结构。

        在我们的示例中,我们有一个名为 rosbag2_wheel_rotational_velocity_data 的文件夹,其中包含我们从正在运行的 Hadabot 机器人预先保存的大量 ROS2 消息。当 Hadabot 的车轮转动时,它发布了 /hadabot/wheel_radps_right 和 /hadabot/wheel_radps_left ROS2 主题的车轮旋转速度测量值,我们将其保存到rosbag2_data中。

        为了播放(以及保存)消息,我们调用 ros2 包 ,如果您已经浏览了示例,您已经完成了此操作。

        通过回放保存的袋子数据,我们可以测试我们的测程节点,而无需物理 Hadabot 在场。


七. 我们如何在 ROS2 中实现里程计

测程代码位于 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 系统。

7.1 使用 VSCode 调试器逐步执行 ROS2 C++代码

        通过使用内置的 GDB 调试器单步执行代码,可以更好地理解实现的更精细细节。有关如何启动调试器的所有易于遵循的说明都由您之前在基于浏览器的 VSCode 环境中打开的自述文件标记描述。

7.2 尝试自己实现里程计

        您可能还注意到hadabot_driver_包中另一个名为 hadabot_odom_diy.cpp 的C++源文件。此文件与_hadabot_odom.cpp文件几乎相同,只是它只有用于 update_odometry(...) 函数定义的基架代码。

        做比阅读更好,所以我们欢迎你自己实现测程方程,充实update_odometry(...)函数定义,并将你的结果与我们的结果进行比较。也许我们的代码中有一个错误。=)


八、结论

        感谢您关注这篇关于机器人测程法的文章。我们做了以下工作:

  1. 学习了如何计算差速驱动机器人(如 Hadabot)的测程。

  2. 运行一个示例来编译计算测程的 ROS2 节点。

  3. 使用我们基于浏览器的 VSCode 环境再次运行调试器,该节点针对 ROS2 包数据编译。

        我们将在以后的帖子中继续沿着机器人导航线程。

        至于哈达博特的进展 - 我们有测试版哈达博特套件的零件库存!!请注册以保持联系,以表明您对抢先体验我们套件的兴趣。当我们最终确定细节时,我们将有一个明确的成本,但它将在 100 到 120 美元左右。

        像往常一样,如果您有建议,有意见,或者只是想打个招呼,请随时与我们联系 - 你好AT hadabot DOT com。

        请与其他软件工程师黑客和机器人专家分享Hadabot。杰克“哈达机器人制造者”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/909388.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

静态代码扫描持续构建(Jenkins)

前提条件 已正确安装、配置Jenkins环境,并装有 Gradle 插件、HTML 插件、SVN 插件等。如下图所示: 已正确安装、配置android sdk,在cmd窗口输入命令“android -h”,回车 配置步骤 打开Jenkins,新建一个job,输入项目…

【数据结构练习】单链表OJ题(一)

目录 一、移除链表元素思路1:思路2: 二、反转链表三、链表的中间节点四、链表中倒数第k个节点五、回文结构六、合并两个有序链表 一、移除链表元素 题目: 思路1: 在原来的链表上进行修改,节点的数据是val的删除&am…

Github的使用指南

首次创建仓库 1.官网创建仓库 打开giuhub官网,右上角点击你的头像,随后点击your repositories 点击New开始创建仓库 如下图为创建仓库的选项解释 出现如下界面就可以进行后续的git指令操作了 2.git上传项目 进入需上传项目的所在目录,打开…

JVM——垃圾回收器G1+垃圾回收调优

4.4 G1(一个垃圾回收器) 定义: 取代了CMS垃圾回收器。和CMS一样时并发的。 适用场景: 物理上分区,逻辑上分代。 相关JVM参数: -XX:UseG1GC-XX:G1HeapRegionSizesize-XX:MaxGCPauseMillistime 1) G1 垃圾回收阶段 三个回收阶段&#xff0…

【私有GPT】CHATGLM-6B部署教程

【私有GPT】CHATGLM-6B部署教程 CHATGLM-6B是什么? ChatGLM-6B是清华大学知识工程和数据挖掘小组(Knowledge Engineering Group (KEG) & Data Mining at Tsinghua University)发布的一个开源的对话机器人。根据官方介绍,这是…

Docker mysql主从同步安装

1. 构建master实例 docker run -p 3307:3306 --name mysql-master \ -v /mydata/mysql-master/log:/var/log/mysql \ -v /mydata/mysql-master/data:/var/lib/mysql \ -v /mydata/mysql-master/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORDroot \ -d mysql:5.7 2. 构建master配置…

Confluent kafka 异常退出rd_tmpabuf_alloc0: rd kafka topic info_new_with_rack

rd_tmpabuf_alloc0: rd kafka topic info_new_with_rack 根据网上的例子,做了一个测试程序。 C# 操作Kafka_c# kafka_Riven Chen的博客-CSDN博客 但是执行下面一行时,弹出上面的异常,闪退。 consumer.Subscribe(queueName) 解决方案&…

Git相关命令

SSH密钥文件 Github里面S设置SH公钥有两者选择方式 账号下的每个仓库都设置一个公钥,因为GitHub官方要求每个仓库的公钥都不能相同,所以每个账号都要搞一个密钥(很麻烦)给账号分配一个公钥,然后这个公钥就可以在这个…

基础恢复1-c语言

用书:c primer plus 学习时间:21-25 重点知识: 1.编译-链接-运行 编译:编译器将源码转换为可执行代码 链接:编译器从c库中获取标准例程放入源码中一同编译 运行:运行可执行文件 2.关键字 数据类型&…

smiley-http-proxy-servlet 实现springboot 反向代理,结合项目鉴权,安全的引入第三方项目服务

项目中反向代理 集成第三方的服务接口或web监控界面&#xff0c;并实现与自身项目相结合的鉴权方法 依赖 smiley-http-proxy-servlet GitHub链接 2.0 版开始&#xff0c;代理切换到jakarta servlet-api<!--HTTP 代理 Servlet--><dependency><groupId>org.mit…

记一次布尔盲注漏洞的挖掘与分析

在上篇文章记一次由于整型参数错误导致的任意文件上传的漏洞成因的分析过程中&#xff0c;发现menu_id貌似是存在注入的。 public function upload() {$menu_id $this->post(menu_id);if ($id) {$where "id {$id}";if ($menu_id) {$where . " and menu_id…

jenkins 日志输出显示时间戳的方式

网上很多方式比较片面&#xff0c;最新版插件直接使用即可无需更多操作。 使用方式如下&#xff1a; 1.安装插件 Timestamper 2.更新全局设置 系统设置-找到 Timestamper 勾选 Enabled for all Pipeline builds 也可修改时间戳格式。 帮助信息中显示 When checked, timesta…

【业务功能篇73】分布式ID解决方案

业界实现方案 1. 基于UUID2. 基于DB数据库多种模式(自增主键、segment)3. 基于Redis4. 基于ZK、ETCD5. 基于SnowFlake6. 美团Leaf(DB-Segment、zkSnowFlake)7. 百度uid-generator() 1.基于UUID生成唯一ID UUID:UUID长度128bit&#xff0c;32个16进制字符&#xff0c;占用存储空…

服务器数据恢复-HP EVA存储VDISK被删除的数据恢复案例

服务器数据恢复环境&#xff1a; 某单位有一台HP EVA存储&#xff0c;连接2组扩展柜&#xff0c;扩展柜中有12块FATA磁盘和10块FC磁盘&#xff0c;不确定数量的LUN&#xff0c;主机安装WINDOWS SERVER操作系统&#xff0c;存储设备用来存放该单位的重要资料。 服务器故障初检&…

线程池的实现全过程v1.0版本(手把手创建,看完必掌握!!!)

目录 线程池的实现过程 线程池的创建 添加任务队列 线程进行处理任务 线程池资源释放 线程池完整程序 线程池v1.0版本总结 线程池的实现过程 实现线程池首先要确定线程池有哪些属性 线程池中线程的数量线程池中已工作的线程数量任务队列任务队列的大小任务队列的锁 还…

mysql-sql性能分析工具

一、sql执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供服务器状态信息。通过如下指令&#xff0c;可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次&#xff1a; -- session 是查看当前会话 ; -- global 是查询全…

uni-app 打包生成签名Sha1

Android平台打包发布apk应用&#xff0c;需要使用数字证书&#xff08;.keystore文件&#xff09;进行签名&#xff0c;用于表明开发者身份。 可以使用JRE环境中的keytool命令生成。以下是windows平台生成证书的方法&#xff1a; 安装JRE环境&#xff08;推荐使用JRE8环境&am…

树结构使用实例---实现数组和树结构的转换

文章目录 一、为什么要用树结构&#xff1f;二、使用步骤 1.引入相关json2.树结构的转换总结 一、为什么要用树结构&#xff1f; 本文将讲述一个实例&#xff0c;构造一棵树来实现数组和tree的转换&#xff0c;这在前端树结构中是经常遇到的 后端返回树结构方便管理&#xff…

OpenCL矢量加法例子

1.向量加内核函数 __kernel void vector_add(__global float* A, __global float* B, __global float* C) {int id get_global_id(0);C[id] A[id] B[id]; }2.向量加主程序 #include<stdio.h> #include<stdlib.h> #ifdef _APPLE_ #include<OpenCL/cl.h> …

通过DBeaver 给Postgre SQL表 设置主键自增

1.创建表 CREATE TABLE public.company ( id int4 NOT NULL , name text NOT NULL, age int4 NOT NULL, address bpchar(50) NULL, salary float4 NULL, join_date date NULL, CONSTRAINT company_pkey PRIMARY KEY (id) ); 2.插入数据&#xff08;不传入id&#xff…