[ROS 系列学习教程] 建模与仿真 - 使用 Xacro 优化 urdf

在这里插入图片描述

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

本文目录

  • 一、使用属性表示常量
  • 二、使用公式
  • 三、使用宏定义
  • 四、include 其他文件
  • 五、优化实践

对于前文介绍的 urdf 模型,我们可以使用 xacro 来优化,使其更易于维护。

优化点:

  1. 多次用到的尺寸用常量定义
  2. 计算使用公式表示,增加可读性
  3. 重复结构用宏定义
  4. 可复用的结构模块用单独文件编写,使用时在其他文件 include

一、使用属性表示常量

对于一些多次用到的常量,可以使用属性表示,以实现更好的可读性与可维护性。

<!-- 属性列表 -->
<xacro:property name="M_PI" value="3.1415926"/>
<xacro:property name="base_radius" value="0.20"/>
<xacro:property name="base_length" value="0.16"/>

<xacro:property name="wheel_radius" value="0.06"/>
<xacro:property name="wheel_length" value="0.025"/>
<xacro:property name="wheel_joint_y" value="0.19"/>
<xacro:property name="wheel_joint_z" value="0.05"/>

<xacro:property name="caster_radius" value="0.015"/> 
<xacro:property name="caster_joint_x" value="0.18"/>

二、使用公式

需要计算的地方,在urdf中一般是计算好后,将结果填入用的地方,但这样就隐藏掉了计算过程,无论是可读性还是维护性都不好。
从 ROS Jade 开始,Xacro支持了 Python 表达式的解析,可以使用 Python 表达式编写计算公式,使代码复用性更强。
比如计算底盘与地面的joint,可以根据常量脚轮半径(caster_radius)与 底盘高(base_length)计算,如下:

<joint name="base_footprint_joint" type="fixed">
    <origin xyz="0 0 ${base_length/2 + caster_radius*2}" rpy="0 0 0" />
    <parent link="base_footprint" />
    <child link="base_link" />
</joint>

三、使用宏定义

使用宏可以封装复杂计算、通用结构等,比如左右轮子、前后脚轮等都可以抽象为一个宏,通过不同入参生成不同对象。

<!-- 轮子宏定义 -->
<xacro:macro name="wheel" params="prefix reflect">
    <joint name="${prefix}_wheel_joint" type="continuous">
        <origin xyz="0 ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0" />
        <parent link="base_link" />
        <child link="${prefix}_wheel_link" />
        <axis xyz="0 1 0" />
    </joint>

    <link name="${prefix}_wheel_link">
        <visual>
            <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
            <geometry>
                <cylinder radius="${wheel_radius}" length="${wheel_length}" />
            </geometry>
            <material name="gray" />
        </visual>
    </link>
</xacro:macro>

<!-- 脚轮宏定义 -->
<xacro:macro name="caster" params="prefix reflect">
    <joint name="${prefix}_caster_joint" type="continuous">
        <origin xyz="${reflect*caster_joint_x} 0 ${-(base_length/2 + caster_radius)}"
            rpy="0 0 0" />
        <parent link="base_link" />
        <child link="${prefix}_caster_link" />
        <axis xyz="0 1 0" />
    </joint>

    <link name="${prefix}_caster_link">
        <visual>
            <origin xyz="0 0 0" rpy="0 0 0" />
            <geometry>
                <sphere radius="${caster_radius}" />
            </geometry>
            <material name="black" />
        </visual>
    </link>
</xacro:macro>

四、include 其他文件

有时同一个实体可能被多个机器人使用,比如传感器,这是可以将传感器单独用一个 xacro 文件表示,然后在其他文件中 include。

比如相机,先写一个单独的相机xacro文件 camera.xacro

<?xml version="1.0"?>
<robot name="camera" xmlns:xacro="http://www.ros.org/wiki/xacro">

    <xacro:macro name="usb_camera" params="prefix:=camera">
        <link name="${prefix}_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>
    </xacro:macro>

</robot>

然后在机器人本体的xacro文件中include这个 camera.xacro

<?xml version="1.0"?>
<robot name="mbot_with_camera" xmlns:xacro="http://www.ros.org/wiki/xacro">

    <xacro:include filename="$(find simulation_learning)/models/xacro/base.xacro" />
    <xacro:include filename="$(find simulation_learning)/models/xacro/sensors/camera.xacro" />

    <xacro:property name="camera_offset_x" value="0.18" />
    <xacro:property name="camera_offset_y" value="0" />
    <xacro:property name="camera_offset_z" value="0.055" />

    <!-- 调用base宏 -->
    <xacro:mbot_base />

    <!-- Camera -->
    <joint name="camera_joint" type="fixed">
        <origin xyz="${camera_offset_x} ${camera_offset_y} ${camera_offset_z}" rpy="0 0 0" />
        <parent link="base_link" />
        <child link="camera_link" />
    </joint>

    <!-- 调用Camera宏 -->
    <xacro:usb_camera prefix="camera" />

