您好,
会员登录 快速注册
退出 ( 条未读消息)
关于本站 意见反馈 首页

公告:小宅博客网可以开发票了,需要发票的,去群里找群主哈!!
全部文章分类
  • 人工智能 >

  • 编程语言 >

  • WPF系列 >

  • ASP.NET系列 >

  • Linux >

  • 数据库 >

  • 嵌入式 >

  • WEB技术 >

  • PLC系列 >

  • 微服务与框架 >

  • 小宅DIY >

  • 学习资料 >

OpenCv基础 ANN车牌识别 yolov5车牌识别 指针式仪表识别 ROS系列 YOLO Halcon Detectron2 昇腾AI ChatGPT在线体验 英伟达JETSON ChatGLM ChatTTS FunASR 地平线 ByteTrack 魔搭社区 LangChain
C C# C++ Python Java Go
WPF
ASP.NET小功能 GPS定位系统-MVC GPS定位系统-VUE ASP.NET WebRTC
Linux Linux内核 Shell MakeFile
MySql SqlServer Oracle
STM8 STM32 51单片机
VUE入门 HTML JavaScript CSS layui镜像网站 ElementUi中文官网 element-plus 图标
三菱 欧姆龙 西门子 施耐德 松下 台达
IOTSharp IOTGateway ABP FRAMEWORK Docker
亚克力音响 编程仙途:智驭万法
面试题与技巧 Python入门技能树 微软C#教程
首页 编程之美 工具下载 全国就业 流量地图 文心一言
ROS系列
ROS - 介绍 ROS1-常规安装方法 ROS1-Linux下的ROS环境搭建 ROS1-ROS话题:发布者 ROS1-发布者与订阅者通讯 ROS1-服务器与客户端节点通讯 ROS1-动作服务器与客户端通讯 ROS1-发布imu和gps消息 ROS2-新建Ubuntu环境 ROS2-创建一个简单节点 ROS2-Python之消息的发布与订阅 ROS2-C++之消息的发布与订阅 ROS2-调用USB免驱摄像头 ROS2-地瓜机器人笔记 ROS2 控制小车进行矩形运动 ROS2 设置节点开机自启 ROS2 添加自定义msg ROS2 URDF建模 ROS2 Gazebo 仿真环境搭建 ROS2 XACRO建模 ROS2 在Gazebo加载机器人模型 ROS2 Carttographer安装 ROS2 配置cartographer进行建图 ROS2 Nav2导航仿真-新建工程 ROS2 Nav2导航仿真 ROS2 Nav2 API导航
ROS2 Gazebo 仿真环境搭建
ROS2 在Gazebo加载机器人模型
激萌の小宅 小宅博客 ROS系列

文章作者:激萌の小宅

促销:¥0

价格:¥0

配送方式: 购买后立即生效(如购买异常,请联系站长)
付款之后一定要等待自动跳转结束,否则购买可能会失败
  • 0 天

    有效期

  • 0

    总销量

  • 0

    累计评价

ROS2 XACRO建模

参考博客:

https://blog.csdn.net/qq_36914987/article/details/111309304

https://blog.csdn.net/m0_67517854/article/details/131479039


URDF是机器人模型描述的统一格式,但是它却有很多缺点,比如

  1. 模型冗长,重复内容太多。比如机器人底盘的左右轮(下图代码的left_wheel_link和right_wheel_link),需要重复编写几乎一样的代码,导致重复代码过多,效率低下。

  2. 不便于参数修改和计算。由于没有宏定义,当需要修改模型的参数时,往往牵一发而动全身。另外,URDF也不能进行类似的参数计算。


为了弥补URDF格式的这些缺点,人们提出了改进版的URDF——XACRO格式。该格式很好地解决了URDF格式的不足,使得机器人的模型描述变得更加灵活和容易。其特点如下:

  1. 简化模型描述:创建宏定义和文件包含。

  2. 提供可编程接口:变量,常量,数学计算,条件语句等。


1.【常量定义】

<!--常量定义-->
<xacro:property name="M_PI" value="3.1415926"/>


通过xacro:property属性定义了一个名为“M_PI”的常量,其值为"3.1415926"。


【常量使用】

<!--参考系-->
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />


常量的使用方法采用美元符==$+{}==的形式来调用。


2.【宏定义】

<!--宏定义-->
<xacro:macro name="name1" params="a b c">
    ......
