ROS2 + C++ 节点(自用笔记)

系列文章目录

留空



前言

自用


一、创建工作空间和功能包

1、工作空间

(1)Ctrl+Win+T开启终端

(2)创建一个叫towm_ws的工作空间

mkdir -p towm_ws

(3)进入工作空间

cd towm_ws

(4)在工作空间中创建一个文件夹src存放功能包

mkdir -p src

(5)编译工作空间

colcon build

在执行colcon build之前,通常需要先进入工作空间并创建一个空的src文件夹。colcon build命令会自动生成install、build、log文件夹。
在这里插入图片描述

2、功能包

(1)进入src文件夹

cd src

(2)创建一个基于C++learning_node功能包

ros2 pkg create learning_node --build-type ament_cmake --dependencies rclcpp

在这里插入图片描述
(3)在Vscode中打开src
在这里插入图片描述
打开后可以看见刚刚创建的功能包
在这里插入图片描述

二、使用RCLCPP编写节点

1、创建节点

在vscode中,learning_node -> 新建文件 -> wang2_node.cpp
在这里插入图片描述
在这里插入图片描述

2、编写代码

(1)完整代码

#include "rclcpp/rclcpp.hpp"

class LearningNode : public rclcpp::Node
{

    public:
        LearningNode(std::string name) : Node(name)
        {
            RCLCPP_INFO(this->get_logger(),"节点%s已启动",name.c_str());
        }
    private:
        
};

