用ROS制作我们的机器人小车: URDF简介

URDF

为了制作模拟器,首先了解下什么是URDF

什么是URDF? Unified Robot Description Format——统一机器人描述格式。

参考文献

1. ROS urdf教程:http://wiki.ros.org/urdf/Tutorials

2. 《Learning ROS for Robostic Programming》



URDF基本语法

统一机器人描述格式URDF,其实就是为了能够抽象描述一个机器人的硬件。而且URDF是基于XML的,所以阅读起来应该非常容易。

(图一)



第一版

在URDF语言中,机器人都会由各个部件(Link)通过关节(Joint)连接而成。而这里的关键就是描述部件和关节之间的关系。

在这个简单的小车模型中,一共有5个部件: 车身 + 4个轮子。 4个关节: 每个轮子一个。

于是,我们得到了最初了URDF版本 01_car_skeleton.urdf

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <robot name="test_robot">  
  2.   <link name="base_link" />  
  3.   <link name="wheel_1" />  
  4.   <link name="wheel_2" />  
  5.   <link name="wheel_3" />  
  6.   <link name="wheel_4" />  
  7.   
  8.   
  9.   <joint name="joint_base_wheel1" type="fixed">  
  10.     <parent link="base_link"/>  
  11.     <child link="wheel_1"/>  
  12.   </joint>  
  13.   
  14.   
  15.   <joint name="joint_base_wheel2" type="fixed">  
  16.     <parent link="base_link"/>  
  17.     <child link="wheel_2"/>  
  18.   </joint>  
  19.   
  20.   
  21.   <joint name="joint_base_wheel3" type="fixed">  
  22.     <parent link="base_link"/>  
  23.     <child link="wheel_3"/>  
  24.   </joint>  
  25.   
  26.   
  27.   <joint name="joint_base_wheel4" type="fixed">  
  28.     <parent link="base_link"/>  
  29.     <child link="wheel_4"/>  
  30.   </joint>  
  31. </robot>  

用<link> tag描述各个部件,<joint> tag描述各个关节。用<parent>和<child>描述关节连接的部件。

只要描述了Link和Joint之间的关系,我们很容易就能构建机器人的框架。

我们可以用如下命令来检查urdf文件是否有语法问题。

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. check_urdf 01_skeleton.urdf  

只要得到如下结果就表明语法没问题。

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. robot name is: test_robot  
  2. ---------- Successfully Parsed XML ---------------  
  3. root Link: base_link has 4 child(ren)  
  4.     child(1):  wheel_1  
  5.     child(2):  wheel_2  
  6.     child(3):  wheel_3  
  7.     child(4):  wheel_4  
但请注意这虽然描述了各个部件之间的关系,但仍是一个不完整的URDF,无法在模拟器中显示。


第二版

<visual>tag用来描述模块的视觉效果。

<geometry>tag 用来描述模块的形状和大小。

<origin>tag用来描述模块的位置。

