ROS2 Galactic中使用Message Filters时回调函数未触发求助
ROS2 Galactic中Message Filters回调函数未触发问题
问题描述
代码编译正常,但运行时topic_callback从未被调用。已确认两个话题的QoS匹配,运行环境为Ubuntu 20.04 + ROS2 Galactic。
问题代码
#include "rclcpp/rclcpp.hpp" #include "sensor_msgs/msg/image.hpp" #include "sensor_msgs/msg/point_cloud2.hpp" #include <message_filters/subscriber.h> #include <message_filters/time_synchronizer.h> #include <message_filters/sync_policies/approximate_time.h> //using std::placeholders::_1; class MinimalSubscriber : public rclcpp::Node { public: message_filters::Subscriber<sensor_msgs::msg::Image> image_sub_; message_filters::Subscriber<sensor_msgs::msg::PointCloud2> cloud_sub_; MinimalSubscriber() : Node("minimal_subscriber_left") { image_sub_.subscribe(this, "/left/image_raw"); cloud_sub_.subscribe(this, "/model/prius_hybrid/laserscan/points"); typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::msg::Image, sensor_msgs::msg::PointCloud2> approximate_policy; message_filters::Synchronizer<approximate_policy> syncApproximate(approximate_policy(10), image_sub_, cloud_sub_); syncApproximate.registerCallback(&MinimalSubscriber::topic_callback, this); }; public: void topic_callback(const sensor_msgs::msg::Image::SharedPtr image, const sensor_msgs::msg::PointCloud2::SharedPtr cloud2) { std::cout<<"Hello messages are being received"; RCLCPP_INFO(this->get_logger(), "Publishing"); }; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<MinimalSubscriber>()); rclcpp::shutdown(); return 0; }
问题原因及解决方案
核心问题
Synchronizer对象是构造函数中的局部变量,构造函数执行完毕后会被立即销毁,导致无法持续监听话题消息、匹配时间戳并触发回调。
修复步骤
- 将
Synchronizer声明为类的成员变量,确保其生命周期与节点一致。 - 使用智能指针管理
Synchronizer对象,避免手动内存管理问题。 - 用
std::bind正确绑定回调函数与类实例,确保回调能被正确触发。
修复后的代码
#include "rclcpp/rclcpp.hpp" #include "sensor_msgs/msg/image.hpp" #include "sensor_msgs/msg/point_cloud2.hpp" #include <message_filters/subscriber.h> #include <message_filters/time_synchronizer.h> #include <message_filters/sync_policies/approximate_time.h> #include <functional> class MinimalSubscriber : public rclcpp::Node { public: message_filters::Subscriber<sensor_msgs::msg::Image> image_sub_; message_filters::Subscriber<sensor_msgs::msg::PointCloud2> cloud_sub_; // 声明同步器为类成员智能指针 typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::msg::Image, sensor_msgs::msg::PointCloud2> approximate_policy; std::shared_ptr<message_filters::Synchronizer<approximate_policy>> sync_approximate_; MinimalSubscriber() : Node("minimal_subscriber_left") { image_sub_.subscribe(this, "/left/image_raw"); cloud_sub_.subscribe(this, "/model/prius_hybrid/laserscan/points"); // 初始化同步器并绑定回调 sync_approximate_ = std::make_shared<message_filters::Synchronizer<approximate_policy>>( approximate_policy(10), image_sub_, cloud_sub_); sync_approximate_->registerCallback( std::bind(&MinimalSubscriber::topic_callback, this, std::placeholders::_1, std::placeholders::_2) ); }; void topic_callback(const sensor_msgs::msg::Image::SharedPtr image, const sensor_msgs::msg::PointCloud2::SharedPtr cloud2) { std::cout<<"Hello messages are being received"<<std::endl; RCLCPP_INFO(this->get_logger(), "Received synchronized messages"); }; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<MinimalSubscriber>()); rclcpp::shutdown(); return 0; }
额外调试建议
- 运行前用
ros2 topic echo确认两个话题确实有消息发布。 - 检查话题名称是否完全匹配,避免拼写错误。
- 若仍有问题,可尝试降低
ApproximateTime策略的队列大小,或调整时间匹配阈值。
内容的提问来源于stack exchange,提问作者Marcelo Mafalda
相关产品推荐
相关产品推荐

