机器人操作系统:ROS2 仿真入门

news2024/11/14 9:21:58

塞巴斯蒂安

·

一、说明

         在机器人项目中,仿真是一个具有多种用途的重要方面。首先,您可以测试希望机器人执行的行为代码。其次,您可以使用仿真来测试不同类型的硬件,例如距离传感器、相机或 3D 点云传感器,看看哪种效果最好。第三,可视化模拟的相同软件可以与真正的机器人实时使用,在机器人扫描和导航环境的同时查看环境。

        在我的机器人项目中,我从 ROS1 开始,并提供了一个可以使用 RVIZ 可视化的基本机器人模型。然后,我构建了一个实用的原型,完全基于Arduino,不涉及ROS。在项目的当前阶段,我致力于构建一个与视觉传感器兼容的 Gazebo 模型。

        本文继续该系列,使用 Gazebo 快速启动 ROS2 模拟。我们将了解创建模拟的基本工具 - ROS启动文件和Gazebo - 并学习应用基本步骤 - 选择3D模型,将它们放置在世界上。

        本文的技术背景是 Ubuntu 20.04、ROS2 Foxy、Gazebo11,但它也应该适用于较新的版本。

二、基本机器人仿真术语

        本段简要列出了理解物理仿真方面所必需的所有术语。如果您对词汇量很坚定,请跳过本节。

  • 运动学:运动学是物理学的一个分支,它控制着身体在时间、位置、速度和加速度方面的运动方式,而不考虑身体的重量或向外力,如重力
  • 动力学:物理学的另一个分支,它考虑当物体有质量并受到力影响时物体的位置、速度和加速度如何变化。(在机器人中,这也称为机器人动力学)
  • 里程计:一种通过连续记录运动数据来估计物体位置并计算物体移动的距离和轨迹的方法
  • 惯性:这种力是运动物体对任何其他会改变其方向、速度或加速度的力的阻力
  • 摩擦力:当两个物体靠近另一个物体移动并抵抗该移动时施加的力
  • 关节:关节是连接两个物体的机械元件。关节有不同的类型来描述连接的物体如何移动。

来源:ROS机器人编程书

  • RPY 值:此首字母缩略词代表横滚、俯仰、偏航,用于描述物体在 3D 空间中的运动。对象可以根据下图在这三个轴上移动:

来源: wikipedia.org

三、循序渐进:如何创建模拟世界

Gazebo是在ROS之外开始的,但后来完全整合了。它更侧重于机器人和世界的完整物理模拟。特别是,世界通过物理引擎提供正确的物理模拟:机器人可以撞到物体,这些物体会移动,最终甚至撞到你的机器人身上。Gazebo 带有预定义的世界模型,您甚至可以定义自己的模型。

在本教程中,我们将启动一个带有空世界的凉亭模拟,然后在里面生成一个机器人。简而言之,基本步骤是:

  • 创建新的 ROS 包并设置目录结构
  • 创建一个空的坐标定位文件
  • 创建启动文件
  • 在机器人 URDF 模型中添加其他物理属性
  • 参数化机器人 URDF 模型以使用 Gazebo 或 RVIZ 运行。
  • 用启动文件开始空的世界

以下各节详细介绍了这些任务。

3.1 第 1 步:包创建和目录结构

        我们将创建一个如下所示的包结构:

radu_gazebo/
├── config
│   └── rviz.config
├── launch
│   └── launch.py
├── radu_bot
│   └── __init__.py
├── resource
├── scripts
├── test
├── urdf
│   └── core.xacro
└── worlds
│   └── room.world
├── package.xml
├── setup.cfg
├── setup.py

为方便起见,只需运行以下命令:

ros2 pkg create  --build-type python radu_gazebo
mkdir radu_gazebo/launch radu_gazebo/world
mkdir radu_gazebo/launch radu_gazebo/world/room.world
touch radu_gazebo/launch/room.launch

3.2 第 2 步:清空坐标定位文件

        该文件是一个SDF文件,将包含我们想要模拟的所有内容的标签:墙壁,窗户和家具等对象。我们将从一个简单的空白世界开始,并逐步添加新对象。room.world<model>

