通过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服务文件编译后都会变成程序的头文件,所以这里写成,来引入此话题类型
<code class="has-numbering">#include "apriltags2_ros/AprilTagDetectionArray.h" </code>
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的节点
<code class="has-numbering">#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(); } </code>
根据上面订阅/tag_detections的节点,我编写了订阅/tf的话题节点,可以看到只是修改了相关的部分,这里只是应用还是有一定规律。这里我们可以试着任意想订阅的话题节点了
<code class="has-numbering">#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(); }</code>