传送门:
机器人操作系统ROS:从入门到放弃(一) 发布接收消息 - 简书
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
/**
* This tutorial demonstrates simple sending of messages over the ROS system.
*/
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 = 0;
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<sstream>
,sstream是c++自带的头文件,可以实现利用输入输出流的方式往string里写东西,并且还可以拼接string和其他类型的变量.代码中的
std::stringstream ss;
ss<<"hello world"<<count;
实现了string hello world
和int变量 count
的拼接,形成一个新的string.即如果count是1,那么helloworld1
会作为string被存放在ss当中.怎么调用这个string呢? ss.str()
就可以了.
4: ros::init(argc, argv, "talker")
,从名字很好理解,在程序初始化ros,这行代码也是你几乎所有节点都需要的.talker
就是node(节点)的名字.即你这段程序在ROS当中的名字叫talker
.
5: ros::NodeHandle n
,官方的解释是nodeHandle是和ROS系统通讯的重要工具。咱们可以暂时这么记着两个东西,4,5都是在程序中初始化ROS节点所必须的。
另外有一点需要提醒的是命名问题,有些刚入门的孩子不敢大胆的命名,比如节点名字talker
,NodeHandle
的对象名n
,其实你可以取任何名字,只要你觉得这个名字方便以后读懂程序。节点名一般要显示这个节点的作用。NodeHandle
的对象名按照习惯一般取为n,nh
什么的。其实个人不太建议对象名为n
,这样的单个字母很容易不经意间和某个变量或者其他什么重复了。
6:ros::Publisher
这一行定义你要publish的信息和信息的名字了。n.advertise
通过NodeHandle的对象n告诉ROS系统我要创建一个可以发布信息的对象了。这个信息是什么类型的呢?<std_msgs::String>
告诉ROS我要发布的是标准信息中的String类型。那些信息叫啥名字呢?名字叫chatter
。这个chatter
就是我们之前提到的topic
!(topic名和节点名不要搞混,topic名字代表的是你要发布的信息,节点的名字代表你这个程序)。
1000
这个数字的意思是要缓冲的信息数量。为什么需要缓冲呢?我们说这是个发布信息的程序,我们还需要写一个接收信息的程序。这发布和接收之间并不是瞬间进行的。我记得刚学ROS的时候老师让我们测试过发布消息和接收到消息之间的时间差。既然有时间差,打个比方1ms接收一条信息,如果我的信息产生地很快,是0.1ms发布一条信息,那么接收方反应不过来了。这时候咋办?ROS会把发布的信息都写进缓冲区,先存个1000条,然后接收的程序慢慢从缓冲区里读,只要信息不超过1000条,总归是可以慢慢读完的。那么超过1000条了呢?最早的信息就直接丢掉了。缓冲区接收最新的信息放到信息序列的最后。即缓冲区的信息的数据结构是queue
。第一条来的信息在序列满了的情况下会被第一个丢弃。