ROS2 如何实现自定义Msg数据结构

1、前置准备

缺少一些库需要提前安装,也可以边colcon边装,缺啥装啥,只作为记录

pip3 install lark -i https://pypi.doubanio.com/simple/

pip3 install numpy -i https://pypi.doubanio.com/simple/

pip3 uninstall em    (如果有em的话 就卸载 安装empy)
pip3 install empy==3.3.2 -i https://pypi.doubanio.com/simple/   版本号有要求 


2、创建msg文件

qhr_ws/src/test_moudle 路径下创建msg文件夹 

文件夹下创建文件 MyMessage.msg   (文件名称必须首单词大写且没有下划线,类似my_message都会报错)

内容如下:

string name
int32 age

创建后目录树如上

3、修改依赖

CMakeLists.txt 添加

find_package(rosidl_default_generators REQUIRED)

# 设置消息文件路径
set(msg_FILES
  "msg/MyMessage.msg"
)

# 添加消息生成目标
rosidl_generate_interfaces(${PROJECT_NAME}
  ${msg_FILES}
)




# 安装消息文件
install(DIRECTORY msg/
DESTINATION share/${PROJECT_NAME}/msg
)

package.xml  添加

  <depend>rosidl_default_generators</depend>

  <exec_depend>rosidl_default_runtime</exec_depend>

  <member_of_group>rosidl_interface_packages</member_of_group>

4、编译生成msg头文件

(rospy38) ➜  qhr_ws colcon build          
Starting >>> test_moudle
Finished <<< test_moudle [7.44s]                     

Summary: 1 package finished [7.60s]

(rospy38) ➜  qhr_ws source install/setup.zsh
(rospy38) ➜  qhr_ws ros2 interface show test_moudle/msg/MyMessage
string name
int32 age
(rospy38) ➜  qhr_ws 

可以看到路径:install/test_moudle/include/test_moudle/test_moudle/msg/my_message.h 已经存在对应的头文件,并且通过命令行 也能查到对应的接口

5、talker和listener代码测试

发布code:

#include "rclcpp/rclcpp.hpp"
#include "test_moudle/msg/my_message.hpp"  // 包含自定义消息头文件
#include <chrono>
#include <memory>

using namespace std::chrono_literals;

class Talker : public rclcpp::Node
{
public:
    Talker() : Node("talker")
    {
        publisher_       = this->create_publisher<test_moudle::msg::MyMessage>("my_topic", 10);
        auto publish_msg = [this]() -> void {
            auto message = test_moudle::msg::MyMessage();
            message.name = "Alice";
            message.age  = count_++;
            RCLCPP_INFO(this->get_logger(), "Publishing: name='%s', age=%d", message.name.c_str(), message.age);
            this->publisher_->publish(message);
        };
        timer_ = this->create_wall_timer(500ms, publish_msg);
    }

private:
    rclcpp::TimerBase::SharedPtr                              timer_;
    rclcpp::Publisher<test_moudle::msg::MyMessage>::SharedPtr publisher_;
    size_t                                                    count_ = 1;
};

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

订阅code:

#include "rclcpp/rclcpp.hpp"
#include "test_moudle/msg/my_message.hpp"  // 包含自定义消息头文件
#include <memory>

class Listener : public rclcpp::Node
{
public:
    Listener() : Node("listener")
    {
        subscription_ = this->create_subscription<test_moudle::msg::MyMessage>("my_topic", 10, std::bind(&Listener::topic_callback, this, std::placeholders::_1));
    }

private:
    void topic_callback(const test_moudle::msg::MyMessage::SharedPtr msg) const
    {
        RCLCPP_INFO(this->get_logger(), "I heard: name='%s', age=%d", msg->name.c_str(), msg->age);
    }
    rclcpp::Subscription<test_moudle::msg::MyMessage>::SharedPtr subscription_;
};

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

修改cmakelists.txt

find_package(test_moudle REQUIRED)



add_executable(talker src/talker.cpp)
ament_target_dependencies(talker rclcpp std_msgs test_moudle)

add_executable(listener src/listener.cpp)
ament_target_dependencies(listener rclcpp std_msgs test_moudle)

install(TARGETS
  talker listener
  DESTINATION lib/${PROJECT_NAME})

编译msg要跟编译node区分开,要不find就出问题 编译不过,试了几种方法不行

6、测试

7、还有个问题

如果不生成py的msg 执行 echo会崩???

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值