Ask Your Question
0

Using tf for plotting frames in rviz

asked 2014-07-15 14:01:23 -0500

rkeatin3 gravatar image

So I'm developing some lab exercises for an introductory robotics course. In one of the first labs, we want students to be able to plot tf frames in rviz by defining the transformations between them:

void plotf(Eigen::Matrix4f h, std::string parentName, std::string childName){
  tf::TransformBroadcaster br;

  tf::Transform frame;
  frame.setOrigin(tf::Vector3(h(0,3), h(1,3), h(2,3)));
  frame.setBasis(tf::Matrix3x3(h(0,0), h(0,1), h(0,2),
                               h(1,0), h(1,1), h(1,2),
                               h(2,0), h(2,1), h(2,2)));

  ros::Duration(0.3).sleep();
  br.sendTransform(tf::StampedTransform(frame, ros::Time::now(), parentName, childName));
  ros::Duration(0.3).sleep();
}

This function works (though only after putting those odd delays in).

We'd also like them to be able to look up the transformation between various frames. I'm having trouble getting lookupTransform() to work, however. It says that the frames don't exist.

Any advice on the delays or the inability to look up transforms?

If the problem looking them up is that they are only published once (rather than continuously), I suppose I could write a node that continuously publishes frames and also change plotf(...) accordingly.

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2014-07-19 19:36:09 -0500

ahendrix gravatar image

It looks like you're creating the transform publisher and then immediately trying to use it. The trouble with this is that, ROS subscribers take some time to subscribe to a topic after a new publisher comes online, and usually miss the first message on a topic - your delay is compensating for this a bit.

The other problem you're having is that you're only publishing once, and then destrying the publisher when you're done - any nodes that aren't running and subscribed to tf when you publish won't receive the transform.

You've also ignoring the time component of the transforms - tf is designed to handle time-varying transformations, and all frames should be published continuously in order to keep them up to date.

The more standard way to use tf is to set up a persistent tf publisher object, either as a class member variable or a global variable, and then publish transforms at a fixed rate - usually between 10 and 100Hz.

There are a couple of ways you could hide these complexities from your students:

  • Provide a wrapper object which has a publish method and contains a thread which continuously republishes the transform.
  • If you're not publishing moving frames, you could move to tf2 and use the static transform broadcaster. you'll still have to keep the publisher around, but you won't have to publish to it continuously.
  • Have your students use the tf::TransformBoadcaster directly, and provide a helper method to convert from Eigen matrices to tf::Transform objects.
edit flag offensive delete link more

Comments

Thanks for your answer! I figured that publishing them only once might be a problem, but I was under the impression that I would have to create another ROS node that runs separately to publish the transforms continuously. Can you elaborate a bit (or point me in the direction of some information) on how to create a wrapper object with a continuously publishing thread? I'm not very familiar with multithreading at all.

rkeatin3 gravatar image rkeatin3  ( 2014-07-23 10:57:53 -0500 )edit

I would probably write a C++ class that contains a Boost::Thread. Note that proper threading and synchronization is one of the hardest topics in computer science. You should probably get some guidance from your professor.

ahendrix gravatar image ahendrix  ( 2014-07-23 14:24:52 -0500 )edit
1

answered 2014-07-15 19:00:41 -0500

2ROS0 gravatar image

Have you looked into waitForTransform()? It might be a case of the transforms not being ready which is why you have to add the delays. There's more information on common tf pitfalls in the tutorials.

edit flag offensive delete link more

Comments

Maybe I'm confused, but I thought waitForTransform() was used only when looking up transforms. Shouldn't I be able to broadcast transforms without a tf listener?

rkeatin3 gravatar image rkeatin3  ( 2014-07-17 10:14:32 -0500 )edit

Your Answer

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

Add Answer

Question Tools

Stats

Asked: 2014-07-15 14:01:23 -0500

Seen: 2,066 times

Last updated: Jul 19 '14