目录
这一篇,主要目的是:熟悉体会编写节点,编译节点,运行节点的过程,基本都是这个套路框架。
一:准备工作:
打开linux终端复制下面这段代码安装Colon。
sudo apt-get install python3-colcon-common-extensions
Colon,它是把代码编译成一个功能包的工具。
二:C++构建包过程:
1.创建工作空间
就是新建一个文件夹,文件夹下面有src放源代码
cd ~/chapt2/
mkdir -p chapt2_ws/src/
2.创建功能包:example_cpp
按照下面这么建立(套路)
//先进入src下面,这样包就构建在src下面
cd chapt2_ws/src
//功能包名字:example_cpp
//编译类型ament-cmake
//依赖:rclcpp
ros2 pkg create example_cpp --build-type ament_cmake --dependencies rclcpp
- pkg create 是创建包的意思
- build-type 用来指定该包的编译类型,一共有三个可选项ament_python、ament_cmake、cmake
- dependencies 指的是这个功能包的依赖,这里是ros2的C++客户端接口rclcpp
这个命令执行之后,发现功能包example_cpp下面有两个文件夹和两个文件,如上图所示,他们的作用文章最后面在补充,先不管!
example_cpp/src下创建一个node_01.cpp文件,创建完成后的目录结构如下:
touch node_01.cpp
3.编辑节点node_01.cpp代码
#include "rclcpp/rclcpp.hpp"
int main(int argc, char **argv)
{
// 初始化 ROS 2 的运行时环境
// 这一步是必要的,它会设置日志系统、参数服务器等基础设施
// `argc` 和 `argv` 用于传递命令行参数
rclcpp::init(argc, argv);
// 创建一个名为 "node_01" 的 ROS 2 节点
// 使用 `std::make_shared` 创建一个智能指针来管理节点对象的生命周期
auto node = std::make_shared<rclcpp::Node>("node_01");
// 使用 ROS 2 的日志系统打印一条信息级别的日志
// `node->get_logger()` 获取当前节点的日志记录器
// 日志信息表明节点已经成功启动
RCLCPP_INFO(node->get_logger(), "node_01节点已经启动.");
// 运行节点的事件循环
// `rclcpp::spin` 是一个阻塞调用,它会持续运行节点,直到收到退出信号(如 Ctrl+C)
// 在事件循环中,节点会处理订阅的消息、服务请求、定时器回调等
rclcpp::spin(node);
// 关闭 ROS 2 的运行时环境
// 这一步是必要的,它会清理资源,确保程序安全退出
rclcpp::shutdown();
return 0; // 程序正常退出,返回值为 0
}
4.修改CmakeLists
在CmakeLists.txt最后一行加入下面两行代码。
目的是让编译器编译node_01这个文件
/*
这行代码的作用是指定一个可执行文件的构建。
这里,node_01 是你想要构建的可执行文件的名称,
而 src/node_01.cpp 是该可执行文件对应的源代码文件。
这意味着CMake将编译src/node_01.cpp源文件,并生成一个名为node_01的可执行文件.
*/
add_executable(node_01 src/node_01.cpp)
/*
这行代码用于指定node_01这个可执行文件所依赖的库。
ament_target_dependencies是ament构建系统的一个命令,用于在ROS 2项目中管理依赖关系。
这里,node_01是目标(即之前通过add_executable定义的可执行文件),
而rclcpp是它所依赖的库
*/
/*
这个代码ros2特有的绑定库语法
*/
ament_target_dependencies(node_01 rclcpp)
//将构建好的目标文件(就是编译好的节点文件)复制到指定的安装目录中。
install(TARGETS
node_01
DESTINATION lib/${PROJECT_NAME}
)
/*
TARGETS node_01:指定要安装的目标,这里是之前通过add_executable定义的node_01可执行文件。
DESTINATION lib/${PROJECT_NAME}:指定安装目标的目的地。这里的目的地是lib/目录下,紧跟着是${PROJECT_NAME}变量的值,该变量通常在CMakeLists.txt文件的顶部通过project(ProjectName)命令设置。
${PROJECT_NAME}的值是mexample_cpp,那么node_01可执行文件将被安装到lib/example_cpp/目录下。
*/
5.编译运行节点
回到chapt2_ws文件夹中编译节点源代码
cd..
colcon build
编译完成之后发现多了一个install,build,log三个文件夹
- build 目录存储的是中间文件。对于每个包,将创建一个子文件夹,在其中调用例如CMake
- install 目录是每个软件包将安装到的位置。默认情况下,每个包都将安装到单独的子目录中。
- log 目录包含有关每个colcon调用的各种日志信息。
6.source环境
作用其实就是一句话:他会更改PYTHONPATH和AMENT_PREFIX_PATH的环境变量指向当前的目录,从而找到我们的包
source install/setup.bash
source install/setup.bash 在ROS(Robot Operating
System)环境中的作用主要是配置和刷新用户的shell环境,以便能够正确地使用ROS命令和工具。具体来说,这个命令执行了以下几个关键任务:设置环境变量:setup.bash 脚本文件设置了多个必要的环境变量,这些变量对于ROS的运行至关重要。例如,它可能设置了ROS_PACKAGE_PATH环境变量,该变量包含了ROS工作空间中源代码目录的路径,使得ROS能够找到并加载这些源代码目录中的功能包。 更新路径:该脚本还将编译生成的可执行文件、库文件等添加到用户的PATH环境变量中。这样,用户就可以直接在命令行中运行这些文件,而无需指定完整的路径。 初始化ROS环境:除了设置环境变量外,setup.bash 还可能执行一些初始化操作,如加载ROS的Python模块、设置日志记录等。
在ROS中,每次重新编译工作空间或启动一个新的终端会话时,都需要执行source
install/setup.bash命令来刷新环境配置。这是因为每次编译后,生成的可执行文件和库文件都可能发生变化,而新的终端会话则不会继承之前会话中的环境变量设置。为了简化这个过程,用户可以将source
install/setup.bash命令添加到他们的/.bashrc或/.bash_profile文件中(取决于使用的shell和操作系统)。这样,每次打开新的终端会话时,该命令都会自动执行,无需手动输入。
7.运行节点
ros2 run example_cpp node_01
三:python构建包过程:
1.创建工作空间
和C++一样操作
2.创建功能包(功能包名字:demo_pkg_python)
ros2 pkg create demo_pkg_python -- build-type ament_python --license Apache-2.0
- ros2 pkg create:创建包命令
- build-type:创建python类型
- license :开源协议
执行完命令后,功能包会新建如下图所示的文件结构
我们在demo_pkg_python文件夹下面新建ros2_python_node.py文件
3.编辑节点ros2_python_node.cpp代码
import rclpy
from rclpy.node import Node
def main(args=None):
"""
ros2运行该节点的入口函数
编写ROS2节点的一般步骤
1. 导入库文件
2. 初始化客户端库
3. 新建节点对象
4. spin循环节点
5. 关闭客户端库
"""
rclpy.init(args=args) # 初始化rclpy
node = Node("node_02") # 新建一个节点
node.get_logger().info("大家好,我是node.")
rclpy.spin(node) # 保持节点运行,检测是否收到退出指令(Ctrl+C)
rclpy.shutdown() # 关闭rclpy
4.修改setup.py
如下图所示
entry_points={
'console_scripts': [
'pyhton_exe_name = demo_pkg_python.ros2_python_node:main',
],
含义是:可执行文件名字(任意起名)= 包名字/节点名字:节点内主函数名
注意,加入多行的时候,后面不要忘记加逗号,单行也可以加
5.修改package.xml中添加依赖信息
如果新建包文件中
3.构建
注意:回到工作空间的文件层架 构建
colcon build
构建完成,出现了三个文件夹
build:构建过程中的中间文件
install:构建结果的文件夹
log
install文件夹->lib文件夹中的对应功能包下面就是可执行文件
四:关于功能包的其他补充(文件结构,包命令)
1.文件结构(python)
2.练习关于包的命令
既然包已经构建好了,就练习一下上一篇文章所写的关于包的命令
列出包中所有可执行文件
cd d2lros2/chapt2/chapt2_ws//进入这个文件夹
source install/setup.bash//必须source一下资源
ros2 pkg executables example_cpp//查询
这个节点就查询出来了
.列出所有的包
ros2 pkg list
可以看到example_cpp已经在里面了
.输出某个包所在路径的前缀
cd d2lros2/chapt2/chapt2_ws//进入这个文件夹
source install/setup.bash//必须source一下资源
ros2 pkg prefix example_cpp
结果:打印出来了路径
.列出包的清单描述文件
ros2 pkg xml example_cpp
还有一个比较牛的命令 ldd 可执行文件 会输出这个可执行文件所依赖的库,以及链接关系
按照本文操作一遍之后,肯定对流程比较了解了,下面一篇,我们来分析和完善代码方面的知识!