从头手搓一台ros2复合机器人(带机械臂)

一.前言   

        大家好呀,从本小节开始我们就步入了仿真篇,主要对机器人仿真进行介绍与操作,当然仿真有优点也有缺陷,基于对此学习,我们可以对上几小节创建的小车模型模拟硬件的特性,

比如:

  • 有多重,
  • 有多大的惯性
  • 重心在哪
  • 碰撞边界在哪
  • 关节的上下界限
  • 其他的一些必要信息等等

让机器人在gazebo中显示出来,并且实现了在Gazebo中简单的搭建了一个环境,好了,话不多说,马上开始!

二.ros2学习

        前17小节内容可订阅往期博客

18 为机器人URDF模型注入物理属性

18.1 需要的物理信息

碰撞描述是物体的用于碰撞检测的包围形状。

内参用于描述物体的质量,惯性矩阵。

link的摩擦力。

18.1.1 碰撞检测

在机器人仿真中,我们要对物体之前是否接触,是否发生碰撞做检测,常用的检测方法比如包围盒,判断两个物体的包围盒是否相交来快速判断物体是否发生碰撞。

在URDF中,我们可以可以在link标签下添加collison子标签来对物体的形状进行描述。

collision可以包含的子标签如下:

  • origin,表示碰撞体的中心位姿
  • geometry,用于表示用于碰撞检测的几何形状
  • material,可选的,描述碰撞几何体的材料(这个设置可以在gazebo仿真时通过view选项看到碰撞包围体的形状)

一个完整的collision标签实例如下:

    <collision><origin xyz="0 0 0.0" rpy="0 0 0"/><geometry><cylinder length="0.12" radius="0.10"/></geometry><material name="blue"><color rgba="0.1 0.1 1.0 0.5" /> </material></collision>
18.1.2 旋转惯量

旋转惯量矩阵是用于描述物体的惯性的,在做动力学仿真的时候,这些参数尤为重要。

在URDF中我们可以通过在link下添加inertial子标签,为link添加惯性参数的描述。

intertial标签包含的子标签如下:

  • mass,描述link的质量
  • inertia,描述link的旋转惯量(该标签有六个属性值ixx\ixy\ixz\iyy\iyz\izz)

一个完整的inertial标签示例如下:

   <inertial><mass value="0.2"/><inertia ixx="0.0122666" ixy="0" ixz="0" iyy="0.0122666" iyz="0" izz="0.02"/></inertial>

关于intertial的属性设置,常见的几何体我们可以通过公式进行计算。

计算方法可以看小鱼老师的这篇文章-URDF仿真惯性参数不知道怎么配?快收藏,常见几何物体URDF分享。

18.1.3 摩擦力和刚性系数

在上节Fishbot的URDF中,前面的支撑轮主要起支撑作用,因为我们将其使用fixed标签固定到了base_link上,所以它无法转动。

我们可以要把这个轮子的摩擦力设置为0,让它直接在地上滑动即可

  <gazebo reference="caster_link"><mu1 value="0.0"/><mu2 value="0.0"/><kp value="1000000.0" /><kd value="10.0" /></gazebo>

其中mu1,mu2代表摩擦力,kp,kd代表刚性系数。

 18.2 为上节的模型添加物理惯性

完全添加好的机器人URDF模型在这里:fishbot_gazebo.urdf

新建一个urdf文件,将添加好的机器人URDF模型代码放入

18.3 使用gazebo加载URDF

18.3.1 安装Gazebo插件

18.3.2 启动Gazebo并启动插件

通过下面的命令行来启动gazebo并加载ros2插件。

18.3.3 插件节点及其服务介绍

来看插件的节点,以及改节点为我们提供的服务有哪些

这个节点对外提供的服务有哪些

我们可以看到另外三个特殊服务:

  • /spawn_entity,用于加载模型到gazebo中
  • /get_model_list,用于获取模型列表
  • /delete_entity,用于删除gazbeo中已经加载的模型

