码迷,mamicode.com
首页 > 编程语言 > 详细

【11】Writing a Simple Publisher and Subscriber (C++)

时间:2016-05-09 20:41:16      阅读:613      评论:0      收藏:0      [点我收藏+]

标签:

Publisher

#include "ros/ros.h"

#include "std_msgs/String.h"

#include <sstream>

int main(int argc, char **argv)

{

  ros::init(argc, argv, "talker");   //1.启动该节点  2.并设置其名称(名称要唯一)

  ros::NodeHandle n;      //设置节点句柄

  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);

        //将节点设置成发布者,并将所发布主题的类型和名称告知节点管理器。

          第一个参数是消息的名称,设置为 message;

          第二个参数是缓冲区的大小。如果主题发布数据速度较快,那么将缓冲区设置为 1000 个消息
  ros::Rate loop_rate(10);    //发送数据的频率10Hz

  while (ros::ok())       //收到Crtl+C消息或者ROS停止运行,ros::ok()库会执行停止节点运行命令

  {

        //创建一个消息变量(消息的类型必须符合发送数据的要求)

    std_msgs::String msg;    

    std::stringstream ss;    

    ss << "hello world " << count;    

    msg.data = ss.str();    

    ROS_INFO("%s", msg.data.c_str());   //ROS_INFO and friends are our replacement for printf/cout.

    chatter_pub.publish(msg);          //就这样,消息被发布了。

    ros::spinOnce();            //若有Subscriber出现,ROS就会更新和读取所有主题

    loop_rate.sleep();               //按照10Hz的频率把程序挂起。(Why???)

    ++count;  

  }

  return 0;


 

 ROS Node

    1)在一个机器人软件中,有各种各样的node。别抢答,各种各样不是指localization,slam ,action这些功能的多种多样,而是指有消息的生产者,消费者,以及消费又生产的深加工者。先插一句吧,这次讨论涉及到这样的一个问题,在用ros构建一个机器人软件时,仅仅从功能划分的角度来构建node是否合适。是否还需要考虑让消息的流动更顺畅,让node更简洁高效呢?先说node是怎么跑的吧。当你建立一个node后,要么它按照一个固定的周期运行,要么它阻塞等待事件发生,由事件驱动运行。无论是那种,node都要干活,node干的什么活呢?callback queue里的活。这个callback queue里的callback是哪里来的呢?常见的是subscriber的callback,当然还有其他的,包括publisher的,service的。那这些callback是什么时候被调用的呢。那就是spin()或者spinonce()。spin调用在queue 里所有的availiable的callback,如果没有availible的,它就阻塞。spinonce,显然只调用一次,看看有没有准备好的callback,有就调用,没有就返回。那什么是availible的、准备好的呢?对于subscribe,准备好的就是那些有新消息的subscriber的callback。现在如果你明白了上述node的运行机理。你在感到舒服之余,请准备接收心烦的问题。1)第一个问题就是,如果subscriber没有收到新消息,那么它的callback就不会被执行。如果你想每次都运行callback呢?对不起,没办法,不是virgin我不娶。

    2)第二个问题,callback执行有个timeout值,如果设置不合理,要么费时,要么callback被中止。被中止呀,兄弟们,多可怕,万一是一个重要逻辑的一环呢?今天就聊到这里,最后送点福利,如果你想实现事件触发的node就用spin;如果你要固定周期的node,那就用spinonce+sleep,但一定要牢记,在每个周期里不是所有callback被执行。

 

 

Subscriber

 

#include "ros/ros.h"

#include "std_msgs/String.h"

        //每次该节点收到一条消息都会调用此函数,我们就可以使用或者处理数据。

            ROS_INFO()函数用于命令行打印数据

            (现在在这里面我们把收到的数据在命令行打印出来。)

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, "listener");

  ros::NodeHandle n;

        //创建一个订阅者,并从topic获取以chatter为名的消息数据。

            设置缓冲区1000

            处理消息的回调函数为chatterCallback()

  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

        //ros::spin();库是node 读取数据的消息响应循环,当消息到达的时候,回调函数被调用。

             Ctrl+C时,node退出消息循环

  ros::spin();

  return 0;

 

 


编译节点

The generated CMakeLists.txt should look like this:

技术分享

添加代码:

技术分享

 

【11】Writing a Simple Publisher and Subscriber (C++)

标签:

原文地址:http://www.cnblogs.com/jack-wangchong/p/5475207.html

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!