[学习笔记]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,编译,环境变量,运行,结果如下:
(完)