加上模块大小之后的小车文件如下所示。02_visual.urdf

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <robot name="test_robot">  
  2.   <link name="base_link">  
  3.     <visual>  
  4.        <geometry>  
  5.          <box size="0.2 .3 .1"/>  
  6.        </geometry>  
  7.        <origin rpy="0 0 0" xyz="0 0 0.05"/>  
  8.     </visual>  
  9.   </link>  
  10.   
  11.   <link name="wheel_1">  
  12.     <visual>  
  13.       <geometry>  
  14.         <cylinder length="0.05" radius="0.05"/>  
  15.       </geometry>  
  16.       <origin rpy="0 1.5 0" xyz="0.1 0.1 0"/>  
  17.     </visual>  
  18.   </link>  
  19.   
  20.   <link name="wheel_2">  
  21.     <visual>  
  22.       <geometry>  
  23.         <cylinder length="0.05" radius="0.05"/>  
  24.       </geometry>  
  25.       <origin rpy="0 1.5 0" xyz="-0.1 0.1 0"/>  
  26.     </visual>  
  27.   </link>  
  28.   
  29.   <link name="wheel_3">  
  30.     <visual>  
  31.       <geometry>  
  32.         <cylinder length="0.05" radius="0.05"/>  
  33.       </geometry>  
  34.       <origin rpy="0 1.5 0" xyz="0.1 -0.1 0"/>  
  35.     </visual>  
  36.   </link>  
  37.   
  38.   <link name="wheel_4">  
  39.     <visual>  
  40.       <geometry>  
  41.         <cylinder length="0.05" radius="0.05"/>  
  42.       </geometry>  
  43.       <origin rpy="0 1.5 0" xyz="-0.1 -0.1 0"/>  
  44.     </visual>  
  45.   </link>  
  46.   
  47.   <joint name="joint_base_wheel1" type="fixed">  
  48.     <parent link="base_link"/>  
  49.     <child link="wheel_1"/>  
  50.   </joint>  
  51.   
  52.   <joint name="joint_base_wheel2" type="fixed">  
  53.     <parent link="base_link"/>  
  54.     <child link="wheel_2"/>  
  55.   </joint>  
  56.   
  57.   <joint name="joint_base_wheel3" type="fixed">  
  58.     <parent link="base_link"/>  
  59.     <child link="wheel_3"/>  
  60.   </joint>  
  61.   
  62.   <joint name="joint_base_wheel4" type="fixed">  
  63.     <parent link="base_link"/>  
  64.     <child link="wheel_4"/>  
  65.   </joint>  
  66. </robot>  

现在通过如下命令,你就通过rviz查看你的小车模型啦。

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. roslaunch urdf_tutorial display.launch model:=02_visual.urdf  



第三步: 上色

Mmm,我们的小车就快完成了,但全是红色总觉得怪怪的而且很难辨认。

不过上色同样很简单。使用<material> tag并且设置<color> tag

我们得到第三个版本:03_color.urdf

[html]  view plain  copy
  1. <robot name="test_robot">  
  2.   <link name="base_link">  
  3.     <visual>  
  4.        <geometry>  
  5.          <box size="0.2 .3 .1"/>  
  6.        </geometry>  
  7.        <origin rpy="0 0 0" xyz="0 0 0.05"/>  
  8.        <material name="white">  
  9.          <color rgba="1 1 1 1"/>  
  10.        </material>  
  11.     </visual>  
  12.   </link>  
  13.   
  14.   <link name="wheel_1">  
  15.     <visual>  
  16.       <geometry>  
  17.         <cylinder length="0.05" radius="0.05"/>  
  18.       </geometry>  
  19.       <origin rpy="0 1.5 0" xyz="0.1 0.1 0"/>  
  20.       <material name="black">  
  21.         <color rgba="0 0 0 1"/>  
  22.       </material>  
  23.     </visual>  
  24.   </link>  
  25.   
  26.   <link name="wheel_2">  
  27.     <visual>  
  28.       <geometry>  
  29.         <cylinder length="0.05" radius="0.05"/>  
  30.       </geometry>  
  31.       <origin rpy="0 1.5 0" xyz="-0.1 0.1 0"/>  
  32.       <material name="black"/>  
  33.     </visual>  
  34.   </link>  
  35.   
  36.   <link name="wheel_3">  
  37.     <visual>  
  38.       <geometry>  
  39.         <cylinder length="0.05" radius="0.05"/>  
  40.       </geometry>  
  41.       <origin rpy="0 1.5 0" xyz="0.1 -0.1 0"/>  
  42.       <material name="black"/>  
  43.     </visual>  
  44.   </link>  
  45.   
  46.   <link name="wheel_4">  
  47.     <visual>  
  48.       <geometry>  
  49.         <cylinder length="0.05" radius="0.05"/>  
  50.       </geometry>  
  51.       <origin rpy="0 1.5 0" xyz="-0.1 -0.1 0"/>  
  52.       <material name="black"/>  
  53.     </visual>  
  54.   </link>  
  55.   
  56.   <joint name="joint_base_wheel1" type="fixed">  
  57.     <parent link="base_link"/>  
  58.     <child link="wheel_1"/>  
  59.   </joint>  
  60.   
  61.   <joint name="joint_base_wheel2" type="fixed">  
  62.     <parent link="base_link"/>  
  63.     <child link="wheel_2"/>  
  64.   </joint>  
  65.   
  66.   <joint name="joint_base_wheel3" type="fixed">  
  67.     <parent link="base_link"/>  
  68.     <child link="wheel_3"/>  
  69.   </joint>  
  70.   
  71.   <joint name="joint_base_wheel4" type="fixed">  
  72.     <parent link="base_link"/>  
  73.     <child link="wheel_4"/>  
  74.   </joint>  
  75. </robot>  


