ROS2学习笔记(1)---组件中cmakelist与launch的ament_cmake_auto写法(自用保存)

一,首先是cmakelists.txt

cmake_minimum_required(VERSION 3.8)
project(my_component_pkg)

set(CMAKE_BUILD_TYPE "RELEASE")
#优化生成的可执行文件以提高其性能,包括开启各种优化选项,减少调试信息输出等。

find_package(ament_cmake_auto REQUIRED)
ament_auto_find_build_dependencies()
#这个宏会自动查找所有已在 package.xml 中声明的依赖项,
#并将它们引入到CMake环境中,省去了手动调用 find_package() 的步骤。

file(GLOB_RECURSE my_component_pkg_srcs "src/*.cpp")
#在 src 目录下找到所有扩展名为 .cpp 的源文件,
#并将这些文件的路径存储在 my_component_pkg_srcs变量中
#定义变量时,不需要添加${}
#SRCS后缀是源文件的含义,整个变量可大写小写,但要保持一致

ament_auto_add_library(my_component_gxk SHARED 
${my_component_pkg_srcs})
#构建项目时需要将源代码编译成一个共享库,以便动态链接(组件)
#第一个参数是共享库的名字(my_component_gxk)
#引用变量时,需要添加${}

rclcpp_components_register_node(my_component_gxk 
 PLUGIN "my_component_pkg::SubscriberComponent"
 EXECUTABLE subscriber_node)

rclcpp_components_register_node(my_component_gxk 
 PLUGIN "my_component_pkg::PublisherComponent"
 EXECUTABLE publisher_node)
#用于注册组件节点,EXECUTABLE subscriber_node会生成可执行文件
#第一个参数也是共享库的名字

install(DIRECTORY
  launch
  DESTINATION share/${PROJECT_NAME}/
)

ament_auto_package()

二,接下来是launch文件

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='my_component_pkg',  #包名
            executable='subscriber_node',  # 可执行文件名
            output='screen',  # 输出到控制台
            
        ),
        Node(
            package='my_component_pkg',  #包名
            executable='publisher_node',  # 可执行文件名
            output='screen',  # 输出到控制台
            
        ),
    ])

三,然后是xml文件

注意把各种依赖用<depend>添加至xml文件,这样

find_package(ament_cmake_auto REQUIRED)
ament_auto_find_build_dependencies()

这个代码块才会生效

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>my_component_pkg</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="liujiawei@todo.todo">liujiawei</maintainer>
  <license>TODO: License declaration</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <depend>rclcpp</depend>
  <depend>rclcpp_components</depend>
  <depend>std_msgs</depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

此外编写组件时,要用面向对象的方法,记得添加

#include "rclcpp_components/register_node_macro.hpp"
RCLCPP_COMPONENTS_REGISTER_NODE(my_component_pkg::PublisherComponent)
//用来将一个类注册为可动态加载的组件,使其能够进行加载和运行
//PublisherComponent是你节点类的名称

四,完整cpp代码一览:

#include "rclcpp/rclcpp.hpp"
#include "rclcpp_components/register_node_macro.hpp"
#include "std_msgs/msg/string.hpp"

namespace my_component_pkg
{
class SubscriberComponent : public rclcpp::Node
{
public:
  SubscriberComponent(const rclcpp::NodeOptions & options)
  : Node("subscriber_component", options)
  {
    // 创建订阅者,订阅“topic”话题
    subscription_ = this->create_subscription<std_msgs::msg::String>(
      "topic", 10,
      std::bind(&SubscriberComponent::topic_callback, this, std::placeholders::_1));
  }

private:
  void topic_callback(const std_msgs::msg::String::SharedPtr msg)
  {
    RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg->data.c_str());
  }

  rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};
}  // namespace my_component_pkg

RCLCPP_COMPONENTS_REGISTER_NODE(my_component_pkg::SubscriberComponent)
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_components/register_node_macro.hpp"
#include "std_msgs/msg/string.hpp"

namespace my_component_pkg
{
class PublisherComponent : public rclcpp::Node
{
public:
  PublisherComponent(const rclcpp::NodeOptions & options)
  : Node("publisher_component", options)
  {
    // 创建发布者,发布到“topic”话题
    publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
    
    // 创建一个定时器,定时发布消息
    timer_ = this->create_wall_timer(
      std::chrono::seconds(1),
      std::bind(&PublisherComponent::publish_message, this));
  }

private:
  void publish_message()
  {
    auto message = std_msgs::msg::String();
    message.data = "Hello from PublisherComponent!";
    RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
    publisher_->publish(message);
  }

  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
  rclcpp::TimerBase::SharedPtr timer_;
};
}  // namespace my_component_pkg

RCLCPP_COMPONENTS_REGISTER_NODE(my_component_pkg::PublisherComponent)
对于多个 C++ 节点的情况,您可以将每个节点的源代码放在不同的子目录,每个子目录都有自己的 CMakeLists.txt 文件。 在每个 CMakeLists.txt 文件,您需要使用 `ament_target_dependencies` 函数来声明节点所依赖的其他软件包。例如,如果您的节点需要使用 ROS2 的 `rclcpp`,您需要在 CMakeLists.txt 文件添加以下代码: ``` find_package(rclcpp REQUIRED) ament_target_dependencies(your_node ${rclcpp_LIBRARIES}) ``` 在每个子目录,您还需要使用 `ament_package` 宏来声明软件包的名称、版本等信息。例如: ``` ament_package( VERSION 0.1.0 DESCRIPTION "My ROS2 package" AUTHOR "Your Name" ) ``` 最后,您需要在顶层 CMakeLists.txt 文件使用 `ament_package` 宏声明整个软件包的信息,并使用 `add_subdirectory` 函数将每个子目录添加到构建过程。例如: ``` cmake_minimum_required(VERSION 3.5) project(my_ros2_package) # Find packages find_package(ament_cmake REQUIRED) # Declare package ament_package() # Add subdirectories add_subdirectory(node1) add_subdirectory(node2) ``` 对于 `install`,您可以在每个子目录的 CMakeLists.txt 文件使用 `install` 命令来安装节点。例如: ``` install(TARGETS your_node DESTINATION lib/${PROJECT_NAME} ) ``` 在顶层 CMakeLists.txt 文件,您可以使用 `ament_install_files` 命令来安装其他文件,例如配置文件、启动文件等。例如: ``` ament_install_files( DIRECTORY config launch DESTINATION share/${PROJECT_NAME} ) ``` 注意,在执行 `install` 命令之前,您需要先构建软件包。您可以使用以下命令构建并安装软件包: ``` colcon build --packages-select my_ros2_package colcon install --packages-select my_ros2_package ``` 这样,您就可以在安装目录找到您的节点和其他文件了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值