ROS URDF机器人建模

本文详细介绍了如何使用ROS创建URDF模型,包括创建功能包、编写URDF文件、添加物理和碰撞属性、使用xacro优化,并展示了如何在rviz中展示优化后的模型。通过实例展示了从基础到高级的建模过程。
该文章已生成可运行项目,

ROS URDF机器人建模

创建URDF模型

(1)创建机器人描述功能包

catkin_create_pkg mrobot_description urdf xacro

(2)mrobot_description下创建urdf, launch文件夹,在urdf文件夹内放置机器人模型的

URDF或xacro文件。launch文件夹内放置相关启动文件。

URDF例子mrobot_chassis.urdf:

<?xml version="1.0" ?>
<robot name="mrobot_chassis">

    <link name="base_link">
        <visual>
            <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="0.005" radius="0.13"/>
            </geometry>
            <material name="yellow">
                <color rgba="1 0.4 0 1"/>
            </material>
        </visual>
    </link>

    <joint name="base_left_motor_joint" type="fixed">
        <origin xyz="-0.055 0.075 0" rpy="0 0 0" />        
        <parent link="base_link"/>
        <child link="left_motor" />
    </joint>

    <link name="left_motor">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0" />
            <geometry>
                <cylinder radius="0.02" length = "0.08"/>
            </geometry>
            <material name="gray">
                <color rgba="0.75 0.75 0.75 1"/>
            </material>
        </visual>
    </link>

    <joint name="left_wheel_joint" type="continuous">
        <origin xyz="0 0.0485 0" rpy="0 0 0"/>
        <parent link="left_motor"/>
        <child link="left_wheel_link"/>
        <axis xyz="0 1 0"/>
    </joint>

    <link name="left_wheel_link">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0" />
            <geometry>
                <cylinder radius="0.033" length = "0.017"/>
            </geometry>
            <material name="white">
                <color rgba="1 1 1 0.9"/>
            </material>
        </visual>
    </link>

    <joint name="base_right_motor_joint" type="fixed">
        <origin xyz="-0.055 -0.075 0" rpy="0 0 0" />        
        <parent link="base_link"/>
        <child link="right_motor" />
    </joint>

    <link name="right_motor">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0" />
            <geometry>
                <cylinder radius="0.02" length = "0.08" />
            </geometry>
            <material name="gray">
                <color rgba="0.75 0.75 0.75 1"/>
            </material>
        </visual>
    </link>

    <joint name="right_wheel_joint" type="continuous">
        <origin xyz="0 -0.0485 0" rpy="0 0 0"/>
        <parent link="right_motor"/>
        <child link="right_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.033" length = "0.017"/>
            </geometry>
            <material name="white">
                <color rgba="1 1 1 0.9"/>
            </material>
        </visual>
    </link>

    <joint name="front_caster_joint" type="fixed">
        <origin xyz="0.1135 0 -0.0165" rpy="0 0 0"/>
        <parent link="base_link"/>
        <child link="front_caster_link"/>
    </joint>

    <link name="front_caster_link">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0"/>
            <geometry>
                <sphere radius="0.0165" />
            </geometry>
            <material name="black">
                <color rgba="0 0 0 0.95"/>
            </material>
        </visual>
    </link>

</robot>

(3)urdf提供一些命令行工具,用于检测模型文件。安装命令

sudo apt-get install liburdfdom-tools

使用check_urdf命令对mrobot_chassis.urdf文件进行检查, 终端会显示如下所示信息。

$ check_urdf mrobot_chassis.urdf
robot name is: mrobot_chassis
---------- Successfully Parsed XML ---------------
root Link: base_link has 3 child(ren)
    child(1):  left_motor
        child(1):  left_wheel_link
    child(2):  right_motor
        child(1):  right_wheel_link
    child(3):  front_caster_link

使用urdf_to_graphiz命令查看urdf模型整体结构,会生成如下一个pdf文件。