我们想要让gazebo显示出我们配置好的模型使用/spawn_entity来加载即可。

接着我们可以来请求服务来加载模型,先看一下服务的接口类型。

看到服务的请求内容包括:

  • string name ,需要加载的实体的名称 (可选的)。
  • string xml ,实体的XML描述字符串, URDF或者SDF。
  • string robot_namespace ,产生的机器人和所有的ROS接口的命名空间,多机器人仿真的时候很有用。
  • geometry_msgs/Pose initial_pose ,机器人的初始化位置
  • string reference_frame ,初始姿态是相对于该实体的frame定义的。如果保持"empty"或"world"或“map”,则使用 gazebo的world作为frame。如果指定了不存在的实体,则会返回错误
18.3.4 调用服务加载模型

命令行输入rqt,在插件选项中选择Services->Service Caller,然后再下拉框选择/spawn_entity服务,即可看到下面的界面。

把我们的FishBot的URDF模型复制粘贴,放到xml中

此时再看Gazebo,一个机器人出现了

18.3.5 在不同位置加载多个机器人

修改rqt中的参数,增加一个命名空间,然后修改一个位置,让第二个机器人和第一个相距1m的地方生产,然后点击Call。

18.3.6 查询和删除机器人

利用rqt工具,我们再对另外两个服务接口进行请求。

查到了三个模型,一个大地,一个fishbot,一个fishbot_0。

我们接着尝试把fishbot_0删掉,选择删除实体,输入fishbot_0的名字,点击call

调用成功,观察gazebo发现机器人没了

18.3.7 将启动gazebo和生产fishbot写成launch文件

打开urdf工作空间,在src/fishbot_description/launch中添加一个gazebo.launch.py文件,我们开始编写launch文件来在gazebo中加载机器人模型。

编译运行

18.3.8 Gazebo仿真插件之两轮差速

通过配置两轮差速控制插件,让我们的机器人动起来,先介绍一下gazebo的插件

gazebo的插件按照用途大致可以分为两种:

  1. 用于控制的插件,通过插件可以控制机器人关节运动,可以进行位置、速度、力的控制,比如我们这节课的两轮差速控制器。
  2. 用于数据采集的插件,比如IMU传感器用于采集机器人的惯性,激光雷达用于采集机器人周围的点云信息。

当然上面两类插件功能也可以写到一个插件里,两轮差速插件就是一个二合一加强版

两轮差速插件用于控制机器人轮子关节的位置变化,同时该插件还会获取轮子的位置以及速度的信息的反馈,根据反馈的位置信息结合运动学模型即可计算出当前机器人的位姿(里程计)。

该插件的名称为:gazebo_ros_diff_drive

两轮差速控制器和Gazebo的关系

两轮差速控制器可以将轮子的目标转速发送给Gazebo,并从Gazebo获取到实际的速度和位置。

注意:发送给Gazebo是目标速度,反馈回来的是实际速度。目标不等于实际,比如轮子卡住了,无论你发什么目标速度,实际速度都是0。

看到该插件主要输入控制指令,主要输出里程计信息

输入参数

该插件还提供了一些可以控制输出的选项,因为是仿真,所以还要告诉插件轮子对应的joint名称等信息,这样就有了下面这个参数表格:

控制指令

两轮差速控制器默认通过订阅话题cmd_vel来获取目标线速度和角速度。该话题的类型为:geometry_msgs/msg/Twist

线速度和角速度都包含在x、y、z,代表坐标系的三个方向上的对应速度。

两轮差速控制器收到这个话题数据后将其中的角速度和线速度转换上两个轮子的转动速度发送给Gazebo。

输出参数

1.里程计

里程计信息默认的输出话题为odom,其消息类型为:nav_msgs/msg/Odometry

可以看到其数据主要包含三个部分:

  • header,表示该消息发布的时间
  • pose,表示当前机器人位置和朝向
  • twist,表示当前机器人的线速度和角速度

covariance,其代表协方差矩阵

2.里程计TF信息

