ROS创建发布者和订阅者C++

ROS创建发布者和订阅者C++

环境:
ubuntu18.04 虚拟机 ROS Melodic
ROS Kinetic 与 Melodic 这些API一致

基本概念:
话题(topic)也可译为“主题”
发布者在一个话题上发布消息
订阅者订阅一个话题并取出里面的消息
话题是一个字符串形式的名字,消息是一种数据结构里面填充了特定的内容

C++
(1)发布者:
cpp文件(文件名study_pub.cpp):

#include "ros/ros.h" //该头文件必须包含
#include "std_msgs/String.h" //ros标准消息里面的字符串消息

#include 

/**
 * 在一个话题上发布一个简单的字符串消息
 */
int main(int argc, char *argv[])
{
     
	/**
	 * ros::init()初始化节点函数需要使用argc和argv,不能缺少这两个参数,与话题重映射等有关的
	 */
	ros::init(argc, argv, "study"); //节点名为study,随便取
	
	/**
	 *NodeHandle是与ROS系统通信的主要访问点(句柄),有了它节点就可以“说话了”(在话题上发布消息)
	 * 构造的第一个NodeHandle将完全初始化该节点,最后一个被析构的NodeHandle将关闭该节点。
	 */
	ros::NodeHandle n;

	/**
	 * advertise()函数是你告诉ROS你想在给定的话题名上发布特定类型的消息。
	 * 在这个advertise()调用之后,master节点将通知任何试图订阅这个话题名称的节点,然后他们将与这个节点建立一个对等网络(peer to peer/P2P)连接。
	 * advertise()括号里面的第一个参数是话题名字,第二个参数是用于发布消息的消息队列的大小。
	 * <>里面指定消息的类型
	 */
	ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
	
	/**
	 * 循环频率10Hz
	 */
	ros::Rate loop_rate(10);

	int count = 0;
	while (ros::ok())
	{
     
		/**
		 * 先创建一个消息对象。然后用数据填充它,最后发布它。
		 * 要查看消息结构在命令行使用rosmsg show std_msgs/String,其它消息类似
		 */
		std_msgs::String msg;

		std::stringstream ss;
		ss << "hello world " << count;
		msg.data = ss.str();

		/**
		 * 在终端打印字符串的内容,消息在ROS里面封装成类,类公有函数这些请去wiki上看API文档
		 */
		ROS_INFO("%s", msg.data.c_str());

		/**
		 * publish()函数是发送消息的函数,参数是消息对象。
		 * 消息类型要与n.advertise<>里面声明的一致。
		 */
		chatter_pub.publish(msg);

		ros::spinOnce();//触发回调函数的,不订阅消息的话可删

		loop_rate.sleep();//以10Hz循环,循环跑太快就在这里睡一会儿
		++count;
	}

	return 0;
}

CMakeList.txt文件:
添加如下:
ROS创建发布者和订阅者C++_第1张图片
ROS创建发布者和订阅者C++_第2张图片
需要注意,这里的study_pub是编译后生成的可执行文件名,就是我们rosrun要执行的那个,例:rosrun my1 study_pub (my1 我的包名)

package.xml文件:
添加如下内容:

ROS创建发布者和订阅者C++_第3张图片
编译后即可执行

(2)订阅者:
cpp文件(文件名study_sub.cpp)

#include "ros/ros.h"
#include "std_msgs/String.h"

/**
 * 回调函数,接收到消息后进入该函数
 * 函数参数使用对应消息的静态指针引用,表示订阅者不能修改发布者发布的消息(只读)
 * 只能用->访问消息类成员
 */
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
     
	ROS_INFO("I heard: [%s]", msg->data.c_str());
}

int main(int argc, char *argv[])
{
     
	ros::init(argc, argv, "study");

	ros::NodeHandle n;

	/**
	 * 调用subscribe()告诉ROS你想订阅关于给定话题的消息的方式
	 * 第一个参数为话题名, 第二个参数为消息缓存队列的大小, 第三参数为回调函数的函数名
	 */
	ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

	/**
	 * ros::spin()将进入一个循环,等待话题上消息的传入并在接收到消息后调用回调函数。
	 * 这是一个死循环
	 */
	ros::spin();

	//如果不想使用ros::spin()可以使用ros::spinOnce()
	//ros::Rate loop_rate(10);
	//while(n.ok())
	//{
     
	//	ros::spinOnce()//调用一次回调函数,并继续往下走
		//你想完成的其它工作
	//	loop_rate.sleep();
	//}

	return 0;
}

CMakeList.txt文件:
ROS创建发布者和订阅者C++_第4张图片
CmakeList.txt和package.xml文件其它内容与发布者一样。

你可能感兴趣的:(ROS学习,c++,linux)