$ urdf_to_graphiz mrobot_chassis.urdf
Created file mrobot_chassis.gv
Created file mrobot_chassis.pdf

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eofvUUhi-1605342281577)(/mnt/hgfs/ROSNote/docs/image/mrobot-chassis-urdf整体结构.png)]

在rviz中显示URDF模型

(1)在mrobot_description功能包的launch文件夹中创建用于显示mrobot_chassis模型的launch文件display_mrobot_chassis_urdf.launch,内容如下

<launch>
	<param name="robot_description" textfile="$(find mrobot_description)/urdf/mrobot_chassis.urdf" />

	<!-- 设置GUI参数,显示关节控制插件 -->
	<param name="use_gui" value="true"/>
	
	<!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
	<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
	
	<!-- 运行robot_state_publisher节点,发布tf  -->
	<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
	
	<!-- 运行rviz可视化界面 -->
	<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mrobot_description)/config/mrobot_urdf.rviz" required="true" />
</launch>

执行启动命令,启动如下窗口,但是显示界面了出现Global Status:Error, Fixed Frame错误。

需要进行一些设置才能正常显示模型,把FixedFrame下拉选项中选择base_link, 点击左下角add按钮,增加一个RobotModel。

roslaunch mrobot_description display_mrobot_chassis_urdf.launch 

在这里插入图片描述

在这里插入图片描述

最后显示的模型如下图所示

在这里插入图片描述

改进URDF模型

添加物理和碰撞属性

在base_link中加入和标签,描述机器人的物理属性和碰撞属性。

<?xml version="1.0" ?>
<robot name="mrobot_chassis">
    <link name="base_link">
	<inertial>
	    <mass value="2" />
	    <origin xyz="0 0 0" />
	    <inertia ixx="0.01" ixy="0.0" ixz="0.0"
		      iyy="0.01" iyz="0.0" izz="0.5" />
	</inertial>

        <visual>
            <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="0.005" radius="0.13"/>
            </geometry>
            <material name="yellow">
                <color rgba="1 0.4 0 1"/>
            </material>
        </visual>
	<collision>
	    <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="0.005" radius="0.13"/>
            </geometry>
	</collision>
    </link>

使用xacro优化URDF

URDF文件不支持代码复用的特性。xacro是URDF的升级版,后缀名为xacro。具有以下几点突出优势

(1)精简模型代码。可以通过宏创建的方式定义常量或复用代码。

(2)提供可编程接口。支持一些可编程接口,如常量、变量、数学公式、条件语句等

在模型标签中需要加入xacro声明:

<robot xmlns:xacro="http://www.ros.org/wiki/xacro">

常量定义及调用

定义常量方便改动机器人模型的参数。

定义

<xacro:property name="M_PI" value="3.14159" />

调用

<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />

调用数学公式

在"${}"语句中,不仅可以调用常量,也可以使用一些常用的数学公式,如加,减,除,负号,括号等,例如:

<origin xyz="0 ${(motor_length+wheel_length)/2} 0" rpy="0 0 0" />

使用宏定义

xacro文件可以使用宏定义来声明重复使用的代码模块,而且可以包含输入参数,类似编程中的函数概念。

    <!-- 定义MRobot本体的宏 -->
    <xacro:macro name="mrobot_standoff_2in" params="parent number x_loc y_loc z_loc">
        <joint name="standoff_2in_${number}_joint" type="fixed">
            <origin xyz="${x_loc} ${y_loc} ${z_loc}" rpy="0 0 0" />
            <parent link="${parent}"/>
            <child link="standoff_2in_${number}_link" />
        </joint>

        <link name="standoff_2in_${number}_link">
            <inertial>
                <mass value="0.001" />
                <origin xyz="0 0 0" />
                <inertia ixx="0.0001" ixy="0.0" ixz="0.0"
                         iyy="0.0001" iyz="0.0"
                         izz="0.0001" />
            </inertial>

            <visual>
                <origin xyz=" 0 0 0 " rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.01 0.07" />
                </geometry>
                <material name="black">
                    <color rgba="0.16 0.17 0.15 0.9"/>
                </material>
            </visual>

            <collision>
                <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.01 0.07" />
                </geometry>
            </collision>
        </link>
    </xacro:macro>

