我已经尝试解决这个问题一段时间了,但没有成功。基本上,我有一个有几个类成员的节点,在其中一个类中,我需要处理3个同步主题的数据。我使用的是近似时间同步器。我的问题是,同步的回调只被调用一两次,然后就停止了(同步超出了范围)。
我在下面放一个简化版的节点。结构是node.cpp实例化成员类A,类A有一个多线程循环。在这个循环中,我实例化了ClassB,声明了订阅者和近似同步器,并设置同步器的回调指向ClassB的函数,这样我就可以在类B中处理这些数据。
我不知道在哪里创建同步器。首先,我试过直接在类B中让它存在,但在classB的构造函数或classB的一个函数中声明它,只得到1次成功的调用,然后同步就被销毁了。
正如你在classA.cpp中看到的那样,现在我把同步器放在循环函数中,在那里我让它成功地回调了几次,但它最终停止了。我想把它放在node.cpp的主函数中,就像这个例子一样,但是我需要把ClassB的环境传递给回调,而且我需要在ClassA中发生了一堆其他事情之后再进行回调。
我很感激你的建议
node.cpp。
#include <ros/ros.h>
#include <node/ClassA.h>
#include <tf2_ros/transform_listener.h>
int main(int argc, char** argv){
ros::init(argc, argv, "node");
tf2_ros::Buffer buffer(ros::Duration(10));
tf2_ros::TransformListener tf(buffer);
node::ClassA lcr("node", buffer);
ros::spin();
return (0);
}
Class A. h:
#include <node/classB.h>
#include <message_filters/sync_policies/approximate_time.h>
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <msgs/msgType.h>
using namespace message_filters;
namespace node
{
Class A
{
public:
ClassA();
~ClassA();
protected:
Object* b_;
private:
void loop(node::Config &config, double frequency);
ClassB * b_;
message_filters::Subscriber<msgs::msgType> subscriber_A;
message_filters::Subscriber<msgs::msgType> subscriber_B;
message_filters::Subscriber<msgs::msgType> subscriber_C;
typedef sync_policies::ApproximateTime<msgs::msgType, msgs::msgType, msgs::msgType> MySyncPolicy;
typedef Synchronizer<MySyncPolicy> Sync;
boost::shared_ptr<Sync> sync;
};
}
ClassA. cpp:
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
using namespace message_filters;
namespace node
{
ClassA::ClassA():
thread_shutdown_(false)
{ // Constructor for classA
}
ClassA::~ClassA(){
thread_shutdown_ = true;
}
objectB_ = new Object ();
function1();
}
void ClassA::function1(){
// ...
thread_ = new boost::thread(boost::bind(&ClassA::loop, this, config, loop_frequency));
}
void ClassA::loop(node::NodeConfig &config, double frequency){
ros::NodeHandle nh;
ros::NodeHandle nh_B("~/" + name_);
ClassB * b_ = new ClassB(&nh_B, objectB_); // Initialize ClassB instance
subscriber_A.subscribe(nh_v2x, "topic1", 1);
subscriber_B.subscribe(nh_v2x, "topic2", 1);
subscriber_C.subscribe(nh_v2x, "topic3", 1);
sync.reset(new Sync(MySyncPolicy(20), subscriber_A, subscriber_B, subscriber_C));
sync->registerCallback(boost::bind(&ClassB::subscribe_synced_callback, b_, _1, _2, _3)); // this gets callback called twice
while (nh.ok() && !thread_shutdown_)
{
//sync->registerCallback(boost::bind(&ClassB::subscribe_synced_callback, b_, _1, _2, _3)); // this gets callback called a few times and then stops
// do stuff
}
}
}
ClassB.h:
#include <message_filters/sync_policies/approximate_time.h>
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
using namespace message_filters;
namespace node
{
class ClassB
{
//...
public:
ClassB();
~ClassB();
void subscribe_synced_callback(const msgs::msgType::ConstPtr& msgA, const msgs::msgType::ConstPtr& msgB, const msgs::msgType::ConstPtr& msgC);
//...
};
}
ClassB. cpp:
#include <node/classB.h>
namespace node
{
ClassB::ClassB(){ // Constructor for classB
// ...
}
void ClassB::subscribe_synced_callback(const msgs::msgTpye::ConstPtr& msgA, const msgs::msgType::ConstPtr& msgB, const msgs::msgType::ConstPtr& msgC)
{
// Do stuff with Time synced data
}
}
好的,首先,我想说,作为一种风格,你应该试着把你的ros代码和你的类真实的代码分开。你应该把所有真正的工作都放在你的类中,然后从一个节点可执行文件中调用它们,这个可执行文件包裹着它们,并与其他节点进行io。另外,你不需要让一个节点成为一个类,你可以把它变成一个单独的文件。这有助于简化&把你所有的ros定义集中在一个地方。
// ROS Includes
#include <ros/ros.h>
#include <sensor_msgs/Image.h>
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <message_filters/sync_policies/approximate_time.h>
// Custom Includes
#include <my_pkg/classA.h>
// Subscribers
// left_img (sensor_msgs/Image): "camera/left"
// right_img (sensor_msgs/Image): "camera/right"
// ROS Handles and Publishers
ros::NodeHandle* nh;
ros::NodeHandle* pnh;
// ROS Callbacks
static void img_cb(const sensor_msgs::Image::ConstPtr& left_img_msg, const sensor_msgs::Image::ConstPtr& right_img_msg);
int main(int argc, char **argv){
ros::init(argc, argv, "synchronizer");
nh = new ros::NodeHandle();
pnh = new ros::NodeHandle("~");
// Subscribers
message_filters::Subscriber<sensor_msgs::Image> left_img_sub(*nh, "camera/left", 10);
message_filters::Subscriber<sensor_msgs::Image> right_img_sub(*nh, "camera/right", 10);
typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::Image, sensor_msgs::Image> MySyncPolicy;
message_filters::Synchronizer<MySyncPolicy> img_sync(MySyncPolicy(10), left_img_sub, right_img_sub);
img_sync.registerCallback(boost::bind(&img_cb, _1, _2));
ros::spin();
}
static void img_cb(const sensor_msgs::Image::ConstPtr& left_img_msg, const sensor_msgs::Image::ConstPtr& right_img_msg){
ROS_INFO("Synchronization successful");
// Real code from classes here
}
这是我从你的代码中所能看到的最好的,但似乎你已经看到了你的代码。相关的ROS维基.