int main(int argc,char** argv)
{
    rclcpp::init(argc,argv);
    auto node = std::make_shared<LearningNode>("wang2");
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

(2)每次编写完代码记得修改CmakeLists.txt,添加以下代码

add_executable(wang2_node src/wang2.cpp)
ament_target_dependencies(wang2_node rclcpp)

install(TARGETS
    wang2_node
    DESTINATION lib/${PROJECT_NAME}
)

在这里插入图片描述

三、分析代码

1、主函数:程序的入口

 编写主函数的步骤:
 (1)初始化rclcpp
 (2)产生一个节点
 (3)运行节点
 (4)停止运行
 (5)return 0
int main(int argc,char** argv)
{
    rclcpp::init(argc,argv);
    auto node = std::make_shared<LearningNode>("wang2");
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

(1)初始化ROS2客户端库。这是创建ROS2节点之前必须做的第一步

rclcpp::init(argc,argv);

可以看看这篇文章:理解argc和argv是什么

(2)创建一个叫“wang2”的节点

auto node = std::make_shared<LearningNode>("wang2");

std::make_shared<LearningNode>("wang2"):这部分代码使用std::make_shared函数创建了一个指向LearningNode对象的shared_ptr智能指针。LearningNode是一个自定义的类,继承自ROS2的rclcpp::Node类。在这里,通过make_shared函数创建了一个名为node的智能指针,并将其初始化为指向一个具有名称"wang2"的LearningNode对象。

auto node = ...:使用auto关键字可以让编译器根据右侧表达式的类型推断出node的类型,这里推断出node是一个指向LearningNode对象的shared_ptr智能指针。

综合起来,这行代码的作用是创建一个名为node的智能指针,指向一个具有名称"wang2"的LearningNode对象(这样就是创建了一个ROS 2节点),并赋予了节点一个特定的名称,以便在程序中引用和操作该节点。

(3)使节点进入事件循环,开始运行节点的回调函数并处理 ROS2中的事件。这个循环会持续运行,直到被外部因素(如程序结束或收到信号)打断。

rclcpp::spin(node);

(4)关闭ROS2系统,清理资源并终止节点运行

rclcpp::shutdown();

2、LearningNode类

class LearningNode : public rclcpp::Node
{

    public:
        LearningNode(std::string name) : Node(name)
        {
            RCLCPP_INFO(this->get_logger(),"节点%s已启动",name.c_str());
        }
        
    private:
         
};

(1)定义了一个继承自rclcpp::Node的类LearningNode

class LearningNode : public rclcpp::Node

class LearningNode :定义了一个名为LearningNode的类
: public rclcpp::Node:表示LearningNode类继承自rclcpp::Node类。这意味着LearningNode类将获得rclcpp::Node类的所有成员变量和方法,同时还可以添加自己的成员变量和方法。

(2) 表示接下来的成员变量和方法在类的访问权限部分

 public/private:

pubilc:接下来的成员变量和方法是类的公共访问权限部分,可以被外部访问。
private:接下来的成员变量和方法是类的私有访问权限部分,只能在类的内部访问。

(3)这是LearningNode类中公有的构造函数

LearningNode(std::string name) : Node(name)
{
	
}

LearningNode(std::string name): 这是LearningNode类的构造函数,它接受一个 std::string类型的参数name

: Node(name): 这部分代码调用基类rclcpp::Node的构造函数,并将前部分代码的name参数传递给它。这意味着当你创建一个LearningNode对象时,它首先会调用rclcpp::Node的构造函数来初始化基类部分。

(4)打印一条消息(类似于C语言中的"printf")

RCLCPP_INFO(this->get_logger(),"节点%s已启动",name.c_str());

RCLCPP_INFO: 这是一个ROS 2的宏,用于记录信息级别的日志。在ROS 2中,日志系统用于记录不同级别的信息,如调试、信息、警告和错误等。

this->get_logger(): this 是一个指向当前对象的指针。get_logger() 是从基类 rclcpp::Node 继承的一个方法,它返回一个与当前节点关联的日志记录器对象。通过这个日志记录器,我们可以记录与节点相关的日志信息。

"节点%s已启动": 这是一个格式字符串,用于定义日志消息的格式。%s 是一个占位符,它将被后面的参数替换。在这个例子中,%s 将被替换为节点的名称。

name.c_str(): name 是一个 std::string 类型的变量,它包含了节点的名称。c_str()std::string类的一个方法,用于返回一个指向以空字符结尾的字符数组的指针,这个字符数组就是该字符串的C风格表示。这是因为RCLCPP_INFO宏的格式化字符串参数需要C风格的字符串(即 char* 类型)。

综上所述,这行代码的作用是:使用当前节点的日志记录器,输出一条信息级别的日志,内容大致为“节点[节点名称]已启动”,其中[节点名称]是传递给构造函数的name参数的值。


四、编译

下面是简洁的叙述,想要了解深入一点,可以看看这篇ROS2编译运行节点代码

打开终端,输入命令行

(1)进入工作空间

cd towm_ws

(2)这个命令告诉计算机去构建一个叫做learning_node的ROS2软件包。就像在工厂里生产一个特定的产品一样。

colcon build --packages-select learning_node

(3)这个命令告诉计算机设置一些东西,让它知道在哪里找到刚刚构建好的软件包。这就像是在告诉工厂工人,新生产的产品应该放在哪个仓库或货架上,以便后续可以轻松地找到并使用它们。

source install/setup.bash

(4)这个命令告诉计算机去运行learning_node软件包中的wang2节点,

ros2 run learning_node wang2_node

在这里插入图片描述

(5)运行结果

[INFO] [1714027571.680855970] [wang2]: 节点wang2已启动

到此,我们就成功的运行了一个节点!

总结

自用

ROS 2 (Robot Operating System) 中,使用 C++ 编写相机节点通常涉及以下几个步骤: 1. **安装依赖**: 首先,你需要确保已经安装了 ROS 2 的相关包,包括 `ros2cpp` 和任何用于摄像头驱动(如 `camera_calibration` 或 `image_transport`)。可以使用 `ros2 package manager`(如 `ros2 apt` 或者 `ament build`)来安装。 2. **创建节点**: 创建一个新的 C++ 工程,并添加必要的头文件,例如 `<rclcpp/rclcpp.hpp>`、`<sensor_msgs/imagemsg.hpp>` 等,它们分别代表了 ROS 2 的通信库和图像消息。 3. **定义节点**: 定义一个继承自 `rclcpp::Node` 类的子类,比如 `CameraNode`,并在构造函数中初始化 `Node` 对象。 ```cpp #include <rclcpp/rclcpp.hpp> #include <sensor_msgs/imagemsg.h> class CameraNode : public rclcpp::Node { public: explicit CameraNode(rclcpp::NodeOptions options) : Node("camera_node", options) {} // 在这里添加相机数据获取和发布图像的方法 }; ``` 4. **订阅和发布**: 创建订阅器订阅相机的数据流,当接收到新的图像数据时,处理并将其转换成 `sensor_msgs::Image` 消息。同时,创建一个发布器将图像发送到其他节点。 ```cpp void image_callback(const sensor_msgs::msg::Image::SharedPtr msg) { auto img_msg = std::make_shared<sensor_msgs::msg::Image>(); // 将接收到的图像数据处理并复制到img_msg中 publisher_->publish(img_msg); } int main(int argc, char * argv[]) { rclcpp::init(argc, argv); CameraNode node; auto sub = node.create_subscription<sensor_msgs::msg::Image>("camera_topic", 10, image_callback); rclcpp::spin(node); // 这里启动事件循环,监听回调和网络活动 return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值