如上定义了一个宏mrobot_standoff_2in,包含五个输入参数。调用该宏模块时,使用如下语句调用,设置输入参数即可:

<mrobot_standoff_2in parent="base_link" number="4" x_loc="${standoff_x/2}" y_loc="${standoff_y}" z_loc="${plate_height/2}"/>

xacro文件引用

改进后的机器人模型文件是mrobot.urdf.xacro, 详细内容如下

<?xml version="1.0"?>
<robot name="mrobot" xmlns:xacro="http://www.ros.org/wiki/xacro">

    <xacro:include filename="$(find mrobot_description)/urdf/mrobot_body.urdf.xacro" />

    <!-- MRobot机器人平台 -->
    <mrobot_body/>

</robot>

标签之间只有两行代码。

<xacro:include filename="$(find mrobot_description)/urdf/mrobot_body.urdf.xacro" />

第一行代码描述了该xacro文件所包含的其他xacro文件。声明关系后就可以调用被包含文件中的模块了。

 <mrobot_body/>

第二行代码就调用了被包含文件mrobot_body.urdf.xacro中的机器人模型的一个宏定义mrbot_body,该宏定义了整个机器人本体模型。

mrobot_body.urdf.xacro的内容如下

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">

    <xacro:property name="M_PI" value="3.14159"/>
    <xacro:property name="wheel_radius" value="0.033"/>
    <xacro:property name="wheel_length" value="0.017"/>
    <xacro:property name="base_link_radius" value="0.13"/>
    <xacro:property name="base_link_length" value="0.005"/>
    <xacro:property name="motor_radius" value="0.02"/>
    <xacro:property name="motor_length" value="0.08"/>
    <xacro:property name="motor_x" value="-0.055"/>
    <xacro:property name="motor_y" value="0.075"/>
    <xacro:property name="plate_height" value="0.07"/>
    <xacro:property name="standoff_x" value="0.12"/>
    <xacro:property name="standoff_y" value="0.10"/>

    <!-- 定义MRobot本体的宏 -->
    <xacro:macro name="mrobot_standoff_2in" params="parent number x_loc y_loc z_loc">
        <joint name="standoff_2in_${number}_joint" type="fixed">
            <origin xyz="${x_loc} ${y_loc} ${z_loc}" rpy="0 0 0" />
            <parent link="${parent}"/>
            <child link="standoff_2in_${number}_link" />
        </joint>

        <link name="standoff_2in_${number}_link">
            <inertial>
                <mass value="0.001" />
                <origin xyz="0 0 0" />
                <inertia ixx="0.0001" ixy="0.0" ixz="0.0"
                         iyy="0.0001" iyz="0.0"
                         izz="0.0001" />
            </inertial>

            <visual>
                <origin xyz=" 0 0 0 " rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.01 0.07" />
                </geometry>
                <material name="black">
                    <color rgba="0.16 0.17 0.15 0.9"/>
                </material>
            </visual>

            <collision>
                <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.01 0.07" />
                </geometry>
            </collision>
        </link>
    </xacro:macro>

    <xacro:macro name="mrobot_body">
        <material name="Green">
            <color rgba="0.0 0.8 0.0 1.0"/>
        </material>
        <material name="yellow">
            <color rgba="1 0.4 0 1"/>
        </material>
        <material name="black">
            <color rgba="0 0 0 0.95"/>
        </material>
        <material name="gray">
            <color rgba="0.75 0.75 0.75 1"/>
        </material>

        <link name="base_footprint">
            <visual>
                <origin xyz="0 0 0" rpy="0 0 0" />
                <geometry>
                    <box size="0.001 0.001 0.001" />
                </geometry>
            </visual>
        </link>

        <link name="base_link">
            <inertial>
                <mass value="2" />
                <origin xyz="0 0 0.0" />
                <inertia ixx="0.01" ixy="0.0" ixz="0.0"
                         iyy="0.01" iyz="0.0" izz="0.5" />
            </inertial>

            <visual>
                <origin xyz=" 0 0 0" rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
                <material name="yellow" />
            </visual>

            <collision>
                <origin xyz="0 0 0" rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
            </collision>
        </link>

        <joint name="base_footprint_joint" type="fixed">
            <origin xyz="0 0 ${wheel_radius}" rpy="0 0 0" />        
            <parent link="base_footprint"/>
            <child link="base_link" />
        </joint>

        <link name="left_motor">
            <inertial>
                <origin xyz="0.0 0 0"/>
                <mass value="0.1" />
                <inertia ixx="0.001" ixy="0.0" ixz="0.0"
                         iyy="0.001" iyz="0.0" izz="0.001" />
            </inertial>

            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${motor_radius}" length = "${motor_length}"/>
                </geometry>
                <material name="gray" />
            </visual>

            <collision>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${motor_radius}" length = "${motor_length}"/>
                </geometry>
            </collision>
        </link>

        <joint name="base_left_motor_joint" type="fixed">
            <origin xyz="${motor_x} ${motor_y} 0" rpy="0 0 0" />        
            <parent link="base_link"/>
            <child link="left_motor" />
        </joint>


        <link name="left_wheel_link">
            <inertial>
                <origin xyz="0 0 0"/>
                <mass value="0.01" />
                <inertia ixx="0.001" ixy="0.0" ixz="0.0"
                         iyy="0.001" iyz="0.0" izz="0.001" />
            </inertial>

            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
                </geometry>
                <material name="white">
                    <color rgba="1 1 1 0.9"/>
                </material>
            </visual>

            <collision>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
                </geometry>
            </collision>
        </link>

        <joint name="left_wheel_joint" type="continuous">
            <origin xyz="0 ${(motor_length+wheel_length)/2} 0" rpy="0 0 0"/>
            <parent link="left_motor"/>
            <child link="left_wheel_link"/>
            <axis xyz="0 1 0"/>
        </joint>

        <link name="right_motor">
            <inertial>
                <origin xyz="0.0 0 0"/>
                <mass value="0.1" />
                <inertia ixx="0.001" ixy="0.0" ixz="0.0"
                         iyy="0.001" iyz="0.0" izz="0.001" />
            </inertial>

            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${motor_radius}" length = "${motor_length}" />
                </geometry>
                <material name="gray" />
            </visual>

            <collision>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${motor_radius}" length = "${motor_length}"/>
                </geometry>
            </collision>
        </link>

        <joint name="base_right_motor_joint" type="fixed">
            <origin xyz="${motor_x} -${motor_y} 0" rpy="0 0 0" />        
            <parent link="base_link"/>
            <child link="right_motor" />
        </joint>

        <link name="right_wheel_link">
            <inertial>
                <origin xyz="0 0 0"/>
                <mass value="0.01" />
                <inertia ixx="0.001" ixy="0.0" ixz="0.0"
                         iyy="0.001" iyz="0.0" izz="0.001" />
            </inertial>

            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
                </geometry>
                <material name="white">
                    <color rgba="1 1 1 0.9"/>
                </material>
            </visual>

            <collision>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
                </geometry>
            </collision>
        </link>

        <joint name="right_wheel_joint" type="continuous">
            <origin xyz="0 -${(motor_length+wheel_length)/2} 0" rpy="0 0 0"/>
            <parent link="right_motor"/>
            <child link="right_wheel_link"/>
            <axis xyz="0 1 0"/>
        </joint>

        <link name="front_caster_link">
            <inertial>
                <origin xyz="0 0 0"/>
                <mass value="0.001" />
                <inertia ixx="0.0001" ixy="0.0" ixz="0.0"
                         iyy="0.0001" iyz="0.0" izz="0.0001" />
            </inertial>

            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0"/>
                <geometry>
                    <sphere radius="${wheel_radius/2}" />
                </geometry>
                <material name="black" />
            </visual>

            <collision>
                <origin xyz="0 0 0.01" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <sphere radius="${wheel_radius/2}" />
                </geometry>
            </collision>
        </link>

        <joint name="front_caster_joint" type="fixed">
            <origin xyz="${base_link_radius-wheel_radius/2} 0 -${wheel_radius/2}" rpy="0 0 0"/>
            <parent link="base_link"/>
            <child link="front_caster_link"/>
        </joint>

        <mrobot_standoff_2in parent="base_link" number="1" x_loc="-${standoff_x/2 + 0.03}" y_loc="-${standoff_y - 0.03}" z_loc="${plate_height/2}"/>
        <mrobot_standoff_2in parent="base_link" number="2" x_loc="-${standoff_x/2 + 0.03}" y_loc="${standoff_y - 0.03}" z_loc="${plate_height/2}"/>
        <mrobot_standoff_2in parent="base_link" number="3" x_loc="${standoff_x/2}" y_loc="-${standoff_y}" z_loc="${plate_height/2}"/>
        <mrobot_standoff_2in parent="base_link" number="4" x_loc="${standoff_x/2}" y_loc="${standoff_y}" z_loc="${plate_height/2}"/>

        <joint name="plate_1_joint" type="fixed">
            <origin xyz="0 0 ${plate_height}" rpy="0 0 0" />
            <parent link="base_link"/>
            <child link="plate_1_link" />
        </joint>

        <link name="plate_1_link">
            <inertial>
                <mass value="0.1" />
                <origin xyz="0 0 0" />
                <inertia ixx="0.01" ixy="0.0" ixz="0.0"
                         iyy="0.01" iyz="0.0" izz="0.01" />
            </inertial>

            <visual>
                <origin xyz=" 0 0 0 " rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
                <material name="yellow"/>
            </visual>

            <collision>
                <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
            </collision>
        </link>


        <mrobot_standoff_2in parent="standoff_2in_1_link" number="5" x_loc="0" y_loc="0" z_loc="${plate_height}"/>
        <mrobot_standoff_2in parent="standoff_2in_2_link" number="6" x_loc="0" y_loc="0" z_loc="${plate_height}"/>
        <mrobot_standoff_2in parent="standoff_2in_3_link" number="7" x_loc="0" y_loc="0" z_loc="${plate_height}"/>
        <mrobot_standoff_2in parent="standoff_2in_4_link" number="8" x_loc="0" y_loc="0" z_loc="${plate_height}"/>

        <joint name="plate_2_joint" type="fixed">
            <origin xyz="0 0 ${plate_height}" rpy="0 0 0" />
            <parent link="plate_1_link"/>
            <child link="plate_2_link" />
        </joint>

        <link name="plate_2_link">
            <inertial>
                <mass value="0.01" />
                <origin xyz="0 0 0" />
                <inertia ixx="0.001" ixy="0.0" ixz="0.0"
                         iyy="0.001" iyz="0.0" izz="0.001" />
            </inertial>

            <visual>
                <origin xyz=" 0 0 0 " rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
                <material name="yellow" />
            </visual>

            <collision>
                <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
                </geometry>
            </collision>
        </link>

    </xacro:macro>

