ROS学习之编写简单的消息发布器和订阅器 (C++ catkin)

1首先是catkin工作空间中ROS package包的文件形式

创建一个包,添加依赖

zhangxuhnr@zhangxuhnr-Lenovo-IdeaPad-S415-Touch:~/catkin_ws/src$ catkin_create_pkg talker_listener std_msgs rospy roscpp
Created file talker_listener/package.xml
Created file talker_listener/CMakeLists.txt
Created folder talker_listener/include/talker_listener
Created folder talker_listener/src
Successfully created files in /home/zhangxuhnr/catkin_ws/src/talker_listener. Please adjust the values in package.xml.

这样包内自动多了package.xml ,CMakeLists.txt, include和src文件夹

然后是更新package.xml

package.xml主要包括包的名称,标签(添加对包的描述),维护者和邮箱,许可协议(一些常见的开源许可协议有BSD、MIT、Boost Software License、GPLv2、GPLv3、LGPLv2.1和LGPLv3,一般是BSD协议),依赖项(

build_depend
buildtool_depend
run_depend
test_depend(这个没见过)

将一些注释的东西删掉,最后变得简洁
 

<?xml version="1.0"?>
<package format="2">
  <name>talker_listener</name>
  <version>0.0.0</version>
  <description>The talker_listener package</description>

  <maintainer email="[email protected]">zhangxuhnr</maintainer>

  <license>BSD</license>


  <buildtool_depend>catkin</buildtool_depend>

  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>

  <run_depend>roscpp</run_depend>
  <run_depend>rospy</run_depend>
  <run_depend>std_msgs</run_depend>


</package>

http://wiki.ros.org/catkin/CMakeLists.txt中有详细描述

CMakeLists.txt 包括以下内容

  1. 必需的CMake版本cmake_minimum_required

  2. 包名称project()

  3. 查找构建所需的其他CMake / Catkin包find_package()

  4. 启用Python模块支持catkin_python_setup()

  5. 消息/服务/动作生成器add_message_files(),add_service_files(),add_action_files()

  6. 调用消息/服务/动作生成generate_messages()

  7. 指定包构建信息导出catkin_package()

  8. 要构建的库/可执行文件add_library()/ add_executable()/ target_link_libraries()

  9. 测试构建catkin_add_gtest()

  10. 安装规则install()



find_package()

catkin总是至少有一个依赖:
catkin REQUIRED
如果项目依赖于其他包,它们会自动变成catkin的组件

COMPONENTS
  roscpp
  rospy

  std_msgs

catkin_package()

使用add_library()add_executable()声明任何目标之前,必须调用此函数

  • INCLUDE_DIRS - 包的导出包含路径(即cflags)

  • LIBRARIES - 项目中导出的库

  • CATKIN_DEPENDS - 该项目所依赖的其他catkin项目

  • DEPENDS - 此项目依赖的非catkin CMake项目。

catkin_package(
   INCLUDE_DIRS include
   LIBRARIES ${PROJECT_NAME}
   CATKIN_DEPENDS roscpp nodelet
   DEPENDS eigen opencv)


include_directories的参数应该是find_package调用生成的* _INCLUDE_DIRS变量以及需要包含的任何其他目录

如果您使用catkin和Boost

$ {Boost_INCLUDE_DIRS} $ {catkin_INCLUDE_DIRS}

第一个参数“include”表示包中的include /目录也是路径的一部分

要指定必须构建的可执行目标,我们必须使用add_executable()

add_library() CMake的功能是用来指定库来构建。默认情况下,catkin构建共享库

使用target_link_libraries()函数指定可执行目标链接的库。这通常在add_executable()调用之后完成

target_link_libraries(<executableTargetName>,<lib1>,<lib2>,... <libN>)

CMake工作流程

$ mkdir build
$ cd build
$ cmake ..
$ make
编写talker.cpp,
#include "ros/ros.h"//ros/ros.h引入了ROS系统中大部分常用的头文件
#include "std_msgs/String.h"//引用了std_msgs/Sting消息,它存放在std_msgs packages里,是由String.msg文件自动生成的头文件,定义了一种 string data

#include <sstream>
//C++引入ostringstream、istringstream、stringstream这三个类,要使用他们创建对象就必须包含<sstream>这个头文件。

/**
 *此程序用ROS发送消息
 */
int main(int argc,char *argv[])
{
	ros::init(argc,argv,"talker");//初始化ROS,指定节点名称
	ros::NodeHandle n;//为这个进程的节点创建一个句柄,第一个创建的NodeHandle会为节点进行初始化,最后一个销毁的会清理节点使用的所有资源
	ros::Publisher chatter_pub=n.advertise<std_msgs::String>("chatter",1000);//告诉master我们将要在chatter topic上发布一个std_msgs/String的消息,1000是发布序列大小,缓冲区中的消息在大于1000个的时候就会丢弃之前的消息
//NodeHandle.advertise()返回一个ros::publish对象,有一个publish()成员函数让你在topic上发布消息,如果消息类型不对拒绝发布
	ros::Rate loop_rate(10);//ros::Rate对象允许指定自循环的频率,记录上一次调用Rate::sleep()后的时间,并休眠到下一个频率周期时间
	int count=0;
	while(ros::ok())//ros::ok()安装一个SIGINT句柄,在按键ctrl+c,返回False
	{
		std_msgs::String msg;//使用一个由msg文件产生的“消息自适应”类在ROS网络中广播消息
		std::stringstream ss;
		ss<<"hello world"<<count;
		msg.data=ss.str();//String消息只有一个数据data
		ROS_INFO("%s",msg.data.c_str());
		chatter_pub.publish(msg);//向所有连接到chatter topic的节点发送了消息
		ros::spinOnce();//调用回调函数,此程序不接受回调,最好加上
		loop_rate.sleep();//休眠一段时间来使发布频率为10Hz
		++count;
	}
	return 0;
}
编写listener.cpp
#include "ros/ros.h"
#include "std_msgs/String.h"

void chatterCallback(const std_msgs::String::ConstPtr&msg)//const [包名]::[消息文件名][ConstPtr]&
{
	ROS_INFO("I heard: [%s]",msg->data.c_str());
}

int main(int argc,char *argv[])
{
	ros::init(argc,argv,"listener");
	ros::NodeHandle n;
	ros::Subscriber sub=n.subscribe("chatter",1000,chatterCallback);//NodeHandle::subscribe()返回ros::Subscriber对象,你必须让它处于活动状态直到你不再想订阅该消息。
	ros::spin();//ros::spin()进入自循环,可以尽可能快的调用消息回调函数
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_37954144/article/details/80998001
今日推荐