前言
本人ROS小白,利用寒假时间学习ROS,在此以笔记的方式记录自己每天的学习过程。争取写满15篇(11/15)。
环境:Ubuntu20.04、ROS1:noetic
环境配置:严格按照下方学习链接的教程配置,基本一次成功。
学习链接:【Autolabor初级教程】ROS机器人入门
对应链接文档:ROS机器人入门课程《ROS理论与实践》
笔记绝大部分代码使用Python语言编写。
本期关键词:基本流程,link标签,joint标签,urdf工具
URDF(Unified Robot Description Format)是ROS中用于描述机器人的一种XML格式。它允许用户定义机器人的物理结构、关节、传感器等属性,以及它们之间的相对位置和运动学关系。URDF文件通常用于在ROS中创建机器人的三维模型,这些模型可以被RViz(ROS的可视化工具)和其他仿真环境(如Gazebo)用来模拟和可视化机器人。
基本流程
- 在工作空间下创建功能包,导入依赖库(urdf、xacro)
- 编写urdf文件
- 编写launch文件(集成urdf与rviz)
- 在rviz显示机器人模型
创建功能包
- 创建方法和以前的功能包创建基本一致,在vscode里右键工作空间的
src
文件,选择Create Catkin Package
选项,输入包名,输入urdf xacro
两个依赖库。 - 在功能包(
my_urdf
)下创建将会用到的config
launch
urdf
meshes
文件夹。
urdf文件编写
- 参考代码如下:
<robot name="mycar">
<link name="base_link">
<visual>
<geometry>
<box size="0.5 0.2 0.1" />
</geometry>
</visual>
</link>
</robot>
- 代码中的
base_link
我们会在rviz中用到 0.5 0.2 0.1
对应的分别是box
模型的长宽高
launch文件编写
- 参考代码如下:
<launch>
<!-- 设置参数 -->
<param name="robot_description" textfile="$(find my_urdf)/urdf/demo_test.urdf" />
<!-- 启动 rviz -->
<node pkg="rviz" type="rviz" name="rviz" />
</launch>
- 注意:这里的
"robot_description"
是固定参数,不能写错。
rviz显示模型
- 直接在终端通过
roslaunch
指令执行刚刚编写的launch文件。 - 进入rviz界面后,在左侧
Display
窗口Add
添加RobotModel
插件。 - 此时仍无法显示模型,需要将
Fixed Frame
中的map
改成上述.urdf文件中link name对应的base_link,才可能看到模型 - 保存rviz配置到
my_urdf
功能包下的config
文件夹,并在launch文件的rviz节点添加该参数,如下所示:
<launch>
<!-- 设置参数 -->
<param name="robot_description" textfile="$(find my_urdf)/urdf/demo_test.urdf" />
<!-- 启动 rviz -->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find my_urdf)/config/demo_test.rviz"/>
</launch>
- rviz节点通过args参数指定配置模式,下次再执行该launch文件时,就不用再自己添加机器人模型等插件,可以节省时间。
link标签
urdf中的link标签用于描述机器人的刚体部分,可以通过link标签设置外观(visual)、惯性矩阵(inertial)、碰撞(collision)等属性。本部分只对visual进行讲解。
- visual所包含的子标签:
- geometry(形状设置)
- 标签1: box(盒状):属性:size=长(x) 宽(y) 高(z)
- 标签2: cylinder(圆柱):属性:radius=半径 length=高度
- 标签3: sphere(球体):属性:radius=半径
- 标签4: mesh(导入已有模型):格式为
filename=资源路径(package://<packagename>/<path>/文件)
- origin(偏移量与倾斜弧度设置)
- 属性1:x偏移 偏移 z偏移
- 属性2:x翻滚 y俯仰 z偏航 (单位是弧度)
- metrial(属性/颜色设置)
- 属性:name
- 颜色:rgba(red green blue a:透明度)
- geometry(形状设置)
- 参考代码1:
<robot name="demo1">
<link name="base_link">
<visual>
<!-- 形状 -->
<geometry>
<!-- 长方体的长宽高 -->
<!-- <box size="0.5 0.3 0.1" /> -->
<!-- 圆柱,半径和长度 -->
<!-- <cylinder radius="0.5" length="0.1" /> -->
<!-- 球体,半径-->
<sphere radius="0.5" />
</geometry>
<!-- xyz坐标 rpy翻滚俯仰与偏航角度(3.14=180度 1.57=90度) -->
<origin xyz="0 0 0" rpy="0 0 0" />
<!-- 颜色: r=red g=green b=blue a=alpha -->
<material name="black">
<color rgba="0.7 0.5 0 1" />
</material>
</visual>
</link>
</robot>
- 参考代码2:(直接导入模型)
<robot name="demo2">
<link name="base_link">
<visual>
<!-- 形状 -->
<geometry>
<mesh filename="package://my_urdf/meshes/autolabor_mini.stl" />
</geometry>
<!-- xyz坐标 rpy翻滚俯仰与偏航角度(3.14=180度 1.57=90度) -->
<origin xyz="0 0 0" rpy="1.57 0 0" />
<!-- 颜色: r=red g=green b=blue a=alpha -->
<material name="color">
<color rgba="0.7 0.5 0 1" />
</material>
</visual>
</link>
</robot>
- 执行参考代码前,需要将launch文件对应的param修改一下。执行参考代码2之前,需要将赵虚左老师提供的
autolabor_mini.stl
文件复制到已经建好的meshes
文件夹下。这里直接附上赵老师提供的文件下载链接: https://github.com/zx595306686/sim_demo.git
joint标签
urdf 中的 joint 标签用于描述机器人关节(连接节点)的运动学和动力学属性,还可以指定关节运动的安全极限。
- 属性:
- name:命名
- type:关节的运动形式
- continuous: 旋转关节,可以绕单轴无限旋转
- revolute: 旋转关节,有旋转角度限制
- prismatic: 滑动关节,沿某一轴线移动的关节,有位置极限
- planer: 平面关节,允许在平面正交方向上平移或旋转
- floating: 浮动关节,允许进行平移、旋转运动
- fixed: 固定关节,不允许运动的特殊关节
- 子标签:
- parent link:父级连杆的名称(必需)
- child link:子级连杆的名称(必需)
- origin(偏移量与倾斜弧度设置)
- 属性1:x偏移 偏移 z偏移
- 属性2:x翻滚 y俯仰 z偏航 (单位是弧度)
- axis: xyz用于设置围绕哪个关节轴运动。
- 要让joint标签生效,launch文件里还必须添加以下两个节点:
<!-- 添加关节状态发布节点 -->
<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" />
- 以下参考代码是在base_link的上表面的特定位置添加摄像头(在这里以长方体代替):
<robot name="mycar">
<!-- 底盘 -->
<link name="base_link">
<visual>
<geometry>
<box size="0.5 0.2 0.1" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="blue">
<color rgba="0 0 1.0 0.5" />
</material>
</visual>
</link>
<!-- 摄像头 -->
<link name="camera">
<visual>
<geometry>
<box size="0.02 0.05 0.05" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="red">
<color rgba="1 0 0 0.5" />
</material>
</visual>
</link>
<!-- joint -->
<joint name="camera2baselink" type="continuous">
<parent link="base_link"/>
<child link="camera" />
<!-- 需要计算两个 link 的物理中心之间的偏移量 -->
<origin xyz="0.2 0 0.075" rpy="0 0 0" />
<axis xyz="0 0 1" />
</joint>
</robot>
- 现在来解释一下上面这段代码:两个link标签就是创建长方体的,joint部分建立两个长方体之间的连接。
- 说一个比较不好理解的地方:以上代码实现的是小长方体的下表面与大长方体(base_link)上表面重合。由joint标签里的origin可知,我们把连接点(joint)设置在了z=0.075的地方。
- 为什么要这么设置呢?一步步来解释:我们在单独使用link创建一个长发体,假设长方体的高为0.1m,在rviz中,我们会发现高在z的正半轴有0.05m,负半轴也有0.05m。这是因为rviz中默认将物体的中心点设置为rviz世界坐标系的中点。
- 当我们不加入joint,只是创建两个物体时,这两个物体的中心点都会和rviz世界坐标系的中心点重合。
- 这时我们加入joint,并且以base_link为父系,将joint里origin的z设置为0.075,表示的是小正方体(摄像头)的中点点位于z=0.075处,这时我们会发现大小正方体的上下表面正好是重合的:0.05+0.025=0.075m
- 说的可能有点乱,大家自己推理一下然后测试一下就能搞懂的。
- launch文件参考如下:
<launch>
<!-- 设置参数 -->
<param name="robot_description" textfile="$(find my_urdf)/urdf/demo3.urdf" />
<!-- 可选:用于控制关节运动的节点 -->
<node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui" />
<!-- 添加关节状态发布节点 -->
<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" />
<!-- 启动 rviz -->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find my_urdf)/config/demo_test.rviz"/>
</launch>
- 如果运行以上launch文件,使用归时摄像头抖动停不下来,可以把关节状态发布节点注释了再尝试。
base_footprint优化urdf
base_footprint主要是用来解决模型半下沉问题的(就是有一半在z平面之下)。具体代码实现如下所示:
<robot name="mycar">
<!-- 设置一个原点(机器人中心点的投影) -->
<link name="base_footprint">
<visual>
<geometry>
<sphere radius="0.001" />
</geometry>
</visual>
</link>
<!-- 添加底盘 -->
<link name="base_link">
<visual>
<geometry>
<box size="0.5 0.2 0.1" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="blue">
<color rgba="0 0 1.0 0.5" />
</material>
</visual>
</link>
<!-- 底盘与原点连接的关节 -->
<joint name="base_link2base_footprint" type="fixed">
<parent link="base_footprint" />
<child link="base_link" />
<origin xyz="0 0 0.05" />
</joint>
<!-- 添加摄像头 -->
<link name="camera">
<visual>
<geometry>
<box size="0.02 0.05 0.05" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="red">
<color rgba="1 0 0 0.5" />
</material>
</visual>
</link>
<!-- 关节 -->
<joint name="camera2baselink" type="continuous">
<parent link="base_link"/>
<child link="camera" />
<origin xyz="0.2 0 0.075" rpy="0 0 0" />
<axis xyz="0 0 1" />
</joint>
</robot>
这里需要注意的是,底盘与极小球体的连接属性为fixed
,即固定关节。
当然要解决模型半下沉问题,也可以让改变模型的z偏移来实现,这个我这里就不详细描述了,大家试一下就能试出来的。
urdf工具
check_urdf
通过check_urdf urdf文件
指令,可以检查编写的urdf是否有误,若无误,终端还会输出urdf设置的模型的层级结构。
urdf_to_graphiz
通过urdf_to_graphiz urdf文件
指令,可以将urdf编写模型的层级结构、位姿等信息以树状图的形式生成,并保存为PDF文件。