浅析ros下修改订阅话题

49
0
4天前

通过rostopic list 可以查看发布的话题,可以看到有/tag_detections和/tf话题,那麽我们先编写订阅/tag_detections,然后根据此模板订阅成/tf

 

在这里插入图片描述

 

1,首先原始话题是订阅/tag_detections

 

通过rostopic info /tag_detections 查看话题的发布者和类型如下:

 

在这里插入图片描述

 

2,已知话题的发布者和类型,这时候我们编写订阅节点

 

2.1,首先我们看到这里的类型后,我们要找到这个类型在msg文件/srv文件下,从而进行头文件定义,这里我们看到很明显的在msg文件下的AprilTagDetectionArray.msg文件下,msg消息和srv服务文件编译后都会变成程序的头文件,所以这里写成,来引入此话题类型

 

#include "apriltags2_ros/AprilTagDetectionArray.h"

 

在这里插入图片描述

 

2.2 编写订阅话题的类Localizer

 

这里的编写,我是根据之前看到话题一种类的格式来修改的,当然我们可以用官网上那种把所有部分都写在main函数的形式,但是那样不便于后来程序阅读和拓展,所以我选择这种形式,现在我们分析下下面的具体实现
对象声明:

 

ros::Subscriber ar_sub_;这句话定义了一个话题订阅对象ar_sub_

 

apriltags2_ros::AprilTagDetectionArrayConstPtr last_msg_;定义了一个 实参对象last_msg_

 

至于这里为什么加ConstPtr,这是一个疑问点,不懂,从下面网址看到:

 

另一个是::ConstPtr,它是boost::shared_ptr。通过将const指针传递到回调,我们避免了复制。网址:https://blog.csdn.net/kantswang/article/details/82947669

 

void number_callback(const apriltags2_ros::AprilTagDetectionArray::ConstPtr& msg)定义回调函数,里面是调用话题类型的形参对象,函数内实现了形参向实参的赋值。

 

ar_sub_ = nh.subscribe<apriltags2_ros::AprilTagDetectionArray>(“tag_detections”, 1,
&Localizer::number_callback, this);
<apriltags2_ros::AprilTagDetectionArray>订阅话题的类型
“tag_detections”,订阅的话题

 

1 缓存队列空间大小,通常订阅和发布缓存大小是一致。被取走的消息存放入了Subscriber的消息队列中,等待被Callback执行。如果Callback执行很慢,消息越堆越多,最老的消息会逐渐被顶替。参考网址:

https://blog.csdn.net/handsome_for_kill/article/details/81984428

 

&Localizer::number_callback 回调函数的引用

 

this 不懂,固定格式,可能跟指针有关

 

main函数Localizer localizer(node_obj);对节点对象的实例化,从而实现订阅

 

ros::spin()函数一般不会出现在循环中,因为程序执行到spin()后就不调用其他语句了,也就是说该循环没有任何意义,还有就是spin()函数后面一定不能有其他语句(return 0 除外),有也是白搭,不会执行的。

 

下面是我们订阅/tag_detections的节点

 

#include "ros/ros.h"
#include "apriltags2_ros/AprilTagDetectionArray.h"
#include <iostream>
class Localizer
{
public:
  Localizer(ros::NodeHandle& nh)
  {
      ar_sub_ = nh.subscribe<apriltags2_ros::AprilTagDetectionArray>("tf", 1,
      &Localizer::number_callback, this);    
  }
  void number_callback(const apriltags2_ros::AprilTagDetectionArray::ConstPtr& msg)
  {
       last_msg_ = msg;
       ROS_INFO_STREAM(last_msg_->detections[0].pose.pose.pose);
  }
ros::Subscriber ar_sub_;
apriltags2_ros::AprilTagDetectionArrayConstPtr last_msg_;
};
int main(int argc, char **argv)
{
    int i=0;
    ros::init(argc, argv,"apriltag_detector_subscriber");
    ros::NodeHandle node_obj;
    Localizer localizer(node_obj);
    ROS_INFO("Vision node starting");
    ros::spin();
}

 

根据上面订阅/tag_detections的节点,我编写了订阅/tf的话题节点,可以看到只是修改了相关的部分,这里只是应用还是有一定规律。这里我们可以试着任意想订阅的话题节点了

 

#include "ros/ros.h"
#include "tf2_msgs/TFMessage.h"
#include <iostream>
class Localizer
{
public:
  Localizer(ros::NodeHandle& nh)
  {
      ar_sub_ = nh.subscribe<tf2_msgs::TFMessage>("tf", 1,
      &Localizer::number_callback, this);    
  }
  void number_callback(const tf2_msgs::TFMessage::ConstPtr& msg)
  {
       last_msg_ = msg;
       ROS_INFO_STREAM(last_msg_->transforms[0].transform);
  }
ros::Subscriber ar_sub_;
tf2_msgs::TFMessageConstPtr last_msg_;
};
int main(int argc, char **argv)
{
    int i=0;
    ros::init(argc, argv,"apriltag_detector_subscriber");
    ros::NodeHandle node_obj;
    Localizer localizer(node_obj);
    ROS_INFO("Vision node starting");
    ros::spin();
}

发表评论

后才能评论