3.左右轮子TF信息

在URDF中配置两轮差速模型

因为是给Gazebo的插件,所以在URDF中,我们需要使用<gazebo>进行配置,因为是要给gazebo配置插件,所有要在gazebo标签下添加plugin子插件。

编译测试

使用CLI工具看一下系统有哪些节点在运行

已经看到了插件订阅的的/cmd_vel和发布的/odom了

使用键盘控制fishbot

键盘控制工具,可以用下面的指令安装

这个功能包下有一个节点,这个节点会监听键盘的按键事件,然后发布cmd_vel话题,该话题被gazebo的两轮差速插件所订阅。所以我们就可以通过这个节点来控制fishbot。

如果你想让这个节点不是发布cmd_vel话题,而是别的,可以采用ROS2的话题重映射功能。 eg: ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args --remap cmd_vel:=cmd_vel1

使用rqt显示速度数据

接着使用rqt将数据在rqt中可视化出来

选择Plugin->Visualization->Plot

在上方Topic输入/cmd_vel/linear/x,再输入/cmd_vel/angular/z,然后用键盘控制机器人移动

cmd_vel中的速度代表目标速度,接着我们显示一下当前速度(在odom.twist中)

添加好后点一下右上角刷新

在RVIZ2中显示模型及其轨迹

打开rviz2

  1. 修改FixedFrame为odom
  2. 添加插件,Add->Odometry->OK
  3. 选择话题,Odometry->Topic->选/odom
  4. 去除协方差显示,Odometry->Covariance>取消勾选
  5. 键盘控制节点,点个U,原地转圈圈

虽然机器人的轨迹已经在RVIZ中显示出来了,但是并没有机器人的模型,也看不到轮子的转动,要发布机器人模型我们所使用的节点是robot_state_publisher,所以我们在gazebo.launch.py中加入这个节点,同时再加上rviz2的启动节点,最终的gazebo.launch.py内容如下:

保存编译启动

18.3.9 Gazebo仿真插件之IMU
1.惯性测量单元IMU介绍

        惯性测量单元是测量物体三轴姿态角(或角速率)以及加速度的装置。一般的,一个IMU包含了三个单轴的加速度计和三个单轴的陀螺,加速度计检测物体在载体坐标系统独立三轴的加速度信号,而陀螺检测载体相对于导航坐标系的角速度信号,测量物体在三维空间中的角速度和加速度,并以此解算出物体的姿态

IMU可以测量以下三组数据:

  • 三维角度
  • 三维加速度
  • 三维角速度
2.Gazebo-IMU插件

仿真的IMU也是对应一个后缀为.so的动态链接库,使用下面的指令可以查看所有的动态链接库:

IMU对应的消息类型为sensor_msgs/msg/Imu

除了每个数据对应的三个协方差之外,每一个还都对应一个3*3的协方差矩阵。

3.配置IMU传感器

        为了更真实的模拟IMU传感器,我们需要给我们的仿真IMU传感器加点高斯噪声,高斯噪声只需要指定平均值和标准差两个参数即可,不过因为IMU传感器的特殊性,我们还需要给模型添加两个偏差参数,分别是 平均值偏差标准差偏差

下面是IMU传感器的URDF配置代码,IMU对应的插件库libgazebo_ros_imu_sensor.so

4.编译测试

CLI看话题

rqt可视化:

18.3.10 Gazebo仿真插件之激光雷达
1.激光雷达原理介绍

普通的单线激光雷达一般有一个发射器,一个接收器,发射器发出激光射线到前方的目标上,物品会将激光反射回来,然后激光雷达的接受器可以检测到反射的激光。

通过计算发送和反馈之间的时间间隔,乘上激光的速度,就可以计算出激光飞行的距离,该计算方法成为TOF(飞行时间法Time of flight,也称时差法)。

2.Gazebo激光雷达插件

激光雷达是属于射线类传感器,该类传感在在Gazebo插件中都被封装成了一个动态库libgazebo_ros_ray_sensor.so