</robot>

显示优化后的模型

xacro文件设计完成后,有两种方式在rviz中显示模型。

1.将xacro文件转换成URDF文件, 命令如下

rosrun xacro xacro.py mrobot.urdf.xacro >mrobot.urdf

这时候会生成一个新的URDF文件mrobot.urdf,使用上面launch文件可将URDF模型显示在rviz中。注意所使用了URDF文件名在launch文件中做相应修改。

launch文件内容如下

<launch>
	<param name="robot_description" textfile="$(find mrobot_description)/urdf/mrobot.urdf" />

	<!-- 设置GUI参数,显示关节控制插件 -->
	<param name="use_gui" value="true"/>
	
	<!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
	<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
	
	<!-- 运行robot_state_publisher节点,发布tf  -->
	<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
	
	<!-- 运行rviz可视化界面 -->
	<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mrobot_description)/config/mrobot_urdf.rviz" required="true" />
</launch>
  1. 直接调用xacro文件解析器

    在launch文件中做如下配置,再运动启动文件即可。

<arg name="model" default="$(find xacro)/xacro --inorder '$(find mrobot_description)/urdf/mrobot.urdf.xacro'" />
<param name="robot_description" command="$(arg model)" />

launch文件的内容如下

<launch>
	<arg name="model" default="$(find xacro)/xacro --inorder '$(find mrobot_description)/urdf/mrobot.urdf.xacro'" />

	<param name="robot_description" command="$(arg model)" />

    <!-- 设置GUI参数,显示关节控制插件 -->
	<param name="use_gui" value="true"/>

    <!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
	<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />

	<!-- 运行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 mrobot_description)/config/mrobot.rviz" required="true" />

