[ROS 系列学习教程] 建模与仿真 - URDF 建模实践

在这里插入图片描述

ROS 系列学习教程(总目录)

本文目录

  • 一、机器人结构组成
  • 二、新建功能包
  • 三、编写launch文件
  • 四、创建底盘
  • 五、添加轮子
  • 六、添加其他部件
  • 七、解决部分实体位于地面以下的问题

前文介绍了URDF建模与URDF语法,接下来介绍怎么使用URDF从零构建一个机器人模型并在rviz中显示。

一、机器人结构组成

最终效果如下图:

在这里插入图片描述

机器人由如下部分组成:

  • 底盘 * 1
  • 主动轮 * 2
  • 从动轮(脚轮)* 2
  • 激光雷达 * 1
  • RGB相机 * 1

二、新建功能包

为面向零基础的同学,使教学清晰,新建一个功能包用于学习该章节,新建功能包方法见前文,功能包结构如下:

在这里插入图片描述

其中,

  • config :存放rviz配置文件
  • launch :存放launch文件
  • meshes :存放模型渲染文件
  • models :存放模型文件
  • src与include :存放源文件和头文件

关于ROS工作空间与功能包的创建,详见 ROS Hello World

三、编写launch文件

如前文所述,rviz显示urdf模型需要先把模型参数注册到参数服务器,然后打开rviz,在rviz中配置好后才能正常显示模型。这些步骤可以手动一步一步完成,也可以编写launch文件快速执行。

另外,对于包含多个link的模型,需要发布link间的jointtf关系,以使rviz可以确定link间的空间位置。ROS提供了 joint_state_publisherrobot_state_publisher 两个功能包来实现linkjointtf关系的发布,如没有安装这两个功能包,可以使用如下命令安装(以noetic为例):

sudo apt install ros-noetic-joint-state-publisher
sudo apt install ros-noetic-robot-state-publisher

launch文件内容如下:

<launch>
    <param name="robot_description" textfile="$(find simulation_learning)/models/urdf/mbot_base.urdf" />

    <!-- 设置GUI参数,显示关节控制插件 -->
    <param name="use_gui" value="true" />

    <!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />

    <!-- 运行robot_state_publisher节点,发布tf  -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />

    <!-- 运行rviz可视化界面,并加载配置 -->
    <node name="rviz" pkg="rviz" type="rviz" args="-d $(find simulation_learning)/config/mbot_urdf.rviz" required="true" />
</launch>

