ros2
功能包(pkg)
一个功能包可以被认为是ROS2代码的容器。如果希望能够管理代码或与他人共享代码,那么需要将其组织在一个包中。通过包,可以发布ROS2工作,并允许其他人轻松地构建和使用它。
功能包 和 程序 的关系
一个功能包里可以包含多个程序。这些程序分成不同职责,共同构成一个功能包的完整功能。通过cmake可控制多个可执行文件:
1 | |
程序 和 节点 的关系
一个程序(对应一个main函数)里一般性跑一个节点,因为spin一个节点是阻塞线程的操作。当然你可以异步跑多个节点,但不常用。
创建并运行一个功能包
- 使用如下命令在当前目录下创建一个ros2包:
1 | |
ros2 pkg create:创建包的 固定语法--build-type:构建包的选项,一般C++写ament_cmake,python写ament_python。--node-name:可选参数,若指定将会默认添加一个src/<程序名>.cpp文件,并指定成程序名称。--dependencies:可选参数,添加依赖项,常见的依赖如rclcpp(ros2的c++接口)。
下图为在ubuntu命令行创建一个名为demo_cpp_pkg的包的示例:
一个包的基本结构:
1 | |
- 新建
src/main.cpp,写入如下基本节点代码:
1 | |
- 修改
CMakeLists.txt成如下所示:
1 | |
其中:ament_target_dependencies函数是ament的扩展函数,等同于绑定依赖的include库和链接libraries,即下两行代码:
1 | |
使用cmake编译(vscode按下f7)。
使用colcon构建包:
colcon buildsource install/setup/bash。运行命令
1
ros2 run <包名> <程序名>示例中即为:
1
ros2 run demo_cpp_pkg main
tf2
(坐标变换工具)
命令行
1 | |
urdf
(Unified Robot Description Format)
urdf是一种用于表示/仿真机器人模型的XML格式。
下面是 URDF 中常见的标签及其作用简明总览,分为核心结构、几何与外观、运动与连接三大类:
一、核心结构标签
| 标签 | 说明 | 示例/备注 |
|---|---|---|
<robot> |
所有 URDF 的根标签,定义机器人名称 | <robot name="my_bot"> |
<link> |
描述一个部件(如一个刚体) | 机器人上每个零件都需定义为一个 link |
<joint> |
描述两个 link 之间的连接关系 | 定义运动、旋转、固定等 |
二、几何与外观标签(在 <visual>、<collision>、<inertial> 中使用)
| 标签 | 说明 | 示例 |
|---|---|---|
<visual> |
link 的可视化外观 | RViz2 中展示用 |
<collision> |
link 的碰撞体 | 用于仿真、碰撞检测 |
<inertial> |
link 的惯性信息 | 包括质量、惯性矩、质心等 |
<origin> |
坐标原点偏移,定义相对于父元素的位置和姿态 | <origin xyz="0 0 1" rpy="0 0 0"/> |
<geometry> |
定义几何形状(与 visual、collision 配合) |
包含 box、cylinder、sphere、mesh |
<box> |
长方体几何 | <box size="1 1 1"/> |
<cylinder> |
圆柱体几何 | <cylinder length="1" radius="0.5"/> |
<sphere> |
球体几何 | <sphere radius="0.3"/> |
<mesh> |
加载外部模型文件(如 .dae, .stl) |
<mesh filename="package://path/model.dae"/> |
<material> |
材质颜色或纹理 | <material name="gray"><color rgba="0.5 0.5 0.5 1"/></material> |
<color> |
定义颜色值 | RGBA 四维(透明度在最后) |
三、连接与运动标签(joint 内部)
| 标签 | 说明 | 示例 |
|---|---|---|
<parent> |
父 link 名称 | <parent link="base_link"/> |
<child> |
子 link 名称 | <child link="wheel_link"/> |
<axis> |
关节运动的轴向 | <axis xyz="0 0 1"/> 表示绕 Z 轴 |
<limit> |
关节限制(适用于 revolute/prismatic) | <limit lower="-1.57" upper="1.57" effort="1" velocity="1"/> |
<dynamics> |
摩擦/阻尼等动态参数 | 可选,增强仿真精度 |
<type> |
关节类型 | revolute, continuous, prismatic, fixed, floating, planar |
四、其它辅助标签(常用但非必须)
| 标签 | 用途 | 说明 |
|---|---|---|
<transmission> |
与控制器配合使用 | 在控制机器人时才需要 |
<gazebo> |
Gazebo 特定配置(带插件) | 与仿真配合用 |
<xacro:macro> |
Xacro 宏定义 | 重复结构抽象 |
<xacro:property> |
定义变量 | 用于参数传递或配置 |
xacro
(Xml Macro)
ROS还提供了用于简化urdf编写的xacro格式。文件后缀名.xacro。编写好文件后不能直接使用,应先转成urdf格式。
1 | |
在RViz中显示机器人
当我们编写好urdf/xacro机器人描述文件后,rviz并不能自动地去识别不同部件的坐标变换关系。实际上,urdf和rivz中间的桥梁是由robot_state_publisher包(和joint_state_publisher包)搭建起来的。
如上图的关系所示,robot_state_publisher包解析urdf中的tf变换关系。遇到静态tf(如定义为fixed的joint)通过/tf_static话题发布;遇到动态tf关系,先发布到/robot_description话题,另一边被joint_state_publisher包订阅,自动扫描动态的关节,并将其数值发布到/joint_states话题,最后robot_state_publisher包收到后,通过/tf话题发布。
步骤
- 要想urdf加载进rviz,应该编写一个launch文件。在launch目录下新建一个
display.launch.py,内容大致如下(大同小异,理解为主,切勿无脑照抄):
1 | |
修改CMakeLists.txt,添加
install命令,部署目录1
2
3
4
5
6
7
8
9# ...
# 将必要的目录(launch, urdf等)部署到share目录下
install(DIRECTORY
launch
urdf
DESTINATION share/${PROJECT_NAME}/)
# ...编译并部署
1
2colcon build
source install/setup.bash通过launch文件启动
1
ros2 launch <功能包名> display.launch.pyRViz将自动启动。
在RViz内进一步调整:
Fixed Frame默认为world,需要手动切换成你urdf的根部件(如base_link)切换好以后很大概率机器人模型依旧加载不出来,只显示坐标轴。如下图:
解决方法是:点开左下角Add - 添加RobotModel可视化 - 手动选择
Description Topic下拉框中的/robot_description话题让rviz重新加载
自定义消息类型XXX.msg
ROS2中有许多内置的包,如std_msgs和 geometry_msgs,它们都有自己的消息类型用于节点间传输。当我们有这样的需求时也可自定义消息类型,步骤如下:
自定义消息最好单开一个功能包存放,以便实现复用。当然如果你项目小的话挤在一个包里也行,看具体需求。这里我要声明装甲板相关的消息,因此创建一个叫
armor_interface的包。1
ros2 pkg create armor_interface --build-type ament_cmake ...一个消息类型其实就是一个
XXX.msg文件。在包目录下新建msg文件夹,添加下面两个文件:Armor.msg:表示一个装甲板1
2
3
4
5string name
string color
string type
geometry_msgs/Vector3 rvec
geometry_msgs/Pose poseArmors.msg:表示多个装甲板的集合,用于传输1
2std_msgs/Header header
Armor[] data
修改CMakeLists.txt:
添加必要的包
1
2
3find_package(rosidl_default_generators REQUIRED) # 编译器自动识别msg文件并编译成代码
find_package(std_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)生成自定义消息的CMake命令
rosidl_generate_interfaces:1
2
3
4
5
6
7
8rosidl_generate_interfaces(${PROJECT_NAME}
"msg/Armor.msg"
"msg/Armors.msg"
DEPENDENCIES
std_msgs
geometry_msgs
)
修改
package.xml:往
package.xml添加一行(不然不给编译)1
<member_of_group>rosidl_interface_packages</member_of_group>编译&部署包
1
2colcon build
source install/setup.bash