看一下LiDAR的话题消息接口sensor_msgs/msg/LaserScan

3.为FishBot添加雷达插件

需要在URDF添加以下内容

可以看到:

  1. 雷达可以设置更新频率update_rate,这里设置为5
  2. 雷达可以设置分辨率,设置为1,采样数量360个,最终生成的点云数量就是360
  3. 雷达也有噪声,模型为gaussian
  4. 雷达有扫描范围range,这里配置成0.12-3.5,0.015分辨率
  5. 雷达的pose就是雷达的joint中位置的设置值
4.编译测试

CLI看话题

使用rviz2进行可视化激光雷达数据

添加和修改RVIZ2的如下:(通过LaserScan插件可以看到激光数据)

改完之后依然是看不到任何激光雷达的数据的,反看topic的echo出来的数据,不是0就是inf(无限大),再看看gazebo你会发现,激光雷达并没有达到任何一个物体上。

我们可以手动的给激光雷达周围添加一下东西,点击Gazebo工具栏的正方体,圆球或者圆柱,随意放置几个到我们激光雷达的最大扫描半径内。

再看一下RVIZ2,把size改大了10倍0.01->0.1。

18.3.11 Gazebo仿真环境搭建
1.Gazebo的world介绍

world即世界,gazebo的world文件就是用于描述世界模型的,也就是环境模型。

Gazebo已经为我们准备了很多常用的物体模型,除了基础的圆球,圆柱,立方体外的,其实还有飞机、汽车、房子等。

好这些模型,需要我们手动下载,万幸的是小鱼老师已经帮我们封装成了一行代码下载

因为一共有281个模型,是逐一下载并解压到~/.gazebo/models/目录的。

此时再次打开终端,输入gazebo,把选项卡切换到Insert

在Insert选项卡下可以看到一个目录,以及目录下的模型名称,随着下载脚本的不断下载,这里的模型会越来越多。

2.通过建墙工具建立world

Gazebo左上角->Edit->Building Editor

接着可以看到这样一个编辑界面

点击左边的Wall,就可以在上方的白色区域进行建墙了

建完后还可以用选Add Color或者Add Texture,然后点击下方墙,给墙添加颜色或者纹理

按下鼠标滑轮可以旋转视角

我们也可以从已有地图画墙

打开Gazebo->Gazebo左上角->Edit->Building Editor->左下方选Import

点击Next

左边选尺寸对应关系,选择默认的,100像素/米。点击OK(需要手动将100改变一下才能点击OK),之后就可以用图片画墙了。

注意:导入完图片不会直接出来墙,图片只是提供了墙的大概位置,需要手动用墙再将边描一遍。

建完后点击File->Exit,在退出的弹框中选Save and Exit。

接着在Gazebo界面中就可以看到墙了,我们再手动添加几个物体,就可以用于下面的导航使用了。

添加完,接着点击File->SaveWorld,将文件保存到我们的fishbot_descrption的world下

3.启动时加载world
1 命令行加载World

加载world其实也很简单,可以先启动Gazebo,再手动的加载文件,也可以在Gazebo启动时加载:

2 在launch中加载World

修改launch文件,将上面的命令行写到gazebo.launch.py

修改setup.py文件,让编译后将world文件拷贝到install目录下

编译测试

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

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

相关文章

洛谷[NOIP2016 提高组] 玩具谜题

[NOIP2016 提高组] 玩具谜题 题目背景 NOIP2016 提高组 D1T1 题目描述 小南有一套可爱的玩具小人&#xff0c;它们各有不同的职业。 有一天&#xff0c;这些玩具小人把小南的眼镜藏了起来。小南发现玩具小人们围成了一个圈&#xff0c;它们有的面朝圈内&#xff0c;有的面…

JetBrains学生包续期

Pycharm进入显示your license has expired 这个意思是你的许可过期了&#xff0c;重新输入最新的激活码就可以了。 1. 说明我的JetBrains学生包需要进行续期了。首先登录JetBrains官网打开个人主页&#xff0c;点击Renew my Education Pack 2. 然后填写一系列信息&#xff0c;…

