-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add actions tutorial page Contains action server tutorial in Python and placeholders for other tutorials. Signed-off-by: Jacob Perron <[email protected]> * Break actions tutorials into separate pages Signed-off-by: Jacob Perron <[email protected]> * Fix errors and do some minor refactoring Signed-off-by: Jacob Perron <[email protected]> * Add Actions to tutorials page Signed-off-by: Jacob Perron <[email protected]> * Add doc8 exception for Actions tutorial pages Specifically, ignore an error related to the :linenos: directive. Signed-off-by: Jacob Perron <[email protected]> * Add 'Writing an Action Client' Python tutorial I've included code snippets with highlighting for clarity. Signed-off-by: Jacob Perron <[email protected]> * Fix typo Signed-off-by: Jacob Perron <[email protected]> * Refactor action server tutorial to have similar style Signed-off-by: Jacob Perron <[email protected]> * Minor refactor Signed-off-by: Jacob Perron <[email protected]> * Address review Signed-off-by: Jacob Perron <[email protected]>
- Loading branch information
1 parent
6b3c2ff
commit e06f465
Showing
16 changed files
with
750 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
Actions | ||
======= | ||
|
||
.. contents:: Table of Contents | ||
:depth: 2 | ||
:local: | ||
|
||
About | ||
----- | ||
|
||
Actions are a form of asynchronous communication in ROS. | ||
*Action clients* send goal requests to *action servers*. | ||
*Action servers* send goal feedback and results to *action clients*. | ||
For more detailed information about ROS actions, please refer to the `design article <http://design.ros2.org/articles/actions.html>`__. | ||
|
||
This document contains a list of tutorials related to actions. | ||
For reference, after completing all of the tutorials you should expect to have a ROS package that looks like the package `action_tutorials <https://github.com/ros2/demos/tree/master/action_tutorials>`__. | ||
|
||
Prequisites | ||
----------- | ||
|
||
- `Install ROS (Dashing or later) <../Installation>` | ||
|
||
- `Install colcon <https://colcon.readthedocs.org>`__ | ||
|
||
- Setup a workspace and create a package named ``action_tutorials``: | ||
|
||
Linux / OSX: | ||
|
||
.. code-block:: bash | ||
mkdir -p action_ws/src | ||
cd action_ws/src | ||
ros2 pkg create action_tutorials | ||
Windows: | ||
|
||
.. code-block:: bash | ||
mkdir -p action_ws\src | ||
cd action_ws\src | ||
ros2 pkg create action_tutorials | ||
Tutorials | ||
--------- | ||
|
||
.. toctree:: | ||
:maxdepth: 1 | ||
|
||
Actions/Creating-an-Action | ||
Actions/Writing-an-Action-Server-CPP | ||
Actions/Writing-an-Action-Client-CPP | ||
Actions/Writing-an-Action-Server-Python | ||
Actions/Writing-an-Action-Client-Python |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
Creating an Action | ||
================== | ||
|
||
In this tutorial we look how to define an action in a ROS package. | ||
|
||
Make sure you have satisfied all `prequisites <../Actions>`. | ||
|
||
Defining an Action | ||
------------------ | ||
|
||
Just like in ROS 1, actions are defined in ``.action`` files of the form: | ||
|
||
.. code-block:: bash | ||
# Request | ||
--- | ||
# Result | ||
--- | ||
# Feedback | ||
An action definition is made up of three message definitions separated by ``---``. | ||
An instance of an action is typically referred to as a *goal*. | ||
A *request* message is sent from an action client to an action server initiating a new goal. | ||
A *result* message is sent from an action server to an action client when a goal is done. | ||
*Feedback* messages are periodically sent from an action server to an action client with updates about a goal. | ||
|
||
Say we want to define a new action "Fibonacci" for computing the `Fibonacci sequence <https://en.wikipedia.org/wiki/Fibonacci_number>`__. | ||
|
||
First, create a directory ``action`` in our ROS package. | ||
With your favorite editor, add the file ``action/Fibonacci.action`` with the following content: | ||
|
||
.. code-block:: bash | ||
int32 order | ||
--- | ||
int32[] sequence | ||
--- | ||
int32[] partial_sequence | ||
The goal request is the ``order`` of the Fibonacci sequence we want to compute, the result is the final ``sequence``, and the feedback is the ``partial_sequence`` computed so far. | ||
|
||
Building an Action | ||
------------------ | ||
|
||
Before we can use the new Fibonacci action type in our code, we must pass the definition to the rosidl code generation pipeline. | ||
This is accomplished by adding the following lines to our ``CMakeLists.txt``: | ||
|
||
.. code-block:: cmake | ||
find_package(action_msgs REQUIRED) | ||
find_package(rosidl_default_generators REQUIRED) | ||
rosidl_generate_interfaces(${PROJECT_NAME} | ||
"action/Fibonacci.action" | ||
DEPENDENCIES action_msgs | ||
) | ||
We should also add the required dependencies to our ``package.xml``: | ||
|
||
.. code-block:: xml | ||
<buildtool_depend>rosidl_default_generators</buildtool_depend> | ||
<depend>action_msgs</depend> | ||
<member_of_group>rosidl_interface_packages</member_of_group> | ||
Note, we need to depend on ``action_msgs`` since action definitions include additional metadata (e.g. goal IDs). | ||
|
||
We should now be able to build the package containing the "Fibonacci" action definition: | ||
|
||
.. code-block:: bash | ||
# Change to the root of the workspace (ie. action_ws) | ||
cd ../.. | ||
# Build | ||
colcon build | ||
We're done! | ||
|
||
By convention, action types will be prefixed by their package name and the word ``action``. | ||
So when we want to refer to our new action, it will have the full name ``action_tutorials/action/Fibonacci``. | ||
|
||
We can check that our action built successfully with the command line tool: | ||
|
||
.. code-block:: bash | ||
# Source our workspace | ||
# On Windows: call install/setup.bat | ||
. install/setup.bash | ||
# Check that our action definition exists | ||
ros2 action show action_tutorials/Fibonacci | ||
You should see the Fibonacci action definition printed to the screen. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Writing an Action Client (C++) | ||
============================== | ||
|
||
Coming soon. |
172 changes: 172 additions & 0 deletions
172
source/Tutorials/Actions/Writing-an-Action-Client-Python.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
Writing an Action Client (Python) | ||
================================= | ||
|
||
In this tutorial, we look at implementing an action client in Python. | ||
|
||
Make sure you have satisfied all `prequisites <../Actions>`. | ||
|
||
Sending a Goal | ||
-------------- | ||
|
||
Let's get started! | ||
|
||
To keep things simple, we'll scope this tutorial to a single file. | ||
Open a new file, let's call it ``fibonacci_action_client.py``, and add the following boilerplate code: | ||
|
||
.. literalinclude:: client_0.py | ||
:language: python | ||
:linenos: | ||
:lines: 1,3,6-11,13-22 | ||
|
||
We've defined a class ``FibonacciActionClient`` that is a subclass of ``Node``. | ||
The class is initialized by calling the ``Node`` constructor, naming our node "fibonacci_action_client": | ||
|
||
.. literalinclude:: client_0.py | ||
:language: python | ||
:lines: 11 | ||
|
||
After the class defintion, we define a function ``main()`` that initializes ROS and creates an instance of our ``FibonacciActionClient`` node. | ||
Finally, we call ``main()`` in the entry point of our Python program. | ||
|
||
You can try running the program: | ||
|
||
.. code-block:: bash | ||
python3 fibonacci_action_client.py | ||
It doesn't do anything interesting...yet. | ||
|
||
Let's import and create an action client using the custom action definition from the previous tutorial on `Creating an Action <Creating-an-Action>`. | ||
|
||
.. literalinclude:: client_0.py | ||
:language: python | ||
:linenos: | ||
:lines: 1-12 | ||
:emphasize-lines: 2,5,12 | ||
|
||
At line 12 we create an ``ActionClient`` by passing it three arguments: | ||
|
||
1. a ROS node to add the action client to: ``self``. | ||
2. the type of the action: ``Fibonacci``. | ||
3. the action name: ``'fibonacci'``. | ||
|
||
Our action client will be able to communicate with action servers of the same action name and type. | ||
|
||
Now let's tell the action client to send a goal. | ||
Add a new method ``send_goal()``: | ||
|
||
.. literalinclude:: client_1.py | ||
:language: python | ||
:linenos: | ||
:lines: 8-20 | ||
:emphasize-lines: 7-13 | ||
|
||
We create a new Fibonacci goal message and assign a sequence order. | ||
Before sending the goal message, we must wait for an action server to become available. | ||
Otherwise, a potential action server may miss the goal we're sending. | ||
|
||
Finally, call the ``send_goal`` method with a value: | ||
|
||
.. literalinclude:: client_1.py | ||
:language: python | ||
:linenos: | ||
:lines: 27-32 | ||
:emphasize-lines: 6 | ||
|
||
Let's test our action client by first running an action server built in the tutorial on `Writing an Action Server (Python) <Writing-an-Action-Server-Python>`: | ||
|
||
.. code-block:: bash | ||
ros2 run action_tutorials fibonacci_action_server.py | ||
In another terminal, run the action client: | ||
|
||
.. code-block:: bash | ||
python3 fibonacci_action_client.py | ||
Tada! You should see messages printed by the action server as it successfully executes the goal. | ||
|
||
Getting Feedback | ||
---------------- | ||
|
||
Our action client can send goals. | ||
Nice! | ||
But it would be great if we could get some feedback about the goals we send from the action server. | ||
Easy, let's write a callback function for feedback messsages: | ||
|
||
.. literalinclude:: client_1.py | ||
:language: python | ||
:linenos: | ||
:lines: 8-24 | ||
:emphasize-lines: 15-17 | ||
|
||
In the callback we get the feedback portion of the message and print the ``partial_sequence`` field to the screen. | ||
|
||
We need to register the callback with the action client. | ||
This is achieved by passing the callback to the action client when we send a goal: | ||
|
||
.. literalinclude:: client_2.py | ||
:language: python | ||
:linenos: | ||
:lines: 14-21 | ||
:emphasize-lines: 7 | ||
|
||
You'll notice at this point that our action client is not printing any feedback. | ||
This is because we're missing a call to `rclpy.spin() <http://docs.ros2.org/latest/api/rclpy/api/init_shutdown.html#rclpy.spin>`_ in order to process callbacks on our node. | ||
Let's add it: | ||
|
||
.. literalinclude:: client_2.py | ||
:language: python | ||
:linenos: | ||
:lines: 27-34 | ||
:emphasize-lines: 8 | ||
|
||
We're all set. If we run our action client, you should see feedback being printed to the screen. | ||
|
||
Getting a Result | ||
---------------- | ||
|
||
So we can send a goal, but how do we know when it is completed? | ||
We can get the result information with a couple steps. | ||
First, we need to get a goal handle for the goal we sent. | ||
Then, we can use the goal handle to request the result. | ||
|
||
The `ActionClient.send_goal_async() <http://docs.ros2.org/latest/api/rclpy/api/actions.html#rclpy.action.client.ActionClient.send_goal_async>`_ method returns a future to a goal handle. | ||
Let's register a callback for when the future is complete: | ||
|
||
.. literalinclude:: client_3.py | ||
:language: python | ||
:linenos: | ||
:lines: 8-27 | ||
:emphasize-lines: 13-20 | ||
|
||
|
||
Note, the future is completed when an action server accepts or rejects the goal request. | ||
We can actually check to see if the goal was rejected and return early since we know there will be no result: | ||
|
||
.. literalinclude:: client_3.py | ||
:language: python | ||
:linenos: | ||
:lines: 26-33 | ||
:emphasize-lines: 4-8 | ||
|
||
Now that we've got a goal handle, we can use it to request the result with the method `get_result_async() <http://docs.ros2.org/latest/api/rclpy/api/actions.html#rclpy.action.client.ClientGoalHandle.get_result_async>`_. | ||
Similar to sending the goal, we will get a future that will complete when the result is ready. | ||
Let's register a callback just like we did for the goal response: | ||
|
||
.. literalinclude:: client_3.py | ||
:language: python | ||
:linenos: | ||
:lines: 26-42 | ||
:emphasize-lines: 10-17 | ||
|
||
In the callback, we log the result sequence and shutdown ROS for a clean exit. | ||
|
||
With an action server running in a separate terminal, go ahead and try running our Fibonacci action client! | ||
|
||
.. code-block:: bash | ||
python3 fibonacci_action_client.py | ||
You should see logged messages for the goal being accepted, feedback, and the final result. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Writing an Action Server (C++) | ||
============================== | ||
|
||
Coming soon. |
Oops, something went wrong.