<!-- FILE: world/room.world -->
<?xml version='1.0'?>
<sdf version="1.6">
<world name="room">
  <include>
    <uri>model://sun</uri>
  </include>
  <include>
    <uri>model://ground_plane</uri>
  </include>
</world>
</sdf>

您可以手动将此文件加载到凉亭中。但是由于我们最终也将在这个模型中生成一个机器人,因此最好继续直接启动文件。

3.3 步骤 3:启动文件

        正如我们在上一篇文章中了解到的,ROS2 不再支持 XML 启动文件,而是使用 Python 文件。

        我们使用的启动文件包装包中的启动命令,并提供一个世界参数。gazebo_ros

#!/usr/bin/python3
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
package_name = 'radu_bot'
world_file = 'room.world'
def generate_launch_description():
    pkg_gazebo_ros = get_package_share_directory('gazebo_ros')
    pkg_radu_simulation = get_package_share_directory(package_name)
    # launch Gazebo by including its definition
    gazebo = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(pkg_gazebo_ros, 'launch', 'gazebo.launch.py'),
        )
    )
    # load the world file
    world_arg = DeclareLaunchArgument(
          'world',
          default_value=[os.path.join(pkg_radu_simulation, 'worlds', world_file), ''],
          description='SDF world file')
    return LaunchDescription([
        gazebo,
        world_arg
    ])

3.4 第 4 步:使用 Gazebo 标签扩展机器人模型

        为了在凉亭中使用RViz的URDF模型,我们需要对模型进行一些更改。

        首先,我们需要为机器人提供额外的物理方面,以便它在模拟中正确运行。其次,机器人的视觉外观不同。RVIZ 模型的颜色和文本定义不适用。如果使用网格,也需要更改它们。第三,我们还需要额外的插件,以便 Gazebo 工具正常工作

        让我们逐步查看这些更改。

3.5 物理模拟属性

惯性

物体的惯性是当其当前运动受到另一个物体影响时施加的反作用力。在凉亭模型中,标签用于表示这一方面。<inertial>

下面是一个示例:

<link name="base_link">
  <inertial>
    <origin xyz="0 0 0" rpy="0 0 0"/>
    <mass value="0.25" />
    <inertia ixx="0.000486" ixy="0.0" ixz="0.0" iyy="0.000486" iyz="0.0" izz="0.000729"/>
  </inertial>
  <visual>
    <origin rpy="0 0 0" xyz="0 0 0"/>
    <geometry>
        <cylinder radius="0.09" length="0.09"/>
    </geometry>
  </visual>
</link>

        标签相对于其父链接定位链接,在这里您可以更改值以移动估计的质量中心。通过您指定此链接质量(以千克为单位)。最后,该元素是 x、y 和 z 上的力如何影响链接的矩阵。您可以在维基百科上阅读物理文章,或使用这个方便的python脚本。<origin>xyz<mass><inertial>

摩擦

        另一组变量控制机器人中链接的摩擦。你用四个值来表达这一点。首先,提供静态和动态接触刚度。在这里,我们使用值和,这是许多ROS项目中使用的默认值。其次,值和是静态和动态摩擦系数,您可以根据链接的材料在维基百科上查找。<kp><kd>1000001.0<mu1><mu2>

<gazebo reference="base_link">
  <kp>100000.0</kp>
  <kd>1.0</kd>
  <mu1>10.0</mu1>
  <mu2>10.0</mu2>  
</gazebo>

碰撞

        这定义了机器人的硬材料边界——它会影响在模拟中将重力和其他力施加到机器人上的方式。这些属性由链接中的标记表示。它的属性非常简单:只需复制原始链接和值,如下所示。<collision><geometry><origin>

