【ROS】URDF:统一机器人描述格式(XML)

news2024/12/20 0:06:23

1、简述

统一机器人描述格式(URDF)是描述机器人模型的 XML 文件,支持Xacro(XML宏),使用Xacro来引用已经存在的XML块,创建更短且可读的XML文件。

2、初始URDF描述文件

URDF描述文件为XML格式,如下示例,定义机器人的常量。

<?xml version="1.0"?>
<robot name="sam_bot" xmlns:xacro="http://ros.org/wiki/xacro">
  <!-- Define robot constants -->
  <xacro:property name="base_width" value="0.31"/>
  <xacro:property name="base_length" value="0.42"/>
  <xacro:property name="base_height" value="0.18"/>

  <xacro:property name="wheel_radius" value="0.10"/>
  <xacro:property name="wheel_width" value="0.04"/>
  <xacro:property name="wheel_ygap" value="0.025"/>
  <xacro:property name="wheel_zoff" value="0.05"/>
  <xacro:property name="wheel_xoff" value="0.12"/>

  <xacro:property name="caster_xoff" value="0.14"/>
</robot>

3、示例

3.1 最终效果

使用URDF创建并在RViz中显示一个三轮小车,如下图所示:
在这里插入图片描述

3.2 安装依赖

sudo apt install ros-humble-joint-state-publisher-gui
sudo apt install ros-humble-xacro

3.3 创建功能包

mkdir -p nav2/src
cd nav2/src
ros2 pkg create --build-type ament_cmake sam_bot_description

3.4 编辑源码

3.4.1 编辑URDF描述文件

cd sam_bot_description/src/
mkdir description
cd description/
vi sam_bot_description.urdf
<?xml version="1.0"?>
<robot name="sam_bot" xmlns:xacro="http://ros.org/wiki/xacro">

  <!-- 定义机器人主底盘的大小和两个后轮的形状 -->
  <xacro:property name="base_width" value="0.31"/> 	<!-- 底盘宽 -->
  <xacro:property name="base_length" value="0.42"/> <!-- 底盘长 -->
  <xacro:property name="base_height" value="0.18"/>	<!-- 底盘高 -->
  <xacro:property name="wheel_radius" value="0.10"/><!-- 后轮半径 -->
  <xacro:property name="wheel_width" value="0.04"/> <!-- 后轮厚度 -->
  <xacro:property name="wheel_ygap" value="0.025"/>	<!-- 两轮间隙 -->
  <xacro:property name="wheel_zoff" value="0.05"/> 	<!-- 后轮在Z轴的定位 -->
  <xacro:property name="wheel_xoff" value="0.12"/> 	<!-- 后轮在X轴的定位 -->
  <xacro:property name="caster_xoff" value="0.14"/> <!-- 前轮在X轴的定位 -->

  <!-- Robot Base  -->
  <link name="base_link"><!-- link 表示一个完整组件,通过link来链接 -->
    <visual>
      <geometry><!-- 小车形状 -->
        <box size="${base_length} ${base_width} ${base_height}"/> 
      </geometry>
      <material name="Cyan"><!-- 小车颜色 -->
        <color rgba="0 1.0 1.0 1.0"/>
      </material>
    </visual>
  </link>

  <!-- Robot Footprint -->
  <link name="base_footprint"/> <!-- 添加一个关节base_footprint将其连接到 base_link-->
  <joint name="base_joint" type="fixed">
    <parent link="base_link"/>
    <child link="base_footprint"/>
    <origin xyz="0.0 0.0 ${-(wheel_radius+wheel_zoff)}" rpy="0 0 0"/>
  </joint>

  <!-- Wheels 添加两个大驱动轮 -->
  <xacro:macro name="wheel" params="prefix x_reflect y_reflect">
    <link name="${prefix}_link">
      <visual>
        <origin xyz="0 0 0" rpy="${pi/2} 0 0"/>
        <geometry>
            <cylinder radius="${wheel_radius}" length="${wheel_width}"/>
        </geometry>
        <material name="Gray">
          <color rgba="0.5 0.5 0.5 1.0"/>
        </material>
      </visual>
    </link>

    <joint name="${prefix}_joint" type="continuous">
      <parent link="base_link"/>
      <child link="${prefix}_link"/>
      <origin xyz="${x_reflect*wheel_xoff} ${y_reflect*(base_width/2+wheel_ygap)} ${-wheel_zoff}" rpy="0 0 0"/>
      <axis xyz="0 1 0"/>
    </joint>
  </xacro:macro>
  <xacro:wheel prefix="drivewhl_l" x_reflect="-1" y_reflect="1" />
  <xacro:wheel prefix="drivewhl_r" x_reflect="-1" y_reflect="-1" />

  <!-- Caster Wheel 添加前脚轮,将前脚轮建模成一个球体-->
  <link name="front_caster">
    <visual>
      <geometry>
        <sphere radius="${(wheel_radius+wheel_zoff-(base_height/2))}"/>
      </geometry>
      <material name="Cyan">
        <color rgba="0 1.0 1.0 1.0"/>
      </material>
    </visual>
  </link>
  
  <joint name="caster_joint" type="fixed">
    <parent link="base_link"/>
    <child link="front_caster"/>
    <origin xyz="${caster_xoff} 0.0 ${-(base_height/2)}" rpy="0 0 0"/>
  </joint>
  
