Ask Your Question

How can i apply two sensor messages on one frame?

asked 2018-07-12 09:18:27 -0600

rubot gravatar image

updated 2018-07-12 12:38:18 -0600

I have a sensor which measures a position of one frame and the other sensor measures the rotation. If I'm subscribing on those two sensor topics, how can i define a transform which gets both of the sensor data, position and rotation?

im also quite new to c++... Is it possible to write something like

void callbackFunc(const geometry_msgs::PointStampedConstPtr& msg, 
                  const sensor_msgs::ImuConstPrt& imuMsg){
//defining transformStamped and Broadcaster
tfStamped.translation.x = msg->point.x;
...// until translation.z
tf.Stamped.rotation.x  = imuMsg->orientation.x;
..// until rotation.w

int main(......){
ros::Subscriber sub = node.subscribe("....");

is it possible to realize it this way?


my current code is:

#include <ros/ros.h>
#include <tf2/LinearMath/Quaternion.h>
#include <tf2_ros/transform_broadcaster.h>
#include <geometry_msgs/PointStamped.h>
#include <geometry_msgs/TransformStamped.h>
#include <sensor_msgs/Imu.h>
#include <message_filters/subscriber.h>
#include <message_filters/time_synchronizer.h>

void callback(const geometry_msgs::PointStampedConstPtr& msg,
                      const sensor_msgs::ImuConstPtr& imuMsg){

  static tf2_ros::TransformBroadcaster tf2_broadcaster;
  geometry_msgs::TransformStamped transformStamped;

  transformStamped.header.stamp = ros::Time::now();
  transformStamped.header.frame_id = "ts_frame";
  transformStamped.child_frame_id = "prism_frame";
  transformStamped.transform.translation.x = msg->point.x;
  transformStamped.transform.translation.y = msg->point.y;
  transformStamped.transform.translation.z = msg->point.z;
  tf2::Quaternion q;
  transformStamped.transform.rotation.x = imuMsg->orientation.x;
  transformStamped.transform.rotation.y = imuMsg->orientation.y;
  transformStamped.transform.rotation.z = imuMsg->orientation.z;
  transformStamped.transform.rotation.w = imuMsg->orientation.w;


int main(int argc, char** argv){
  ros::init(argc, argv, "tf_ts2prism");
  ros::NodeHandle nh;

  message_filters::Subscriber<sensor_msgs::Imu> imu_sub(nh, "/imu/data_raw", 1);
  message_filters::Subscriber<geometry_msgs::PointStamped> point_sub(nh, "/ts_points", 1);

  message_filters::TimeSynchronizer<sensor_msgs::Imu, geometry_msgs::PointStamped> sync(imu_sub, point_sub, 10);
  sync.registerCallback(boost::bind(&callback, _1, _2));

  return 0;

the error message is:

In file included from /usr/include/boost/bind.hpp:22:0,
                 from /opt/ros/kinetic/include/ros/publisher.h:35,
                 from /opt/ros/kinetic/include/ros/node_handle.h:32,
                 from /opt/ros/kinetic/include/ros/ros.h:45,
                 from /home/mango/tut_ws/src/totalstation/src/tf_ts2prism.cpp:1:
/usr/include/boost/bind/bind.hpp: In instantiation of ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = void (*)(const boost::shared_ptr<const geometry_msgs::PointStamped_<std::allocator<void> > >&, const boost::shared_ptr<const sensor_msgs::Imu_<std::allocator<void> > >&); A = boost::_bi::list9<const boost::shared_ptr<const sensor_msgs::Imu_<std::allocator<void> > >&, const boost::shared_ptr<const geometry_msgs::PointStamped_<std::allocator<void> > >&, const boost::shared_ptr<const message_filters::NullType>&, const boost::shared_ptr<const message_filters::NullType>&, const boost::shared_ptr<const message_filters::NullType>&, const boost::shared_ptr<const message_filters::NullType>&, const boost::shared_ptr<const message_filters::NullType>&, const boost::shared_ptr<const message_filters::NullType>&, const boost::shared_ptr<const message_filters::NullType>&>; A1 = boost::arg<1>; A2 = boost::arg<2>]’:
/usr/include/boost/bind/bind.hpp:1102:50:   required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&, A2&&, A3&&, A4&&, A5&&, A6&&, A7&&, A8&&, A9&&) [with A1 = const boost::shared_ptr<const sensor_msgs::Imu_<std::allocator<void> > >&; A2 = const boost::shared_ptr<const geometry_msgs::PointStamped_<std::allocator ...
edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted

answered 2018-07-12 09:52:37 -0600

Yes there is a package to help you achieve this quite easily.

The message_filters package specifically the time synchroniser filter can listen to two different topics and execute a callback with the messages of both topics when they arrive at a very similar time.

Hope this helps.

edit flag offensive delete link more


Thanks a lot! This was exactly what i was searching for... unfortunately by using the line sync.registerCallback(boost::bind(&callback, _1, _2));

i get a huge error message containing:

/usr/include/boost/smart_ptr/shared_ptr.hpp: In instantiation of ‘boost::shared_ptr<T>::shared_ptr(Y*) [with

rubot gravatar imagerubot ( 2018-07-12 10:38:48 -0600 )edit

By compiling the example code everything works fine, but when i add a sensor_msgs::Imu object to the message_filters::Subscriber<> boost starts to complain

rubot gravatar imagerubot ( 2018-07-12 11:26:46 -0600 )edit

Did you update the message types in the callback definition (line 9), the subscribers (lines 20,21) and the synchronizer (line 22)? If that doesn't solve your problem can you update the content of your original question with your source code and the full error message.

PeteBlackerThe3rd gravatar imagePeteBlackerThe3rd ( 2018-07-12 12:32:32 -0600 )edit

yes, i did. i added my code and the error message to the question

rubot gravatar imagerubot ( 2018-07-12 12:41:18 -0600 )edit

I'm as confused as you are at the moment. Hopefully someone else can figure this one out!

PeteBlackerThe3rd gravatar imagePeteBlackerThe3rd ( 2018-07-12 12:46:44 -0600 )edit

answered 2018-07-12 13:09:07 -0600

rubot gravatar image

Since my second problem had something to do with boost i decided to post an other question here. The problem was that i declared the message_filters::TimeSynchronizer with Imu first and then PointStamped on the second position, but in the callback function i wrote it the other way around, so boost couldn't handle the types.

So either it's possible to change my code to boost::bind(&callback, _2, _1) or change my callback to callback(const geometry_msgs::PointStampedConstPtr& msg, const sensor_msgs::ImuConstPtr& imuMsg)

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2018-07-12 09:18:27 -0600

Seen: 233 times

Last updated: Jul 12 '18