当前位置:网站首页>ROS自定义消息发布订阅示例
ROS自定义消息发布订阅示例
2022-07-06 11:06:00 【Adunn】
ROS自定义消息发布订阅示例
本文主要从以下几个方面进行说明:
- 1. 创建自定义msg消息
- 2. 发布msg - 其他包调用自定义msg类型
- 3. 订阅自定义msg
1. 创建自定义msg消息
首先创建一个空的package单独存放msg类型(当然也可以在任意的package中自定义msg类型)
这里为便于说明,建立一个名为 wts_rviz_msgs 的包,用于对自定义msg类型的用法举例。
$ cd catkin_ws/src //这里只是举例,实际为工程根目录(src、devel同级目录下)
$ catkin_create_pkg wts_rviz_msgs
1.1. 新建msg文件
在 wts_rviz_msgs 中创建msg文件夹,在msg文件夹其中新建如下消息类型文件:
- PointInfo.msg
- ParkingSpot.msg
- ParkingSpotList.msg
$ cd wts_rviz_msgs
$ mkdir msg
基本类型可参考:
- common_msgs – http://wiki.ros.org/common_msgs
- std_msgs – http://wiki.ros.org/std_msgs
PointInfo.msg内容:
float32 dPointX
float32 dPointY
ParkingSpot.msg内容:
string parking_spot_name
bool publish_state
geometry_msgs/Pose2D pose
PointInfo[] point_list
ParkingSpotList.msg内容:
ParkingSpot[] parking_spot_list
1.2. 修改package.xml
需要message_generation生成C++或Python能使用的代码,需要message_runtime提供运行时的支持,所以package.xml中添加以下两句
ROS1中:
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
ROS2中:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
1.3. 修改CMakeLists.txt
CMakeLists.txt要注意四个地方
(1) 设置find_package
首先调用 find_package 查找依赖的包,必备的有roscpp rospy message_generation,其他根据具体类型添加,比如上面的msg文件中用到了geometry_msgs/Pose pose类型,那么必须查找geometry_msgs
find_package(catkin REQUIRED COMPONENTS roscpp rospy message_generation std_msgs geometry_msgs)
(2) 设置add_message_files
然后是 add_message_files ,指定msg文件
add_message_files(
FILES
PointInfo.msg
ParkingSpot.msg
ParkingSpotList.msg
)
(3) 设置generate_messages
然后是 generate_messages ,指定生成消息文件时的依赖项,比如上面嵌套了其他消息类型geometry_msgs,那么必须注明
#generate_messages必须在catkin_package前面
generate_messages(
DEPENDENCIES
std_msgs
geometry_msgs
)
(4) 设置catkin_package
然后是 catkin_package 设置运行依赖
catkin_package(
CATKIN_DEPENDS message_runtime
)
(5) 编译
$ cd catkin_ws //这里只是举例,实际为工程根目录(src、devel同级目录下)
$ catkin_make -j4
(6) 查看rosmsg
到这里新的msg类型 wts_rviz_msgs/ParkingSpotList 就可以使用了,下面编译这个包,然后利用rosmsg show指令查看。
$ cd 工程根目录 //与devel同级目录
$ source devel/setup.bash #注意:必须执行source 进行安装,否则不识别该消息
$ rosmsg show wts_rviz_msgs/ParkingSpotList
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KPYytd15-1656918643941)(vx_images/396065792889745.png)]](/img/d4/fddc87647af4cb5a5a0769d7eb943b.png)
2. 发布msg - 其他包调用自定义msg类型
要使用自定义的消息类型必须source自定义消息所在的工作空间, 否则rosmsg show wts_rviz_msgs/ParkingSpotList t和rostopic echo /wts_topic_rviz_msgs(/wts_rviz_msgs 是节点中使用自定义消息类型 wts_rviz_msgs/ParkingSpotList 的topic)都会报错,因为没有source的情况下自定义消息类型是不可见的,被认为是未定义类型
一种典型的错误是删掉工作空间下的devel和build文件夹之后重新编译代码,此时由于没有source自定义消息所在的工作空间,即使使用自定义消息的代码和自定义消息在同一个包也无法找到,该消息头文件,此时需要运行source devel/setup.bash之后重新编译就好。
如果是在test_msgs包内的节点中调用test_msgs/Test类型,只需要在.cpp文件中如下调用即可
#include "wts_rviz_msgs/ParkingSpotList.h"
wts_rviz_msgs::ParkingSpotList msg_parking_spot_list_published;
如果是在其他包调用 wts_rviz_msgs/ParkingSpotList 类型则需要修改package.xml和CMakeLists.txt,比如同样在工作空间catkin_ws内有一个名为 interactive_parking_spot 的包,我们可以在这个包内写一个节点,使用我们刚才自定义的消息类型 wts_rviz_msgs/ParkingSpotList ,如下:
**(1)修改package.xml **
养成好习惯,维护软件包清单的更新,以便于别人使用你的软件前安装各种依赖项,当然这个文件不影响程序编译
ROS1中:
<build_depend>roscpp</build_depend>
<run_depend>roscpp</run_depend>
<build_depend>wts_rviz_msgs</build_depend>
<run_depend>wts_rviz_msgs</run_depend>
ROS2中:
<build_depend>roscpp</build_depend>
<run_depend>roscpp</run_depend>
<build_depend>wts_rviz_msgs</build_depend>
<exec_depend>wts_rviz_msgs</exec_depend>
**(2)修改CMakeLists.txt **
调用自定义消息类型主要修改两个地方,以下是重点:
一是find_package中需要声明查找包含该消息类型的包;
二是add_dependencies要注明该消息的依赖,其他地方和普通节点一样
#:注意,由于本例中使用了 geometry_msgs/Pose2D 类型,编译版本需要 大于 C++11
add_compile_options(-std=c++17)
find_package(catkin REQUIRED COMPONENTS
roscpp
geometry_msgs
wts_rviz_msgs
)
add_executable(interactive_parking_spot src/main.cpp)
target_link_libraries(interactive_parking_spot
${catkin_LIBRARIES}
)
#调用同一工作空间的自定义消息类型时注明依赖关系,防止发生头文件找不到的报错
add_dependencies(interactive_parking_spot wts_rviz_msgs_gencpp)
如果缺少add_dependencies中对 wts_rviz_msgs_gencpp 的依赖声明,在编译的时候如果先编译 interactive_parking_spot 包再编译 wts_rviz_msgs/ParkingSpotList 包则会出现如下报错(ROS工作空间各个软件包的编译顺序是随机的),因为头文件wts_rviz_msgs/ParkingSpotList.h 还未生成
fatal error: wts_rviz_msgs/ParkingSpotList.h: 没有那个文件或目录
#include “wts_rviz_msgs/ParkingSpotList.h”
2.1. 编写消息发布代码: src/main.cpp
#include "wts_rviz_msgs/ParkingSpotList.h"
int main(int argc, char** argv)
{
ros::init(argc, argv, "simple_marker");
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<wts_rviz_msgs::ParkingSpotList>("wts_topic_msg_parking_spots_info", 1000);
ros::Rate loop_rate(1);
while(ros::ok())
{
int iNum = parkingSpot.m_mapParkingSpot.size();
wts_rviz_msgs::ParkingSpotList msg_parking_spot_list_published;
std::map<std::string, WtsRvizParkingSpot>::iterator iter;
int iIndex = 0;
for(iter = parkingSpot.m_mapParkingSpot.begin(); iter!=parkingSpot.m_mapParkingSpot.end(); iter++)
{
wts_rviz_msgs::ParkingSpot parking_spot;
parking_spot.parking_spot_name = "ParkingSpotName";
parking_spot.publish_state = true
parking_spot.pose.x = 2.0082790851593018;
parking_spot.pose.x = 0;
parking_spot.pose.theta = 0.7217559218406677;
for(int iIndex = 0; iIndex < iter->second.vctrParkingSpotPoints.size(); iIndex++)
{
wts_rviz_msgs::PointInfo point_info;
point_info.dPointX = -1.6596179008483887;
point_info.dPointY = 2.2936594486236572;
parking_spot.point_list.push_back(point_info);
}
msg_parking_spot_list_published.parking_spot_list.push_back(parking_spot);
iIndex++;
}
chatter_pub.publish(msg_parking_spot_list_published);
ros::spinOnce();
loop_rate.sleep();
}
}
3. 订阅自定义msg
新建接受消息节点mylisten.cpp,添加以下代码:bash
#include <ros/ros.h>
#include <geometry_msgs/Pose2D.h>
#include "wts_rviz_msgs/ParkingSpotList.h"
void msgCallback(const wts_rviz_msgs::ParkingSpotList::ConstPtr &P)
{
ROS_INFO("I recevied the topic: ");
for(std::vector<wts_rviz_msgs::ParkingSpotList>::const_iterator it = P->path.begin(); it != P->path.end(); ++it)
{
//... ...
}
}
int main(int argc,char ** argv)
{
ros::init(argc,argv,"test1");
ros::NodeHandle n;
ros::Subscriber msg_sub = n.subscribe("wts_topic_msg_parking_spots_info", 100, msgCallback);
ros::spin();
return 0;
}
仿照前面发布msg的示例,修改CMakeLists.txt、package.xml,而后catkin_make从新编译,就OK了。
边栏推荐
- Binary search tree
- Stm32+mfrc522 completes IC card number reading, password modification, data reading and writing
- Using block to realize the traditional values between two pages
- 应用使用Druid连接池经常性断链问题分析
- About NPM install error 1
- 十、进程管理
- Epoll () whether it involves wait queue analysis
- 【中山大学】考研初试复试资料分享
- Crawling data encounters single point login problem
- 美庐生物IPO被终止:年营收3.85亿 陈林为实控人
猜你喜欢

