25/1/21 算法笔记<ROS2> 编译ROS2 c++节点文档步骤

        在 ROS 2 中,创建节点是指编写一个程序(通常是 C++ 或 Python 代码),这个程序能够与 ROS 2 系统进行交互,执行特定的任务。

        节点是 ROS 2 中最基本的执行单元,每个节点通常负责完成一个特定的功能,例如控制机器人、处理传感器数据或执行计算。

完整步骤:编译 ROS 2 C++ 节点

1. 准备工作

  1. 有ROS2
  2. 安装colcon构建工具
  3. 安装turtlesim包

2. 创建工作空间

  • 创建工作空间:ROS 2 的工作空间是一个目录结构,用于组织和管理你的代码。工作空间通常包含以下目录:

    • src:存放源代码。

    • build:存放编译生成的中间文件。

    • install:存放编译后的可执行文件和库。

    • log:存放编译和运行的日志文件。

  • 创建包:使用 ros2 pkg create 命令创建一个新的 ROS 2 包。包是 ROS 2 中的基本单元,包含代码、配置文件和依赖项。

     1.创建一个新的工作空间目录:

mkdir -p ~/topic_ws/src
cd ~/topic_ws/src

     2.使用 ros2 pkg create 创建一个新的 ROS 2 包:

ros2 pkg create --build-type ament_cmake demo_cpp_topic
  • 这会生成一个名为 demo_cpp_topic 的包,包含 package.xml 和 CMakeLists.txt 文件。

  • ros2 pkg create status_interfaces --dependencies builtin_interfaces rosidl_default_genterators --license Apache-2.0

3. 编写 C++ 代码

1.进入包的目录:

cd demo_cpp_topic

2.创建 src 目录(如果不存在):

mkdir src

3.在 src 目录下创建 turtle_circle.cpp 文件,并编写代码:

#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"

using namespace std::chrono_literals;

class TurtleCircleNode : public rclcpp::Node
{
public:
    TurtleCircleNode() : Node("turtle_circle")
    {
        publisher_ = this->create_publisher("/turtle1/cmd_vel", 10);
        timer_ = this->create_wall_timer(1000ms, std::bind(&TurtleCircleNode::timer_callback, this));
    }

private:
    void timer_callback()
    {
        auto msg = geometry_msgs::msg::Twist();
        msg.linear.x = 1.0;
        msg.angular.z = 0.5;
        publisher_->publish(msg);
    }

    rclcpp::Publisher::SharedPtr publisher_;
    rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char *argv[])
{
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared());
    rclcpp::shutdown();
    return 0;
}

4. 配置 CMakeLists.txt

  • 定义编译规则CMakeLists.txt 文件告诉 colcon 如何编译你的代码。它指定了:

    • 可执行文件的名称(如 turtle_circle)。

    • 需要编译的源文件(如 src/turtle_circle.cpp)。

    • 依赖的库(如 rclcpp 和 geometry_msgs)。

1.打开 CMakeLists.txt 文件,添加以下内容以编译 turtle_circle.cpp

# 添加可执行文件
add_executable(turtle_circle src/turtle_circle.cpp)

# 链接依赖库
ament_target_dependencies(turtle_circle rclcpp geometry_msgs)

# 安装可执行文件
install(TARGETS
  turtle_circle
  DESTINATION lib/${PROJECT_NAME})

5. 配置 package.xml

  • 定义包元数据package.xml 文件包含了包的元数据,如名称、版本、描述、作者和许可证。

  • 声明依赖项package.xml 文件还声明了包所依赖的其他 ROS 2 包(如 rclcpp 和 geometry_msgs)。这些依赖项会在编译和运行时被自动加载。

1.打开 package.xml 文件,确保以下依赖项已添加:

rclcpp
geometry_msgs

6. 编译工作空间

  • 定义包元数据package.xml 文件包含了包的元数据,如名称、版本、描述、作者和许可证。

  • 声明依赖项package.xml 文件还声明了包所依赖的其他 ROS 2 包(如 rclcpp 和 geometry_msgs)。这些依赖项会在编译和运行时被自动加载。

        1.返回工作空间根目录:

cd ~/topic_ws

        2.使用 colcon build 编译工作空间:

colcon build

        如果只想编译 demo_cpp_topic 包,可以使用:

colcon build --packages-select demo_cpp_topic

        3.编译完成后,加载工作空间环境:

source install/setup.bash

7. 运行节点

        1.启动 turtlesim 仿真器:

ros2 run turtlesim turtlesim_node

        2.运行你的节点:

ros2 run demo_cpp_topic turtle_circle

分析完整代码

我们来分析一下这段完整的代码

#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"

using namespace std::chrono_literals;