</robot>

3.4.2 编辑launch启动文件

cd sam_bot_description/
mkdir launch
cd launch
vi display.launch.py
import launch
from launch.substitutions import Command, LaunchConfiguration
import launch_ros
import os

def generate_launch_description():
    pkg_share = launch_ros.substitutions.FindPackageShare(package='sam_bot_description').find('sam_bot_description')
    default_model_path = os.path.join(pkg_share, 'src/description/sam_bot_description.urdf')
    default_rviz_config_path = os.path.join(pkg_share, 'rviz/urdf_config.rviz')

    robot_state_publisher_node = launch_ros.actions.Node(
        package='robot_state_publisher',
        executable='robot_state_publisher',
        parameters=[{'robot_description': Command(['xacro ', LaunchConfiguration('model')])}]
    )
    joint_state_publisher_node = launch_ros.actions.Node(
        package='joint_state_publisher',
        executable='joint_state_publisher',
        name='joint_state_publisher',
        condition=launch.conditions.UnlessCondition(LaunchConfiguration('gui'))
    )
    joint_state_publisher_gui_node = launch_ros.actions.Node(
        package='joint_state_publisher_gui',
        executable='joint_state_publisher_gui',
        name='joint_state_publisher_gui',
        condition=launch.conditions.IfCondition(LaunchConfiguration('gui'))
    )
    rviz_node = launch_ros.actions.Node(
        package='rviz2',
        executable='rviz2',
        name='rviz2',
        output='screen',
        arguments=['-d', LaunchConfiguration('rvizconfig')],
    )

    return launch.LaunchDescription([
        launch.actions.DeclareLaunchArgument(name='gui', default_value='True',
                                            description='Flag to enable joint_state_publisher_gui'),
        launch.actions.DeclareLaunchArgument(name='model', default_value=default_model_path,
                                            description='Absolute path to robot urdf file'),
        launch.actions.DeclareLaunchArgument(name='rvizconfig', default_value=default_rviz_config_path,
                                            description='Absolute path to rviz config file'),
        joint_state_publisher_node,
        joint_state_publisher_gui_node,
        robot_state_publisher_node,
        rviz_node
    ])

3.4.3 编辑RViz配置文件

cd sam_bot_description/
mkdir rviz
cd rviz
vi urdf_config.rviz
Panels:
  - Class: rviz_common/Displays
    Help Height: 78
    Name: Displays
    Property Tree Widget:
      Expanded:
        - /Global Options1
        - /Status1
        - /RobotModel1/Links1
        - /TF1
      Splitter Ratio: 0.5
    Tree Height: 557
Visualization Manager:
  Class: ""
  Displays:
    - Alpha: 0.5
      Cell Size: 1
      Class: rviz_default_plugins/Grid
      Color: 160; 160; 164
      Enabled: true
      Name: Grid
    - Alpha: 0.6
      Class: rviz_default_plugins/RobotModel
      Description Topic:
        Depth: 5
        Durability Policy: Volatile
        History Policy: Keep Last
        Reliability Policy: Reliable
        Value: /robot_description
      Enabled: true
      Name: RobotModel
      Visual Enabled: true
    - Class: rviz_default_plugins/TF
      Enabled: true
      Name: TF
      Marker Scale: 0.3
      Show Arrows: true
      Show Axes: true
      Show Names: true
  Enabled: true
  Global Options:
    Background Color: 48; 48; 48
    Fixed Frame: base_link
    Frame Rate: 30
  Name: root
  Tools:
    - Class: rviz_default_plugins/Interact
      Hide Inactive Objects: true
    - Class: rviz_default_plugins/MoveCamera
    - Class: rviz_default_plugins/Select
    - Class: rviz_default_plugins/FocusCamera
    - Class: rviz_default_plugins/Measure
      Line color: 128; 128; 0
  Transformation:
    Current:
      Class: rviz_default_plugins/TF
  Value: true
  Views:
    Current:
      Class: rviz_default_plugins/Orbit
      Name: Current View
      Target Frame: <Fixed Frame>
      Value: Orbit (rviz)
    Saved: ~