</launch>

显示的模型如下图所示

在这里插入图片描述

到此,使用URDF建模的过程就走一遍了。

参考文献

[1]胡春旭. ROS机器人开发实践[M]. 机械工业出版社, 北京, 2018.5

本文章已经生成可运行项目
ROS2中使用URDF(Unified Robot Description Format)进行机器人建模,可按以下步骤操作: ### 了解机器人组成和参数 建模前需熟悉机器人的组成和参数,机器人一般由硬件结构、驱动系统、传感器系统、控制系统四大部分组成,常见的移动机器人或机械臂都可按此分解 [^1]。 ### 创建URDF文件 URDF文件是一个XML格式的文件,用于描述机器人的链接(links)和关节(joints)。以下是一个简单的URDF文件示例: ```xml <?xml version="1.0"?> <robot name="my_robot"> <link name="base_link"> <visual> <geometry> <box size="0.2 0.2 0.1"/> </geometry> </visual> </link> <link name="arm_link"> <visual> <geometry> <cylinder radius="0.05" length="0.5"/> </geometry> </visual> </link> <joint name="arm_joint" type="revolute"> <parent link="base_link"/> <child link="arm_link"/> <axis xyz="0 0 1"/> <origin xyz="0 0 0.1"/> </joint> </robot> ``` 此示例定义了一个简单的机器人,包含两个链接(`base_link`和`arm_link`)和一个关节(`arm_joint`)。 ### 创建ROS2功能包 使用`ros2 pkg create`命令创建一个新的ROS2功能包,例如: ```bash ros2 pkg create --build-type ament_cmake my_robot_description --dependencies urdf xacro ``` 该命令创建了一个名为`my_robot_description`的功能包,并添加了`urdf`和`xacro`依赖。 ### 将URDF文件放入功能包 将创建的URDF文件放入功能包的`urdf`目录下。若没有该目录,可手动创建。 ### 编写启动文件 在功能包的`launch`目录下创建一个启动文件,用于加载URDF文件并启动相关节点。以下是一个简单的启动文件示例: ```python import os from ament_index_python.packages import get_package_share_directory from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): urdf_file_name = 'my_robot.urdf' urdf = os.path.join( get_package_share_directory('my_robot_description'), 'urdf', urdf_file_name) with open(urdf, 'r') as infp: robot_desc = infp.read() return LaunchDescription([ Node( package='robot_state_publisher', executable='robot_state_publisher', name='robot_state_publisher', output='screen', parameters=[{'robot_description': robot_desc}] ) ]) ``` 此启动文件加载URDF文件并启动`robot_state_publisher`节点。 ### 运行启动文件 使用`ros2 launch`命令运行启动文件: ```bash ros2 launch my_robot_description my_robot_launch.py ``` ### 教程资源 - **官方文档**:ROS2官方文档提供了关于URDF建模的详细介绍和教程,可访问ROS2官方网站获取。 - **在线教程**:如古月居的《ROS2入门21讲》,其中有专门章节介绍URDF建模方法 [^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Galaxy_Robot

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值