class TurtleCircleNode : public rclcpp::Node
{
private:
    rclcpp::Publisher::SharedPtr publisher_; // 发布者
    rclcpp::TimerBase::SharedPtr timer_; // 定时器

public:
    explicit TurtleCircleNode(const std::string& node_name) : Node(node_name) // 使用传入的节点名称
    {
        // 创建发布者,发布到 /turtle1/cmd_vel 话题
        publisher_ = this->create_publisher("/turtle1/cmd_vel", 10);
        // 创建定时器,每隔 1000ms 调用一次 timer_callback
        timer_ = this->create_wall_timer(1000ms, std::bind(&TurtleCircleNode::timer_callback, this));
    }

    void timer_callback()
    {
        auto msg = geometry_msgs::msg::Twist(); // 创建 Twist 消息
        msg.linear.x = 1.0;  // 设置线速度
        msg.angular.z = 0.5; // 设置角速度
        publisher_->publish(msg); // 发布消息
    }
};

int main(int argc, char* argv[])
{
    rclcpp::init(argc, argv); // 初始化 ROS 2
    auto node = std::make_shared("turtle_circle"); // 创建节点
    rclcpp::spin(node); // 进入事件循环
    rclcpp::shutdown(); // 关闭 ROS 2
    return 0;
}

1. 头文件引入

#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"
  • rclcpp/rclcpp.hpp:ROS 2 的 C++ 客户端库,提供了创建节点、发布者、订阅者等功能的 API。

  • geometry_msgs/msg/twist.hpp:ROS 2 中的标准消息类型,用于表示速度(线速度和角速度)。

2. 命名空间

using namespace std::chrono_literals;
  • std::chrono_literals:C++ 的时间字面量库,方便表示时间单位(如 1000ms 表示 1000 毫秒)。

3. 节点类定义
class TurtleCircleNode : public rclcpp::Node
{
private:
    rclcpp::Publisher::SharedPtr publisher_; // 发布者
    rclcpp::TimerBase::SharedPtr timer_; // 定时器
  • TurtleCircleNode:自定义的 ROS 2 节点类,继承自 rclcpp::Node

  • publisher_:用于发布 geometry_msgs::msg::Twist 消息的发布者。

  • timer_:定时器,用于定期触发回调函数。

4. 构造函数
public:
    explicit TurtleCircleNode(const std::string& node_name) : Node(node_name)
    {
        // 创建发布者,发布到 /turtle1/cmd_vel 话题
        publisher_ = this->create_publisher("/turtle1/cmd_vel", 10);
        // 创建定时器,每隔 1000ms 调用一次 timer_callback
        timer_ = this->create_wall_timer(1000ms, std::bind(&TurtleCircleNode::timer_callback, this));
    }
  • Node(node_name):调用基类构造函数,初始化节点,节点名称为传入的 node_name

  • create_publisher:创建一个发布者,发布到 /turtle1/cmd_vel 话题,消息类型为 geometry_msgs::msg::Twist,队列长度为 10。

  • create_wall_timer:创建一个定时器,每隔 1000 毫秒(1 秒)调用一次 timer_callback 函数。

5. 定时器回调函数
void timer_callback()
{
    auto msg = geometry_msgs::msg::Twist(); // 创建 Twist 消息
    msg.linear.x = 1.0;  // 设置线速度
    msg.angular.z = 0.5; // 设置角速度
    publisher_->publish(msg); // 发布消息
}
  • geometry_msgs::msg::Twist():创建一个 Twist 消息对象。

  • msg.linear.x:设置线速度(x 方向的速度,单位为 m/s)。

  • msg.angular.z:设置角速度(绕 z 轴的旋转速度,单位为 rad/s)。

  • publisher_->publish(msg):将消息发布到 /turtle1/cmd_vel 话题,控制海龟运动。

6. 主函数
int main(int argc, char* argv[])
{
    rclcpp::init(argc, argv); // 初始化 ROS 2
    auto node = std::make_shared("turtle_circle"); // 创建节点
    rclcpp::spin(node); // 进入事件循环
    rclcpp::shutdown(); // 关闭 ROS 2
    return 0;
}
  • rclcpp::init(argc, argv):初始化 ROS 2,解析命令行参数。

  • std::make_shared("turtle_circle"):创建 TurtleCircleNode 节点对象,节点名称为 "turtle_circle"

  • rclcpp::spin(node):进入事件循环,等待回调函数被触发(如定时器回调)。

  • rclcpp::shutdown():关闭 ROS 2,释放资源。

代码运行逻辑:

  1. 节点启动后,定时器每隔 1 秒触发一次 timer_callback

  2. 在 timer_callback 中,创建一个 Twist 消息,设置线速度和角速度。

  3. 将消息发布到 /turtle1/cmd_vel 话题,控制海龟运动。

  4. 由于线速度和角速度是固定的,海龟会以固定的半径和速度画圆。

总结步骤

1. 编写节点代码
2. 配置 CMakeLists.txt
3. 配置 package.xml
4. 编译节点
5. 运行节点

你可能感兴趣的:(c++,开发语言)