</xacro:macro>


【宏调用】

<!--宏调用--> 
<xacro:name1  a="xxx" b="xxx" c="xxx" />


这里需要注意的是,从ubuntu20.04开始,xacro的宏调用需要在宏名前添加前缀xacro:,否则模型不能在rviz中正常显示。


3.【文件包含】

<!--文件包含--> 
<xacro:include filename="$(find mbot_description)/urdf/mbot_base_gazebo.xacro" />


为了便于模块化管理,xacro提供了文件包含的功能。这样就可以在不同的文件中对不同的部件进行建模,最后在通过文件包含进行整合。


新建工程

1、创建功能包

ros2 pkg create  robot_xacro --build-type ament_cmake


2、添加xacro代码

# 进入功能包目录
cd robot_xacro 

# 创建urdf rviz launch三个目录
mkdir urdf rviz launch


创建结果如下:

robot_xacro

├── CMakeLists.txt

├── include

│   └── robot_xacro

├── launch

├── package.xml

├── rviz

├── src

└── urdf


修改CMakeLists.txt文件

cmake_minimum_required(VERSION 3.8)

project(robot_xacro)


if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")

  add_compile_options(-Wall -Wextra -Wpedantic)

endif()


# find dependencies

find_package(ament_cmake REQUIRED)

# uncomment the following section in order to fill in

# further dependencies manually.

# find_package(<dependency> REQUIRED)


if(BUILD_TESTING)

  find_package(ament_lint_auto REQUIRED)

  # the following line skips the linter which checks for copyrights

  # comment the line when a copyright and license is added to all source files

  set(ament_cmake_copyright_FOUND TRUE)

  # the following line skips cpplint (only works in a git repo)

  # comment the line when this package is in a git repo and when

  # a copyright and license is added to all source files

  set(ament_cmake_cpplint_FOUND TRUE)

  ament_lint_auto_find_test_dependencies()

endif()


# 安装 launch/rviz/urdf 目录到安装空间

install( DIRECTORY launch rviz urdf

  DESTINATION share/${PROJECT_NAME} 

)


ament_package()


然后编译我们的工程

colcon build --packages-select robot_xacro

如下:

微信截图_20250529105951.jpg


在package.xml文件中添加以下代码:

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>robot_xacro</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="grb@todo.todo">grb</maintainer>
  <license>TODO: License declaration</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <!-- 添加下面代码 -->
  <exec_depend>ros2launch</exec_depend>
  <exec_depend>xacro</exec_depend>
  <exec_depend>robot_state_publisher</exec_depend>
  <exec_depend>joint_state_publisher</exec_depend>
  <exec_depend>rviz2</exec_depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>


urdf文件夹下新建base_urdf.xacro文件,代码如下:

<!--
    使用 xacro 优化 URDF 版的小车底盘实现:
 
    实现思路
    1.将一些常量、变量封装为 xacro:property
      比如:PI 值、小车底盘半径、离地间距、车轮半径、宽度 ....
    2.使用 宏 封装驱动轮以及支撑轮实现,调用相关宏生成驱动轮与支撑轮