<link name="base_link">
  <inertial>
    <origin xyz="0 0 0" rpy="0 0 0"/>
    <mass value="0.25" />
    <inertia ixx="0.000486" ixy="0.0" ixz="0.0" iyy="0.000486" iyz="0.0" izz="0.000729"/>
  </inertial>
  <visual>
    <origin rpy="0 0 0" xyz="0 0 0"/>
    <geometry>
        <cylinder radius="0.09" length="0.09"/>
    </geometry>
  </visual>
  <collision>
    <origin rpy="0 0 0" xyz="0 0 0"/>
    <geometry>
        <cylinder radius="0.09" length="0.09"/>
    </geometry>
  </collision>
</link>

关节特性

机器人中的关节应进一步建模,以表达其真实世界的行为。

  • 对于所有非静态、非连续接头,集合和值<upper><lower>
  • 对于所有连续接头,添加和限制<effort><velocity>
<joint name="camera_joint">
  <limit upper="0.5" lower="-0.5"/>
</joint>
<joint name="left_wheel_joint">
  <limit effort="0.1" velocity="0.005"/>
</joint>

3.6 可视化模拟属性

要更改机器人的视觉效果,您有以下选项:

简单的颜色

这与 RViz 中的工作方式相同:在链接标签中,您可以引用一个元素。<visual><color>

<material name="blue">
  <color rgba="0 0 0.8 1"/>
</material>
<link name="camera">
  <visuals>
    <material name="blue">
  </visuals>
</link>

预定义网格

        Gazebo 提供了一组内置网格,这些网格在此源代码文件中列出。应用它们,在标签内添加标签,如下所示。<material><gazebo>

<gazebo reference="base_link">
  <material>Gazebo/Grey</material>  
</gazebo>

自定义网格

        使用自定义网格表示链接时,只需在链接的标记中引用它们,如下所示:<geometry>

<link name="camera">
  <mesh filename:"package://radu_bot/model/meshes/camera.dae" />
</link>

        重要提示:建议不要在标签中使用自定义网格文件,因为这会影响仿真性能。相反,请根据可用的盒子、圆柱体和球体类型定义值。<collision><geometry>

3.7 第 5 步:参数化机器人 URDF 模型以使用 Gazebo 或 RViz 跑步

        如您所见,所需的更改是根本性的。而且它们不向后兼容:Gazebo 所需的所有更改都无法被 RVIZ 解析。

        由于这些原因,复杂的机器人项目将URDF方面分成不同的XACRO文件。经过一些实验,我想出了以下层次结构。

  • core- 包含用于渲染机器人链接和关节的核心宏
  • rviz- RVIZ主文件,它定义参数并导入其他文件
  • rviz_viusals- 定义机器人在RViz中的可视化方式
  • gazebo- 凉亭核心文件,就像定义参数和导入其他文件一样
  • gazebo_visuals- 定义如何在凉亭中可视化机器人
  • gazebo_physics- 计算链接和标签的附加宏<inertial><collision>
  • gazebo_sensor- 添加传感器数据
  • gazebo_controll- 添加了 ROS 控制插件并定义用于渲染标签的宏<transmission>

让我们看看这种方法在实践中是如何工作的。运行 Xacro 渲染模型时,将使用命令 -o radu_rviz_compiled.urdf'。此文件将...xacro rviz.xacro

  1. 导入其他必需的文件
<xacro:include filename="$(find radu_bot)/urdf2/core.xacro"/>
<xacro:include filename="$(find radu_bot)/urdf2/visuals.xacro"/>

2. 定义控制宏执行的基本参数

<xacro:property name="gazebo_build" value="false" />
<xacro:property name="rviz_build" value="true" />

3. 执行宏以创建 URDF 模型

