diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4c3c2ceac60..619e5e5eb0e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,7 +5,7 @@ }, "workspaceMount": "source=${localWorkspaceFolder},target=/tmp/doc_repository,type=bind", "workspaceFolder": "/tmp/doc_repository", - "postCreateCommand": "pip3 install --no-warn-script-location --user -r requirements.txt -c constraints.txt --break-system-packages", + "postCreateCommand": "pip3 install --no-warn-script-location --user -r requirements.txt -c constraints.txt", "features": { "ghcr.io/devcontainers/features/git:1": {} }, diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f1d478c3f61..c287342bbfc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,6 +37,23 @@ jobs: - name: Lint run: make lint + spellcheck: + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install dependencies with pip + run: pip install --no-warn-script-location --user -r requirements.txt -c constraints.txt + + - name: Spellcheck + run: make spellcheck + build: needs: [test, lint] runs-on: ubuntu-22.04 diff --git a/Makefile b/Makefile index 5014099150f..b5d0ece7c46 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,9 @@ lint: test: doc8 --ignore D001 --ignore-path build +spellcheck: + git ls-files '*.md' '*.rst' | xargs codespell --config codespell.cfg + linkcheck: $(BUILD) -b linkcheck $(OPTS) $(SOURCE) $(LINKCHECKDIR) @echo diff --git a/README.md b/README.md index 062f63b4759..3de74eb10be 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,15 @@ For local testing of the current tree use: `sensible-browser build/html/index.html` +### Spelling Check + +To check the spelling, use: + +`make spellcheck` + +> [!NOTE] +> If that detects specific words that need to be ignored, add it to [codespell_whitelist](./codespell_whitelist.txt). + ### Deployment test To test building the multisite version deployed to the website use: diff --git a/codespell.cfg b/codespell.cfg new file mode 100644 index 00000000000..e34631dee88 --- /dev/null +++ b/codespell.cfg @@ -0,0 +1,15 @@ +[codespell] + +# Enable built-in dictionaries/rules. +# See more details for https://github.com/codespell-project/codespell/tree/main/codespell_lib/data. +builtin = clear,rare,informal,code + +# Ignore words listed in this file. +ignore-words = codespell_whitelist.txt + +# Skip checking files in this directory. +# This folder is ignored for a couple of reasons. +# *-Changelog.rst files are generated by commit history that could include some misspellings, +# but we should keep the original commit messages here. +# Besides, it includes names of authors and contributors, which compile up the false alarms. +skip = source/Releases/* diff --git a/codespell_whitelist.txt b/codespell_whitelist.txt new file mode 100644 index 00000000000..918813b83c1 --- /dev/null +++ b/codespell_whitelist.txt @@ -0,0 +1,4 @@ +empy +ws +lets +jupyter diff --git a/docker/image/Dockerfile b/docker/image/Dockerfile index 28ee3e2bea7..7c0988f9090 100644 --- a/docker/image/Dockerfile +++ b/docker/image/Dockerfile @@ -3,7 +3,7 @@ # # docker build -f docker/image/Dockerfile . -FROM ubuntu:noble +FROM ubuntu:jammy ARG user=rosindex ARG uid=1000 diff --git a/requirements.txt b/requirements.txt index 2406de14841..d75e4c9adbf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +codespell doc8 docutils pip diff --git a/source/Concepts/Basic/About-Client-Libraries.rst b/source/Concepts/Basic/About-Client-Libraries.rst index 1079ece209d..9780e0320c7 100644 --- a/source/Concepts/Basic/About-Client-Libraries.rst +++ b/source/Concepts/Basic/About-Client-Libraries.rst @@ -77,7 +77,8 @@ While the C++ and Python client libraries are maintained by the core ROS 2 team, * `C `__ ``rclc`` does not put a layer on top of rcl but complements rcl to make rcl+rclc a feature-complete client library in C. See `micro.ros.org `__ for tutorials. * `JVM and Android `__ Java and Android bindings for ROS 2. * `.NET Core, UWP and C# `__ This is a collection of projects (bindings, code generator, examples and more) for writing ROS 2 applications for .NET Core and .NET Standard. -* `Node.js `__ rclnodejs is a Node.js client for ROS 2. It provides a simple and easy JavaScript API for ROS 2 programming. +* `Node.js `__ rclnodejs is a Node.js client for ROS 2. + It provides a simple and easy JavaScript API for ROS 2 programming. * `Rust `__ This is a set of projects (the rclrs client library, code generator, examples and more) that enables developers to write ROS 2 applications in Rust. * `Flutter and Dart `__ Flutter and Dart bindings for ROS 2. diff --git a/source/Concepts/Basic/About-Interfaces.rst b/source/Concepts/Basic/About-Interfaces.rst index 9c7d5f4677c..ed72f28c0c9 100644 --- a/source/Concepts/Basic/About-Interfaces.rst +++ b/source/Concepts/Basic/About-Interfaces.rst @@ -18,9 +18,13 @@ This description makes it easy for ROS tools to automatically generate source co In this document we will describe the supported types: -* msg: ``.msg`` files are simple text files that describe the fields of a ROS message. They are used to generate source code for messages in different languages. -* srv: ``.srv`` files describe a service. They are composed of two parts: a request and a response. The request and response are message declarations. -* action: ``.action`` files describe actions. They are composed of three parts: a goal, a result, and feedback. +* msg: ``.msg`` files are simple text files that describe the fields of a ROS message. + They are used to generate source code for messages in different languages. +* srv: ``.srv`` files describe a service. + They are composed of two parts: a request and a response. + The request and response are message declarations. +* action: ``.action`` files describe actions. + They are composed of three parts: a goal, a result, and feedback. Each part is a message declaration itself. Messages @@ -207,7 +211,7 @@ For example: Constants ^^^^^^^^^ -Each constant definition is like a field description with a default value, except that this value can never be changed programatically. +Each constant definition is like a field description with a default value, except that this value can never be changed programmatically. This value assignment is indicated by use of an equal '=' sign, e.g. .. code-block:: bash diff --git a/source/Concepts/Basic/About-Parameters.rst b/source/Concepts/Basic/About-Parameters.rst index c1378eb7154..d2f5a00ce65 100644 --- a/source/Concepts/Basic/About-Parameters.rst +++ b/source/Concepts/Basic/About-Parameters.rst @@ -89,11 +89,14 @@ The services that are created by default are: * ``/node_name/get_parameters``: Uses a service type of ``rcl_interfaces/srv/GetParameters``. Given a list of parameter names, returns a list of parameter values associated with the parameters. * ``/node_name/list_parameters``: Uses a service type of ``rcl_interfaces/srv/ListParameters``. - Given an optional list of parameter prefixes, returns a list of the available parameters with that prefix. If the prefixes are empty, returns all parameters. + Given an optional list of parameter prefixes, returns a list of the available parameters with that prefix. + If the prefixes are empty, returns all parameters. * ``/node_name/set_parameters``: Uses a service type of ``rcl_interfaces/srv/SetParameters``. - Given a list of parameter names and values, attempts to set the parameters on the node. Returns a list of results from trying to set each parameter; some of them may have succeeded and some may have failed. + Given a list of parameter names and values, attempts to set the parameters on the node. + Returns a list of results from trying to set each parameter; some of them may have succeeded and some may have failed. * ``/node_name/set_parameters_atomically``: Uses a service type of ``rcl_interfaces/srv/SetParametersAtomically``. - Given a list of parameter names and values, attempts to set the parameters on the node. Returns a single result from trying to set all parameters, so if one failed, all of them failed. + Given a list of parameter names and values, attempts to set the parameters on the node. + Returns a single result from trying to set all parameters, so if one failed, all of them failed. Setting initial parameter values when running a node ---------------------------------------------------- @@ -119,16 +122,4 @@ Migrating from ROS 1 The :doc:`Launch file migration guide <../../How-To-Guides/Migrating-from-ROS1/Migrating-Launch-Files>` explains how to migrate ``param`` and ``rosparam`` launch tags from ROS 1 to ROS 2. -The :doc:`YAML parameter file migration guide <../../How-To-Guides/Migrating-from-ROS1/Migrating-Parameters>` explains how to migrate parameter files from ROS 1 to ROS 2. - -In ROS 1, the ``roscore`` acted like a global parameter blackboard where all nodes could get and set parameters. -Since there is no central ``roscore`` in ROS 2, that functionality no longer exists. -The recommended approach in ROS 2 is to use per-node parameters that are closely tied to the nodes that use them. -If a global blackboard is still needed, it is possible to create a dedicated node for this purpose. -ROS 2 ships with one in the ``ros-{DISTRO}-demo-nodes-cpp`` package called ``parameter_blackboard``; it can be run with: - -.. code-block:: console - - ros2 run demo_nodes_cpp parameter_blackboard - -The code for the ``parameter_blackboard`` is `here `__. +The :doc:`Migration guide <../../How-To-Guides/Migrating-from-ROS1/Migrating-Parameters>` explains how to migrate parameter from ROS 1 to ROS 2. diff --git a/source/Concepts/Basic/About-Topics.rst b/source/Concepts/Basic/About-Topics.rst index 3cd7086a33c..23081a69b03 100644 --- a/source/Concepts/Basic/About-Topics.rst +++ b/source/Concepts/Basic/About-Topics.rst @@ -14,7 +14,7 @@ Publish/Subscribe ----------------- A publish/subscribe system is one in which there are producers of data (publishers) and consumers of data (subscribers). -The publishers and subscribers know how to contact each other through the concept of a "topic", which is a common name so that the entites can find each other. +The publishers and subscribers know how to contact each other through the concept of a "topic", which is a common name so that the entities can find each other. For instance, when you create a publisher, you must also give it a string that is the name of the topic; the same goes for the subscriber. Any publishers and subscribers that are on the same topic name can directly communicate with each other. There may be zero or more publishers and zero or more subscribers on any particular topic. @@ -48,4 +48,7 @@ That has two meanings in this context: Then the code will ensure that ``field1`` is always an unsigned integer and that ``field2`` is always a string. -2. The semantics of each field are well-defined. There is no automated mechanism to ensure this, but all of the core ROS types have strong semantics associated with them. For instance, the IMU message contains a 3-dimensional vector for the measured angular velocity, and each of the dimensions is specified to be in radians/second. Other interpretations should not be placed into the message. +2. The semantics of each field are well-defined. + There is no automated mechanism to ensure this, but all of the core ROS types have strong semantics associated with them. + For instance, the IMU message contains a 3-dimensional vector for the measured angular velocity, and each of the dimensions is specified to be in radians/second. + Other interpretations should not be placed into the message. diff --git a/source/Concepts/Intermediate/About-Cross-Compilation.rst b/source/Concepts/Intermediate/About-Cross-Compilation.rst index 91f1eb743c8..d70eb66e664 100644 --- a/source/Concepts/Intermediate/About-Cross-Compilation.rst +++ b/source/Concepts/Intermediate/About-Cross-Compilation.rst @@ -22,7 +22,9 @@ How does it work ? Cross-compiling simple software (e.g. no dependencies on external libraries) is relatively simple and only requiring a cross-compiler toolchain to be used instead of the native toolchain. There are a number of factors which make this process more complex: - - The software being built must support the target architecture. Architecture specific code must be properly isolated and enabled during the build according to the target architecture. Examples include assembly code. + - The software being built must support the target architecture. + Architecture specific code must be properly isolated and enabled during the build according to the target architecture. + Examples include assembly code. - All dependencies (e.g. libraries) must be present, either as pre-built or cross-compiled packages, before the target software using them is cross-compiled. - When building software stacks (as opposed to standalone software) using build tools (e.g. colcon), it is expected that the build tool provides a mechanism to allow the developer to enable cross-compilation on the underlying build system used by each piece of software in the stack. diff --git a/source/Concepts/Intermediate/About-Different-Middleware-Vendors.rst b/source/Concepts/Intermediate/About-Different-Middleware-Vendors.rst index 8c1b9ae4338..47ad1d950f5 100644 --- a/source/Concepts/Intermediate/About-Different-Middleware-Vendors.rst +++ b/source/Concepts/Intermediate/About-Different-Middleware-Vendors.rst @@ -37,19 +37,24 @@ Supported RMW implementations * - eProsima *Fast DDS* - Apache 2 - ``rmw_fastrtps_cpp`` - - Full support. Default RMW. Packaged with binary releases. + - Full support. + Default RMW. + Packaged with binary releases. * - Eclipse *Cyclone DDS* - Eclipse Public License v2.0 - ``rmw_cyclonedds_cpp`` - - Full support. Packaged with binary releases. + - Full support. + Packaged with binary releases. * - RTI *Connext DDS* - commercial, research - ``rmw_connextdds`` - - Full support. Support included in binaries, but Connext installed separately. + - Full support. + Support included in binaries, but Connext installed separately. * - GurumNetworks *GurumDDS* - commercial - ``rmw_gurumdds_cpp`` - - Community support. Support included in binaries, but GurumDDS installed separately. + - Community support. + Support included in binaries, but GurumDDS installed separately. For practical information on working with multiple RMW implementations, see the :doc:`"Working with multiple RMW implementations" <../../How-To-Guides/Working-with-multiple-RMW-implementations>` tutorial. diff --git a/source/Concepts/Intermediate/About-Executors.rst b/source/Concepts/Intermediate/About-Executors.rst index 49d53b2f10f..72e3e1532da 100644 --- a/source/Concepts/Intermediate/About-Executors.rst +++ b/source/Concepts/Intermediate/About-Executors.rst @@ -169,7 +169,8 @@ The following flow diagram visualizes this scheduling semantics. .. image:: ../images/executors_scheduling_semantics.png This semantics was first described in a `paper by Casini et al. at ECRTS 2019 `_. -(Note: The paper also explains that timer events are prioritized over all other messages. `This prioritization was removed in Eloquent. `_) +(Note: The paper also explains that timer events are prioritized over all other messages. +`This prioritization was removed in Eloquent. `_) Outlook @@ -198,6 +199,12 @@ These issues have been partially addressed by the following developments: Further information ------------------- -* Michael Pöhnl et al.: `"ROS 2 Executor: How to make it efficient, real-time and deterministic?" `_. Workshop at ROS World 2021. Virtual event. 19 October 2021. -* Ralph Lange: `"Advanced Execution Management with ROS 2" `_. ROS Industrial Conference. Virtual event. 16 December 2020. +* Michael Pöhnl et al.: `"ROS 2 Executor: How to make it efficient, real-time and deterministic?" `_. + Workshop at ROS World 2021. + Virtual event. + 19 October 2021. +* Ralph Lange: `"Advanced Execution Management with ROS 2" `_. + ROS Industrial Conference. + Virtual event. + 16 December 2020. * Daniel Casini, Tobias Blass, Ingo Lütkebohle, and Björn Brandenburg: `“Response-Time Analysis of ROS 2 Processing Chains under Reservation-Based Scheduling” `_, Proc. of 31st ECRTS 2019, Stuttgart, Germany, July 2019. diff --git a/source/Concepts/Intermediate/About-RQt.rst b/source/Concepts/Intermediate/About-RQt.rst index 3268b9a5950..b73ff96179a 100644 --- a/source/Concepts/Intermediate/About-RQt.rst +++ b/source/Concepts/Intermediate/About-RQt.rst @@ -56,7 +56,7 @@ RQt Components Structure RQt consists of two metapackages: -* *rqt* - core infrastucture modules. +* *rqt* - core infrastructure modules. * *rqt_common_plugins* - Commonly useful debugging tools. Advantage of RQt framework @@ -72,7 +72,7 @@ Compared to building your own GUIs from scratch: From system architecture's perspective: * Support multi-platform (basically wherever `QT `__ and ROS run) and multi-language (``Python``, ``C++``). -* Manageable lifecycle: RQt plugins using a common API makes maintainance & reuse easier. +* Manageable lifecycle: RQt plugins using a common API makes maintenance & reuse easier. Further Reading diff --git a/source/Contact.rst b/source/Contact.rst index 888aa74160d..8340376e3b5 100644 --- a/source/Contact.rst +++ b/source/Contact.rst @@ -57,9 +57,14 @@ When filing an issue, please make sure to: Describe exactly what you were doing or are trying to do, and exactly what, if anything, went wrong. If following a tutorial or online instructions provide a link to the specific instructions. -* Use a descriptive headline or subject line. Bad: "rviz doesn't work". Good: "Rviz crashing looking for missing .so after latest apt update" -* Include information about the exact platform, software, versions, and environment relevant to the problem. This includes how you installed the software (from binaries or from source) and which ROS middleware/DDS vendor you are using (if you know it). -* Any warnings or errors. Cut and paste them directly from the terminal window to which they were printed. Please do not re-type or include a screenshot. +* Use a descriptive headline or subject line. + Bad: "rviz doesn't work". + Good: "Rviz crashing looking for missing .so after latest apt update" +* Include information about the exact platform, software, versions, and environment relevant to the problem. + This includes how you installed the software (from binaries or from source) and which ROS middleware/DDS vendor you are using (if you know it). +* Any warnings or errors. + Cut and paste them directly from the terminal window to which they were printed. + Please do not re-type or include a screenshot. * In case of a bug consider providing a `short, self contained, correct (compilable), example `__. * When discussing any compiling/linking/installation issues, also provide the compiler version diff --git a/source/Glossary.rst b/source/Glossary.rst index 48e0ad31592..7fa6ecc9343 100644 --- a/source/Glossary.rst +++ b/source/Glossary.rst @@ -8,7 +8,11 @@ Glossary of terms used throughout this documentation: .. glossary:: API - An API, or Application Programming Interface, is an interface that is provided by an "application", which in this case is usually a shared library or other language appropriate shared resource. APIs are made up of files that define a contract between the software using the interface and the software providing the interface. These files typically manifest as header files in C and C++ and as Python files in Python. In either case it is important that APIs are grouped and described in documentation and that they are declared as either public or private. Public interfaces are subject to change rules and changes to the public interfaces prompt a new version number of the software that provides them. + An API, or Application Programming Interface, is an interface that is provided by an "application", which in this case is usually a shared library or other language appropriate shared resource. + APIs are made up of files that define a contract between the software using the interface and the software providing the interface. + These files typically manifest as header files in C and C++ and as Python files in Python. + In either case it is important that APIs are grouped and described in documentation and that they are declared as either public or private. + Public interfaces are subject to change rules and changes to the public interfaces prompt a new version number of the software that provides them. client_library A client library is an :term:`API` that provides access to the ROS graph using primitive middleware concepts like Topics, Services, and Actions. @@ -17,7 +21,8 @@ Glossary of terms used throughout this documentation: A single unit of software, including source code, build system files, documentation, tests, and other associated resources. REP - ROS Enhancement Proposal. A document that describes an enhancement, standardization, or convention for the ROS community. + ROS Enhancement Proposal. + A document that describes an enhancement, standardization, or convention for the ROS community. The associated REP approval process allows the community to iterate on a proposal until some consensus has been made, at which point it can be ratified and implemented, which then becomes documentation. All REPs are viewable from the `REP index `_. @@ -25,7 +30,8 @@ Glossary of terms used throughout this documentation: Version Control System, such as CVS, SVN, git, mercurial, etc... rclcpp - The C++ specific :term:`Client Library ` for ROS. This includes any middleware related APIs as well as the related message generation of C++ data structures based on interface definitions like Messages, Services, and Actions. + The C++ specific :term:`Client Library ` for ROS. + This includes any middleware related APIs as well as the related message generation of C++ data structures based on interface definitions like Messages, Services, and Actions. repository A collection of packages usually managed using a :term:`VCS` like git or mercurial and usually hosted on a site like GitHub or BitBucket. diff --git a/source/How-To-Guides/Ament-CMake-Documentation.rst b/source/How-To-Guides/Ament-CMake-Documentation.rst index bd32615ccc3..97bc8ec40b7 100644 --- a/source/How-To-Guides/Ament-CMake-Documentation.rst +++ b/source/How-To-Guides/Ament-CMake-Documentation.rst @@ -323,7 +323,8 @@ One example of how to do so can be found in the `ament_cmake_lint_cmake document Testing ^^^^^^^ -Ament contains CMake macros to simplify setting up GTests. Call: +Ament contains CMake macros to simplify setting up GTests. +Call: .. code-block:: cmake @@ -341,14 +342,16 @@ The macros have additional parameters: find_package(ament_cmake_gtest REQUIRED) ament_add_gtest(some_test - APPEND_ENV PATH=some/addtional/path/for/testing/resources) + APPEND_ENV PATH=some/additional/path/for/testing/resources) - ``APPEND_LIBRARY_DIRS``: append libraries so that they can be found by the linker at runtime. This can be achieved by setting environment variables like ``PATH`` on Windows and ``LD_LIBRARY_PATH`` on Linux, but this makes the call platform specific. - ``ENV``: set environment variables (same syntax as ``APPEND_ENV``). -- ``TIMEOUT``: set a test timeout in second. The default for GTests is 60 seconds. For example: +- ``TIMEOUT``: set a test timeout in second. + The default for GTests is 60 seconds. + For example: .. code-block:: cmake @@ -550,7 +553,8 @@ For the RViz mesh resource, the corresponding choices were: - ``rviz_ogre_media_exports`` as name of the resource, -- install path relative paths to all folders containing resources. This will already enable you to write the logic for using the corresponding resource in your package. +- install path relative paths to all folders containing resources. + This will already enable you to write the logic for using the corresponding resource in your package. To allow users to easily register resources for your package, you should furthermore provide macros or functions such as the pluginlib function or ``rviz_ogre_media_exports`` function. diff --git a/source/How-To-Guides/Ament-CMake-Python-Documentation.rst b/source/How-To-Guides/Ament-CMake-Python-Documentation.rst index ccb1bcf9283..34eceaf8156 100644 --- a/source/How-To-Guides/Ament-CMake-Python-Documentation.rst +++ b/source/How-To-Guides/Ament-CMake-Python-Documentation.rst @@ -63,8 +63,8 @@ In this case, it is ``my_project``, or ``${PROJECT_NAME}``. .. warning:: Calling ``rosidl_generate_interfaces`` and ``ament_python_install_package`` in the same CMake project does not work. - See this `Github issue `_ for more info. It is best practice to instead - separate out the message generation into a separate package. + See this `Github issue `_ for more info. + It is best practice to instead separate out the message generation into a separate package. Then, another Python package that correctly depends on ``my_project`` can use it as a normal Python module: diff --git a/source/How-To-Guides/Core-maintainer-guide.rst b/source/How-To-Guides/Core-maintainer-guide.rst index 504673c3069..6743129ec8c 100644 --- a/source/How-To-Guides/Core-maintainer-guide.rst +++ b/source/How-To-Guides/Core-maintainer-guide.rst @@ -6,7 +6,7 @@ ROS 2 Core Maintainer Guide =========================== -Each package in the ROS 2 core has one or more maintainers that are responsibile for the general health of the package. +Each package in the ROS 2 core has one or more maintainers that are responsible for the general health of the package. This guide gives some information about the responsibilities of a ROS 2 core package maintainer. .. contents:: Table of Contents diff --git a/source/How-To-Guides/DDS-tuning.rst b/source/How-To-Guides/DDS-tuning.rst index 79014a6b238..e2c0f7c1843 100644 --- a/source/How-To-Guides/DDS-tuning.rst +++ b/source/How-To-Guides/DDS-tuning.rst @@ -163,7 +163,8 @@ However, it always at least managed to complete the delivery. **Solution:** Use the `Connext QoS profile `_ *without* adjusting ``rmem_max``. -The ROS2TEST_QOS_PROFILES.xml file was configured using RTI’s documentation on `configuring flow controllers `_. It has slow, medium and fast flow controllers (seen in the Connext QoS profile link). +The ROS2TEST_QOS_PROFILES.xml file was configured using RTI’s documentation on `configuring flow controllers `_. +It has slow, medium and fast flow controllers (seen in the Connext QoS profile link). The medium flow controller produced the best results for our case. However, the controllers will still need to be tuned for the particular machine/network/environment they are operating in. diff --git a/source/How-To-Guides/Getting-Backtraces-in-ROS-2.rst b/source/How-To-Guides/Getting-Backtraces-in-ROS-2.rst index 401fa7ee9fb..2ec9f357a14 100755 --- a/source/How-To-Guides/Getting-Backtraces-in-ROS-2.rst +++ b/source/How-To-Guides/Getting-Backtraces-in-ROS-2.rst @@ -232,7 +232,7 @@ We will insert the GDB snippet here. prefix=['xterm -e gdb -ex run --args'] -This will provide a more interactive debbuging experience. +This will provide a more interactive debugging experience. Example usecase for debugging building upon ``'start_sync_slam_toolbox_node'`` - .. code-block:: python diff --git a/source/How-To-Guides/Installation-Troubleshooting.rst b/source/How-To-Guides/Installation-Troubleshooting.rst index e346b7bcfc6..459a9322a46 100644 --- a/source/How-To-Guides/Installation-Troubleshooting.rst +++ b/source/How-To-Guides/Installation-Troubleshooting.rst @@ -51,7 +51,7 @@ then you will need to update your firewall configuration to allow multicast usin sudo ufw allow in proto udp from 224.0.0.0/4 -You can check if the multicast flag is enabled for your network interface using the :code:`ifconfig` tool and looking for :code:`MULITCAST` in the flags section: +You can check if the multicast flag is enabled for your network interface using the :code:`ifconfig` tool and looking for :code:`MULTICAST` in the flags section: .. code-block:: bash @@ -66,7 +66,8 @@ If so, compare the libraries present in the directory with the one mentioned in Assuming a file with a similar name exists (same prefix like ``_rclpy.`` and same suffix like ``.so`` but a different Python version / architecture) you are using a different Python interpreter than which was used to build the C extension. Be sure to use the same Python interpreter as the one used to build the binary. -For example, such a mismatch can crop up after an update of the OS. Then, rebuilding the workspace may fix the issue. +For example, such a mismatch can crop up after an update of the OS. +Then, rebuilding the workspace may fix the issue. .. _linux-troubleshooting: @@ -242,7 +243,7 @@ To resolve this error, you will need to: rosdep install error ``homebrew: Failed to detect successful installation of [qt5]`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -While following the :doc:`Creating a workspace <../Tutorials/Beginner-Client-Libraries/Creating-A-Workspace/Creating-A-Workspace>` tutorial, you might encounter the following error stating that ``rosdep`` failes to install Qt5. +While following the :doc:`Creating a workspace <../Tutorials/Beginner-Client-Libraries/Creating-A-Workspace/Creating-A-Workspace>` tutorial, you might encounter the following error stating that ``rosdep`` fails to install Qt5. .. code-block:: bash @@ -289,7 +290,8 @@ Use this information to install additional dependencies or adjust your path as n CMake error setting modification time ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If you run into the CMake error ``file INSTALL cannot set modification time on ...`` when installing files it is likely that an anti virus software or Windows Defender are interfering with the build. E.g. for Windows Defender you can list the workspace location to be excluded to prevent it from scanning those files. +If you run into the CMake error ``file INSTALL cannot set modification time on ...`` when installing files it is likely that an anti virus software or Windows Defender are interfering with the build. +E.g. for Windows Defender you can list the workspace location to be excluded to prevent it from scanning those files. 260 character path limit ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -323,7 +325,8 @@ patch.exe opens a new command window and asks for administrator This will also cause the build of packages which need to use patch to fail, even you allow it to use administrator rights. -- ``choco uninstall patch; colcon build --cmake-clean-cache`` - This is a bug in the `GNU Patch For Windows package `_. If this package is not installed, the build process will instead use the version of Patch distributed with git. +- ``choco uninstall patch; colcon build --cmake-clean-cache`` - This is a bug in the `GNU Patch For Windows package `_. + If this package is not installed, the build process will instead use the version of Patch distributed with git. Failed to load Fast RTPS shared library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/source/How-To-Guides/Installing-on-Raspberry-Pi.rst b/source/How-To-Guides/Installing-on-Raspberry-Pi.rst index 9ee39dcbac7..a774526819a 100644 --- a/source/How-To-Guides/Installing-on-Raspberry-Pi.rst +++ b/source/How-To-Guides/Installing-on-Raspberry-Pi.rst @@ -29,7 +29,8 @@ After flashing the OS, `install Docker `__. -You may choose from ros-core, ros-base, or perception. See `here `__ for more information on these variants. +You may choose from ros-core, ros-base, or perception. +See `here `__ for more information on these variants. Fetch and run an image: diff --git a/source/How-To-Guides/Migrating-from-ROS1/Migrating-CPP-Package-Example.rst b/source/How-To-Guides/Migrating-from-ROS1/Migrating-CPP-Package-Example.rst index 5cdb8ff0ccf..f380f55e3b8 100644 --- a/source/How-To-Guides/Migrating-from-ROS1/Migrating-CPP-Package-Example.rst +++ b/source/How-To-Guides/Migrating-from-ROS1/Migrating-CPP-Package-Example.rst @@ -204,13 +204,13 @@ Change the publish call to use the ``->`` operator instead of ``.``. chatter_pub->publish(msg); Spinning (i.e., letting the communications system process any pending -incoming/outgoing messages) is different in that the call now takes the node as -an argument: +incoming/outgoing messages until no more work is available) is different +in that the call now takes the node and timeout as arguments: .. code-block:: cpp // ros::spinOnce(); - rclcpp::spin_some(node); + rclcpp::spin_all(node, 0s); Sleeping using the rate object is unchanged. @@ -218,11 +218,15 @@ Putting it all together, the new ``talker.cpp`` looks like this: .. code-block:: cpp + #include #include // #include "ros/ros.h" #include "rclcpp/rclcpp.hpp" // #include "std_msgs/String.h" #include "std_msgs/msg/string.hpp" + + using namespace std::chrono_literals; + int main(int argc, char **argv) { // ros::init(argc, argv, "talker"); @@ -247,7 +251,7 @@ Putting it all together, the new ``talker.cpp`` looks like this: // chatter_pub.publish(msg); chatter_pub->publish(msg); // ros::spinOnce(); - rclcpp::spin_some(node); + rclcpp::spin_all(node, 0s); loop_rate.sleep(); } return 0; diff --git a/source/How-To-Guides/Migrating-from-ROS1/Migrating-CPP-Packages.rst b/source/How-To-Guides/Migrating-from-ROS1/Migrating-CPP-Packages.rst index 94e099bed5a..ac6b5655a18 100644 --- a/source/How-To-Guides/Migrating-from-ROS1/Migrating-CPP-Packages.rst +++ b/source/How-To-Guides/Migrating-from-ROS1/Migrating-CPP-Packages.rst @@ -109,7 +109,7 @@ If your ``CMakeLists.txt`` uses ``include_directories()``, then delete those cal # Delete calls to include_directories like this one! include_directories(include ${catkin_INCLUDE_DIRS}) -Add a call ``target_include_directories()`` for every library in your pacakage (`example `__). +Add a call ``target_include_directories()`` for every library in your package (`example `__). .. code-block:: cmake diff --git a/source/How-To-Guides/Migrating-from-ROS1/Migrating-Launch-Files.rst b/source/How-To-Guides/Migrating-from-ROS1/Migrating-Launch-Files.rst index 24212f46c93..6d00fc71147 100644 --- a/source/How-To-Guides/Migrating-from-ROS1/Migrating-Launch-Files.rst +++ b/source/How-To-Guides/Migrating-from-ROS1/Migrating-Launch-Files.rst @@ -314,7 +314,7 @@ New tags in ROS 2 set_env and unset_env ^^^^^^^^^^^^^^^^^^^^^ -See `env`_ tag decription. +See `env`_ tag description. push_ros_namespace ^^^^^^^^^^^^^^^^^^ diff --git a/source/How-To-Guides/Migrating-from-ROS1/Migrating-Parameters.rst b/source/How-To-Guides/Migrating-from-ROS1/Migrating-Parameters.rst index ac07b2faf0e..af99c20e596 100644 --- a/source/How-To-Guides/Migrating-from-ROS1/Migrating-Parameters.rst +++ b/source/How-To-Guides/Migrating-from-ROS1/Migrating-Parameters.rst @@ -18,10 +18,25 @@ In ROS 2, parameters are associated per node and are configurable at runtime wit * See :doc:`ROS 2 CLI usage <../../Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Parameters/Understanding-ROS2-Parameters>` for a better understanding of how the CLI tools work and its differences with ROS 1 tooling. +Global Parameter Server +----------------------- + +In ROS 1, the ``roscore`` acted like a global parameter blackboard where all nodes could get and set parameters. +Since there is no central ``roscore`` in ROS 2, that functionality no longer exists. +The recommended approach in ROS 2 is to use per-node parameters that are closely tied to the nodes that use them. +If a global blackboard is still needed, it is possible to create a dedicated node for this purpose. +ROS 2 ships with one in the ``ros-{DISTRO}-demo-nodes-cpp`` package called ``parameter_blackboard``; it can be run with: + +.. code-block:: console + + ros2 run demo_nodes_cpp parameter_blackboard + +The code for the ``parameter_blackboard`` is `here `__. + Migrating YAML Parameter Files ------------------------------ -This guide describes how to adapt ROS 1 parameters files for ROS 2. +This guide describes how to adapt ROS 1 parameters files for ROS 2 and illustrates the difference in the way parameters can be accessed from the node level. YAML file example ^^^^^^^^^^^^^^^^^ @@ -60,6 +75,13 @@ We would construct our ROS 2 parameters file as follows: Note the use of wildcards (``/**``) to indicate that the parameter ``debug`` should be set on any node in any namespace. +Accessing parameters inside node +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Let's say we want to use ``lidar_name`` parameter inside C++/Python node. +In ROS 1, we used slashes to separate node name and namespaces - ``"lidar_ns/lidar_node_name/lidar_name"``. +In ROS 2, we use dots instead of slashes - ``"lidar_ns.lidar_node_name.lidar_name"``. + Feature parity ^^^^^^^^^^^^^^ @@ -67,3 +89,13 @@ Some features of ROS 1 parameters files do not exist in ROS 2: - Mixed types in a list is not supported yet (`related issue `_) - ``deg`` and ``rad`` substitutions are not supported + + +Parameter Atomic Operation +-------------------------- + +When migrating parameter groups from ROS 1 to ROS 2, there are important differences to consider. +In ROS 1, ``dynamic_reconfigure`` handles parameter groups atomically, meaning all parameters in a reconfiguration request are processed together in a single callback. +In ROS 2, the ``set_parameters`` service processes each parameter individually, which may lead to multiple callback invocations. +To maintain atomic behavior when migrating from ``dynamic_reconfigure``, use the ``set_parameters_atomically`` service, which validates and applies all parameters as a single operation. +If any parameter fails validation, no parameters will be updated. diff --git a/source/How-To-Guides/Migrating-from-ROS1/Migrating-Python-Package-Example.rst b/source/How-To-Guides/Migrating-from-ROS1/Migrating-Python-Package-Example.rst index 81f23a2d191..47e006a8919 100644 --- a/source/How-To-Guides/Migrating-from-ROS1/Migrating-Python-Package-Example.rst +++ b/source/How-To-Guides/Migrating-from-ROS1/Migrating-Python-Package-Example.rst @@ -485,7 +485,7 @@ Remove the statement that imports ``rospy``. # Remove this import rospy -Rplace it with a statement that imports ``rclpy``. +Replace it with a statement that imports ``rclpy``. .. code-block:: Python @@ -807,7 +807,7 @@ Echo the message published by the node in the third terminal: You should see messages with the current time being published in the second terminal, and those same messages received in the third. -Refactor code to use ROS 2 convensions +Refactor code to use ROS 2 conventions -------------------------------------- You have successfully migrated a ROS 1 Python package to ROS 2! diff --git a/source/How-To-Guides/Node-arguments.rst b/source/How-To-Guides/Node-arguments.rst index d7c73f5c5fc..e0d4751c43c 100644 --- a/source/How-To-Guides/Node-arguments.rst +++ b/source/How-To-Guides/Node-arguments.rst @@ -125,6 +125,27 @@ As an example, save the following as ``demo_params.yaml``: some_integers: [1, 2, 3, 4] some_doubles : [3.14, 2.718] + /**: + ros__parameters: + wildcard_full: "Full wildcard for any namespaces and any node names" + + /**/parameter_blackboard: + ros__parameters: + wildcard_namespace: "Wildcard for a specific node name under any namespace" + + /*: + ros__parameters: + wildcard_nodename_root_namespace: "Wildcard for any node names, but only in root namespace" + + +.. note:: + + Wildcards can be used for node names and namespaces. + ``*`` matches a single token delimited by slashes (``/``). + ``**`` matches zero or more tokens delimited by slashes. + Partial matches are not allowed (e.g. ``foo*``). + + Then either declare the parameters within your node with `declare_parameter `__ or `declare_parameters `__, or `set the node to automatically declare parameters `__ if they were passed in via a command line override. Then run the following: @@ -148,3 +169,6 @@ Other nodes will be able to retrieve the parameter values, e.g.: some_lists.some_doubles some_lists.some_integers use_sim_time + wildcard_full + wildcard_namespace + wildcard_nodename_root_namespace diff --git a/source/How-To-Guides/ROS-2-IDEs.rst b/source/How-To-Guides/ROS-2-IDEs.rst index 157a80603b6..99fb66a4b4c 100644 --- a/source/How-To-Guides/ROS-2-IDEs.rst +++ b/source/How-To-Guides/ROS-2-IDEs.rst @@ -47,7 +47,8 @@ So: #. Create your ROS workspace as you would normally. #. In a terminal, source both ROS 2 and your install (if it was built already). -#. Start VSCode from the same command line. The terminal will be blocked until the application is closed again. +#. Start VSCode from the same command line. + The terminal will be blocked until the application is closed again. .. tabs:: @@ -172,7 +173,8 @@ Instead, some settings need to be tweaked. #. Create your ROS workspace as you would normally. #. Start PyCharm normally. -#. Open a project. This should be the root directory of the ROS node you're developing, e.g. ``C:\dev_ws\src\my_node``. +#. Open a project. + This should be the root directory of the ROS node you're developing, e.g. ``C:\dev_ws\src\my_node``. #. Click "Add new interpreter" > "Add local interpreter...". Select a system interpreter (or virtual environment if you're using one) and select the executable of your ROS Python version (typically ``C:\Python38\python.exe``). diff --git a/source/How-To-Guides/Releasing/First-Time-Release.rst b/source/How-To-Guides/Releasing/First-Time-Release.rst index b5c146625ca..351a3c9712a 100644 --- a/source/How-To-Guides/Releasing/First-Time-Release.rst +++ b/source/How-To-Guides/Releasing/First-Time-Release.rst @@ -114,6 +114,13 @@ You should respond to the prompts as following: Bloom will automatically create a pull request for you against `rosdistro `_. +.. note:: + + By default, bloom will release all packages in the source repository. + To selectively block the release of some packages for a particular ``{DISTRO}``, add ``{DISTRO}.ignored`` files to the ``master``` branch of the release repository. + In each file, list the name of the package, one per line, to block the release of the package. + The `rosidl-release `_ repository may serve as a useful reference for this configuration. + Next Steps ---------- diff --git a/source/How-To-Guides/Releasing/Index-Your-Packages.rst b/source/How-To-Guides/Releasing/Index-Your-Packages.rst index 2249586273f..4a1716ff195 100644 --- a/source/How-To-Guides/Releasing/Index-Your-Packages.rst +++ b/source/How-To-Guides/Releasing/Index-Your-Packages.rst @@ -70,9 +70,15 @@ For each ROS distribution you want to release into: Here's how to fill out each item: -* YOUR-REPO-NAME: This is an arbitrary human-readable name. For repos hosted on GitHub, use the lowercase name of your repository not including the organization. For example, the repository name of ``https://github.com/ros2/rosidl`` is ``rosidl``. -* YOUR-GIT-REPO-URL: This is the https URL from which one could ``git clone`` your repository. For example, the git repo URL of ``https://github.com/ros2/rosidl`` is ``https://github.com/ros2/rosidl.git``. It is important that this URL ends in ``.git``, or it will fail to pass the linters. -* YOUR-BRANCH-NAME: This is the git branch on your repository from which you will release your package into this ROS distribution. This is commonly one of: ``main``, ``master``, or the name of the ROS distribution itself. For example, the `rosidl repository `__ uses the branch ``rolling`` to hold changes to be released into ROS Rolling. +* YOUR-REPO-NAME: This is an arbitrary human-readable name. + For repos hosted on GitHub, use the lowercase name of your repository not including the organization. + For example, the repository name of ``https://github.com/ros2/rosidl`` is ``rosidl``. +* YOUR-GIT-REPO-URL: This is the https URL from which one could ``git clone`` your repository + For example, the git repo URL of ``https://github.com/ros2/rosidl`` is ``https://github.com/ros2/rosidl.git``. + It is important that this URL ends in ``.git``, or it will fail to pass the linters. +* YOUR-BRANCH-NAME: This is the git branch on your repository from which you will release your package into this ROS distribution. + This is commonly one of: ``main``, ``master``, or the name of the ROS distribution itself. + For example, the `rosidl repository `__ uses the branch ``rolling`` to hold changes to be released into ROS Rolling. * YOUR-STATUS: This is a status from the list in `REP 141 `__. You likely want either ``maintained`` or ``developed``. Open a pull request to ros/rosdistro diff --git a/source/How-To-Guides/Releasing/Subsequent-Releases.rst b/source/How-To-Guides/Releasing/Subsequent-Releases.rst index 34d99ea1e9a..767ffc264b6 100644 --- a/source/How-To-Guides/Releasing/Subsequent-Releases.rst +++ b/source/How-To-Guides/Releasing/Subsequent-Releases.rst @@ -54,6 +54,13 @@ Run the following command, replacing ``my_repo`` with the name of your repositor Bloom will automatically create a pull request for you against `rosdistro `_. +.. note:: + + By default, bloom will release all packages in the source repository. + To selectively block the release of some packages for a particular ``{DISTRO}``, add ``{DISTRO}.ignored`` files to the ``master``` branch of the release repository. + In each file, list the name of the package, one per line, to block the release of the package. + The `rosidl-release `_ repository may serve as a useful reference for this configuration. + Next Steps ---------- diff --git a/source/How-To-Guides/Run-2-nodes-in-single-or-separate-docker-containers.rst b/source/How-To-Guides/Run-2-nodes-in-single-or-separate-docker-containers.rst index b327094d8fb..717ec107ab5 100644 --- a/source/How-To-Guides/Run-2-nodes-in-single-or-separate-docker-containers.rst +++ b/source/How-To-Guides/Run-2-nodes-in-single-or-separate-docker-containers.rst @@ -58,13 +58,15 @@ Run a minimal example of 2 C++ nodes (1 topic subscriber ``listener``, 1 topic p Run two nodes in two separate docker containers ----------------------------------------------- -Open a terminal. Run the image in a container in interactive mode and launch a topic publisher (executable ``talker`` from the package ``demo_nodes_cpp``) with ``ros2 run``: +Open a terminal. +Run the image in a container in interactive mode and launch a topic publisher (executable ``talker`` from the package ``demo_nodes_cpp``) with ``ros2 run``: .. code-block:: bash docker run -it --rm osrf/ros:{DISTRO}-desktop ros2 run demo_nodes_cpp talker -Open a second terminal. Run the image in a container in interactive mode and launch a topic subscriber (executable ``listener`` from the package ``demo_nodes_cpp``) with ``ros2 run``: +Open a second terminal. +Run the image in a container in interactive mode and launch a topic subscriber (executable ``listener`` from the package ``demo_nodes_cpp``) with ``ros2 run``: .. code-block:: bash diff --git a/source/How-To-Guides/Setup-ROS-2-with-VSCode-and-Docker-Container.rst b/source/How-To-Guides/Setup-ROS-2-with-VSCode-and-Docker-Container.rst index 7d21be7f956..75b58914e97 100644 --- a/source/How-To-Guides/Setup-ROS-2-with-VSCode-and-Docker-Container.rst +++ b/source/How-To-Guides/Setup-ROS-2-with-VSCode-and-Docker-Container.rst @@ -201,7 +201,8 @@ Open and Build Development Container Use ``View->Command Palette...`` or ``Ctrl+Shift+P`` to open the command palette. Search for the command ``Dev Containers: Reopen in Container`` and execute it. -This will build your development docker container for your. It will take a while - sit back or go for a coffee. +This will build your development docker container for your. +It will take a while - sit back or go for a coffee. Test Container diff --git a/source/How-To-Guides/Topics-Services-Actions.rst b/source/How-To-Guides/Topics-Services-Actions.rst index 1c1bbdfb421..dc37818d99c 100644 --- a/source/How-To-Guides/Topics-Services-Actions.rst +++ b/source/How-To-Guides/Topics-Services-Actions.rst @@ -14,14 +14,18 @@ This is written to provide the reader with guidelines about when to use each typ Topics ------ -* Should be used for continuous data streams (sensor data, robot state, ...). -* Are for continuous data flow. Data might be published and subscribed at any time independent of any senders/receivers. Many to many connection. Callbacks receive data once it is available. The publisher decides when data is sent. +* Should be used for continuous data streams (sensor data, robot state, ...) +* Are for continuous data flow. + Data might be published and subscribed at any time independent of any senders/receivers. + Many to many connection. + Callbacks receive data once it is available. + The publisher decides when data is sent. Services -------- -* Should be used for remote procedure calls that terminate quickly, e.g. for querying the state of a node or doing a quick calculation such as IK. They should never be used for longer running processes, in particular processes that might be required to preempt if exceptional situations occur and they should never change or depend on state to avoid unwanted side effects for other nodes. -* Simple blocking call. Mostly used for comparably fast tasks as requesting specific data. Semantically for processing requests. +* Should be used for remote procedure calls that terminate quickly, e.g. for querying the state of a node or doing a quick calculation such as IK. + They should never be used for longer running processes, in particular processes that might be required to preempt if exceptional situations occur and they should never change or depend on state to avoid unwanted side effects for other nodes. Actions ------- @@ -30,4 +34,6 @@ Actions * The most important property of actions is that they can be preempted and preemption should always be implemented cleanly by action servers. * Actions can keep state for the lifetime of a goal, i.e. if executing two action goals in parallel on the same server, for each client a separate state instance can be kept since the goal is uniquely identified by its id. * Slow perception routines which take several seconds to terminate or initiating a lower-level control mode are good use cases for actions. -* More complex non-blocking background processing. Used for longer tasks like execution of robot actions. Semantically for real-world actions. +* More complex non-blocking background processing. + Used for longer tasks like execution of robot actions. + Semantically for real-world actions. diff --git a/source/How-To-Guides/Using-Python-Packages.rst b/source/How-To-Guides/Using-Python-Packages.rst index da313b93ae7..27a750d7cba 100644 --- a/source/How-To-Guides/Using-Python-Packages.rst +++ b/source/How-To-Guides/Using-Python-Packages.rst @@ -23,7 +23,8 @@ Using Python Packages with ROS 2 Installing via ``rosdep`` ------------------------- -The fastest way to include third-party python packages is to use their corresponding rosdep keys, if available. ``rosdep`` keys can be checked via: +The fastest way to include third-party python packages is to use their corresponding rosdep keys, if available. +``rosdep`` keys can be checked via: * https://github.com/ros/rosdistro/blob/master/rosdep/base.yaml * https://github.com/ros/rosdistro/blob/master/rosdep/python.yaml diff --git a/source/How-To-Guides/Using-Variants.rst b/source/How-To-Guides/Using-Variants.rst index 485d957f56e..12a680e4710 100644 --- a/source/How-To-Guides/Using-Variants.rst +++ b/source/How-To-Guides/Using-Variants.rst @@ -1,7 +1,7 @@ Using variants ============== -Metapackages do not provide software directly but depend on a group of other related packages to provide a convienent installation mechanism for the complete group of packages. [#]_ [#]_ +Metapackages do not provide software directly but depend on a group of other related packages to provide a convenient installation mechanism for the complete group of packages. [#]_ [#]_ Variants are a list of official metapackages for commonly useful groups of ROS packages. .. [#] https://wiki.debian.org/metapackage diff --git a/source/How-To-Guides/Using-ros2-param.rst b/source/How-To-Guides/Using-ros2-param.rst index 9351ce614f0..1f496ba10b2 100644 --- a/source/How-To-Guides/Using-ros2-param.rst +++ b/source/How-To-Guides/Using-ros2-param.rst @@ -64,7 +64,7 @@ This can be worked around by using the YAML syntax for explicitly setting string ros param set /my_node my_string '!!str off' Additionally, YAML supports heterogeneous lists, containing (say) a string, a boolean, and an integer. -However, ROS 2 parameters do not support heterogenous lists, so any YAML list that has multiple types will be interpreted as a string. +However, ROS 2 parameters do not support heterogeneous lists, so any YAML list that has multiple types will be interpreted as a string. Assuming that the parameter ``my_int_array`` on node ``my_node`` is of type integer array, the following will not work: .. code-block:: console diff --git a/source/How-To-Guides/Working-with-multiple-RMW-implementations.rst b/source/How-To-Guides/Working-with-multiple-RMW-implementations.rst index 78ee1a32461..a25fc367f4f 100644 --- a/source/How-To-Guides/Working-with-multiple-RMW-implementations.rst +++ b/source/How-To-Guides/Working-with-multiple-RMW-implementations.rst @@ -21,7 +21,8 @@ You should have already read the :doc:`DDS and ROS middleware implementations pa Specifying RMW implementations ------------------------------ -To have multiple RMW implementations available for use you must have installed the ROS 2 binaries and any additional dependencies for specific RMW implementations, or built ROS 2 from source with multiple RMW implementations in the workspace (the RMW implementations are included in the build by default if their compile-time dependencies are met). See :doc:`Install DDS implementations <../Installation/DDS-Implementations>`. +To have multiple RMW implementations available for use you must have installed the ROS 2 binaries and any additional dependencies for specific RMW implementations, or built ROS 2 from source with multiple RMW implementations in the workspace (the RMW implementations are included in the build by default if their compile-time dependencies are met). +See :doc:`Install DDS implementations <../Installation/DDS-Implementations>`. ---- @@ -79,7 +80,8 @@ Troubleshooting Checking the Current RMW ^^^^^^^^^^^^^^^^^^^^^^^^ -To check the RMW that is currently in use you simply check the ``RMW_IMPLEMENTATION`` environment variable. On Linux systems ``printenv`` prints the full list of environment variables. +To check the RMW that is currently in use you simply check the ``RMW_IMPLEMENTATION`` environment variable. +On Linux systems ``printenv`` prints the full list of environment variables. Other operating systems will have other procedures for viewing environment variables. If ``RMW_IMPLEMENTATION`` is not in the environment it is safe to assume you are using the default for your ROS distro, otherwise the current RMW is the value listed. The default RMW for each ROS Distro can be found in `REP-2000 `_. @@ -140,7 +142,8 @@ If you receive an error message similar to below when running RTI Connext on OSX [D0062|ENABLE]DDS_DomainParticipantPresentation_reserve_participant_index_entryports:!enable reserve participant index [D0062|ENABLE]DDS_DomainParticipant_reserve_participant_index_entryports:Unusable shared memory transport. For a more in- depth explanation of the possible problem and solution, please visit https://community.rti.com/kb/osx510. -This error is caused by an insufficient number or size of shared memory segments allowed by the operating system. As a result, the ``DomainParticipant`` is unable to allocate enough resources and calculate its participant index which causes the error. +This error is caused by an insufficient number or size of shared memory segments allowed by the operating system. +As a result, the ``DomainParticipant`` is unable to allocate enough resources and calculate its participant index which causes the error. You can increase the shared memory resources of your machine either temporarily or permanently. diff --git a/source/Installation/Alternatives/RHEL-Development-Setup.rst b/source/Installation/Alternatives/RHEL-Development-Setup.rst index 57d77d39168..e14c3898cac 100644 --- a/source/Installation/Alternatives/RHEL-Development-Setup.rst +++ b/source/Installation/Alternatives/RHEL-Development-Setup.rst @@ -64,7 +64,6 @@ Install development tools python3-colcon-common-extensions \ python3-mypy \ python3-pip \ - python3-pydocstyle \ python3-pytest \ python3-pytest-cov \ python3-pytest-mock \ diff --git a/source/Installation/Alternatives/RHEL-Install-Binary.rst b/source/Installation/Alternatives/RHEL-Install-Binary.rst index 5a64eb58073..e53e09c70de 100644 --- a/source/Installation/Alternatives/RHEL-Install-Binary.rst +++ b/source/Installation/Alternatives/RHEL-Install-Binary.rst @@ -68,7 +68,6 @@ If you are going to build ROS packages or otherwise do development, you can also python3-colcon-common-extensions \ python3-mypy \ python3-pip \ - python3-pydocstyle \ python3-pytest \ python3-pytest-repeat \ python3-pytest-rerunfailures \ diff --git a/source/Installation/Alternatives/Windows-Development-Setup.rst b/source/Installation/Alternatives/Windows-Development-Setup.rst index 06e96b2c5bd..2670766a14f 100644 --- a/source/Installation/Alternatives/Windows-Development-Setup.rst +++ b/source/Installation/Alternatives/Windows-Development-Setup.rst @@ -41,7 +41,7 @@ Install additional Python dependencies: .. code-block:: bash - pip install -U colcon-common-extensions coverage flake8 flake8-blind-except flake8-builtins flake8-class-newline flake8-comprehensions flake8-deprecated flake8-docstrings flake8-import-order flake8-quotes mock mypy==0.931 pep8 pydocstyle pytest pytest-cov pytest-mock pytest-repeat pytest-rerunfailures pytest-runner vcstool + pip install -U colcon-common-extensions coverage flake8 flake8-blind-except flake8-builtins flake8-class-newline flake8-comprehensions flake8-deprecated flake8-import-order flake8-quotes mock mypy==0.931 pytest pytest-cov pytest-mock pytest-repeat pytest-rerunfailures pytest-runner vcstool Build ROS 2 ----------- diff --git a/source/Installation/Alternatives/macOS-Development-Setup.rst b/source/Installation/Alternatives/macOS-Development-Setup.rst index 4ee35a41786..631e9b81aaf 100644 --- a/source/Installation/Alternatives/macOS-Development-Setup.rst +++ b/source/Installation/Alternatives/macOS-Development-Setup.rst @@ -92,9 +92,9 @@ You need the following things installed to build ROS 2: argcomplete catkin_pkg colcon-common-extensions coverage \ cryptography empy flake8 flake8-blind-except==0.1.1 flake8-builtins \ flake8-class-newline flake8-comprehensions flake8-deprecated \ - flake8-docstrings flake8-import-order flake8-quotes \ + flake8-import-order flake8-quotes \ importlib-metadata jsonschema lark==1.1.1 lxml matplotlib mock mypy==0.931 netifaces \ - nose pep8 psutil pydocstyle pydot pygraphviz pyparsing==2.4.7 \ + psutil pydot pygraphviz pyparsing==2.4.7 \ pytest-mock rosdep rosdistro setuptools==59.6.0 vcstool Please ensure that the ``$PATH`` environment variable contains the install location of the binaries (``$(brew --prefix)/bin``) diff --git a/source/Installation/DDS-Implementations.rst b/source/Installation/DDS-Implementations.rst index 7e26a11ecf6..d412ab7c161 100644 --- a/source/Installation/DDS-Implementations.rst +++ b/source/Installation/DDS-Implementations.rst @@ -10,6 +10,7 @@ The default DDS vendor is eProsima's Fast DDS. * :doc:`Working with Eclipse Cyclone DDS ` explains how to utilize Cyclone DDS. * :doc:`Working with eProsima Fast DDS ` explains how to utilize Fast DDS. +* :doc:`Working with RTI Connext DDS ` explains how to utilize and evaluate RTI Connext DDS. * :doc:`Working with GurumNetworks GurumDDS ` explains how to utilize GurumDDS. .. toctree:: @@ -22,178 +23,3 @@ If you would like to use one of the other vendors you will need to install their The ROS 2 build will automatically build support for vendors that have been installed and sourced correctly. Once you've installed a new DDS vendor, you can change the vendor used at runtime: :doc:`Working with Multiple RMW Implementations <../How-To-Guides/Working-with-multiple-RMW-implementations>`. - -Detailed instructions for installing other DDS vendors are provided below. - -.. contents:: Platforms / Installation types - :depth: 1 - :local: - -Ubuntu Linux source install ---------------------------- - -RTI Connext (version 6.0.1, amd64 only) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Deb packages provided in the ROS 2 apt repositories -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can install a deb package of RTI Connext available on the ROS 2 apt repositories. -You will need to accept a license from RTI. - -.. code-block:: bash - - sudo apt update && sudo apt install -q -y rti-connext-dds-6.0.1 - -Source the setup file to set the ``NDDSHOME`` environment variable. - -.. code-block:: bash - - cd /opt/rti.com/rti_connext_dds-6.0.1/resource/scripts && source ./rtisetenv_x64Linux4gcc7.3.0.bash; cd - - -Note: when using ``zsh`` you need to be in the directory of the script when sourcing it to have it work properly - -Now you can build as normal and support for RTI will be built as well. - -Official binary packages from RTI -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can install the Connext 6.0.1 package for Linux provided by RTI, via options available for :doc:`university, purchase or evaluation ` - -After downloading, use ``chmod +x`` on the ``.run`` executable and then execute it. -Note that if you're installing to a system directory use ``sudo`` as well. - -The default location is ``~/rti_connext_dds-6.0.1`` - -After installation, run RTI launcher and point it to your license file (obtained from RTI). - -Add the following line to your ``.bashrc`` file pointing to your copy of the license. - -.. code-block:: bash - - export RTI_LICENSE_FILE=path/to/rti_license.dat - -Source the setup file to set the ``NDDSHOME`` environment variable. - -.. code-block:: bash - - cd ~/rti_connext_dds-6.0.1/resource/scripts && source ./rtisetenv_x64Linux4gcc7.3.0.bash; cd - - -Now you can build as normal and support for RTI will be built as well. - -Ubuntu Linux binary install ---------------------------- - -RTI Connext (version 6.0.1, amd64 only) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -To use RTI Connext DDS there are full-suite install options available for :doc:`university, purchase or evaluation ` -or you can install a libraries-only deb package of RTI Connext 6.0.1, available from the OSRF Apt repository -under a `non-commercial license `__. - -To install the libs-only deb package: - -.. code-block:: bash - - sudo apt update && sudo apt install -q -y rti-connext-dds-6.0.1 - -You will need to accept a license agreement from RTI, and will find an 'rti_license.dat file in the installation. - -Add the following line to your ``.bashrc`` file pointing to your copy of the license (and source it). - -.. code-block:: bash - - export RTI_LICENSE_FILE=path/to/rti_license.dat - -All options need you to source the setup file to set the ``NDDSHOME`` environment variable: - -.. code-block:: bash - - cd /opt/rti.com/rti_connext_dds-6.0.1/resource/scripts && source ./rtisetenv_x64Linux4gcc7.3.0.bash; cd - - -Note: the above may need modification to match your RTI installation location - -If you want to install the Connext DDS-Security plugins please refer to :doc:`this page `. - -OSX source install ------------------- - -RTI Connext (6.0.1) -^^^^^^^^^^^^^^^^^^^ - -If you would like to also build against RTI Connext DDS there are options available for :doc:`university, purchase or evaluation ` - -You also need a Java runtime installed to run the RTI code generator, which you can get `here `__. - -After installing, run RTI launcher and point it to your license file. - -Source the setup file to set the ``NDDSHOME`` environment variable before building your workspace. - -.. code-block:: bash - - source /Applications/rti_connext_dds-6.0.1/resource/scripts/rtisetenv_x64Darwin17clang9.0.bash - -You may need to increase shared memory resources following https://community.rti.com/kb/osx510 - -If you want to install the Connext DDS-Security plugins please refer to :doc:`this page `. - -OSX binary install ------------------- - - -Enable Connext support -^^^^^^^^^^^^^^^^^^^^^^ - -To use RTI Connext DDS there are options available for :doc:`university, purchase or evaluation ` - -After installing, run RTI launcher and point it to your license file. - -Source the setup file to set the ``NDDSHOME`` environment variable before building your workspace. - -.. code-block:: bash - - source /Applications/rti_connext_dds-6.0.1/resource/scripts/rtisetenv_x64Darwin17clang9.0.bash - -You may need to increase shared memory resources following https://community.rti.com/kb/osx510. - -If you want to install the Connext DDS-Security plugins please refer to :doc:`this page `. - -Windows source install ----------------------- - -RTI Connext 6.0.1 -^^^^^^^^^^^^^^^^^ - -If you would like to also build against RTI Connext DDS there are options available for :doc:`university, purchase or evaluation ` - -After installing, use the RTI Launcher to load your license file. - -Then before building ROS 2, set up the Connext environment: - -.. code-block:: bash - - call "C:\Program Files\rti_connext_dds-6.0.1\resource\scripts\rtisetenv_x64Win64VS2017.bat" - -Note that this path might need to be slightly altered depending on where you selected to install RTI Connext DDS, and which version of Visual Studio was selected. -The path above is the current default path as of version 6.0.1, but will change as the version numbers increment in the future. - -If you want to install the Connext DDS-Security plugins please refer to :doc:`this page `. - -Windows binary install ----------------------- - - -RTI Connext -^^^^^^^^^^^ - -To use RTI Connext DDS there are options available for :doc:`university, purchase or evaluation ` - -After installing, run RTI launcher and point it to your license file. - -Then before using ROS 2, set up the Connext environment: - -.. code-block:: bash - - call "C:\Program Files\rti_connext_dds-6.0.1\resource\scripts\rtisetenv_x64Win64VS2017.bat" - -If you want to install the Connext DDS-Security plugins please refer to :doc:`this page `. diff --git a/source/Installation/DDS-Implementations/Install-Connext-University-Eval.rst b/source/Installation/DDS-Implementations/Install-Connext-University-Eval.rst index 0f312b092c6..68f6b7d72fb 100644 --- a/source/Installation/DDS-Implementations/Install-Connext-University-Eval.rst +++ b/source/Installation/DDS-Implementations/Install-Connext-University-Eval.rst @@ -1,8 +1,9 @@ RTI Connext DDS =============== -A libraries-only version of RTI Connext DDS 6.0.1 may be installed per the :doc:`installation instructions <../../Installation>` for -Debian/Ubuntu Linux (amd64) platforms only, under a `non-commercial license `__. +.. contents:: Table of Contents + :depth: 1 + :local: A full-suite installation of RTI Connext DDS is available for many additional platforms, for universities, evaluation, or purchase. This installation includes diagnostic tools, layered services, and security. See below for installation details. @@ -18,9 +19,170 @@ The university license application can be found `here `__. * Download the version(s) to match your environment. * Contact license@rti.com for an evaluation license. * Install RTI Connext 6.0.1 by running the installation program. When finished, it will run the RTI Launcher. * Use the RTI Launcher to install the license file (rti_license.dat) if needed. The launcher may also be used to launch the diagnostic tools and services. + +Detailed instructions for each platform are provided below. + +Ubuntu Linux source install +--------------------------- + +RTI Connext (version 6.0.1, amd64 only) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Deb packages provided in the ROS 2 apt repositories +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can install a deb package of RTI Connext available on the ROS 2 apt repositories. +You will need to accept a license from RTI. + +.. code-block:: bash + + sudo apt update && sudo apt install -q -y ros-{DISTRO}-rmw-connextdds rti-connext-dds-6.0.1 + +Source the setup file to set the ``NDDSHOME`` environment variable. + +.. code-block:: bash + + cd /opt/rti.com/rti_connext_dds-6.0.1/resource/scripts && source ./rtisetenv_x64Linux4gcc7.3.0.bash; cd - + +Note: when using ``zsh`` you need to be in the directory of the script when sourcing it to have it work properly + +Now you can build as normal and support for RTI will be built as well. + +Official binary packages from RTI +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can install the Connext 6.0.1 package for Linux provided by RTI. + +After downloading, use ``chmod +x`` on the ``.run`` executable and then execute it. +Note that if you're installing to a system directory use ``sudo`` as well. + +The default location is ``~/rti_connext_dds-6.0.1`` + +After installation, run RTI launcher and point it to your license file (obtained from RTI). + +Add the following line to your ``.bashrc`` file pointing to your copy of the license. + +.. code-block:: bash + + export RTI_LICENSE_FILE=path/to/rti_license.dat + +Source the setup file to set the ``NDDSHOME`` environment variable. + +.. code-block:: bash + + cd ~/rti_connext_dds-6.0.1/resource/scripts && source ./rtisetenv_x64Linux4gcc7.3.0.bash; cd - + +Now you can build as normal and support for RTI will be built as well. + +Ubuntu Linux binary install +--------------------------- + +RTI Connext (version 6.0.1, amd64 only) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can install a libraries-only deb package of RTI Connext 6.0.1, available from the OSRF Apt repository under a `non-commercial license `__. + +To install the libs-only deb package: + +.. code-block:: bash + + sudo apt update && sudo apt install -q -y ros-{DISTRO}-rmw-connextdds rti-connext-dds-6.0.1 + +You will need to accept a license agreement from RTI, and will find an 'rti_license.dat file in the installation. + +Add the following line to your ``.bashrc`` file pointing to your copy of the license (and source it). + +.. code-block:: bash + + export RTI_LICENSE_FILE=path/to/rti_license.dat + +All options need you to source the setup file to set the ``NDDSHOME`` environment variable: + +.. code-block:: bash + + cd /opt/rti.com/rti_connext_dds-6.0.1/resource/scripts && source ./rtisetenv_x64Linux4gcc7.3.0.bash; cd - + +Note: the above may need modification to match your RTI installation location + +If you want to install the Connext DDS-Security plugins please refer to :doc:`this page <./Install-Connext-Security-Plugins>`. + +OSX source install +------------------ + +RTI Connext (6.0.1) +^^^^^^^^^^^^^^^^^^^ + +You also need a Java runtime installed to run the RTI code generator, which you can get `here `__. + +After installing, run RTI launcher and point it to your license file. + +Source the setup file to set the ``NDDSHOME`` environment variable before building your workspace. + +.. code-block:: bash + + source /Applications/rti_connext_dds-6.0.1/resource/scripts/rtisetenv_x64Darwin17clang9.0.bash + +You may need to increase shared memory resources following https://community.rti.com/kb/osx510 + +If you want to install the Connext DDS-Security plugins please refer to :doc:`this page <./Install-Connext-Security-Plugins>`. + +OSX binary install +------------------ + + +Enable Connext support +^^^^^^^^^^^^^^^^^^^^^^ + +After installing, run RTI launcher and point it to your license file. + +Source the setup file to set the ``NDDSHOME`` environment variable before building your workspace. + +.. code-block:: bash + + source /Applications/rti_connext_dds-6.0.1/resource/scripts/rtisetenv_x64Darwin17clang9.0.bash + +You may need to increase shared memory resources following https://community.rti.com/kb/osx510. + +If you want to install the Connext DDS-Security plugins please refer to :doc:`this page <./Install-Connext-Security-Plugins>`. + +Windows source install +---------------------- + +RTI Connext 6.0.1 +^^^^^^^^^^^^^^^^^ + +After installing, use the RTI Launcher to load your license file. + +Then before building ROS 2, set up the Connext environment: + +.. code-block:: bash + + call "C:\Program Files\rti_connext_dds-6.0.1\resource\scripts\rtisetenv_x64Win64VS2017.bat" + +Note that this path might need to be slightly altered depending on where you selected to install RTI Connext DDS, and which version of Visual Studio was selected. +The path above is the current default path as of version 6.0.1, but will change as the version numbers increment in the future. + +If you want to install the Connext DDS-Security plugins please refer to :doc:`this page <./Install-Connext-Security-Plugins>`. + +Windows binary install +---------------------- + + +RTI Connext +^^^^^^^^^^^ + +After installing, run RTI launcher and point it to your license file. + +Then before using ROS 2, set up the Connext environment: + +.. code-block:: bash + + call "C:\Program Files\rti_connext_dds-6.0.1\resource\scripts\rtisetenv_x64Win64VS2017.bat" + +If you want to install the Connext DDS-Security plugins please refer to :doc:`this page <./Install-Connext-Security-Plugins>`. diff --git a/source/Installation/RHEL-Install-RPMs.rst b/source/Installation/RHEL-Install-RPMs.rst index 3f36192bd24..80b1f00e1db 100644 --- a/source/Installation/RHEL-Install-RPMs.rst +++ b/source/Installation/RHEL-Install-RPMs.rst @@ -69,7 +69,6 @@ If you are going to build ROS packages or otherwise do development, you can also python3-colcon-common-extensions \ python3-mypy \ python3-pip \ - python3-pydocstyle \ python3-pytest \ python3-pytest-repeat \ python3-pytest-rerunfailures \ diff --git a/source/Package-Docs.rst b/source/Package-Docs.rst index 7f82f8adbfe..c12133aad8e 100644 --- a/source/Package-Docs.rst +++ b/source/Package-Docs.rst @@ -8,12 +8,14 @@ Here is a brief list of where to look for specific ROS package documentation. * Most ROS 2 packages have their package level documentation `included in this index page `__. -* All ROS 2 package's documentation is hosted alongside its information on the `ROS Index `_. Searching for packages on ROS Index will yield their information such as released distributions, ``README.md`` files, URLs, and other important metadata. +* All ROS 2 package's documentation is hosted alongside its information on the `ROS Index `_. + Searching for packages on ROS Index will yield their information such as released distributions, ``README.md`` files, URLs, and other important metadata. Larger Packages --------------- -Larger packages like MoveIt, Nav2, and microROS, are given their own domain or subdomain on ros.org. Here is a short list. +Larger packages like MoveIt, Nav2, and microROS, are given their own domain or subdomain on ros.org. +Here is a short list. * `MoveIt `__ * `Navigation2 `__ diff --git a/source/Related-Projects/Nvidia-ROS2-Projects.rst b/source/Related-Projects/Nvidia-ROS2-Projects.rst index 3240c848db8..a3d1a8e75a6 100644 --- a/source/Related-Projects/Nvidia-ROS2-Projects.rst +++ b/source/Related-Projects/Nvidia-ROS2-Projects.rst @@ -8,7 +8,8 @@ ROS Projects ------------ * `Isaac ROS Nvblox `__ : Hardware-accelerated 3D scene reconstruction and Nav2 local costmap provider using nvblox. * `Isaac ROS Object Detection `__ : Deep learning model support for object detection including DetectNet. -* `Isaac ROS DNN Inference `__ : This repository provides two NVIDIA GPU-accelerated ROS 2 nodes that perform deep learning inference using custom models. One node uses the TensorRT SDK, while the other uses the Triton SDK. +* `Isaac ROS DNN Inference `__ : This repository provides two NVIDIA GPU-accelerated ROS 2 nodes that perform deep learning inference using custom models. + One node uses the TensorRT SDK, while the other uses the Triton SDK. * `Isaac ROS Visual SLAM `__ : This repository provides a ROS 2 package that estimates stereo visual inertial odometry using the Isaac Elbrus GPU-accelerated library. * `Isaac ROS Argus Camera `__ : This repository provides monocular and stereo nodes that enable ROS developers to use cameras connected to Jetson platforms over a CSI interface. * `Isaac ROS image_pipeline `__ : This metapackage offers similar functionality as the standard, CPU-based image_pipeline metapackage, but does so by leveraging the Jetson platform's specialized computer vision hardware. @@ -16,7 +17,8 @@ ROS Projects * `Isaac ROS AprilTags `__ : ROS 2 node uses the NVIDIA GPU-accelerated AprilTags library to detect AprilTags in images and publish their poses, ids, and additional metadata. * `ROS and ROS 2 Docker Images `__ : Docker images for easy deployment on the NVIDIA Jetson platform, consisting of ROS 2, PyTorch, and other important machine learning libraries. * `ROS and ROS 2 DockerFiles `__: Dockerfiles for ROS 2 based on l4t which all you to build your own Docker image. -* `ROS 2 Packages for PyTorch and TensorRT `__: ROS 2 packageis for classification and object detection tasks using PyTorch and NVIDIA TensorRT. This tutorial is a good starting point AI integration with ROS 2 on NVIDIA Jetson. +* `ROS 2 Packages for PyTorch and TensorRT `__: ROS 2 packageis for classification and object detection tasks using PyTorch and NVIDIA TensorRT. + This tutorial is a good starting point AI integration with ROS 2 on NVIDIA Jetson. * `ROS / ROS 2 Packages for Accelerated Deep Learning Nodes `__: Deep learning image recognition, object detection, and semantic segmentation inference nodes and camera/video streaming nodes for ROS/ROS 2 using the `jetson-inference `__ library and `NVIDIA Hello AI World tutorial `__. * `ROS 2 Package for Human Pose Estimation `__: A ROS 2 package for human pose estimation. * `ROS 2 Package for Hand Pose Estimation and Gesture Classification `__: A ROS 2 package for real-time hand pose estimation and gesture classification using TensorRT. diff --git a/source/Related-Projects/Visualizing-ROS-2-Data-With-Foxglove.rst b/source/Related-Projects/Visualizing-ROS-2-Data-With-Foxglove.rst index 424341bdfb5..99e8d133ac6 100644 --- a/source/Related-Projects/Visualizing-ROS-2-Data-With-Foxglove.rst +++ b/source/Related-Projects/Visualizing-ROS-2-Data-With-Foxglove.rst @@ -11,7 +11,8 @@ It's available in the browser or as a standalone desktop app and is free for ind Installation ------------ -To use Foxglove, you'll need to `create an account `__. It's free and all you need is a valid email address. +To use Foxglove, you'll need to `create an account `__. +It's free and all you need is a valid email address. Once you've created an account, you can use Foxglove on the web by opening Google Chrome and navigating to `app.foxglove.dev `__. @@ -19,7 +20,9 @@ To use the desktop app for Linux, macOS, or Windows, download it directly from t .. note:: - Foxglove uses specific features of Google Chrome. While some features may work, other browsers are not supported. For the best experience, we recommend using Chrome or the desktop app. + Foxglove uses specific features of Google Chrome. + While some features may work, other browsers are not supported. + For the best experience, we recommend using Chrome or the desktop app. Connect to a live data source ----------------------------- @@ -36,9 +39,11 @@ Once you have the bridge installed, launch it with: ros2 launch foxglove_bridge foxglove_bridge_launch.xml -With the bridge running on your robot, you're ready to connect view data in Foxglove. Make sure you are on the same network as your robot, open Foxglove (web or desktop) and click "Open connection". +With the bridge running on your robot, you're ready to connect view data in Foxglove. +Make sure you are on the same network as your robot, open Foxglove (web or desktop) and click "Open connection". -Select the option for "Foxglove WebSocket" and enter your robot's WebSocket URL. The default is ``ws://localhost:8765``, however you can read about configuration options for the ROS Foxglove bridge `here `__. +Select the option for "Foxglove WebSocket" and enter your robot's WebSocket URL. +The default is ``ws://localhost:8765``, however you can read about configuration options for the ROS Foxglove bridge `here `__. .. note:: @@ -47,7 +52,8 @@ Select the option for "Foxglove WebSocket" and enter your robot's WebSocket URL. View and replay recorded data ----------------------------- -If you'd rather visualize recorded data, you can use Foxglove to replay ROS 2 ``.mcap`` as well as older ROS 2 ``.db3``, and ROS 1 ``.bag`` files. Foxglove is particularly convenient for recorded data because it does not require ROS 2 to be running to view data. +If you'd rather visualize recorded data, you can use Foxglove to replay ROS 2 ``.mcap`` as well as older ROS 2 ``.db3``, and ROS 1 ``.bag`` files. +Foxglove is particularly convenient for recorded data because it does not require ROS 2 to be running to view data. Use the :doc:`ros2 bag command line tool <../Tutorials/Beginner-CLI-Tools/Recording-And-Playing-Back-Data/Recording-And-Playing-Back-Data>` to record data from your robot to a ``.mcap`` file: @@ -73,7 +79,8 @@ We've highlighted some particularly useful ones below: 3D panel: View 3D data and visualization markers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Open the panel settings by clicking the gear icon in the upper right. Choose the topics you want to display via the topic picker on the left, and configure each topic's visualization settings in the "Edit topic settings" menu. +Open the panel settings by clicking the gear icon in the upper right. +Choose the topics you want to display via the topic picker on the left, and configure each topic's visualization settings in the "Edit topic settings" menu. Publish marker messages to add primitive shapes (arrows, spheres, etc.) and more complex visualizations (occupancy grids, point clouds, etc.) to your 3D panel's scene. @@ -97,7 +104,8 @@ Reference the `docs Image panel: View camera feed images ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Display raw and compressed images, as well as compressed videos, with 2D annotations like text labels, circles, and points. Superimpose 3D markers for additional context. +Display raw and compressed images, as well as compressed videos, with 2D annotations like text labels, circles, and points. +Superimpose 3D markers for additional context. .. image:: foxglove/image.png :width: 500 px @@ -121,7 +129,8 @@ Plot panel: Plot arbitrary values over time Plot arbitrary numeric values from topic `message paths `__ . -When playing back local or remote data files, this panel will preload the data belonging to the specified topic message paths for the whole playback timeline. Current playback time is indicated by a vertical gray bar. +When playing back local or remote data files, this panel will preload the data belonging to the specified topic message paths for the whole playback timeline. +Current playback time is indicated by a vertical gray bar. .. image:: foxglove/plot.png :width: 500 px @@ -134,7 +143,8 @@ Raw Messages panel: View incoming topic messages Inspect a particular `message path `__ in your data source. -As new messages are received for a given path, the collapsible tree will show just the latest message. You will be able to expand and collapse keys, and have those changes persist across playback. +As new messages are received for a given path, the collapsible tree will show just the latest message. +You will be able to expand and collapse keys, and have those changes persist across playback. .. image:: foxglove/raw-messages.png :width: 500 px diff --git a/source/Releases/Release-Kilted-Kaiju.rst b/source/Releases/Release-Kilted-Kaiju.rst index f5d3f93bb4a..78c38266af8 100644 --- a/source/Releases/Release-Kilted-Kaiju.rst +++ b/source/Releases/Release-Kilted-Kaiju.rst @@ -19,15 +19,17 @@ Kilted Kaiju is primarily supported on the following platforms: Tier 1 platforms: -* TODO +* Ubuntu 24.04 (Noble): ``amd64`` and ``arm64`` +* Windows 10 (Visual Studio 2019): ``amd64`` Tier 2 platforms: -* TODO +* RHEL 9: ``amd64`` Tier 3 platforms: -* TODO +* macOS: ``amd64`` +* Debian Bookworm: ``amd64`` For more information about RMW implementations, compiler / interpreter versions, and system dependency versions see `REP 2000 `__. @@ -45,3 +47,44 @@ Development progress For progress on the development of Kiltled Kaiju, see `this project board `__. For the broad process followed by Kilted Kaiju, see the :doc:`process description page `. + +Release Timeline +---------------- + + December, 2024 - Platform decisions + REP 2000 is updated with the target platforms and major dependency versions. + + Mon. April 7, 2025 - Alpha + RMW freeze + Preliminary testing and stabilization of ROS Base [1]_ packages, and API and feature freeze for RMW provider packages. + + Mon. April 14, 2024 - Freeze + API and feature freeze for ROS Base [1]_ packages in Rolling Ridley. + Only bug fix releases should be made after this point. + New packages can be released independently. + + Mon. April 21, 2024 - Branch + Branch from Rolling Ridley. + ``rosdistro`` is reopened for Rolling PRs for ROS Base [1]_ packages. + Kilted development shifts from ``ros-rolling-*`` packages to ``ros-kilted-*`` packages. + + Mon. April 28, 2024 - Beta + Updated releases of ROS Desktop [2]_ packages available. + Call for general testing. + + Thu, May 1, 2024 - Kick off of Tutorial Party + Tutorials hosted at https://github.com/osrf/ros2_test_cases are open for community testing. + + Mon. May 12, 2024 - Release Candidate + Release Candidate packages are built. + Updated releases of ROS Desktop [2]_ packages available. + + Mon. May 19, 2024 - Distro Freeze + Freeze all Kilted branches on all `ROS 2 desktop packages `__ and ``rosdistro``. + No pull requests for any ``kilted`` branch or targeting ``kilted/distribution.yaml`` in ``rosdistro`` repo will be merged. + + Fri. May 23, 2024 - General Availability + Release announcement. + `ROS 2 desktop packages `__ source freeze is lifted and ``rosdistro`` is reopened for Kilted pull requests. + +.. [1] The ``ros_base`` variant is described in `REP 2001 (ros-base) `_. +.. [2] The ``desktop`` variant is described in `REP 2001 (desktop-variants) `_. diff --git a/source/The-ROS2-Project/Contributing/Build-Farms.rst b/source/The-ROS2-Project/Contributing/Build-Farms.rst index 26edc804b2d..4f27b2c65b5 100644 --- a/source/The-ROS2-Project/Contributing/Build-Farms.rst +++ b/source/The-ROS2-Project/Contributing/Build-Farms.rst @@ -74,7 +74,8 @@ Execution of the jobs depends on the type of the job: * `devel jobs`_ will be triggered every time a commit is done to the respective branch polling based on a configured frequency. * `pull_request jobs`_ will be triggered by webhooks from respective pull request of the upstream [2]_ repository * `release jobs`_ will be triggered once every time a new package version is released, i.e. a new - rosdistro_ pull request was accepted for this package. The source jobs are triggered by a version + rosdistro_ pull request was accepted for this package. + The source jobs are triggered by a version change in the rosdistro distribution file, the binary jobs are triggered by their source counterpart. @@ -83,25 +84,26 @@ Frequency Asked Questions (FAQ) and Troubleshooting #. **I get Jenkins mails from failing build farm jobs. What do I do?** - Go to the job that raised the issue. You find the link on top of the Jenkins email. - Once you followed the link to the build job, click *Console Output* on the left, then click - *Full Log*. This will give you the full console output of the failing build. Try to find the - top-most error as it is usually the most important and other errors might be follow-ups. + Go to the job that raised the issue. + You find the link on top of the Jenkins email. + Once you followed the link to the build job, click *Console Output* on the left, then click *Full Log*. + This will give you the full console output of the failing build. + Try to find the top-most error as it is usually the most important and other errors might be follow-ups. - The bottom of the email might read ``'apt-src build [...]' failed. This is usually because of - an error building the package.`` This usually hints at missing dependencies, see 2. + The bottom of the email might read + ``'apt-src build [...]' failed. This is usually because of an error building the package.`` + This usually hints at missing dependencies, see 2. #. **I seem to be missing a dependency, how do I find out which one?** You basically have two options, a. is easier but may take several iterations, b. is more elaborate and gives you the full insight as well as local debugging. - a) Inspect the release job that raised the issue (see 1.) and localize the cmake dependency - issue. To do so, browse to the cmake section, e.g., navigate to the *build binarydeb* - section through the menu on the left in case of a Ubuntu/Debian build job. The *CMake Error* - will typically hint at a dependency required by the cmake configuration but missing in the - `package manifest`_. Once you have fixed the dependency in the manifest, do a new release - of your package and wait for feedback from the build farms or... + a) Inspect the release job that raised the issue (see 1.) and localize the cmake dependency issue. + To do so, browse to the cmake section, e.g., navigate to the *build binarydeb* + section through the menu on the left in case of a Ubuntu/Debian build job. + The *CMake Error* will typically hint at a dependency required by the cmake configuration but missing in the `package manifest`_. + Once you have fixed the dependency in the manifest, do a new release of your package and wait for feedback from the build farms or... b) To get the full insight and faster, local debugging, you can `run the release jobs locally`_. This allows to iterate the manifest locally until all dependencies are fixed. @@ -109,12 +111,13 @@ Frequency Asked Questions (FAQ) and Troubleshooting There are several potential reasons for this. First, release jobs build against a minimal ROS installation to check if all dependencies are - properly declared in the `package manifest`_. Devel jobs / github actions / local builds may + properly declared in the `package manifest`_. + Devel jobs / github actions / local builds may be performed in an environment that has the dependencies already installed, therefore does not - notice dependency issues. Second, they might build different versions of the source code. + notice dependency issues. + Second, they might build different versions of the source code. While devel jobs / github actions / local builds usually build the latest version from the - *upstream* [2]_ repository, `release jobs`_ build the source code of the latest release, i.e. - the source code in the respective *upstream* branches of the *release* repository [3]_. + *upstream* [2]_ repository, `release jobs`_ build the source code of the latest release, i.e. the source code in the respective *upstream* branches of the *release* repository [3]_. Further Reading diff --git a/source/The-ROS2-Project/Contributing/Code-Style-Language-Versions.rst b/source/The-ROS2-Project/Contributing/Code-Style-Language-Versions.rst index c1284cb634d..99ac9f148f9 100644 --- a/source/The-ROS2-Project/Contributing/Code-Style-Language-Versions.rst +++ b/source/The-ROS2-Project/Contributing/Code-Style-Language-Versions.rst @@ -51,7 +51,8 @@ All of the following modifications only apply if we are not writing Python modul * The stuff about documentation strings doesn't apply -We can use the `pep7 `__ python module for style checking. The editor integration seems slim, we may need to look into automated checking for C in more detail. +We can use the `pep7 `__ python module for style checking. +The editor integration seems slim, we may need to look into automated checking for C in more detail. C++ --- @@ -166,9 +167,9 @@ Pointer Syntax Alignment Class Privacy Keywords ~~~~~~~~~~~~~~~~~~~~~~ -* Do not put 1 space before ``public:``, ``private:``, or ``protected:``, it is more consistent for all indentions to be a multiple of 2 +* Do not put 1 space before ``public:``, ``private:``, or ``protected:``, it is more consistent for all indentations to be a multiple of 2 - * rationale: most editors don't like indentions which are not a multiple of the (soft) tab size + * rationale: most editors don't like indentations which are not a multiple of the (soft) tab size * Use zero spaces before ``public:``, ``private:``, or ``protected:``, or 2 spaces * If you use 2 spaces before, indent other class statements by 2 additional spaces * Prefer zero spaces, i.e. ``public:``, ``private:``, or ``protected:`` in the same column as the class @@ -194,7 +195,9 @@ Open Versus Cuddled Braces * Exception: when an ``if`` (or ``while``, etc.) condition is long enough to require line-wrapping, then use an open brace (i.e., don't cuddle). -* When a function call cannot fit on one line, wrap at the open parenthesis (not in between arguments) and start them on the next line with a 2-space indent. Continue with the 2-space indent on subsequent lines for more arguments. (Note that the `Google style guide `__ is internally contradictory on this point.) +* When a function call cannot fit on one line, wrap at the open parenthesis (not in between arguments) and start them on the next line with a 2-space indent. + Continue with the 2-space indent on subsequent lines for more arguments. + (Note that the `Google style guide `__ is internally contradictory on this point.) * Same goes for ``if`` (and ``while``, etc.) conditions that are too long to fit on one line. @@ -254,7 +257,7 @@ This is **not** OK: } -Use open braces rather than excessive indention, e.g. for distinguishing constructor code from constructor initializer lists +Use open braces rather than excessive indentation, e.g. for distinguishing constructor code from constructor initializer lists This is OK: @@ -364,7 +367,7 @@ Since there is not an existing CMake style guide we will define our own: * Use ``snake_case`` identifiers (variables, functions, macros). * Use empty ``else()`` and ``end...()`` commands. * No whitespace before ``(``\ 's. -* Use two spaces of indention, do not use tabs. +* Use two spaces of indentation, do not use tabs. * Do not use aligned indentation for parameters of multi-line macro invocations. Use two spaces only. * Prefer functions with ``set(PARENT_SCOPE)`` to macros. * When using macros prefix local variables with ``_`` or a reasonable prefix. diff --git a/source/The-ROS2-Project/Contributing/Contributing-To-ROS-2-Documentation.rst b/source/The-ROS2-Project/Contributing/Contributing-To-ROS-2-Documentation.rst index d551e85ac29..205069a8400 100644 --- a/source/The-ROS2-Project/Contributing/Contributing-To-ROS-2-Documentation.rst +++ b/source/The-ROS2-Project/Contributing/Contributing-To-ROS-2-Documentation.rst @@ -99,12 +99,33 @@ This is the recommended way to test out local changes. The build process can take some time. To see the output, open ``build/html/index.html`` in your browser. -You can also run the documentation tests locally (using `doc8 `_) with the following command: + +Checking / Testing the site +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can run the documentation tests locally (using `doc8 `_) with the following command: .. code-block:: console make test +You can run the documentation linter locally (using `sphinx-lint `_) with the following command: + +.. code-block:: console + + make lint + +You can run the documentation spell checker locally (using `codespell `_) with the following command: + +.. code-block:: console + + make spellcheck + +.. note:: + + If that detects specific words that need to be ignored, add it to `codespell_whitelist `_ . + + View Site Through Github CI ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -173,9 +194,11 @@ We've found that the easiest way to migrate a page from the ROS Wiki is to conve Migrating a Wiki File ^^^^^^^^^^^^^^^^^^^^^ -#. Clone the appropriate repository. If you are migrating a page to the official documentation hosted here, then you should clone https://github.com/ros2/ros2_documentation. +#. Clone the appropriate repository. + If you are migrating a page to the official documentation hosted here, then you should clone https://github.com/ros2/ros2_documentation. -#. Create a new Github branch for your migrated page. We suggest something like ``pagename-migration``. +#. Create a new Github branch for your migrated page. + We suggest something like ``pagename-migration``. #. Download the appropriate ROS Wiki page to an html file using wget or a similar tool (e.g. ``wget -O urdf.html https://wiki.ros.org/urdf``). Alternatively you can use your web browser to save the page's HTML. @@ -183,10 +206,11 @@ Migrating a Wiki File #. Next you need to remove the extraneous HTML in the file you downloaded Using your browser's developer mode, find the name of the first useful HTML element in the Wiki page. In most cases all of the HTML between the third line of the file, starting with the ```` tag, through the start of the first ``

