[学习笔记]ROS自定义msg及使用

在话题通讯中,ros提供的数据类型并不足以支持我们的使用,这时就需要自定义一些消息类型了。

首先打开一个工作空间,在包内与第二个src目录同级(即工作空间下级)自己建立一个msg文件夹,里面建立一个.msg文件,在里面自定义消息类型。

需要注意的是,这里的int,float不能用普通的类型,必须用int32(有点像单片机里的格式,或许这就是机器人的共通之处吧)

接下来,需要配置一(亿)些文件。首先是唯一一个package.xml

第55行,63行是增加的内容,55行把54行复制,改下message_generation;

             63行把62行复制,改下message_runtime;

这两个可以分别理解为编译时依赖,运行时依赖。

接下来是CMakeLists.txt

需要修改的地方有点多,一个一个来,这里把修改前后的部分都放出来,上面是原来的样子,后面是修改后的样子。

# find_package(catkin REQUIRED COMPONENTS
#   roscpp
#   rospy
#   std_msgs
# )
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)#依赖的包,需要增加message_generation
# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )
add_message_files(
  FILES
  num.msg
)#将message12给删了,因为我们没有这两个包,然后改成我们自定义的包
# generate_messages(
#   DEPENDENCIES
#   std_msgs
# )
generate_messages(
  DEPENDENCIES
  std_msgs
)#去除注释即可
#  CATKIN_DEPENDS roscpp rospy std_msgs
 CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#去除注释,并且添加message_runtime(这部分在catkin_package中)

之后就可以正常编译/运行了。编译运行后会生成一个头文件,在项目包目录下的devel/include目录中,与自定义的包名字相同

这样之后,就可以让代码正常编译了。

但是,这个情况下是不会有代码不全提示的,需要在.vscode的c_cpp_properties.json中修改一下includePath,增加以上include文件夹的绝对路径。

 

(如上图11行)

接下来就是代码部分了。来看看数组类型该怎么定义:

1、.msg文件

int32[] num

这样定义了一个int类型的数组num,说是数组其实更像一个队列(容器),接下来展示如何使用

2、发布端

#include<bits/stdc++.h>
#include<ros/ros.h>
#include"list/lis.h"//自定义的头文件
using namespace ros;
// numTheoryPub”
//订阅方节点命名:“numTheorySub”
//话题命名为:“numTheory”。
int main(int argc,char *argv[])
{
    init(argc, argv, "numTheoryPub");
    NodeHandle nh;
    Publisher pub = nh.advertise<list::lis>("numTheory", 10);
    Rate rate(1);
    list::lis a;//定义一个容器
    while(ok())
    {
        while(!a.num.empty())
            a.num.pop_back();//来看这一行,这个语法简直和stl一模一样
        for (int i = 1; i <= 4; i++)
        {
            int x;
            scanf("%d", &x);
            a.num.push_back(x);//压栈
        }
        pub.publish(a);//发布
        rate.sleep();
        spinOnce();
    }
    return 0;
}

3、订阅端

#include<bits/stdc++.h>
#include<ros/ros.h>
#include"list/lis.h"
using namespace ros;
const int maxn = 505;
// numTheoryPub”
//订阅方节点命名:“numTheorySub”
//话题命名为:“numTheory”。

void solve(const list::lis::ConstPtr &a)
{
    int tmp[maxn], cnt = 0;
   for (int i = 0; i < 4; i++)
        tmp[i + 1] = a->num.at(i), cnt++;//这里也是stl语法,不能简单地调用数组
   for (int i = 1; i <= 4; i++)
   ROS_INFO("%d", tmp[i]); } int main(int argc,char *argv[]) { ROS_INFO("the result is"); init(argc, argv, "numTheorySub"); NodeHandle nh; Subscriber sub = nh.subscribe("numTheory", 10, solve); spin(); return 0; }

之后roscore,编译,环境变量,运行,结果如下:

 

 (完)

 

posted @ 2022-07-09 16:12  阿基米德的澡盆  阅读(2109)  评论(0编辑  收藏  举报