话题通信自定义msg调用c++

在 ROS 通信协议中,数据载体是一个较为重要组成部分,ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty.... 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,比如: 激光雷达的信息... std_msgs 由于描述性较差而显得力不从心,这种场景下可以使用自定义的消息类型

msgs只是简单的文本文件,每行具有字段类型和字段名称,可以使用的字段类型有:

  • int8, int16, int32, int64 (或者无符号类型: uint*)

  • float32, float64

  • string

  • time, duration

  • other msg files

  • variable-length array[] and fixed-length array[C]

ROS中还有一种特殊类型:Header,标头包含时间戳和ROS中常用的坐标帧信息。会经常看到msg文件的第一行具有Header标头

准备工作

1.定义msg文件

功能包下新建 msg 目录,添加文件 Person.msg

自定义消息类型

string name
uint16 age
float64 height

2.编辑配置文件

package.xml中添加编译依赖与执行依赖

  <build_depend>message_generation</build_depend>//功能包编译时的相关包
  <exec_depend>message_runtime</exec_depend>//编译的同时进行声明
  <!-- 
  exce_depend 以前对应的是 run_depend 现在非法
  -->

 CMakeLists.txt编辑 msg 相关配置

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation//编译我们的功能包需要message_generation
)
# 需要加入 message_generation,必须有 std_msgs

添加我们自己的message文件

## 配置 msg 源文件
add_message_files(
  FILES
  Person.msg
)
# 生成消息时依赖于 std_msgs
generate_messages(
  DEPENDENCIES
  std_msgs
)

如果自定义功能包,必须依赖于find_package这些包 find_package这些功能包又必须依赖于catkin_package 这些功能包

#执行时依赖
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES demo02_talker_listener
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)

 3.编译

编译后的中间文件查看:

C++ 需要调用的中间文件(.../工作空间/devel/include/包名/xxx.h)

实现过程

0.vscode 配置

为了方便代码提示以及避免误抛异常,需要先配置 vscode,将前面生成的 head 文件路径配置进 c_cpp_properties.json 的 includepath属性:

注:定位到工作空间下/devel/include打开终端 输入pwd 获取head文件路径

1.发布方

/*
    需求: 循环发布人的信息

*/

#include "ros/ros.h"
#include "demo02_talker_listener/Person.h"

int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");

    //1.初始化 ROS 节点
    ros::init(argc,argv,"talker_person");

    //2.创建 ROS 句柄
    ros::NodeHandle nh;

    //3.创建发布者对象
    ros::Publisher pub = nh.advertise<demo02_talker_listener::Person>("chatter_person",1000);

    //4.组织被发布的消息,编写发布逻辑并发布消息
    demo02_talker_listener::Person p;
    p.name = "sunwukong";
    p.age = 2000;
    p.height = 1.45;

    ros::Rate r(1);
    while (ros::ok())
    {
        pub.publish(p);
        p.age += 1;
        ROS_INFO("我叫:%s,今年%d岁,高%.2f米", p.name.c_str(), p.age, p.height);

        r.sleep();
        ros::spinOnce();
    }



    return 0;
}

2.订阅方

/*
    需求: 订阅人的信息

*/

#include "ros/ros.h"
#include "demo02_talker_listener/Person.h"

void doPerson(const demo02_talker_listener::Person::ConstPtr& person_p){
    ROS_INFO("订阅的人信息:%s, %d, %.2f", person_p->name.c_str(), person_p->age, person_p->height);
}

int main(int argc, char *argv[])
{   
    setlocale(LC_ALL,"");

    //1.初始化 ROS 节点
    ros::init(argc,argv,"listener_person");
    //2.创建 ROS 句柄
    ros::NodeHandle nh;
    //3.创建订阅对象
    ros::Subscriber sub = nh.subscribe<demo02_talker_listener::Person>("chatter_person",10,doPerson);

    //4.回调函数中处理 person

    //5.ros::spin();
    ros::spin();    
    return 0;
}

3.配置 CMakeLists.txt

需要添加 add_dependencies 用以设置所依赖的消息相关的中间文件。

add_executable(节点名称1 src/person_talker.cpp)
add_executable(节点名称2 src/person_listener.cpp)



add_dependencies(节点名称1 ${PROJECT_NAME}_generate_messages_cpp)
add_dependencies(节点名称2 ${PROJECT_NAME}_generate_messages_cpp)


target_link_libraries(节点名称1
  ${catkin_LIBRARIES}
)
target_link_libraries(节点名称2
  ${catkin_LIBRARIES}
)

4.执行

1.启动 roscore;

2.启动发布节点;

3.启动订阅节点。

5.rqt_graph查看节点关系

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值