ROS建模:一起从零手写URDF模型

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="1 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文件进行查看,发现出现如下报错:

解决方法:

joint_state_publisher_gui 中的 slider.setValue 方法接收到了一个浮点数(float)作为参数,而它期望的是一个整数(int

编辑文件:请确保您正确保存了对 /opt/ros/noetic/lib/python3/dist-packages/joint_state_publisher_gui/__init__.py 文件的更改。使用有管理员权限的编辑器打开该文件,以确保您能够保存更改。

sudo nano /opt/ros/noetic/lib/python3/dist-packages/joint_state_publisher_gui/__init__.py

确认并修改代码:找到第 103 行,确保将浮点数转换为整数。代码应该如下所示:

slider.setValue(int(RANGE/2))

 保存并关闭文件:如果您使用 nano,通过按 Ctrl+X,然后按 Y,最后按 Enter 保存更改。

 再次运行launch文件发现:

这个新的错误信息仍然是关于类型错误,但这次它出现在 joint_state_publisher_gui 的另一个位置。错误发生在 __init__.py 文件的第 182 行,涉及到 joint_info['slider'].setValue 方法。就像之前的错误一样,setValue 方法接收到了一个浮点数(float)而不是它期望的整数(int)。

打开文件进行编辑:打开 /opt/ros/noetic/lib/python3/dist-packages/joint_state_publisher_gui/__init__.py 文件进行编辑。确保您使用的是具有管理员权限的文本编辑器:

sudo nano /opt/ros/noetic/lib/python3/dist-packages/joint_state_publisher_gui/__init__.py

定位并修改代码:找到第 182 行,您可能会看到类似这样的代码:

joint_info['slider'].setValue(self.valueToSlider(joint['zero'], joint))

需要确保 setValue 接收到的参数是整数类型。假设 self.valueToSlider(joint['zero'], joint) 返回一个浮点数,您可以通过使用 int() 函数来转换它:

joint_info['slider'].setValue(int(self.valueToSlider(joint['zero'], joint)))

保存并关闭文件:保存更改并关闭编辑器。