ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
3

tf::TransformBroadcaster in callback

asked 2012-10-22 13:15:45 -0600

Barbosa gravatar image

updated 2012-12-15 01:54:24 -0600

Hi,

So I was trying to have a transform published over tf as a result of a callback call, which made me think I had to have a tf::TransformBroadcaster as a global variable. However these can't be declared before the ros::NodeHandle is created.

I have tried using a boost::shared_ptr and almost got the hang of it but I still didn't quite understand how to use these boost pointers. Here's what I tried to do:

boost::shared_ptr<tf::TransformBroadcaster> pose_broadcaster;
void poseCallback(const nav_msgs::Odometry& pose){

    geometry_msgs::TransformStamped pose_trans;
    pose_trans.header.stamp = pose.header.stamp;
    pose_trans.header.frame_id = "odometry_frame"; 
    pose_trans.child_frame_id = "base_link";

    pose_trans.transform.translation.x = pose.pose.pose.position.x;
    pose_trans.transform.translation.y = pose.pose.pose.position.y;
    pose_trans.transform.translation.z = pose.pose.pose.position.z;
    pose_trans.transform.rotation = pose.pose.pose.orientation;
    ROS_INFO("Sending TF broadcast");
    pose_broadcaster.sendTransform(pose_trans);


}
int main(){
    ros::init(argc, argv, "pioneer_tf");
    ros::NodeHandle n;
    ros::Subscriber pose_sub=n.subscribe("pose", 1000, poseCallback);
    boost::shared_ptr<tf::TransformBroadcaster> ptr;
    pose_broadcaster= boost::shared_ptr<tf::TransformBroadcaster>(ptr);//problem here
   ros::spin();
}

I obviously got it wrong in the initialization of the pointer, what's the right way of doing it in this case?

--- EDIT ---

This problem is solved now, but I have a similar issue at the moment with a transformListener

It is basically the same set up, with a global variable (pointer declared as global and initialized in main) and the listener being called in a callback. The thing is, even though it compiles, the callback is never called, but if I comment the line where it is called inside the callback, it works and does everything normally... Any ideas of why the callback might not be called?

--- EDIT2 ---

This problem is totally solved. It was just a matter of making the TF buffer bigger and using a try/catch.

edit retag flag offensive close merge delete

Comments

If you have a new question, please open a new one instead of using this old question.

dornhege gravatar image dornhege  ( 2012-12-14 05:07:45 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted
4

answered 2012-10-22 19:35:24 -0600

Mani gravatar image

This is not a direct answer to your question. But a simpler (yet more naive) way to do what you want. Instead of using boost:share_ptr, I usually globally declare a pointer of type tf::TransformBroadcaster first. Next, In the main function, I use new to create the object after ros::init.

//Global Variable(s)
tf::TransformBroadcaster *tb;
// Rest of the code
int main(int argc, char **argv) {
    // After ros::init
    tb = new tf::TransformBroadcaster();
edit flag offensive delete link more

Comments

I will try this simpler way of doing it! Thanks!

Barbosa gravatar image Barbosa  ( 2012-10-29 04:10:57 -0600 )edit

This worked fine. thank you!

Barbosa gravatar image Barbosa  ( 2012-12-15 01:54:52 -0600 )edit
8

answered 2012-10-22 20:44:41 -0600

I usually encapsulate things into a class to avoid using global variables. You could do something like this:

class PoseBroadcaster
{
public:
  PoseBroadcaster()
  {
    pose_sub_ = n_.subscribe("pose", 1000, &PoseBroadcaster::poseCallback, this);
  }
private:
  poseCallback(const nav_msgs::Odometry& pose)
  {
    geometry_msgs::TransformStamped pose_trans;
    pose_trans.header.stamp = pose.header.stamp;
    pose_trans.header.frame_id = "odometry_frame"; 
    pose_trans.child_frame_id = "base_link";

    pose_trans.transform.translation.x = pose.pose.pose.position.x;
    pose_trans.transform.translation.y = pose.pose.pose.position.y;
    pose_trans.transform.translation.z = pose.pose.pose.position.z;
    pose_trans.transform.rotation = pose.pose.pose.orientation;
    ROS_INFO("Sending TF broadcast");
    pose_broadcaster_.sendTransform(pose_trans);
  }

  ros::NodeHandle n_;
  tf::TransformBroadcaster pose_proadcaster_;
};

int main(int argc, char **argv)
{
  ros::init(argc, argv, "pioneer_tf");

  PoseBroadcaster pb;

  ros::spin();
}

I hope this helps

edit flag offensive delete link more

Comments

I think this will help, thanks a lot. I did try this approach too but I was having some trouble with errors, maybe now this will help clear them out.

Barbosa gravatar image Barbosa  ( 2012-10-29 04:10:23 -0600 )edit

Question Tools

Stats

Asked: 2012-10-22 13:15:45 -0600

Seen: 2,405 times

Last updated: Dec 15 '12