-->
<!-- 根标签,必须声明 xmlns:xacro -->
<robot name="my_base" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <!-- 封装变量、常量 -->
    <xacro:property name="PI" value="3.141"/>
    <!-- 宏:黑色设置 -->
    <material name="black">
        <color rgba="0.0 0.0 0.0 1.0" />
    </material>
    <!-- 底盘属性 -->
    <xacro:property name="base_footprint_radius" value="0.001" /> <!-- base_footprint 半径  -->
    <xacro:property name="base_link_radius" value="0.1" /> <!-- base_link 半径 -->
    <xacro:property name="base_link_length" value="0.08" /> <!-- base_link 长 -->
    <xacro:property name="earth_space" value="0.015" /> <!-- 离地间距 -->
 
    <!-- 底盘 -->
    <link name="base_footprint">
      <visual>
        <geometry>
          <sphere radius="${base_footprint_radius}" />
        </geometry>
      </visual>
    </link>
 
    <link name="base_link">
      <visual>
        <geometry>
          <cylinder radius="${base_link_radius}" length="${base_link_length}" />
        </geometry>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <material name="yellow">
          <color rgba="0.8 0.8 0.0 1.0" />
        </material>
      </visual>
    </link>
 
    <joint name="base_link2base_footprint" type="fixed">
      <parent link="base_footprint" />
      <child link="base_link" />
      <origin xyz="0 0 ${earth_space + base_link_length / 2 }" />
    </joint>
 
    <!-- 驱动轮 -->
    <!-- 驱动轮属性 -->
    <xacro:property name="wheel_radius" value="0.0325" /><!-- 半径 -->
    <xacro:property name="wheel_length" value="0.015" /><!-- 宽度 -->
    <!-- 驱动轮宏实现 -->
    <xacro:macro name="add_wheels" params="name flag">
      <link name="${name}_wheel">
        <visual>
          <geometry>
            <cylinder radius="${wheel_radius}" length="${wheel_length}" />
          </geometry>
          <origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
          <material name="black" />
        </visual>
      </link>
 
      <joint name="${name}_wheel2base_link" type="continuous">
        <parent link="base_link" />
        <child link="${name}_wheel" />
        <origin xyz="0 ${flag * base_link_radius} ${-(earth_space + base_link_length / 2 - wheel_radius) }" />
        <axis xyz="0 1 0" />
      </joint>
    </xacro:macro>
    <xacro:add_wheels name="left" flag="1" />
    <xacro:add_wheels name="right" flag="-1" />
    <!-- 支撑轮 -->
    <!-- 支撑轮属性 -->
    <xacro:property name="support_wheel_radius" value="0.0075" /> <!-- 支撑轮半径 -->
 
    <!-- 支撑轮宏 -->
    <xacro:macro name="add_support_wheel" params="name flag" >
      <link name="${name}_wheel">
        <visual>
            <geometry>
                <sphere radius="${support_wheel_radius}" />
            </geometry>
            <origin xyz="0 0 0" rpy="0 0 0" />
            <material name="black" />
        </visual>
      </link>
 
      <joint name="${name}_wheel2base_link" type="continuous">
          <parent link="base_link" />
          <child link="${name}_wheel" />
          <origin xyz="${flag * (base_link_radius - support_wheel_radius)} 0 ${-(base_link_length / 2 + earth_space / 2)}" />
          <axis xyz="1 1 1" />
      </joint>
    </xacro:macro>
 
    <xacro:add_support_wheel name="front" flag="1" />
    <xacro:add_support_wheel name="back" flag="-1" />
 
</robot>


urdf文件夹下新建camera_urdf.xacro文件,代码如下

<!-- 摄像头相关的 xacro 文件 -->
<robot name="my_camera" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <!-- 摄像头属性 -->
    <xacro:property name="camera_length" value="0.01" /> <!-- 摄像头长度(x) -->
    <xacro:property name="camera_width" value="0.025" /> <!-- 摄像头宽度(y) -->
    <xacro:property name="camera_height" value="0.025" /> <!-- 摄像头高度(z) -->
    <xacro:property name="camera_x" value="0.08" /> <!-- 摄像头安装的x坐标 -->
    <xacro:property name="camera_y" value="0.0" /> <!-- 摄像头安装的y坐标 -->
    <xacro:property name="camera_z" value="${base_link_length / 2 + camera_height / 2}" /> <!-- 摄像头安装的z坐标:底盘高度 / 2 + 摄像头高度 / 2  -->
 
    <!-- 摄像头关节以及link -->
    <link name="camera">
        <visual>
            <geometry>
                <box size="${camera_length} ${camera_width} ${camera_height}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="black" />
        </visual>
    </link>
 
    <joint name="camera2base_link" type="fixed">
        <parent link="base_link" />
        <child link="camera" />
        <origin xyz="${camera_x} ${camera_y} ${camera_z}" />
    </joint>
</robot>


urdf文件夹下新建laser_urdf.xacro文件,代码如下

<!--
    小车底盘添加雷达
