在初学ROS时,一般都是使用的ROS标准库,包括激光电云laserscan、位姿posestamp等。这些库基本满足了我们的日常使用,但是在开发时,难免会遇到一些情况使用标准库不太合适,这时候使用自己的自定义消息格式就变得非常方便。
首先建立一个名为catkin_ws的文件夹,在文件夹内执行:
mkdir src
cd src
catkin_create_pkg msg_test roscpp rospy
这里的含义是在src文件夹下新建一个catkin工程,工程名称为msg_test,依赖于roscpp以及rospy
然后执行:
cd msg_test
mkdir msg
cd msg
gedit point.msg
这里的含义是在msg_test文件夹下新建一个msg文件夹,并在该文件夹内添加一个point.msg消息。
然后在该文件内添加如下代码:
float64 x
float64 y
float64 z
最后显示如下:
到这里我们的一个自定义消息就建立完成了,但是如果需要让其生效的话需要修改cmakelist文件以及package.xml文件。
首先对于cmakelist文件,需要确定以下几个地方:
一、
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
rospy
message_generation
)
find_package这里需要包含message_generation,初始时应该是只有roscpp以及rospy的,其他依赖需要自己根据需要添加
二、
## Generate messages in the 'msg' folder
add_message_files(
FILES
point.msg
# Message2.msg
)
Generate messages这里需要添加自己的msg消息,代表链接的是哪一个具体的msg,例如这里我需要生成的point.msg所以这里需要添加这一行
point.msg
其他部分不用改动
三、
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
# geometry_msgs
)
generate_messages这里是一定要有的,要不然即使编译成功也不会生成自己的msg
另外对于package.xml文件,需要确认其中这两行代码即可:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
在这些地方都确认无误的情况下,在catkin_ws文件夹下打开终端,使用catkin_make命令编译文件夹。如果没有问题的话会在catkin_ws/devel路径下生成一个include文件夹,其中存储了名为point.h的文件。注意这个文件并不是一开始就有的,而是通过msg文件编译生成的。
这里可以建立一个简单的talker来使用上面定义的msg并进行话题的发布。代码比较简单就直接给出了:
#include "ros/ros.h"
#include "msg_test/point.h"
int main(int argc, char **argv)
{
ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<msg_test::point>("chatter", 1000);
ros::Rate loop_rate(10);
while (ros::ok())
{
msg_test::point point;
point.x=1;
point.y=2;
point.z=3;
chatter_pub.publish(point);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
这个文件写在src文件夹下,我们命名为msg_test.cpp。同样的在catkin_ws下进行编译一下,然后在终端中输入执行该node:
roscore
rosrun msg_test msg_test
注意执行前先把路径添加到bashrc文件夹下,要不然会显示找不到该node,添加方式:
gedit ~/.bashrc
打开bashrc文件,在最后名添加一行:
source ~/catkin_ws/devel/setup.bash
点击保存,关闭该文件,然后执行:
source ~/.bashrc
最后,新开一个终端,监听一下chatter话题,可以看到结果如下:
在定义msg的时候,有时可以定义多个msg,或者在自己的msg中调用其他msg。例如我们可以定义如下的mg消息格式:
string id
msg_test/point[] data
geometry_msgs/Pose pose
这是一个非标准的数据格式,包含了一个自定义的string,一个我们之前定义的消息类型point数组以及一个标准的ROS库函数geometry_msgs/Pose
需要注意如果添加官方标准库的话要在cmakelist文件夹中的:
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
# geometry_msgs
)
这里添加对应的库函数,例如这里需要改为:
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
geometry_msgs
)
要不然编译时会提示找不到geometry_msgs
然后我们可以同样通过一个chatter测试一下msg:
#include "ros/ros.h"
#include "msg_test/points.h"
int main(int argc, char **argv)
{
ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<msg_test::points>("chatter", 1000);
ros::Rate loop_rate(10);
while (ros::ok())
{
msg_test::points points;
points.id="123";
msg_test::point point;
for(int i=0;i<3;i++)
{
point.x=i;
point.y=i+1;
point.z=i+2;
points.data.push_back(point);
}
points.pose.position.x=1;
points.pose.position.y=2;
chatter_pub.publish(points);
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
代码存放在:
https://download.csdn.net/download/YiYeZhiNian/86511347?spm=1001.2014.3001.5501