1.tf::MessageFilter
是一个消息过滤器,用于从一个话题订阅消息并根据坐标变换信息进行过滤。它是ROS中tf
库的一部分。
下面是 tf::MessageFilter
的详细用法:
1.1首先,包含所需的头文件:
#include
1.2创建一个tf::TransformListener
对象来监听坐标变换:
tf::TransformListener tf_listener;
1.3创建一个message_filters::Subscriber
对象并订阅相关话题:
message_filters::Subscriber<YOUR_MESSAGE_TYPE> sub(node_handle, topic_name, queue_size);
1.4创建一个tf::MessageFilter
对象并将message_filters::Subscriber
对象传递给它:
tf::MessageFilter<YOUR_MESSAGE_TYPE> filter(sub, tf_listener, target_frame, queue_size);
sub: message_filters::Subscriber对象,用于订阅消息。
tf_listener: tf::TransformListener对象,用于监听坐标变换。
target_frame:目标帧,消息将会被转换到该帧中。
queue_size: 在缓冲区中允许的最大未处理消息数量。
1.5注册回调函数,当消息通过过滤器时被调用:
filter.registerCallback(boost::bind(&YOUR_CLASS::YOUR_CALLBACK_FUNCTION, this, _1));
YOUR_CLASS::YOUR_CALLBACK_FUNCTION
是你自己定义的回调函数。
1.6启动ROS的主循环,等待消息的到来:
ros::spin();
在上述步骤中,tf::MessageFilter
会根据 target_frame
参数给定的坐标系变换信息过滤sub
订阅的消息。只有在通过坐标变换后能够获得有效的消息时,才会调用回调函数。
需要注意的是,tf::MessageFilter
还提供了其他可用的功能,如设置超时时间、设置坐标系插值方法等。你可以参考ROS的官方文档以获取更详细的使用方法和选项。
2.tf::MessageFilter
接受 message_filters::Subscriber
类型的参数
message_filters::Subscriber
是一个ROS库中的订阅者类,用于订阅消息并提供过滤、同步等功能。
在tf::MessageFilter
构造函数中,可以将一个message_filters::Subscriber
对象作为参数传递给它,以便在订阅的消息上应用坐标变换过滤器。
下面是一个示例代码,展示了如何在tf::MessageFilter
中使用message_filters::Subscriber
对象:
#include
#include
#include
void callback(const YOUR_MESSAGE_TYPE::ConstPtr& msg)
{
// 处理接收到的消息
}
int main(int argc, char** argv)
{
// 初始化ROS节点
ros::init(argc, argv, "example_node");
ros::NodeHandle nh;
// 创建订阅者,订阅特定话题的消息
message_filters::Subscriber<YOUR_MESSAGE_TYPE> sub(nh, "topic_name", 1);
// 创建变换监听器
tf::TransformListener tf_listener;
// 创建消息过滤器,并将订阅者和变换监听器作为参数
tf::MessageFilter<YOUR_MESSAGE_TYPE> filter(sub, tf_listener, "target_frame", 1);
// 注册回调函数,当消息通过过滤器时调用
filter.registerCallback(boost::bind(&callback, _1));
// 进入ROS循环,等待消息的到来
ros::spin();
return 0;
}
在上述代码中,首先,通过调用ros::init()
初始化ROS节点,并创建一个ros::NodeHandle
对象,用于节点的通信。
然后,使用message_filters::Subscriber
在指定的话题上创建一个订阅者sub
,并设置队列大小为1
。
接下来,创建一个tf::TransformListener
对象tf_listener
,用于监听坐标变换。使用tf::MessageFilter
构造函数,将订阅者对象sub
、tf_listener
对象和目标帧名称target_frame
作为参数,创建一个消息过滤器filter
。最后,使用filter.registerCallback()
注册回调函数callback
,当消息通过过滤器时,将调用该回调函数进行处理。
使用ros::spin()
进入ROS的主循环,等待消息的到来并处理。请根据你的实际需求,将代码中的YOUR_MESSAGE_TYPE
替换为你要订阅的消息类型,并根据需要调整话题名称、目标帧名称和队列大小等参数。
3.消息通过过滤器,如何才叫做通过过滤器?
当消息通过tf::MessageFilter
的过滤器时,具体条件是根据消息的时间戳和坐标变换的可用性来决定的。
tf::MessageFilter
默认会根据消息的时间戳和tf变换的可用性来过滤消息。具体地说,当接收到一个消息时,tf::MessageFilter
会:
只有当消息满足上述两个条件时,才会将其视为"通过过滤器",才会调用注册的回调函数进行处理。如果消息未通过过滤器,tf::MessageFilter
将不会执行任何操作。
需要注意的是,在实际使用中,可以根据需要调整过滤器的行为,例如设置超时时间、定义自定义的过滤条件等。这些调整可以通过tf::MessageFilter
提供的方法和选项来实现。您可以参考官方文档或查阅相关教程了解更多细节。
4.例子
//订阅激光数据 同时和odom_frame之间的转换同步
// tf::MessageFilter 是一个消息过滤器,用于从一个话题订阅消息并根据坐标变换信息进行过滤。
// 当消息通过tf::MessageFilter的过滤器时,具体条件是根据消息的时间戳和坐标变换的可用性来决定的。
// tf::MessageFilter默认会根据消息的时间戳和tf变换的可用性来过滤消息。具体地说,当接收到一个消息时,tf::MessageFilter会:
// - 检查消息的时间戳,确保它处于tf变换数据的时间范围内,以防止使用过时的变换数据进行转换。
// - 检查tf树中是否存在从消息中给定的坐标系到目标坐标系的连续变换序列。如果能够找到该序列,就表示消息通过了过滤器。
// 只有当消息满足上述两个条件时,才会将其视为"通过过滤器",才会调用注册的回调函数进行处理。
// 如果消息未通过过滤器,tf::MessageFilter将不会执行任何操作。
// will add: tf::MessageFilter会根据 target_frame:odom_frame_ 参数给定的坐标系变换信息
// 过滤 scan_filter_sub_ 订阅的消息。只有在通过坐标变换后 能够获得有效的消息时,才会调用回调函数 SlamGMapping::laserCallback。
scan_filter_sub_ = new message_filters::Subscriber<sensor_msgs::LaserScan>(node_, "scan", 5);
scan_filter_ = new tf::MessageFilter<sensor_msgs::LaserScan>(*scan_filter_sub_, tf_, odom_frame_, 5);
scan_filter_->registerCallback(boost::bind(&SlamGMapping::laserCallback, this, _1));