3.5 添加编译依赖

1)修改package.xml

<exec_depend>joint_state_publisher</exec_depend>
<exec_depend>joint_state_publisher_gui</exec_depend>
<exec_depend>robot_state_publisher</exec_depend>
<exec_depend>rviz</exec_depend>
<exec_depend>xacro</exec_depend>

2)修改CMakeLists.txt

install(
  DIRECTORY src launch rviz
  DESTINATION share/${PROJECT_NAME}
)

3.6 编译

cd 功能包根目录
colcon build
. install/setup.bash

3.7 启动

ros2 launch sam_bot_description display.launch.py

3.8 效果

滑动Publisher窗口中的滑块,可以控制轮子旋转
在这里插入图片描述

4、URDF的官方示例

http://wiki.ros.org/urdf/Examples

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

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

相关文章

测试左移-快速玩转Debug

目录 背 景 学习的意义 玩 转 Debug 一、基本介绍 二、断点设置 三、启动调试 四、调试技巧 定 位 问 题 总 结 背 景 一段代码的问题产生阶段可以分为&#xff1a;编译期和运行时 编译期的代码可以由工具&#xff08;idea、eclipse&#xff09;在程序编码过程中提示错误…

面对对象。

1.类&#xff1a; 类&#xff1a;是对象共同特征的描述。 对象&#xff1a;是真实存在的具体实例。 先设计类&#xff0c;才能创建对象并使用。 pulic class 类名{1.成员变量&#xff08;代表属性&#xff0c;一般是名词&#xff09;2.成员方法&#xff08;代表行为&#x…

达梦主备守护集群相关概念和基本原理介绍

DM数据守护一主一备或一主多备是一种集成化的高可用、高性能数据库解决方案&#xff0c;是数据库异地容灾的首选方案。通过部署 DM 数据守护&#xff0c;可以在硬件故障&#xff08;如磁盘损坏&#xff09;、自然灾害&#xff08;地震、火灾&#xff09;等极端情况下&#xff0…

思科交换机与路由器基础命令(一)

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 作者会持续更新网络知识和python基础知识&#xff0c;期待你的关注 目录 一、Cisco交换机的命令行模式&#xff1a; 1、用户模式 2、 特权模式 3、 全局配置模式 4、 接口模式 5、退回命令 二、帮助机制 …

20. 算法之回溯算法

1. 概念 回溯算法实际上一个类似枚举的深度优先搜索尝试过程&#xff0c;主要是在搜索尝试过程中寻找问题的解&#xff0c;当发现已不满足求解条件时&#xff0c;就“回溯”返回&#xff08;也就是递归返回&#xff09;&#xff0c;尝试别的路径。 回溯的处理思想&#xff0c…

必备:音乐的魅力,一边听歌一边练习英语!

音乐是一种跨越语言和文化的艺术形式&#xff0c;能够带给我们无限的感动和快乐。下面是我推荐的一些好听的英文歌曲&#xff0c;希望大家喜欢。 这首歌是英国歌手Ed Sheeran的代表作之一&#xff0c;曲调轻快&#xff0c;旋律优美&#xff0c;歌词简单易懂&#xff0c;非常容…

搞懂mysql事物隔离级别

事物是为交易而生 事物的英文单词 TRANSACTION,就是交易的意思. 交易和事物是一个东西. mysql的事物的4种隔离级别 mysql的事物隔离级设计的一点也不高级 隔离级别只是一个很烧脑的概念,并不是什么高大上的技术. RU,全称read-uncommitted, 中文翻译:读未提交,能够读到未提交…

static关键字在C语言中的作用

static关键字有三个主要作用&#xff1a; 1.修饰全局变量 2.修饰函数 3.修饰局部变量 (1)首先是修饰全局变量&#xff0c;就是变量只能在本文件中使用&#xff0c;不能在其他文件中使用 代码示例&#xff1a;vi 1.c vi 2.c 编译&#xff1a;gcc 1.c 2.c -o main ./main …

指定数组的维度,返回由随机数构成的数组numpy.random.ranf()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 指定数组的维度&#xff0c; 返回由随机数构成的数组 numpy.random.ranf() 选择题 以下说法错误的是? import numpy as np print("【执行1】np.random.ranf()") print(np.random.ra…

