• 正文
  • 相关推荐
申请入驻 产业图谱

ROS2发布自定义数据C++编程示例

08/18 08:23
117
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

之前的文章:Ubuntu20安装ROS2-FoxyFitzroy与C++基础测试,介绍了ROS2的安装和ROS2的C++基础编程示例,本篇来继续介绍ROS2的话题发布功能,并测试发布自定义的数据。

1 创建自定义消息的包

1.1 创建test_msg包

cd ~/dev_ws/src
ros2 pkg create --build-type ament_cmake test_msg

1.2 自定义msg

cd test_msg
mkdir msg

新建文件 msg/PersonInfo.msg,写入内容

# 自定义结构体一样的消息
string name
int32 age
float32 height
bool is_student

等价于 C++ 结构体

struct PersonInfo{
  std::string name;
  int32_t age;
  float height;
  bool is_student;
};

1.3 修改package.xml

修改 package.xml的消息生成依赖,增加这3行

<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>

1.4 修改 CMakeLists.txt

在文件末尾,`ament_package()之前添加消息生成代码

find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/PersonInfo.msg"
)

ament_export_dependencies(rosidl_default_runtime)

2 创建发布节点的包

2.1 创建test_02_publish

该包依赖rclcpp和自定义的test_msg

cd ~/dev_ws/src
ros2 pkg create --build-type ament_cmake test_02_publish --dependencies rclcpp test_msg
cd test_02_publish

2.2  编写代码

src中创建person_publisher.cpp

测试代码如下:

#include "rclcpp/rclcpp.hpp"
#include "test_msg/msg/person_info.hpp"

using namespace std::chrono_literals;

class PersonInfoPublisher : public rclcpp::Node
{
public:
    PersonInfoPublisher() : Node("person_publisher_node")
    {
        // 创建发布器,话题名 /person_info,消息类型 test_msg::msg::PersonInfo,队列10
        publisher_ = this->create_publisher<test_msg::msg::PersonInfo>("/person_info", 10);
        // 定时器 500ms 发布一次
        timer_ = this->create_wall_timer(500ms, std::bind(&PersonInfoPublisher::timer_callback, this));
        RCLCPP_INFO(this->get_logger(), "自定义消息发布节点启动");
    }

private:
    void timer_callback()
    {
        auto msg = test_msg::msg::PersonInfo();
        msg.name = "zhangsan";
        msg.age = 22;
        msg.height = 1.75f;

        RCLCPP_INFO(this->get_logger(), "发布: name=%s, age=%d, height=%.2f",
                    msg.name.c_str(), msg.age, msg.height);
        publisher_->publish(msg);
    }

    rclcpp::Publisher<test_msg::msg::PersonInfo>::SharedPtr publisher_;
    rclcpp::TimerBase::SharedPtr timer_;
};

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

2.2.1 代码说明

    • PersonInfoPublisher构造函数中,会创建发布器

publisher_

    • 和定时器

timer_

      • 发布器的话题名是

/person_info

      • ,消息类型

test_msg::msg::PersonInfo

      • ,队列10定时器周期500ms,注册回调函数

timer_callback

回调函数中,发布器publisher_发布自定义的PersonInfo数据

2.2.2 发布器的写法

// 发布器声明
rclcpp::Publisher<test_msg::msg::PersonInfo>::SharedPtr publisher_;

// 创建发布器,话题名 /person_info,消息类型 test_msg::msg::PersonInfo,队列10
publisher_ = this->create_publisher<test_msg::msg::PersonInfo>("/person_info", 10);

// 发布数据
auto msg = test_msg::msg::PersonInfo();
msg.name = "zhangsan";
msg.age = 22;
msg.height = 1.75f;
RCLCPP_INFO(this->get_logger(), "发布: name=%s, age=%d, height=%.2f",msg.name.c_str(), msg.age, msg.height);
publisher_->publish(msg);

2.3 修改package.xml

ros2 pkg create 已经自动添加 rclcpp、test_msg 依赖,确认存在即可

  <buildtool_depend>ament_cmake</buildtool_depend>

  <depend>rclcpp</depend>
  <depend>test_msg</depend>

2.4 修改 CMakeLists.txt

test_02_publish/CMakeLists 增加下面这些内容

# 编译可执行文件
add_executable(person_publisher src/person_publisher.cpp)
ament_target_dependencies(person_publisher rclcpp test_msg)

# 安装
install(TARGETS
  person_publisher
  DESTINATION lib/${PROJECT_NAME}
)

3 编译

3.1 代码目录结构

可以先看到代码的目录结构

3.2 编译

cd ~/dev_ws
colcon build --packages-select test_msg test_02_publish

4 运行

4.1 运行数据发布程序

在终端 1中运行发布节点

source install/setup.bash
ros2 run test_02_publish person_publisher

4.2 ros2指令监听话题

新开终端 2,监听话题验证

source ~/dev_ws/install/setup.bash
ros2 topic echo /person_info

5 关于自定义消息的头文件的生成

ROS2 的 rosidl 生成器,对于驼峰命名 PersonInfo.msg生成的头文件是 person_info.hpp

转换逻辑是:

输入格式‌:.msg 源文件必须位于包的 msg/ 目录下,文件名通常采用‌大驼峰命名法‌(PascalCase),如 MyMessage.msg。‌

大小写处理‌:生成器自动将文件名中的大写字母转换为‌全小写‌。‌

分隔符处理‌:原文件名中的大写字母边界处插入‌下划线_(即驼峰转蛇形),若原文件名已含下划线则保留。‌

后缀替换‌:将 .msg 后缀替换为 ‌**.hpp**‌。‌

最终路径‌:头文件安装在 <package_name>/msg/<converted_name>.hpp

去对应目录看,可以看到 person_info.hpp的内容,它实际又是引用的 person_info__struct.hpp

再继续看,实际是定义的PersonInfo_

然后通过using PersonInfo = test_msg::msg::PersonInfo_<std::allocator<void>>;对外展示为PersonInfo

6 总结

本篇介绍了ROS2中发布器的简单使用,使用C++编程,创建自定义话题的数据结构,在定时器回调函数中,发布器发布自定义的数据,再通过ros2指令监听话题来验证发布的数据

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录