<xacro:box_link name="base_link" size="0.6 0.3 0.05" color="${torso_color_name}" color_rgb="${torso_color_rgb}" />
<xacro:wheel_link name="right_wheel_frontside" />
<xacro:wheel_joint name="base_link_right_wheel_frontside" parent="base_link" child="right_wheel_frontside" xyz="0.2 -0.2 -0.05" />
<xacro:wheel_link name="right_wheel_backside" />
<xacro:wheel_joint name="base_link_right_wheel_backside" parent="base_link" child="right_wheel_backside" xyz="-0.2 -0.2 -0.05" />
<xacro:wheel_link name="left_wheel_frontside" /> 
<xacro:wheel_joint name="base_link_left_wheel_frontside" parent="base_link" child="left_wheel_frontside" xyz="0.2 0.2 -0.05" />
<xacro:wheel_link name="left_wheel_backside" /> 
<xacro:wheel_joint name="base_link_left_wheel_backside" parent="base_link" child="left_wheel_backside" xyz="-0.2 0.2 -0.05" />

        在使用这种方法一段时间后,我意识到处理可变性的核心逻辑在文件内部:用于呈现链接和关节的宏具有将由主文件触发的不同块。请参阅以下定义。在第 3 行中,评估条件以添加特定于 RViz 的视觉对象。在第 14 行中,另一个条件检查凉亭物理属性并将其应用于模型。core.xacro<link><xacro:if>

<xacro:macro name="box_link" params="name size color color_rgb" >
  <link name="${name}">
    <xacro:if value="${rviz_build}">
      <visual>
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <geometry>
          <box size="${size}"/>
        </geometry>
        <material name="${color}">
          <color rgba="${color_rgb}"/>
        </material>
      </visual>
    </xacro:if>
    <xacro:if value="${gazebo_build}">
      <pose>0 0 0 0 0 0</pose>
      <xacro:box_inertia m="0.6" x="0.7" y="0.4" z="0.2"/>
      <collision name="collision_${name}">
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <geometry>
          <box size="${size}"/>
        </geometry>
      </collision>
    </xacro:if>  
  </link>
</xacro:macro>

3.8 第 6 步:生成机器人

        Gazebo 节点通过启动文件启动,但机器人需要生成到节点中。感谢博客文章如何在 ROS2 中生成机器人,我创建了以下启动文件。

#!/usr/bin/python3
import os
import sys
import rclpy
from gazebo_msgs.srv import SpawnEntity
from ament_index_python.packages import get_package_share_directory
package_name = 'radu_bot'
def main(args=None):
    rclpy.init(args=args)
    node = rclpy.create_node('minimal_client')
    cli = node.create_client(SpawnEntity, '/spawn_entity')
    sdf_file_path = (os.path.join(get_package_share_directory(package_name), 'urdf', 'radu_gazebo_compiled.urdf')),
    model = open(sdf_file_path[0], 'r').read()
    print("MODEL %s" %model)
    
    req = SpawnEntity.Request(
        name = "radu_bot",
        xml = model,
        robot_namespace = "radu",
        reference_frame = "world",
    )
    while not cli.wait_for_service(timeout_sec=1.0):
        node.get_logger().info('service not available, waiting again...')
    future = cli.call_async(req)
    rclpy.spin_until_future_complete(node, future)
    if future.result() is not None:
        node.get_logger().info(
            'Result ' + str(future.result().success) + " " + future.result().status_message)
    else:
        node.get_logger().info('Service call failed %r' % (future.exception(),))
    node.destroy_node()
    rclpy.shutdown()
if __name__ == '__main__':
    main()

启动文件还可以在启动期间转换 Xacro 文件,如diff_bot示例中所示。例如,要加载 Gazebo 配置,您需要执行以下命令:

import xacro
def generate_launch_description():
    pkg_radu_simulation = get_package_share_directory(package_name)
    robot_description_path =  os.path.join(
        pkg_radu_simulation,
        "urdf",
        "gazebo.xacro",
    )
    
    robot_description = {"robot_description": xacro.process_file(robot_description_path).toxml()}

四、启动机器人

首先,我们构建当前工作区。

$> colcon build --symlink-install --cmake-clean-first --event-handlers console_direct+ --packages-up-to radu_bot

然后我们推出凉亭。

$> ros2 launch radu_bot gazebo.launch.py 
[INFO] [launch]: All log files can be found below /home/devcon/.ros/log/2021-05-30-09-07-30-541933-giga-36879
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [gzserver-1]: process started with pid [36886]
[INFO] [gzclient   -2]: process started with pid [36889]