Jushan database was among the first batch of financial information innovation solutions!
三年Android开发,2022疫情期间八家大厂的Android面试经历和真题整理

Binary search tree

Implementation of AVL tree

十、进程管理

Online notes

Wx applet learning notes day01

Execution process of MySQL query request - underlying principle

C#/VB.NET 给PDF文档添加文本/图像水印

Human bone point detection: top-down (part of the theory)
随机推荐
[Sun Yat sen University] information sharing of postgraduate entrance examination and re examination
关于npm install 报错问题 error 1
上海部分招工市场对新冠阳性康复者拒绝招录
First, look at K, an ugly number
Human bone point detection: top-down (part of the theory)
AUTOCAD——中心线绘制、CAD默认线宽是多少?可以修改吗?
44所高校入选!分布式智能计算项目名单公示
应用使用Druid连接池经常性断链问题分析
Crawling data encounters single point login problem
一种用于夜间和无袖测量血压手臂可穿戴设备【翻译】
There is a sound prompt when inserting a USB flash disk under win10 system, but the drive letter is not displayed
Certains marchés de l'emploi de Shanghai refusent d'embaucher des personnes qui se rétablissent positives à Xinguan
Cobra quick start - designed for command line programs
2022.2.12
10、 Process management
深度循环网络长期血压预测【翻译】
POJ 2208 six lengths of tetrahedron are known, and the volume is calculated
Docker安装Redis
Oracle advanced (IV) table connection explanation
【论文笔记】TransUNet: Transformers Make StrongEncoders for Medical Image Segmentation