0
$\begingroup$

Rosanswers logo

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


Originally posted by [email protected] on ROS Answers with karma: 159 on 2015-06-12

Post score: 0


Original comments

Comment by [email protected] on 2015-06-12:
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 ??

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

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.


Originally posted by jarvisschultz with karma: 9031 on 2015-06-12

This answer was ACCEPTED on the original site

Post score: 0


Original comments

Comment by jarvisschultz on 2015-06-12:
I just submitted a bug report: https://github.com/ros/ros_tutorials/issues/24

Comment by [email protected] on 2015-06-12:
Thank you so much!!

$\endgroup$

This site is temporarily in read-only mode and not accepting new answers.