我们可以看到rviz的结果,如图一所示。

这下我们差不多完成了。我们马上就可以移动我们的小车啦。

但是等等,在我们的URDF文件中,内嵌了关于各个部件的大小参数以及位置。这些当然是我们根据草图用计算器算出来的。

但是这样的扩展性也太差了吧?难道对每个模型我们都得这么计算吗?对于相同模型的不同尺寸我们还得重新计算一次?


第四步: Xacro

什么是Xacro? 我们可以把它理解成为针对URDF的扩展性和配置性而设计的宏语言(macro language)。

有了Xacro,我们就可以像编程一样来写URDF文件了。

首先我们来看Xacro文件的变量定义:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <xacro:property name="body_width" value=".2" />  
只要定义了body_width,我们就可以通过${body_width}来引用其值了。有了这个,至少我们可以把需要配置的变量进行统一管理。

其次,我们来看一下Xacro如何进行宏定义。

这里的宏和C语言的宏很像,在转换成URDF文件时编译器会将其展开。其基本语法为:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <xacro:macro name="wheel" params="param1 param2">  
  2. </xacro:macro>  

我们来看下URDF文件中关于车身和车轮的大小描述。

<box size="0.2 .3 .1"/>

<origin rpy="0 0 0" xyz="0 0 0.05"/>

<cylinder length="0.05" radius="0.05"/>

<origin rpy="0 1.5 0" xyz="-0.1 0.1 0"/>

这里涉及到的参数有:

车身的大小(body_size),车身中心的位置(body_pos)。

车轮半径(wheel_radius)和轮胎宽度(wheel_width),车轮圆心的位置(wheel1_pos, wheel2_pos, wheel3_pos, wheel4_pos)。

相应的在Xacro中定义参数的语法为:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1.   <xacro:property name="body_size" value=".2 .3 .1" />  
  2.   <xacro:property name="body_pos" value="0 0 0.05" />  
  3.   <xacro:property name="wheel_radius" value="0.05" />  
  4.   <xacro:property name="wheel_length" value="0.05" />  
  5.   <xacro:property name="wheel1_pos" value="0.1 0.1 0" />  
  6.   <xacro:property name="wheel2_pos" value="-0.1 0.1 0" />  
  7.   <xacro:property name="wheel3_pos" value="0.1 -0.1 0" />  
  8.   <xacro:property name="wheel4_pos" value="-0.1 -0.1 0" />  

并且每个轮子和连接的代码也基本相同。

