## page was renamed from tf/Tutorials/Adding a fixed frame (Python) #################################### ##FILL ME IN #################################### ## for a custom note with links: ## note =This tutorial assumes you have completed the writing a tf listener tutorial [[tf/Tutorials/Writing a tf listener (Python)|(Python)]] [[tf/Tutorials/Writing a tf listener (C++)|(C++)]] ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0= ## descriptive title for the tutorial ## title =Adding a frame (Python) ## multi-line description to be displayed in search ## description = This tutorial teaches you how to add an extra fixed frame to tf. ## the next tutorial description (optional) ## next = tf and time ## links to next tutorial (optional) ## next.0.link=[[tf/Tutorials/tf and Time (Python)|(Python)]] ## next.1.link= ## what level user is this tutorial for ## level= BeginnerCategory ## keywords = #################################### <> {{{#!wiki caution tf is deprecated in favor of [[tf2]]. [[tf2]] provides a superset of the functionality of tf and is actually now the implementation under the hood. If you're just learning now it's strongly recommended to use the [[tf2/Tutorials]] instead. }}} <> <> === The Code === Fire up your favorite editor and paste the following code into a new file called '''nodes/fixed_tf_broadcaster.py'''. {{{ #!python block=broadcaster #!/usr/bin/env python import roslib roslib.load_manifest('learning_tf') import rospy import tf if __name__ == '__main__': rospy.init_node('fixed_tf_broadcaster') br = tf.TransformBroadcaster() rate = rospy.Rate(10.0) while not rospy.is_shutdown(): br.sendTransform((0.0, 2.0, 0.0), (0.0, 0.0, 0.0, 1.0), rospy.Time.now(), "carrot1", "turtle1") rate.sleep() }}} Don't forget to make the node executable: {{{ chmod +x nodes/fixed_tf_broadcaster.py }}} The code is very similar to the example in the [[tf/Tutorials/Writing a tf broadcaster (Python)|tf broadcaster tutorial]]. Only here the transform does not change over time. === The Code Explained === Let's take a look at the key lines in this piece of code: <> Here we create a new transform, from the parent "turtle1" to the new child "carrot1". The carrot1 frame is 2 meters offset from the turtle1 frame. == Running the frame broadcaster == Edit the '''start_demo.launch''' launch file. Simply add the following line: {{{ ... }}} <> Open the '''nodes/turtle_tf_listener.py''' file, and simple replace "/turtle1" with "/carrot1": {{{#!python block=broadcaster (trans,rot) = listener.lookupTransform("/turtle2", "/carrot1", rospy.Time(0)) }}} And now the good part: just restart the turtle demo, and you'll see the second turtle following the carrot instead of the first turtle! Remember that the carrot is 2 meters to the left of turtle1. There is no visual representation for the carrot, but you should see the second turtle moving to that point. {{{ $ roslaunch learning_tf start_demo.launch }}} == Broadcasting a moving frame == The extra frame we published in this tutorial is a fixed frame that doesn't change over time in relation to the parent frame. However, if you want to publish a moving frame you can code the broadcaster to change the frame over time. Let's change our `carrot1` frame to change relative to `turtle1` over time. Create the file '''nodes/dynamic_tf_broadcaster.py''' containing the following (and make it executable with `chmod +x` as we did above): {{{ #!python block=dynamic_broadcaster #!/usr/bin/env python import roslib roslib.load_manifest('learning_tf') import rospy import tf import math if __name__ == '__main__': rospy.init_node('dynamic_tf_broadcaster') br = tf.TransformBroadcaster() rate = rospy.Rate(10.0) while not rospy.is_shutdown(): t = rospy.Time.now().to_sec() * math.pi br.sendTransform((2.0 * math.sin(t), 2.0 * math.cos(t), 0.0), (0.0, 0.0, 0.0, 1.0), rospy.Time.now(), "carrot1", "turtle1") rate.sleep() }}} Note that instead of defining a fixed offset from `turtle1`, we are using a `sin` and `cos` function based on the current time to cause the definition of the frame's offset. To test this code, remember to change the launch file to point to our new, dynamic broadcaster for the definition of `carrot1` instead of the fixed broadcaster above: {{{ ... }}} You're now ready to move to the next tutorial about tf and time [[tf/Tutorials/tf and Time (Python)|(Python)]] [[tf/Tutorials/tf and Time (C++)|(C++)]] ## AUTOGENERATED DO NOT DELETE ## TutorialCategory ## TutorialTurtlesim ## PythonCategory ## LearningCategory