</robot>

这里注意,Xacro的 xacro:include 会把被include的文件内容解析展开到 xacro:include 的位置,所以在被include的文件中,如果有宏调用等语句,也会在 xacro:include 的地方生效。

五、优化实践

对于纯urdf实现的模型,用xacro优化后如下:

优化前,完整的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>

rviz中显示结果如下:

在这里插入图片描述

使用xacro优化后:

分成四个文件:camera.xacrolaser.xacrobase.xacrombot_base_with_laser_camera.xacro

camera.xacro:

<?xml version="1.0"?>
<robot name="camera" xmlns:xacro="http://www.ros.org/wiki/xacro">

    <xacro:macro name="usb_camera" params="prefix:=camera">
        <link name="${prefix}_link">
            <visual>
                <origin xyz="0 0 0 " rpy="0 1.57 0" />
                <geometry>
                    <cylinder radius="0.02" length="0.05" />
                </geometry>
                <material name="black" />
            </visual>
        </link>
    </xacro:macro>

</robot>

laser.xacro:

<?xml version="1.0"?>
<robot name="laser" xmlns:xacro="http://www.ros.org/wiki/xacro">

    <xacro:macro name="laser" params="prefix:=laser">
        <link name="${prefix}_link">
            <visual>
                <origin xyz="0 0 0 " rpy="0 0 0" />
                <geometry>
                    <cylinder length="0.05" radius="0.05" />
                </geometry>
                <material name="black" />
            </visual>
        </link>
    </xacro:macro>

</robot>

base.xacro:

<?xml version="1.0"?>
<robot name="base" xmlns:xacro="http://www.ros.org/wiki/xacro">

    <!-- 属性列表 -->
    <xacro:property name="M_PI" value="3.1415926" />
    <xacro:property name="base_radius" value="0.20" />
    <xacro:property name="base_length" value="0.16" />

    <xacro:property name="wheel_radius" value="0.06" />
    <xacro:property name="wheel_length" value="0.025" />
    <xacro:property name="wheel_joint_y" value="0.19" />

    <xacro:property name="caster_radius" value="0.015" />
    <xacro:property name="caster_joint_x" value="0.18" />

    <!-- 颜色列表 -->
    <material name="yellow">
        <color rgba="1 0.4 0 1" />
    </material>
    <material name="black">
        <color rgba="0 0 0 0.95" />
    </material>
    <material name="gray">
        <color rgba="0.25 0.25 0.25 0.95" />
    </material>
    <material name="white">
        <color rgba="1 1 1 0.9" />
    </material>

    <!-- 轮子宏定义 -->
    <xacro:macro name="wheel" params="prefix reflect">
        <joint name="${prefix}_wheel_joint" type="continuous">
            <origin xyz="0 ${reflect*wheel_joint_y} ${wheel_radius}" rpy="0 0 0" />
            <parent link="base_link" />
            <child link="${prefix}_wheel_link" />
            <axis xyz="0 1 0" />
        </joint>

        <link name="${prefix}_wheel_link">
            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${wheel_radius}" length="${wheel_length}" />
                </geometry>
                <material name="white" />
            </visual>
        </link>
    </xacro:macro>

    <!-- 脚轮宏定义 -->
    <xacro:macro name="caster" params="prefix reflect">
        <joint name="${prefix}_caster_joint" type="continuous">
            <origin xyz="${reflect*caster_joint_x} 0 ${caster_radius}"
                rpy="0 0 0" />
            <parent link="base_link" />
            <child link="${prefix}_caster_link" />
            <axis xyz="0 1 0" />
        </joint>

        <link name="${prefix}_caster_link">
            <visual>
                <origin xyz="0 0 0" rpy="0 0 0" />
                <geometry>
                    <sphere radius="${caster_radius}" />
                </geometry>
                <material name="black" />
            </visual>
        </link>
    </xacro:macro>

    <!-- 底盘宏定义 -->
    <xacro:macro name="mbot_base">

        <link name="base_link">
            <visual>
                <origin xyz="0 0 ${2*caster_radius + base_length/2}" rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_length}" radius="${base_radius}" />
                </geometry>
                <material name="yellow" />
            </visual>
        </link>

        <!-- 调用轮子宏 -->
        <xacro:wheel prefix="left" reflect="-1" />
        <xacro:wheel prefix="right" reflect="1" />

        <!-- 调用脚轮宏 -->
        <xacro:caster prefix="front" reflect="-1" />
        <xacro:caster prefix="back" reflect="1" />
    </xacro:macro>