然后生成机器人。

$> ros2 run radu_bot spawn_radu
[INFO] [1622358479.722919377] [minimal_client]: Result True SpawnEntity: Successfully spawned entity [radu_bot]

最后,渲染机器人:

五、结论

        本文向您展示了如何从头开始在 ROS2 中创建与 Gazebo 兼容的模拟。事实证明,这是一个漫长的 过程,您需要 (1) 创建一个包,(2) 创建坐标定位文件,(3) 创建启动文件,(4) 将 Gazebo 特定标签添加到我们的机器人模型中,(5) 参数化您的机器人模型以与 Gazebo 和 RVIZ 兼容,以及 (6) 在模拟中生成机器人实体。形成所有这些步骤。添加 Gazebo 物理是学习和应用的时间密集型,我希望您也能获得宝贵的见解。最后,我们可以使用自定义启动脚本文件在 Gazebo 和 RViz 中生成 RADU。从这里,我们可以在模拟中移动机器人。

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

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

相关文章

找免费视频剪辑素材就上这6个网站

视频剪辑必备的6个免费素材网站&#xff0c;值得收藏~ 1、菜鸟图库 视频素材下载_mp4视频大全 - 菜鸟图库 菜鸟图库不仅是一个设计网站&#xff0c;它还有非常丰富的视频和音频素材&#xff0c;视频素材高清无水印&#xff0c;全部都有标签分类&#xff0c;各种类型都能找到。…

直线模组的运行注意事项

直线模组是属于高精密的传动元件&#xff0c;大家都知道&#xff0c;安装不当&#xff0c;直线模组就无法显示其高精度的优势&#xff0c;不仅如此&#xff0c;使用不当也会磨损直线模&#xff0c;针对直线模组的使用安全性事宜&#xff0c;我们切记严苛遵照有关的安全操作规程…

QuantLib学习笔记——利用quantlib绘制零息利率(zero rate)期限结构曲线

⭐️ 引言 利率&#xff0c;这个看似简单的概念&#xff0c;在金融领域有很多内涵。以这个词为基础&#xff0c;扩展出类似零息利率&#xff08;即期利率&#xff09;、远期利率等概念。本文就零息利率展开讨论&#xff0c;并绘制零息利率期限结构曲线。 ⭐️ 一些金融概念 …

TCP拥塞控制详解 | 6. 主动队列管理

网络传输问题本质上是对网络资源的共享和复用问题&#xff0c;因此拥塞控制是网络工程领域的核心问题之一&#xff0c;并且随着互联网和数据中心流量的爆炸式增长&#xff0c;相关算法和机制出现了很多创新&#xff0c;本系列是免费电子书《TCP Congestion Control: A Systems …

中小企业进销存软件哪个好?4款进销存商品管理软件推荐-亿发

在现代商业运营中&#xff0c;有效的开单记账系统是中小商户增强管理水平、优化业务流程的重要利器。市面上涌现出众多开单记账软件&#xff0c;如亿发软件、秦丝、智慧记、管家婆等&#xff0c;每款软件都有各自的优势和特点。本文帮助您了解每款软件的特点&#xff0c;为您的…

周期性函数算出其周期(python)

在日常生活中&#xff0c;总是会遇见一些周期性的函数&#xff0c;我们可以人眼看出他们是有一定规律的&#xff0c;但是我们不能准确地发现它们的周期是多少。 创建一根周期性曲线 import numpy as np import matplotlib.pyplot as plt# 定义周期性函数 def periodic_functi…

行业追踪,2023-08-21

自动复盘 2023-08-21 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

教师爱用查分利器

易查分是一款非常实用的教学工具&#xff0c;给老师们提供了便捷的学生成绩管理和学生信息管理功能。通过易查分&#xff0c;老师们可以轻松地发布学生成绩&#xff0c;录入成绩&#xff0c;并对学生信息进行有效管理&#xff0c;从而进行提高班级管理效率。 易查分能够方便地发…

通过 git上传到 gitee 仓库