VR历史建筑漫游介绍|虚拟现实体验店|VR设备购买

VR历史建筑漫游是一种利用虚拟现实技术&#xff0c;让用户可以身临其境地参观和探索历史建筑的体验。通过VR头显和相关设备&#xff0c;用户可以在虚拟环境中自由移动和互动&#xff0c;感受历史建筑的真实氛围和文化内涵。 在VR历史建筑漫游中&#xff0c;您可以选择不同的历史…

手机备忘录怎么导出到电脑,如何将手机备忘录导出到电脑

备忘录是我们日常生活和工作中常用的工具之一&#xff0c;我们可以在手机上轻松地记录重要的事务、想法和灵感。然而&#xff0c;在某些情况下&#xff0c;我们可能需要将手机备忘录导出到电脑进行更详细的整理和管理。那么&#xff0c;手机备忘录怎么导出到电脑&#xff0c;如…

开箱即用之 windows部署jdk、设置nginx、jar自启

jdk安装 官网下载对应的安装包&#xff0c;解压之后放在本地指定的文件夹下 传送门https://www.oracle.com/java/technologies/downloads/#jdk21-windows 我比较喜欢下载zip方式的&#xff0c;解压之后直接能用&#xff0c;不需要安装了 配置环境 JAVA_HOME 添加path路径 …

MySQL数据导入的方式介绍

MySQL数据库中的数据导入是一个常见操作&#xff0c;它涉及将数据从外部源转移到MySQL数据库表中。在本教程中&#xff0c;我们将探讨几种常见的数据导入方式&#xff0c;包括它们的特点、使用场景以及简单的示例。 1. 命令行导入 使用MySQL命令行工具mysql是导入数据的…

有关【指针运算】的经典笔试题

题目1&#xff1a; #include <stdio.h>int main() {int a[5] { 1, 2, 3, 4, 5 };int* ptr (int*)(&a 1);printf("%d,%d", *(a 1), *(ptr - 1));return 0; } //程序的输出结果是什么&#xff1f; 2 5解析&#xff1a; 代码的内存布局如图&#xff1a…

Nutanix 国产化替代|一文了解 SmartX 超融合替代可行性与迁移方案

2022 年 8 月 19 日&#xff0c;Nutanix&#xff08;路坦力&#xff09;宣布中国市场自 2023 财年起将转型为合作伙伴销售主导模式&#xff0c;引起了广泛关注&#xff1b;同时结合当前 IT 基础架构的国产化趋势背景&#xff0c;不少正在使用和考虑使用 Nutanix 产品的企业开始…

编译原理-实现LR语法分析器——沐雨先生

实验任务&#xff1a; 实现LR语法分析器 实验要求&#xff1a; 根据编译原理理论课教材中例3.22给出的算术表达式文法以及该文法的LR分析表&#xff0c;用C语言编写接受算术表达式为输入的语法分析器&#xff0c;以控制台&#xff08;或文本文件&#xff0c;也可以结合词法分…

C语言种sizeof()和strlen的区别

sizeof 是 C 语言内置的操作符关键字&#xff0c;而 strlen 是 C 语言库函数&#xff1b; sizeof 仅用于计算数据类型的大小或者变量的大小&#xff0c;而 strlen 只能以结尾为 \0 的字符串作为参数&#xff1b; 编译器在编译时就计算出了 sizeof 的结果&#xff0c;而 strlen …

Spring Security的开发

文章目录 1,介绍2, 核心流程3, 核心原理3.1 过滤器链机制3.2 主体3.3 认证3.4 授权3.5 流程图4, 核心对象4.1 UserDetailsService 接口4.2 PasswordEncoder 接口4.3 hasAuthority方法4.4 hasAnyAuthority方法4.5 hasRole方法4.5 hasAnyRole方法5, 核心注解5.1 @PreAuthorize5.1…

