A sutble question about the /odom topic

130 views
Skip to first unread message

Davide Picchi

unread,
Aug 28, 2014, 5:02:04 PM8/28/14
to ros-by-...@googlegroups.com
Hi,
I was reading your book and making again the tutorials online. Since I m giong to write a UDRF for my robot I wanted to be sure, that I understood correctly.
I have a question:
Let s take the odom_out_and_back.py script. In the script you wrote the following code to check whether the base_link or the base_footprint has been defined:

        # Set the odom frame
       
self.odom_frame = '/odom'
       
       
# Find out if the robot uses /base_link or /base_footprint
       
try:
           
self.tf_listener.waitForTransform(self.odom_frame, '/base_footprint', rospy.Time(), rospy.Duration(1.0))
           
self.base_frame = '/base_footprint'
       
except (tf.Exception, tf.ConnectivityException, tf.LookupException):
           
try:
               
self.tf_listener.waitForTransform(self.odom_frame, '/base_link', rospy.Time(), rospy.Duration(1.0))
               
self.base_frame = '/base_link'
           
except (tf.Exception, tf.ConnectivityException, tf.LookupException):
                rospy
.loginfo("Cannot find transform between /odom and /base_link or /base_footprint")
                rospy
.signal_shutdown("tf Exception")  

and you define the odom frame as a string '/odom'

So I checked again all your code form the launch file and so on but I realised that the frame odom is not in the URDF file of the robot defined nor in any other URDF-like file.
As I start learning ROS I thought that every frame shoudl be at least once defined in order to calculated trasnformations between them.
But this code is an example that this is not the rule.

Am I wrong? What I m missing???!

Thanks you very much for your patience and help.
Kindly regards
Davide

Patrick Goebel

unread,
Aug 28, 2014, 8:46:22 PM8/28/14
to ros-by-...@googlegroups.com
Hi Davide,

Excellent question!  You are correct that the /odom frame does not appear in the robot's URDF model and that's because it is not part of the robot.  Instead, it is defined by the robot's base controller node to reflect the motion of the robot as reported by the odometry data coming from the robot's encoders.  (For a distinction between the /odom frame and the /odom topic, see Section 7.8.4 but I don't think you are having a problem with that.)

Using the robot's odometry data, the base controller node uses a ROS TransformBroadcaster to publish a transformation between the /odom frame (created just for this purpose) and the /base_link (or /base_footprint) frame.  In effect, the /odom frame is imaginary and assumed to be fixed relative to the world.  So the transform broadcast by the base controller reflects the robot's idea of how it is moving relative to this imaginary frame.

You can see the code that does the work in the ArbotiX simulator by looking at the file diff_controller.py in the arbotix_ros package.  In particular, the code that broadcasts the odometry transform starts on line 149.

--patrick
--
You received this message because you are subscribed to the Google Groups "ros-by-example" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ros-by-exampl...@googlegroups.com.
Visit this group at http://groups.google.com/group/ros-by-example.
For more options, visit https://groups.google.com/d/optout.

Davide Picchi

unread,
Aug 29, 2014, 7:34:50 AM8/29/14
to ros-by-...@googlegroups.com
Hi Patrick,
in the file he defines the odom and base_link frames at first:
self.base_frame_id = rospy.get_param('~controllers/'+name+'/base_frame_id', 'base_link')
self.odom_frame_id = rospy.get_param('~controllers/'+name+'/odom_frame_id', 'odom')

and later the joint position to be published through a /joint_states topic:
# output for joint states publisher
self.joint_names = ["base_l_wheel_joint","base_r_wheel_joint"]
self.joint_positions = [0,0]
self.joint_velocities = [0,0]

so, it seems to me that frames, as a general rule, must be not defined in urdf files (IF is not a frame with a link-joint relation like a arm-robot).
And this answers the first question frm my side.

But there is more... I found those lines of code very interesting. I was surprised to found that:

self.odomBroadcaster.sendTransform(
(self.x, self.y, 0),
(quaternion.x, quaternion.y, quaternion.z, quaternion.w),
rospy.Time.now(),
self.base_frame_id,
self.odom_frame_id )
that means that the robot is going to project his supposed position (/odom) from the base_frame and not viceversa (which is intuitively the first thing that one could understand).
Or am I wrong?

Thank you very much Patrick!
Kindly regards

Davide Picchi

unread,
Aug 29, 2014, 7:43:31 AM8/29/14
to ros-by-...@googlegroups.com
...And this answers the first question from my side....helped and integrated of course with your explanation! :)

Patrick Goebel

unread,
Aug 29, 2014, 10:13:50 AM8/29/14
to ros-by-...@googlegroups.com
Hi Davide,

The order of the frames in the SendTransform() function is the reverse of what we might intuitively think.  (This messed me up early on as well.)   So the command below is broadcasting a transform from the odom_frame to the base_frame; i.e. from the second argument to the first.

--patrick
Reply all
Reply to author
Forward
0 new messages