)1、机器人的定义与组成
2、URDF建模方法
link的描述部分:
其中geometry中参数origin的xyz单位为: m,其描述的是相对于坐标系的平移变换;
rpy单位为:弧度,其描述的是相对于坐标系下的旋转偏移
collision是指碰撞属性,也有着几何参数,图中的绿色方框就是cylinder圆柱体,可设置长和半径,主要是描述的区域不同了,与mesh中的stl文件模型相比,这个定义可以减少计算量,因为碰撞检测的计算是十分耗时的,所以将实际模型用绿色方框代替,来做简化操作。
当然,也可以用实际模型来做计算,只要将cylinder换成mesh实际模型即可
惯性矩阵图中没有展示出来(省略了),如果实际模型的几何不规则,那么需要借助第三方的工具来进行输出,比如SW等等,可以帮助我们完成计算,后面会进行介绍。
joint的描述部分:
link1和link2两个连杆之间坐标系的运动关系就是靠joint关节来产生的运动类型
其中name可以自定义,type是指运动类型,下面注意:
在ROS中,一个joint必须只能连接2个连杆,不能连接3个及以上的连杆,也不能连接1个连杆。
在上图中,link1就是parent,而link2就是child,origin描述了2个连杆之间的坐标变换关系,axis描述了关节对于的旋转轴,limit是指限位,上下限为(-180°,180°),上限的速度设置的是1.0,因为revolute是含限位的。
robot的描述部分:
整个URDF模型的最顶层的标签叫做robot,其中name可以自定义,注意所有的连杆和关节标签必须在robot中进行描述,在别处描述是不行的。
3、从零手写移动机器人的URDF模型
下面开始在linux系统中进行操作:
在home目录中创建一个文件夹,../src:
进入src文件夹中打开一个终端,运行如下命令:
catkin_create_pkg mbot_description urdf xacro
会在src中的mbot_description文件夹中出现如下文件夹:
继续:下面分别创建4个文件夹
下面进一步来创建URDF模型:
下面进入urdf文件夹后开启一个终端后输入:
touch mbot.urdf
打开刚刚创建的模型文件,复制粘贴如下内容并保存:
<?xml version="1.0" ?>
<robot name="mbot">
<material name="Black">
<color rgba="0 0 0 1"/>
</material>
<material name="White">
<color rgba="1 1 1 0.95"/>
</material>
<material name="Blue">
<color rgba="0 0 1 1"/>
</material>
<material name="Yellow">
<color rgba="1 0.4 0 1"/>
</material>
<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"/>
</visual>
</link>
</robot>
下面进入到 launch 文件中去,开启一个终端后输入:
touch display_mbot_urdf.launch
打开刚刚创建的模型文件,复制粘贴如下内容并保存:
<launch>
<!-- 设置机器人模型路径参数 -->
<param name="robot_description" textfile="$(find mbot_description)/urdf/mbot.urdf" />
<!-- 运行joint_state_publisher节点,发布机器人的关节状态 -->
<node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" />
<!-- 运行robot_state_publisher节点,发布tf -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
<!-- 运行rviz可视化界面 -->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot_urdf.rviz" required="true" />
</launch>
下面来到这个文件夹的页面处:
在工作空间下进行编译,让环境变量能够找到功能包:
catkin_make
出现以下截图界面:
重合任意开启一个终端,输入:
roslaunch mbot_description display_mbot_urdf.launch
注意--如果遇到如下报错:
解决方案
在home下打开.bashrc文件,在该文件的最后添加如下代码,catkin_ws是我的ROS工作路径:
source /home/hjx/hjx_file/URDF_model/catkin_ws/devel/setup.bash
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:~/catkin_ws/
然后保存bashrc,查看ROS路径是否添加上:
echo $ROS_PACKAGE_PATH
设置成功会显示你添加的路径。
下面继续新开一个终端输入:
roslaunch mbot_description display_mbot_urdf.launch
会出现如下Rviz界面:
下面点击——> Add,找到RobotModel:
成功添加出urdf模型!
但是,左边出现了明显的报错信息,进行查看:
这个是说没有base_link到map坐标系的一个变换,其中map是rviz默认设置的一个坐标系,但当前我们并没有这个坐标系。下面进行更改操作:
点击 Fixed Frame 并将其更改为 base_link:
可以发现,模型显示正常!!!
这个base_link对应于我们之前模型文件中的base_link,每一个link都会产生一个同名的坐标系:
下面为防止每次打开模型文件时都要添加Add,可以进行rviz模型的保存:
在开启的rviz中点击File——> Save config As:
找到我们功能包下面的config文件夹后,点击进行,进行命名(自定义):
再点击save保存即可
OK,下次如果调整rviz整个界面的时候,按ctrl+s即可保存界面中的整个配置,保存至刚刚完成命名的config文件夹中
下面我们将urdf文件中的参数进行一些修改:
关闭rviz后再次打开urdf文件,使用:
roslaunch mbot_description display_mbot_urdf.launch
可以明显发现原来的长度变长了,由0.16m变为了1.16m,同理:半径也可以进行修改。
下面继续更改origin部分,将xyz变为0.5,0,0:
关闭rviz后再次打开urdf文件,发现模型有了偏移,base_link还是位于原点位置:
下面再更改rpy试试看,注意rpy的单位是“弧度”:
关闭rviz后再次打开urdf文件,发现模型有了旋转:
到此为止车体模型的建立完成!
下面继续:
进一步通过link来做描述,将urdf文件改为:
<?xml version="1.0" ?>
<robot name="mbot">
<material name="Black">
<color rgba="0 0 0 1"/>
</material>
<material name="White">
<color rgba="1 1 1 0.95"/>
</material>
<material name="Blue">
<color rgba="0 0 1 1"/>
</material>
<material name="Yellow">
<color rgba="1 0.4 0 1"/>
</material>
<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"/>
</visual>
</link>
<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"/>
</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>
</robot>
保存urdf文件后再次启动launch文件进行查看,发现出现如下报错:
ModuleNotFoundError: No module named 'PySide2' [joint_state_publisher_gui-2]
解决方法:
可以通过运行以下命令来完成:
pip install PySide2 -i https://pypi.tuna.tsinghua.edu.cn/simple gevent
-i https://pypi.tuna.tsinghua.edu.cn/simple gevent是指使用清华源下载
再次执行launch指令,进入你自己设定的conda环境中:
conda activate hjx
roslaunch mbot_description display_mbot_urdf.launch
出现如下界面则算成功!
-----------------------------------------------------------------------------------------------
下面进一步继续学习一下坐标系的概念:
在上述出现轮子的rviz界面中,按照下面的步骤来添加TF:
为了能更加直观地看到TF坐标系,将RobotModel给隐藏即可:
接着使用插件进行旋转关节,坐标系也随之旋转起来:
通过joint的角度来控制两个坐标系之间的位置关系
补充:TF坐标系中的箭头(向量),对应于urdf文件中的下面这一段代码:
好了,左轮创建完毕后,我们继续来创建一个右轮,更改urdf文件:
复制粘贴如下内容并保存:
<?xml version="1.0" ?>
<robot name="mbot">
<material name="Black">
<color rgba="0 0 0 1"/>
</material>
<material name="White">
<color rgba="1 1 1 0.95"/>
</material>
<material name="Blue">
<color rgba="0 0 1 1"/>
</material>
<material name="Yellow">
<color rgba="1 0.4 0 1"/>
</material>
<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"/>
</visual>
</link>
<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"/>
</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="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"/>
</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>
</robot>
下面来继续执行launch命令:
roslaunch mbot_description display_mbot_urdf.launch
发现右轮完成了创建:
由于2个轮子在地面接触时,是2个点的接触,无法保存机器人的平衡,故需要继续改进:
下面继续来添加2个支撑轮,更改urdf文件,复制粘贴如下内容并保存:
<?xml version="1.0" ?>
<robot name="mbot">
<material name="Black">
<color rgba="0 0 0 1"/>
</material>
<material name="White">
<color rgba="1 1 1 0.95"/>
</material>
<material name="Blue">
<color rgba="0 0 1 1"/>
</material>
<material name="Yellow">
<color rgba="1 0.4 0 1"/>
</material>
<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"/>
</visual>
</link>
<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"/>
</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="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"/>
</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="front_caster_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.015" />
</geometry>
<material name="Black"/>
</visual>
</link>
<joint name="front_caster_joint" type="fixed">
<origin xyz="0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="front_caster_link"/>
</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"/>
</visual>
</link>
<joint name="back_caster_joint" type="fixed">
<origin xyz="-0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="back_caster_link"/>
</joint>
</robot>
下面来继续执行launch命令:
roslaunch mbot_description display_mbot_urdf.launch
发现支撑轮完成了创建:
目前这个机器人的本体只是能动,但是缺少对周围环境的感知,所以需要添加传感器。
下面我们来创建第二个模型文件,复制粘贴改名大法,启动!
在mbot_with_laser.urdf文件中进行改动,增添传感器部分的代码描述:
更改mbot_with_laser.urdf文件,复制粘贴如下内容并保存:
<?xml version="1.0" ?>
<robot name="mbot">
<material name="Black">
<color rgba="0 0 0 1"/>
</material>
<material name="White">
<color rgba="1 1 1 0.95"/>
</material>
<material name="Blue">
<color rgba="0 0 1 1"/>
</material>
<material name="Yellow">
<color rgba="1 0.4 0 1"/>
</material>
<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"/>
</visual>
</link>
<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"/>
</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="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"/>
</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="front_caster_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.015" />
</geometry>
<material name="Black"/>
</visual>
</link>
<joint name="front_caster_joint" type="fixed">
<origin xyz="0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="front_caster_link"/>
</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"/>
</visual>
</link>
<joint name="back_caster_joint" type="fixed">
<origin xyz="-0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="back_caster_link"/>
</joint>
<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="Black"/>
</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>
</robot>
其中laser_link是用来描述雷达的
下面需要新创建一个launch启动文件:display_mbot_with_laser_urdf.launch
需要进入到 launch 文件中去,开启一个终端后输入:
touch display_mbot_with_laser_urdf.launch
打开刚刚创建的launch文件,复制粘贴如下内容并保存:
<launch>
<!-- 设置机器人模型路径参数 -->
<param name="robot_description" textfile="$(find mbot_description)/urdf/mbot_with_laser.urdf" />
<!-- 运行joint_state_publisher节点,发布机器人的关节状态 -->
<node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" />
<!-- 运行robot_state_publisher节点,发布tf -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
<!-- 运行rviz可视化界面 -->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot_urdf.rviz" required="true" />
</launch>
于是,下面来继续执行新的launch命令:
roslaunch mbot_description display_mbot_with_laser_urdf.launch
发现雷达完成了创建:
这个雷达看上去不太好看,怪怪的,可以让这个雷达的显示更加逼真吗?
答案是可以的!下面我们来创建第三个模型文件,复制粘贴改名大法,启动!
在mbot_with_kinect.urdf文件中进行改动,复制粘贴如下内容并保存:
<?xml version="1.0" ?>
<robot name="mbot">
<material name="Black">
<color rgba="0 0 0 1"/>
</material>
<material name="White">
<color rgba="1 1 1 0.95"/>
</material>
<material name="Blue">
<color rgba="0 0 1 1"/>
</material>
<material name="Yellow">
<color rgba="1 0.4 0 1"/>
</material>
<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"/>
</visual>
</link>
<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"/>
</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="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"/>
</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="front_caster_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.015" />
</geometry>
<material name="Black"/>
</visual>
</link>
<joint name="front_caster_joint" type="fixed">
<origin xyz="0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="front_caster_link"/>
</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"/>
</visual>
</link>
<joint name="back_caster_joint" type="fixed">
<origin xyz="-0.18 0 -0.095" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="back_caster_link"/>
</joint>
<link name="kinect_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 1.5708"/>
<geometry>
<mesh filename="package://mbot_description/meshes/kinect.dae" />
</geometry>
</visual>
</link>
<joint name="kinect_joint" type="fixed">
<origin xyz="0.15 0 0.11" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="kinect_link"/>
</joint>
</robot>
其中kinect_link是用来描述kinect的, kinect是一个1:1的真实模型。
需要在meshes文件夹当中添加kinect.dae文件,我这里实现完成了拷贝:
下面需要新创建一个launch启动文件:display_mbot_with_kinect_urdf.launch
需要进入到 launch 文件中去,开启一个终端后输入:
touch display_mbot_with_kinect_urdf.launch
打开刚刚创建的launch文件,复制粘贴如下内容并保存:
<launch>
<!-- 设置机器人模型路径参数 -->
<param name="robot_description" textfile="$(find mbot_description)/urdf/mbot_with_kinect.urdf" />
<!-- 运行joint_state_publisher节点,发布机器人的关节状态 -->
<node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" />
<!-- 运行robot_state_publisher节点,发布tf -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
<!-- 运行rviz可视化界面 -->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot_urdf.rviz" required="true" />
</launch>
于是,下面来继续执行新的launch命令:
roslaunch mbot_description display_mbot_with_kinect_urdf.launch
发现kinect完成了创建:
可以发现,通过meshes标签,可以让模型显示的更加逼真;或者通过SW来导出STL文件。
好了~~~最基本的URDF模型创建到此结束!
-------------------------------------------------------------------------------------------------
最后,我们来检查一下URDF模型的整体结构,可以借助下面的工具进行查看:
通过之前的mbot模型来进行演示,进入到urdf文件夹中开启一个终端:
在终端中输入并执行如下指令:
urdf_to_graphiz
显示如下报错:
原因是没有安装,运行终端中提示的指令:
sudo apt install liburdfdom-tools
安装完成,再次执行urdf_to_graphiz指令,显示:Usage: urdf_to_graphiz input.xml则算成功
下面来执行如下指令:
urdf_to_graphiz mbot.urdf
发现在urdf文件夹中会多出2个文件,可以看到:
点开mbot.pdf文件:
发现通过树形图来描述各个link,各个joint之间的联系,这种描述可视化方便对urdf文件的检查,同时也能迅速了解自己或别人的urdf模型的含义!
-------------------------------------------------------------------
由于篇幅问题,后续的机械臂URDF补充:ROS建模:从零手写机械臂的URDF模型-CSDN博客