`` tag can be safely removed. - In the case where there is a table of contents, the first useful tag may be an ``

`` tag. Similarly, the ROS wiki contains some footer text that starts with ``
`` and ends just above ```` that can also be removed. + In the case where there is a table of contents, the first useful tag may be an ``

`` tag. + Similarly, the ROS wiki contains some footer text that starts with ``
`` and ends just above ```` that can also be removed. #. Convert your html file by running a PanDoc conversion between HTML and restructured text. - The following command coverts an HTML file to the equivalent reStructured text files: ``pandoc -f html -t rst urdf.html > URDF.rst``. + The following command converts an HTML file to the equivalent reStructured text files: ``pandoc -f html -t rst urdf.html > URDF.rst``. #. Attempt to build your new documentation using the ``make html`` command. There may be errors and warnings that you will need to address. @@ -198,11 +222,13 @@ Migrating a Wiki File This process may require you alter the document considerably, and you may need to pull multiple wiki files. You should verify that every code sample in the document is working correctly under ROS 2. -#. Find and download any images that may be in the old document. The easiest way to do this is to right click in the browser and download all of the images. Alternatively you can find images by searching for ```` tags in the HTML file. +#. Find and download any images that may be in the old document. + The easiest way to do this is to right click in the browser and download all of the images. + Alternatively you can find images by searching for ```` tags in the HTML file. #. For each image files downloaded update the image file links to point to the correct image directory for the ROS Docs. If any of the images require updating, or could be replaced with a `Mermaid `__ chart, please make this change. - Be aware that Mermaid.js is only supported in the core ROS 2 documenation currently. + Be aware that Mermaid.js is only supported in the core ROS 2 documentation currently. #. Once your document is complete add a table of contents to the top of your new rst document using the appropriate Sphinx commands. This block should replace any existing table of contents from the old ROS Wiki. @@ -226,7 +252,8 @@ After that, you can open the repository in Codespaces, it can be done just by cl :alt: Codespaces creation After that, you will be redirected to your Codespaces page, where you can see the progress of the Codespaces creation. -Once it is done, a Visual Studio Code tab will be opened in your browser. You can open the terminal by clicking on the "Terminal" tab in the top panel or by pressing :kbd:`Ctrl-J`. +Once it is done, a Visual Studio Code tab will be opened in your browser. +You can open the terminal by clicking on the "Terminal" tab in the top panel or by pressing :kbd:`Ctrl-J`. In this terminal, you can run any command you want, for example, you can run the following command to build the site for just this branch: @@ -278,6 +305,10 @@ Writing pages The ROS 2 documentation website uses the ``reStructuredText`` format, which is the default plaintext markup language used by Sphinx. This section is a brief introduction to ``reStructuredText`` concepts, syntax, and best practices. +When formatting your ``reStructuredText`` file **please make sure to write only one sentence per line as it makes reviewing and modifying your file much easier.** +Also, be mindful of the use of white space in your file! +The ROS 2 documentation linter will not accept pull requests with trailing white space. +We recommend that you enable automatic white space highlighting and or cleanup if your editor supports it. You can refer to `reStructuredText User Documentation `_ for a detailed technical specification. @@ -383,6 +414,13 @@ Images can be inserted using the ``.. image::`` directive. .. image:: images/turtlesim_follow1.png +Charts, Graphs, and Diagrams +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ROS 2 Documentation now supports charts, graphs, and diagrams written using `Mermaid Charts. `__ +We prefer that charts, graphs, and diagrams use Mermaid instead of static image files as it allows us to programmatically update and edit these resources as the project evolves. +Full documentation of the `Mermaid graph language syntax can be found on their website. `__ + References and Links ^^^^^^^^^^^^^^^^^^^^ diff --git a/source/The-ROS2-Project/Contributing/Developer-Guide.rst b/source/The-ROS2-Project/Contributing/Developer-Guide.rst index e0fb2b40b67..8b90556e6fd 100644 --- a/source/The-ROS2-Project/Contributing/Developer-Guide.rst +++ b/source/The-ROS2-Project/Contributing/Developer-Guide.rst @@ -206,8 +206,8 @@ Examples: * This is an example of describing an extension point for a package -API Documetation for ROS Packages -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +API Documentation for ROS Packages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ API documentation for all released ROS packages can be `found here `__. We recommend using `index.ros.org `_ to search through available ROS packages to find their documentation. @@ -425,7 +425,8 @@ Package Naming Conventions Names play an important role in ROS and following naming conventions simplifies the process of learning and understanding large systems. -The ROS packages occupy a flat namespace, so naming should be done carefully and consistently. There is a standard for package naming in `REP-144 `__ +The ROS packages occupy a flat namespace, so naming should be done carefully and consistently. +There is a standard for package naming in `REP-144 `__ * Package names should follow common C variable naming conventions: lower case, start with a letter, use underscore separators, e.g. laser_viewer @@ -578,7 +579,8 @@ The usual workflow is: * In the first box "CI_BRANCH_TO_TEST" enter your feature branch name * Hit the ``build`` button - (if you are not a ROS 2 committer, you don't have access to the CI farm. In that case, ping the reviewer of your PR to run CI for you) + (if you are not a ROS 2 committer, you don't have access to the CI farm. + In that case, ping the reviewer of your PR to run CI for you) * If your use case requires running code coverage: diff --git a/source/The-ROS2-Project/Contributing/Quality-Guide.rst b/source/The-ROS2-Project/Contributing/Quality-Guide.rst index 5963076861e..ad182afa69e 100644 --- a/source/The-ROS2-Project/Contributing/Quality-Guide.rst +++ b/source/The-ROS2-Project/Contributing/Quality-Guide.rst @@ -127,7 +127,8 @@ However, this step-by-step is a great place to start! * Enabling Analysis for Package/Target - When the C++ compiler is Clang, enable the ``-Wthread-safety`` flag. Example below for CMake-based projects + When the C++ compiler is Clang, enable the ``-Wthread-safety`` flag. + Example below for CMake-based projects .. code-block:: cmake diff --git a/source/The-ROS2-Project/Contributing/Windows-Tips-and-Tricks.rst b/source/The-ROS2-Project/Contributing/Windows-Tips-and-Tricks.rst index 01db8b8af0e..dda812a7d45 100644 --- a/source/The-ROS2-Project/Contributing/Windows-Tips-and-Tricks.rst +++ b/source/The-ROS2-Project/Contributing/Windows-Tips-and-Tricks.rst @@ -20,8 +20,10 @@ Practically speaking, 4 of those characters are always used by the drive letter, That means that only 256 characters are available for the *sum* of all parts of the path. This has two practical consequences for ROS 2: -* Some of the ROS 2 internal path names are fairly long. Because of this, we always recommend using a short path name for the root of your ROS 2 directory, like ``C:\dev``. -* When building ROS 2 from source, the default isolated build mode of colcon can generate very long path names. To avoid these very long path names, use ``--merge-install`` when building on Windows. +* Some of the ROS 2 internal path names are fairly long. + Because of this, we always recommend using a short path name for the root of your ROS 2 directory, like ``C:\dev``. +* When building ROS 2 from source, the default isolated build mode of colcon can generate very long path names. + To avoid these very long path names, use ``--merge-install`` when building on Windows. **Note**: It is possible to change Windows to have much longer maximum path lengths. See `this article `__ for more information. @@ -95,7 +97,8 @@ In another library, ``MY_LIB`` would be replaced with the library name. For a complete example of this header, see `rviz_rendering `__. -To use the macro, add ``MY_LIB_PUBLIC`` before symbols which need to be visible to external libraries. For example: +To use the macro, add ``MY_LIB_PUBLIC`` before symbols which need to be visible to external libraries. +For example: .. code-block:: c++ diff --git a/source/The-ROS2-Project/Feature-Ideas.rst b/source/The-ROS2-Project/Feature-Ideas.rst index acd1204b550..d063a42c488 100644 --- a/source/The-ROS2-Project/Feature-Ideas.rst +++ b/source/The-ROS2-Project/Feature-Ideas.rst @@ -133,7 +133,9 @@ The trailing stars indicate the rough effort: 1 star for small, 2 stars for medi * More granularity in security configuration (allow authentication only, authentication and encryption, etc.) [\*] * Integrate DDS-Security logging plugin (unified way to aggregate security events and report them to the users through a ROS interface) [\*\*] * Key storage security (right now, keys are just stored in the filesystem) [\*\*] - * More user friendly interface (make it easier to specify security config). Maybe a Qt GUI? This GUI could also assist in distributing keys somehow. [\*\*\*] + * More user friendly interface (make it easier to specify security config). + Maybe a Qt GUI? + This GUI could also assist in distributing keys somehow. [\*\*\*] * A way to say "please secure this running system" with some UI that would auto-generate keys and policies for everything that is currently running. [\*\*\*] * If there are hardware-specific features for securing keys or accelerating encryption/signing messages, that could be interesting to add to DDS/RTPS implementations that don't use it already. [\*\*\*] diff --git a/source/The-ROS2-Project/Features.rst b/source/The-ROS2-Project/Features.rst index bade5c363d3..749cf246d0b 100644 --- a/source/The-ROS2-Project/Features.rst +++ b/source/The-ROS2-Project/Features.rst @@ -73,7 +73,8 @@ For planned future development, see the :doc:`Roadmap `. - * - Preliminary support for real-time code - :doc:`Demo <../Tutorials/Demos/Real-Time-Programming>`, :doc:`demo <../Tutorials/Advanced/Allocator-Template-Tutorial>` - - Linux only. Not available for Fast RTPS. + - Linux only. + Not available for Fast RTPS. * - Preliminary support for "bare-metal" microcontrollers - `Wiki `__ - diff --git a/source/The-ROS2-Project/Governance.rst b/source/The-ROS2-Project/Governance.rst index d63ef8c4fc9..10223d331c1 100644 --- a/source/The-ROS2-Project/Governance.rst +++ b/source/The-ROS2-Project/Governance.rst @@ -105,11 +105,6 @@ The ROS PMC currently consists of the following constituents: - `nuclearsandwich `_ - Member / Infrastructure Project Lead - PST (UTC-8)/PDT (UTC-7) - * - Kat Scott - - `Intrinsic `_ - - `kscottz `_ - - OSRA Developer Advocate - - PST (UTC-8)/PDT (UTC-7) * - Alberto Soragna - `iRobot `_ - `alsora `_ @@ -146,6 +141,10 @@ The ROS committers (who are not also part of the ROS PMC) consists of the follow - `Intrinsic `_ - `quarkytale `_ - PST (UTC-8)/PDT (UTC-7) + * - Kat Scott + - `Intrinsic `_ + - `kscottz `_ + - PST (UTC-8)/PDT (UTC-7) * - Miguel Company - `eProsima `_ - `MiguelCompany `_ diff --git a/source/The-ROS2-Project/Marketing.rst b/source/The-ROS2-Project/Marketing.rst index 4f9037a713f..b07bee7c249 100644 --- a/source/The-ROS2-Project/Marketing.rst +++ b/source/The-ROS2-Project/Marketing.rst @@ -11,9 +11,8 @@ General Use ROS Artwork ----------------------- The ROS 2 media kit, which includes branding language, high resolution ROS logo -graphics, and release images, can be found in the `ROS art -repository. `__ Please refer to -this repository for ROS art work and our branding guidelines. +graphics, and release images, can be found in the `ROS art repository. `__ +Please refer to this repository for ROS art work and our branding guidelines. Stickers, Posters, and Canvas Prints ------------------------------------ diff --git a/source/The-ROS2-Project/ROSCon-Content.rst b/source/The-ROS2-Project/ROSCon-Content.rst index bcf5cb00dca..d7dc328e1c8 100644 --- a/source/The-ROS2-Project/ROSCon-Content.rst +++ b/source/The-ROS2-Project/ROSCon-Content.rst @@ -11,7 +11,7 @@ The following `ROSCon `__ talks have been given on ROS 2 .. tabs:: - .. group-tab:: 2024 + .. group-tab:: 2024 .. list-table:: :header-rows: 1 @@ -116,7 +116,7 @@ The following `ROSCon `__ talks have been given on ROS 2 - `video `__ * - Building Foundation Model-powered Robots with ROS: A Survey - `video `__ - * - Scenic for ROS: A Probabilistic Programming Language for World Modelin... + * - Scenic for ROS: A Probabilistic Programming Language for World Modeling... - `video `__ * - Software Platform Design and SDK Development for ROS 2-based LG AI Com... - `video `__ @@ -131,7 +131,7 @@ The following `ROSCon `__ talks have been given on ROS 2 * - Navigation à la carte: choose navigation profile and strategy as you go - `video `__ - .. group-tab:: 2023 + .. group-tab:: 2023 .. list-table:: :header-rows: 1 diff --git a/source/The-ROS2-Project/Roadmap.rst b/source/The-ROS2-Project/Roadmap.rst index 4cda15fde53..f0a7b649589 100644 --- a/source/The-ROS2-Project/Roadmap.rst +++ b/source/The-ROS2-Project/Roadmap.rst @@ -56,7 +56,8 @@ Please see the :doc:`Distributions page <../Releases>` for the timeline of and i Contributing to ROS 2 --------------------- -Looking for something to work on, or just want to help out? Here are a few resources to get you going. +Looking for something to work on, or just want to help out? +Here are a few resources to get you going. 1. The :doc:`Contributing ` guide describes how to make a contribution to ROS 2. 2. Check out the list of :doc:`Feature Ideas ` for inspiration. diff --git a/source/Tutorials/Advanced/Ament-Lint-For-Clean-Code.rst b/source/Tutorials/Advanced/Ament-Lint-For-Clean-Code.rst index 14b619f960e..7f866ca5717 100644 --- a/source/Tutorials/Advanced/Ament-Lint-For-Clean-Code.rst +++ b/source/Tutorials/Advanced/Ament-Lint-For-Clean-Code.rst @@ -109,8 +109,10 @@ For example, if you wish to scan just a recently modified file you can call ``am ``ament_cppcheck`` supports the following options: -* ``--libraries [LIBRARIES ...]`` - Library configurations to load in addition to the standard libraries of C and C++. Each library is passed to cppcheck as '--library=' -* ``--include_dirs [INCLUDE_DIRS ...]`` - Include directories for C/C++ files being checked.Each directory is passed to cppcheck as '-I ' (default: None) +* ``--libraries [LIBRARIES ...]`` - Library configurations to load in addition to the standard libraries of C and C++. + Each library is passed to cppcheck as '--library=' +* ``--include_dirs [INCLUDE_DIRS ...]`` - Include directories for C/C++ files being checked. + Each directory is passed to cppcheck as '-I ' (default: None) * ``--cppcheck-version`` - Get the cppcheck version, print it, and then exit. 2.3 ``ament_cppcheck`` Example @@ -283,7 +285,8 @@ For example, if you wish to scan just one package in your workspace you can call 5.2 ``ament_uncrustify`` Options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* ``-c CFG`` - The config file that Uncrustify should use if you would prefer to use your own settings. We recommend you stick to the defaults +* ``-c CFG`` - The config file that Uncrustify should use if you would prefer to use your own settings. + We recommend you stick to the defaults * ``--linelength N`` - The maximum line length. * ``--language`` - One of {C,C++,CPP}, passed to uncrustify as '-l ' to force a specific language rather then choosing one based on file extension. * ``--reformat`` - Reformat the files in place, i.e. fix the formatting errors encountered. **We recommend you use this option when running ``ament_uncrustify`` as it will save you quite a bit of time!** diff --git a/source/Tutorials/Advanced/Discovery-Server/Discovery-Server.rst b/source/Tutorials/Advanced/Discovery-Server/Discovery-Server.rst index 2ca8e669bc0..6efd96bbf6e 100644 --- a/source/Tutorials/Advanced/Discovery-Server/Discovery-Server.rst +++ b/source/Tutorials/Advanced/Discovery-Server/Discovery-Server.rst @@ -76,7 +76,8 @@ Run this tutorial The ``talker-listener`` ROS 2 demo creates a ``talker`` node that publishes a "hello world" message every second, and a ``listener`` node that listens to these messages. By :doc:`sourcing ROS 2 <../../Beginner-CLI-Tools/Configuring-ROS2-Environment>` you will get access to the CLI tool ``fastdds``. -This tool gives access to the `discovery tool `__, which can be used to launch a discovery server. This server will manage the discovery process for the nodes that connect to it. +This tool gives access to the `discovery tool `__, which can be used to launch a discovery server. +This server will manage the discovery process for the nodes that connect to it. .. important:: @@ -117,7 +118,8 @@ In a new terminal, set the environment variable ``ROS_DISCOVERY_SERVER`` to the set ROS_DISCOVERY_SERVER=127.0.0.1:11811 -Launch the listener node. Use the argument ``--remap __node:=listener_discovery_server`` to change the node's name for this tutorial. +Launch the listener node. +Use the argument ``--remap __node:=listener_discovery_server`` to change the node's name for this tutorial. .. code-block:: console @@ -330,7 +332,9 @@ In another terminal run the second server listening on localhost using another p fastdds discovery --server-id 1 --ip-address 127.0.0.1 --port 11888 -Now, run each node in a different terminal. Use ``ROS_DISCOVERY_SERVER`` environment variable to decide which server they are connected to. Be aware that the `ids must match `__. +Now, run each node in a different terminal. +Use ``ROS_DISCOVERY_SERVER`` environment variable to decide which server they are connected to. +Be aware that the `ids must match `__. .. tabs:: @@ -428,7 +432,8 @@ In this sense, ROS 2 introspection tools can be configured as **Super Client**, .. note:: - In this section we use the term *Participant* as a DDS entity. Each DDS *Participant* corresponds with a ROS 2 *Context*, a ROS 2 abstraction over DDS. + In this section we use the term *Participant* as a DDS entity. + Each DDS *Participant* corresponds with a ROS 2 *Context*, a ROS 2 abstraction over DDS. `Nodes ` are ROS 2 entities that rely on DDS communication interfaces: ``DataWriter`` and ``DataReader``. Each *Participant* can hold multiple ROS 2 Nodes. For further details about these concepts, please visit the `Node to Participant mapping design document `__ diff --git a/source/Tutorials/Advanced/FastDDS-Configuration.rst b/source/Tutorials/Advanced/FastDDS-Configuration.rst index 61fdb10bb11..94e69449b17 100644 --- a/source/Tutorials/Advanced/FastDDS-Configuration.rst +++ b/source/Tutorials/Advanced/FastDDS-Configuration.rst @@ -453,7 +453,7 @@ In order to use the values in the XML file, the environment variable ``RMW_FASTR However, this entails **another caveat**: If ``RMW_FASTRTPS_USE_QOS_FROM_XML`` is set, but the XML file does not define ``publishMode`` or ``historyMemoryPolicy``, these attributes take the *Fast DDS* default value instead of the ``rmw_fastrtps`` default value. -This is important, especially for ``historyMemoryPolicy``, because the *Fast DDS* deafult value is ``PREALLOCATED`` which does not work with ROS2 topic data types. +This is important, especially for ``historyMemoryPolicy``, because the *Fast DDS* default value is ``PREALLOCATED`` which does not work with ROS2 topic data types. Therefore, in the example, a valid value for this policy has been explicitly set (``DYNAMIC``). diff --git a/source/Tutorials/Advanced/Improved-Dynamic-Discovery.rst b/source/Tutorials/Advanced/Improved-Dynamic-Discovery.rst index c9a8cba6694..fcd0e4086ab 100755 --- a/source/Tutorials/Advanced/Improved-Dynamic-Discovery.rst +++ b/source/Tutorials/Advanced/Improved-Dynamic-Discovery.rst @@ -227,28 +227,28 @@ For example, the following commands will limit the ROS 2 communication only with .. code-block:: console export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST - export ROS_STATIC_PEERS=192.168.0.1;remote.com + export ROS_STATIC_PEERS='192.168.0.1;remote.com' To maintain this setting between shell sessions, you can add the command to your shell startup script: .. code-block:: console echo "export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST" >> ~/.bashrc - echo "export ROS_STATIC_PEERS=192.168.0.1;remote.com" >> ~/.bashrc + echo "export ROS_STATIC_PEERS='192.168.0.1;remote.com'" >> ~/.bashrc .. group-tab:: macOS .. code-block:: console export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST - export ROS_STATIC_PEERS=192.168.0.1;remote.com + export ROS_STATIC_PEERS='192.168.0.1;remote.com' To maintain this setting between shell sessions, you can add the command to your shell startup script: .. code-block:: console echo "export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST" >> ~/.bash_profile - echo "export ROS_STATIC_PEERS=192.168.0.1;remote.com" >> ~/.bash_profile + echo "export ROS_STATIC_PEERS='192.168.0.1;remote.com'" >> ~/.bash_profile .. group-tab:: Windows diff --git a/source/Tutorials/Advanced/Reading-From-A-Bag-File-CPP.rst b/source/Tutorials/Advanced/Reading-From-A-Bag-File-CPP.rst index 88118b1dc54..ce984c6dc9e 100644 --- a/source/Tutorials/Advanced/Reading-From-A-Bag-File-CPP.rst +++ b/source/Tutorials/Advanced/Reading-From-A-Bag-File-CPP.rst @@ -204,7 +204,7 @@ Then, we can pass both these objects to the ``rclcpp::Serialization::deserialize serialization_.deserialize_message(&serialized_msg, ros_msg.get()); Finally, we publish the deserialized message and print out the xy coordinate to the terminal. -We also break out of the loop so that we publish the next message during the next timer calback. +We also break out of the loop so that we publish the next message during the next timer callback. .. code-block:: C++ diff --git a/source/Tutorials/Advanced/Reading-From-A-Bag-File-Python.rst b/source/Tutorials/Advanced/Reading-From-A-Bag-File-Python.rst index 68bf7b8bb6b..c2bcccc7f17 100644 --- a/source/Tutorials/Advanced/Reading-From-A-Bag-File-Python.rst +++ b/source/Tutorials/Advanced/Reading-From-A-Bag-File-Python.rst @@ -68,8 +68,8 @@ Also be sure to add this information to the ``setup.py`` file as well. description='Python bag reading tutorial', license='Apache-2.0', -2 Write the C++ Reader -^^^^^^^^^^^^^^^^^^^^^^ +2 Write the Python Reader +^^^^^^^^^^^^^^^^^^^^^^^^^ Inside the ``ros2_ws/src/bag_reader_node_py/bag_reader_node_py`` directory, create a new file called ``simple_bag_reader.py`` and paste the following code into it. @@ -87,10 +87,10 @@ Inside the ``ros2_ws/src/bag_reader_node_py/bag_reader_node_py`` directory, crea def __init__(self): super().__init__('simple_bag_reader') self.reader = rosbag2_py.SequentialReader() - storage_options = rosbag2_py._storage.StorageOptions( + storage_options = rosbag2_py.StorageOptions( uri='my_bag', storage_id='mcap') - converter_options = rosbag2_py._storage.ConverterOptions('', '') + converter_options = rosbag2_py.ConverterOptions('', '') self.reader.open(storage_options, converter_options) self.publisher = self.create_publisher(String, 'chatter', 10) @@ -138,10 +138,10 @@ The default conversion options are used, which will perform no conversion and st .. code-block:: Python - storage_options = rosbag2_py._storage.StorageOptions( + storage_options = rosbag2_py.StorageOptions( uri='my_bag', storage_id='mcap') - converter_options = rosbag2_py._storage.ConverterOptions('', '') + converter_options = rosbag2_py.ConverterOptions('', '') self.reader.open(storage_options, converter_options) Next, we create a publisher and a timer to publish the data that reader object reads from the bag file. diff --git a/source/Tutorials/Advanced/Recording-A-Bag-From-Your-Own-Node-Py.rst b/source/Tutorials/Advanced/Recording-A-Bag-From-Your-Own-Node-Py.rst index 85fc1513141..4e86d5877d9 100644 --- a/source/Tutorials/Advanced/Recording-A-Bag-From-Your-Own-Node-Py.rst +++ b/source/Tutorials/Advanced/Recording-A-Bag-From-Your-Own-Node-Py.rst @@ -104,13 +104,13 @@ Inside the ``ros2_ws/src/bag_recorder_nodes_py/bag_recorder_nodes_py`` directory super().__init__('simple_bag_recorder') self.writer = rosbag2_py.SequentialWriter() - storage_options = rosbag2_py._storage.StorageOptions( + storage_options = rosbag2_py.StorageOptions( uri='my_bag', storage_id='mcap') - converter_options = rosbag2_py._storage.ConverterOptions('', '') + converter_options = rosbag2_py.ConverterOptions('', '') self.writer.open(storage_options, converter_options) - topic_info = rosbag2_py._storage.TopicMetadata( + topic_info = rosbag2_py.TopicMetadata( id=0, name='chatter', type='std_msgs/msg/String', @@ -163,10 +163,10 @@ The default conversion options are used, which will perform no conversion and st .. code-block:: Python - storage_options = rosbag2_py._storage.StorageOptions( + storage_options = rosbag2_py.StorageOptions( uri='my_bag', storage_id='mcap') - converter_options = rosbag2_py._storage.ConverterOptions('', '') + converter_options = rosbag2_py.ConverterOptions('', '') self.writer.open(storage_options, converter_options) Next, we need to tell the writer about the topics we wish to store. @@ -175,7 +175,7 @@ This object specifies the topic name, topic data type, and serialization format .. code-block:: Python - topic_info = rosbag2_py._storage.TopicMetadata( + topic_info = rosbag2_py.TopicMetadata( id=0, name='chatter', type='std_msgs/msg/String', @@ -346,13 +346,13 @@ Inside the ``ros2_ws/src/bag_recorder_nodes_py/bag_recorder_nodes_py`` directory self.data.data = 0 self.writer = rosbag2_py.SequentialWriter() - storage_options = rosbag2_py._storage.StorageOptions( + storage_options = rosbag2_py.StorageOptions( uri='timed_synthetic_bag', storage_id='mcap') - converter_options = rosbag2_py._storage.ConverterOptions('', '') + converter_options = rosbag2_py.ConverterOptions('', '') self.writer.open(storage_options, converter_options) - topic_info = rosbag2_py._storage.TopicMetadata( + topic_info = rosbag2_py.TopicMetadata( id=0, name='synthetic', type='example_interfaces/msg/Int32', @@ -391,7 +391,7 @@ First, the name of the bag is changed. .. code-block:: Python - storage_options = rosbag2_py._storage.StorageOptions( + storage_options = rosbag2_py.StorageOptions( uri='timed_synthetic_bag', storage_id='mcap') @@ -399,7 +399,7 @@ The name of the topic is also changed, as is the data type stored. .. code-block:: Python - topic_info = rosbag2_py._storage.TopicMetadata( + topic_info = rosbag2_py.TopicMetadata( id=0, name='synthetic', type='example_interfaces/msg/Int32', @@ -531,13 +531,13 @@ Inside the ``ros2_ws/src/bag_recorder_nodes_py/bag_recorder_nodes_py`` directory def main(args=None): writer = rosbag2_py.SequentialWriter() - storage_options = rosbag2_py._storage.StorageOptions( + storage_options = rosbag2_py.StorageOptions( uri='big_synthetic_bag', storage_id='mcap') - converter_options = rosbag2_py._storage.ConverterOptions('', '') + converter_options = rosbag2_py.ConverterOptions('', '') writer.open(storage_options, converter_options) - topic_info = rosbag2_py._storage.TopicMetadata( + topic_info = rosbag2_py.TopicMetadata( id=0, name='synthetic', type='example_interfaces/msg/Int32', diff --git a/source/Tutorials/Advanced/Security/Access-Controls.rst b/source/Tutorials/Advanced/Security/Access-Controls.rst index 511520dc9b7..ef30adae135 100644 --- a/source/Tutorials/Advanced/Security/Access-Controls.rst +++ b/source/Tutorials/Advanced/Security/Access-Controls.rst @@ -111,7 +111,7 @@ Sign the policy file This next command creates the new S/MIME signed policy file ``permissions.p7s`` from the updated XML file ``permissions.xml``. The file must be signed with the Permissions CA certificate, **which requires access to the Permission CA private key**. -If the private key has been protected, additional steps may be required to unlock and use it accoring to your security plan. +If the private key has been protected, additional steps may be required to unlock and use it according to your security plan. .. code-block:: bash diff --git a/source/Tutorials/Advanced/Security/Deployment-Guidelines.rst b/source/Tutorials/Advanced/Security/Deployment-Guidelines.rst index eab8b362285..8a2b86a4156 100644 --- a/source/Tutorials/Advanced/Security/Deployment-Guidelines.rst +++ b/source/Tutorials/Advanced/Security/Deployment-Guidelines.rst @@ -16,7 +16,7 @@ Background ---------- Typical deployment scenarios often involve shipping containerized applications, or packages, into remote systems. -Special attention should be payed when deploying security enabled applications, requiring users to reason about the sensitivity of packaged files. +Special attention should be paid when deploying security enabled applications, requiring users to reason about the sensitivity of packaged files. Complying with the `DDS Security standard `_, the ``sros2`` package provides a collection of utilities for managing security under ROS 2 environments in a highly modular and flexible fashion. @@ -30,7 +30,8 @@ Prerequisites * A docker installation with the compose plugin. Please refer to the installation steps detailed in `Docker installation `_ and `Compose Plugin `_. * (Recommended) A basic understanding on `ROS 2 Security design `_. -* (Recommended) Previous security tutorials completion. In particular: +* (Recommended) Previous security tutorials completion. + In particular: * :doc:`Introducing-ros2-security` * :doc:`The-Keystore` @@ -124,7 +125,7 @@ Now, build the docker image with the command: Understanding the compose file ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A compose configration file takes an image to create containers as services. +A compose configuration file takes an image to create containers as services. In this tutorial, three services are defined within the configuration: * *keystore-creator*: That, similarly to previous tutorials, it internally initializes a new keystore tree directory. diff --git a/source/Tutorials/Advanced/Security/Examine-Traffic.rst b/source/Tutorials/Advanced/Security/Examine-Traffic.rst index 2a9bc7f66ba..254c8469448 100644 --- a/source/Tutorials/Advanced/Security/Examine-Traffic.rst +++ b/source/Tutorials/Advanced/Security/Examine-Traffic.rst @@ -185,7 +185,8 @@ The typical discovery packet looks somewhat like the following:: This packet is much larger and includes information which can be used to set up encryption among ROS nodes. As we will see shortly, this actually includes some of the security configuration files that were created when we enabled security. -Interested in learning more? Take a look at the excellent paper `Network Reconnaissance and Vulnerability Excavation of Secure DDS Systems `_ to understand why this matters. +Interested in learning more? +Take a look at the excellent paper `Network Reconnaissance and Vulnerability Excavation of Secure DDS Systems `_ to understand why this matters. Display encrypted data packets diff --git a/source/Tutorials/Advanced/Security/Introducing-ros2-security.rst b/source/Tutorials/Advanced/Security/Introducing-ros2-security.rst index 2c5fdd49b8d..cce97f136f7 100644 --- a/source/Tutorials/Advanced/Security/Introducing-ros2-security.rst +++ b/source/Tutorials/Advanced/Security/Introducing-ros2-security.rst @@ -71,7 +71,7 @@ Fast DDS requires an additional CMake flag to build the security plugins, so the .. code-block:: bash - colcon build --symlink-install --cmake-args -DSECURITY=ON + colcon build --symlink-install --cmake-args -DSECURITY=ON --packages-select fastrtps rmw_fastrtps_cpp rmw_fastrtps_dynamic_cpp rmw_fastrtps_shared_cpp Selecting an alternate middleware @@ -80,7 +80,7 @@ Selecting an alternate middleware If you choose not to use the default middleware implementation, be sure to :doc:`change your DDS implementation <../../../Installation/DDS-Implementations/>` before proceeding. ROS 2 allows you to change the DDS implementation at runtime. -See `how to work with mulitple RMW implementations <../../../How-To-Guides/Working-with-multiple-RMW-implementations>` to explore different middleware implementations. +See `how to work with multiple RMW implementations <../../../How-To-Guides/Working-with-multiple-RMW-implementations>` to explore different middleware implementations. Note that secure communication between vendors is not supported. diff --git a/source/Tutorials/Advanced/Security/The-Keystore.rst b/source/Tutorials/Advanced/Security/The-Keystore.rst index 8efba9e16ae..23aeba16aa3 100644 --- a/source/Tutorials/Advanced/Security/The-Keystore.rst +++ b/source/Tutorials/Advanced/Security/The-Keystore.rst @@ -24,8 +24,8 @@ Background Before proceeding ensure you have completed the :doc:`Introducing-ros2-security` tutorial. The ``sros2`` package can be used to create keys, certificates and policies necessary to enable ROS 2 security. -However, the security configuration is extrememly flexible. -A basic understanding of the ROS 2 Security Keystore will allow integration with an existing PKI (Public Key Infrastructure) and managment of sensitive key materials consistent with organizational policies. +However, the security configuration is extremely flexible. +A basic understanding of the ROS 2 Security Keystore will allow integration with an existing PKI (Public Key Infrastructure) and management of sensitive key materials consistent with organizational policies. Security Artifact Locations @@ -177,11 +177,11 @@ Secure processes (typically ROS nodes) run within a security enclave. In the simplest case, all the processes can be consolidated into the same enclave, and all processes will then use the same security policy. However, to apply different policies to different processes, the processes can use different security enclaves when starting. For more details about security enclaves, see the `design document `_. -The security enclave is specifed by using the ROS argument ``--enclave`` when running a node. +The security enclave is specified by using the ROS argument ``--enclave`` when running a node. **Each security enclave requires six files** in order to enable security. Each file **must** be named as defined below, and as outlined in the `DDS Security standard `_. -In order to avoid having mulitple copies of the same files, the ``sros2`` utilities create links for each enclave to the single governance policy, the Identity CA and Permissions CA descibed above. +In order to avoid having multiple copies of the same files, the ``sros2`` utilities create links for each enclave to the single governance policy, the Identity CA and Permissions CA described above. See the following six files within the ``listener`` enclave. Three are specific to this enclave, while three are generic to this ROS system: diff --git a/source/Tutorials/Advanced/Simulators/Webots/Installation-MacOS.rst b/source/Tutorials/Advanced/Simulators/Webots/Installation-MacOS.rst index 7fd83be0712..cbf850f6d31 100644 --- a/source/Tutorials/Advanced/Simulators/Webots/Installation-MacOS.rst +++ b/source/Tutorials/Advanced/Simulators/Webots/Installation-MacOS.rst @@ -59,7 +59,8 @@ In the UTM software: * Leave all the remaining parameters as default. * Start the VM. Note that you can select another shared folder each time you start the VM. -* During the first launch of the VM, install Ubuntu and choose a username for your account. In this example, the username is ``ubuntu``. +* During the first launch of the VM, install Ubuntu and choose a username for your account. + In this example, the username is ``ubuntu``. * Once Ubuntu is installed, close the VM, remove the iso image from the CD/DVD field and restart the VM. 2 Configure the VM diff --git a/source/Tutorials/Advanced/Simulators/Webots/Installation-Windows.rst b/source/Tutorials/Advanced/Simulators/Webots/Installation-Windows.rst index fcc93231580..51f8120f4bd 100644 --- a/source/Tutorials/Advanced/Simulators/Webots/Installation-Windows.rst +++ b/source/Tutorials/Advanced/Simulators/Webots/Installation-Windows.rst @@ -165,7 +165,8 @@ The Tiago robot can be controlled using: ros2 run teleop_twist_keyboard teleop_twist_keyboard -With older WSL versions, RViz2 may not work directly, as no display is available. To use RViz, you can either upgrade WSL or enable X11 forwarding. +With older WSL versions, RViz2 may not work directly, as no display is available. +To use RViz, you can either upgrade WSL or enable X11 forwarding. .. tabs:: .. group-tab:: Upgrade WSL diff --git a/source/Tutorials/Advanced/Simulators/Webots/Simulation-Supervisor.rst b/source/Tutorials/Advanced/Simulators/Webots/Simulation-Supervisor.rst index d16b4980b6e..06a9efe9188 100644 --- a/source/Tutorials/Advanced/Simulators/Webots/Simulation-Supervisor.rst +++ b/source/Tutorials/Advanced/Simulators/Webots/Simulation-Supervisor.rst @@ -32,7 +32,8 @@ The ``Ros2Supervisor`` The ``Ros2Supervisor`` is made of two main parts: -* A Webots Robot node added to the simulation world. Its ``supervisor`` field is set to TRUE. +* A Webots Robot node added to the simulation world. + Its ``supervisor`` field is set to TRUE. * A ROS 2 node that connects to the Webots Robot as an extern controller (in a similar way to your own robot plugin). The ROS 2 node acts as a controller that calls Supervisor API functions to control or interact with the simulation world. diff --git a/source/Tutorials/Advanced/Topic-Statistics-Tutorial/Topic-Statistics-Tutorial.rst b/source/Tutorials/Advanced/Topic-Statistics-Tutorial/Topic-Statistics-Tutorial.rst index 9fc850fc956..7d94dbf8263 100644 --- a/source/Tutorials/Advanced/Topic-Statistics-Tutorial/Topic-Statistics-Tutorial.rst +++ b/source/Tutorials/Advanced/Topic-Statistics-Tutorial/Topic-Statistics-Tutorial.rst @@ -324,8 +324,9 @@ Summary ------- You created a subscriber node with topic statistics enabled, which published statistics data from -the :doc:`C++ <../../Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client>`'s publisher node. You were able to compile and run this node. While running, -you were able to observe the statistics data. +the :doc:`C++ <../../Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client>`'s publisher node. +You were able to compile and run this node. +While running, you were able to observe the statistics data. Related content --------------- diff --git a/source/Tutorials/Beginner-CLI-Tools/Configuring-ROS2-Environment.rst b/source/Tutorials/Beginner-CLI-Tools/Configuring-ROS2-Environment.rst index ade973c487f..e1f4ddc7c8f 100644 --- a/source/Tutorials/Beginner-CLI-Tools/Configuring-ROS2-Environment.rst +++ b/source/Tutorials/Beginner-CLI-Tools/Configuring-ROS2-Environment.rst @@ -111,7 +111,7 @@ If you don't want to have to source the setup file every time you open a new she C:\dev\ros2_{DISTRO}\local_setup.ps1 - PowerShell will request permission to run this script everytime a new shell is opened. + PowerShell will request permission to run this script every time a new shell is opened. To avoid that issue you can run: .. code-block:: console diff --git a/source/Tutorials/Beginner-CLI-Tools/Launching-Multiple-Nodes/Launching-Multiple-Nodes.rst b/source/Tutorials/Beginner-CLI-Tools/Launching-Multiple-Nodes/Launching-Multiple-Nodes.rst index ba7ed9da43c..c37bc7109cd 100644 --- a/source/Tutorials/Beginner-CLI-Tools/Launching-Multiple-Nodes/Launching-Multiple-Nodes.rst +++ b/source/Tutorials/Beginner-CLI-Tools/Launching-Multiple-Nodes/Launching-Multiple-Nodes.rst @@ -38,6 +38,8 @@ You also won't be able to use the ``sudo apt install ros--`` co If you are using Linux and are not already familiar with the shell, `this tutorial `__ will help. +As always, don't forget to source ROS 2 in :doc:`every new terminal you open <../Configuring-ROS2-Environment>`. + Tasks ----- diff --git a/source/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Nodes/Understanding-ROS2-Nodes.rst b/source/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Nodes/Understanding-ROS2-Nodes.rst index cce9f52d0ef..4c50501f268 100644 --- a/source/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Nodes/Understanding-ROS2-Nodes.rst +++ b/source/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Nodes/Understanding-ROS2-Nodes.rst @@ -142,7 +142,8 @@ To examine your latest node, ``my_turtle``, run the following command: ros2 node info /my_turtle -``ros2 node info`` returns a list of subscribers, publishers, services, and actions. i.e. the ROS graph connections that interact with that node. +``ros2 node info`` returns a list of subscribers, publishers, services, and actions. +i.e. the ROS graph connections that interact with that node. The output should look like this: .. code-block:: console diff --git a/source/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Parameters/Understanding-ROS2-Parameters.rst b/source/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Parameters/Understanding-ROS2-Parameters.rst index 5d28b52f8ec..8ad0b507316 100644 --- a/source/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Parameters/Understanding-ROS2-Parameters.rst +++ b/source/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Parameters/Understanding-ROS2-Parameters.rst @@ -85,6 +85,8 @@ You will see the node namespaces, ``/teleop_turtle`` and ``/turtlesim``, followe qos_overrides./parameter_events.publisher.reliability use_sim_time +The namespaces of the parameter and its name are separated using dots as you can see, for example, in ``parameter_events.publisher.depth``. + Every node has the parameter ``use_sim_time``; it's not unique to turtlesim. Based on their names, it looks like ``/turtlesim``'s parameters determine the background color of the turtlesim window using RGB color values. @@ -214,6 +216,8 @@ Your terminal will return the message: Read-only parameters can only be modified at startup and not afterwards, that is why there are some warnings for the "qos_overrides" parameters. +.. _LoadParameterFileOnNodeStartup: + 7 Load parameter file on node startup ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/source/Tutorials/Beginner-Client-Libraries/Colcon-Tutorial.rst b/source/Tutorials/Beginner-Client-Libraries/Colcon-Tutorial.rst index 92d9b8fa98c..1e94a073900 100644 --- a/source/Tutorials/Beginner-Client-Libraries/Colcon-Tutorial.rst +++ b/source/Tutorials/Beginner-Client-Libraries/Colcon-Tutorial.rst @@ -340,7 +340,7 @@ The ``colcon-argcomplete`` package must be installed, and `some setup may be req Tips ---- -* If you do not want to build a specific package place an empty file named ``COLCON_IGNORE`` in the directory and it will not be indexed. +* If you do not want to build a specific package, then place an empty file named ``COLCON_IGNORE`` in the directory and it will not be indexed. * If you want to avoid configuring and building tests in CMake packages you can pass: ``--cmake-args -DBUILD_TESTING=0``. diff --git a/source/Tutorials/Beginner-Client-Libraries/Pluginlib.rst b/source/Tutorials/Beginner-Client-Libraries/Pluginlib.rst index ed95dd1a588..c8e1557e3ce 100644 --- a/source/Tutorials/Beginner-Client-Libraries/Pluginlib.rst +++ b/source/Tutorials/Beginner-Client-Libraries/Pluginlib.rst @@ -189,7 +189,8 @@ Create ``ros2_ws/src/polygon_plugins/plugins.xml`` with the following code: A couple things to note: 1. The ``library`` tag gives the relative path to a library that contains the plugins that we want to export. - In ROS 2, that is just the name of the library. In ROS 1, it contained the prefix ``lib`` or sometimes ``lib/lib`` (i.e. ``lib/libpolygon_plugins``), but here it is simpler. + In ROS 2, that is just the name of the library. + In ROS 1, it contained the prefix ``lib`` or sometimes ``lib/lib`` (i.e. ``lib/libpolygon_plugins``), but here it is simpler. 2. The ``class`` tag declares a plugin that we want to export from our library. Let's go through its parameters: @@ -313,4 +314,5 @@ It should print: Summary ------- -Congratulations! You've just written and used your first plugins. +Congratulations! +You've just written and used your first plugins. diff --git a/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-CPP.rst b/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-CPP.rst index 20102288586..24320fc3b34 100644 --- a/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-CPP.rst +++ b/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-CPP.rst @@ -22,7 +22,7 @@ Background When making your own :doc:`nodes <../Beginner-CLI-Tools/Understanding-ROS2-Nodes/Understanding-ROS2-Nodes>` you will sometimes need to add parameters that can be set from the launch file. -This tutorial will show you how to create those parameters in a C++ class, and how to set them in a launch file. +This tutorial will show you how to create those parameters in a C++ class, and how to set them using launch file. Prerequisites ------------- @@ -297,7 +297,7 @@ The terminal should return the following message every second: [INFO] [minimal_param_node]: Hello world! Now you can see the default value of your parameter, but you want to be able to set it yourself. -There are two ways to accomplish this. +There are four ways to accomplish this. 3.1 Change via the console ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -428,6 +428,22 @@ The terminal should return the following message the first time: Further outputs should show ``[INFO] [minimal_param_node]: Hello world!`` every second. +3.3 Change via launch file loading parameters from YAML file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instead of listing parameters and their values in launch file, you can create a separate YAML file that will be loaded in launch file. +Placing parameters in a YAML file makes it easier to organize them, for example, by assigning them to different namespaces. +You can read more about it :ref:`here `. + +.. note:: + + While declaring, getting and setting parameter value inside your C++ node, you should use dot as a separator between parameter's namespace and name. + +3.4 Change via passing YAML file as an argument at node startup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Return to :ref:`tutorial about parameters ` to remind yourself, how to load parameters file at node startup using CLI. + Summary ------- @@ -438,3 +454,9 @@ Next steps ---------- Now that you have some packages and ROS 2 systems of your own, the :doc:`next tutorial <./Getting-Started-With-Ros2doctor>` will show you how to examine issues in your environment and systems in case you have problems. + +Related content +--------------- + +* For more detailed information about using YAML files to load parameters, please refer to :ref:`this section ` of Managing large projects tutorial. +* If you want to learn, how to monitor and respond to parameter changes, check out :doc:`Monitoring for parameter changes (C++) <../Intermediate/Monitoring-For-Parameter-Changes-CPP>` tutorial. diff --git a/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-Python.rst b/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-Python.rst index 7e87b472a52..6f919ed31da 100644 --- a/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-Python.rst +++ b/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-Python.rst @@ -22,7 +22,7 @@ Background When making your own :doc:`nodes <../Beginner-CLI-Tools/Understanding-ROS2-Nodes/Understanding-ROS2-Nodes>` you will sometimes need to add parameters that can be set from the launch file. -This tutorial will show you how to create those parameters in a Python class, and how to set them in a launch file. +This tutorial will show you how to create those parameters in a Python class, and how to set them using launch file. Prerequisites ------------- @@ -294,12 +294,12 @@ The terminal should return the following message every second: [INFO] [parameter_node]: Hello world! Now you can see the default value of your parameter, but you want to be able to set it yourself. -There are two ways to accomplish this. +There are four ways to accomplish this. 3.1 Change via the console ~~~~~~~~~~~~~~~~~~~~~~~~~~ -This part will use the knowledge you have gained from the :doc:`tutoral about parameters <../Beginner-CLI-Tools/Understanding-ROS2-Parameters/Understanding-ROS2-Parameters>` and apply it to the node you have just created. +This part will use the knowledge you have gained from the :doc:`tutorial about parameters <../Beginner-CLI-Tools/Understanding-ROS2-Parameters/Understanding-ROS2-Parameters>` and apply it to the node you have just created. Make sure the node is running: @@ -434,6 +434,22 @@ The terminal should return the following message the first time: Further outputs should show ``[INFO] [minimal_param_node]: Hello world!`` every second. +3.3 Change via launch file loading parameters from YAML file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instead of listing parameters and their values in launch file, you can create a separate YAML file that will be loaded in launch file. +Placing parameters in a YAML file makes it easier to organize them, for example, by assigning them to different namespaces. +You can read more about it :ref:`here `. + +.. note:: + + While declaring, getting and setting parameter value inside your Python node, you should use dot as a separator between parameter's namespace and name. + +3.4 Change via passing YAML file as an argument at node startup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Return to :ref:`tutorial about parameters ` to remind yourself, how to load parameters file at node startup using CLI. + Summary ------- @@ -444,3 +460,9 @@ Next steps ---------- Now that you have some packages and ROS 2 systems of your own, the :doc:`next tutorial <./Getting-Started-With-Ros2doctor>` will show you how to examine issues in your environment and systems in case you have problems. + +Related content +--------------- + +* For more detailed information about using YAML files to load parameters, please refer to :ref:`this section ` of Managing large projects tutorial. +* If you want to learn, how to monitor and respond to parameter changes, check out :doc:`Monitoring for parameter changes (Python) <../Intermediate/Monitoring-For-Parameter-Changes-Python>` tutorial. diff --git a/source/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.rst b/source/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.rst index 0a71492ba88..a1a743ad30f 100644 --- a/source/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.rst +++ b/source/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.rst @@ -215,7 +215,7 @@ Inside the ``ros2_ws/src/cpp_srvcli/src`` directory, create a new file called `` request->a = 41; request->b = 1; auto result_future = client->async_send_request(request); - if (rclcpp::spin_until_future_complete(node, result_future) == + if (rclcpp::spin_until_future_complete(node, result_future) != rclcpp::FutureReturnCode::SUCCESS) { RCLCPP_ERROR(node->get_logger(), "service call failed :("); diff --git a/source/Tutorials/Demos/Intra-Process-Communication.rst b/source/Tutorials/Demos/Intra-Process-Communication.rst index 50a5217c4ac..acd65439876 100644 --- a/source/Tutorials/Demos/Intra-Process-Communication.rst +++ b/source/Tutorials/Demos/Intra-Process-Communication.rst @@ -324,7 +324,8 @@ The watermark and image view nodes are designed to modify the image without copy .. note:: On some systems (we've seen it happen on Linux), the address printed to the screen might not change. - This is because the same unique pointer is being reused. In this situation, the pipeline is still running. + This is because the same unique pointer is being reused. + In this situation, the pipeline is still running. Let's run the demo by executing the following executable: @@ -347,7 +348,8 @@ Pipeline with two image viewers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Now let's look at an example just like the one above, except it has two image view nodes. -All the nodes are still in the same process, but now two image view windows should show up. (Note for macOS users: your image view windows might be on top of each other). +All the nodes are still in the same process, but now two image view windows should show up. +(Note for macOS users: your image view windows might be on top of each other). Let's run it with the command: .. code-block:: bash @@ -358,26 +360,39 @@ Let's run it with the command: .. image:: images/intra-process-demo-pipeline-two-windows-copy.png -Just like the last example, you can pause the rendering with the spacebar and continue by pressing the spacebar a second time. You can stop the updating to inspect the pointers written to the screen. +Just like the last example, you can pause the rendering with the spacebar and continue by pressing the spacebar a second time. +You can stop the updating to inspect the pointers written to the screen. -As you can see in the example image above, we have one image with all of the pointers the same and then another image with the same pointers as the first image for the first two entries, but the last pointer on the second image is different. To understand why this is happening consider the graph's topology: +As you can see in the example image above, we have one image with all of the pointers the same and then another image with the same pointers as the first image for the first two entries, but the last pointer on the second image is different. +To understand why this is happening consider the graph's topology: .. code-block:: bash camera_node -> watermark_node -> image_view_node -> image_view_node2 -The link between the ``camera_node`` and the ``watermark_node`` can use the same pointer without copying because there is only one intra process subscription to which the message should be delivered. But for the link between the ``watermark_node`` and the two image view nodes the relationship is one to many, so if the image view nodes were using ``unique_ptr`` callbacks then it would be impossible to deliver the ownership of the same pointer to both. It can be, however, delivered to one of them. Which one would get the original pointer is not defined, but instead is simply the last to be delivered. +The link between the ``camera_node`` and the ``watermark_node`` can use the same pointer without copying because there is only one intra process subscription to which the message should be delivered. +But for the link between the ``watermark_node`` and the two image view nodes the relationship is one to many, so if the image view nodes were using ``unique_ptr`` callbacks then it would be impossible to deliver the ownership of the same pointer to both. +It can be, however, delivered to one of them. +Which one would get the original pointer is not defined, but instead is simply the last to be delivered. -Note that the image view nodes are not subscribed with ``unique_ptr`` callbacks. Instead they are subscribed with ``const shared_ptr``\ s. This means the system deliveres the same ``shared_ptr`` to both callbacks. When the first intraprocess subscription is handled, the internally stored ``unique_ptr`` is promoted to a ``shared_ptr``. Each of the callbacks will receive shared ownership of the same message. +Note that the image view nodes are not subscribed with ``unique_ptr`` callbacks. +Instead they are subscribed with ``const shared_ptr``\ s. +This means the system deliveres the same ``shared_ptr`` to both callbacks. +When the first intraprocess subscription is handled, the internally stored ``unique_ptr`` is promoted to a ``shared_ptr``. +Each of the callbacks will receive shared ownership of the same message. Pipeline with interprocess viewer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -One other important thing to get right is to avoid interruption of the intra process zero-copy behavior when interprocess subscriptions are made. To test this we can run the first image pipeline demo, ``image_pipeline_all_in_one``, and then run an instance of the stand alone ``image_view_node`` (don't forget to prefix them with ``ros2 run intra_process_demo`` in the terminal). This will look something like this: +One other important thing to get right is to avoid interruption of the intra process zero-copy behavior when interprocess subscriptions are made. +To test this we can run the first image pipeline demo, ``image_pipeline_all_in_one``, and then run an instance of the stand alone ``image_view_node`` (don't forget to prefix them with ``ros2 run intra_process_demo`` in the terminal). +This will look something like this: .. image:: images/intra-process-demo-pipeline-inter-process.png -It's hard to pause both images at the same time so the images may not line up, but the important thing to notice is that the ``image_pipeline_all_in_one`` image view shows the same address for each step. This means that the intra process zero-copy is preserved even when an external view is subscribed as well. You can also see that the interprocess image view has different process IDs for the first two lines of text and the process ID of the standalone image viewer in the third line of text. +It's hard to pause both images at the same time so the images may not line up, but the important thing to notice is that the ``image_pipeline_all_in_one`` image view shows the same address for each step. +This means that the intra process zero-copy is preserved even when an external view is subscribed as well. +You can also see that the interprocess image view has different process IDs for the first two lines of text and the process ID of the standalone image viewer in the third line of text. diff --git a/source/Tutorials/Demos/Quality-of-Service.rst b/source/Tutorials/Demos/Quality-of-Service.rst index 4620196f78f..8d2ade34a49 100644 --- a/source/Tutorials/Demos/Quality-of-Service.rst +++ b/source/Tutorials/Demos/Quality-of-Service.rst @@ -126,7 +126,8 @@ In the first window, you'll see output from the subscriber: $ sudo sysctl -w net.inet.udp.recvspace=209715 $ sudo sysctl -w net.inet.udp.maxdgram=65500 - These changes will not persist a reboot. If you want the changes to persist, add these lines to ``/etc/sysctl.conf`` (create the file if it doesn't exist already): + These changes will not persist a reboot. + If you want the changes to persist, add these lines to ``/etc/sysctl.conf`` (create the file if it doesn't exist already): .. code-block:: bash diff --git a/source/Tutorials/Demos/Real-Time-Programming.rst b/source/Tutorials/Demos/Real-Time-Programming.rst index 83739fbe92b..6cc079f80ab 100644 --- a/source/Tutorials/Demos/Real-Time-Programming.rst +++ b/source/Tutorials/Demos/Real-Time-Programming.rst @@ -16,7 +16,8 @@ Background Real-time computing is a key feature of many robotics systems, particularly safety- and mission-critical applications such as autonomous vehicles, spacecrafts, and industrial manufacturing. We are designing and prototyping ROS 2 with real-time performance constraints in mind, since this is a requirement that was not considered in the early stages of ROS 1 and it is now intractable to refactor ROS 1 to be real-time friendly. -`This document `__ outlines the requirements of real-time computing and best practices for software engineers. In short: +`This document `__ outlines the requirements of real-time computing and best practices for software engineers. +In short: To make a real-time computer system, our real-time loop must update periodically to meet deadlines. We can only tolerate a small margin of error on these deadlines (our maximum allowable jitter). @@ -35,18 +36,21 @@ The real-time demo was written with Linux operating systems in mind, since many Since many of the operations done in the demo to optimize performance are OS-specific, the demo only builds and runs on Linux systems. **So, if you are an OSX or Windows user, don't try this part!** -Also this must be built from source using a static DDS API. **Currently the only supported implementation is Connext**. +Also this must be built from source using a static DDS API. +**Currently the only supported implementation is Connext**. First, follow the instructions to build ROS 2 :doc:`from source <../../Installation/Alternatives/Ubuntu-Development-Setup>` using Connext DDS as the middleware. Run the tests ^^^^^^^^^^^^^ -**Before you run make sure you have at least 8Gb of RAM free. With the memory locking, swap will not work anymore.** +**Before you run make sure you have at least 8Gb of RAM free. +With the memory locking, swap will not work anymore.** Source your ROS 2 setup.bash. -Run the demo binary, and redirect the output. You may want to use ``sudo`` in case you get permission error: +Run the demo binary, and redirect the output. +You may want to use ``sudo`` in case you get permission error: .. code-block:: bash @@ -162,10 +166,11 @@ Here, latency means the amount of time after the update was expected to occur. The requirements of a real-time system depend on the application, but let's say in this demo we have a 1kHz (1 millisecond) update loop, and we're aiming for a maximum allowable latency of 5% of our update period. -So, our average latency was really good in this run, but the maximum latency was unacceptable because it actually exceeded our update loop! What happened? +So, our average latency was really good in this run, but the maximum latency was unacceptable because it actually exceeded our update loop! +What happened? We may be suffering from a non-deterministic scheduler. -If you're running a vanilla Linux system and you don't have the RT_PREEMPT kernel installed, you probably won't be able to meet the real-time goal we set for ourselves, because the Linux scheduler won't allow you to arbitrarily pre-empt threads at the user level. +If you're running a vanilla Linux system and you don't have the RT_PREEMPT kernel installed, you probably won't be able to meet the real-time goal we set for ourselves, because the Linux scheduler won't allow you to arbitrarily preempt threads at the user level. See the `realtime design article `__ for more information. diff --git a/source/Tutorials/Demos/dummy-robot-demo.rst b/source/Tutorials/Demos/dummy-robot-demo.rst index 791e7e70045..208f2cc33c1 100644 --- a/source/Tutorials/Demos/dummy-robot-demo.rst +++ b/source/Tutorials/Demos/dummy-robot-demo.rst @@ -11,7 +11,8 @@ In this demo, we present a simple demo robot with all components from publishing Launching the demo ------------------ -We assume your ROS 2 installation dir as ``~/ros2_ws``. Please change the directories according to your platform. +We assume your ROS 2 installation dir as ``~/ros2_ws``. +Please change the directories according to your platform. To start the demo, we execute the demo bringup launch file, which we are going to explain in more details in the next section. @@ -45,14 +46,17 @@ You should see some prints inside your terminal along the lines of the following [dummy_laser-4] [INFO] [1714837459.645626640] [dummy_laser]: scan time increment: 0.000000 [robot_state_publisher-2] [INFO] [1714837459.652977937] [robot_state_publisher]: Robot initialized -If you now open RViz2 in a new terminal, you'll see your robot. 🎉 +If you now open RViz2 in a new terminal, you'll see your robot. +🎉 .. code-block:: bash $ source ~/ros2_ws/install/setup.bash $ rviz2 -This opens RViz2. Assuming you have your dummy_robot_bringup still launched, you can now add the TF display plugin and configure your global frame to ``world``. Once you did that, you should see a similar picture: +This opens RViz2. +Assuming you have your dummy_robot_bringup still launched, you can now add the TF display plugin and configure your global frame to ``world``. +Once you did that, you should see a similar picture: .. image:: images/rviz-dummy-robot.png @@ -69,10 +73,15 @@ If you have a closer look at the launch file, we start a couple of nodes at the * dummy_joint_states * robot_state_publisher -The first two packages are relatively simple. The ``dummy_map_server`` constantly publishes an empty map with a periodic update. The ``dummy_laser`` does basically the same; publishing dummy fake laser scans. +The first two packages are relatively simple. +The ``dummy_map_server`` constantly publishes an empty map with a periodic update. +The ``dummy_laser`` does basically the same; publishing dummy fake laser scans. -The ``dummy_joint_states`` node is publishing fake joint state data. As we are publishing a simple RRbot with only two joints, this node publishes joint states values for these two joints. +The ``dummy_joint_states`` node is publishing fake joint state data. +As we are publishing a simple RRbot with only two joints, this node publishes joint states values for these two joints. -The ``robot_state_publisher`` is doing the actual interesting work. It parses the given URDF file, extracts the robot model and listens to the incoming joint states. With this information, it publishes TF values for our robot which we visualize in RViz. +The ``robot_state_publisher`` is doing the actual interesting work. +It parses the given URDF file, extracts the robot model and listens to the incoming joint states. +With this information, it publishes TF values for our robot which we visualize in RViz. Hooray! diff --git a/source/Tutorials/Intermediate.rst b/source/Tutorials/Intermediate.rst index 583bac4d6fa..65d453c187a 100644 --- a/source/Tutorials/Intermediate.rst +++ b/source/Tutorials/Intermediate.rst @@ -10,6 +10,7 @@ Intermediate Intermediate/Writing-an-Action-Server-Client/Py Intermediate/Writing-a-Composable-Node Intermediate/Composition + Intermediate/Using-Node-Interfaces-Template-Class Intermediate/Monitoring-For-Parameter-Changes-CPP Intermediate/Monitoring-For-Parameter-Changes-Python Intermediate/Launch/Launch-Main diff --git a/source/Tutorials/Intermediate/Composition.rst b/source/Tutorials/Intermediate/Composition.rst index f03d441ef1d..e5833e1ef00 100644 --- a/source/Tutorials/Intermediate/Composition.rst +++ b/source/Tutorials/Intermediate/Composition.rst @@ -367,12 +367,56 @@ Passing additional arguments into components ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The ``ros2 component load`` command-line supports passing particular options to the component manager for use when constructing the node. -As of now, the only command-line option that is supported is to instantiate a node using intra-process communication. -This functionality can be used as follows: + +The following example shows the use of the extra arguments ``use_intra_process_comms`` and ``forward_global_arguments``: .. code-block:: bash - ros2 component load /ComponentManager composition composition::Talker -e use_intra_process_comms:=true + ros2 component load /ComponentManager composition composition::Talker -e use_intra_process_comms:=true -e forward_global_arguments:=false + +The following extra arguments are supported. + +.. list-table:: Extra Arguments for Component Manager + :widths: 15 15 15 15 + :header-rows: 1 + + * - Argument + - Type + - Default + - Description + * - ``forward_global_arguments`` + - Boolean + - True + - Apply global arguments to the component node when loading. + * - ``enable_rosout`` + - Boolean + - True + - Enable the ``rosout`` topic publisher in the component node. + * - ``use_intra_process_comms`` + - Boolean + - False + - Enable intra-process communication in the component node. + * - ``enable_topic_statistics`` + - Boolean + - False + - Enable a topic statistics publisher in the component node. + * - ``start_parameter_services`` + - Boolean + - True + - Enable services to manage parameters in the component node. + * - ``start_parameter_event_publisher`` + - Boolean + - True + - Enable the parameter event publisher in the component node. + * - ``use_clock_thread`` + - Boolean + - True + - Enable a dedicated clock thread in the component node. + * - ``enable_logger_service`` + - Boolean + - False + - Enable logger level management service in the component node. + Composable nodes as shared libraries ------------------------------------ diff --git a/source/Tutorials/Intermediate/Launch/Using-ROS2-Launch-For-Large-Projects.rst b/source/Tutorials/Intermediate/Launch/Using-ROS2-Launch-For-Large-Projects.rst index 8217cb76d74..7442b58daf4 100644 --- a/source/Tutorials/Intermediate/Launch/Using-ROS2-Launch-For-Large-Projects.rst +++ b/source/Tutorials/Intermediate/Launch/Using-ROS2-Launch-For-Large-Projects.rst @@ -123,6 +123,8 @@ However, there are cases when some nodes or launch files have to be launched sep .. note:: Design tip: Be aware of the tradeoffs when deciding how many top-level launch files your application requires. +.. _Parameters: + 2 Parameters ^^^^^^^^^^^^ @@ -170,6 +172,8 @@ First, create a new file called ``turtlesim_world_1_launch.py``. This launch file starts the ``turtlesim_node`` node, which starts the turtlesim simulation, with simulation configuration parameters that are defined and passed to the nodes. +.. _LoadingParametersFromYAMLFile: + 2.2 Loading parameters from YAML file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/source/Tutorials/Intermediate/Monitoring-For-Parameter-Changes-CPP.rst b/source/Tutorials/Intermediate/Monitoring-For-Parameter-Changes-CPP.rst index a0344295627..654fea47784 100644 --- a/source/Tutorials/Intermediate/Monitoring-For-Parameter-Changes-CPP.rst +++ b/source/Tutorials/Intermediate/Monitoring-For-Parameter-Changes-CPP.rst @@ -320,7 +320,7 @@ Now, to test monitoring of remote parameters, first run the newly-built paramete ros2 run cpp_parameter_event_handler parameter_event_handler -Next, from another teminal (with ROS initialized), run the parameter_blackboard demo application, as follows: +Next, from another terminal (with ROS initialized), run the parameter_blackboard demo application, as follows: .. code-block:: console diff --git a/source/Tutorials/Intermediate/Monitoring-For-Parameter-Changes-Python.rst b/source/Tutorials/Intermediate/Monitoring-For-Parameter-Changes-Python.rst index 87de5f52bec..a2065ac25b9 100644 --- a/source/Tutorials/Intermediate/Monitoring-For-Parameter-Changes-Python.rst +++ b/source/Tutorials/Intermediate/Monitoring-For-Parameter-Changes-Python.rst @@ -316,7 +316,7 @@ Now, to test monitoring of remote parameters, first run the newly-built paramete ros2 run python_parameter_event_handler node_with_parameters -Next, from another teminal (with ROS initialized), run the parameter_blackboard demo application, as follows: +Next, from another terminal (with ROS initialized), run the parameter_blackboard demo application, as follows: .. code-block:: console diff --git a/source/Tutorials/Intermediate/RViz/Marker-Display-types/Marker-Display-types.rst b/source/Tutorials/Intermediate/RViz/Marker-Display-types/Marker-Display-types.rst index ab82bac5e29..97494d97c89 100644 --- a/source/Tutorials/Intermediate/RViz/Marker-Display-types/Marker-Display-types.rst +++ b/source/Tutorials/Intermediate/RViz/Marker-Display-types/Marker-Display-types.rst @@ -85,15 +85,18 @@ The messages in this package include comments that are helpful in understanding * ``ns``: - Namespace for these markers. This plus the id form a unique identifier. + Namespace for these markers. + This plus the id form a unique identifier. * ``id``: - Unique id assigned to this marker. It is your responsibility to keep these unique within your namespace. + Unique id assigned to this marker. + It is your responsibility to keep these unique within your namespace. * ``type``: - Type of marker (Arrow, Sphere, ...). The available types are specified in the message definition. + Type of marker (Arrow, Sphere, ...). + The available types are specified in the message definition. * ``action``: @@ -105,11 +108,16 @@ The messages in this package include comments that are helpful in understanding * ``scale``: - Scale of the marker. Applied before the position/orientation. A scale of [1, 1, 1] means the object will be 1m by 1m by 1m. + Scale of the marker. + Applied before the position/orientation. + A scale of [1, 1, 1] means the object will be 1m by 1m by 1m. * ``color``: - Color of the object, specified as r/g/b/a, with values in the range of [0, 1]. The, ``a`` or alpha value, denotes the opacity of the marker with 1 indicating opaque and 0 indicating completely transparent. The default value is 0, or completely transparent. **You must set the a value of your marker to a non-zero value or it will be transparent by default!** + Color of the object, specified as r/g/b/a, with values in the range of [0, 1]. + The, ``a`` or alpha value, denotes the opacity of the marker with 1 indicating opaque and 0 indicating completely transparent. + The default value is 0, or completely transparent. + **You must set the a value of your marker to a non-zero value or it will be transparent by default!** * ``points``: @@ -119,7 +127,8 @@ The messages in this package include comments that are helpful in understanding * ``colors``: - This field is only used for markers that use the points member. This field specifies per-vertex color r/g/b/ color (no alpha yet) for each entry in ``points``. + This field is only used for markers that use the points member. + This field specifies per-vertex color r/g/b/ color (no alpha yet) for each entry in ``points``. * ``lifetime``: @@ -154,11 +163,14 @@ The arrow type provides two different ways of specifying where the arrow should * ``Position/Orientation``: - Pivot point is around the tip of its tail. Identity orientation points it along the +X axis. ``scale.x`` is the arrow length, ``scale.y`` is the arrow width and ``scale.z`` is the arrow height. + Pivot point is around the tip of its tail. + Identity orientation points it along the +X axis. + ``scale.x`` is the arrow length, ``scale.y`` is the arrow width and ``scale.z`` is the arrow height. * ``Start/End Points``: - You can also specify a start/end point for the arrow, using the points member. If you put points into the points member, it will assume you want to do things this way. + You can also specify a start/end point for the arrow, using the points member. + If you put points into the points member, it will assume you want to do things this way. * The point at index 0 is assumed to be the start point, and the point at index 1 is assumed to be the end. * ``scale.x`` is the shaft diameter, and ``scale.y`` is the head diameter. If ``scale.z`` is not zero, it specifies the head length. @@ -207,7 +219,8 @@ Note that ``pose`` is still used (the points in the line will be transformed by .. image:: images/LineListMarker.png -Line lists use the points member of the `visualization_msgs/msg/Marker `_ message. It will draw a line between each pair of points, so 0-1, 2-3, 4-5, ... +Line lists use the points member of the `visualization_msgs/msg/Marker `_ message. +It will draw a line between each pair of points, so 0-1, 2-3, 4-5, ... Line lists also have some special handling for scale: only ``scale.x`` is used and it controls the width of the line segments. @@ -256,7 +269,8 @@ Note that ``pose`` is still used (the ``points`` in the line will be transformed .. image:: images/text_view_facing_marker.png This marker displays text in a 3D spot in the world. -The text always appears oriented correctly for the RViZ user to see the included text. Uses the ``text`` field in the marker. +The text always appears oriented correctly for the RViZ user to see the included text. +Uses the ``text`` field in the marker. Only ``scale.z`` is used. ``scale.z`` specifies the height of an uppercase "A". diff --git a/source/Tutorials/Intermediate/RViz/RViz-Custom-Display/RViz-Custom-Display.rst b/source/Tutorials/Intermediate/RViz/RViz-Custom-Display/RViz-Custom-Display.rst index 3cdf5adede7..089733158e4 100644 --- a/source/Tutorials/Intermediate/RViz/RViz-Custom-Display/RViz-Custom-Display.rst +++ b/source/Tutorials/Intermediate/RViz/RViz-Custom-Display/RViz-Custom-Display.rst @@ -3,14 +3,17 @@ Building a Custom RViz Display Background ---------- -There are many types of data that have existing visualizations in RViz. However, if there is a message type that does +There are many types of data that have existing visualizations in RViz. +However, if there is a message type that does not yet have a plugin to display it, there are two choices to see it in RViz. 1. Convert the message to another type, such as ``visualization_msgs/Marker``. 2. Write a Custom RViz Display. -With the first option, there is more network traffic and limitations to how the data can be represented. It is also quick and flexible. -The latter option is explained in this tutorial. It takes a bit of work, but can lead to much richer visualizations. +With the first option, there is more network traffic and limitations to how the data can be represented. +It is also quick and flexible. +The latter option is explained in this tutorial. +It takes a bit of work, but can lead to much richer visualizations. All of the code for this tutorial can be found in `this repository `__. In order to see the incremental progress of the plugin written in this tutorial, @@ -224,7 +227,8 @@ First, you need to add a dependency in ``CMakeLists.txt`` and ``package.xml`` on We need to add three lines to the header file: -* ``#include `` - There's `lots of options in the rviz_rendering package `_ for objects to build your visualization on. Here we're using a simple shape. +* ``#include `` - There's `lots of options in the rviz_rendering package `_ for objects to build your visualization on. + Here we're using a simple shape. * In the class, we'll add a new ``protected`` virtual method: ``void onInitialize() override;`` * We also add a pointer to our shape object: ``std::unique_ptr point_shape_;`` @@ -407,11 +411,13 @@ First, we update the plugin declaration. * We add the ``name`` field to the ``class`` tag. This changes the name that is displayed in RViz. In code, it makes sense to call it a ``PointDisplay`` but in RViz, we want to simplify. -* We put actual text into the description. Don't be lazy. +* We put actual text into the description. + Don't be lazy. * By declaring the specific message type here, when you attempt to add a Display by Topic, it will suggest this plugin for the topics of that type. We also add an icon for the plugin at ``icons/classes/Point2D.png``. -The folder is hardcoded, and the filename should match the name from the plugin declaration (or the name of the class if not specified). `[icon source] `_ +The folder is hardcoded, and the filename should match the name from the plugin declaration (or the name of the class if not specified). +`[icon source] `_ We need to install the image file in the CMake. diff --git a/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/RViz-Custom-Panel.rst b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/RViz-Custom-Panel.rst new file mode 100644 index 00000000000..1f44bad8e61 --- /dev/null +++ b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/RViz-Custom-Panel.rst @@ -0,0 +1,352 @@ +Building a Custom RViz Panel +============================ + +This tutorial is for people who would like to work within the RViz environment to either display or interact with some data in a two-dimensional environment. + +In this tutorial you will learn how to do three things within RViz: + +* Create a new QT panel within RViz. +* Create a topic subscriber within RViz that can monitor messages published on that topic and display them within the RViz panel. +* Create a topic publisher such button presses within RViz publish to an output topic in ROS. + +All of the code for this tutorial can be found in `this repository `__. + +Boilerplate Code +---------------- + +Header File +^^^^^^^^^^^ + +Here are the contents of ``demo_panel.hpp`` + +.. code-block:: c++ + + #ifndef RVIZ_PANEL_TUTORIAL__DEMO_PANEL_HPP_ + #define RVIZ_PANEL_TUTORIAL__DEMO_PANEL_HPP_ + + #include + + namespace rviz_panel_tutorial + { + class DemoPanel + : public rviz_common::Panel + { + Q_OBJECT + public: + explicit DemoPanel(QWidget * parent = 0); + ~DemoPanel() override; + }; + } // namespace rviz_panel_tutorial + + #endif // RVIZ_PANEL_TUTORIAL__DEMO_PANEL_HPP_ + +* We're extending the `rviz_common::Panel `__ class. +* `For reasons outside the scope of this tutorial `__, you need the ``Q_OBJECT`` macro in there to get the QT parts of the GUI to work. +* We start by declaring just a constructor and destructor, implemented in the cpp file. + +Source File +^^^^^^^^^^^ + +``demo_panel.cpp`` + +.. code-block:: c++ + + #include + + namespace rviz_panel_tutorial + { + DemoPanel::DemoPanel(QWidget* parent) : Panel(parent) + { + } + + DemoPanel::~DemoPanel() = default; + } // namespace rviz_panel_tutorial + + #include + PLUGINLIB_EXPORT_CLASS(rviz_panel_tutorial::DemoPanel, rviz_common::Panel) + +* Overriding the constructor and deconstructor are not strictly necessary, but we can do more with them later. +* In order for RViz to find our plugin, we need this ``PLUGINLIB`` invocation in our code (as well as other things below). + +package.xml +^^^^^^^^^^^ + +We need the following dependencies in our package.xml: + +.. code-block:: xml + + pluginlib + rviz_common + +rviz_common_plugins.xml +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: xml + + + + + + + +* This is standard ``pluginlib`` code. + + * The library ``path`` is the name of the library we'll assign in the CMake. + * The class should match the ``PLUGINLIB`` invocation from above. + +* We'll come back to the description later, I promise. + +CMakeLists.txt +^^^^^^^^^^^^^^ + +Add the following lines to the top of the standard boilerplate. + +.. code-block:: cmake + + find_package(ament_cmake_ros REQUIRED) + find_package(pluginlib REQUIRED) + find_package(rviz_common REQUIRED) + + set(CMAKE_AUTOMOC ON) + qt5_wrap_cpp(MOC_FILES + include/rviz_panel_tutorial/demo_panel.hpp + ) + + add_library(demo_panel src/demo_panel.cpp ${MOC_FILES}) + target_include_directories(demo_panel PUBLIC + $ + $ + ) + ament_target_dependencies(demo_panel + pluginlib + rviz_common + ) + install(TARGETS demo_panel + EXPORT export_rviz_panel_tutorial + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + ) + install(DIRECTORY include/ + DESTINATION include + ) + install(FILES rviz_common_plugins.xml + DESTINATION share/${PROJECT_NAME} + ) + ament_export_include_directories(include) + ament_export_targets(export_rviz_panel_tutorial) + pluginlib_export_plugin_description_file(rviz_common rviz_common_plugins.xml) + + +* To generate the proper Qt files, we need to + + * Turn ``CMAKE_AUTOMOC`` on. + * Wrap the headers by calling ``qt5_wrap_cpp`` with each header that has ``Q_OBJECT`` in it. + * Include the ``MOC_FILES`` in the library alongside our other cpp files. + +* A lot of the other code ensures that the plugin portion works. + Namely, calling ``pluginlib_export_plugin_description_file`` is essential to getting RViz to find your new plugin. + +Testing it out +^^^^^^^^^^^^^^ + +Compile your code, source your workspace and run ``rviz2``. + +In the top Menu bar, there should be a "Panels" menu. +Select "Add New Panel" from that menu. + +.. image:: images/Select0.png + :target: images/Select0.png + :alt: screenshot of Add New Panel dialog + +A dialog will pop up showing all the panels accessible in your ROS environment, grouped into folders based on their ROS package. +Create a new instance of your panel by either double clicking on its name, or selecting it and clicking OK. + +This should create a new panel in your RViz window, albeit with nothing but a title bar with the name of your panel. + +.. image:: images/RViz0.png + :target: images/RViz0.png + :alt: screenshot of the whole RViz window showing the new simple panel + +Filling in the Panel +-------------------- +We're going to update our panel with some very basic ROS/QT interaction. +What we will do, roughly, is access the ROS node from within RViz that can both subscribe and publish to ROS topics. +We will use our subscriber to monitor an ``/input`` topic within ROS and display the published ``String`` values in the widget. +We use our publisher to map button presses within RViz to messages published on a ROS topic named ``/output`` . + +Updated Header File +^^^^^^^^^^^^^^^^^^^ + +Update ``demo_panel.hpp`` to include the following includes and class Body. + +.. code-block:: c++ + + #include + #include + #include + #include + #include + + namespace rviz_panel_tutorial + { + class DemoPanel : public rviz_common::Panel + { + Q_OBJECT + public: + explicit DemoPanel(QWidget * parent = 0); + ~DemoPanel() override; + + void onInitialize() override; + + protected: + std::shared_ptr node_ptr_; + rclcpp::Publisher::SharedPtr publisher_; + rclcpp::Subscription::SharedPtr subscription_; + + void topicCallback(const std_msgs::msg::String & msg); + + QLabel* label_; + QPushButton* button_; + + private Q_SLOTS: + void buttonActivated(); + }; + } // namespace rviz_panel_tutorial + +* On the ROS side, we declare an abstract node pointer, which we will use to create interfaces to the wider ROS ecosystem. + We have a subscriber which will allow us to take information from ROS and use it in RViz. + The publisher allows us to publish information/events from within RViz and make them available in ROS. + We also have methods an initialization method for setting up the ROS components (``onInitialize``) and a callback for the subscriber (``topicCallback``). +* On the QT side, we declare a label and a button, as well as a callback for the button (``buttonActivated``). + +Updated Source File +^^^^^^^^^^^^^^^^^^^ + +Update ``demo_panel.cpp`` to have the following contents: + +.. code-block:: c++ + + #include + #include + #include + + namespace rviz_panel_tutorial + { + + DemoPanel::DemoPanel(QWidget* parent) : Panel(parent) + { + // Create a label and a button, displayed vertically (the V in VBox means vertical) + const auto layout = new QVBoxLayout(this); + // Create a button and a label for the button + label_ = new QLabel("[no data]"); + button_ = new QPushButton("GO!"); + // Add those elements to the GUI layout + layout->addWidget(label_); + layout->addWidget(button_); + + // Connect the event of when the button is released to our callback, + // so pressing the button results in the buttonActivated callback being called. + QObject::connect(button_, &QPushButton::released, this, &DemoPanel::buttonActivated); + } + + DemoPanel::~DemoPanel() = default; + + void DemoPanel::onInitialize() + { + // Access the abstract ROS Node and + // in the process lock it for exclusive use until the method is done. + node_ptr_ = getDisplayContext()->getRosNodeAbstraction().lock(); + + // Get a pointer to the familiar rclcpp::Node for making subscriptions/publishers + // (as per normal rclcpp code) + rclcpp::Node::SharedPtr node = node_ptr_->get_raw_node(); + + // Create a String publisher for the output + publisher_ = node->create_publisher("/output", 10); + + // Create a String subscription and bind it to the topicCallback inside this class. + subscription_ = node->create_subscription("/input", 10, std::bind(&DemoPanel::topicCallback, this, std::placeholders::_1)); + } + + // When the subscriber gets a message, this callback is triggered, + // and then we copy its data into the widget's label + void DemoPanel::topicCallback(const std_msgs::msg::String & msg) + { + label_->setText(QString(msg.data.c_str())); + } + + // When the widget's button is pressed, this callback is triggered, + // and then we publish a new message on our topic. + void DemoPanel::buttonActivated() + { + auto message = std_msgs::msg::String(); + message.data = "Button clicked!"; + publisher_->publish(message); + } + + } // namespace rviz_panel_tutorial + + #include + + PLUGINLIB_EXPORT_CLASS(rviz_panel_tutorial::DemoPanel, rviz_common::Panel) + +Testing with ROS +^^^^^^^^^^^^^^^^ +Compile and launch RViz2 with your panel again. +You should see your label and button in the panel now. + +.. image:: images/RViz1.png + :target: images/RViz1.png + :alt: screenshot of the RViz panel in its default state + +To change the label, we simply have to publish a message on the ``/input`` topic, which you can do with this command: + +.. code-block:: bash + + ros2 topic pub /input std_msgs/msg/String "{data: 'Please be kind.'}" + +Since the widget is subscribed to this topic, it will trigger the callback and change the text of the label. + +.. image:: images/RViz2.png + :target: images/RViz2.png + :alt: screenshot of the RViz panel with custom string message displayed + + +Pressing the button will publish a message, which you can see by echoing the ``/output`` topic, like with this command. + +.. code-block:: bash + + ros2 topic echo /output + + +Cleanup +------- + +Now its time to clean it up a bit. +This makes things look nicer and be a little easier to use, but aren't strictly required. + +First, you should update the description of your plugin in ``rviz_common_plugins.xml`` + +We also add an icon for the plugin at ``icons/classes/DemoPanel.png``. +The folder is hardcoded, and the filename should match the name from the plugin declaration (or the name of the class if not specified). + +We need to install the image file in the CMake. + +.. code-block:: cmake + + install(FILES icons/classes/DemoPanel.png + DESTINATION share/${PROJECT_NAME}/icons/classes + ) + +Now when you add the panel, it should show up with an icon and description. + +.. image:: images/Select1.png + :target: images/Select1.png + :alt: screenshot of Add New Panel dialog with our custom icon and description + +The panel will also have an updated icon. + +.. image:: images/RViz3.png + :target: images/RViz3.png + :alt: screenshot of the RViz panel with custom icon diff --git a/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz0.png b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz0.png new file mode 100644 index 00000000000..ca1d8f5cb5f Binary files /dev/null and b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz0.png differ diff --git a/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz1.png b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz1.png new file mode 100644 index 00000000000..a7efaace35b Binary files /dev/null and b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz1.png differ diff --git a/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz2.png b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz2.png new file mode 100644 index 00000000000..a434ad55763 Binary files /dev/null and b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz2.png differ diff --git a/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz3.png b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz3.png new file mode 100644 index 00000000000..5936972bca9 Binary files /dev/null and b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/RViz3.png differ diff --git a/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/Select0.png b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/Select0.png new file mode 100644 index 00000000000..60b32c761ce Binary files /dev/null and b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/Select0.png differ diff --git a/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/Select1.png b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/Select1.png new file mode 100644 index 00000000000..fbee72d1980 Binary files /dev/null and b/source/Tutorials/Intermediate/RViz/RViz-Custom-Panel/images/Select1.png differ diff --git a/source/Tutorials/Intermediate/RViz/RViz-Main.rst b/source/Tutorials/Intermediate/RViz/RViz-Main.rst index 59559f5a4e7..4d2e687eab4 100644 --- a/source/Tutorials/Intermediate/RViz/RViz-Main.rst +++ b/source/Tutorials/Intermediate/RViz/RViz-Main.rst @@ -12,4 +12,5 @@ RViz is a 3D visualizer for the Robot Operating System (ROS) framework. RViz-User-Guide/RViz-User-Guide RViz-Custom-Display/RViz-Custom-Display + RViz-Custom-Panel/RViz-Custom-Panel Marker-Display-types/Marker-Display-types diff --git a/source/Tutorials/Intermediate/RViz/RViz-User-Guide/RViz-User-Guide.rst b/source/Tutorials/Intermediate/RViz/RViz-User-Guide/RViz-User-Guide.rst index d6bb5a901be..cac256195a7 100644 --- a/source/Tutorials/Intermediate/RViz/RViz-User-Guide/RViz-User-Guide.rst +++ b/source/Tutorials/Intermediate/RViz/RViz-User-Guide/RViz-User-Guide.rst @@ -108,7 +108,8 @@ Built-in Display Types - Draws cells from a grid, usually obstacles from a costmap from the `navigation `__ stack. - `nav_msgs/msg/GridCells `__ * - Image - - Creates a new rendering window with an Image. Unlike the Camera display, this display does not use a CameraInfo + - Creates a new rendering window with an Image. + Unlike the Camera display, this display does not use a CameraInfo - `sensor_msgs/msg/Image `__ * - InteractiveMarker - Displays 3D objects from one or multiple Interactive Marker servers and allows mouse interaction with them @@ -144,7 +145,8 @@ Built-in Display Types - Accumulates odometry poses from over time. - `nav_msgs/msg/Odometry `__ * - Range - - Displays cones representing range measurements from sonar or IR range sensors. Version: Electric+ + - Displays cones representing range measurements from sonar or IR range sensors. + Version: Electric+ - `sensor_msgs/msg/Range `__ * - RobotModel - Shows a visual representation of a robot in the correct pose (as defined by the current TF transforms). @@ -169,7 +171,7 @@ A configuration contains: * Displays + their properties * Tool properties -* The viewpoint and settings for the 3D visualzation +* The viewpoint and settings for the 3D visualization Views Panel ----------- @@ -189,8 +191,10 @@ The focal point is visualized as a small disc while you're moving the camera: Controls: * **Left mouse button**: Click and drag to rotate around the focal point. -* **Middle mouse button**: Click and drag to move the focal point in the plane formed by the camera's up and right vectors. The distance moved depends on the focal point -- if there is an object on the focal point, and you click on top of it, it will stay under your mouse. -* **Right mouse button**: Click and drag to zoom in/out of the focal point. Dragging up zooms in, down zooms out. +* **Middle mouse button**: Click and drag to move the focal point in the plane formed by the camera's up and right vectors. + The distance moved depends on the focal point -- if there is an object on the focal point, and you click on top of it, it will stay under your mouse. +* **Right mouse button**: Click and drag to zoom in/out of the focal point. + Dragging up zooms in, down zooms out. * **Scrollwheel**: Zoom in/out of the focal point FPS (first-person) Camera @@ -199,9 +203,11 @@ The FPS camera is a first-person camera, so it rotates as if you're looking with Controls: -* **Left mouse button**: Click and drag to rotate. Control-click to pick the object under the mouse and look directly at it. +* **Left mouse button**: Click and drag to rotate. + Control-click to pick the object under the mouse and look directly at it. * **Middle mouse button**: Click and drag to move along the plane formed by the camera's up and right vectors. -* **Right mouse button**: Click and drag to move along the camera's forward vector. Dragging up moves forward, down moves backward. +* **Right mouse button**: Click and drag to move along the camera's forward vector. + Dragging up moves forward, down moves backward. * **Scrollwheel**: Move forward/backward. Top-down Orthographic diff --git a/source/Tutorials/Intermediate/Rosdep.rst b/source/Tutorials/Intermediate/Rosdep.rst index c7dda3a3fc7..87414d3411d 100644 --- a/source/Tutorials/Intermediate/Rosdep.rst +++ b/source/Tutorials/Intermediate/Rosdep.rst @@ -105,7 +105,8 @@ How do I know what keys to put in my package.xml? Great question, I'm glad you asked! * If the package you want to depend in your package is ROS-based, AND has been released into the ROS ecosystem [1]_, e.g. ``nav2_bt_navigator``, you may simply use the name of the package. You can find a list of all released ROS packages in https://github.com/ros/rosdistro at ``/distribution.yaml`` (e.g. ``humble/distribution.yaml``) for your given ROS distribution. -* If you want to depend on a non-ROS package, something often called "system dependencies", you will need to find the keys for a particular library. In general, there are two files of interest: +* If you want to depend on a non-ROS package, something often called "system dependencies", you will need to find the keys for a particular library. + In general, there are two files of interest: * `rosdep/base.yaml `_ contains the ``apt`` system dependencies * `rosdep/python.yaml `_ contains the Python dependencies diff --git a/source/Tutorials/Intermediate/Testing/Python.rst b/source/Tutorials/Intermediate/Testing/Python.rst index 4350f597ece..4a729ca4304 100644 --- a/source/Tutorials/Intermediate/Testing/Python.rst +++ b/source/Tutorials/Intermediate/Testing/Python.rst @@ -48,7 +48,8 @@ Example package layout: Test Contents ------------- -You can now write tests to your heart's content. There are `plenty of resources on pytest `__, but in short, you can write functions with the ``test_`` prefix and include whatever assert statements you'd like. +You can now write tests to your heart's content. +There are `plenty of resources on pytest `__, but in short, you can write functions with the ``test_`` prefix and include whatever assert statements you'd like. .. code-block:: python diff --git a/source/Tutorials/Intermediate/Testing/Testing-Main.rst b/source/Tutorials/Intermediate/Testing/Testing-Main.rst index 2f905a7f749..4a1720cf922 100644 --- a/source/Tutorials/Intermediate/Testing/Testing-Main.rst +++ b/source/Tutorials/Intermediate/Testing/Testing-Main.rst @@ -8,14 +8,43 @@ Why automatic tests? Here are some of the many good reasons why should we have automated tests: -* You can make incremental updates to your code more quickly. ROS has hundreds of packages with many interdependencies, so it can be hard to anticipate the problems a small change might cause. If your change passes the unit tests, you can be more confident that you haven't introduced problems — or at least the problems aren't your fault. -* You can refactor your code with greater confidence. Passing the unit tests verifies that you haven't introduced any bugs while refactoring. This gives you this wonderful freedom from change fear! -* It leads to better designed code. Unit tests force you to write your code so that it can be more easily tested. This often means keeping your underlying functions and framework separate, which is one of our design goals with ROS code. -* They prevent recurring bugs (bug regressions). It's a good practice to write a unit test for every bug you fix. In fact, write the unit test before you fix the bug. This will help you to precisely, or even deterministically, reproduce the bug, and much more precisely understand what the problem is. As a result, you will also create a better patch, which you can then test with your regression test to verify that the bug is fixed. That way the bug won't accidentally get reintroduced if the code gets modified later on. It also means that it will be easier to convince the reviewer of the patch that the problem is solved, and the contribution is of high quality. -* Other people can work on your code more easily (an automatic form of documentation). It can be hard to figure out whether or not you've broken someone else's code when you make a change. The unit tests are a tool for other developers to validate their changes. Automatic tests document your coding decisions, and communicate to other developers automatically about their violation. Thus tests become documentation for your code — a documentation that does not need to be read for the most time, and when it does need to be inspected the test system will precisely indicate what to read (which tests fail). By writing automatic tests you make other contributors faster. This improves the entire ROS project. -* It is much easier to become a contributor to ROS if we have automated unit tests. It is very difficult for new external developers to contribute to your components. When they make changes to code, they are often doing it in the blind, driven by a lot of guesswork. By providing a harness of automated tests, you help them in the task. They get immediate feedback for their changes. It becomes easier to contribute to a project, and new contributors to join more easily. Also their first contributions are of higher quality, which decreases the workload on maintainers. A win-win! -* Automatic tests simplify maintainership. Especially for mature packages, which change more slowly, and mostly need to be updated to new dependencies, an automatic test suite helps to very quickly establish whether the package still works. This makes it much easier to decide whether the package is still supported or not. -* Automatic tests amplify the value of Continuous Integration. Regression tests, along with normal scenario-based requirements tests, contribute to overall body of automated tests for your component. Your component is better tested against evolution of other APIs that it depends on (CI servers will tell you better and more precisely what problems develop in your code). +* You can make incremental updates to your code more quickly. + ROS has hundreds of packages with many interdependencies, so it can be hard to anticipate the problems a small change might cause. + If your change passes the unit tests, you can be more confident that you haven't introduced problems — or at least the problems aren't your fault. +* You can refactor your code with greater confidence. + Passing the unit tests verifies that you haven't introduced any bugs while refactoring. + This gives you this wonderful freedom from change fear! +* It leads to better designed code. + Unit tests force you to write your code so that it can be more easily tested. + This often means keeping your underlying functions and framework separate, which is one of our design goals with ROS code. +* They prevent recurring bugs (bug regressions). + It's a good practice to write a unit test for every bug you fix. + In fact, write the unit test before you fix the bug. + This will help you to precisely, or even deterministically, reproduce the bug, and much more precisely understand what the problem is. + As a result, you will also create a better patch, which you can then test with your regression test to verify that the bug is fixed. + That way the bug won't accidentally get reintroduced if the code gets modified later on. + It also means that it will be easier to convince the reviewer of the patch that the problem is solved, and the contribution is of high quality. +* Other people can work on your code more easily (an automatic form of documentation). + It can be hard to figure out whether or not you've broken someone else's code when you make a change. + The unit tests are a tool for other developers to validate their changes. + Automatic tests document your coding decisions, and communicate to other developers automatically about their violation. + Thus tests become documentation for your code — a documentation that does not need to be read for the most time, and when it does need to be inspected the test system will precisely indicate what to read (which tests fail). + By writing automatic tests you make other contributors faster. + This improves the entire ROS project. +* It is much easier to become a contributor to ROS if we have automated unit tests. + It is very difficult for new external developers to contribute to your components. + When they make changes to code, they are often doing it in the blind, driven by a lot of guesswork. + By providing a harness of automated tests, you help them in the task. + They get immediate feedback for their changes. + It becomes easier to contribute to a project, and new contributors to join more easily. + Also their first contributions are of higher quality, which decreases the workload on maintainers. + A win-win! +* Automatic tests simplify maintainership. + Especially for mature packages, which change more slowly, and mostly need to be updated to new dependencies, an automatic test suite helps to very quickly establish whether the package still works. + This makes it much easier to decide whether the package is still supported or not. +* Automatic tests amplify the value of Continuous Integration. + Regression tests, along with normal scenario-based requirements tests, contribute to overall body of automated tests for your component. + Your component is better tested against evolution of other APIs that it depends on (CI servers will tell you better and more precisely what problems develop in your code). Perhaps the most important benefit of writing tests is that tests make you a good citizen. Tests influence quality in the long term. @@ -28,8 +57,13 @@ Is this all coming for free? Of course, there is never free lunch. To get the benefits of testing, some investment is necessary. -* You need to develop a test, which sometimes may be difficult or costly. Sometimes it might also be nontrivial, as the test should be automatic. Things get particularly hairy if your tests should involve special hardware (they should not: try to use simulation, mock the hardware, or narrow down the test to a smaller software problem) or require external environment, for instance human operators. -* Regression tests and other automatic tests need to be maintained. When the design of the component changes, a lot of tests become invalidated (for instance they no longer compile, or throw runtime exceptions related to the API design). These tests fail not only because the redesign re-introduced bugs but also because they need to be updated to the new design. Occasionally, with bigger redesigns, old regression tests should be dropped. +* You need to develop a test, which sometimes may be difficult or costly. + Sometimes it might also be nontrivial, as the test should be automatic. + Things get particularly hairy if your tests should involve special hardware (they should not: try to use simulation, mock the hardware, or narrow down the test to a smaller software problem) or require external environment, for instance human operators. +* Regression tests and other automatic tests need to be maintained. + When the design of the component changes, a lot of tests become invalidated (for instance they no longer compile, or throw runtime exceptions related to the API design). + These tests fail not only because the redesign re-introduced bugs but also because they need to be updated to the new design. + Occasionally, with bigger redesigns, old regression tests should be dropped. * Large bodies of tests can take a long time to run, which can increase Continuous Integration server costs. Available Tutorials: diff --git a/source/Tutorials/Intermediate/Tf2/Quaternion-Fundamentals.rst b/source/Tutorials/Intermediate/Tf2/Quaternion-Fundamentals.rst index 6e62f49e4c8..d81ca0858b7 100644 --- a/source/Tutorials/Intermediate/Tf2/Quaternion-Fundamentals.rst +++ b/source/Tutorials/Intermediate/Tf2/Quaternion-Fundamentals.rst @@ -32,7 +32,7 @@ In this tutorial, you will learn how quaternions and conversion methods work in Prerequisites ------------- -However, this is not a hard requirement and you can stick to any other geometric transfromation library that suit you best. +However, this is not a hard requirement and you can stick to any other geometric transformation library that suit you best. You can take a look at libraries like `transforms3d `_, `scipy.spatial.transform `_, `pytransform3d `_, `numpy-quaternion `_ or `blender.mathutils `_. Components of a quaternion @@ -168,7 +168,8 @@ You want to find the relative rotation, ``q_r``, that converts ``q_1`` to ``q_2` q_2 = q_r * q_1 You can solve for ``q_r`` similarly to solving a matrix equation. -Invert ``q_1`` and right-multiply both sides. Again, the order of multiplication is important: +Invert ``q_1`` and right-multiply both sides. +Again, the order of multiplication is important: .. code-block:: C++ diff --git a/source/Tutorials/Intermediate/Tf2/Time-Travel-With-Tf2-Cpp.rst b/source/Tutorials/Intermediate/Tf2/Time-Travel-With-Tf2-Cpp.rst index 635145b29cb..adee5bc6474 100644 --- a/source/Tutorials/Intermediate/Tf2/Time-Travel-With-Tf2-Cpp.rst +++ b/source/Tutorials/Intermediate/Tf2/Time-Travel-With-Tf2-Cpp.rst @@ -48,7 +48,8 @@ Edit the ``lookupTransform()`` call in ``turtle_tf2_listener.cpp`` file to } catch (const tf2::TransformException & ex) { Now if you run this, during the first 5 seconds, the second turtle would not know where to go because we do not yet have a 5-second history of poses of the carrot. -But what happens after these 5 seconds? Build the package then let's just give it a try: +But what happens after these 5 seconds? +Build the package then let's just give it a try: .. code-block:: console @@ -56,9 +57,11 @@ But what happens after these 5 seconds? Build the package then let's just give i .. 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. +You should now notice that your turtle is driving around uncontrollably like in this screenshot. +Let's try to understand reason behind that behavior. -#. In our code we asked tf2 the following question: "What was the pose of ``carrot1`` 5 seconds ago, relative to ``turtle2`` 5 seconds ago?". This means we are controlling the second turtle based on where it was 5 seconds ago as well as where the first carrot was 5 seconds ago. +#. In our code we asked tf2 the following question: "What was the pose of ``carrot1`` 5 seconds ago, relative to ``turtle2`` 5 seconds ago?". + This means we are controlling the second turtle based on where it was 5 seconds ago as well as where the first carrot was 5 seconds ago. #. However, what we really want to ask is: "What was the pose of ``carrot1`` 5 seconds ago, relative to the current position of the ``turtle2``?". diff --git a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Cpp.rst b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Cpp.rst index e36f88ba29a..3f100774810 100644 --- a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Cpp.rst +++ b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Cpp.rst @@ -407,7 +407,8 @@ The following command publishes a static coordinate transform to tf2 using an x/ ros2 run tf2_ros static_transform_publisher --x x --y y --z z --qx qx --qy qy --qz qz --qw qw --frame-id frame_id --child-frame-id child_frame_id -``static_transform_publisher`` is designed both as a command-line tool for manual use, as well as for use within ``launch`` files for setting static transforms. For example: +``static_transform_publisher`` is designed both as a command-line tool for manual use, as well as for use within ``launch`` files for setting static transforms. +For example: .. code-block:: console diff --git a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Py.rst b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Py.rst index 442206d7a80..2b638d5925b 100644 --- a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Py.rst +++ b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Py.rst @@ -426,7 +426,8 @@ The following command publishes a static coordinate transform to tf2 using an x/ ros2 run tf2_ros static_transform_publisher --x x --y y --z z --qx qx --qy qy --qz qz --qw qw --frame-id frame_id --child-frame-id child_frame_id -``static_transform_publisher`` is designed both as a command-line tool for manual use, as well as for use within ``launch`` files for setting static transforms. For example: +``static_transform_publisher`` is designed both as a command-line tool for manual use, as well as for use within ``launch`` files for setting static transforms. +For example: .. code-block:: python diff --git a/source/Tutorials/Intermediate/URDF/Adding-Physical-and-Collision-Properties-to-a-URDF-Model.rst b/source/Tutorials/Intermediate/URDF/Adding-Physical-and-Collision-Properties-to-a-URDF-Model.rst index 59d54df2e34..0064c8e7944 100644 --- a/source/Tutorials/Intermediate/URDF/Adding-Physical-and-Collision-Properties-to-a-URDF-Model.rst +++ b/source/Tutorials/Intermediate/URDF/Adding-Physical-and-Collision-Properties-to-a-URDF-Model.rst @@ -61,8 +61,7 @@ However, there are two main cases where you wouldn’t: Physical Properties ------------------- -In order to get your model to simulate properly, you need to define several physical properties of your robot, i.e. -the properties that a physics engine like Gazebo would need. +In order to get your model to simulate properly, you need to define several physical properties of your robot, i.e. the properties that a physics engine like Gazebo would need. Inertia ^^^^^^^ @@ -109,7 +108,8 @@ Here is a simple one. * The inertia tensor depends on both the mass and the distribution of mass of the object. A good first approximation is to assume equal distribution of mass in the volume of the object and compute the inertia tensor based on the object's shape, as outlined above. * If unsure what to put, a matrix with ixx/iyy/izz=1e-3 or smaller is often a reasonable default for a mid-sized link (it corresponds to a box of 0.1 m side length with a mass of 0.6 kg). - The identity matrix is a particularly bad choice, since it is often much too high (it corresponds to a box of 0.1 m side length with a mass of 600 kg!). + The identity matrix is a particularly bad choice, since it is often much too high. + (it corresponds to a box of 0.1 m side length with a mass of 600 kg!) * You can also specify an origin tag to specify the center of gravity and the inertial reference frame (relative to the link's reference frame). * When using realtime controllers, inertia elements of zero (or almost zero) can cause the robot model to collapse without warning, and all links will appear with their origins coinciding with the world origin. diff --git a/source/Tutorials/Intermediate/URDF/Building-a-Movable-Robot-Model-with-URDF.rst b/source/Tutorials/Intermediate/URDF/Building-a-Movable-Robot-Model-with-URDF.rst index dd34707f77b..d44b9688b5f 100644 --- a/source/Tutorials/Intermediate/URDF/Building-a-Movable-Robot-Model-with-URDF.rst +++ b/source/Tutorials/Intermediate/URDF/Building-a-Movable-Robot-Model-with-URDF.rst @@ -109,7 +109,8 @@ Specifying the Pose ------------------- As you move the sliders around in the GUI, the model moves in Rviz. -How is this done? First the `GUI `_ parses the URDF and finds all the non-fixed joints and their limits. +How is this done? +First the `GUI `_ parses the URDF and finds all the non-fixed joints and their limits. Then, it uses the values of the sliders to publish `sensor_msgs/msg/JointState `_ messages. Those are then used by `robot_state_publisher `_ to calculate all of transforms between the different parts. The resulting transform tree is then used to display all of the shapes in Rviz. diff --git a/source/Tutorials/Intermediate/URDF/Building-a-Visual-Robot-Model-with-URDF-from-Scratch.rst b/source/Tutorials/Intermediate/URDF/Building-a-Visual-Robot-Model-with-URDF-from-Scratch.rst index d28a955fd24..73ab6718e87 100644 --- a/source/Tutorials/Intermediate/URDF/Building-a-Visual-Robot-Model-with-URDF-from-Scratch.rst +++ b/source/Tutorials/Intermediate/URDF/Building-a-Visual-Robot-Model-with-URDF-from-Scratch.rst @@ -186,7 +186,8 @@ We also rotate the leg so it is upright. * The launch file runs packages that will create TF frames for each link in your model based on your URDF. Rviz uses this information to figure out where to display each shape. -* If a TF frame does not exist for a given URDF link, then it will be placed at the origin in white (ref. `related question `_). +* If a TF frame does not exist for a given URDF link, then it will be placed at the origin in white + (ref. `related question `_). Material Girl ------------- diff --git a/source/Tutorials/Intermediate/URDF/Exporting-an-URDF-File.rst b/source/Tutorials/Intermediate/URDF/Exporting-an-URDF-File.rst index 2614c4ef286..b4c9743c848 100644 --- a/source/Tutorials/Intermediate/URDF/Exporting-an-URDF-File.rst +++ b/source/Tutorials/Intermediate/URDF/Exporting-an-URDF-File.rst @@ -15,7 +15,8 @@ Most roboticists work in teams, and often those teams include a mechanical engin Instead of crafting an URDF by hand it is possible to export an URDF model from many different CAD and modeling programs. These export tools are often developed by individuals that are familiar with the particular CAD program they use. Below you will find a list of available URDF exporters for a variety of CAD and 3D modeling software systems. -*The ROS core maintainers do not maintain these packages. As such we make no claims about their performance or ease of use.* +*The ROS core maintainers do not maintain these packages. +As such we make no claims about their performance or ease of use.* However, we figured it would be helpful to produce a list of available URDF exporters. **CAD Exporters** @@ -37,7 +38,7 @@ However, we figured it would be helpful to produce a list of available URDF expo * `Gazebo SDFormat to URDF Parser `_ * `SDF to URDF Converter in Python `_ * `URDF to Webots Simulator Format `_ - * The `Blender Robotics Tools `_ respository includes a number of useful tools, including a tool to export `URDF files from Blender. `_ + * The `Blender Robotics Tools `_ repository includes a number of useful tools, including a tool to export `URDF files from Blender. `_ * `CoppeliaSim URDF Exporter `_ * `Isaac Sim URDF Exporter `_ diff --git a/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-py.rst b/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-py.rst index a7c9ba07d01..3459f13caf8 100644 --- a/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-py.rst +++ b/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-py.rst @@ -282,6 +282,7 @@ Save the ``setup.py`` file with your changes. 6 Install the package ^^^^^^^^^^^^^^^^^^^^^ + .. code-block:: console cd second_ros2_ws diff --git a/source/Tutorials/Intermediate/URDF/Using-Xacro-to-Clean-Up-a-URDF-File.rst b/source/Tutorials/Intermediate/URDF/Using-Xacro-to-Clean-Up-a-URDF-File.rst index c27c6f3cad5..2f5014ada1c 100644 --- a/source/Tutorials/Intermediate/URDF/Using-Xacro-to-Clean-Up-a-URDF-File.rst +++ b/source/Tutorials/Intermediate/URDF/Using-Xacro-to-Clean-Up-a-URDF-File.rst @@ -179,7 +179,8 @@ Let’s take a look at a simple useless macro. -(This is useless, since if the origin is not specified, it has the same value as this.) This code will generate the following. +(This is useless, since if the origin is not specified, it has the same value as this.) +This code will generate the following. .. code-block:: xml diff --git a/source/Tutorials/Intermediate/Using-Node-Interfaces-Template-Class.rst b/source/Tutorials/Intermediate/Using-Node-Interfaces-Template-Class.rst new file mode 100644 index 00000000000..74006e81288 --- /dev/null +++ b/source/Tutorials/Intermediate/Using-Node-Interfaces-Template-Class.rst @@ -0,0 +1,242 @@ +Using the Node Interfaces Template Class (C++) +============================================== + +**Goal:** Learn how to access ``Node`` information using ``rclcpp::NodeInterfaces<>`` + +**Tutorial level:** Intermediate + +**Time:** 10 minutes + +.. contents:: Table of Contents + :depth: 2 + :local: + + +Overview +-------- + +Not all ROS Nodes are created equally! +the ``rclcpp::Node`` and ``rclcpp_lifecycle::LifecycleNode`` classes do not share an inheritance tree, which means ROS developers can run into compile time type issues when they want to write a function that takes in a ROS node pointer as an argument. +To address this issue, ``rclcpp`` includes the ``rclcpp::NodeInterfaces<>`` template type that should be used as the preferred convention for passing for both conventional and lifecycle nodes to functions. +This `ROSCon 2023 lightning talk `_ summarizes the issue and remedy succinctly. +The following tutorial will show you how to use ``rclcpp::NodeInterfaces<>`` as reliable and compact interface for all ROS node types. + +The ``rclcpp::NodeInterfaces<>`` template class provides a compact and efficient way to manage Node Interfaces in ROS 2. This is particularly useful when working with different types of ``Nodes``, such as ``rclcpp::Node`` and ``rclcpp_lifecycle::LifecycleNode``, which do not share the same inheritance tree. + +1 Accessing Node Information with a ``SharedPtr`` +------------------------------------------------- + +In the example below, we create a simple ``Node`` called ``Simple_Node`` and define a function ``node_info`` that accepts a ``SharedPtr`` to the ``Node``. The function retrieves and prints the name of the ``Node``. + +.. code-block:: c++ + + #include + #include "rclcpp/rclcpp.hpp" + + void node_info(rclcpp::Node::SharedPtr node) + { + RCLCPP_INFO(node->get_logger(), "Node name: %s", node->get_name()); + } + + class SimpleNode : public rclcpp::Node + { + public: + SimpleNode(const std::string & node_name) + : Node(node_name) + { + } + }; + + int main(int argc, char * argv[]) + { + rclcpp::init(argc, argv); + auto node = std::make_shared("Simple_Node"); + node_info(*node); + } + +Output: + +.. code-block:: console + + [INFO] [Simple_Node]: Node name: Simple_Node + +While this approach works well for arguments of type ``rclcpp::Node``, it does not work for other node types like ``rclcpp_lifecycle::LifecycleNode``. + +2 Explicitly pass ``rclcpp::node_interfaces`` +--------------------------------------------- + +A more robust approach, applicable to all node types, is to explicitly pass ``rclcpp::node_interfaces`` as function arguments, as demonstrated in the example below. +In the example that follows, we create function called ``node_info`` that take as arguments two ``rclcpp::node_interfaces``, ``NodeBaseInterface`` and ``NodeLoggingInterface`` and prints the ``Node`` name. +We then create two nodes of type ``rclcpp_lifecycle::LifecycleNode`` and ``rclcpp::Node`` and pass their interfaces in ``node_info``. + +.. code-block:: c++ + + void node_info(std::shared_ptr base_interface, + std::shared_ptr logging_interface) + { + RCLCPP_INFO(logging_interface->get_logger(), "Node name: %s", base_interface->get_name()); + } + + class SimpleNode : public rclcpp::Node + { + public: + SimpleNode(const std::string & node_name) + : Node(node_name) + { + } + }; + + class LifecycleTalker : public rclcpp_lifecycle::LifecycleNode + { + public: + explicit LifecycleTalker(const std::string & node_name, bool intra_process_comms = false) + : rclcpp_lifecycle::LifecycleNode(node_name, + rclcpp::NodeOptions().use_intra_process_comms(intra_process_comms)) + {} + } + + int main(int argc, char * argv[]) + { + rclcpp::init(argc, argv); + rclcpp::executors::SingleThreadedExecutor exe; + auto node = std::make_shared("Simple_Node"); + auto lc_node = std::make_shared("Simple_LifeCycle_Node"); + node_info(node->get_node_base_interface(),node->get_node_logging_interface()); + node_info(lc_node->get_node_base_interface(),lc_node->get_node_logging_interface()); + } + +.. code-block:: console + + [INFO] [Simple_Node]: Node name: Simple_Node + [INFO] [Simple_LifeCycle_Node]: Node name: Simple_LifeCycle_Node + +As functions grow in complexity, the number of ``rclcpp::node_interfaces`` arguments also increases, leading to readability and compactness issues. +To make the code more flexible and compatible with different node types, we use ``rclcpp::NodeInterfaces<>``. + +3 Using ``rclcpp::NodeInterfaces<>`` +------------------------------------ + +The recommended way of accessing a ``Node`` type's information is through the ``Node Interfaces``. + +Below, similar to the previous example, a ``rclcpp_lifecycle::LifecycleNode`` and a ``rclcpp::Node`` are created. + +.. code-block:: c++ + + #include + #include + #include + #include "lifecycle_msgs/msg/transition.hpp" + #include "rclcpp/rclcpp.hpp" + #include "rclcpp_lifecycle/lifecycle_node.hpp" + #include "rclcpp_lifecycle/lifecycle_publisher.hpp" + #include "rclcpp/node_interfaces/node_interfaces.hpp" + + using MyNodeInterfaces = + rclcpp::node_interfaces::NodeInterfaces; + + void node_info(MyNodeInterfaces interfaces) + { + auto base_interface = interfaces.get_node_base_interface(); + auto logging_interface = interfaces.get_node_logging_interface(); + RCLCPP_INFO(logging_interface->get_logger(), "Node name: %s", base_interface->get_name()); + } + + class SimpleNode : public rclcpp::Node + { + public: + SimpleNode(const std::string & node_name) + : Node(node_name) + { + } + }; + + class LifecycleTalker : public rclcpp_lifecycle::LifecycleNode + { + public: + explicit LifecycleTalker(const std::string & node_name, bool intra_process_comms = false) + : rclcpp_lifecycle::LifecycleNode(node_name, + rclcpp::NodeOptions().use_intra_process_comms(intra_process_comms)) + {} + } + + int main(int argc, char * argv[]) + { + rclcpp::init(argc, argv); + rclcpp::executors::SingleThreadedExecutor exe; + auto node = std::make_shared("Simple_Node"); + auto lc_node = std::make_shared("Simple_LifeCycle_Node"); + node_info(*node); + node_info(*lc_node); + } + +Output: + +.. code-block:: console + + [INFO] [Simple_Node]: Node name: Simple_Node + [INFO] [Simple_LifeCycle_Node]: Node name: Simple_LifeCycle_Node + +3.1 Examine the code +~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: c++ + + using MyNodeInterfaces = + rclcpp::node_interfaces::NodeInterfaces; + + void node_info(MyNodeInterfaces interfaces) + { + auto base_interface = interfaces.get_node_base_interface(); + auto logging_interface = interfaces.get_node_logging_interface(); + RCLCPP_INFO(logging_interface->get_logger(), "Node name: %s", base_interface->get_name()); + } + +Instead of accepting ``SharedPtr`` or a node interface, this function takes a reference to a ``rclcpp::node_interfaces::NodeInterfaces`` object. +Another advantage of using this approach is the support for implicit conversion of node-like objects. +This means that it is possible to directly pass any node-like object to a function expecting a ``rclcpp::node_interfaces::NodeInterfaces`` object. + +It extracts: + +* ``NodeBaseInterface`` Provides basic node functionalities. +* ``NodeLoggingInterface`` Enables logging. + +Then, it retrieves and prints the node name. + +.. code-block:: c++ + + class SimpleNode : public rclcpp::Node + { + public: + SimpleNode(const std::string & node_name) + : Node(node_name) + { + } + }; + + class LifecycleTalker : public rclcpp_lifecycle::LifecycleNode + { + public: + explicit LifecycleTalker(const std::string & node_name, bool intra_process_comms = false) + : rclcpp_lifecycle::LifecycleNode(node_name, + rclcpp::NodeOptions().use_intra_process_comms(intra_process_comms)) + {} + } + +Next, we create a ``rclcpp::Node`` as well as a ``rclcpp_lifecycle::LifecycleNode`` class. The ``rclcpp_lifecycle::LifecycleNode`` class often includes functions for the state transitions ``Unconfigured``, ``Inactive``, ``Active``, and ``Finalized``. However, they are not included for demonstration purposes. + +.. code-block:: c++ + + int main(int argc, char * argv[]) + { + rclcpp::init(argc, argv); + rclcpp::executors::SingleThreadedExecutor exe; + auto node = std::make_shared("Simple_Node"); + auto lc_node = std::make_shared("Simple_LifeCycle_Node"); + node_info(*node); + node_info(*lc_node); + } + +In the main function, a ``SharedPtr`` to both ``rclcpp_lifecycle::LifecycleNode`` and ``rclcpp::Node`` is created. +The function declared above is called once with each node type as an argument. + +.. note:: The ``SharedPtr`` needs to be dereferenced as the template accepts a reference to the ``NodeT`` object. diff --git a/source/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.rst b/source/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.rst index 81d690570b5..5dd898e2d48 100644 --- a/source/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.rst +++ b/source/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.rst @@ -232,7 +232,8 @@ Open up ``custom_action_cpp/CMakeLists.txt``, and add the following right after LIBRARY DESTINATION lib RUNTIME DESTINATION bin) -And now we can compile the package. Go to the top-level of the ``ros2_ws``, and run: +And now we can compile the package. +Go to the top-level of the ``ros2_ws``, and run: .. code-block:: bash @@ -360,7 +361,8 @@ Open up ``custom_action_cpp/CMakeLists.txt``, and add the following right after LIBRARY DESTINATION lib RUNTIME DESTINATION bin) -And now we can compile the package. Go to the top-level of the ``ros2_ws``, and run: +And now we can compile the package. +Go to the top-level of the ``ros2_ws``, and run: .. code-block:: bash diff --git a/source/Tutorials/Intermediate/Writing-an-Action-Server-Client/Py.rst b/source/Tutorials/Intermediate/Writing-an-Action-Server-Client/Py.rst index b0830190a27..e24fd92a6fe 100644 --- a/source/Tutorials/Intermediate/Writing-an-Action-Server-Client/Py.rst +++ b/source/Tutorials/Intermediate/Writing-an-Action-Server-Client/Py.rst @@ -346,7 +346,8 @@ This is achieved by additionally passing the callback to the action client when :language: python :lines: 21 -We're all set. If we run our action client, you should see feedback being printed to the screen. +We're all set. +If we run our action client, you should see feedback being printed to the screen. Summary ------- diff --git a/source/Tutorials/Miscellaneous/Building-ROS2-Package-with-eclipse-2021-06.rst b/source/Tutorials/Miscellaneous/Building-ROS2-Package-with-eclipse-2021-06.rst index 7f5f559759a..b4bc0ad500d 100644 --- a/source/Tutorials/Miscellaneous/Building-ROS2-Package-with-eclipse-2021-06.rst +++ b/source/Tutorials/Miscellaneous/Building-ROS2-Package-with-eclipse-2021-06.rst @@ -38,7 +38,8 @@ We see that we got C++ includes. :alt: eclipse_c++_project_includes -We now import our ROS 2 project. The code is still in the old place. +We now import our ROS 2 project. +The code is still in the old place. .. image:: images/eclipse_import_project.png :target: images/eclipse_import_project.png diff --git a/source/Tutorials/Miscellaneous/Building-Realtime-rt_preempt-kernel-for-ROS-2.rst b/source/Tutorials/Miscellaneous/Building-Realtime-rt_preempt-kernel-for-ROS-2.rst index 71120de07a8..ff9ea4a0314 100644 --- a/source/Tutorials/Miscellaneous/Building-Realtime-rt_preempt-kernel-for-ROS-2.rst +++ b/source/Tutorials/Miscellaneous/Building-Realtime-rt_preempt-kernel-for-ROS-2.rst @@ -6,7 +6,9 @@ Building a real-time Linux kernel [community-contributed] ========================================================= -This tutorial begins with a clean Ubuntu 20.04.1 install on Intel x86_64. Actual kernel is 5.4.0-54-generic, but we will install the Latest Stable RT_PREEMPT Version. To build the kernel you need at least 30GB free disk space. +This tutorial begins with a clean Ubuntu 20.04.1 install on Intel x86_64. +Actual kernel is 5.4.0-54-generic, but we will install the Latest Stable RT_PREEMPT Version. +To build the kernel you need at least 30GB free disk space. Check https://wiki.linuxfoundation.org/realtime/start for the latest stable version, at the time of writing this is "Latest Stable Version 5.4-rt". If we click on the `link `_, we get the exact version. @@ -68,7 +70,8 @@ We simply want to use the config of our Ubuntu installation, so we get the Ubunt cp /boot/config-5.4.0-54-generic .config -Open Software & Updates. in the Ubuntu Software menu tick the 'Source code' box +Open Software & Updates. +in the Ubuntu Software menu tick the 'Source code' box We need some tools to build kernel, install them with @@ -83,7 +86,8 @@ To enable all Ubuntu configurations, we simply use yes '' | make oldconfig -Then we need to enable rt_preempt in the kernel. We call +Then we need to enable rt_preempt in the kernel. +We call .. code-block:: bash @@ -121,7 +125,8 @@ and set the following -> Default CPUFreq governor ( [=y]) (X) performance -Save and exit menuconfig. Now we're going to build the kernel which will take quite some time. (10-30min on a modern cpu) +Save and exit menuconfig. +Now we're going to build the kernel which will take quite some time. (10-30min on a modern cpu) .. code-block:: bash @@ -141,7 +146,8 @@ Then we install all kernel deb packages sudo dpkg -i ../*.deb -Now the real time kernel should be installed. Reboot the system and check the new kernel version +Now the real time kernel should be installed. +Reboot the system and check the new kernel version .. code-block:: bash diff --git a/source/Tutorials/Miscellaneous/Deploying-ROS-2-on-IBM-Cloud.rst b/source/Tutorials/Miscellaneous/Deploying-ROS-2-on-IBM-Cloud.rst index 708cf5d0661..c758978f086 100644 --- a/source/Tutorials/Miscellaneous/Deploying-ROS-2-on-IBM-Cloud.rst +++ b/source/Tutorials/Miscellaneous/Deploying-ROS-2-on-IBM-Cloud.rst @@ -14,7 +14,8 @@ Deploying on IBM Cloud Kubernetes [community-contributed] About ----- -This article describes how to get ROS 2 running on IBM Cloud using Docker files. It first gives a brief overview of docker images and how they work locally and then explores IBM Cloud and how the user can deploy their containers on it. +This article describes how to get ROS 2 running on IBM Cloud using Docker files. +It first gives a brief overview of docker images and how they work locally and then explores IBM Cloud and how the user can deploy their containers on it. Afterwards, a short description of how the user can use their own custom packages for ROS 2 from github on IBM Cloud is provided. A walkthrough of how to create a cluster and utilize Kubernetes on IBM Cloud is provided and finally the Docker image is deployed on the cluster. Originally published `here `__ and `here `__. @@ -25,11 +26,10 @@ ROS 2 on IBM Cloud In this tutorial, we show how you can easily integrate and run ROS 2 on IBM Cloud with your custom packages. -ROS 2 is the new generation of ROS which gives more control over -multi-robot formations. With the advancements of cloud computing, cloud -robotics are becoming more important in today's age. In this tutorial, -we will go through a short introduction on running ROS 2 on IBM Cloud. By -the end of the tutorial, you will be able to create your own packages in +ROS 2 is the new generation of ROS which gives more control over multi-robot formations. +With the advancements of cloud computing, cloud robotics are becoming more important in today's age. +In this tutorial, we will go through a short introduction on running ROS 2 on IBM Cloud. +By the end of the tutorial, you will be able to create your own packages in ROS 2 and deploy them to the cloud using docker files. The following instructions assume you're using Linux and have been @@ -38,29 +38,26 @@ tested with Ubuntu 18.04 (Bionic Beaver). Step 1: Setting up your system ------------------------------- -Before we go into how the exact process works, lets first make sure all -the required software is properly installed. We'll point you towards the -appropriate sources to set up your system and only highlight the details -that pertain to our use-case. +Before we go into how the exact process works, lets first make sure all the required software is properly installed. +We'll point you towards the appropriate sources to set up your system and only highlight the details that pertain to our use-case. a) Docker files? ^^^^^^^^^^^^^^^^ Docker files are a form of containers that can run separate from your system, this way, you can set-up potentially hundreds of different -projects without affecting one another. You can even set-up different -versions of Linux on one machine, without the need for virtual machine. -Docker files have an advantage of saving space and only utilizing your -system resources when running. In addition, dockers are versatile and -transferable. They contain all the required pre-requisites to run +projects without affecting one another. +You can even set-up different versions of Linux on one machine, without the need for virtual machine. +Docker files have an advantage of saving space and only utilizing your system resources when running. +In addition, dockers are versatile and transferable. +They contain all the required pre-requisites to run separately, meaning that you can easily use a docker file for a specific system or service without any cubersome steps! -Excited yet? Let's start off by installing docker to your system by -following the following `link `__. -From the tutorial, you should have done some sanity checks to make sure -docker is properly set-up. Just in case, however, let's run the -following command once again that uses the hello-world docker image: +Excited yet? +Let's start off by installing docker to your system by following the following `link `__. +From the tutorial, you should have done some sanity checks to make sure docker is properly set-up. +Just in case, however, let's run the following command once again that uses the hello-world docker image: .. code-block:: bash @@ -96,16 +93,17 @@ b) ROS 2 Image ROS `announced `__ -image containers for several ROS distributions in January 2019. More -detailed instructions on the use of ROS 2 docker images can be found +image containers for several ROS distributions in January 2019. +More detailed instructions on the use of ROS 2 docker images can be found `here `__. Let's skip through that and get to real-deal right away; creating a -local ROS 2 docker. We'll create our own Dockerfile (instead of using a +local ROS 2 docker. +We'll create our own Dockerfile (instead of using a ready Image) since we'll need this method for deployment on IBM Cloud. First, we create a new directory which will hold our Dockerfile and any -other files we need later on and navigate to it. Using your favorite -$EDITOR of choice, open a new file named *Dockerfile* (make sure the +other files we need later on and navigate to it. +Using your favorite $EDITOR of choice, open a new file named *Dockerfile* (make sure the file naming is correct): .. code-block:: bash @@ -141,15 +139,14 @@ Insert the following in the *Dockerfile*, and save it (also found be for it Of course, you are free to change the ROS distribution (*foxy* is used -here) or change the directory name. The above docker file sets up -ROS-foxy and installs the demo nodes for C++ and Python. Then it -launches a file which runs a talker and a listener node. We will see it -in action in just a few, but they act very similar to the +here) or change the directory name. +The above docker file sets up ROS-foxy and installs the demo nodes for C++ and Python. +Then it launches a file which runs a talker and a listener node. +We will see it in action in just a few, but they act very similar to the publisher-subscriber example found in the `ROS wiki `__ -Now, we are ready to build the docker image to run ROS 2 in it (yes, it -is THAT easy!). +Now, we are ready to build the docker image to run ROS 2 in it (yes, it is THAT easy!). **Note**: if you have errors due to insufficient privileges or *permission denied*, try running the command with *sudo* privileges: @@ -162,7 +159,8 @@ is THAT easy!). Successfully built 0dc6ce7cb487 *0dc6ce7cb487* will most probably be different for you, so keep note of -it and copy it somewhere for reference. You can always go back and check +it and copy it somewhere for reference. +You can always go back and check the docker images you have on your system using: .. code-block:: bash @@ -191,15 +189,16 @@ Now, run the docker file using: [talker-1] [INFO] [1603852912.249556670] [talker]: Publishing: 'Hello World: 6' [listener-2] [INFO] [1603852912.250212678] [listener]: I heard: [Hello World: 6] -If it works correctly, you should see something similar to what is shown -above. As can be seen, there are two ROS nodes (a publisher and a +If it works correctly, you should see something similar to what is shown above. +As can be seen, there are two ROS nodes (a publisher and a subscriber) running and their output is provided to us through ROS INFO. Step 2: Running the image on IBM Cloud -------------------------------------- The following steps assume you have an IBM cloud account and have -ibmcloud CLI installed. If not, please check this +ibmcloud CLI installed. +If not, please check this `link `__ out to get that done first. @@ -216,20 +215,18 @@ Afterwards, login to your ibmcloud account through the terminal: $ ibmcloud login --sso -From here, let's create a container registry name-space. Make sure you -use a unique name that is also descriptive as to what it is. Here, I -used *ros2nasr*. +From here, let's create a container registry name-space. +Make sure you use a unique name that is also descriptive as to what it is. +Here, I used *ros2nasr*. .. code-block:: bash $ ibmcloud cr namespace-add ros2nasr -IBM cloud has a lot of shortcuts that would help us get our container -onto the cloud right away. The command below builds the container and -tags it with the name **ros2foxy** and the version of **1**. Make sure -you use the correct registry name you created and you are free to change -the container name as you wish. The **.** at the end indicates that the -*Dockerfile* is in the current directory (and it is important), if not, +IBM cloud has a lot of shortcuts that would help us get our container onto the cloud right away. +The command below builds the container and tags it with the name **ros2foxy** and the version of **1**. +Make sure you use the correct registry name you created and you are free to change the container name as you wish. +The **.** at the end indicates that the *Dockerfile* is in the current directory (and it is important), if not, change it to point to the directory containing the Dockerfile. .. code-block:: bash @@ -249,10 +246,9 @@ you created by running the following command OK -Next, it is important to log-in to your registry to run the docker -image. Again, if you face a *permission denied* error, perform the -command with sudo privileges. Afterwards, run your docker file as shown -below. +Next, it is important to log-in to your registry to run the docker image. +Again, if you face a *permission denied* error, perform the command with sudo privileges. +Afterwards, run your docker file as shown below. .. code-block:: bash @@ -276,14 +272,12 @@ to that you saw when you ran it locally on your machine. Step 3: Using Custom ROS 2 Packages ----------------------------------- -So now we have the full pipeline working, from creating the Dockerfile, -all the way to deploying it and seeing it work on IBM Cloud. But, what -if we want to use a custom set of packages we (or someone else) created? +So now we have the full pipeline working, from creating the Dockerfile, all the way to deploying it and seeing it work on IBM Cloud. +But, what if we want to use a custom set of packages we (or someone else) created? -Well that all has to do with how you set-up your Dockerfile. Lets use -the example provided by ROS 2 `here `__. -Create a new directory with a new Dockerfile (or overwrite the existing -one) and add the following in it (or download the file +Well that all has to do with how you set-up your Dockerfile. +Let's use the example provided by ROS 2 `here `__. +Create a new directory with a new Dockerfile (or overwrite the existing one) and add the following in it (or download the file `here `__) .. code-block:: bash @@ -408,12 +402,10 @@ and then run them. **Back to IBM Cloud** -With this Dockerfile, we can follow the same steps we did before to -deploy it on IBM Cloud. Since we already have our registry created, and -we're logged in to IBM Cloud, we directly build our new Dockerfile. -Notice how I kept the tag the same but changed the version, this way I -can update the docker image created previously. (You are free to create -a completely new one if you want) +With this Dockerfile, we can follow the same steps we did before to deploy it on IBM Cloud. +Since we already have our registry created, and we're logged in to IBM Cloud, we directly build our new Dockerfile. +Notice how I kept the tag the same but changed the version, this way I can update the docker image created previously. +(You are free to create a completely new one if you want) .. code-block:: bash @@ -434,9 +426,8 @@ image: $ docker run -v -it registry.ng.bluemix.net/ros2nasr/ros2foxy:2 -You should see, again, the same output. However, this time we did it -through custom packages from github, which allows us to utilize our -personally created packages for ROS 2 on IBM Cloud. +You should see, again, the same output. +However, this time we did it through custom packages from github, which allows us to utilize our personally created packages for ROS 2 on IBM Cloud. Extra: Deleting Docker Images ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -465,11 +456,11 @@ Step 4: Kubernetes a) Creating the Cluster ^^^^^^^^^^^^^^^^^^^^^^^ -Create a cluster using the Console. The instructions are found -`here `__. -The settings used are detailed below. These are merely suggestions and -can be changed if you need to. However, make sure you understand the -implications of your choices: +Create a cluster using the Console. +The instructions are found `here `__. +The settings used are detailed below. +These are merely suggestions and can be changed if you need to. +However, make sure you understand the implications of your choices: 1. Plan: *Standard* @@ -483,9 +474,8 @@ implications of your choices: - Geography: *North America* (you are free to change this) -- Availability: *Single zone* (you are free to change this but make - sure you understand the impact of your choices by checking the IBM - Cloud documentation.) +- Availability: *Single zone* + (you are free to change this but make sure you understand the impact of your choices by checking the IBM Cloud documentation.) - Worker Zone: *Toronto 01* (choose the location that is physically closest to you) @@ -506,13 +496,11 @@ implications of your choices: - Tags: *version:1* -After you create your cluster, you will be redirected to a page which -details how you can set up the CLI tools and access your cluster. Please -follow these instructions (or check the instructions -`here `__)and -wait for the progress bar to show that the worker nodes you created are -ready by indicating *Normal* next to the cluster name. You can also -reach this screen from the IBM Cloud Console inside the Kubernetes. +After you create your cluster, you will be redirected to a page which details how you can set up the CLI tools and access your cluster. +Please follow these instructions (or check the instructions `here `__) +and wait for the progress bar to show that the worker nodes you created are +ready by indicating *Normal* next to the cluster name. +You can also reach this screen from the IBM Cloud Console inside the Kubernetes. b) Deploying your Docker Image *Finally!* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -588,8 +576,9 @@ parameters of your cluster as well as its CPU and Memory Usage. 4. On the top right corner, click on *Exec into pod* -Now you are inside your docker image! You can source your workspace (if -needed) and run ROS 2! For example: +Now you are inside your docker image! +You can source your workspace (if needed) and run ROS 2! +For example: .. code-block:: bash @@ -599,4 +588,8 @@ needed) and run ROS 2! For example: Final Remarks --------------- -At this point, you are capable of creating your own docker image using ROS 2 packages on github. It is also possible, with little changes to utilize local ROS 2 packages as well. This could be the topic of another article. However, you are encouraged to check out the following `Dockerfile `__ which uses a local copy of the demos repository. Similarly, you can use your own local package. +At this point, you are capable of creating your own docker image using ROS 2 packages on github. +It is also possible, with little changes to utilize local ROS 2 packages as well. +This could be the topic of another article. +However, you are encouraged to check out the following `Dockerfile `__ which uses a local copy of the demos repository. +Similarly, you can use your own local package. diff --git a/source/index.rst b/source/index.rst index a686ef528cc..0d38cb776f7 100644 --- a/source/index.rst +++ b/source/index.rst @@ -29,7 +29,8 @@ From drivers and state-of-the-art algorithms to powerful developer tools, ROS ha Since ROS was started in 2007, a lot has changed in the robotics and ROS community. The goal of the ROS 2 project is to adapt to these changes, leveraging what is great about ROS 1 and improving what isn’t. -**Are you looking for documentation for a particular ROS package like MoveIt, image_proc, or octomap?** Please see `ROS Index `__ or check out `this index of per-package documentation `__. +**Are you looking for documentation for a particular ROS package like MoveIt, image_proc, or octomap?** +Please see `ROS Index `__ or check out `this index of per-package documentation `__. This site contains the documentation for ROS 2. If you are looking for ROS 1 documentation, check out the `ROS wiki `__.