昨儿个兴奋了半天,以为有了雷达就可以开开心心的去建图跑车了,结果导入官方原厂的URDF不是那么回事。所以一大早8点钟坐在这里,又把赵虚左老师的教程拿出来啃,肯的办法还是按照教程输入代码。
1 URDF知识回顾
从自己浅薄的认识来看,URDF的目的分为对自己和对机器人设计两部分,对自己就是可以让自己更加明白设计出来的机器人各部分组建的关系,并且可以通过RVIZ软件中的robot构型大概看出来车辆我们关心的部件坐标系的分布。对机器人设计来说,我觉得就是告诉ROS我们的机器人到底是个啥样子,有哪些坐标系,有那些link和joint,以及他们的关系是啥,用赵虚左老师中教程的一句话就是“将 urdf 文件的路径设置到参数服务器,使用的参数名是:robot_description
”。
实际中也确实是这样做,我们在调用urdf文件的lanuch文件中引入了一个参数,而这个参数的名称就是robot_description。
yabhoom
机器人官方给的文件中确实有这个。
当然,给了ROS系统这个文件,还要给一些解析这个文件的节点,才可以将其中的Fixed_Frame解析出来。这里需要用到官方给的两个功能包,实际上是三个。
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher"/>
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher"/>
以上两个是必须的,地一个是发布关节的,第二个是发布状态的。如果设计的urdf中有旋转轴,并且也想看看这个旋转轴在模型上的真实旋转情况,可以增加第三个:
<!-- 可选:用于控制关节运动的节点 -->
<node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui" />
其实这个我就记一个“gui”。
下面就是复制粘贴一些赵老师教程中的重点讲解,作为后期快速查找时候的检索。
1.1link
link有一个属性,叫name,这毋庸置疑,link在通篇URDF中都要用,肯定是要有个名字的。
<robot name = "mycar">
<link name= "base_footprint">
...
</link>
</robot>
描述link都有哪些呢?下面这些子标签:
-
visual ---> 描述外观(对应的数据是可视的)
-
geometry 设置连杆的形状
-
标签1: box(盒状)
- 属性:size=长(x) 宽(y) 高(z)
-
标签2: cylinder(圆柱)
- 属性:radius=半径 length=高度
-
标签3: sphere(球体)
- 属性:radius=半径
-
标签4: mesh(为连杆添加皮肤)
- 属性: filename=资源路径(格式:package://<packagename>/<path>/文件)
-
-
origin 设置偏移量与倾斜弧度
-
属性1: xyz=x偏移 y便宜 z偏移
-
属性2: rpy=x翻滚 y俯仰 z偏航 (单位是弧度)
-
-
metrial 设置材料属性(颜色)
-
属性: name
-
标签: color
- 属性: rgba=红绿蓝权重值与透明度 (每个权重值以及透明度取值[0,1])
-
-
-
collision ---> 连杆的碰撞属性
-
Inertial ---> 连杆的惯性矩阵
赵老师后面的那几个例子可以用用,在树梅派中运行的同时,可以在分布式的笔记本电脑上打开rviz上选择控件和坐标系作一个显示,两个知识点都可以熟悉一下。
1.2 joint
关节有两个根本属性,一个是name,一个是type。名字自不必说,type有以下这些:
-
continuous: 旋转关节,可以绕单轴无限旋转
-
revolute: 旋转关节,类似于 continues,但是有旋转角度限制
-
prismatic: 滑动关节,沿某一轴线移动的关节,有位置极限
-
planer: 平面关节,允许在平面正交方向上平移或旋转
-
floating: 浮动关节,允许进行平移、旋转运动
-
fixed: 固定关节,不允许运动的特殊关节
我匮乏的知识里面好像也就只用到绿色标出来的两种。
接下来,我们来分析一下yahboom的urdf文件。
2 yabhoom机器人URDF文件分析
2.1 launch文件
我复制过来。
<launch>
<arg name="ns" default="robot1"/>
<arg name="use_gui" default="true"/>
<arg name="robot_type" value="$(env ROBOT_TYPE)" doc="robot_type [X1,X3,X3plus,R2,X7]"/>
<param name="robot_description" command="$(find xacro)/xacro --inorder
'$(find yahboomcar_description)/urdf/yahboomcar_$(arg robot_type).urdf' ns:=$(arg ns)"/>
<!-- <param name="robot_description" command="$(find xacro)/xacro --inorder-->
<!-- '$(find yahboomcar_description)/urdf/yahboomcar_$(arg robot_type).urdf.xacro' ns:=$(arg ns)" />-->
<node name="joint_state_publisher" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui"
if="$(arg use_gui)"/>
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher"
unless="$(arg use_gui)"/>
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"/>
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find yahboomcar_description)/rviz/yahboomcar.rviz"/>
</launch>
第一个参数,定义了一个命名空间的默认名字,应该是编队多车的时候用到的吧,先不管。
第二个参数,不是很理解,但是默认是true,后面引用到这个变量的地方,使用的方法是if和unless,网上搜索到了这么一个示例
<param name="foo" value="bar" if="$(arg foo)" />
<!-- 当 foo 为 true 时,包含该标签 -->
<param name="foo" value="bar" unless="$(arg foo)" />
<!-- 当 foo 为 false 时,包含该标签 -->
可见,含义还是要包含三个功能包中的robot和joint带gui的那个。
第三个参数,就是告诉和地一个param一起使用,就是告诉当前的robot_description用到的是哪一个文件。也就是yahboomcar_X3.urdf这个文件。既然用了xacro这个指令了,看来这个urdf里面应该有复用的地方。
2.2 URDF文件
然后去了那个文件,查找了一下,没有xacro这个关键词,打脸打的真快。按照joint和link的思路,我们先把这个文件分了四段。
2.2.1 base_footprint/imu_link/base_link以及base_joint/base_imu段
智力测验,三个link几个joint?是的,答案是两个,就是这样分的。为什么这样分,我看到关键的类型都是fixed,有没有可能这就是原因?
2.2.2 front_right_wheel/front_left_wheel/back_right_wheel/back_left_wheel以及front_right_joint/front_left_joint/back_right_joint/back_left_joint段
轮系的
2.2.3 laser_link以及laser_joint段
雷达的,是的,我目前最想要的。
2.2.4 camera_link以及camera_joint段
相机的,没有啦。。。。。
看内容的话,只有geometry这个标签用的是本包目录下的meshes,那就好办,复制进去。其实我感觉到此,我们就可以Ctrl+C,Ctrl+V了,但是我想多费点时间尝试着一部分一部分的复制,让车体一点点的浮出RVIZ。好了,我去了。明儿分享成果。
3 问题解决
好吧,事情并没有想象中的那么顺利。由于使用的是分布式控制,运行Rviz的设备和加载URDF文件的设备,不是同一个设备,这导致了我在加载的时候出现了一大堆问题,最终发现问题是我使用的笔记本电脑上没有mesh文件夹的路径,其实好解决,在本地建立一个工程,将树梅派中的工程靠本到本地一份,然后source一下环境变量,然后再加载就有了,当然也可以在bashrc中直接加,反正就这么回事。这个问题困扰了我一天半。。。