3.4 头文件引用
3.4.1 引用当前包头文件
在编写代码时我们经常会需要引用头文件,引用公用的头文件很容易,因为它们已经在标准库头文件路径中。但是如果要引用自定义的头文件就稍微麻烦点,我们首先查看软件包的目录结构,需要在正确的目录下创建头文件并修改CMakeLists.txt文件这样才能正确编译,下面来举例说明:
为了方便说明我们来创建一个头文件。
在路径:~/ros_workspace/src/test_pkg/include/test_pkg下创建test_pkg.h
打开终端输入以下命令进入要创建头文件的目录:
$ cd ~/ros_workspace/src/test_pkg/include/test_pkg
输入以下命令创建头文件:
$ touch test_pkg.h
输入以下命令打开创建的头文件:
$ gedit test_pkg.h
输入以下代码:
#ifndef _TEST_PKG_
#define _TEST_PKG_
#define TEST_PKG_VER "1.0.0"
#define INIT_COUNT 100
int addTwoNum(int a,int b);
#endif
完成后保存关闭头文件,修改test.cpp,如下代码:
#include "ros/ros.h"
#include "std_msgs/String.h"
#include "test_pkg/test_pkg.h" //自定义头文件
#include <sstream>
int addTwoNum(int a,int b)
{
return a+b;
}//头文件函数实现部分
int main(int argc, char *argv[])
{
ros::init(argc, argv, "talker");//这个名字是给系统看的
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise <std_msgs::String >("chatter", 1000);
ros::Rate loop_rate(10);
int count = INIT_COUNT;//调用了头文件中的宏定义
ROS_INFO("test_pkg version:%s",TEST_PKG_VER);
while (ros::ok())
{
std_msgs::String msg;
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();
ROS_INFO("%s", msg.data.c_str());chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
++count;
}
return 0;
}
此处修改是添加了一个头文件的包含路径:include。当然,此处的include是一个相对路径,指的是当前功能包test_pkg下的include。这样编译器在编译源码的时候会到include文件下查找我们自定义的头文件test_pkg/test_pkg.h。
到此我们就完成如何在当前包下引用自定义头文件的代码修改以及配置修改。现在我们需要对源码重新编译。
$ cd ~/ros_workspace
$ catkin_make
编译完成之后运行:
$ roscore
$ rosrun test_pkg test_pkg_node
3.4.2 引用同一工作空间内其他软件包的头文件
在一些情况我们需要引用其他软件包中提供的函数或宏定义,这样可以一定程度上减少我们在两个节点之间需要进行通信的话题个数,下面我们通过举例来进行说明。为了方便说明我们需要在之前创建的工作空间中创建一个新的packge并命名为my_pkg。
如何通过catkin_create_pkg命令来创建功能包前面已经讲过,这里要注意的是我们创建my_pkg的目的是要引用test_pkg中的自定义头文件,因此这里创建my_pkg的时候要对test_pkg进行依赖。
在路径my_pkg/src路径下创建源码文件my_pkg.cpp。写入如下代码:
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
#include "test_pkg/test_pkg.h" **//****自定义头文件**
int main(int argc, char *argv[])
{
ros::init(argc, argv, "my_pkg");
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("my_chatter", 1000);
ros::Rate loop_rate(10);
int count = INIT_COUNT;**//****调用了头文件中的宏定义**
ROS_INFO("test_pkg version:%s,init count:%d",TEST_PKG_VER,INIT_COUNT);/**/****将其他软件包头文件中声明的宏定义打印出来**
while (ros::ok())
{
std_msgs::String msg;
std::stringstream ss;
ss << "my_pkg " << count;
msg.data = ss.str();
ROS_INFO("%s", msg.data.c_str());
chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
++count;
}
return 0;
}
完成源码编写之后首先我们来修改my_pkg的CMakeLists.txt文件。如下图3.8所示,在my_pkg的CMakeLists.txt指定了要编译的源码。
其次来修改test_pkg的CMakeLists.txt文件,如下图3.9所示。做如下修改的主要目的是通知其他软件包当前软件包含有自定义头文件,在include目录下。这样其他包在引用头文件的时候就可以到这个地方查找
对工作空间进行编译:
$ cd ~/ros_workspace/
$ catkin_make
编译完成之后可以运行节点查看结果。
$ roscore
$ rosrun my_pkg my_pkg_node
3.4.3如何在ros中添加新的依赖
**方法一:**在ROS中添加新的依赖可以通过以下步骤进行:
-
下载依赖包:首先,您需要下载所需的依赖包。您可以在ROS官方仓库(http://wiki.ros.org/)或其他第三方源中找到所需的包。
-
将依赖包放置在合适的位置:一般情况下,您可以将依赖包放置在ROS工作空间的src目录下。如果您还没有创建工作空间,可以使用以下命令创建:
mkdir -p catkin_ws/src cd catkin_ws/src
将下载的依赖包放置在src目录中。
-
更新依赖关系:在catkin工作空间的根目录,运行以下命令来更新依赖关系:
cd .. catkin_make
这将会更新工作空间的依赖关系,并编译构建您的工作空间。
-
编译工作空间:运行以下命令来编译您的工作空间:
catkin_make
这将会编译您的工作空间,并将新添加的依赖包包括进去。
-
源文件包含:在您的ROS程序中,您需要添加新依赖包的头文件引用。在需要使用新依赖包的源文件中,添加以下语句:
#include <新依赖包名称/头文件名.h>
这样,您就可以在程序中使用新的依赖包了。
**方法二:**链接同一个工作空间的其他包的头文件。正确调用其他package头文件的方法如下:
1.在A_package包的package.xml中添加编译和运行的依赖库,如下:
<build_depend>B_package</build_depend> <run_depend>B_package</run_depend>12
2.在A_package包的CMakeList.txt中的find_package添加B_package如下:
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs B_package )1
主要添加”B_package”,其他已有的package项不用添加
3.在A_package包的CMakeList.txt中的include_directories添加${catkin_INCLUDE_DIRS}如下:
include_directories(include ${catkin_INCLUDE_DIRS})1
部分工程已经有该项,不用重复添加
4.此时在调用该头文件则不会出错
#include <B_package/testB.h>
以上两种方法就可以引用其他的包的头文件。