目标:学习一些使用 Xacro 减少 URDF 文件代码量的技巧
教程级别:中级
时间:20 分钟
目录
使用 Xacro
常量
数学
宏
简单宏
参数化宏
实际使用
腿宏
到目前为止,如果你在家里按照这些步骤设计自己的机器人,你可能已经厌倦了做各种数学运算来正确解析非常简单的机器人描述。幸运的是,你可以使用 xacro 包来简化你的生活。它做了三件非常有用的事情。
常量
简单数学
宏
在本教程中,我们将看看所有这些快捷方式,以帮助减少 URDF 文件的整体大小,并使其更易于阅读和维护。
使用 Xacro
顾名思义,xacro https://index.ros.org/p/xacro/ 是一种用于 XML 的宏语言。xacro 程序运行所有宏并输出结果。典型用法如下所示:
xacro model.xacro > model.urdf
您还可以在启动文件中自动生成 urdf。这很方便,因为它保持最新状态并且不会占用硬盘空间。然而,生成它需要时间,因此请注意,您的启动文件可能需要更长时间才能启动。
要在启动文件中运行 xacro,您需要将 Command
替换作为 robot_state_publisher
的参数。
# 获取'turtlebot3_description'包的共享路径,并拼接成URDF文件的路径
path_to_urdf = get_package_share_path('turtlebot3_description') / 'urdf' / 'turtlebot3_burger.urdf'
# 创建一个ROS节点,用于发布机器人状态
robot_state_publisher_node = launch_ros.actions.Node(
package='robot_state_publisher', # 指定节点所在的包
executable='robot_state_publisher', # 指定可执行文件
parameters=[{
'robot_description': ParameterValue(
Command(['xacro ', str(path_to_urdf)]), value_type=str # 使用xacro命令处理URDF文件
)
}]
)
一种更简单的加载机器人模型的方法是使用 urdf_launch 包自动加载 xacro/urdf。
from launch import LaunchDescription # 从launch模块导入LaunchDescription类
from launch.actions import IncludeLaunchDescription # 从launch.actions模块导入IncludeLaunchDescription类
from launch.substitutions import PathJoinSubstitution # 从launch.substitutions模块导入PathJoinSubstitution类
from launch_ros.substitutions import FindPackageShare # 从launch_ros.substitutions模块导入FindPackageShare类
def generate_launch_description():
ld = LaunchDescription() # 创建一个LaunchDescription对象
# 添加一个IncludeLaunchDescription动作,用于包含另一个launch文件
ld.add_action(IncludeLaunchDescription(
PathJoinSubstitution([FindPackageShare('urdf_launch'), 'launch', 'display.launch.py']), # 指定要包含的launch文件的路径
launch_arguments={ # 指定传递给launch文件的参数
'urdf_package': 'turtlebot3_description', # urdf包的名称
'urdf_package_path': PathJoinSubstitution(['urdf', 'turtlebot3_burger.urdf']) # urdf文件的路径
}.items() # 将参数字典转换为items对象
))
return ld # 返回LaunchDescription对象
在 URDF 文件的顶部,您必须指定一个命名空间,以便文件能够正确解析。例如,这是一份有效的 xacro 文件的前两行:
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="firefighter">
常量
让我们快速看一下 R2D2 中的 base_link。
<link name="base_link">
<visual>
<geometry>
<cylinder length="0.6" radius="0.2"/>
</geometry>
<material name="blue"/>
</visual>
<collision>
<geometry>
<cylinder length="0.6" radius="0.2"/>
</geometry>
</collision>
</link>
这里的信息有点多余。我们两次指定了圆柱体的长度和半径。更糟糕的是,如果我们想要更改它,我们需要在两个不同的地方进行更改。
幸运的是,xacro 允许您指定作为常量的属性。相反,我们可以编写上述代码。
<xacro:property name="width" value="0.2" />
<xacro:property name="bodylen" value="0.6" />
<link name="base_link">
<visual>
<geometry>
<cylinder radius="${width}" length="${bodylen}"/>
</geometry>
<material name="blue"/>
</visual>
<collision>
<geometry>
<cylinder radius="${width}" length="${bodylen}"/>
</geometry>
</collision>
</link>
这两个值在前两行中指定。它们可以在任何地方定义(假设是有效的 XML),在任何级别,在使用之前或之后。通常它们位于顶部。
与其在几何元素中指定实际半径,我们使用美元符号和花括号来表示该值。
此代码将生成上面显示的相同代码。
${} 构造的内容值将用于替换 ${}。这意味着您可以将其与属性中的其他文本结合使用。
<xacro:property name=”robotname” value=”mar