关于launch文件的具体描述,见[4.1 launch文件](#4.1 launch文件)

四、创建底盘

models/urdf中创建mbot_base.urdf文件,用于编写urdf模型。

底盘是一个圆柱体,半径为 0.2m,高为0.16m,urdf代码如下:

<?xml version="1.0"?>
<robot name="mbot">
    <link name="base_link">
        <visual>
            <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="0.16" radius="0.20" />
            </geometry>
            <material name="yellow">
                <color rgba="1 0.4 0 1" />
            </material>
        </visual>
    </link>
</robot>

运行 launch 文件,结果如下:

在这里插入图片描述

这里注意base_link的原点位于圆柱体的几何中心,即有一半圆柱体是位于地面以下的,这一点到最后会解决,目前先把机器人模型搭建起来。

五、添加轮子

轮子是小一点的圆柱体,半径为 0.06m,高为0.025m

现在有了两个实体,底盘和一个轮子,需要使用joint说明他们之间的几何与运动关系,否则rviz解析urdf时会报错。

urdf代码如下:

<!-- 底盘实体描述 -->
<link name="base_link">
    <visual>
        <origin xyz=" 0 0 0" rpy="0 0 0" />
        <geometry>
            <cylinder length="0.16" radius="0.20" />
        </geometry>
        <material name="yellow">
            <color rgba="1 0.4 0 1" />
        </material>
    </visual>
</link>

<!-- 左轮与底盘的关节描述 -->
<joint name="left_wheel_joint" type="continuous">
    <origin xyz="0 0.19 -0.05" rpy="0 0 0" />
    <parent link="base_link" />
    <child link="left_wheel_link" />
    <axis xyz="0 1 0" />
</joint>

<!-- 左轮实体描述 -->
<link name="left_wheel_link">
    <visual>
        <origin xyz="0 0 0" rpy="1.5707 0 0" />
        <geometry>
            <cylinder radius="0.06" length="0.025" />
        </geometry>
        <material name="white">
            <color rgba="1 1 1 0.9" />
        </material>
    </visual>
</link>

其中,joint中的type描述了关节类型(机械中的运动副),该类型为旋转类型(机械中的旋转副),origin表示左轮原点相对于底盘原点的空间位姿偏移,parentchild分别表示该关节的父实体和子实体,由于该关节为旋转关节,使用axis定义旋转轴。关于joint的具体描述见 建模与仿真 - URDF 语法介绍。

运行 launch 文件,结果如下:

在这里插入图片描述

六、添加其他部件

其他部件同理,添加实体与相应的关节描述。

完整的urdf代码如下:

<?xml version="1.0"?>
<robot name="mbot">

    <!-- 底盘实体描述 -->
    <link name="base_link">
        <visual>
            <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="0.16" radius="0.20" />
            </geometry>
            <material name="yellow">
                <color rgba="1 0.4 0 1" />
            </material>
        </visual>
    </link>

    <!-- 左轮与底盘的关节描述 -->
    <joint name="left_wheel_joint" type="continuous">
        <origin xyz="0 0.19 -0.05" rpy="0 0 0" />
        <parent link="base_link" />
        <child link="left_wheel_link" />
        <axis xyz="0 1 0" />
    </joint>

    <!-- 左轮实体描述 -->
    <link name="left_wheel_link">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0" />
            <geometry>
                <cylinder radius="0.06" length="0.025" />
            </geometry>
            <material name="white">
                <color rgba="1 1 1 0.9" />
            </material>
        </visual>
    </link>

    <!-- 右轮与底盘的关节描述 -->
    <joint name="right_wheel_joint" type="continuous">
        <origin xyz="0 -0.19 -0.05" rpy="0 0 0" />
        <parent link="base_link" />
        <child link="right_wheel_link" />
        <axis xyz="0 1 0" />
    </joint>

    <!-- 右轮实体描述 -->
    <link name="right_wheel_link">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0" />
            <geometry>
                <cylinder radius="0.06" length="0.025" />
            </geometry>
            <material name="white">
                <color rgba="1 1 1 0.9" />
            </material>
        </visual>
    </link>

    <!-- 前脚轮实体描述 -->
    <joint name="front_caster_joint" type="continuous">
        <origin xyz="0.18 0 -0.095" rpy="0 0 0" />
        <parent link="base_link" />
        <child link="front_caster_link" />
        <axis xyz="0 1 0" />
    </joint>

    <!-- 前脚轮和底盘的关节描述 -->
    <link name="front_caster_link">
        <visual>
            <origin xyz="0 0 0" rpy="0 0 0" />
            <geometry>
                <sphere radius="0.015" />
            </geometry>
            <material name="black">
                <color rgba="0 0 0 0.95" />
            </material>
        </visual>
    </link>

    <!-- 后脚轮实体描述 -->
    <joint name="back_caster_joint" type="continuous">
        <origin xyz="-0.18 0 -0.095" rpy="0 0 0" />
        <parent link="base_link" />
        <child link="back_caster_link" />
        <axis xyz="0 1 0" />
    </joint>

    <!-- 后脚轮和底盘的关节描述 -->
    <link name="back_caster_link">
        <visual>
            <origin xyz="0 0 0" rpy="0 0 0" />
            <geometry>
                <sphere radius="0.015" />
            </geometry>
            <material name="black">
                <color rgba="0 0 0 0.95" />
            </material>
        </visual>
    </link>

    <!-- 激光雷达实体描述 -->
    <link name="laser_link">
        <visual>
            <origin xyz=" 0 0 0 " rpy="0 0 0" />
            <geometry>
                <cylinder length="0.05" radius="0.05" />
            </geometry>
            <material name="gray">
                <color rgba="0.25 0.25 0.25 0.95" />
            </material>
        </visual>
    </link>

    <!-- 激光雷达和底盘的关节描述 -->
    <joint name="laser_joint" type="fixed">
        <origin xyz="0 0 0.105" rpy="0 0 0" />
        <parent link="base_link" />
        <child link="laser_link" />
    </joint>

    <!-- 相机实体描述 -->
    <link name="camera_link">
        <visual>
            <origin xyz=" 0 0 0 " rpy="0 1.57 0" />
            <geometry>
                <cylinder radius="0.02" length = "0.05"/>
            </geometry>
            <material name="gray">
                <color rgba="0.25 0.25 0.25 0.95"/>
            </material>
        </visual>
    </link>

    <!-- 相机和底盘的关节描述 -->
    <joint name="camera_joint" type="fixed">
        <origin xyz="0.18 0 0.055" rpy="0 0 0"/>
        <parent link="base_link"/>
        <child link="camera_link"/>
    </joint>

</robot>

运行 launch 文件,结果如下:

在这里插入图片描述

七、解决部分实体位于地面以下的问题

首先明确我们的 Fixed Framebase_linkFixed Frame 可以理解为世界坐标系,对于我们的设置就是base_link即当前的世界,rviz默认一切都是从世界中心诞生。

实体位于地面以下,是由于我们设置的其他实体都是以世界中心为参考而又认为地面在轮子下方,但rviz认为地面原点在世界中心,所以看起来和我们的认知有些冲突。

解决办法有多种,但基本都是改变base_link或其他实体与世界中心的关系。

方法一:

比较常见的一种:新增floor_link作为 Fixed Frame 世界坐标系,base_link作为他的子级。这种方法对现有已经完成的模型修改最少。

在urdf文件中新增如下内容即可:

<!-- 地面实体描述 -->
<link name="floor_link">
    <visual>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <geometry>
            <!-- 圆柱体高度尽量小,已达到可忽略的精度 -->
            <cylinder length="0.000001" radius="0.20" />
        </geometry>
        <material name="floor">
            <color rgba="1 0.4 0 0" />
        </material>
    </visual>
</link>

<!-- 底盘与地面的关节关系描述 -->
<joint name="base_joint" type="continuous">
    <origin xyz="0 0 0.11" rpy="0 0 0" />
    <parent link="floor_link" />
    <child link="base_link" />
    <axis xyz="0 1 0" />
</joint>

结果如下:

在这里插入图片描述

使用rviz查看TF关系如下:

在这里插入图片描述

新增的floor_link如图中框选,但这种方法在工程上很难测量base_link的实际位置,所以就有了方法二。

方法二:

floor_link直接命名为base_link,其他实体都以它为基准,但位置描述都要作相应的修改,这种方法对于现有已经完成的模型修改较多,对新工程比较友好,各实体的实际位置也很容易通过测量得到。

修改后的TF树如下,此时base_link位于世界原点,也是机器人底盘原点在地面的投影点。

在这里插入图片描述

机器人的外观显示和方法一一样:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络爬虫安全:90后小伙,用软件非法搬运他人原创视频被判刑

目录 违法视频搬运软件是网络爬虫 如何发现偷盗视频的爬虫&#xff1f; 拦截违法网络爬虫 央视《今日说法》栏目近日报道了一名程序员开发非法视频搬运软件获利超700多万&#xff0c;最终获刑的案例。 国内某知名短视频平台报警称&#xff0c;有人在网络上售卖一款视频搬运…

2024年最新最全面的软件测试面试题(四)

1、在项目中如何保证软件质量? 项目质量不仅仅是某个人或某个团队来保障的&#xff0c;而是整个团队一起努力的结果&#xff0c;因此&#xff0c;在公司级别需要 有一个规范的项目流程。 产品&#xff0c;保证迭代过程中的产品逻辑&#xff0c;对于可能的兼容&#xff0c;升…

C++列表实现

文章目录 一、listView相关内容主要思想实例全部代码 二、QTreeView 一、listView 相关内容 QAbstractItemModel&#xff1a;一个抽象的类&#xff0c;为数据项模型提供抽象的接口&#xff0c;常见的的数据模型列如&#xff1a;QStringListModel,QStandardItemMode,QDirModel…

(实测验证)Gitee代码托管尝试(一)——克隆/下载

一、登录 Gitee&#xff08;码云&#xff09;代码托管平台&#xff1a; Gitee - 基于 Git 的代码托管和研发协作平台 新建个人账户如下&#xff1a; 二、SSH 公钥设置 1、在git安装目录打开“git-cmd.exe”; 2、通过命令 ssh-keygen 生成 SSH Key&#xff1a; ssh-keygen …

社区服务用工具建立与居民的强关系

在数字化时代的浪潮下&#xff0c;社区服务不再局限于传统的面对面交流模式&#xff0c;而是借助互联网医疗健康服务应用&#xff0c;尤其是智慧康养服务平台&#xff0c;构建起了与居民之间更为紧密、便捷的联系。这种新型的社区服务模式&#xff0c;不仅提升了服务效率&#…

PDK安装及简介

目录 PDK简介 pdk安装 Standard Cell Library简介 IO Library简介 PDK简介 PDK&#xff1a;全称Process Design Kit&#xff0c;是工艺设计工具包的缩写&#xff0c;是制造和设计之间的沟通桥梁&#xff0c;是模拟电路设计的起始点。 具体来说&#xff0c;PDK是代工厂(FAB…

webhook 和 API:你了解吗

Webhooks 是许多 API 的补充。通过设置 webhook 系统&#xff0c;系统 B 可以注册接收有关系统 A 某些更改的通知。当更改发生时&#xff0c;系统 A 推送 更改到系统 B&#xff0c;通常是以发出 HTTP POST 请求的形式。 Webhooks 旨在消除或减少不断轮询数据的需要。但根据我的…

【Axure原型分享】动态伸缩组织架构图

今天和大家分享动态伸缩组织架构图图原型模板&#xff0c;我们可以通过点击加减按钮来展开或收起子内容&#xff0c;具体效果可以点击下方视频观看或者打开预览地址来体验 【原型效果】 【Axure高保真原型】动态伸缩组织架构图 【原型预览含下载地址】 https://axhub.im/ax9/…

AI大模型探索之路-训练篇23:ChatGLM3微调实战-基于P-Tuning V2技术的实践指南

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

【计算机毕业设计】springboot成都奥科厨具厂产品在线销售系统设计与实现

时代在飞速进步&#xff0c;每个行业都在努力发展现在先进技术&#xff0c;通过这些先进的技术来提高自己的水平和优势&#xff0c;成都奥科厨具厂产品在线销售系统当然不能排除在外。成都奥科厨具厂产品在线销售系统是在实际应用和 软件工程的开发原理之上&#xff0c;运用jav…

《网探》:网络安全,你不得不学的知识。

有没有一些亲戚朋友联系过你&#xff0c;让你和他们一起参与某一项投资&#xff1f; 他们会告诉你&#xff0c;只要投入少部分钱就可以成为会员&#xff0c;今后每个月参与分红&#xff0c;投资的钱越多&#xff0c;分红越多。 而且要是你能成功带一定数量的人加入他们&#…

代码+视频,R言语处理数据中的缺失值

在SCI论文中&#xff0c;我们不可避免和缺失数据打交道&#xff0c;特别是在回顾性研究&#xff0c;对于缺失的协变量&#xff08;就是混杂因素&#xff09;&#xff0c;我们可以使用插补补齐数据&#xff0c;但是对于结局变量和原因变量的缺失&#xff0c;我们不能这么做。部分…

网络审计:为什么定期检查您的网络很重要

在数字化时代&#xff0c;网络安全成为组织和个人必须面对的重要挑战。网络审计是一种关键的安全措施&#xff0c;通过定期检查和评估网络系统的安全性&#xff0c;帮助发现潜在的安全漏洞和弱点&#xff0c;从而防止数据泄露和其他安全威胁。本文将介绍网络审计的重要性&#…

不干人事的表达式:(void)0

assert是C语言的一个宏。在<assert.h>中可以找到它的定义&#xff1a; #ifdef NDEBUG#define assert(_Expression) ((void)0) #else /* !defined (NDEBUG) */// 省略... #endif /* !defined (NDEBUG) */ 其用法在“捕捉错误的assert”一文中已有说明。 决定assert是否…

【计算机毕业设计】springboot超市在线销售系统的设计与实现

当今社会已经步入了科学技术进步和经济社会快速发展的新时期&#xff0c;国际信息和学术交流也不断加强&#xff0c; 计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统超市在线销售采取了人工的管理方法&#xff0c…

sqlite3命令行工具无法退出问题处理

一、背景&#xff1a; 软件使用的后台数据库为sqlite&#xff0c;linux主机系统层面使用sqlite3命令行工具登录数据库后&#xff0c;无法执行sql脚本&#xff0c;无法退出sqlite3。无法执行ctrlc&#xff0c;执行ctrlz后sqlite3前台进程被中断&#xff0c;但是该进程没有退出。…

PADS:生成自交叉平面区域

根据板外形铺铜方法&#xff1a; pads根据板外形铺铜_铺铜如何根据板子形状改变-CSDN博客 根据板外形创建平面区域出现问题&#xff1a; 解决方法&#xff1a;去找结构&#xff0c;让他把出图之前把线合并了

笔记3:torch训练测试VGG网络

&#xff08;1&#xff09;利用Netron查看网络实际情况 上图链接 python生成上图代码如下&#xff0c;其中GETVGGnet是搭建VGG网络的程序GETVGGnet.py&#xff0c;VGGnet是该程序中的搭建网络类。netron是需要pip安装的可视化库&#xff0c;注意do_constant_foldingFalse可以防…

26 分钟惊讶世界,GPT-4o 引领未来人机交互

前言 原文链接&#xff1a;OpenAI最新模型——GPT-4o&#xff0c;实时语音视频交互&#xff0c;未来人机交互近在眼前 - Kaiho小站 北京时间 5 月 14 日凌晨&#xff0c;OpenAI 发布新一代模型——GPT-4o&#xff0c;仅在 ChatGPT 面世 17 个月后&#xff0c;OpenAI 再次通过…

掌握这些神器,让你的编程之路更加“丝滑”

前言&#xff1a; 在软件开发的旅程中&#xff0c;程序员的实用神器确实如同指南针&#xff0c;帮助他们在复杂的代码海洋中导航。以下是从三个方向——自动化测试工具、持续集成/持续部署&#xff08;CI/CD&#xff09;以及代码审查与质量分析——来探讨这些实用神器的应用和影…