-->
<robot name="my_laser" xmlns:xacro="http://www.ros.org/wiki/xacro">
 
    <!-- 雷达支架 -->
    <xacro:property name="support_length" value="0.15" /> <!-- 支架长度 -->
    <xacro:property name="support_radius" value="0.01" /> <!-- 支架半径 -->
    <xacro:property name="support_x" value="0.0" /> <!-- 支架安装的x坐标 -->
    <xacro:property name="support_y" value="0.0" /> <!-- 支架安装的y坐标 -->
    <xacro:property name="support_z" value="${base_link_length / 2 + support_length / 2}" /> <!-- 支架安装的z坐标:底盘高度 / 2 + 支架高度 / 2  -->
 
    <link name="support">
        <visual>
            <geometry>
                <cylinder radius="${support_radius}" length="${support_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="red">
                <color rgba="0.8 0.8 0.8 1.0" />
            </material>
        </visual>
    </link>
 
    <joint name="support2base_link" type="fixed">
        <parent link="base_link" />
        <child link="support" />
        <origin xyz="${support_x} ${support_y} ${support_z}" />
    </joint>
 
 
    <!-- 雷达属性 -->
    <xacro:property name="laser_length" value="0.05" /> <!-- 雷达长度 -->
    <xacro:property name="laser_radius" value="0.03" /> <!-- 雷达半径 -->
    <xacro:property name="laser_x" value="0.0" /> <!-- 雷达安装的x坐标 -->
    <xacro:property name="laser_y" value="0.0" /> <!-- 雷达安装的y坐标 -->
    <xacro:property name="laser_z" value="${support_length / 2 + laser_length / 2}" /> <!-- 雷达安装的z坐标:支架高度 / 2 + 雷达高度 / 2  -->
 
    <!-- 雷达关节以及link -->
    <link name="laser">
        <visual>
            <geometry>
                <cylinder radius="${laser_radius}" length="${laser_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="black" />
        </visual>
    </link>
 
    <joint name="laser2support" type="fixed">
        <parent link="support" />
        <child link="laser" />
        <origin xyz="${laser_x} ${laser_y} ${laser_z}" />
    </joint>
</robot>


urdf文件夹下新建lcar_urdf.xacro文件,代码如下

<!-- 组合小车底盘、摄像头与雷达 -->
<robot name="my_robot_car" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:include filename="base_urdf.xacro" />
    <xacro:include filename="camera_urdf.xacro" />
    <xacro:include filename="laser_urdf.xacro" />
</robot>


在launch文件夹下新建robot_car_xacro.launch.py文件

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from ament_index_python.packages import get_package_share_directory
from launch_ros.parameter_descriptions import ParameterValue
from launch.substitutions import Command
 
def generate_launch_description():
 
    model = DeclareLaunchArgument(name="model",default_value=get_package_share_directory("robot_xacro") + "/urdf/lcar_urdf.xacro")
    p_value = ParameterValue(Command(["xacro ",LaunchConfiguration("model")]))
    robot_state_pub = Node(package="robot_state_publisher",
        executable="robot_state_publisher",
        parameters=[{"robot_description":p_value}] #robot_description的值p_value其实就是urdf文件的内容
    ) 
 
    joint_state_pub = Node(package="joint_state_publisher",executable="joint_state_publisher")
    
    rviz2 = Node(package="rviz2",executable="rviz2")
 
    return LaunchDescription([model,robot_state_pub,joint_state_pub,rviz2])


最后目录结构如下:

微信截图_20250529112406.jpg


构建并测试

# 返回src工作空间,构建包
colcon build --packages-select robot_xacro

# Source工作空间
source install/setup.bash

# 启动可视化
ros2 launch robot_xacro robot_car_xacro.launch.py


运行结果如下:

截图 2025-05-29 11-32-11.jpg




ROS2 Gazebo 仿真环境搭建
ROS2 在Gazebo加载机器人模型

友情链接: CSDN激萌の小宅 95知识库 自考题库 罗分明个人网络博客 精益编程leanboot

小宅博客  www.bilibili996.com All Rights Reserved. 备案号: 闽ICP备2024034575号

网站经营许可证  福建省福州市 Copyright©2021-2025 版权所有

小宅博客
首页 智能家居 地图定位
公告:小宅博客网可以开发票了,需要发票的,去群里找群主哈!!

文章作者:激萌の小宅

促销:¥0

价格:¥0

配送方式: 购买后立即生效(如购买异常,请联系站长)
付款之后一定要等待自动跳转结束,否则购买可能会失败
  • 0 天

    有效期

  • 0

    总销量

  • 0

    累计评价

ROS2 XACRO建模

参考博客:

https://blog.csdn.net/qq_36914987/article/details/111309304

https://blog.csdn.net/m0_67517854/article/details/131479039