</robot>

mbot_base_with_laser_camera.xacro:

<?xml version="1.0"?>
<robot name="mbot_with_laser_camera" xmlns:xacro="http://www.ros.org/wiki/xacro">

    <xacro:include filename="$(find simulation_learning)/models/xacro/base.xacro" />
    <xacro:include filename="$(find simulation_learning)/models/xacro/sensors/laser.xacro" />
    <xacro:include filename="$(find simulation_learning)/models/xacro/sensors/camera.xacro" />

    <xacro:property name="laser_offset_x" value="0" />
    <xacro:property name="laser_offset_y" value="0" />
    <xacro:property name="laser_offset_z" value="${2*caster_radius + base_length + laser_length/2}" />

    <xacro:property name="camera_offset_x" value="0.18" />
    <xacro:property name="camera_offset_y" value="0" />
    <xacro:property name="camera_offset_z" value="0.165" />

    <!-- 调用base宏 -->
    <xacro:mbot_base />

    <!-- laser_joint -->
    <joint name="laser_joint" type="fixed">
        <origin xyz="${laser_offset_x} ${laser_offset_y} ${laser_offset_z}" rpy="0 0 0" />
        <parent link="base_link" />
        <child link="laser_link" />
    </joint>

    <!-- 调用laser宏 -->
    <xacro:laser prefix="laser" />

    <!-- camera_joint -->
    <joint name="camera_joint" type="fixed">
        <origin xyz="${camera_offset_x} ${camera_offset_y} ${camera_offset_z}" rpy="0 0 0" />
        <parent link="base_link" />
        <child link="camera_link" />
    </joint>

    <!-- 调用Camera宏 -->
    <xacro:usb_camera prefix="camera" />

</robot>

rviz中显示结果为:

在这里插入图片描述

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

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

相关文章

嵌入式linux系统中图片处理详解

大家好,今天给大家分享一下,嵌入式中如何进行图像处理,常见的处理方式有哪几种?这次将详细分析一下 第一:BMP图形处理方式 图形的基本特点,所有的图像文件,都是一种二进制格式文件,每一个图像文件,都可以通过解析文件中的每一组二进制数的含义来获得文件中的各种信息…

Scriptings Tracker

"Scriptings Tracker"&#xff08;脚本追踪器&#xff09;可能是一个用于追踪脚本&#xff08;scriptings&#xff09;的工具或系统。它可以用于记录和管理脚本的创建、修改、版本控制和执行情况。这种工具可能被用于软件开发、自动化任务、电影制作、戏剧等领域。 …

ubuntu系统下安装mysql的步骤详解

一、下载安装包 下载地址&#xff1a; https://dev.mysql.com/downloads/repo/apt 跳转到这个页面&#xff1a; 直接点击Download。 直接点击最下面的开始下载安装包即可。 二、将安装包下载到ubuntu系统中 先将用户切换成root用户&#xff0c;把下载好的安装包复制到桌面上&…

windows配置dns访问git , 加快访问速度保姆级教程

设置 DNS 访问 Git 需要修改电脑的 DNS 配置。下面是具体的操作流程&#xff1a; 第一步&#xff1a;打开命令提示符或终端窗口 在 Windows 系统中&#xff0c;可以按下 Win R 组合键&#xff0c;然后输入 “cmd”&#xff0c;按下 Enter 键打开命令提示符窗口。在 macOS 或 …

TCP/IP(网络编程)

一、网络每一层的作用 &#xff0a;网络接口层和物理层的作用&#xff1a;屏蔽硬件的差异&#xff0c;通过底层的驱动&#xff0c;会提供统一的接口&#xff0c;供网络层使用 &#xff0a;网络层的作用&#xff1a;实现端到端的传输 &#xff0a;传输层:数据应该交给哪一个任…

[数据集][目标检测]老鼠检测数据集VOC+YOLO格式4107张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4107 标注数量(xml文件个数)&#xff1a;4107 标注数量(txt文件个数)&#xff1a;4107 标注…

测试工具fio

一、安装部署 fio是一款优秀的磁盘IO测试工具&#xff0c;在Linux中比较常用于测试磁盘IO 其下载地址&#xff1a;https://brick.kernel.dk/snaps/fio-2.1.10.tar.gz 或者登录其官网&#xff1a;http://freshmeat.sourceforge.net/projects/fio/ 进行下载。 tar -zxvf fio-…

RabbitMQ延时队列

一、RabbitMQ下载并使用插件 1、查看RabbitMQ插件的文件路径 docker inspect rabbitmq 找到Mounts下面Name:rabbitmq_plugin的Source即为插件路径 使用 cd 进入到该目录 2、下载插件 wget https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/download…