介绍 Git是目前世界上最先进的分布式版本控制系统&#xff0c;有这么几个特点&#xff1a; 分布式 &#xff1a;是用来保存工程源代码历史状态的命令行工具。保存点 &#xff1a;保存点可以追溯源码中的文件&#xff0c;并能得到某个时间点上的整个工程项目额状态&#xff1b;…

在google play store 里安装expo go

参考链接&#xff1a; https://chat.xutongbao.top/

智慧医院IT运维方案,全局网络态势感知

随着医疗卫生体制改革不断深化&#xff0c;卫生行业信息化应用不断普及&#xff0c;大数据、AI、医疗物联网等技术的应用&#xff0c;快速推动“智慧医院”建设。以HIS&#xff08;医院信息系统&#xff09;、EMRS&#xff08;电子病历系统&#xff09;、PACS&#xff08;影像归…

Linux学习 3

date 显示当前时间 date -s 字符串时间 &#xff0c;设置系统时间 cal 显示当前日历&#xff0c;默认显示当前月 cal 2023 展示全年日历 find指令&#xff0c;从执行目录向下递归遍历各个子目录 find 搜索范围 选项 find /root -name hello.txt find /root -user goc fi…

Qt6之带三角形的提示框——仿ToDesk(3)

声明&#xff1a;本文仅用于用qt学习todesk界面设计&#xff1b; 如下左图有一排扩展功能的菜单&#xff0c;鼠标滑块会显示带三角形的提示框&#xff0c;本文将用qt实现如右图&#xff1a; 1、布局按钮 直接拖拽出QPushButton&#xff0c;7个&#xff0c;分别设置默认样式和…

从零开始,IntelliJ IDEA快速创建 SpringBoot 项目

准备 Java JDK8 下载 https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html 开发工具 IntelliJ IDEA 下载 https://www.jetbrains.com/idea/ 接口调试工具 Postman 下载 https://www.postman.com/downloads/ 创建项目 用IDEA创建SpringBoot项目 打…

OLED透明屏案例:揭示技术创新的无限可能性

OLED透明屏作为一项创新性技术&#xff0c;在各个领域展现出了令人惊叹的应用潜力。 那么&#xff0c;尼伽便通过介绍一些具体的OLED透明屏案例&#xff0c;探索其在智能家居、汽车行业、商业展示、航空航天、教育与培训以及医疗健康等领域的成功应用。 这些案例将展示OLED透明…

JAMstack架构:快速构建安全、高性能的现代应用

随着Web应用的快速发展&#xff0c;开发者们在寻找更加高效、安全和可维护的应用架构。JAMstack架构应运而生&#xff0c;它通过将前端、后端和部署过程分离&#xff0c;提供了一种现代化的方式来构建Web应用。在本文中&#xff0c;我们将深入探讨JAMstack架构的特点、优势以及…

人事变动?前沃尔沃汽车大中华区总裁钦培吉将加盟吉利

根据消息&#xff0c;吉利控股集团高级副总裁杨学良在今天上午通过微博宣布&#xff0c;前沃尔沃汽车大中华区总裁钦培吉将加盟吉利。钦培吉将担任吉利汽车集团销售公司副总经理&#xff0c;并负责集团渠道发展委员会的主任一职&#xff0c;向吉利汽车集团的高级副总裁林杰报告…

什么是链表,前端如何理解链表

一、什么是链表 多个元素存储的列表链表中的元素在内存中不是顺序存储的&#xff0c;而是通过“next”指针联系在一起的。 JS中的原型链 原理就是 链表结构 链表结构 {key: "A",next: {key: "B",next: {key: "C",next: null}} } //原型链 //对…

“智荟·数字未来 2023-得帆数字化高管峰会”成功举办

规模空前&#xff0c;业内最大规模AIGC低代码数字化高管峰会 近日&#xff0c;根据IDC最新数据报告&#xff0c;得帆获得2022年独立低代码厂商市场份额第一&#xff0c;这是客户对得帆最大的认可&#xff0c;也是得帆优秀产品的体现&#xff0c;除了市场份额第一之外&#xff…