基于上述亮点,我们可以得到以下xacro文件。04_xacro.xacro

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0"?>  
  2. <robot xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"  
  3.          xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"  
  4.          xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"  
  5.          xmlns:xacro="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface" name="test_robot">  
  6.   
  7.   <xacro:property name="body_size" value=".2 .3 .1" />  
  8.   <xacro:property name="body_pos" value="0 0 0.05" />  
  9.   <xacro:property name="wheel_radius" value="0.05" />  
  10.   <xacro:property name="wheel_length" value="0.05" />  
  11.   <xacro:property name="wheel1_pos" value="0.1 0.1 0" />  
  12.   <xacro:property name="wheel2_pos" value="-0.1 0.1 0" />  
  13.   <xacro:property name="wheel3_pos" value="0.1 -0.1 0" />  
  14.   <xacro:property name="wheel4_pos" value="-0.1 -0.1 0" />  
  15.   
  16.   <xacro:macro name="wheel" params="wheelname position">  
  17.     <link name="${wheelname}">  
  18.       <visual>  
  19.         <geometry>  
  20.           <cylinder length="${wheel_length}" radius="${wheel_radius}"/>  
  21.         </geometry>  
  22.         <origin rpy="0 1.5 0" xyz="${position}"/>  
  23.         <material name="black">  
  24.           <color rgba="0 0 0 1"/>  
  25.         </material>  
  26.       </visual>  
  27.     </link>  
  28.   
  29.     <joint name="joint_base_${wheelname}" type="fixed">  
  30.       <parent link="base_link"/>  
  31.       <child link="${wheelname}"/>  
  32.     </joint>  
  33.   </xacro:macro>  
  34.   <xacro:wheel wheelname="wheel1" position="${wheel1_pos}"/>  
  35.   <xacro:wheel wheelname="wheel2" position="${wheel2_pos}"/>  
  36.   <xacro:wheel wheelname="wheel3" position="${wheel3_pos}"/>  
  37.   <xacro:wheel wheelname="wheel4" position="${wheel4_pos}"/>  
  38.   
  39.   <link name="base_link">  
  40.     <visual>  
  41.        <geometry>  
  42.          <box size="${body_size}"/>  
  43.        </geometry>  
  44.        <origin rpy="0 0 0" xyz="${body_pos}"/>  
  45.        <material name="white">  
  46.          <color rgba="1 1 1 1"/>  
  47.        </material>  
  48.     </visual>  
  49.   </link>  
  50. </robot>  

验证该文件的正确性可以有两种方法。

1. 转换成URDF文件,使用check_urdf

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. rosrun xacro xacro.py 04_xacro.xacro > 04_xacro.urdf  

2. 使用xacrodisplay.launch

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. roslaunch urdf_tutorial xacrodisplay.launch model:=04_xacro.xacro  

我们都会得到和图1一样的小车模型。这下我们就可以用Xacro来构建机器人模型了。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一段 C++ 代码,包含了几个语句,主要功能是订阅ROS话题,加载URDF模型,并获取ROS节点的命名空间。 具体来说,这段代码中: - `if (orientation_from_imu_)` 表示如果满足条件 `orientation_from_imu_`,则执行下面的语句。这里的 `orientation_from_imu_` 是一个成员变量,可能是一个布尔类型的变量。 - `imu_subscriber_ = nh->subscribe<sensor_msgs::Imu>("imu/data", 1, &StateEstimation::imu_callback_, this);` 表示创建了一个 ROS 订阅者对象 `imu_subscriber_`,订阅了名为 "imu/data" 的话题,并指定了回调函数 `&StateEstimation::imu_callback_`。其中,`nh` 是一个 ROS 节点句柄,用于创建 ROS 订阅者对象;`1` 表示订阅话题的队列长度为 1;`this` 表示回调函数的对象是当前对象。 - `base_.setGaitConfig(gait_config_);` 表示调用对象 `base_` 的成员函数 `setGaitConfig()`,并将参数 `gait_config_` 传递给该函数。这里的 `base_` 可能是一个对象。 - `champ::URDF::loadFromServer(base_, nh);` 表示调用 `champ::URDF` 命名空间中的静态成员函数 `loadFromServer()`,并将 `base_` 和 `nh` 作为参数传递给该函数。这个函数的作用是从 ROS 参数服务器中加载 URDF 模型,然后将模型设置到 `base_` 对象中。 - `joint_names_ = champ::URDF::getJointNames(nh);` 表示调用 `champ::URDF` 命名空间中的静态成员函数 `getJointNames()`,并将 `nh` 作为参数传递给该函数。这个函数的作用是从 ROS 参数服务器中获取机器人关节名称列表,并将结果保存到 `joint_names_` 变量中。 - `node_namespace_ = ros::this_node::getNamespace();` 表示调用 ROS API 中的 `ros::this_node::getNamespace()` 函数,获取当前节点的命名空间,并将结果保存到 `node_namespace_` 变量中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值