-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add actions tutorial page #169
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
55e1cf2
Add actions tutorial page
jacobperron 6152cbe
Break actions tutorials into separate pages
jacobperron bbfc3ef
Fix errors and do some minor refactoring
jacobperron d63d691
Add Actions to tutorials page
jacobperron f84391b
Add doc8 exception for Actions tutorial pages
jacobperron 01a3270
Add 'Writing an Action Client' Python tutorial
jacobperron ad55b35
Fix typo
jacobperron 6d3ebce
Refactor action server tutorial to have similar style
jacobperron c7ef6e3
Minor refactor
jacobperron 6afcb07
Address review
jacobperron File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This link won't work until the
action_tutorials
package is added.