URDF是机器人模型描述的统一格式,但是它却有很多缺点,比如

  1. 模型冗长,重复内容太多。比如机器人底盘的左右轮(下图代码的left_wheel_link和right_wheel_link),需要重复编写几乎一样的代码,导致重复代码过多,效率低下。

  2. 不便于参数修改和计算。由于没有宏定义,当需要修改模型的参数时,往往牵一发而动全身。另外,URDF也不能进行类似的参数计算。


为了弥补URDF格式的这些缺点,人们提出了改进版的URDF——XACRO格式。该格式很好地解决了URDF格式的不足,使得机器人的模型描述变得更加灵活和容易。其特点如下:

  1. 简化模型描述:创建宏定义和文件包含。

  2. 提供可编程接口:变量,常量,数学计算,条件语句等。


1.【常量定义】

<!--常量定义-->
<xacro:property name="M_PI" value="3.1415926"/>


通过xacro:property属性定义了一个名为“M_PI”的常量,其值为"3.1415926"。


【常量使用】

<!--参考系-->
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />


常量的使用方法采用美元符==$+{}==的形式来调用。


2.【宏定义】

<!--宏定义-->
<xacro:macro name="name1" params="a b c">
    ......
</xacro:macro>


【宏调用】

<!--宏调用--> 
<xacro:name1  a="xxx" b="xxx" c="xxx" />


这里需要注意的是,从ubuntu20.04开始,xacro的宏调用需要在宏名前添加前缀xacro:,否则模型不能在rviz中正常显示。


3.【文件包含】

<!--文件包含--> 
<xacro:include filename="$(find mbot_description)/urdf/mbot_base_gazebo.xacro" />


为了便于模块化管理,xacro提供了文件包含的功能。这样就可以在不同的文件中对不同的部件进行建模,最后在通过文件包含进行整合。


新建工程

1、创建功能包

ros2 pkg create  robot_xacro --build-type ament_cmake


2、添加xacro代码

# 进入功能包目录
cd robot_xacro 

# 创建urdf rviz launch三个目录
mkdir urdf rviz launch


创建结果如下:

robot_xacro

├── CMakeLists.txt

├── include

│   └── robot_xacro

├── launch

├── package.xml

├── rviz

├── src

└── urdf


修改CMakeLists.txt文件

cmake_minimum_required(VERSION 3.8)

project(robot_xacro)


if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")

  add_compile_options(-Wall -Wextra -Wpedantic)

endif()


# find dependencies

find_package(ament_cmake REQUIRED)

# uncomment the following section in order to fill in

# further dependencies manually.

# find_package(<dependency> REQUIRED)


if(BUILD_TESTING)

  find_package(ament_lint_auto REQUIRED)

  # the following line skips the linter which checks for copyrights

  # comment the line when a copyright and license is added to all source files

  set(ament_cmake_copyright_FOUND TRUE)

  # the following line skips cpplint (only works in a git repo)

  # comment the line when this package is in a git repo and when

  # a copyright and license is added to all source files

  set(ament_cmake_cpplint_FOUND TRUE)

  ament_lint_auto_find_test_dependencies()

endif()


# 安装 launch/rviz/urdf 目录到安装空间

install( DIRECTORY launch rviz urdf

  DESTINATION share/${PROJECT_NAME} 

)


ament_package()


然后编译我们的工程

colcon build --packages-select robot_xacro

如下:

微信截图_20250529105951.jpg


在package.xml文件中添加以下代码:

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>robot_xacro</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="grb@todo.todo">grb</maintainer>
  <license>TODO: License declaration</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <!-- 添加下面代码 -->
  <exec_depend>ros2launch</exec_depend>
  <exec_depend>xacro</exec_depend>
  <exec_depend>robot_state_publisher</exec_depend>
  <exec_depend>joint_state_publisher</exec_depend>
  <exec_depend>rviz2</exec_depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>


urdf文件夹下新建base_urdf.xacro文件,代码如下:

<!--
    使用 xacro 优化 URDF 版的小车底盘实现:
 
    实现思路
    1.将一些常量、变量封装为 xacro:property
      比如:PI 值、小车底盘半径、离地间距、车轮半径、宽度 ....
    2.使用 宏 封装驱动轮以及支撑轮实现,调用相关宏生成驱动轮与支撑轮
