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

Question on frame transform

asked 2015-06-12 04:13:06 -0500

kevin.kuei.0321@gmail.com gravatar image

Hi all,

After reading the tf tutorials, I think I'm almost understood the basics of ROS /tf. But when I did some test, I got a strange problem.

First, I created a frame called "turtleA" on (1, 1, 0) Also, I created a frame called "turtleB" on (10, 10, 0)

Then I wrote a simple listener1 to lookup turtleA to turtleB transform, and use getOrigin() to get position of turtle1 to turtle2. I ran my listener1. I expected to get (-9, -9). Right? But I got (-9, 9).

Is there anybody can help to check if anything I went wrong?

Here is the steps

A. Run turtlesim_node, create two more turtles

$ rosrun turtlesim turtlesim_node
$ rosservice call /spawn 1.0 1.0 0 turtleA
$ rosservice call /spawn 10.0 10.0 0 turtleB

(Here is the output log...)

[ INFO] [1434096863.907583199]: Starting turtlesim with node name /turtlesim
[ INFO] [1434096863.928566152]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]
[ INFO] [1434097013.827165207]: Spawning turtle [turtleA] at x=[1.000000], y=[1.000000], theta=[0.000000]
[ INFO] [1434097035.040781460]: Spawning turtle [turtleB] at x=[10.000000], y=[10.000000], theta=[0.000000]

B. Generate a frame called "turtleA" on (1, 1, 0)

// one one terminal
$ rosrun learning_tf turtle_tf_broadcaster __name:=turtleA turtleA

C. Generate a frame called "turtleB" on (10, 10, 0)

// on the other terminal
$ rosrun learning_tf turtle_tf_broadcaster __name:=turtleB turtleB

D. Here is my listener1 code.

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

  ros::NodeHandle node;


  tf::TransformListener listener;

  ros::Rate rate(10.0);
  while (node.ok()){
    tf::StampedTransform transform;
    try{
      listener.lookupTransform("/turtleB", "/turtleA",
                               ros::Time(0), transform);
    }
    catch (tf::TransformException &ex) {
      ROS_ERROR("%s",ex.what());
      ros::Duration(1.0).sleep();
      continue;
    }


    ROS_INFO("turtleA is on (%f, %f) to turtleB\n",
             transform.getOrigin().x(),
             transform.getOrigin().y());

    rate.sleep();
  }
  return 0;
};

E. My listener output

$ rosrun learning_tf turtle_tf_listener1 
[ERROR] [1434097444.841959496]: "turtleB" passed to lookupTransform argument target_frame does not exist. 
[ INFO] [1434097445.842391115]: turtleA is on (-9.000000, 9.000000) to turtleB
[ INFO] [1434097445.842532474]: turtleA is on (-9.000000, 9.000000) to turtleB
[ INFO] [1434097445.943704829]: turtleA is on (-9.000000, 9.000000) to turtleB

Plz help!! :)

Kevin Kuei

edit retag flag offensive close merge delete

Comments

Hm.. I think there must be some problem in spawn service. When I issued "rosservice call /spawn 1.0 1.0 0 turtleA". And check the turtleA pose, I got:

$ rostopic echo /turtleA/pose

x: 1.0 y: 10.088889122 theta: 0.0 linear_velocity: 0.0

angular_velocity: 0.0

Why it's NOT on 1.0, 1.0 ??

kevin.kuei.0321@gmail.com gravatar image kevin.kuei.0321@gmail.com  ( 2015-06-12 10:32:08 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2015-06-12 16:30:01 -0500

In my opinion, you've actually uncovered a bit of a bug in how the turtlesim package works. If you look at the source code for the turtlesim package, you'll see that the coordinate system definitions used are different for the /spawn service than for all of the other topics and services.

The window that pops up when you rosrun turtlesim turtlesim_node is a Qt window. As is common in many GUIs, that window uses the top left corner of the window as the (0,0) point; x is to the right and y points down. For the poses published on the /turtleX/pose topic, the teleportation services, and the /tf stuff in the tutorials you are referencing, they instead use the bottom left corner for (0,0); x is to the right and y points up. I'm sure this is to make the coordinate system more familiar to people trying to learn ROS.

In the spawnCallback method that handles /spawn service clients you'll see that eventually the spawnTurtle method gets called. That function instantiates a new Turtle object using the raw (x,y) values passed into the service; this is in the Qt coordinate system, not the one used by everything else. If you look at the update function inside of turtle.cpp, you can see several examples of where they convert between the Qt system and the ROS system. Lines 131-133 show this when handling turtlesim/TeleportAbsolute requests; line 168 shows this when they publish the /turtleX/pose topic.

edit flag offensive delete link more

Comments

I just submitted a bug report: https://github.com/ros/ros_tutorials/...

jarvisschultz gravatar image jarvisschultz  ( 2015-06-12 16:36:18 -0500 )edit

Thank you so much!!

kevin.kuei.0321@gmail.com gravatar image kevin.kuei.0321@gmail.com  ( 2015-06-12 19:07:26 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2015-06-12 04:13:06 -0500

Seen: 376 times

Last updated: Jun 12 '15