Redis整合jedis 学习

前言 redis简单来讲是内存数据库&#xff0c;因为是将数据存放到内存&#xff0c;因此读写速率高快(传统数据库&#xff0c;不是先从内存转到硬存&#xff0c;慢) 1.jedis连接Redis redis是java操作redis的客户端&#xff0c;通过他我们能通过java语句操控redis。 jedis对于…

Vue使用Echarts折线图,实现点击播放、暂停、选择播放倍数;实现数据直播功能

文章目录 &#x1f31f;前言&#x1f31f;先看效果&#x1f31f;整体代码&#xff08;详细注释&#xff09;&#x1f31f;写在最后 &#x1f31f;前言 哈喽小伙伴们&#xff0c;最近公司有个小需求&#xff0c;就是基于Echarts的折线图&#xff0c;做一个数据直播的功能&#…

manacher(图文详解)

文章目录 简要介绍实际应用算法详解 简要介绍 马拉车算法&#xff0c;Manacher‘s Algorithm 是用来查找一个字符串的最长回文子串的线性方法&#xff0c;是一个叫Manacher的人在1975年发明的&#xff0c;这个方法的最大贡献是在于将时间复杂度提升到了线性O(N)。 实际应用 刷…

玩转脚本实现自动化

目录 前言&#xff1a; 自动化原理 前置和后置脚本的区别&#xff08;它们的功能就如同名字一样&#xff09; 淘宝联盟接入文档 签名算法 调用示例 配置环境参数 设置全局变量 设置相关环境下的服务器地址 开始分析参数指定规则 添加接口 前言&#xff1a; 自动化测…

shell索引数组变量-定义获取拼接删除

目录 介绍数组的定义演示 数组的获取数组的拼接演示&#xff1a; 数组的删除 介绍 Shell 支持数组&#xff08;Array&#xff09;, 数组是若干数据的集合&#xff0c;其中的每一份数据都称为数组的元素。 &#xff08; 注意Bash Shell 只支持一维数组&#xff0c;不支持多维数组…

如何在ASP.NET Core应用中实现与第三方IoC/DI框架的整合?

我们知道整个ASP.NET Core建立在以ServiceCollection/ServiceProvider为核心的DI框架上&#xff0c;它甚至提供了扩展点使我们可以与第三方DI框架进行整合。对此比较了解的读者朋友应该很清楚&#xff0c;针对第三方DI框架的整合可以通过在定义Startup类型的ConfigureServices方…

大学毕业生自荐信范文

大学毕业生自荐信范文1 尊敬的贵公司领导&#xff1a; 您好&#xff01; 首先感谢您对我的关注&#xff0c;在我即将走出校门的时候&#xff0c;给我一次宝贵的工作机会。 学习了两年的会计专业相关知识后&#xff0c;已经使得我对会计行业有了深刻的认识。技能要靠经验&#x…

7.OpenCV-图像轮廓

1.通过OpenCV的findContours可以很方便的找到图片中内容的轮廓。 2.为了提取轮廓有更高的准确率&#xff0c;在提取轮廓前&#xff0c;需要对图片进行预处理&#xff08;二值阈值&#xff09;&#xff0c;只保留感兴趣的图像。 3.通过计算轮廓面积与外接矩形或外接圆的面积&a…

2023年6/16 操作系统小知识点

目录 分值第二章1. 进程状态转化的条件2. 进程控制块概念&#xff0c;作用&#xff0c;构成。3. 进程上下文概念&#xff0c;组成4. 进程的创建过程以及步骤5. 作业调度和低级调度算法&#xff0c;基本思想&#xff0c;7个&#xff0c;都要掌握6. 线程概念和处理过程7. 为什么有…

【玩转Docker小鲸鱼叭】虚拟化技术是什么?

到底什么是虚拟化&#xff1f; Docker 是一款基于容器虚拟化技术构建的软件&#xff0c;那到底什么虚拟化技术呢&#xff1f;在学习Docker之前&#xff0c;先简单了解下虚拟化技术。 虚拟化是云原生的实现基础&#xff0c;它能够帮助我们更加有效地利用物理计算机硬件。 虚拟…

德国Kipu Quantum与法国Pasqal合作优化量子算法

​ &#xff08;图片来源&#xff1a;网络&#xff09; 6月12日&#xff0c;德国量子软件公司Kipu Quantum宣布与法国中性原子量子计算领域的领导者PASQAL达成为期两年的研发协议&#xff0c;以优化量子算法功能&#xff0c;并为企业加速带来量子效益。 Kipu Quantum专注于为特…