-->
<!-- 根标签,必须声明 xmlns:xacro -->
<robot name="my_base" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <!-- 封装变量、常量 -->
    <xacro:property name="PI" value="3.141"/>
    <!-- 宏:黑色设置 -->
    <material name="black">
        <color rgba="0.0 0.0 0.0 1.0" />
    </material>
    <!-- 底盘属性 -->
    <xacro:property name="base_footprint_radius" value="0.001" /> <!-- base_footprint 半径  -->
    <xacro:property name="base_link_radius" value="0.1" /> <!-- base_link 半径 -->
    <xacro:property name="base_link_length" value="0.08" /> <!-- base_link 长 -->
    <xacro:property name="earth_space" value="0.015" /> <!-- 离地间距 -->
 
    <!-- 底盘 -->
    <link name="base_footprint">
      <visual>
        <geometry>
          <sphere radius="${base_footprint_radius}" />
        </geometry>
      </visual>
    </link>
 
    <link name="base_link">
      <visual>
        <geometry>
          <cylinder radius="${base_link_radius}" length="${base_link_length}" />
        </geometry>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <material name="yellow">
          <color rgba="0.8 0.8 0.0 1.0" />
        </material>
      </visual>
    </link>
 
    <joint name="base_link2base_footprint" type="fixed">
      <parent link="base_footprint" />
      <child link="base_link" />
      <origin xyz="0 0 ${earth_space + base_link_length / 2 }" />
    </joint>
 
    <!-- 驱动轮 -->
    <!-- 驱动轮属性 -->
    <xacro:property name="wheel_radius" value="0.0325" /><!-- 半径 -->
    <xacro:property name="wheel_length" value="0.015" /><!-- 宽度 -->
    <!-- 驱动轮宏实现 -->
    <xacro:macro name="add_wheels" params="name flag">
      <link name="${name}_wheel">
        <visual>
          <geometry>
            <cylinder radius="${wheel_radius}" length="${wheel_length}" />
          </geometry>
          <origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
          <material name="black" />
        </visual>
      </link>
 
      <joint name="${name}_wheel2base_link" type="continuous">
        <parent link="base_link" />
        <child link="${name}_wheel" />
        <origin xyz="0 ${flag * base_link_radius} ${-(earth_space + base_link_length / 2 - wheel_radius) }" />
        <axis xyz="0 1 0" />
      </joint>
    </xacro:macro>
    <xacro:add_wheels name="left" flag="1" />
    <xacro:add_wheels name="right" flag="-1" />
    <!-- 支撑轮 -->
    <!-- 支撑轮属性 -->
    <xacro:property name="support_wheel_radius" value="0.0075" /> <!-- 支撑轮半径 -->
 
    <!-- 支撑轮宏 -->
    <xacro:macro name="add_support_wheel" params="name flag" >
      <link name="${name}_wheel">
        <visual>
            <geometry>
                <sphere radius="${support_wheel_radius}" />
            </geometry>
            <origin xyz="0 0 0" rpy="0 0 0" />
            <material name="black" />
        </visual>
      </link>
 
      <joint name="${name}_wheel2base_link" type="continuous">
          <parent link="base_link" />
          <child link="${name}_wheel" />
          <origin xyz="${flag * (base_link_radius - support_wheel_radius)} 0 ${-(base_link_length / 2 + earth_space / 2)}" />
          <axis xyz="1 1 1" />
      </joint>
    </xacro:macro>
 
    <xacro:add_support_wheel name="front" flag="1" />
    <xacro:add_support_wheel name="back" flag="-1" />
 
</robot>


urdf文件夹下新建camera_urdf.xacro文件,代码如下

<!-- 摄像头相关的 xacro 文件 -->
<robot name="my_camera" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <!-- 摄像头属性 -->
    <xacro:property name="camera_length" value="0.01" /> <!-- 摄像头长度(x) -->
    <xacro:property name="camera_width" value="0.025" /> <!-- 摄像头宽度(y) -->
    <xacro:property name="camera_height" value="0.025" /> <!-- 摄像头高度(z) -->
    <xacro:property name="camera_x" value="0.08" /> <!-- 摄像头安装的x坐标 -->
    <xacro:property name="camera_y" value="0.0" /> <!-- 摄像头安装的y坐标 -->
    <xacro:property name="camera_z" value="${base_link_length / 2 + camera_height / 2}" /> <!-- 摄像头安装的z坐标:底盘高度 / 2 + 摄像头高度 / 2  -->
 
    <!-- 摄像头关节以及link -->
    <link name="camera">
        <visual>
            <geometry>
                <box size="${camera_length} ${camera_width} ${camera_height}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="black" />
        </visual>
    </link>
 
    <joint name="camera2base_link" type="fixed">
        <parent link="base_link" />
        <child link="camera" />
        <origin xyz="${camera_x} ${camera_y} ${camera_z}" />
    </joint>
