3.构建ROS2功能包
文章目录
- 3.构建ROS2功能包
- 3.1ROS2中包的组成部分
- 3.2创建ROS2功能包并编写节点
- 3.2.1使用CMake创建功能包
- 3.2.2编写cpp节点代码
- 3.3编译运行节点
- 3.4使用面向对象的方式编写ROS2节点
- 3.5使用RCLPY编写节点
- Reference
3.1ROS2中包的组成部分
ROS2可以使用CMake
或者Python
来创建工作包,使用cpp
进行开发推荐使用CMake
,使用python
进行开发推荐使用Python
来创建包。
ROS2 Python
和CMake
各自有自己的最低要求内容:
CMake
:
CMakeLists.txt
描述如何在包中构建代码的文件include/<package_name>
包含包的公共标头的目录package.xml
包含有关包的元信息的文件src
包含包的源代码的目录
Python
:
package.xml
包含有关包的元信息的文件resource/<package_name>
包的标记文件setup.cfg
当包有可执行文件时是必需的,因此可以找到它们ros2 run
setup.py
包含如何安装软件包的说明<package_name>
- 与您的包同名的目录,ROS 2 工具使用它来查找您的包,包含__init__.py
3.2创建ROS2功能包并编写节点
在创建ROS2功能包之前,确保你已经位于工作空间当中,这里我的工作空间命名为colcon_test02_ws
cd colcon_test02_ws/src
创建功能包,推荐使用ament_cmake
(cpp)或ament_python
(python)作为编译类型,并且添加rclcpp
依赖。
3.2.1使用CMake创建功能包
1.创建一个包,在ROS2中创建新包的命令语法是:
ros2 pkg create <package_name> --build-type ament_cmake --license Apache-2.0 --dependencies rclcpp
pkg create
是创建包的意思--build-type
用来指定该包的编译类型,一共有三个可选项ament_python
、ament_cmake
、cmake
--license
用于制定证书,一般设置为Apache-2.0
,如果不指定的话会弹出一个警告但是没有别的影响--dependencies
指的是这个功能包的依赖,这里使用的依赖是rclcpp
这里使用以下语句构建了一个包
ros2 pkg create example_cpp --build-type ament_cmake --dependencies rclcpp --license Apache-2.0
构建完毕后,包内的目录为:
.
├── CMakeLists.txt
├── include
│ └── example_cpp
├── LICENSE
├── package.xml
└── src3 directories, 3 files
2.编译新创建的包,在ROS2中的编译命令为:
colcon build
但是这条命令会编译整个工作空间,非常耗时,如果我们只想编译构建特定的功能包可以使用:
colcon build --packages-select <my_package>
这里使用了以下的命令来构建上面创建的功能包
colcon build --packages-select example_cpp
构建完毕后,结果如下:
Starting >>> example_cpp
Finished <<< example_cpp [1.46s] Summary: 1 package finished [1.72s]
3.2.2编写cpp节点代码
1.首先编写脚本代码,我们在example_cpp/src
下创建一个脚本文件node01.cpp
,编写下列代码
#include "rclcpp/rclcpp.hpp"int main(int argc, char **argv){// 初始化rclcpprclcpp::init(argc, argv);// 产生一个节点,并命名为node01auto node = std::make_shared<rclcpp::Node>("node01");// 打印消息RCLCPP_INFO(node->get_logger(), "node01 has already launched");rclcpp::spin(node);// 停止运行rclcpp::shutdown();return 0;
}
2.然后配置CMakeLists.txt
将其添加为可执行文件,在CMakeLists.txt
最后一行(ament_package()
之前)加入
add_executable(node01 src/node01.cpp)
ament_target_dependencies(node01 rclcpp)
并且使用install
指令将其安装到install
目录中,在上面两行代码的后面加入
install(TARGETSnode01DESTINATION lib/${PROJECT_NAME}
)
修改完毕的CMakeLists.txt
文件看起来像
cmake_minimum_required(VERSION 3.8)
project(example_cpp)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)
find_package(rclcpp 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 filesset(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 filesset(ament_cmake_cpplint_FOUND TRUE)ament_lint_auto_find_test_dependencies()
endif()add_executable(node01 src/node01.cpp)
ament_target_dependencies(node01 rclcpp)
install(TARGETSnode01DESTINATION lib/${PROJECT_NAME}
)
ament_package()
3.3编译运行节点
进入到工作空间
cd <your_workspace>
然后编译指定的功能包
colcon build --packages-select example_cpp
然后source
一下,运行节点
source install/setup.bash
ros2 run example_cpp node01
结果如下:
3.4使用面向对象的方式编写ROS2节点
在之前的功能包example_cpp
中,我们使用面向对象编成的方式来重构代码,新建一个node02.cpp
脚本文件,然后输入以下的代码
#include "rclcpp/rclcpp.hpp"
#include <string>// 构建一个类节点Node02,该节点继承自rclcpp::Node
class Node02: public rclcpp::Node
{
public:// 构造函数,传入的参数为节点的名字Node02(std::string name) : Node(name) // 调用了基类的构造函数rclcpp::Node{RCLCPP_INFO(this->get_logger(), "node02 has already launched");}
private:};int main(int argc, char **argv){rclcpp::init(argc, argv);auto node = std::make_shared<Node02>("node02");rclcpp::spin(node);rclcpp::shutdown();return 0;
}
然后添加配置文件
add_executable(node02 src/node02.cpp)
ament_target_dependencies(node02 rclcpp)
install(TARGETSnode02DESTINATION lib/${PROJECT_NAME}
)
然后运行
cd <your_workspace>
colcon build
source ./install/setup.bash
ros2 run example_cpp node02
结果如下:
3.5使用RCLPY编写节点
整个流程省略了,可以参考d2lros2和编写一个简单的服务和客户端Python。
Reference
d2lros2
ROS2 Tutorial