Skip to content

Commit

Permalink
tf2 tutorials: Consistency fixes in Python and C++ tutorials (#1936)
Browse files Browse the repository at this point in the history
* check and update consistency in Writing-A-Tf2-Static-Broadcaster Python and C++ tutorials

* check and update consistency in Writing-A-Tf2-Broadcaster Python and C++ tutorials

* check and update consistency in Writing-A-Tf2-Listener Python and C++ tutorials and update code snippet to match update in geopmetry_tutorials

* check and update consistency in Adding-A-Frame Python and C++ tutorials

* check and update consistency in Time-Travel-With-Tf2 Python and C++ tutorials

* use lowercase in titles in Introduction-To-Tf2 tutorial

* lowercase in title in Tf2-Main

* update tutorial time estimation in Adding-A-Frame tutorials

* update depend type in package.xml snippet

* update title Tf2 introduction

* update colon in Time-Travel-With-Tf2

* update text in Writing-A-Tf2-Static-Broadcaster

* move all images to folder and update links
  • Loading branch information
kurshakuz authored Sep 16, 2021
1 parent 0e193f0 commit d2ec42e
Show file tree
Hide file tree
Showing 23 changed files with 196 additions and 146 deletions.
10 changes: 5 additions & 5 deletions source/Tutorials/Tf2/Adding-A-Frame-Cpp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Adding a frame (C++)

**Tutorial level:** Intermediate

**Time:** 10 minutes
**Time:** 15 minutes

.. contents:: Contents
:depth: 3
Expand All @@ -34,7 +34,7 @@ Currently, our tf2 tree contains three frames: ``world``, ``turtle1`` and ``turt
The two turtle frames are children of the ``world`` frame.
If we want to add a new frame to tf2, one of the three existing frames needs to be the parent frame, and the new one will become its child frame.

.. image:: turtlesim_frames.png
.. image:: images/turtlesim_frames.png

Tasks
-----
Expand Down Expand Up @@ -211,7 +211,7 @@ Rebuild the package and start the turtle broadcaster demo:
You should notice that the new ``carrot1`` frame appeared in the transformation tree.

.. image:: turtlesim_frames_carrot.png
.. image:: images/turtlesim_frames_carrot.png

1.4 Checking the results
~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -240,7 +240,7 @@ To do so, open the ``turtle_tf2_fixed_frame_demo.launch.py`` file, and add the `
Now just rebuild the package, restart the ``turtle_tf2_fixed_frame_demo.launch.py``, and you'll see the second turtle following the carrot instead of the first turtle!

.. image:: carrot_static.png
.. image:: images/carrot_static.png

2 Write the dynamic frame broadcaster
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -388,7 +388,7 @@ To test this code, create a new launch file ``turtle_tf2_dynamic_frame_demo.laun

Rebuild the package, and start the ``turtle_tf2_dynamic_frame_demo.launch.py`` launch file, and now you’ll see that the second turtle is following the carrot's position that is constantly changing.

.. image:: carrot_dynamic.png
.. image:: images/carrot_dynamic.png

Summary
-------
Expand Down
92 changes: 74 additions & 18 deletions source/Tutorials/Tf2/Adding-A-Frame-Py.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Adding a frame (Python)

**Tutorial level:** Intermediate

**Time:** 10 minutes
**Time:** 15 minutes

.. contents:: Contents
:depth: 3
Expand All @@ -17,27 +17,24 @@ Background
----------

In previous tutorials, we recreated the turtle demo by writing a :ref:`tf2 broadcaster <WritingATf2BroadcasterPy>` and a :ref:`tf2 listener <WritingATf2ListenerPy>`.
This tutorial will teach you how to add an extra frame to the transformation tree.
This tutorial will teach you how to add extra fixed and dynamic frames to the transformation tree.
In fact, adding a frame in tf2 is very similar to creating the tf2 broadcaster, but this example will show you some additional features of tf2.

1 Why add frames?
^^^^^^^^^^^^^^^^^

For many tasks related to transformations, it is easier to think inside a local frame.
For example, it is easiest to reason about laser scan measurements in a frame at the center of the laser scanner.
tf2 allows you to define a local frame for each sensor, link, or joint in your system.
When transforming from one frame to another, tf2 will take care of all the hidden intermediate frame transformations that are introduced.

2 Where to add frames
^^^^^^^^^^^^^^^^^^^^^
tf2 tree
--------

tf2 builds up a tree structure of frames, and thus does not allow a closed loop in the frame structure.
tf2 builds up a tree structure of frames and, thus, does not allow a closed loop in the frame structure.
This means that a frame only has one single parent, but it can have multiple children.
Currently, our tf2 tree contains three frames: ``world``, ``turtle1`` and ``turtle2``.
The two turtle frames are children of the ``world`` frame.
If we want to add a new frame to tf2, one of the three existing frames needs to be the parent frame, and the new one will become its child frame.

.. image:: turtlesim_frames.png
.. image:: images/turtlesim_frames.png

Tasks
-----
Expand All @@ -49,7 +46,37 @@ In our turtle example, we'll add a new frame ``carrot1``, which will be the chil
This frame will serve as the goal for the second turtle.

Let's first create the source files. Go to the ``learning_tf2_py`` package we created in the previous tutorials.
Fire up your favorite editor and paste the following code into a new file called ``fixed_frame_tf2_broadcaster.py``.
Download the fixed frame broadcaster code by entering the following command:

.. tabs::

.. group-tab:: Linux

.. code-block:: console
wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py
.. group-tab:: macOS

.. code-block:: console
wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py
.. group-tab:: Windows

In a Windows command line prompt:

.. code-block:: console
curl -sk https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py -o fixed_frame_tf2_broadcaster.py
Or in powershell:

.. code-block:: console
curl https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/fixed_frame_tf2_broadcaster.py -o fixed_frame_tf2_broadcaster.py
Now open the file called ``fixed_frame_tf2_broadcaster.py``.

.. code-block:: python
Expand Down Expand Up @@ -150,7 +177,7 @@ With your text editor, create a new file called ``turtle_tf2_fixed_frame_demo.la
])
This launch file first imports the required packages, then creates a ``demo_nodes`` variable that will store nodes that we created in the previous tutorial's launch file.
This launch file imports the required packages and then creates a ``demo_nodes`` variable that will store nodes that we created in the previous tutorial's launch file.

The last part of the code will add our fixed ``carrot1`` frame to the turtlesim world using our ``fixed_frame_tf2_broadcaster`` node.

Expand All @@ -165,21 +192,21 @@ The last part of the code will add our fixed ``carrot1`` frame to the turtlesim
1.3 Build and run
~~~~~~~~~~~~~~~~~

Rebuild the package, and start the turtle broadcaster demo:
Rebuild the package and start the turtle broadcaster demo:

.. code-block:: console
ros2 launch learning_tf2_py turtle_tf2_fixed_frame_demo.launch.py
You should notice that the new ``carrot1`` frame appeared in the transformation tree.

.. image:: turtlesim_frames_carrot.png
.. image:: images/turtlesim_frames_carrot.png

1.4 Checking the results
~~~~~~~~~~~~~~~~~~~~~~~~

If you drive the first turtle around, you should notice that the behavior didn't change from the previous tutorial, even though we added a new frame.
That's because adding an extra frame does not affect the other frames, and our listener is still using the previously defined frames.
That's because adding an extra frame does not affect the other frames and our listener is still using the previously defined frames.

Therefore if we want our second turtle to follow the carrot instead of the first turtle, we need to change value of the ``target_frame``.
This can be done two ways.
Expand All @@ -202,16 +229,45 @@ To do so, open the ``turtle_tf2_fixed_frame_demo.launch.py`` file, and add the `
Now just rebuild the package, restart the ``turtle_tf2_fixed_frame_demo.launch.py``, and you'll see the second turtle following the carrot instead of the first turtle!

.. image:: carrot_static.png
.. image:: images/carrot_static.png

2 Write the dynamic frame broadcaster
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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 so that it changes relative to ``turtle1`` frame over time.
Now download the dynamic frame broadcaster code by entering the following command:

.. tabs::

.. group-tab:: Linux

.. code-block:: console
wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.py
.. group-tab:: macOS

.. code-block:: console
wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.py
.. group-tab:: Windows

In a Windows command line prompt:

.. code-block:: console
curl -sk https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.py -o dynamic_frame_tf2_broadcaster.py
Or in powershell:

.. code-block:: console
curl https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_py/turtle_tf2_py/dynamic_frame_tf2_broadcaster.py -o dynamic_frame_tf2_broadcaster.py
Create the file called ``dynamic_frame_tf2_broadcaster.py``:
Now open the file called ``dynamic_frame_tf2_broadcaster.py``:

.. code-block:: python
Expand Down Expand Up @@ -314,10 +370,10 @@ To test this code, create a new launch file ``turtle_tf2_dynamic_frame_demo.laun

Rebuild the package, and start the ``turtle_tf2_dynamic_frame_demo.launch.py`` launch file, and now you’ll see that the second turtle is following the carrot's position that is constantly changing.

.. image:: carrot_dynamic.png
.. image:: images/carrot_dynamic.png

Summary
-------

In this tutorial, you learned about the tf2 transformation tree, its structure, and its features.
You also learned how to add extra fixed and dynamic frames to tf2.
You also learned that it is easiest to think inside a local frame, and learned to add extra fixed and dynamic frames for that local frame.
4 changes: 2 additions & 2 deletions source/Tutorials/Tf2/Debugging-Tf2-Problems.rst
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ If you like to get a graphical representation of this, use ``view_frames`` tool.
Open the generated ``frames.pdf`` file to see the following output:

.. image:: turtlesim_frames.png
.. image:: images/turtlesim_frames.png

So obviously the problem is that we are requesting transform from frame ``turtle3``, which does not exist.
To fix this bug, just replace ``turtle3`` with ``turtle2`` in line 67.
Expand Down Expand Up @@ -265,7 +265,7 @@ Stop the demo, build and run:
And you should finally see the turtle move!

.. image:: turtlesim_follow1.png
.. image:: images/turtlesim_follow1.png

That last fix we made is not really what you want to do, it was just to make sure that was our problem.
The real fix would look like this:
Expand Down
18 changes: 9 additions & 9 deletions source/Tutorials/Tf2/Introduction-To-Tf2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Introduction to tf2
:depth: 2
:local:

Installing the Demo
Installing the demo
-------------------

Let's start by installing the demo package and its dependencies.
Expand All @@ -39,7 +39,7 @@ Additionally, install a ``transforms3d`` package, which provides the quaternion
pip3 install transforms3d
Running the Demo
Running the demo
----------------

Now that we've installed the ``turtle_tf2_py`` tutorial package let's run the demo.
Expand All @@ -52,7 +52,7 @@ Then run the following command:
You will see the turtlesim start with two turtles.

.. image:: turtlesim_follow1.png
.. image:: images/turtlesim_follow1.png

In the second terminal window type the following command:

Expand All @@ -63,17 +63,17 @@ In the second terminal window type the following command:
Once the turtlesim is started you can drive the central turtle around in the turtlesim using the keyboard arrow keys,
select the second terminal window so that your keystrokes will be captured to drive the turtle.

.. image:: turtlesim_follow2.png
.. image:: images/turtlesim_follow2.png

You can see that one turtle continuously moves to follow the turtle you are driving around.

What is Happening
-----------------
What is happening?
------------------

This demo is using the tf2 library to create three coordinate frames: a ``world`` frame, a ``turtle1`` frame, and a ``turtle2`` frame.
This tutorial uses a tf2 broadcaster to publish the turtle coordinate frames and a tf2 listener to compute the difference in the turtle frames and move one turtle to follow the other.

tf2 Tools
tf2 tools
---------

Now let's look at how tf2 is being used to create this demo.
Expand All @@ -98,7 +98,7 @@ You will see:
Here a tf2 listener is listening to the frames that are being broadcasted over ROS and drawing a tree of how the frames are connected.
To view the tree, open the resulting ``frames.pdf`` with your favorite PDF viewer.

.. image:: turtlesim_frames.png
.. image:: images/turtlesim_frames.png

Here we can see three frames that are broadcasted by tf2: ``world``, ``turtle1``, and ``turtle2``.
The ``world`` here is the parent of the ``turtle1`` and ``turtle2`` frames.
Expand Down Expand Up @@ -146,6 +146,6 @@ Let's start rviz with the ``turtle_rviz.rviz`` configuration file using the `
ros2 run rviz2 rviz2 -d $(ros2 pkg prefix --share turtle_tf2_py)/rviz/turtle_rviz.rviz
.. image:: turtlesim_rviz.png
.. image:: images/turtlesim_rviz.png

In the side bar you will see the frames broadcasted by tf2. As you drive the turtle around you will see the frames move in rviz.
14 changes: 6 additions & 8 deletions source/Tutorials/Tf2/Tf2-Main.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ tf2 Tutorials

Many of the tf2 tutorials are available for both C++ and Python.
The tutorials are streamlined to complete either the C++ track or the Python track.
If you want to learn both C++ and Python, you should go through the tutorials
once for C++ and once for Python.
If you want to learn both C++ and Python, you should go through the tutorials once for C++ and once for Python.

.. contents:: Contents
:depth: 2
Expand All @@ -30,19 +29,18 @@ once for C++ and once for Python.
Time-Travel-With-Tf2-Cpp
Debugging-Tf2-Problems

Workspace Setup
Workspace setup
---------------

If you have not yet created a workspace in which to complete the tutorials,
:ref:`follow this tutorial <ROS2Workspace>`.
If you have not yet created a workspace in which to complete the tutorials, :ref:`follow this tutorial <ROS2Workspace>`.

Learning tf2
------------

#. :ref:`Introduction to tf2 <IntroToTf2>`.

This tutorial will give you a good idea of what tf2 can do for you. It
shows off some of the tf2 power in a multi-robot example using turtlesim.
This tutorial will give you a good idea of what tf2 can do for you.
It shows off some of the tf2 power in a multi-robot example using turtlesim.
This also introduces using ``tf2_echo``, ``view_frames``, and ``rviz``.

#. Writing a tf2 static broadcaster :ref:`(Python) <WritingATf2StaticBroadcasterPy>` :ref:`(C++) <WritingATf2StaticBroadcasterCpp>`.
Expand Down Expand Up @@ -71,7 +69,7 @@ Learning tf2
This tutorial teaches you about advanced time travel features of tf2.

Debugging tf2
--------------
-------------

#. :ref:`Debugging tf2 problems <DebuggingTf2Problems>`.

Expand Down
6 changes: 3 additions & 3 deletions source/Tutorials/Tf2/Time-Travel-With-Tf2-Cpp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ First, let's go back to where we ended in the previous tutorial :ref:`Learning a
Go to your ``learning_tf2_cpp`` package.

Now, instead of making the second turtle go to where the carrot is now, we will make the second turtle go to where the first carrot was 5 seconds ago.
Edit the ``lookupTransform()`` call in ``turtle_tf2_listener.cpp`` file to:
Edit the ``lookupTransform()`` call in ``turtle_tf2_listener.cpp`` file to

.. code-block:: C++

Expand All @@ -48,7 +48,7 @@ But what happens after these 5 seconds? Let's just give it a try:
ros2 launch learning_tf2_cpp turtle_tf2_fixed_frame_demo.launch.py
.. image:: turtlesim_delay1.png
.. image:: images/turtlesim_delay1.png

You should now notice that your turtle is driving around uncontrollably like in this screenshot. Let's try to understand reason behind that behavior.

Expand Down Expand Up @@ -103,7 +103,7 @@ Let's run the simulation again, this time with the advanced time-travel API:
ros2 launch learning_tf2_cpp turtle_tf2_fixed_frame_demo.launch.py
.. image:: turtlesim_delay2.png
.. image:: images/turtlesim_delay2.png

And yes, the second turtle is directed to where the first carrot was 5 seconds ago!

Expand Down
Loading

0 comments on commit d2ec42e

Please sign in to comment.