用C++写一个简单的发布者
节点是一个可执行程序,它连接到了ROS的网络系统中。我们将会创建一个发布者,也就是说话者节点,它将会持续的广播一个信息。
改变目录到之前所建立的那个包下:
cd ~/catkin_ws/src/beginner_tutorials
在beginner_tutorials包下面建立一个src文件夹:这个目录包含于beginner_tutorials包相关的所有的源码文件。
mkdir -p ~/catkin_ws/src/beginner_tutorials/src
创建文件src/talker.cpp:
vim src/talker.cpp
将下面的内容复制进去:
#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)
{
/**
* The ros::init() function needs to see argc and argv so that it can perform
* any ROS arguments and name remapping that were provided at the command line. For programmatic
* remappings you can use a different version of init() which takes remappings
* directly, but for most command-line programs, passing argc and argv is the easiest
* way to do it. The third argument to init() is the name of the node.
*
* You must call one of the versions of ros::init() before using any other
* part of the ROS system.
*/
ros::init(argc, argv, "talker"); /**
* NodeHandle is the main access point to communications with the ROS system.
* The first NodeHandle constructed will fully initialize this node, and the last
* NodeHandle destructed will close down the node.
*/
ros::NodeHandle n; /**
* The advertise() function is how you tell ROS that you want to
* publish on a given topic name. This invokes a call to the ROS
* master node, which keeps a registry of who is publishing and who
* is subscribing. After this advertise() call is made, the master
* node will notify anyone who is trying to subscribe to this topic name,
* and they will in turn negotiate a peer-to-peer connection with this
* node. advertise() returns a Publisher object which allows you to
* publish messages on that topic through a call to publish(). Once
* all copies of the returned Publisher object are destroyed, the topic
* will be automatically unadvertised.
*
* The second parameter to advertise() is the size of the message queue
* used for publishing messages. If messages are published more quickly
* than we can send them, the number here specifies how many messages to
* buffer up before throwing some away.
*/
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", ); ros::Rate loop_rate(); /**
* A count of how many messages we have sent. This is used to create
* a unique string for each message.
*/
int count = ;
while (ros::ok())
{
/**
* This is a message object. You stuff it with data, and then publish it.
*/
std_msgs::String msg; std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str(); ROS_INFO("%s", msg.data.c_str()); /**
* The publish() function is how you send messages. The parameter
* is the message object. The type of this object must agree with the type
* given as a template parameter to the advertise<>() call, as was done
* in the constructor above.
*/
chatter_pub.publish(msg); ros::spinOnce(); loop_rate.sleep();
++count;
} return ;
}
保存退出。
解释一下代码:
#include "ros/ros.h"
ros/ros.h包括了使用ROS系统最基本的头文件。
#include "std_msgs/String.h"
这条代码包括了std_msgs/String消息,它存在于std_msgs包中。这是由std_msgs中的String.msg文件自动产生的。
ros::init(argc, argv, "talker");
初始化ROS,它允许ROS通过命令行重新命名,现在还不太重要。这里也是我们确切说明节点名字的地方,在运行的系统中,节点的名字必须唯一。
ros::NodeHandle n;
为正在处理的节点创建了一个句柄,这个句柄是这个节点和ROS系统通信的主要入口点。第一个创建的节点句柄将会初始化这个节点,最后一个销毁的节点句柄将会释放这个节点所使用的所有资源。
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", );
告诉主机,我们将会在一个名字为chatter的话题上发布一个std_msgs/String类型的消息,这就使得主机告诉了所有订阅了chatter话题的节点,我们将在这个话题上发布数据。第二个参数是发布队列的大小,它的作用是缓冲。如果我们发布信息太快,最后溢出,就会丢掉原来的老消息。
NodeHandle::advertise()将会返回ros::Publisher对象,该对象有两个作用,首先是它包括一个publish()方法可以在制定的话题上发布消息,其次,当超出范围之外的时候就会自动的处理。
ros::Rate loop_rate();
一个ros::Rate对象允许你制定循环的频率。它将会记录从上次调用Rate::sleep()到现在为止的时间,休眠正确的时间。在这个例子中,设置的频率为10hz。
int count = ;
while (ros::ok())
{
默认情况下,roscpp将会安装一个SIGINT监听,它使当Ctrl-C按下时,ros::ok()将会返回false。
ros::ok()在以下几种情况下也会返回false:
(1)按下Ctrl-C时
(2)我们被一个同名同姓的节点从网络中踢出
(3)ros::shutdown()被应用程序的另一部分调用
(4)所有的ros::NodeHandles都被销毁了。
一旦ros::ok()返回false,所有的ROS调用都会失败。
std_msgs::String msg; std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();
这里我们建立了一个输入输出流,然后向流中塞入数据,最后把数据赋值给msg的data字段。
我们可以使用message-adapted类在ROS中广播信息,这个类一般是从msg文件中产生的。但是我们现在使用的是std_msgs命名空间中的标准的String消息,它只有一个data数据成员,当然更复杂的消息也是可以的。
chatter_pub.publish(msg);
现在我们向话题chatter发布消息 。
ROS_INFO("%s", msg.data.c_str());
ROS_INFO是cout/printf的替代品。
ros::spinOnce();
在这个简单的程序中调用ros::spinOnce();是不必要的,因为我们没有收到任何的回调信息。然而如果你为这个应用程序添加一个订阅者,并且在这里没有调用ros::spinOnce(),你的回调函数将不会被调用。所以这是一个良好的风格。
loop_rate.sleep();
休眠一下,使程序满足前面所设置的10hz的要求。
下面总结一下创建一个发布者节点的步骤:(1)初始化ROS系统(2)告诉主机我们将要在chatter话题上发布std_msgs/String类型的消息(3)循环每秒发送10次消息。
用C++写一个简单的发布者的更多相关文章
- 用Python写一个简单的Web框架
一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...
- 如何写一个简单的http服务器
最近几天用C++写了一个简单的HTTP服务器,作为学习网络编程和Linux环境编程的练手项目,这篇文章记录我在写一个HTTP服务器过程中遇到的问题和学习到的知识. 服务器的源代码放在Github. H ...
- 如何写一个简单的shell
如何写一个简单的shell 看完<UNIX环境高级编程>后我就一直想写一个简单的shell来作为练习,因为有事断断续续的写了好几个月,如今写了差不多来总结一下. 源代码放在了Github: ...
- 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
- 一步一步写一个简单通用的makefile(三)
上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...
- Java写一个简单学生管理系统
其实作为一名Java的程序猿,无论你是初学也好,大神也罢,学生管理系统一直都是一个非常好的例子,初学者主要是用数组.List等等来写出一个简易的学生管理系统,二.牛逼一点的大神则用数据库+swing来 ...
- (2)自己写一个简单的servle容器
自己写一个简单的servlet,能够跑一个简单的servlet,说明一下逻辑. 首先是写一个简单的servlet,这就关联到javax.servlet和javax.servlet.http这两个包的类 ...
- express 写一个简单的web app
之前写过一个简单的web app, 能够完成注册登录,展示列表,CURD 但是版本好像旧了,今天想写一个简单的API 供移动端调用 1.下载最新的node https://nodejs.org/zh- ...
- 写一个简单的C词法分析器
写一个简单的C词法分析器 在写本文过程中,我参考了<词法分析器的实现>中的一些内容.这里我们主要讨论写一个C语言的词法分析器. 一.关键字 首先,C语言中关键字有: auto.break. ...
随机推荐
- 图片延迟加载技术-Lazyload的应用
我们在浏览图片量非常大的页面时,像淘宝商城商品展示.必应图片搜索这类网站,图片的加载非常流畅,其中就应用了图片延迟加载技术.本文讲解Lazyload图片加载插件,当我们打开页面时,首先在屏幕可视区域加 ...
- spring框架详解
把之前分享的spring框架整理一份放在这里. 整体架构: Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架 框架图(选自:http://docs.spring.io/spr ...
- iOS根据2个经纬度计算距离
#pragma mark - calculate distance 根据2个经纬度计算距离 #define PI 3.14159265358979323 +(double) CalculationDi ...
- windows如何获取Win10 Win8 Win8.1版本
GetVersionEx 在win8 win8.1 win10 之后已经无法使用,如果非要使用的话需要让exe嵌入manifest,mainfest如下.这个文件需要已utf-8存储. <?xm ...
- BZOJ 1087 互不侵犯king
Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包 ...
- IO库 8.6
题目:重写7.1.1节的书店程序(P229),从一个文件中读取交易记录.将文件名作为一个参数传递给main. #include <iostream> #include <fstrea ...
- Java学习之Java中常用对象
java的几种对象(PO,VO,DAO,BO,POJO)解释 一.PO:persistant object 持久对象,可以看成是与数据库中的表相映射的java对象.最简单的PO就是对应数据库中 ...
- iMac Termanel命令まとめ
1.mac环境下命令的使用ls -l -a 列出指定目录下文件 -l 显示文件的详细信息 -a 显示目录下所有文件(包括隐藏文件) -d ...
- JavaScript中创建命名空间
引用:http://ourjs.com/detail/538d8d024929582e6200000c 在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量也不是按照你想像中的顺 ...
- python模块—optparse
处理命令行参数 1 #-*-coding:utf-8-*- __author__ = 007 __date__ = 16 / 1 / 19 from optparse import OptionPar ...