一、前言
在进行ROS开发过程中,有时候遇到一种情况:在功能包A_pkg 中需要用到 功能包B_pkg 中自定义的消息(message)或者服务(service)的类型。
如果仅仅在B_pkg中编程用到这些的自定义类型,就是常见的ROS自定义数据类型的实现流程,可以参考如下的模板进行:
自定义消息类型->> ros发布和订阅msg,自定义msg_ros自定义消息msg-CSDN博客
自定义服务类型->> ros---服务端和客户端-CSDN博客
如果在A_pkg中用到这样的自定义数据类型,则需要在A_pkg中进行如下配置。
二、具体实现步骤
首先 在功能包A_pkg中的 package.xml 文件中添加如下语句:
<build_depend>B_pkg</build_depend>
<run_depend>B_pkg</run_depend>
这一步的目的是在A_pkg中加载功能包B_pkg,这样就可以顺利引用到B_pkg中的相关头文件。
其次 在功能包A_pkg中的 CMakeLists.txt 文件中,找到 find_package() 所在位置并添加功能包名称:
find_package(
B_pkg
)
三、A_pkg的例程中使用B_pkg的这个数据类型
假设在功能包B_pkg中自定义了一个 消息数据类型 MyData , 如果在A_pkg中要写一个订阅例程,那么在 .cpp 文件中的调用方法如下:
#include <ros/ros.h>
#include <iostream>
#include "B_pkg/MyData.h" //数据类型定义所在的头文件
void subCallBack(const B_pkg::MyData::ConstPtr &msg) //数据类型的指针
{
//
//
}
int main(int argc ,char **argv){
ros::init(argc,argv,"demo01");
std::string topic_name = "data_topic";
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe(topic_name,10,&subCallBack);
ros::spin();
return 0;
}
此外,值得注意的是(与本文其实关联不大),在类中实现相关的订阅函数时,句柄类ros::NodeHandle中的 subscribe 成员在初始化的时候与上面的 .cpp 文件中实现过程有点区别,即 需要在后面多增加 this 指针 :
#include <ros/ros.h>
#include <iostream>
#include "B_pkg/MyData.h" //数据类型定义所在的头文件
class MyThread
{
public:
MyThread(int argc, char **argv);
~MyThread();
void subscribeNode();
private:
int init_argc; //ros初始化用到的环境参数
char** init_argv;
};
MyThread::MyThread(int argc, char **argv) :
init_argc(argc),
init_argv(argv)
{}
void MyThread::subscribeNode()
{
ros::init(init_argc,init_argv,"demo01");
std::string topic_name = "data_topic";
ros::NodeHandle nh;
// 首先,回调函数要加所在的类名作用域
// 其次,后面还要增加一个指针参数 this,表明这个回调函数用的是当前类对象的
ros::Subscriber sub = nh.subscribe(topic_name,10,&MyThread::subCallBack,this);
ros::spin();
}