【Linux】系统开启和关闭过程

Linux 系统启动过程 BIOS 自检&#xff1a;在计算机开机时&#xff0c;BIOS 会进行自检&#xff0c;检查硬件设备是否正常。 加载引导程序&#xff1a;BIOS 自检完成后&#xff0c;会加载引导程序&#xff0c;如 GRUB、LILO 等。引导程序会加载内核和初始化 RAM 磁盘&#xff…

想入门Web测试,看这篇文章!

今天要谈的是很多软件测试工程师都需要面对的——Web测试 不管你是处在二十不惑的青春有你阶段还是三十而已的乘风破浪阶段我们都需要面对“Web测试”。 Web测试其实有以下几个方面&#xff1a; 1、页面测试 大多数的Web网站的网页都是html语言编写的&#xff0c;测试工程师…

3.3 RK3399项目开发实录-板载Ubuntu系统的使用(wulianjishu666)

嵌入式物联网常用90款传感器开发例程。链接&#xff1a;https://pan.baidu.com/s/1oisHMZXDzKqa4EspY83V-A?pwdo5f4 1. 介绍 Ubuntu 使用手册是针对 Firefly 官方发布的 Ubuntu 系统固件特性所编写&#xff0c;适用于 Ubuntu Desktop 与 Minimal 系统&#xff0c;部分与 UI 显…

开源文本挖掘引擎:情感分析|API接口|可私有化部署

中文的表达方式五花八门&#xff0c;比如成语、俗语、还有那些让人哭笑不得的双关语&#xff0c;这些都让情感分析变得复杂。再者&#xff0c;中文里头的情感表达很多时候得看上下文&#xff0c;一句话放在不同的情景里&#xff0c;意思可能就大相径庭了。 中文里面的否定和讽…

openGauss学习笔记-245 openGauss性能调优-SQL调优-典型SQL调优点-算子级调优

文章目录 openGauss学习笔记-245 openGauss性能调优-SQL调优-典型SQL调优点-算子级调优245.1 算子级调优245.1.1 算子级调优介绍245.1.2 算子级调优示例 openGauss学习笔记-245 openGauss性能调优-SQL调优-典型SQL调优点-算子级调优 SQL调优是一个不断分析与尝试的过程&#x…

Vector Magic:矢量图像转换神器,轻松驾驭Mac与Win双平台

在数字化时代&#xff0c;图像已经成为我们生活和工作中不可或缺的一部分。无论是设计师、艺术家&#xff0c;还是普通用户&#xff0c;都对图像质量有着极高的要求。而矢量图像&#xff0c;以其清晰度高、可无限放大的特点&#xff0c;逐渐受到广大用户的青睐。今天&#xff0…

长安链正式发布三周年,技术更迭支撑产业变革

导语&#xff1a; 2024年1月27日长安链正式发布三周年&#xff0c;开源社区借开年之际与大家一同回顾长安链三年来的技术发展历程&#xff0c;每一个里程碑的建设都得益于与长安链同行的合作伙伴与开发者&#xff0c;希望在2024年可以共同携手继往开来&#xff0c;为数字经济发…

2024腾龙杯web签到题-初识jwt(签到:这是一个登录页面)

什么是 jwt? 它是 JSON Web Token 的缩写&#xff0c;是一个开放标准&#xff0c;定义了一种紧凑的、自包含的方式&#xff0c;用于作为JSON对象在各方之间安全地传输信息&#xff0c;该信息可以被验证和信任&#xff0c;因为它是数字签名的。它就是一种认证机制&#xff0c;…

Kotlin: 协程的四种启动模式(CoroutineStart)

点击查看CoroutineStart英文文档 创建协程的三种方式 runBlocking 运行一个协程并且会阻塞当前线程&#xff0c;直到它完成。launch 启动一个新的协程&#xff0c;不会阻塞当前线程&#xff0c;并且返回一个Job&#xff0c;可以取消。async async和await是两个函数&#xff0c…