</robot>


urdf文件夹下新建laser_urdf.xacro文件,代码如下

<!--
    小车底盘添加雷达
-->
<robot name="my_laser" xmlns:xacro="http://www.ros.org/wiki/xacro">
 
    <!-- 雷达支架 -->
    <xacro:property name="support_length" value="0.15" /> <!-- 支架长度 -->
    <xacro:property name="support_radius" value="0.01" /> <!-- 支架半径 -->
    <xacro:property name="support_x" value="0.0" /> <!-- 支架安装的x坐标 -->
    <xacro:property name="support_y" value="0.0" /> <!-- 支架安装的y坐标 -->
    <xacro:property name="support_z" value="${base_link_length / 2 + support_length / 2}" /> <!-- 支架安装的z坐标:底盘高度 / 2 + 支架高度 / 2  -->
 
    <link name="support">
        <visual>
            <geometry>
                <cylinder radius="${support_radius}" length="${support_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="red">
                <color rgba="0.8 0.8 0.8 1.0" />
            </material>
        </visual>
    </link>
 
    <joint name="support2base_link" type="fixed">
        <parent link="base_link" />
        <child link="support" />
        <origin xyz="${support_x} ${support_y} ${support_z}" />
    </joint>
 
 
    <!-- 雷达属性 -->
    <xacro:property name="laser_length" value="0.05" /> <!-- 雷达长度 -->
    <xacro:property name="laser_radius" value="0.03" /> <!-- 雷达半径 -->
    <xacro:property name="laser_x" value="0.0" /> <!-- 雷达安装的x坐标 -->
    <xacro:property name="laser_y" value="0.0" /> <!-- 雷达安装的y坐标 -->
    <xacro:property name="laser_z" value="${support_length / 2 + laser_length / 2}" /> <!-- 雷达安装的z坐标:支架高度 / 2 + 雷达高度 / 2  -->
 
    <!-- 雷达关节以及link -->
    <link name="laser">
        <visual>
            <geometry>
                <cylinder radius="${laser_radius}" length="${laser_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="black" />
        </visual>
    </link>
 
    <joint name="laser2support" type="fixed">
        <parent link="support" />
        <child link="laser" />
        <origin xyz="${laser_x} ${laser_y} ${laser_z}" />
    </joint>
</robot>


urdf文件夹下新建lcar_urdf.xacro文件,代码如下

<!-- 组合小车底盘、摄像头与雷达 -->
<robot name="my_robot_car" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:include filename="base_urdf.xacro" />
    <xacro:include filename="camera_urdf.xacro" />
    <xacro:include filename="laser_urdf.xacro" />
</robot>


在launch文件夹下新建robot_car_xacro.launch.py文件

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from ament_index_python.packages import get_package_share_directory
from launch_ros.parameter_descriptions import ParameterValue
from launch.substitutions import Command
 
def generate_launch_description():
 
    model = DeclareLaunchArgument(name="model",default_value=get_package_share_directory("robot_xacro") + "/urdf/lcar_urdf.xacro")
    p_value = ParameterValue(Command(["xacro ",LaunchConfiguration("model")]))
    robot_state_pub = Node(package="robot_state_publisher",
        executable="robot_state_publisher",
        parameters=[{"robot_description":p_value}] #robot_description的值p_value其实就是urdf文件的内容
    ) 
 
    joint_state_pub = Node(package="joint_state_publisher",executable="joint_state_publisher")
    
    rviz2 = Node(package="rviz2",executable="rviz2")
 
    return LaunchDescription([model,robot_state_pub,joint_state_pub,rviz2])


最后目录结构如下:

微信截图_20250529112406.jpg


构建并测试

# 返回src工作空间,构建包
colcon build --packages-select robot_xacro

# Source工作空间
source install/setup.bash

# 启动可视化
ros2 launch robot_xacro robot_car_xacro.launch.py


运行结果如下:

截图 2025-05-29 11-32-11.jpg