vue前端Echars

<template><div :class"className" :style"{height:height,width:width}" /> </template><script> import * as echarts from echarts require(echarts/theme/macarons) // echarts theme 柱状图 import resize from ./mixins/re…

win10环境下nodejs安装过程

打开 https://nodejs.org/en/官网下载node.js 2.下载完成后的安装文件为node-v16.16.0-x64.msi&#xff0c;双击进行安装即可。 3.一直默认安装&#xff0c;记得可以更改安装路径 4.其他不用打勾&#xff0c;一直next&#xff0c;安装完成即可。 5.安装完成后&#xff0c;wi…

AI在线UI代码生成,不需要敲一行代码,聊聊天,上传图片,就能生成前端页面的开发神器

ioDraw的在线UI代码生成器是一款开发神器&#xff0c;它可以让您在无需编写一行代码的情况下创建前端页面。 主要优势&#xff1a; 1、极简操作&#xff1a;只需聊天或上传图片&#xff0c;即可生成响应式的Tailwind CSS代码。 2、节省时间&#xff1a;自动生成代码可以节省大…

【论文复现|智能算法改进】融合黑寡妇思想的蜣螂优化算法

目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】蜣螂优化算法&#xff08;DBO&#xff09;原理及实现 2.改进点 ICMIC混沌映射 z n 1 sin ⁡ ( α z n ) , α ∈ ( 0 , ∞ ) (1) z_{n1}\sin(\frac{\alpha}{z_n}),\alpha\in(0,\infty)\ta…

3D目标检测入门:探索OpenPCDet框架

前言 在自动驾驶和机器人视觉这两个飞速发展的领域中&#xff0c;3D目标检测技术扮演着核心角色。随着深度学习技术的突破性进展&#xff0c;3D目标检测算法的研究和应用正日益深入。OpenPCDet&#xff0c;这个由香港中文大学OpenMMLab实验室精心打造的开源工具箱&#xff0c;…

【六一儿童节】的科技奇幻旅程:解锁【机器学习】与【人工智能】的无限创意

目录 一、机器学习与人工智能简介 二、六一儿童节的特殊意义 三、项目概述&#xff1a;智能绘画助手 四、技术栈和工具 五、数据准备 六、模型训练 1. 数据预处理 2. 构建和训练模型 七、智能绘画助手的实现 1. 搭建Flask应用 2. 客户端界面 八、扩展功能与优化 1…

SQL面试题001--图文并茂解答连续登录问题

连续登录问题是经典问题&#xff0c;今天做下总结。首先对原数据进行处理成客户和日期是不重复的&#xff0c;且日期是 yyyy-MM-dd 格式&#xff0c;这样好使用日期相关的函数。 本文参考在文末&#xff0c;增加了图表&#xff0c;更加容易理解。 表&#xff1a;temp01_cust_…

从0开始制作微信小程序

目录 前言 正文 需要事先准备的 需要事先掌握的 什么是uniapp 平台应用的分类方式 什么是TypeScript 创建项目 项目文件作用 源码地址 尾声 &#x1f52d; Hi,I’m Pleasure1234&#x1f331; I’m currently learning Vue.js,SpringBoot,Computer Security and so on.&#x1…

[数据集][目标检测]旋风检测数据集VOC+YOLO格式157张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;159 标注数量(xml文件个数)&#xff1a;159 标注数量(txt文件个数)&#xff1a;159 标注类别…

代码随想录算法训练营第十一天| 20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

20. 有效的括号 题目链接&#xff1a;20. 有效的括号 文档讲解&#xff1a;代码随想录 状态&#xff1a;so easy 思路&#xff1a; 使用栈&#xff0c;如果是左括号就入栈&#xff0c;如果是右括号则判断是否和栈顶括号匹配&#xff0c;如果匹配就出栈&#xff0c;否则判断遍历…

ubuntu--Linux运行时格式

Linux运行时格式 \r 错误 用vim打开那个执行错误的 sh脚本文件 进入最后一行模式下 :set ff显示 fileformatdos 解决方法 : :set ffunix查看是否更改 : :set ff结果 : 保存退出即可 :x运行, 没有出错 * Author: cpu_code * Date: 2020-07-29 19:07:52 * LastEditTime: 2020…

MMPose-RTMO推理详解及部署实现(上)

目录 前言1. 概述1.1 MMPopse1.2 MMDeploy1.3 RTMO 2. 环境配置3. Demo测试4. ONNX导出初探5. ONNX导出代码浅析6. 剔除NMS7. 输出合并8. LayerNormalization算子导出9. 动态batch的实现10. 导出修改总结11. 拓展-MMPose中导出ONNX结语下载链接参考 前言 最近在 MMPose 上看到了…