From 7b786b2ec9d056c2cfc46e447839d1e68bcb2b5f Mon Sep 17 00:00:00 2001
From: m-bochenek <62942399+m-bochenek@users.noreply.github.com>
Date: Wed, 22 Apr 2026 17:38:22 +0100
Subject: [PATCH 01/20] Editing the GET STARTED section of the TOC
---
source/Capabilities.rst | 20 +++++++++++++++
.../Testing}/Testing.rst | 0
source/Get-Started.rst | 24 ++++++++++++++++++
source/{ => Get-Started}/About-ROS.rst | 0
.../Configuring-ROS2-Environment.rst | 0
source/{ => Get-Started}/Installation.rst | 14 +++++-----
.../Installation/Alternatives.rst | 3 ++-
.../Alternatives/Latest-Development-Setup.rst | 0
.../Maintaining-a-Source-Checkout.rst | 0
.../Alternatives/RHEL-Development-Setup.rst | 0
.../Alternatives/RHEL-Install-Binary.rst | 0
.../Alternatives/Ubuntu-Development-Setup.rst | 0
.../Alternatives/Ubuntu-Install-Binary.rst | 0
.../Windows-Development-Setup.rst | 0
.../Alternatives/macOS-Development-Setup.rst | 0
.../Installation/RHEL-Install-RPMs.rst | 0
.../Installation/RMW-Implementations.rst | 0
.../DDS-Implementations.rst | 0
.../Working-with-Eclipse-CycloneDDS.rst | 0
.../Working-with-GurumNetworks-GurumDDS.rst | 0
.../Working-with-RTI-Connext-DDS.rst | 0
.../Working-with-eProsima-Fast-DDS.rst | 0
.../Non-DDS-Implementations.rst | 0
.../Working-with-Zenoh.rst | 0
.../Installation/ROS-2-Mirrors.rst | 0
.../Installation/Ubuntu-Install-Debs.rst | 0
.../Installation/Windows-Install-Binary.rst | 0
.../Installation/_Apt-Repositories.rst | 0
.../Installation/_Apt-Upgrade-Admonition.rst | 0
.../Installation/_Dnf-Update-Admonition.rst | 0
.../Installation/_RHEL-Set-Locale.rst | 0
.../Installation/_Ubuntu-Set-Locale.rst | 0
.../Installation/_rosdep_Linux_Mint.rst | 0
.../python_installation_enable_debug.png | Bin
.../images/python_installation_modify.png | Bin
.../images/python_installation_next.png | Bin
.../images/vs_community_screenshot.png | Bin
.../images/windows-vs-studio-install.png | Bin
.../Introducing-Turtlesim.rst | 0
.../Introducing-Turtlesim/images/new_pen.png | Bin
.../Introducing-Turtlesim/images/remap.png | Bin
.../Introducing-Turtlesim/images/rqt.png | Bin
.../Introducing-Turtlesim/images/set_pen.png | Bin
.../Introducing-Turtlesim/images/spawn.png | Bin
.../images/turtlesim.png | Bin
source/{ => Get-Started}/Releases.rst | 16 ++++++------
.../Releases/Alpha-Overview.rst | 0
.../Releases/Beta1-Overview.rst | 0
.../Releases/Beta2-Overview.rst | 0
.../Releases/Beta3-Overview.rst | 0
.../Releases/Development.rst | 0
.../Releases/End-of-Life.rst | 0
...Galactic-Geochelone-Complete-Changelog.rst | 0
.../Humble-Hawksbill-Complete-Changelog.rst | 0
.../Iron-Irwini-Complete-Changelog.rst | 0
.../Jazzy-Jalisco-Complete-Changelog.rst | 0
.../Kilted-Kaiju-Complete-Changelog.rst | 0
.../Releases/Release-Ardent-Apalone.rst | 0
.../Releases/Release-Bouncy-Bolson.rst | 0
.../Releases/Release-Crystal-Clemmys.rst | 0
.../Releases/Release-Dashing-Diademata.rst | 0
.../Releases/Release-Eloquent-Elusor.rst | 0
.../Releases/Release-Foxy-Fitzroy.rst | 0
.../Releases/Release-Galactic-Geochelone.rst | 0
.../Releases/Release-Humble-Hawksbill.rst | 0
.../Releases/Release-Iron-Irwini.rst | 0
.../Releases/Release-Jazzy-Jalisco.rst | 0
.../Releases/Release-Kilted-Kaiju.rst | 0
.../Releases/Release-Lyrical-Luth.rst | 0
.../Releases/Release-Process.rst | 0
.../Releases/Release-Rolling-Ridley.rst | 0
.../Releases/ardent-small.png | Bin
.../Releases/bouncy-small.png | Bin
.../Releases/crystal-small.png | Bin
.../Releases/dashing-small.png | Bin
.../Releases/eloquent-small.png | Bin
.../{ => Get-Started}/Releases/foxy-small.png | Bin
.../Releases/galactic-small.png | Bin
.../Releases/humble-small.png | Bin
...t_graph-qos-incompatibility-2021-05-17.png | Bin
.../images/rviz2-far-plane-distance.png | Bin
.../Releases/images/rviz_mass_inertia.png | Bin
.../Releases/images/tb4_inertia.png | Bin
.../images/triangle_marker_with_gradient.png | Bin
.../{ => Get-Started}/Releases/iron-small.png | Bin
.../Releases/jazzy-small.png | Bin
.../Releases/kilted-small.png | Bin
.../Releases/rolling-small.png | Bin
.../Releases/rviz2-time-panel-2021-05-17.png | Bin
source/ROS-Framework.rst | 20 +++++++++++++++
90 files changed, 80 insertions(+), 17 deletions(-)
create mode 100644 source/Capabilities.rst
rename source/{Installation => Developer-Tools/Testing}/Testing.rst (100%)
create mode 100644 source/Get-Started.rst
rename source/{ => Get-Started}/About-ROS.rst (100%)
rename source/{Tutorials/Beginner-CLI-Tools => Get-Started}/Configuring-ROS2-Environment.rst (100%)
rename source/{ => Get-Started}/Installation.rst (92%)
rename source/{ => Get-Started}/Installation/Alternatives.rst (81%)
rename source/{ => Get-Started}/Installation/Alternatives/Latest-Development-Setup.rst (100%)
rename source/{Installation => Get-Started/Installation/Alternatives}/Maintaining-a-Source-Checkout.rst (100%)
rename source/{ => Get-Started}/Installation/Alternatives/RHEL-Development-Setup.rst (100%)
rename source/{ => Get-Started}/Installation/Alternatives/RHEL-Install-Binary.rst (100%)
rename source/{ => Get-Started}/Installation/Alternatives/Ubuntu-Development-Setup.rst (100%)
rename source/{ => Get-Started}/Installation/Alternatives/Ubuntu-Install-Binary.rst (100%)
rename source/{ => Get-Started}/Installation/Alternatives/Windows-Development-Setup.rst (100%)
rename source/{ => Get-Started}/Installation/Alternatives/macOS-Development-Setup.rst (100%)
rename source/{ => Get-Started}/Installation/RHEL-Install-RPMs.rst (100%)
rename source/{ => Get-Started}/Installation/RMW-Implementations.rst (100%)
rename source/{ => Get-Started}/Installation/RMW-Implementations/DDS-Implementations.rst (100%)
rename source/{ => Get-Started}/Installation/RMW-Implementations/DDS-Implementations/Working-with-Eclipse-CycloneDDS.rst (100%)
rename source/{ => Get-Started}/Installation/RMW-Implementations/DDS-Implementations/Working-with-GurumNetworks-GurumDDS.rst (100%)
rename source/{ => Get-Started}/Installation/RMW-Implementations/DDS-Implementations/Working-with-RTI-Connext-DDS.rst (100%)
rename source/{ => Get-Started}/Installation/RMW-Implementations/DDS-Implementations/Working-with-eProsima-Fast-DDS.rst (100%)
rename source/{ => Get-Started}/Installation/RMW-Implementations/Non-DDS-Implementations.rst (100%)
rename source/{ => Get-Started}/Installation/RMW-Implementations/Non-DDS-Implementations/Working-with-Zenoh.rst (100%)
rename source/{ => Get-Started}/Installation/ROS-2-Mirrors.rst (100%)
rename source/{ => Get-Started}/Installation/Ubuntu-Install-Debs.rst (100%)
rename source/{ => Get-Started}/Installation/Windows-Install-Binary.rst (100%)
rename source/{ => Get-Started}/Installation/_Apt-Repositories.rst (100%)
rename source/{ => Get-Started}/Installation/_Apt-Upgrade-Admonition.rst (100%)
rename source/{ => Get-Started}/Installation/_Dnf-Update-Admonition.rst (100%)
rename source/{ => Get-Started}/Installation/_RHEL-Set-Locale.rst (100%)
rename source/{ => Get-Started}/Installation/_Ubuntu-Set-Locale.rst (100%)
rename source/{ => Get-Started}/Installation/_rosdep_Linux_Mint.rst (100%)
rename source/{ => Get-Started}/Installation/images/python_installation_enable_debug.png (100%)
rename source/{ => Get-Started}/Installation/images/python_installation_modify.png (100%)
rename source/{ => Get-Started}/Installation/images/python_installation_next.png (100%)
rename source/{ => Get-Started}/Installation/images/vs_community_screenshot.png (100%)
rename source/{ => Get-Started}/Installation/images/windows-vs-studio-install.png (100%)
rename source/{Tutorials/Beginner-CLI-Tools => Get-Started}/Introducing-Turtlesim/Introducing-Turtlesim.rst (100%)
rename source/{Tutorials/Beginner-CLI-Tools => Get-Started}/Introducing-Turtlesim/images/new_pen.png (100%)
rename source/{Tutorials/Beginner-CLI-Tools => Get-Started}/Introducing-Turtlesim/images/remap.png (100%)
rename source/{Tutorials/Beginner-CLI-Tools => Get-Started}/Introducing-Turtlesim/images/rqt.png (100%)
rename source/{Tutorials/Beginner-CLI-Tools => Get-Started}/Introducing-Turtlesim/images/set_pen.png (100%)
rename source/{Tutorials/Beginner-CLI-Tools => Get-Started}/Introducing-Turtlesim/images/spawn.png (100%)
rename source/{Tutorials/Beginner-CLI-Tools => Get-Started}/Introducing-Turtlesim/images/turtlesim.png (100%)
rename source/{ => Get-Started}/Releases.rst (96%)
rename source/{ => Get-Started}/Releases/Alpha-Overview.rst (100%)
rename source/{ => Get-Started}/Releases/Beta1-Overview.rst (100%)
rename source/{ => Get-Started}/Releases/Beta2-Overview.rst (100%)
rename source/{ => Get-Started}/Releases/Beta3-Overview.rst (100%)
rename source/{ => Get-Started}/Releases/Development.rst (100%)
rename source/{ => Get-Started}/Releases/End-of-Life.rst (100%)
rename source/{ => Get-Started}/Releases/Galactic-Geochelone-Complete-Changelog.rst (100%)
rename source/{ => Get-Started}/Releases/Humble-Hawksbill-Complete-Changelog.rst (100%)
rename source/{ => Get-Started}/Releases/Iron-Irwini-Complete-Changelog.rst (100%)
rename source/{ => Get-Started}/Releases/Jazzy-Jalisco-Complete-Changelog.rst (100%)
rename source/{ => Get-Started}/Releases/Kilted-Kaiju-Complete-Changelog.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Ardent-Apalone.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Bouncy-Bolson.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Crystal-Clemmys.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Dashing-Diademata.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Eloquent-Elusor.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Foxy-Fitzroy.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Galactic-Geochelone.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Humble-Hawksbill.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Iron-Irwini.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Jazzy-Jalisco.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Kilted-Kaiju.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Lyrical-Luth.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Process.rst (100%)
rename source/{ => Get-Started}/Releases/Release-Rolling-Ridley.rst (100%)
rename source/{ => Get-Started}/Releases/ardent-small.png (100%)
rename source/{ => Get-Started}/Releases/bouncy-small.png (100%)
rename source/{ => Get-Started}/Releases/crystal-small.png (100%)
rename source/{ => Get-Started}/Releases/dashing-small.png (100%)
rename source/{ => Get-Started}/Releases/eloquent-small.png (100%)
rename source/{ => Get-Started}/Releases/foxy-small.png (100%)
rename source/{ => Get-Started}/Releases/galactic-small.png (100%)
rename source/{ => Get-Started}/Releases/humble-small.png (100%)
rename source/{ => Get-Started}/Releases/images/rqt_graph-qos-incompatibility-2021-05-17.png (100%)
rename source/{ => Get-Started}/Releases/images/rviz2-far-plane-distance.png (100%)
rename source/{ => Get-Started}/Releases/images/rviz_mass_inertia.png (100%)
rename source/{ => Get-Started}/Releases/images/tb4_inertia.png (100%)
rename source/{ => Get-Started}/Releases/images/triangle_marker_with_gradient.png (100%)
rename source/{ => Get-Started}/Releases/iron-small.png (100%)
rename source/{ => Get-Started}/Releases/jazzy-small.png (100%)
rename source/{ => Get-Started}/Releases/kilted-small.png (100%)
rename source/{ => Get-Started}/Releases/rolling-small.png (100%)
rename source/{ => Get-Started}/Releases/rviz2-time-panel-2021-05-17.png (100%)
create mode 100644 source/ROS-Framework.rst
diff --git a/source/Capabilities.rst b/source/Capabilities.rst
new file mode 100644
index 00000000000..45a954048e3
--- /dev/null
+++ b/source/Capabilities.rst
@@ -0,0 +1,20 @@
+.. _InstallationGuide:
+.. _RollingInstall:
+
+Capabilities
+============
+
+PLACEHOLDER
+
+.. toctree::
+ :hidden:
+ :glob:
+
+ Installation/Ubuntu-Install-Debs
+ Installation/Windows-Install-Binary
+ Installation/RHEL-Install-RPMs
+ Installation/Alternatives
+ Installation/Maintaining-a-Source-Checkout
+ Installation/Testing
+ Installation/RMW-Implementations
+ Installation/ROS-2-Mirrors
diff --git a/source/Installation/Testing.rst b/source/Developer-Tools/Testing/Testing.rst
similarity index 100%
rename from source/Installation/Testing.rst
rename to source/Developer-Tools/Testing/Testing.rst
diff --git a/source/Get-Started.rst b/source/Get-Started.rst
new file mode 100644
index 00000000000..c3241747466
--- /dev/null
+++ b/source/Get-Started.rst
@@ -0,0 +1,24 @@
+.. _InstallationGuide:
+.. _RollingInstall:
+
+Get started
+============
+
+PLACEHOLDER
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+
+ Get-Started/About-ROS
+ Get-Started/Installation/Ubuntu-Install-Debs
+ Get-Started/Installation/Windows-Install-Binary
+ Get-Started/Installation/RHEL-Install-RPMs
+ Get-Started/Installation/Alternatives
+ Get-Started/Installation/Maintaining-a-Source-Checkout
+ Get-Started/Installation/Testing
+ Get-Started/Installation/RMW-Implementations
+ Get-Started/Installation/ROS-2-Mirrors
+ Get-Started/Releases
+ Get-Started/Configuring-ROS2-Environment
+ Get-Started/Introducing-Turtlesim
\ No newline at end of file
diff --git a/source/About-ROS.rst b/source/Get-Started/About-ROS.rst
similarity index 100%
rename from source/About-ROS.rst
rename to source/Get-Started/About-ROS.rst
diff --git a/source/Tutorials/Beginner-CLI-Tools/Configuring-ROS2-Environment.rst b/source/Get-Started/Configuring-ROS2-Environment.rst
similarity index 100%
rename from source/Tutorials/Beginner-CLI-Tools/Configuring-ROS2-Environment.rst
rename to source/Get-Started/Configuring-ROS2-Environment.rst
diff --git a/source/Installation.rst b/source/Get-Started/Installation.rst
similarity index 92%
rename from source/Installation.rst
rename to source/Get-Started/Installation.rst
index 5f0ec3f0722..a4f445ba608 100644
--- a/source/Installation.rst
+++ b/source/Get-Started/Installation.rst
@@ -10,14 +10,12 @@ Options for installing ROS 2 {DISTRO_TITLE_FULL}:
:hidden:
:glob:
- Installation/Ubuntu-Install-Debs
- Installation/Windows-Install-Binary
- Installation/RHEL-Install-RPMs
- Installation/Alternatives
- Installation/Maintaining-a-Source-Checkout
- Installation/Testing
- Installation/RMW-Implementations
- Installation/ROS-2-Mirrors
+ Get-Started/Installation/Ubuntu-Install-Debs
+ Get-Started/Installation/Windows-Install-Binary
+ Get-Started/Installation/RHEL-Install-RPMs
+ Get-Started/Installation/Alternatives
+ Get-Started/Installation/RMW-Implementations
+ Get-Started/Installation/ROS-2-Mirrors
.. _binary-package-platforms:
diff --git a/source/Installation/Alternatives.rst b/source/Get-Started/Installation/Alternatives.rst
similarity index 81%
rename from source/Installation/Alternatives.rst
rename to source/Get-Started/Installation/Alternatives.rst
index 4a05c841222..8bad2cbfdc1 100644
--- a/source/Installation/Alternatives.rst
+++ b/source/Get-Started/Installation/Alternatives.rst
@@ -1,4 +1,4 @@
-Alternatives
+Advanced installation options
============
A list of alternative ways to install ROS 2 – whether it's by building from source or installing a binary.
@@ -13,3 +13,4 @@ A list of alternative ways to install ROS 2 – whether it's by building from s
Alternatives/RHEL-Install-Binary
Alternatives/macOS-Development-Setup
Alternatives/Latest-Development-Setup
+ Get-Started/Installation/Alternatives/Maintaining-a-Source-Checkout
diff --git a/source/Installation/Alternatives/Latest-Development-Setup.rst b/source/Get-Started/Installation/Alternatives/Latest-Development-Setup.rst
similarity index 100%
rename from source/Installation/Alternatives/Latest-Development-Setup.rst
rename to source/Get-Started/Installation/Alternatives/Latest-Development-Setup.rst
diff --git a/source/Installation/Maintaining-a-Source-Checkout.rst b/source/Get-Started/Installation/Alternatives/Maintaining-a-Source-Checkout.rst
similarity index 100%
rename from source/Installation/Maintaining-a-Source-Checkout.rst
rename to source/Get-Started/Installation/Alternatives/Maintaining-a-Source-Checkout.rst
diff --git a/source/Installation/Alternatives/RHEL-Development-Setup.rst b/source/Get-Started/Installation/Alternatives/RHEL-Development-Setup.rst
similarity index 100%
rename from source/Installation/Alternatives/RHEL-Development-Setup.rst
rename to source/Get-Started/Installation/Alternatives/RHEL-Development-Setup.rst
diff --git a/source/Installation/Alternatives/RHEL-Install-Binary.rst b/source/Get-Started/Installation/Alternatives/RHEL-Install-Binary.rst
similarity index 100%
rename from source/Installation/Alternatives/RHEL-Install-Binary.rst
rename to source/Get-Started/Installation/Alternatives/RHEL-Install-Binary.rst
diff --git a/source/Installation/Alternatives/Ubuntu-Development-Setup.rst b/source/Get-Started/Installation/Alternatives/Ubuntu-Development-Setup.rst
similarity index 100%
rename from source/Installation/Alternatives/Ubuntu-Development-Setup.rst
rename to source/Get-Started/Installation/Alternatives/Ubuntu-Development-Setup.rst
diff --git a/source/Installation/Alternatives/Ubuntu-Install-Binary.rst b/source/Get-Started/Installation/Alternatives/Ubuntu-Install-Binary.rst
similarity index 100%
rename from source/Installation/Alternatives/Ubuntu-Install-Binary.rst
rename to source/Get-Started/Installation/Alternatives/Ubuntu-Install-Binary.rst
diff --git a/source/Installation/Alternatives/Windows-Development-Setup.rst b/source/Get-Started/Installation/Alternatives/Windows-Development-Setup.rst
similarity index 100%
rename from source/Installation/Alternatives/Windows-Development-Setup.rst
rename to source/Get-Started/Installation/Alternatives/Windows-Development-Setup.rst
diff --git a/source/Installation/Alternatives/macOS-Development-Setup.rst b/source/Get-Started/Installation/Alternatives/macOS-Development-Setup.rst
similarity index 100%
rename from source/Installation/Alternatives/macOS-Development-Setup.rst
rename to source/Get-Started/Installation/Alternatives/macOS-Development-Setup.rst
diff --git a/source/Installation/RHEL-Install-RPMs.rst b/source/Get-Started/Installation/RHEL-Install-RPMs.rst
similarity index 100%
rename from source/Installation/RHEL-Install-RPMs.rst
rename to source/Get-Started/Installation/RHEL-Install-RPMs.rst
diff --git a/source/Installation/RMW-Implementations.rst b/source/Get-Started/Installation/RMW-Implementations.rst
similarity index 100%
rename from source/Installation/RMW-Implementations.rst
rename to source/Get-Started/Installation/RMW-Implementations.rst
diff --git a/source/Installation/RMW-Implementations/DDS-Implementations.rst b/source/Get-Started/Installation/RMW-Implementations/DDS-Implementations.rst
similarity index 100%
rename from source/Installation/RMW-Implementations/DDS-Implementations.rst
rename to source/Get-Started/Installation/RMW-Implementations/DDS-Implementations.rst
diff --git a/source/Installation/RMW-Implementations/DDS-Implementations/Working-with-Eclipse-CycloneDDS.rst b/source/Get-Started/Installation/RMW-Implementations/DDS-Implementations/Working-with-Eclipse-CycloneDDS.rst
similarity index 100%
rename from source/Installation/RMW-Implementations/DDS-Implementations/Working-with-Eclipse-CycloneDDS.rst
rename to source/Get-Started/Installation/RMW-Implementations/DDS-Implementations/Working-with-Eclipse-CycloneDDS.rst
diff --git a/source/Installation/RMW-Implementations/DDS-Implementations/Working-with-GurumNetworks-GurumDDS.rst b/source/Get-Started/Installation/RMW-Implementations/DDS-Implementations/Working-with-GurumNetworks-GurumDDS.rst
similarity index 100%
rename from source/Installation/RMW-Implementations/DDS-Implementations/Working-with-GurumNetworks-GurumDDS.rst
rename to source/Get-Started/Installation/RMW-Implementations/DDS-Implementations/Working-with-GurumNetworks-GurumDDS.rst
diff --git a/source/Installation/RMW-Implementations/DDS-Implementations/Working-with-RTI-Connext-DDS.rst b/source/Get-Started/Installation/RMW-Implementations/DDS-Implementations/Working-with-RTI-Connext-DDS.rst
similarity index 100%
rename from source/Installation/RMW-Implementations/DDS-Implementations/Working-with-RTI-Connext-DDS.rst
rename to source/Get-Started/Installation/RMW-Implementations/DDS-Implementations/Working-with-RTI-Connext-DDS.rst
diff --git a/source/Installation/RMW-Implementations/DDS-Implementations/Working-with-eProsima-Fast-DDS.rst b/source/Get-Started/Installation/RMW-Implementations/DDS-Implementations/Working-with-eProsima-Fast-DDS.rst
similarity index 100%
rename from source/Installation/RMW-Implementations/DDS-Implementations/Working-with-eProsima-Fast-DDS.rst
rename to source/Get-Started/Installation/RMW-Implementations/DDS-Implementations/Working-with-eProsima-Fast-DDS.rst
diff --git a/source/Installation/RMW-Implementations/Non-DDS-Implementations.rst b/source/Get-Started/Installation/RMW-Implementations/Non-DDS-Implementations.rst
similarity index 100%
rename from source/Installation/RMW-Implementations/Non-DDS-Implementations.rst
rename to source/Get-Started/Installation/RMW-Implementations/Non-DDS-Implementations.rst
diff --git a/source/Installation/RMW-Implementations/Non-DDS-Implementations/Working-with-Zenoh.rst b/source/Get-Started/Installation/RMW-Implementations/Non-DDS-Implementations/Working-with-Zenoh.rst
similarity index 100%
rename from source/Installation/RMW-Implementations/Non-DDS-Implementations/Working-with-Zenoh.rst
rename to source/Get-Started/Installation/RMW-Implementations/Non-DDS-Implementations/Working-with-Zenoh.rst
diff --git a/source/Installation/ROS-2-Mirrors.rst b/source/Get-Started/Installation/ROS-2-Mirrors.rst
similarity index 100%
rename from source/Installation/ROS-2-Mirrors.rst
rename to source/Get-Started/Installation/ROS-2-Mirrors.rst
diff --git a/source/Installation/Ubuntu-Install-Debs.rst b/source/Get-Started/Installation/Ubuntu-Install-Debs.rst
similarity index 100%
rename from source/Installation/Ubuntu-Install-Debs.rst
rename to source/Get-Started/Installation/Ubuntu-Install-Debs.rst
diff --git a/source/Installation/Windows-Install-Binary.rst b/source/Get-Started/Installation/Windows-Install-Binary.rst
similarity index 100%
rename from source/Installation/Windows-Install-Binary.rst
rename to source/Get-Started/Installation/Windows-Install-Binary.rst
diff --git a/source/Installation/_Apt-Repositories.rst b/source/Get-Started/Installation/_Apt-Repositories.rst
similarity index 100%
rename from source/Installation/_Apt-Repositories.rst
rename to source/Get-Started/Installation/_Apt-Repositories.rst
diff --git a/source/Installation/_Apt-Upgrade-Admonition.rst b/source/Get-Started/Installation/_Apt-Upgrade-Admonition.rst
similarity index 100%
rename from source/Installation/_Apt-Upgrade-Admonition.rst
rename to source/Get-Started/Installation/_Apt-Upgrade-Admonition.rst
diff --git a/source/Installation/_Dnf-Update-Admonition.rst b/source/Get-Started/Installation/_Dnf-Update-Admonition.rst
similarity index 100%
rename from source/Installation/_Dnf-Update-Admonition.rst
rename to source/Get-Started/Installation/_Dnf-Update-Admonition.rst
diff --git a/source/Installation/_RHEL-Set-Locale.rst b/source/Get-Started/Installation/_RHEL-Set-Locale.rst
similarity index 100%
rename from source/Installation/_RHEL-Set-Locale.rst
rename to source/Get-Started/Installation/_RHEL-Set-Locale.rst
diff --git a/source/Installation/_Ubuntu-Set-Locale.rst b/source/Get-Started/Installation/_Ubuntu-Set-Locale.rst
similarity index 100%
rename from source/Installation/_Ubuntu-Set-Locale.rst
rename to source/Get-Started/Installation/_Ubuntu-Set-Locale.rst
diff --git a/source/Installation/_rosdep_Linux_Mint.rst b/source/Get-Started/Installation/_rosdep_Linux_Mint.rst
similarity index 100%
rename from source/Installation/_rosdep_Linux_Mint.rst
rename to source/Get-Started/Installation/_rosdep_Linux_Mint.rst
diff --git a/source/Installation/images/python_installation_enable_debug.png b/source/Get-Started/Installation/images/python_installation_enable_debug.png
similarity index 100%
rename from source/Installation/images/python_installation_enable_debug.png
rename to source/Get-Started/Installation/images/python_installation_enable_debug.png
diff --git a/source/Installation/images/python_installation_modify.png b/source/Get-Started/Installation/images/python_installation_modify.png
similarity index 100%
rename from source/Installation/images/python_installation_modify.png
rename to source/Get-Started/Installation/images/python_installation_modify.png
diff --git a/source/Installation/images/python_installation_next.png b/source/Get-Started/Installation/images/python_installation_next.png
similarity index 100%
rename from source/Installation/images/python_installation_next.png
rename to source/Get-Started/Installation/images/python_installation_next.png
diff --git a/source/Installation/images/vs_community_screenshot.png b/source/Get-Started/Installation/images/vs_community_screenshot.png
similarity index 100%
rename from source/Installation/images/vs_community_screenshot.png
rename to source/Get-Started/Installation/images/vs_community_screenshot.png
diff --git a/source/Installation/images/windows-vs-studio-install.png b/source/Get-Started/Installation/images/windows-vs-studio-install.png
similarity index 100%
rename from source/Installation/images/windows-vs-studio-install.png
rename to source/Get-Started/Installation/images/windows-vs-studio-install.png
diff --git a/source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/Introducing-Turtlesim.rst b/source/Get-Started/Introducing-Turtlesim/Introducing-Turtlesim.rst
similarity index 100%
rename from source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/Introducing-Turtlesim.rst
rename to source/Get-Started/Introducing-Turtlesim/Introducing-Turtlesim.rst
diff --git a/source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/new_pen.png b/source/Get-Started/Introducing-Turtlesim/images/new_pen.png
similarity index 100%
rename from source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/new_pen.png
rename to source/Get-Started/Introducing-Turtlesim/images/new_pen.png
diff --git a/source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/remap.png b/source/Get-Started/Introducing-Turtlesim/images/remap.png
similarity index 100%
rename from source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/remap.png
rename to source/Get-Started/Introducing-Turtlesim/images/remap.png
diff --git a/source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/rqt.png b/source/Get-Started/Introducing-Turtlesim/images/rqt.png
similarity index 100%
rename from source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/rqt.png
rename to source/Get-Started/Introducing-Turtlesim/images/rqt.png
diff --git a/source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/set_pen.png b/source/Get-Started/Introducing-Turtlesim/images/set_pen.png
similarity index 100%
rename from source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/set_pen.png
rename to source/Get-Started/Introducing-Turtlesim/images/set_pen.png
diff --git a/source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/spawn.png b/source/Get-Started/Introducing-Turtlesim/images/spawn.png
similarity index 100%
rename from source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/spawn.png
rename to source/Get-Started/Introducing-Turtlesim/images/spawn.png
diff --git a/source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/turtlesim.png b/source/Get-Started/Introducing-Turtlesim/images/turtlesim.png
similarity index 100%
rename from source/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/images/turtlesim.png
rename to source/Get-Started/Introducing-Turtlesim/images/turtlesim.png
diff --git a/source/Releases.rst b/source/Get-Started/Releases.rst
similarity index 96%
rename from source/Releases.rst
rename to source/Get-Started/Releases.rst
index 7a050c1476e..7007cc415fe 100644
--- a/source/Releases.rst
+++ b/source/Get-Started/Releases.rst
@@ -23,14 +23,14 @@ Rows in the table marked in blue are the currently supported distributions.
.. toctree::
:hidden:
- Releases/Release-Kilted-Kaiju
- Releases/Release-Jazzy-Jalisco
- Releases/Release-Humble-Hawksbill
- Releases/Release-Rolling-Ridley
- Releases/Development
- Releases/End-of-Life
- Releases/Release-Process
-
+ Get-Started/Releases/Release-Process
+ Get-Started/Releases/Release-Kilted-Kaiju
+ Get-Started/Releases/Release-Jazzy-Jalisco
+ Get-Started/Releases/Release-Humble-Hawksbill
+ Get-Started/Releases/Release-Rolling-Ridley
+ Get-Started/Releases/Development
+ Get-Started/Releases/End-of-Life
+
.. raw:: html
-
-
- rosdoc2.yaml
-
-
-
-However, for most packages, the default settings in ``rosdoc2`` will suffice, and no custom config is necessary.
-More information about ``rosdoc2.yaml`` can be found in the `rosdoc2 readme `__.
-
-conf.py, rosdoc2_settings
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The final output of the package docs is (almost) always built by Sphinx.
-Each Sphinx project is configured by a ``conf.py`` file in the ``doc`` directory.
-If no configuration is present, a default Sphinx project is created and used when building the documentation.
-If however a ``conf.py`` Sphinx config is found in the ``doc`` subdirectory of the package, this is used instead.
-A custom Sphinx project is required if you want to include a standalone reStructuredText documentation page.
-A standalone documentation page can be used to list multiple tutorials and guides; if that's something you want for your package you'll need to create a custom Sphinx project.
-
-``rosdoc2`` provides additional settings to ``conf.py`` and overrides some.
-Information about changes done to the Sphinx settings are logged to the console with a ``[rosdoc2]`` prefix.
-
-Doxyfile
-^^^^^^^^
-
-Doxygen is a tool for automatically generating C++ API docs from code comments.
-While Doxygen can also generate HTML output directly, in the usual workflow for ROS packages, Doxygen produces machine readable output in XML format which is then consumed by Sphinx and integrated with the rest of the documentation.
-Doxygen-only docs are possible by only enabling the Doxygen builder in ``rosdoc2.yaml``, but this is uncommon.
-
-Customizing Sphinx Documentation
---------------------------------
-
-Creating a Sphinx Project
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-In order to add standalone documentation pages in addition to the automatically generated API docs, a custom Sphinx project is necessary.
-This should be created in a subdirectory called ``doc`` in the package directory.
-A new Sphinx project can be created by running ``sphinx-quickstart`` in the ``doc`` directory, answering ``no`` to "Separate source and build directories".
-The wizard requires entering the project name, author and version, but this can later be removed and will be provided to Sphinx by ``rosdoc2`` from your packages ``package.xml``.
-More information about creating a sphinx project can be found on the `Sphinx quickstart page `__,
-
-Customizing ``index.rst``
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The ``sphinx-quickstart`` wizard creates an ``index.rst`` file, which is the custom landing page for your package, similar to a Github ``README`` file.
-
-Adding Python API-Docs
-^^^^^^^^^^^^^^^^^^^^^^
-
-By default ``rosdoc2`` uses the `sphinx-apidoc tool `__ and the `autodoc Sphinx extension `__ to automatically generate documentation for python code.
-In order for autodoc to find the Python modules in your package, it must be added to the python search path in ``conf.py``:
-
-.. code-block:: python
-
- sys.path.insert(0, os.path.abspath('.'))
-
-This is because ``rosdoc2`` wraps the custom ``conf.py`` with more configuration from a script which will be placed in the package.
-In this case the ``.`` path in ``os.path.abspath`` refers to the package's directory root, not the package's ``doc`` directory due to the interaction between rosdoc2 and ``conf.py``.
-
-By default, package API docs are already reachable through the "Module Index" link that is present on the landing page.
-For the API docs to also appear in the table of contents, simply add a link to the ``modules`` page to your ``index.rst``:
-
-.. code-block:: rst
-
- .. toctree::
- :maxdepth: 2
- :caption: Contents:
-
- Python Modules
-
-Adding C++ API-Docs
-^^^^^^^^^^^^^^^^^^^
-
-If you would like to add your automatically generated API docs back to your custom landing page, add the line ``generated/index`` to your documentation page where you would like the API docs to appear:
-
-.. code-block:: rst
-
- .. toctree::
- :maxdepth: 2
-
- C++ API Docs
-
-This adds the elements "Class Hierarchy", "File Hierarchy" and "Reference" to the table of contents in the sidebar.
-To make those appear under one "C++ API Docs" heading for a less cluttered sidebar, a separate file such as ``cpp_api_docs.rst`` can be added, which links to the generated docs:
-
-.. code-block:: rst
- :caption: cpp_api_docs.rst
-
- C++ API Docs
- ============
-
- These are the autogenerated docs for the internal implementation.
-
- .. toctree::
- :maxdepth: 3
- :caption: Contents:
-
- generated/index
-
-Which then also needs to be added in ``index.rst`` to appear in the sidebar:
-
-.. code-block:: rst
- :caption: index.rst
-
- .. toctree::
- :maxdepth: 2
- :caption: Contents:
-
- cpp_api_docs
-
-
-Including an existing README.md
--------------------------------
-
-If your git repository already has an existing ``README.md``, it is possible to reuse this as the landing page for the documentation, without duplicating the contents.
-To correctly include a Markdown file in Sphinx while preserving relative links and images, some additional effort is required.
-
-First, create a proxy-file ``readme_include.md`` next to ``index.rst``.
-This is a markdown file which just includes the original README.md, but preserves the relative image paths, which would otherwise break in the next step:
-
-.. code-block:: markdown
- :caption: readme_include.md
-
- ```{include} ../README.md
- :relative-images:
- ```
-
-
-Then, include the contents of this file from ``index.rst`` using ``myst`` to include markdown from rst:
-
-.. code-block:: rst
- :caption: index.rst
-
- .. include:: readme_include.md
- :parser: myst_parser.sphinx_
-
-
-This also requires adding ``myst_parser`` to the extensions in ``conf.py``:
-
-.. code-block:: python
- :caption: conf.py
-
- extensions = ["myst_parser"]
-
-
-CI, docs.ros.org
-----------------
-
-The ROS build farm uses ``rosdoc2`` to build the package documentation hosted at ``docs.ros.org/en//p//``.
-To enable this, the repository containing the documentation must be configured in `rosdistro/{DISTRO}/distribution.yaml `__.
-This would usually be the package source repository:
-
-.. code-block:: yaml
-
- :
- doc:
- type: git
- url: https://github.com//.git
- version: main
- release:
- [...]
-
-The buildfarm hosts the documentation for every distribution separately, and periodically rebuilds it from the latest commit on the specified branch.
-It is not required to tag a new release to update the hosted documentation.
-To view the status of your package's documentation build, search for ``doc__`` on ``__.
-One job is created for every distribution for which the package is released.
-On each job page, you can see when a build was last triggered, as well as the status and logs of each build.
-
-Further Reading
----------------
-
-* `rosdoc2 readme `_
-* `ROS 2 design document on package documentation `_
-* `The ROS 2 cookbook `_
+.. redirect-from::
+
+ How-To-Guides/Documenting-a-ROS-2-Package
+
+Documenting a ROS 2 package
+###########################
+
+.. contents:: Table of Contents
+ :depth: 2
+ :local:
+
+
+This guide introduces the standard way to create documentation for ROS 2 packages.
+For packages with binary releases this also results in the docs being hosted at ``docs.ros.org/en//p//``.
+For information on how to contribute to this documentation on docs.ros.org, see :doc:`Contributing to ROS 2 Documentation <../../The-ROS2-Project/Contributing/Contributing-To-ROS-2-Documentation>`.
+
+Prerequisites
+-------------
+
+- :doc:`Install ROS <../../Installation>`
+
+- `Install rosdoc2 `__
+
+Package Documentation Overview
+------------------------------
+
+The type of documentation discussed in this guide is referred to as "package docs" or "API docs".
+For ROS packages that have been released on ROS Index, their documentation will be built on the ROS buildfarm, included on docs.ros.org, and visible via the ``API Docs`` button on index.ros.org.
+
+The tool responsible for generating ROS 2 package docs is `rosdoc2 `__.
+
+``rosdoc2`` is a convenient wrapper around the commonly used `Sphinx `__ documentation framework.
+Sphinx allows freeform written documentation as well as API documentation for python code generated from comments in the code.
+The `breathe `__ + `exhale `__ packages allow integration with Doxygen, to include autogenerated C++ API documentation as well.
+
+``rosdoc2`` creates a default configuration for packages with no documentation or configuration at all, and applies options for a uniform theme and integration with other packages.
+
+Building Package Docs
+---------------------
+
+To generate the documentation for a package in HTML format with ``rosdoc2``, run:
+
+.. code-block:: console
+
+ $ rosdoc2 build --package-path
+
+The documentation is written to ``docs_output//index.html`` and can be viewed in a browser.
+
+Configuration
+-------------
+
+There are three configuration locations for ROS package docs: ``rosdoc2.yaml`` for general settings,
+``conf.py`` for sphinx settings and the ``Doxyfile`` for doxygen settings.
+For all of those, a default is assumed or generated if not present, so none of them is strictly required.
+However, it might be necessary to create and modify those once you want to use features such as custom textual documentation pages.
+
+rosdoc2.yaml
+^^^^^^^^^^^^
+
+This is the main entrypoint for rosdoc2.
+It specifies generic settings, and can be used to control the execution of specific builders (Doxygen and Sphinx) and decides which builders to run.
+
+``rosdoc2`` provides a multitude of configuration options, which can be adjusted in a config file ``rosdoc2.yaml``.
+To generate a default ``rosdoc2.yaml`` which you can then further customize, run:
+
+.. code-block:: console
+
+ $ rosdoc2 default_config --package-path
+
+And add ``rosdoc2.yaml`` to the export section in your ``package.xml``:
+
+.. code-block:: xml
+
+
+
+
+
+ rosdoc2.yaml
+
+
+
+However, for most packages, the default settings in ``rosdoc2`` will suffice, and no custom config is necessary.
+More information about ``rosdoc2.yaml`` can be found in the `rosdoc2 readme `__.
+
+conf.py, rosdoc2_settings
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The final output of the package docs is (almost) always built by Sphinx.
+Each Sphinx project is configured by a ``conf.py`` file in the ``doc`` directory.
+If no configuration is present, a default Sphinx project is created and used when building the documentation.
+If however a ``conf.py`` Sphinx config is found in the ``doc`` subdirectory of the package, this is used instead.
+A custom Sphinx project is required if you want to include a standalone reStructuredText documentation page.
+A standalone documentation page can be used to list multiple tutorials and guides; if that's something you want for your package you'll need to create a custom Sphinx project.
+
+``rosdoc2`` provides additional settings to ``conf.py`` and overrides some.
+Information about changes done to the Sphinx settings are logged to the console with a ``[rosdoc2]`` prefix.
+
+Doxyfile
+^^^^^^^^
+
+Doxygen is a tool for automatically generating C++ API docs from code comments.
+While Doxygen can also generate HTML output directly, in the usual workflow for ROS packages, Doxygen produces machine readable output in XML format which is then consumed by Sphinx and integrated with the rest of the documentation.
+Doxygen-only docs are possible by only enabling the Doxygen builder in ``rosdoc2.yaml``, but this is uncommon.
+
+Customizing Sphinx Documentation
+--------------------------------
+
+Creating a Sphinx Project
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In order to add standalone documentation pages in addition to the automatically generated API docs, a custom Sphinx project is necessary.
+This should be created in a subdirectory called ``doc`` in the package directory.
+A new Sphinx project can be created by running ``sphinx-quickstart`` in the ``doc`` directory, answering ``no`` to "Separate source and build directories".
+The wizard requires entering the project name, author and version, but this can later be removed and will be provided to Sphinx by ``rosdoc2`` from your packages ``package.xml``.
+More information about creating a sphinx project can be found on the `Sphinx quickstart page `__,
+
+Customizing ``index.rst``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``sphinx-quickstart`` wizard creates an ``index.rst`` file, which is the custom landing page for your package, similar to a Github ``README`` file.
+
+Adding Python API-Docs
+^^^^^^^^^^^^^^^^^^^^^^
+
+By default ``rosdoc2`` uses the `sphinx-apidoc tool `__ and the `autodoc Sphinx extension `__ to automatically generate documentation for python code.
+In order for autodoc to find the Python modules in your package, it must be added to the python search path in ``conf.py``:
+
+.. code-block:: python
+
+ sys.path.insert(0, os.path.abspath('.'))
+
+This is because ``rosdoc2`` wraps the custom ``conf.py`` with more configuration from a script which will be placed in the package.
+In this case the ``.`` path in ``os.path.abspath`` refers to the package's directory root, not the package's ``doc`` directory due to the interaction between rosdoc2 and ``conf.py``.
+
+By default, package API docs are already reachable through the "Module Index" link that is present on the landing page.
+For the API docs to also appear in the table of contents, simply add a link to the ``modules`` page to your ``index.rst``:
+
+.. code-block:: rst
+
+ .. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+
+ Python Modules
+
+Adding C++ API-Docs
+^^^^^^^^^^^^^^^^^^^
+
+If you would like to add your automatically generated API docs back to your custom landing page, add the line ``generated/index`` to your documentation page where you would like the API docs to appear:
+
+.. code-block:: rst
+
+ .. toctree::
+ :maxdepth: 2
+
+ C++ API Docs
+
+This adds the elements "Class Hierarchy", "File Hierarchy" and "Reference" to the table of contents in the sidebar.
+To make those appear under one "C++ API Docs" heading for a less cluttered sidebar, a separate file such as ``cpp_api_docs.rst`` can be added, which links to the generated docs:
+
+.. code-block:: rst
+ :caption: cpp_api_docs.rst
+
+ C++ API Docs
+ ============
+
+ These are the autogenerated docs for the internal implementation.
+
+ .. toctree::
+ :maxdepth: 3
+ :caption: Contents:
+
+ generated/index
+
+Which then also needs to be added in ``index.rst`` to appear in the sidebar:
+
+.. code-block:: rst
+ :caption: index.rst
+
+ .. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+
+ cpp_api_docs
+
+
+Including an existing README.md
+-------------------------------
+
+If your git repository already has an existing ``README.md``, it is possible to reuse this as the landing page for the documentation, without duplicating the contents.
+To correctly include a Markdown file in Sphinx while preserving relative links and images, some additional effort is required.
+
+First, create a proxy-file ``readme_include.md`` next to ``index.rst``.
+This is a markdown file which just includes the original README.md, but preserves the relative image paths, which would otherwise break in the next step:
+
+.. code-block:: markdown
+ :caption: readme_include.md
+
+ ```{include} ../README.md
+ :relative-images:
+ ```
+
+
+Then, include the contents of this file from ``index.rst`` using ``myst`` to include markdown from rst:
+
+.. code-block:: rst
+ :caption: index.rst
+
+ .. include:: readme_include.md
+ :parser: myst_parser.sphinx_
+
+
+This also requires adding ``myst_parser`` to the extensions in ``conf.py``:
+
+.. code-block:: python
+ :caption: conf.py
+
+ extensions = ["myst_parser"]
+
+
+CI, docs.ros.org
+----------------
+
+The ROS build farm uses ``rosdoc2`` to build the package documentation hosted at ``docs.ros.org/en//p//``.
+To enable this, the repository containing the documentation must be configured in `rosdistro/{DISTRO}/distribution.yaml `__.
+This would usually be the package source repository:
+
+.. code-block:: yaml
+
+ :
+ doc:
+ type: git
+ url: https://github.com//.git
+ version: main
+ release:
+ [...]
+
+The buildfarm hosts the documentation for every distribution separately, and periodically rebuilds it from the latest commit on the specified branch.
+It is not required to tag a new release to update the hosted documentation.
+To view the status of your package's documentation build, search for ``doc__`` on ``__.
+One job is created for every distribution for which the package is released.
+On each job page, you can see when a build was last triggered, as well as the status and logs of each build.
+
+Further Reading
+---------------
+
+* `rosdoc2 readme `_
+* `ROS 2 design document on package documentation `_
+* `The ROS 2 cookbook `_
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Eclipse-Oxygen-with-ROS-2-and-rviz2.rst b/source/Developer-Tools/Build/Eclipse-Oxygen-with-ROS-2-and-rviz2.rst
index ff54262c528..a8d99c940bd 100644
--- a/source/Developer-Tools/Build/Eclipse-Oxygen-with-ROS-2-and-rviz2.rst
+++ b/source/Developer-Tools/Build/Eclipse-Oxygen-with-ROS-2-and-rviz2.rst
@@ -1,230 +1,231 @@
-.. redirect-from::
-
- Eclipse-Oxygen-with-ROS-2-and-rviz2
- Tutorials/Eclipse-Oxygen-with-ROS-2-and-rviz2
-
-Using Eclipse Oxygen with ``rviz2`` [community-contributed]
-===========================================================
-
-.. contents:: Table of Contents
- :depth: 1
- :local:
-
-Setup
------
-
-This tutorial assumes Eclipse Oxygen, git, and `Egit `_ are already installed.
-
-Throughout the tutorial we name the eclipse workspace the same name as the ros2 package, but this is not required.
-
-HINT: We use nested projects and one Eclipse Workspace for each ROS-2 package.
-
-.. image:: images/eclipse-oxygen-01.png
-
-
-Create a C++ Project.
-
-.. image:: images/eclipse-oxygen-02.png
-
-
-
-.. image:: images/eclipse-oxygen-03.png
-
-
-Choose the ROS 2 package name as the Project Name.
-Choose a Makefile Project and Other Toolchain.
-
-.. image:: images/eclipse-oxygen-04.png
-
-
-Click on Finish
-
-.. image:: images/eclipse-oxygen-05.png
-
-
-Our project should be shown in the "Project Explorer".
-
-.. image:: images/eclipse-oxygen-06.png
-
-
-Inside our Project create a folder called "src".
-
-.. image:: images/eclipse-oxygen-07.png
-
-
-Import a git repository.
-
-.. image:: images/eclipse-oxygen-08.png
-
-
-Put in the repository URL.
-
-.. image:: images/eclipse-oxygen-09.png
-
-
-IMPORTANT: Use the source folder of the project we created before as the destination folder.
-
-HINT: If you ran into problems choosing the destination folder path, the Eclipse Dialog needs a name in the name field.
-
-.. image:: images/eclipse-oxygen-10.png
-
-
-Import using the new project wizard.
-
-.. image:: images/eclipse-oxygen-11.png
-
-
-Create a General->Project.
-
-.. image:: images/eclipse-oxygen-12.png
-
-
-Use the git repository name as the project name.
-IMPORTANT: Use the folder we cloned the git repository in as the "Location".
-
-.. image:: images/eclipse-oxygen-13.png
-
-
-The git project and the new project should be visible in the Project Explorer view.
-The same files are listed multiple times, but only one project is linked with Egit.
-
-.. image:: images/eclipse-oxygen-14.png
-
-
-Repeat this procedure again.
-Import git repository pluginlib.
-
-.. image:: images/eclipse-oxygen-15.png
-
-
-IMPORTANT: Use a folder inside the source folder as "Destination->Directory".
-
-.. image:: images/eclipse-oxygen-16.png
-
-
-IMPORTANT: Use the folder we cloned the git repository in as the location for the new project.
-
-.. image:: images/eclipse-oxygen-17.png
-
-
-Run the same procedure with the tinyxml2_vendor git repository.
-
-.. image:: images/eclipse-oxygen-18.png
-
-
-IMPORTANT: Again use a folder inside the source folder.
-
-.. image:: images/eclipse-oxygen-19.png
-
-
-IMPORTANT: Use the location of the folder we cloned as the new project folder.
-
-.. image:: images/eclipse-oxygen-20.png
-
-
-Now all four Projects should be visible in the Project Explorer view.
-
-.. image:: images/eclipse-oxygen-21.png
-
-
-Clicking in the top right cornder for the Project Explorer view allows us to change the Project Presentation to Hierarchical view.
-Now it looks like a ROS-2 project as it is on the hard drive.
-But this view loses the linkage to Egit, so use the Flat Project Presentation.
-The Egit linkage is good if you want to see e.g. which author wrote which code-line, etc.
-
-.. image:: images/eclipse-oxygen-22.png
-
-
-Go to "C/C++ build"-section and put "ament" into "Build command".
-
-.. image:: images/eclipse-oxygen-23.png
-
-
-Go to "Behavior" tab and unselect "clean" and put "build" into Build textbox.
-
-.. image:: images/eclipse-oxygen-24.png
-
-
-Before "Build project" will work, we need to close Eclipse.
-Open a shell and source the ROS-2 setup.bash file, then cd into the directory of the eclipse project (here: /home/ubu/rviz2_ws/rviz2_ws) and start Eclipse from inside this directory.
-
-.. image:: images/eclipse-oxygen-25.png
-
-
-Now code completion, egit annotations, eclipse C/C++ Tools, etc. should all work.
-
-.. image:: images/eclipse-oxygen-26.png
-
-
-Eclipse-indexer
----------------
-
-Opening the main.cpp of rviz2 may show a lot of "unresolved inclusion" warnings.
-To fix this, go to Project->Properties->C++ General->Path and Symbols.
-Click on the "References" tab and select "ros2_ws".
-
-
-.. image:: images/eclipse-oxygen-27.png
-
-
-Go to C/C++-General->Path-and-Symbols, click on the "Source locations" tab and click on "Link folder".
-Choose the location of qt5 includes.
-
-
-.. image:: images/eclipse-oxygen-28.png
-
-
-The next image should be shown.
-It is a good idea to add excludes to the source locations, so that some directories (like "Build" and "Install") don't get indexed.
-
-
-.. image:: images/eclipse-oxygen-29.png
-
-
-Go to C++General->Preprocessor includes, select "CDT GCC Built in compiler settings [Shared]" and enter in the "command to get compiler specs" text box the following:
-
-.. code-block:: bash
-
- -std=c++14
-
-
-.. image:: images/eclipse-oxygen-30.png
-
-
-Go to "C/C++-General->Indexer" and select the following in the image.
-E.g "index unused headers as c files" to resolve e.g. QApplication, because the QApplication headers content is only "#include "qapplication.h".
-
-
-.. image:: images/eclipse-oxygen-31.png
-
-
-After running the indexer (which happens later, so you will see this also later), you can see what it added
-
-
-.. image:: images/eclipse-oxygen-32.png
-
-
-After that right-click on the rviz2 project and select "Indexer->Rebuild", which will start rebuilding the index (there is an icon in the lower right showing progress).
-Once the index is finished rebuilding, it should be able to resolve all includes.
-
-
-.. image:: images/eclipse-oxygen-33.png
-
-
-Debugging with eclipse
-----------------------
-
-Go to "C/C++-Build" and add to the build command:
-
-.. code-block:: bash
-
- -DCMAKE_BUILD_TYPE=Debug
-
-
-.. image:: images/eclipse-oxygen-34.png
-
-
-Then in eclipse go to "Run->Debug Configurations" and add the following and click on "Debug".
-
-
-.. image:: images/eclipse-oxygen-35.png
+.. redirect-from::
+
+ Eclipse-Oxygen-with-ROS-2-and-rviz2
+ Tutorials/Eclipse-Oxygen-with-ROS-2-and-rviz2
+ Tutorials/Miscellaneous/Eclipse-Oxygen-with-ROS-2-and-rviz2
+
+Using Eclipse Oxygen with ``rviz2`` [community-contributed]
+===========================================================
+
+.. contents:: Table of Contents
+ :depth: 1
+ :local:
+
+Setup
+-----
+
+This tutorial assumes Eclipse Oxygen, git, and `Egit `_ are already installed.
+
+Throughout the tutorial we name the eclipse workspace the same name as the ros2 package, but this is not required.
+
+HINT: We use nested projects and one Eclipse Workspace for each ROS-2 package.
+
+.. image:: images/eclipse-oxygen-01.png
+
+
+Create a C++ Project.
+
+.. image:: images/eclipse-oxygen-02.png
+
+
+
+.. image:: images/eclipse-oxygen-03.png
+
+
+Choose the ROS 2 package name as the Project Name.
+Choose a Makefile Project and Other Toolchain.
+
+.. image:: images/eclipse-oxygen-04.png
+
+
+Click on Finish
+
+.. image:: images/eclipse-oxygen-05.png
+
+
+Our project should be shown in the "Project Explorer".
+
+.. image:: images/eclipse-oxygen-06.png
+
+
+Inside our Project create a folder called "src".
+
+.. image:: images/eclipse-oxygen-07.png
+
+
+Import a git repository.
+
+.. image:: images/eclipse-oxygen-08.png
+
+
+Put in the repository URL.
+
+.. image:: images/eclipse-oxygen-09.png
+
+
+IMPORTANT: Use the source folder of the project we created before as the destination folder.
+
+HINT: If you ran into problems choosing the destination folder path, the Eclipse Dialog needs a name in the name field.
+
+.. image:: images/eclipse-oxygen-10.png
+
+
+Import using the new project wizard.
+
+.. image:: images/eclipse-oxygen-11.png
+
+
+Create a General->Project.
+
+.. image:: images/eclipse-oxygen-12.png
+
+
+Use the git repository name as the project name.
+IMPORTANT: Use the folder we cloned the git repository in as the "Location".
+
+.. image:: images/eclipse-oxygen-13.png
+
+
+The git project and the new project should be visible in the Project Explorer view.
+The same files are listed multiple times, but only one project is linked with Egit.
+
+.. image:: images/eclipse-oxygen-14.png
+
+
+Repeat this procedure again.
+Import git repository pluginlib.
+
+.. image:: images/eclipse-oxygen-15.png
+
+
+IMPORTANT: Use a folder inside the source folder as "Destination->Directory".
+
+.. image:: images/eclipse-oxygen-16.png
+
+
+IMPORTANT: Use the folder we cloned the git repository in as the location for the new project.
+
+.. image:: images/eclipse-oxygen-17.png
+
+
+Run the same procedure with the tinyxml2_vendor git repository.
+
+.. image:: images/eclipse-oxygen-18.png
+
+
+IMPORTANT: Again use a folder inside the source folder.
+
+.. image:: images/eclipse-oxygen-19.png
+
+
+IMPORTANT: Use the location of the folder we cloned as the new project folder.
+
+.. image:: images/eclipse-oxygen-20.png
+
+
+Now all four Projects should be visible in the Project Explorer view.
+
+.. image:: images/eclipse-oxygen-21.png
+
+
+Clicking in the top right cornder for the Project Explorer view allows us to change the Project Presentation to Hierarchical view.
+Now it looks like a ROS-2 project as it is on the hard drive.
+But this view loses the linkage to Egit, so use the Flat Project Presentation.
+The Egit linkage is good if you want to see e.g. which author wrote which code-line, etc.
+
+.. image:: images/eclipse-oxygen-22.png
+
+
+Go to "C/C++ build"-section and put "ament" into "Build command".
+
+.. image:: images/eclipse-oxygen-23.png
+
+
+Go to "Behavior" tab and unselect "clean" and put "build" into Build textbox.
+
+.. image:: images/eclipse-oxygen-24.png
+
+
+Before "Build project" will work, we need to close Eclipse.
+Open a shell and source the ROS-2 setup.bash file, then cd into the directory of the eclipse project (here: /home/ubu/rviz2_ws/rviz2_ws) and start Eclipse from inside this directory.
+
+.. image:: images/eclipse-oxygen-25.png
+
+
+Now code completion, egit annotations, eclipse C/C++ Tools, etc. should all work.
+
+.. image:: images/eclipse-oxygen-26.png
+
+
+Eclipse-indexer
+---------------
+
+Opening the main.cpp of rviz2 may show a lot of "unresolved inclusion" warnings.
+To fix this, go to Project->Properties->C++ General->Path and Symbols.
+Click on the "References" tab and select "ros2_ws".
+
+
+.. image:: images/eclipse-oxygen-27.png
+
+
+Go to C/C++-General->Path-and-Symbols, click on the "Source locations" tab and click on "Link folder".
+Choose the location of qt5 includes.
+
+
+.. image:: images/eclipse-oxygen-28.png
+
+
+The next image should be shown.
+It is a good idea to add excludes to the source locations, so that some directories (like "Build" and "Install") don't get indexed.
+
+
+.. image:: images/eclipse-oxygen-29.png
+
+
+Go to C++General->Preprocessor includes, select "CDT GCC Built in compiler settings [Shared]" and enter in the "command to get compiler specs" text box the following:
+
+.. code-block:: bash
+
+ -std=c++14
+
+
+.. image:: images/eclipse-oxygen-30.png
+
+
+Go to "C/C++-General->Indexer" and select the following in the image.
+E.g "index unused headers as c files" to resolve e.g. QApplication, because the QApplication headers content is only "#include "qapplication.h".
+
+
+.. image:: images/eclipse-oxygen-31.png
+
+
+After running the indexer (which happens later, so you will see this also later), you can see what it added
+
+
+.. image:: images/eclipse-oxygen-32.png
+
+
+After that right-click on the rviz2 project and select "Indexer->Rebuild", which will start rebuilding the index (there is an icon in the lower right showing progress).
+Once the index is finished rebuilding, it should be able to resolve all includes.
+
+
+.. image:: images/eclipse-oxygen-33.png
+
+
+Debugging with eclipse
+----------------------
+
+Go to "C/C++-Build" and add to the build command:
+
+.. code-block:: bash
+
+ -DCMAKE_BUILD_TYPE=Debug
+
+
+.. image:: images/eclipse-oxygen-34.png
+
+
+Then in eclipse go to "Run->Debug Configurations" and add the following and click on "Debug".
+
+
+.. image:: images/eclipse-oxygen-35.png
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Package-Docs.rst b/source/Developer-Tools/Build/Package-Docs.rst
index 9c717d2252a..c872c20cc2f 100644
--- a/source/Developer-Tools/Build/Package-Docs.rst
+++ b/source/Developer-Tools/Build/Package-Docs.rst
@@ -1,39 +1,40 @@
-.. redirect-from::
-
-Package Docs
-============
-
-ROS package documentation, that is to say documentation for specific packages you install via apt or some other tool, can be found in multiple places.
-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.
-
-Larger Packages
----------------
-
-Larger packages like MoveIt, Nav2, and microROS, are given their own domain or subdomain on ros.org.
-Here is a short list.
-
-* `MoveIt `__
-* `Navigation2 `__
-* `Control `__
-* `microROS (embedded systems) `__
-
-API Documentation
------------------
-
-You can find the API level documentation for the ROS client libraries in the {DISTRO_TITLE} distribution using the links below:
-
-* `rclcpp - C++ client library `_
-* `rclcpp_lifecycle - C++ lifecycle library `_
-* `rclcpp_components - C++ components library `_
-* `rclcpp_action - C++ actions library `_
-
-Adding Your Package to docs.ros.org
------------------------------------
-
-All released ROS 2 packages are automatically added to docs.ros.org and `ROS Index `_.
-If you would like to enable or configure your own package please see: :doc:`./How-To-Guides/Documenting-a-ROS-2-Package`.
+.. redirect-from::
+
+ Package-Docs
+Package Docs
+============
+
+ROS package documentation, that is to say documentation for specific packages you install via apt or some other tool, can be found in multiple places.
+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.
+
+Larger Packages
+---------------
+
+Larger packages like MoveIt, Nav2, and microROS, are given their own domain or subdomain on ros.org.
+Here is a short list.
+
+* `MoveIt `__
+* `Navigation2 `__
+* `Control `__
+* `microROS (embedded systems) `__
+
+API Documentation
+-----------------
+
+You can find the API level documentation for the ROS client libraries in the {DISTRO_TITLE} distribution using the links below:
+
+* `rclcpp - C++ client library `_
+* `rclcpp_lifecycle - C++ lifecycle library `_
+* `rclcpp_components - C++ components library `_
+* `rclcpp_action - C++ actions library `_
+
+Adding Your Package to docs.ros.org
+-----------------------------------
+
+All released ROS 2 packages are automatically added to docs.ros.org and `ROS Index `_.
+If you would like to enable or configure your own package please see: :doc:`Documenting-a-ROS-2-Package`.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/First-Time-Release.rst b/source/Developer-Tools/Build/Releasing/First-Time-Release.rst
index 5aebb14aa76..d320d8dbdeb 100644
--- a/source/Developer-Tools/Build/Releasing/First-Time-Release.rst
+++ b/source/Developer-Tools/Build/Releasing/First-Time-Release.rst
@@ -1,127 +1,131 @@
-First Time Release
-==================
-
-This guide explains how to release ROS 2 packages that you have not released before.
-Due to numerous options available when releasing ROS packages, this guide intends to cover the most common scenario and does not cover every corner-case.
-
-.. contents:: Table of Contents
- :depth: 1
- :local:
-
-Be part of a release team
--------------------------
-
-You must be part of a :ref:`release team `.
-If you are not part of a release team yet, follow either:
-
-* :ref:`Join a release team `
-* :ref:`Start a new release team `
-
-Create a new release repository
--------------------------------
-
-You need a :ref:`release repository ` to release a package.
-Follow :ref:`Create a new release repository `.
-
-Install dependencies
---------------------
-
-.. include:: _Install-Dependencies.rst
-
-Set Up a Personal Access Token
-------------------------------
-
-.. include:: _Personal-Access-Token.rst
-
-Ensure repositories are up-to-date
-----------------------------------
-
-.. include:: _Ensure-Repositories-Are-Up-To-Date.rst
-
-Generate Changelog
-------------------
-
-Generate a ``CHANGELOG.rst`` file per package in your repo using the following command:
-
-.. code-block:: console
-
- $ catkin_generate_changelog --all
-
-.. include:: _Clean-Up-Changelog.rst
-
-Bump the package version
-------------------------
-
-.. include:: _Bump-Package-Version.rst
-
-Bloom Release
--------------
-
-Run the following command, replacing ``my_repo`` with the name of your repository:
-
-.. code-block:: console
-
- $ bloom-release --new-track --rosdistro {DISTRO} --track {DISTRO} my_repo
-
-.. tip::
-
- * ``--new-track`` tells bloom to create a new :ref:`track ` and configure it.
- * ``--rosdistro {DISTRO}`` indicates that this release is for the ``{DISTRO}`` distro
- * ``--track {DISTRO}`` indicates that you want the track name to be ``{DISTRO}``
-
-
-You will be prompted to enter information to configure a new track.
-In a common scenario such as:
-
-* Your packages are in a repository called ``my_repo``
-* You are releasing a branch called ``main``
-* The repository is hosted on GitHub at ``https://github.com/my_organization/my_repo.git``
-* Your release repository is at ``https://github.com/ros2-gbp/my_repo-release.git``
-
-You should respond to the prompts as following:
-
-.. list-table::
- :header-rows: 1
- :widths: 1 2
-
- * - Configuration
- - Value
- * - :ref:`Release Repository url `
- - ``https://github.com/ros2-gbp/my_repo-release.git``
- * - :ref:`Repository Name `
- - ``my_repo``
- * - :ref:`Upstream Repository URI `
- - ``https://github.com/my_organization/my_repo.git``
- * - :ref:`Upstream VCS Type `
- -
- * - :ref:`Version `
- -
- * - :ref:`Release Tag `
- -
- * - :ref:`Upstream Devel Branch `
- - ``main``
- * - :ref:`ROS Distro `
- -
- * - :ref:`Patches Directory `
- -
- * - :ref:`Release Repository Push URL `
- -
-
-.. note::
-
- An empty cell in the table indicates that the default value should be used.
- Simply respond to the prompt by pressing Enter.
-
-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
-----------
-
-.. include:: _Next-Steps.rst
+.. redirect-from::
+
+ How-To-Guides/Releasing/First-Time-Release
+
+First Time Release
+==================
+
+This guide explains how to release ROS 2 packages that you have not released before.
+Due to numerous options available when releasing ROS packages, this guide intends to cover the most common scenario and does not cover every corner-case.
+
+.. contents:: Table of Contents
+ :depth: 1
+ :local:
+
+Be part of a release team
+-------------------------
+
+You must be part of a :ref:`release team `.
+If you are not part of a release team yet, follow either:
+
+* :ref:`Join a release team `
+* :ref:`Start a new release team `
+
+Create a new release repository
+-------------------------------
+
+You need a :ref:`release repository ` to release a package.
+Follow :ref:`Create a new release repository `.
+
+Install dependencies
+--------------------
+
+.. include:: _Install-Dependencies.rst
+
+Set Up a Personal Access Token
+------------------------------
+
+.. include:: _Personal-Access-Token.rst
+
+Ensure repositories are up-to-date
+----------------------------------
+
+.. include:: _Ensure-Repositories-Are-Up-To-Date.rst
+
+Generate Changelog
+------------------
+
+Generate a ``CHANGELOG.rst`` file per package in your repo using the following command:
+
+.. code-block:: console
+
+ $ catkin_generate_changelog --all
+
+.. include:: _Clean-Up-Changelog.rst
+
+Bump the package version
+------------------------
+
+.. include:: _Bump-Package-Version.rst
+
+Bloom Release
+-------------
+
+Run the following command, replacing ``my_repo`` with the name of your repository:
+
+.. code-block:: console
+
+ $ bloom-release --new-track --rosdistro {DISTRO} --track {DISTRO} my_repo
+
+.. tip::
+
+ * ``--new-track`` tells bloom to create a new :ref:`track ` and configure it.
+ * ``--rosdistro {DISTRO}`` indicates that this release is for the ``{DISTRO}`` distro
+ * ``--track {DISTRO}`` indicates that you want the track name to be ``{DISTRO}``
+
+
+You will be prompted to enter information to configure a new track.
+In a common scenario such as:
+
+* Your packages are in a repository called ``my_repo``
+* You are releasing a branch called ``main``
+* The repository is hosted on GitHub at ``https://github.com/my_organization/my_repo.git``
+* Your release repository is at ``https://github.com/ros2-gbp/my_repo-release.git``
+
+You should respond to the prompts as following:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 1 2
+
+ * - Configuration
+ - Value
+ * - :ref:`Release Repository url `
+ - ``https://github.com/ros2-gbp/my_repo-release.git``
+ * - :ref:`Repository Name `
+ - ``my_repo``
+ * - :ref:`Upstream Repository URI `
+ - ``https://github.com/my_organization/my_repo.git``
+ * - :ref:`Upstream VCS Type `
+ -
+ * - :ref:`Version `
+ -
+ * - :ref:`Release Tag `
+ -
+ * - :ref:`Upstream Devel Branch `
+ - ``main``
+ * - :ref:`ROS Distro `
+ -
+ * - :ref:`Patches Directory `
+ -
+ * - :ref:`Release Repository Push URL `
+ -
+
+.. note::
+
+ An empty cell in the table indicates that the default value should be used.
+ Simply respond to the prompt by pressing Enter.
+
+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
+----------
+
+.. include:: _Next-Steps.rst
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/Index-Your-Packages.rst b/source/Developer-Tools/Build/Releasing/Index-Your-Packages.rst
index 296ea168307..952b4ac2e5d 100644
--- a/source/Developer-Tools/Build/Releasing/Index-Your-Packages.rst
+++ b/source/Developer-Tools/Build/Releasing/Index-Your-Packages.rst
@@ -1,98 +1,102 @@
-Index Your Packages
-===================
-
-Are you releasing a new ROS package into a ROS distribution?
-Make the process faster by indexing your packages first.
-
-Put your ROS packages into a public repository
-----------------------------------------------
-
-If you haven't done so already, put the source code of your ROS packages into a public git repository.
-All packages released into ROS must be open source.
-You can host code anywhere, but GitHub is recommended because it gives you the option to enable pull request jobs.
-Here are some choices:
-
-* `GitHub `__ **Recommended**
-* `GitLab `__
-* `Bitbucket `__
-
-Give your packages an OSI Approved license
-------------------------------------------
-Choose an `OSI approved license `__ and give it to your ROS packages.
-If you're having trouble deciding, consider using the license used by most of the core ROS 2 packages: `Apache-2.0 license `__.
-
-For each ``package.xml`` in your repository, put the SPDX short identifier of the license in the ```` tag in your ``package.xml``.
-
-If all of your ROS packages have the same license, or if there's only one ROS package in your repository, create a file called ``LICENSE`` at the root of your repository and put the text of the license you chose in it.
-If the ROS packages in your repository have different licenses, create a ``LICENSE`` file adjacent to every ``package.xml`` file.
-
-Give your packages REP 144 compliant names
-------------------------------------------
-Packages released into a ROS distribution must have names that comply with `REP 144 `__.
-Read the full REP to understand the rules.
-If one of your ROS package names doesn't comply, then change the name before continuing.
-
-Decide what ROS distribution you want to release into
------------------------------------------------------
-Decide what ROS distribution you want to release your packages into.
-At a minimum, you should release your packages into `ROS Rolling `__ so that your ROS packages are automatically included in the next ROS release.
-You may also want to release into any active ROS distributions, but this is up to you.
-
-Create a GitHub account
------------------------
-`Create a GitHub account `__ if you don't already have one.
-You don't have to host the source code of your ROS packages on GitHub, but you will need an account to index and release packages.
-
-Fork and clone ros/rosdistro
-----------------------------
-`Fork `__ the `ros/rosdistro `__ repository.
-You only need to do this step once on your account.
-The fork will be used every time you do a release.
-
-Make changes to your fork
--------------------------
-Remember the ROS distributions you decided to release into?
-Each ROS distribution has a folder in the `ros/rosdistro `__ repository.
-For example, the name of the ROS Rolling folder is ``rolling``.
-For each ROS distribution you want to release into:
-
-1. fill out the following template
-2. put the filled-out template into the ``distribution.yaml`` file in the corresponding ROS distribution's folder
-
-.. code-block:: yaml
-
- YOUR-REPO-NAME:
- source:
- type: git
- url: https://YOUR-GIT-REPO-URL.git
- version: YOUR-BRANCH-NAME
- status: YOUR-STATUS
-
-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-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
-------------------------------------
-`Open a pull request `__ to `ros/rosdistro `__ with the branch that you made your changes to.
-Wait a few days for it to be reviewed.
-
-What happens next
------------------
-You've now done everything required to index your ROS packages.
-One of the reviewers will look at your pull request and decide if it `satisfies the review guidelines `__.
-The reviewer may either approve your changes as is, or give you actionable feedback.
-Once the pull request meets the review guidelines it will be merged, and your packages will appear on the `ROS Index `__.
-
-You've completed an important step toward releasing your package.
-Proceed to the next guide: :doc:`First Time Release `.
+.. redirect-from::
+
+ How-To-Guides/Releasing/Index-Your-Packages
+
+Index Your Packages
+===================
+
+Are you releasing a new ROS package into a ROS distribution?
+Make the process faster by indexing your packages first.
+
+Put your ROS packages into a public repository
+----------------------------------------------
+
+If you haven't done so already, put the source code of your ROS packages into a public git repository.
+All packages released into ROS must be open source.
+You can host code anywhere, but GitHub is recommended because it gives you the option to enable pull request jobs.
+Here are some choices:
+
+* `GitHub `__ **Recommended**
+* `GitLab `__
+* `Bitbucket `__
+
+Give your packages an OSI Approved license
+------------------------------------------
+Choose an `OSI approved license `__ and give it to your ROS packages.
+If you're having trouble deciding, consider using the license used by most of the core ROS 2 packages: `Apache-2.0 license `__.
+
+For each ``package.xml`` in your repository, put the SPDX short identifier of the license in the ```` tag in your ``package.xml``.
+
+If all of your ROS packages have the same license, or if there's only one ROS package in your repository, create a file called ``LICENSE`` at the root of your repository and put the text of the license you chose in it.
+If the ROS packages in your repository have different licenses, create a ``LICENSE`` file adjacent to every ``package.xml`` file.
+
+Give your packages REP 144 compliant names
+------------------------------------------
+Packages released into a ROS distribution must have names that comply with `REP 144 `__.
+Read the full REP to understand the rules.
+If one of your ROS package names doesn't comply, then change the name before continuing.
+
+Decide what ROS distribution you want to release into
+-----------------------------------------------------
+Decide what ROS distribution you want to release your packages into.
+At a minimum, you should release your packages into `ROS Rolling `__ so that your ROS packages are automatically included in the next ROS release.
+You may also want to release into any active ROS distributions, but this is up to you.
+
+Create a GitHub account
+-----------------------
+`Create a GitHub account `__ if you don't already have one.
+You don't have to host the source code of your ROS packages on GitHub, but you will need an account to index and release packages.
+
+Fork and clone ros/rosdistro
+----------------------------
+`Fork `__ the `ros/rosdistro `__ repository.
+You only need to do this step once on your account.
+The fork will be used every time you do a release.
+
+Make changes to your fork
+-------------------------
+Remember the ROS distributions you decided to release into?
+Each ROS distribution has a folder in the `ros/rosdistro `__ repository.
+For example, the name of the ROS Rolling folder is ``rolling``.
+For each ROS distribution you want to release into:
+
+1. fill out the following template
+2. put the filled-out template into the ``distribution.yaml`` file in the corresponding ROS distribution's folder
+
+.. code-block:: yaml
+
+ YOUR-REPO-NAME:
+ source:
+ type: git
+ url: https://YOUR-GIT-REPO-URL.git
+ version: YOUR-BRANCH-NAME
+ status: YOUR-STATUS
+
+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-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
+------------------------------------
+`Open a pull request `__ to `ros/rosdistro `__ with the branch that you made your changes to.
+Wait a few days for it to be reviewed.
+
+What happens next
+-----------------
+You've now done everything required to index your ROS packages.
+One of the reviewers will look at your pull request and decide if it `satisfies the review guidelines `__.
+The reviewer may either approve your changes as is, or give you actionable feedback.
+Once the pull request meets the review guidelines it will be merged, and your packages will appear on the `ROS Index `__.
+
+You've completed an important step toward releasing your package.
+Proceed to the next guide: :doc:`First Time Release `.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/Release-Team-Repository.rst b/source/Developer-Tools/Build/Releasing/Release-Team-Repository.rst
index 362f34a5e8e..a8b92c2e2c0 100644
--- a/source/Developer-Tools/Build/Releasing/Release-Team-Repository.rst
+++ b/source/Developer-Tools/Build/Releasing/Release-Team-Repository.rst
@@ -1,82 +1,86 @@
-Release Team / Repository
-=========================
-
-.. contents:: Table of Contents
- :depth: 2
- :local:
-
-This page explains the recommended method of hosting your release repositories on `ros2-gbp `_.
-
-What is ROS 2 GBP?
-------------------
-
-`ros2-gbp `_ is a GitHub organization that hosts the release repositories for ROS packages.
-It also maintains a list of release teams, the list of members per release team and the list of release repositories maintained by the release teams in https://github.com/ros2-gbp/ros2-gbp-github-org.
-Interactions with ros2-gbp-github-org are done through raising GitHub issues.
-It is recommended that you request to join a release team and set up a release repository early as it can take some time for the ros2-gbp maintainers to respond to your requests.
-
-.. _what-is-a-release-team:
-
-What is a release team?
------------------------
-
-A release team is a `GitHub team `_ that consists of a group of people who are responsible for the release process of one or more repositories.
-Release teams are often made up of an organization, a working group, or even an individual, and are named after the team or group that they represent.
-The list of release teams and their associated release repositories are maintained at `ros2-gbp-github-org `_.
-
-**You must be a part of the release team that you are planning on releasing the project for.**
-If you intend to release the repository under an existing team, follow :ref:`Join a release team `.
-If you intend to start a new team, follow :ref:`Start a new release team `.
-
-.. _join-a-release-team:
-
-Join a release team
-^^^^^^^^^^^^^^^^^^^
-
-Fill the `Update Release Team Membership issue `_ issue template
-if a release team already exists for your project but you are not part of it.
-
-.. _start-a-new-release-team:
-
-Start a new release team
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-If no release team exists for your project yet, fill out the `New Release Team issue `_ issue template to request one be created.
-
-.. _what-is-a-release-repository:
-
-What is a release repository?
------------------------------
-
-A release repository is a repository that
-
-* stores files generated from the release process, for the ROS buildfarm to use
-* caches configurations from the release process to simplify subsequent releases of the repository in the future
-
-Having a release repository separate from your source code repository is a requirement for making a release in ROS 2.
-
-.. _create-a-new-release-repository:
-
-Create a new release repository
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If your repository is new to the ROS community, you should first open a pull request on `ros/rosdistro `_ adding a ``source`` entry for your repository (e.g. https://github.com/ros/rosdistro/pull/39513).
-The review process for the rosdistro database will ensure your repository and packages conform to the `REP 144 package naming conventions `_ and other requirements before release.
-Once your package name has been approved and merged, fill in the `Add New Release Repositories issue `_ issue template
-if you don't have a release repo for your project yet.
-
-What if my existing release repo isn't on ros2-gbp?
----------------------------------------------------
-
-Packages released before ros2-gbp existed may have their release repositories hosted elsewhere.
-It is now strongly recommended for release repositories to live in this dedicated GitHub organization.
-If you are porting a ROS 1 package to ROS 2 and planning on releasing your packages into ROS 2 for the first time, follow standard procedure to request for a new release repository for your ROS 2 releases.
-If you have previously released your packages for ROS 2, when raising the `Add New Release Repositories issue `_, **specify your current release repository url**, and follow standard procedure for the rest.
-
-.. note::
-
- **When releasing your packages into the Rolling distribution, you must use a release repository hosted in the ros2-gbp organization**.
- Release repositories hosted elsewhere are still supported for stable distributions if you are not planning to release the repository into Rolling.
- Since stable distributions created from Rolling will start with release repositories in the ros2-gbp organization it is recommend that you use the ros2-gbp release repositories for all ROS 2 distributions to avoid fragmenting the release information.
-
- A ros2-gbp release repository may become a hard requirement for all distros in the future and maintaining a single release repository for all ROS 2 distributions simplifies the maintenance of releases for both the Rolling distribution maintainers and package maintainers.
+.. redirect-from::
+
+ How-To-Guides/Releasing/Release-Team-Repository
+
+Release Team / Repository
+=========================
+
+.. contents:: Table of Contents
+ :depth: 2
+ :local:
+
+This page explains the recommended method of hosting your release repositories on `ros2-gbp `_.
+
+What is ROS 2 GBP?
+------------------
+
+`ros2-gbp `_ is a GitHub organization that hosts the release repositories for ROS packages.
+It also maintains a list of release teams, the list of members per release team and the list of release repositories maintained by the release teams in https://github.com/ros2-gbp/ros2-gbp-github-org.
+Interactions with ros2-gbp-github-org are done through raising GitHub issues.
+It is recommended that you request to join a release team and set up a release repository early as it can take some time for the ros2-gbp maintainers to respond to your requests.
+
+.. _what-is-a-release-team:
+
+What is a release team?
+-----------------------
+
+A release team is a `GitHub team `_ that consists of a group of people who are responsible for the release process of one or more repositories.
+Release teams are often made up of an organization, a working group, or even an individual, and are named after the team or group that they represent.
+The list of release teams and their associated release repositories are maintained at `ros2-gbp-github-org `_.
+
+**You must be a part of the release team that you are planning on releasing the project for.**
+If you intend to release the repository under an existing team, follow :ref:`Join a release team `.
+If you intend to start a new team, follow :ref:`Start a new release team `.
+
+.. _join-a-release-team:
+
+Join a release team
+^^^^^^^^^^^^^^^^^^^
+
+Fill the `Update Release Team Membership issue `_ issue template
+if a release team already exists for your project but you are not part of it.
+
+.. _start-a-new-release-team:
+
+Start a new release team
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+If no release team exists for your project yet, fill out the `New Release Team issue `_ issue template to request one be created.
+
+.. _what-is-a-release-repository:
+
+What is a release repository?
+-----------------------------
+
+A release repository is a repository that
+
+* stores files generated from the release process, for the ROS buildfarm to use
+* caches configurations from the release process to simplify subsequent releases of the repository in the future
+
+Having a release repository separate from your source code repository is a requirement for making a release in ROS 2.
+
+.. _create-a-new-release-repository:
+
+Create a new release repository
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If your repository is new to the ROS community, you should first open a pull request on `ros/rosdistro `_ adding a ``source`` entry for your repository (e.g. https://github.com/ros/rosdistro/pull/39513).
+The review process for the rosdistro database will ensure your repository and packages conform to the `REP 144 package naming conventions `_ and other requirements before release.
+Once your package name has been approved and merged, fill in the `Add New Release Repositories issue `_ issue template
+if you don't have a release repo for your project yet.
+
+What if my existing release repo isn't on ros2-gbp?
+---------------------------------------------------
+
+Packages released before ros2-gbp existed may have their release repositories hosted elsewhere.
+It is now strongly recommended for release repositories to live in this dedicated GitHub organization.
+If you are porting a ROS 1 package to ROS 2 and planning on releasing your packages into ROS 2 for the first time, follow standard procedure to request for a new release repository for your ROS 2 releases.
+If you have previously released your packages for ROS 2, when raising the `Add New Release Repositories issue `_, **specify your current release repository url**, and follow standard procedure for the rest.
+
+.. note::
+
+ **When releasing your packages into the Rolling distribution, you must use a release repository hosted in the ros2-gbp organization**.
+ Release repositories hosted elsewhere are still supported for stable distributions if you are not planning to release the repository into Rolling.
+ Since stable distributions created from Rolling will start with release repositories in the ros2-gbp organization it is recommend that you use the ros2-gbp release repositories for all ROS 2 distributions to avoid fragmenting the release information.
+
+ A ros2-gbp release repository may become a hard requirement for all distros in the future and maintaining a single release repository for all ROS 2 distributions simplifies the maintenance of releases for both the Rolling distribution maintainers and package maintainers.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/Release-Track.rst b/source/Developer-Tools/Build/Releasing/Release-Track.rst
index c7a1c71cb4a..a033e48dc08 100644
--- a/source/Developer-Tools/Build/Releasing/Release-Track.rst
+++ b/source/Developer-Tools/Build/Releasing/Release-Track.rst
@@ -1,246 +1,250 @@
-Release Track
-=============
-
-.. contents:: Table of Contents
- :depth: 2
- :local:
-
-.. _what-is-a-track:
-
-What is a Track?
-----------------
-
-Bloom requires the user to enter configuration information when releasing packages for the first time.
-It is beneficial to store such configurations in the release repository so we don't have to manually enter configurations that won't change for subsequent releases.
-
-Since some of the configurations will differ when releasing the package for different ROS distributions, bloom uses **release tracks to store the configurations for releasing** per distribution.
-By convention you should create tracks with the same name as the ROS distro you are releasing for.
-
-All release track configurations are stored in ``tracks.yaml`` on the master branch of your release repository.
-
-Track Configurations
---------------------
-
-Track configurations are explained in more detail along with the prompts from bloom.
-
-.. _release-repository-url:
-
-Release Repository url
-^^^^^^^^^^^^^^^^^^^^^^
-
-This is the url of your release repository, and should be of form ``https://github.com/ros2-gbp/my_repo-release.git`` if your release repository is hosted on ros2-gbp.
-
-.. code-block:: bash
-
- No reasonable default release repository url could be determined from previous releases.
- Release repository url [press enter to abort]:
-
-Paste your release repository URL and press Enter.
-
-Bloom may additionally ask you about initializing the new repository, as following:
-
-.. code-block:: bash
-
- Freshly initialized git repository detected.
- An initial empty commit is going to be made.
- Continue [Y/n]?
-
-Simply press Enter to accept the default of yes.
-
-.. _repository-name:
-
-Repository Name
-^^^^^^^^^^^^^^^
-
-The repository name is trivial, but it is recommended to set this to the name of your project.
-
-.. code-block:: bash
-
- Repository Name:
- upstream
- Default value, leave this as upstream if you are unsure
-
- Name of the repository (used in the archive name)
- ['upstream']:
-
-Type the name of your project (e.g. ``my_project``) and press Enter.
-
-.. _upstream-repository-uri:
-
-Upstream Repository URI
-^^^^^^^^^^^^^^^^^^^^^^^
-
-The **upstream repository** is the repository where your source code is.
-This is most likely an https link to your project hosted on a git hosting service such as GitHub or GitLab.
-
-.. code-block:: bash
-
- Upstream Repository URI:
-
- Any valid URI. This variable can be templated, for example an svn url
- can be templated as such: "https://svn.foo.com/foo/tags/foo-:{version}"
- where the :{version} token will be replaced with the version for this release.
- [None]:
-
-Make sure you **use the https address** (e.g. ``https://github.com/my_organization/my_repo.git``) and not the ssh address.
-
-.. _upstream-vcs-type:
-
-Upstream VCS Type
-^^^^^^^^^^^^^^^^^
-
-This is the `Upstream Repository URI`_'s version control system (VCS) type.
-You must specify the type of vcs your repository is using, from ``svn``, ``git``, ``hg`` or ``tar``.
-
-.. code-block:: bash
-
- Upstream VCS Type:
- svn
- Upstream URI is a svn repository
- git
- Upstream URI is a git repository
- hg
- Upstream URI is a hg repository
- tar
- Upstream URI is a tarball
- ['git']:
-
-Most repositories will be using git, but some legacy repositories might be using hg or svn.
-
-.. _version:
-
-Version
-^^^^^^^
-
-This is the version of the package you are releasing.
-(e.g. ``1.0.3``)
-
-.. code-block:: bash
-
- Version:
- :{ask}
- This means that the user will be prompted for the version each release.
- This also means that the upstream devel will be ignored.
- :{auto}
- This means the version will be guessed from the devel branch.
- This means that the devel branch must be set, the devel branch must exist,
- and there must be a valid package.xml in the upstream devel branch.
-
- This will be the version used.
- It must be updated for each new upstream version.
- [':{auto}']:
-
-Setting this to ``:{auto}`` (the default, and recommended setup) will automatically determine the version from the devel branch's package.xml.
-
-Setting this to ``:{ask}`` will bring up a prompt asking for the version every time you run a release with bloom.
-
-.. _release-tag:
-
-Release Tag
-^^^^^^^^^^^
-
-The Release Tag refers to which tag or branch you want to import the code from.
-
-.. code-block:: bash
-
- Release Tag:
- :{version}
- This means that the release tag will match the :{version} tag.
- This can be further templated, for example: "foo-:{version}" or "v:{version}"
-
- This can describe any vcs reference. For git that means {tag, branch, hash},
- for hg that means {tag, branch, hash}, for svn that means a revision number.
- For tar this value doubles as the sub directory (if the repository is
- in foo/ of the tar ball, putting foo here will cause the contents of
- foo/ to be imported to upstream instead of foo itself).
- :{ask}
- This means the user will be prompted for the release tag on each release.
- :{none}
- For svn and tar only you can set the release tag to :{none}, so that
- it is ignored. For svn this means no revision number is used.
- [':{version}']:
-
-Setting this to ``:{version}`` (the default, and recommended setup) will make the release tag match the version tag.
-
-A less common setup is to set this to a branch name to always pull in that branch at the time of release from the upstream project.
-
-Alternatively, if you want to be prompted to enter a different tag every time you do a release, enter ``:{ask}``.
-``:{ask}`` is useful if the upstream project has frequent tagged releases and you want to refer to the new tag every time you're releasing.
-
-.. _upstream-devel-branch:
-
-Upstream Devel Branch
-^^^^^^^^^^^^^^^^^^^^^
-
-The upstream devel branch is the name of the branch in your :ref:`upstream repository `.
-If you use separate branches for each ROS distribution, this field would be different for each release track.
-It is used to determine the version of the package you are releasing when :ref:`Version` is set to ``:{auto}``.
-
-.. code-block:: bash
-
- Upstream Devel Branch:
-
- Branch in upstream repository on which to search for the version.
- This is used only when version is set to ':{auto}'.
- [None]:
-
-To release from a branch called ``{DISTRO}``, enter ``{DISTRO}``.
-Leaving this as ``None`` would result in the version being determined from the default branch of your repository (this is not recommended).
-
-.. _ros-distro:
-
-ROS Distro
-^^^^^^^^^^
-
-This is the distribution you're planning on releasing the package into.
-
-.. code-block:: bash
-
- ROS Distro:
-
- This can be any valid ROS distro, e.g. indigo, kinetic, lunar, melodic
- ['indigo']:
-
-If you plan on releasing into ROS {DISTRO}, enter ``{DISTRO}``.
-
-.. _patches-directory:
-
-Patches Directory
-^^^^^^^^^^^^^^^^^
-
-This is the directory where any additional patches to the releases are.
-
-.. code-block:: bash
-
- Patches Directory:
-
- This can be any valid relative path in the bloom branch. The contents
- of this folder will be overlaid onto the upstream branch after each
- import-upstream. Additionally, any package.xml files found in the
- overlay will have the :{version} string replaced with the current
- version being released.
- :{none}
- Use this if you want to disable overlaying of files.
- [None]:
-
-Adding additional patches to a release is a rarely used feature.
-For almost all packages, this should be left as the default ``None``.
-
-.. _release-repository-push-url:
-
-Release Repository Push URL
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: bash
-
- Release Repository Push URL:
- :{none}
- This indicates that the default release url should be used.
-
- (optional) Used when pushing to remote release repositories. This is only
- needed when the release uri which is in the rosdistro file is not writable.
- This is useful, for example, when a releaser would like to use a ssh url
- to push rather than a https:// url.
- [None]:
-
-Can be left as the default in most cases.
+.. redirect-from::
+
+ How-To-Guides/Releasing/Release-Track
+
+Release Track
+=============
+
+.. contents:: Table of Contents
+ :depth: 2
+ :local:
+
+.. _what-is-a-track:
+
+What is a Track?
+----------------
+
+Bloom requires the user to enter configuration information when releasing packages for the first time.
+It is beneficial to store such configurations in the release repository so we don't have to manually enter configurations that won't change for subsequent releases.
+
+Since some of the configurations will differ when releasing the package for different ROS distributions, bloom uses **release tracks to store the configurations for releasing** per distribution.
+By convention you should create tracks with the same name as the ROS distro you are releasing for.
+
+All release track configurations are stored in ``tracks.yaml`` on the master branch of your release repository.
+
+Track Configurations
+--------------------
+
+Track configurations are explained in more detail along with the prompts from bloom.
+
+.. _release-repository-url:
+
+Release Repository url
+^^^^^^^^^^^^^^^^^^^^^^
+
+This is the url of your release repository, and should be of form ``https://github.com/ros2-gbp/my_repo-release.git`` if your release repository is hosted on ros2-gbp.
+
+.. code-block:: bash
+
+ No reasonable default release repository url could be determined from previous releases.
+ Release repository url [press enter to abort]:
+
+Paste your release repository URL and press Enter.
+
+Bloom may additionally ask you about initializing the new repository, as following:
+
+.. code-block:: bash
+
+ Freshly initialized git repository detected.
+ An initial empty commit is going to be made.
+ Continue [Y/n]?
+
+Simply press Enter to accept the default of yes.
+
+.. _repository-name:
+
+Repository Name
+^^^^^^^^^^^^^^^
+
+The repository name is trivial, but it is recommended to set this to the name of your project.
+
+.. code-block:: bash
+
+ Repository Name:
+ upstream
+ Default value, leave this as upstream if you are unsure
+
+ Name of the repository (used in the archive name)
+ ['upstream']:
+
+Type the name of your project (e.g. ``my_project``) and press Enter.
+
+.. _upstream-repository-uri:
+
+Upstream Repository URI
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The **upstream repository** is the repository where your source code is.
+This is most likely an https link to your project hosted on a git hosting service such as GitHub or GitLab.
+
+.. code-block:: bash
+
+ Upstream Repository URI:
+
+ Any valid URI. This variable can be templated, for example an svn url
+ can be templated as such: "https://svn.foo.com/foo/tags/foo-:{version}"
+ where the :{version} token will be replaced with the version for this release.
+ [None]:
+
+Make sure you **use the https address** (e.g. ``https://github.com/my_organization/my_repo.git``) and not the ssh address.
+
+.. _upstream-vcs-type:
+
+Upstream VCS Type
+^^^^^^^^^^^^^^^^^
+
+This is the `Upstream Repository URI`_'s version control system (VCS) type.
+You must specify the type of vcs your repository is using, from ``svn``, ``git``, ``hg`` or ``tar``.
+
+.. code-block:: bash
+
+ Upstream VCS Type:
+ svn
+ Upstream URI is a svn repository
+ git
+ Upstream URI is a git repository
+ hg
+ Upstream URI is a hg repository
+ tar
+ Upstream URI is a tarball
+ ['git']:
+
+Most repositories will be using git, but some legacy repositories might be using hg or svn.
+
+.. _version:
+
+Version
+^^^^^^^
+
+This is the version of the package you are releasing.
+(e.g. ``1.0.3``)
+
+.. code-block:: bash
+
+ Version:
+ :{ask}
+ This means that the user will be prompted for the version each release.
+ This also means that the upstream devel will be ignored.
+ :{auto}
+ This means the version will be guessed from the devel branch.
+ This means that the devel branch must be set, the devel branch must exist,
+ and there must be a valid package.xml in the upstream devel branch.
+
+ This will be the version used.
+ It must be updated for each new upstream version.
+ [':{auto}']:
+
+Setting this to ``:{auto}`` (the default, and recommended setup) will automatically determine the version from the devel branch's package.xml.
+
+Setting this to ``:{ask}`` will bring up a prompt asking for the version every time you run a release with bloom.
+
+.. _release-tag:
+
+Release Tag
+^^^^^^^^^^^
+
+The Release Tag refers to which tag or branch you want to import the code from.
+
+.. code-block:: bash
+
+ Release Tag:
+ :{version}
+ This means that the release tag will match the :{version} tag.
+ This can be further templated, for example: "foo-:{version}" or "v:{version}"
+
+ This can describe any vcs reference. For git that means {tag, branch, hash},
+ for hg that means {tag, branch, hash}, for svn that means a revision number.
+ For tar this value doubles as the sub directory (if the repository is
+ in foo/ of the tar ball, putting foo here will cause the contents of
+ foo/ to be imported to upstream instead of foo itself).
+ :{ask}
+ This means the user will be prompted for the release tag on each release.
+ :{none}
+ For svn and tar only you can set the release tag to :{none}, so that
+ it is ignored. For svn this means no revision number is used.
+ [':{version}']:
+
+Setting this to ``:{version}`` (the default, and recommended setup) will make the release tag match the version tag.
+
+A less common setup is to set this to a branch name to always pull in that branch at the time of release from the upstream project.
+
+Alternatively, if you want to be prompted to enter a different tag every time you do a release, enter ``:{ask}``.
+``:{ask}`` is useful if the upstream project has frequent tagged releases and you want to refer to the new tag every time you're releasing.
+
+.. _upstream-devel-branch:
+
+Upstream Devel Branch
+^^^^^^^^^^^^^^^^^^^^^
+
+The upstream devel branch is the name of the branch in your :ref:`upstream repository `.
+If you use separate branches for each ROS distribution, this field would be different for each release track.
+It is used to determine the version of the package you are releasing when :ref:`Version` is set to ``:{auto}``.
+
+.. code-block:: bash
+
+ Upstream Devel Branch:
+
+ Branch in upstream repository on which to search for the version.
+ This is used only when version is set to ':{auto}'.
+ [None]:
+
+To release from a branch called ``{DISTRO}``, enter ``{DISTRO}``.
+Leaving this as ``None`` would result in the version being determined from the default branch of your repository (this is not recommended).
+
+.. _ros-distro:
+
+ROS Distro
+^^^^^^^^^^
+
+This is the distribution you're planning on releasing the package into.
+
+.. code-block:: bash
+
+ ROS Distro:
+
+ This can be any valid ROS distro, e.g. indigo, kinetic, lunar, melodic
+ ['indigo']:
+
+If you plan on releasing into ROS {DISTRO}, enter ``{DISTRO}``.
+
+.. _patches-directory:
+
+Patches Directory
+^^^^^^^^^^^^^^^^^
+
+This is the directory where any additional patches to the releases are.
+
+.. code-block:: bash
+
+ Patches Directory:
+
+ This can be any valid relative path in the bloom branch. The contents
+ of this folder will be overlaid onto the upstream branch after each
+ import-upstream. Additionally, any package.xml files found in the
+ overlay will have the :{version} string replaced with the current
+ version being released.
+ :{none}
+ Use this if you want to disable overlaying of files.
+ [None]:
+
+Adding additional patches to a release is a rarely used feature.
+For almost all packages, this should be left as the default ``None``.
+
+.. _release-repository-push-url:
+
+Release Repository Push URL
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: bash
+
+ Release Repository Push URL:
+ :{none}
+ This indicates that the default release url should be used.
+
+ (optional) Used when pushing to remote release repositories. This is only
+ needed when the release uri which is in the rosdistro file is not writable.
+ This is useful, for example, when a releaser would like to use a ssh url
+ to push rather than a https:// url.
+ [None]:
+
+Can be left as the default in most cases.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/Releasing-a-Package.rst b/source/Developer-Tools/Build/Releasing/Releasing-a-Package.rst
index b005b0a979e..94611980328 100644
--- a/source/Developer-Tools/Build/Releasing/Releasing-a-Package.rst
+++ b/source/Developer-Tools/Build/Releasing/Releasing-a-Package.rst
@@ -1,34 +1,35 @@
-.. redirect-from::
-
- Releasing-a-ROS-2-package-with-bloom
- Guides/Releasing-a-ROS-2-package-with-bloom
- Tutorials/Releasing-a-ROS-2-package-with-bloom
- How-To-Guides/Releasing-a-ROS-2-package-with-bloom
-
-Releasing a Package
-===================
-
-.. toctree::
- :hidden:
-
- Index-Your-Packages
- First-Time-Release
- Subsequent-Releases
- Release-Team-Repository
- Release-Track
-
-**Releasing a package makes your package available on the public ROS 2 buildfarm.**
-This will:
-
-* Make your package available to be installed via package managers (e.g. ``apt`` on Ubuntu) for all supported Linux platforms in a ROS distribution as described in `REP 2000 `_.
-* Allow your package to have API documentation automatically generated.
-* Make your package part of the `ROS Index `_.
-* (Optionally) Allow you to have automatic CI run for pull requests in your repository.
-
-**Follow one of the guides below to get your package released:**
-
-* :doc:`Index Your Packages ` - if this is the first release for the package
-* :doc:`First Time Release ` - if this is the first release for the package, but it is already indexed
-* :doc:`Subsequent Releases ` - if you are releasing a new version of a package that has already been released
-
-After successfully following the instructions, your package will be released into the ROS ecosystem on the next distro synchronization!
+.. redirect-from::
+
+ Releasing-a-ROS-2-package-with-bloom
+ Guides/Releasing-a-ROS-2-package-with-bloom
+ Tutorials/Releasing-a-ROS-2-package-with-bloom
+ How-To-Guides/Releasing-a-ROS-2-package-with-bloom
+ How-To-Guides/Releasing/Releasing-a-Package
+
+Releasing a Package
+===================
+
+.. toctree::
+ :hidden:
+
+ Index-Your-Packages
+ First-Time-Release
+ Subsequent-Releases
+ Release-Team-Repository
+ Release-Track
+
+**Releasing a package makes your package available on the public ROS 2 buildfarm.**
+This will:
+
+* Make your package available to be installed via package managers (e.g. ``apt`` on Ubuntu) for all supported Linux platforms in a ROS distribution as described in `REP 2000 `_.
+* Allow your package to have API documentation automatically generated.
+* Make your package part of the `ROS Index `_.
+* (Optionally) Allow you to have automatic CI run for pull requests in your repository.
+
+**Follow one of the guides below to get your package released:**
+
+* :doc:`Index Your Packages ` - if this is the first release for the package
+* :doc:`First Time Release ` - if this is the first release for the package, but it is already indexed
+* :doc:`Subsequent Releases ` - if you are releasing a new version of a package that has already been released
+
+After successfully following the instructions, your package will be released into the ROS ecosystem on the next distro synchronization!
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/Subsequent-Releases.rst b/source/Developer-Tools/Build/Releasing/Subsequent-Releases.rst
index 44cca46b85f..32d4c557e7f 100644
--- a/source/Developer-Tools/Build/Releasing/Subsequent-Releases.rst
+++ b/source/Developer-Tools/Build/Releasing/Subsequent-Releases.rst
@@ -1,67 +1,71 @@
-Subsequent Releases
-===================
-
-This guide explains how to release new versions of ROS packages that have already been released before.
-
-.. contents:: Table of Contents
- :depth: 1
- :local:
-
-Be part of the release team
----------------------------
-
-If you are not part of the release team that has write access to the release repository, follow :ref:`Join a release team `.
-
-Install dependencies
---------------------
-
-.. include:: _Install-Dependencies.rst
-
-Set up a Personal Access Token
-------------------------------
-
-.. include:: _Personal-Access-Token.rst
-
-Ensure repositories are up-to-date
-----------------------------------
-
-.. include:: _Ensure-Repositories-Are-Up-To-Date.rst
-
-Updating Changelog
-------------------
-
-For your users and for the developers, keep the changelog concise and up to date.
-
-.. code-block:: console
-
- $ catkin_generate_changelog
-
-.. include:: _Clean-Up-Changelog.rst
-
-Bump the package version
-------------------------
-
-.. include:: _Bump-Package-Version.rst
-
-Bloom Release
--------------
-
-Run the following command, replacing ``my_repo`` with the name of your repository with the packages:
-
-.. code-block:: console
-
- $ bloom-release --rosdistro {DISTRO} my_repo
-
-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
-----------
-
-.. include:: _Next-Steps.rst
+.. redirect-from::
+
+ How-To-Guides/Releasing/Subsequent-Releases
+
+Subsequent Releases
+===================
+
+This guide explains how to release new versions of ROS packages that have already been released before.
+
+.. contents:: Table of Contents
+ :depth: 1
+ :local:
+
+Be part of the release team
+---------------------------
+
+If you are not part of the release team that has write access to the release repository, follow :ref:`Join a release team `.
+
+Install dependencies
+--------------------
+
+.. include:: _Install-Dependencies.rst
+
+Set up a Personal Access Token
+------------------------------
+
+.. include:: _Personal-Access-Token.rst
+
+Ensure repositories are up-to-date
+----------------------------------
+
+.. include:: _Ensure-Repositories-Are-Up-To-Date.rst
+
+Updating Changelog
+------------------
+
+For your users and for the developers, keep the changelog concise and up to date.
+
+.. code-block:: console
+
+ $ catkin_generate_changelog
+
+.. include:: _Clean-Up-Changelog.rst
+
+Bump the package version
+------------------------
+
+.. include:: _Bump-Package-Version.rst
+
+Bloom Release
+-------------
+
+Run the following command, replacing ``my_repo`` with the name of your repository with the packages:
+
+.. code-block:: console
+
+ $ bloom-release --rosdistro {DISTRO} my_repo
+
+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
+----------
+
+.. include:: _Next-Steps.rst
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/_Bump-Package-Version.rst b/source/Developer-Tools/Build/Releasing/_Bump-Package-Version.rst
index 96e7c7ca10b..b5cea782391 100644
--- a/source/Developer-Tools/Build/Releasing/_Bump-Package-Version.rst
+++ b/source/Developer-Tools/Build/Releasing/_Bump-Package-Version.rst
@@ -1,27 +1,31 @@
-Every release of the package must have a unique version number higher than the previous release.
-
-Run:
-
-.. code-block:: console
-
- $ catkin_prepare_release
-
-which performs the following:
-
-#. increases the package version in ``package.xml``
-#. replaces the heading ``Forthcoming`` with ``version (date)`` (e.g. ``0.0.1 (2022-01-08)``) in ``CHANGELOG.rst``
-#. commits those changes
-#. creates a tag (e.g. ``0.0.1``)
-#. pushes the changes and the tag to your remote repository
-
-.. note::
-
- By default the patch version of the package is incremented, such as from ``0.0.0`` to ``0.0.1``.
- To increment the minor or major version instead, run ``catkin_prepare_release --bump minor`` or ``catkin_prepare_release --bump major``.
- For more details, see ``catkin_prepare_release --help``.
-
-.. note::
-
- If your repository has a strict merge rule like ``Require a pull request before merging``, you will need to create a pull request with the changes/tag generated by ``catkin_prepare_release`` and then merge that, since you cannot directly push to the branch.
- Depending on your repository's pull request merge settings (such as squash merge or rebase merge), merging the pull request may change the SHA of the version commit.
- In such cases, you will need to manually re-tag the version commit after merging to ensure the tag points to the correct commit.
+.. redirect-from::
+
+ How-To-Guides/Releasing/_Bump-Package-Version
+
+Every release of the package must have a unique version number higher than the previous release.
+
+Run:
+
+.. code-block:: console
+
+ $ catkin_prepare_release
+
+which performs the following:
+
+#. increases the package version in ``package.xml``
+#. replaces the heading ``Forthcoming`` with ``version (date)`` (e.g. ``0.0.1 (2022-01-08)``) in ``CHANGELOG.rst``
+#. commits those changes
+#. creates a tag (e.g. ``0.0.1``)
+#. pushes the changes and the tag to your remote repository
+
+.. note::
+
+ By default the patch version of the package is incremented, such as from ``0.0.0`` to ``0.0.1``.
+ To increment the minor or major version instead, run ``catkin_prepare_release --bump minor`` or ``catkin_prepare_release --bump major``.
+ For more details, see ``catkin_prepare_release --help``.
+
+.. note::
+
+ If your repository has a strict merge rule like ``Require a pull request before merging``, you will need to create a pull request with the changes/tag generated by ``catkin_prepare_release`` and then merge that, since you cannot directly push to the branch.
+ Depending on your repository's pull request merge settings (such as squash merge or rebase merge), merging the pull request may change the SHA of the version commit.
+ In such cases, you will need to manually re-tag the version commit after merging to ensure the tag points to the correct commit.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/_Clean-Up-Changelog.rst b/source/Developer-Tools/Build/Releasing/_Clean-Up-Changelog.rst
index 59adf33a35d..fe9605dbfa3 100644
--- a/source/Developer-Tools/Build/Releasing/_Clean-Up-Changelog.rst
+++ b/source/Developer-Tools/Build/Releasing/_Clean-Up-Changelog.rst
@@ -1,16 +1,20 @@
-Open all ``CHANGELOG.rst`` files in an editor.
-You will see that ``catkin_generate_changelog`` has auto-generated a forthcoming section with notes from commit messages:
-
-.. code-block:: rst
-
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Changelog for package your_package
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- Forthcoming
- -----------
- * you can modify this commit message
- * and this
-
-Clean up the list of commit messages to concisely convey the notable changes that have been made to the packages since the last release, and **commit all the CHANGELOG.rst files.**
-Do not modify the ``Forthcoming`` header.
+.. redirect-from::
+
+ How-To-Guides/Releasing/_Clean-Up-Changelog
+
+Open all ``CHANGELOG.rst`` files in an editor.
+You will see that ``catkin_generate_changelog`` has auto-generated a forthcoming section with notes from commit messages:
+
+.. code-block:: rst
+
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ Changelog for package your_package
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ Forthcoming
+ -----------
+ * you can modify this commit message
+ * and this
+
+Clean up the list of commit messages to concisely convey the notable changes that have been made to the packages since the last release, and **commit all the CHANGELOG.rst files.**
+Do not modify the ``Forthcoming`` header.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/_Ensure-Repositories-Are-Up-To-Date.rst b/source/Developer-Tools/Build/Releasing/_Ensure-Repositories-Are-Up-To-Date.rst
index 58ed6d1b20a..e9ef79ba392 100644
--- a/source/Developer-Tools/Build/Releasing/_Ensure-Repositories-Are-Up-To-Date.rst
+++ b/source/Developer-Tools/Build/Releasing/_Ensure-Repositories-Are-Up-To-Date.rst
@@ -1,5 +1,9 @@
-Make sure that:
-
-* Your repository is hosted on a remote such as GitHub.
-* You have a clone of the repository on your computer and are on the right branch.
-* Both the remote repository and your clone are up-to-date.
+.. redirect-from::
+
+ How-To-Guides/Releasing/_Ensure-Repositories-Are-Up-To-Date
+
+Make sure that:
+
+* Your repository is hosted on a remote such as GitHub.
+* You have a clone of the repository on your computer and are on the right branch.
+* Both the remote repository and your clone are up-to-date.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/_Install-Dependencies.rst b/source/Developer-Tools/Build/Releasing/_Install-Dependencies.rst
index 8b69dca153a..6362625427c 100644
--- a/source/Developer-Tools/Build/Releasing/_Install-Dependencies.rst
+++ b/source/Developer-Tools/Build/Releasing/_Install-Dependencies.rst
@@ -1,30 +1,34 @@
-Install tools that you will use in the upcoming steps according to your platform:
-
-.. tabs::
-
- .. group-tab:: deb (e.g. Ubuntu)
-
- .. code-block:: console
-
- $ sudo apt install python3-bloom python3-catkin-pkg
-
- .. group-tab:: RPM (e.g. RHEL)
-
- .. code-block:: console
-
- $ sudo dnf install python3-bloom python3-catkin_pkg
-
- .. group-tab:: Other
-
- .. code-block:: console
-
- $ pip3 install -U bloom catkin_pkg
-
-Make sure you have rosdep initialized:
-
-.. code-block:: console
-
- $ sudo rosdep init
- $ rosdep update
-
-Note that the ``rosdep init`` command may fail if it has already been initialized in the past; this can safely be ignored.
+.. redirect-from::
+
+ How-To-Guides/Releasing/_Install-Dependencies
+
+Install tools that you will use in the upcoming steps according to your platform:
+
+.. tabs::
+
+ .. group-tab:: deb (e.g. Ubuntu)
+
+ .. code-block:: console
+
+ $ sudo apt install python3-bloom python3-catkin-pkg
+
+ .. group-tab:: RPM (e.g. RHEL)
+
+ .. code-block:: console
+
+ $ sudo dnf install python3-bloom python3-catkin_pkg
+
+ .. group-tab:: Other
+
+ .. code-block:: console
+
+ $ pip3 install -U bloom catkin_pkg
+
+Make sure you have rosdep initialized:
+
+.. code-block:: console
+
+ $ sudo rosdep init
+ $ rosdep update
+
+Note that the ``rosdep init`` command may fail if it has already been initialized in the past; this can safely be ignored.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/_Next-Steps.rst b/source/Developer-Tools/Build/Releasing/_Next-Steps.rst
index 99310bb60c3..33c1071cef0 100644
--- a/source/Developer-Tools/Build/Releasing/_Next-Steps.rst
+++ b/source/Developer-Tools/Build/Releasing/_Next-Steps.rst
@@ -1,6 +1,10 @@
-Once your pull request has been submitted, usually within one or two days, one of the maintainers of rosdistro will review and merge your Pull Request.
-If your package build is successful, in 24-48 hours your packages will become available in the **ros-testing** repository, where you can :doc:`test your pre-release binaries <../../../Installation/Testing>`.
-
-Approximately every two to four weeks, the distribution's release manager manually synchronizes the contents of ros-testing into the main ROS repository.
-This is when your packages actually become available to the rest of the ROS community.
-To get updates on when the next synchronization (sync) is coming, subscribe to the `Packaging and Release Management Category on Open Robotics Discourse `_.
+.. redirect-from::
+
+ How-To-Guides/Releasing/_Next-Steps
+
+Once your pull request has been submitted, usually within one or two days, one of the maintainers of rosdistro will review and merge your Pull Request.
+If your package build is successful, in 24-48 hours your packages will become available in the **ros-testing** repository, where you can :doc:`test your pre-release binaries <../../../Installation/Testing>`.
+
+Approximately every two to four weeks, the distribution's release manager manually synchronizes the contents of ros-testing into the main ROS repository.
+This is when your packages actually become available to the rest of the ROS community.
+To get updates on when the next synchronization (sync) is coming, subscribe to the `Packaging and Release Management Category on Open Robotics Discourse `_.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Releasing/_Personal-Access-Token.rst b/source/Developer-Tools/Build/Releasing/_Personal-Access-Token.rst
index b60e80db8ff..d0c8b7fe244 100644
--- a/source/Developer-Tools/Build/Releasing/_Personal-Access-Token.rst
+++ b/source/Developer-Tools/Build/Releasing/_Personal-Access-Token.rst
@@ -1,45 +1,49 @@
-.. warning::
-
- If the file ``~/.config/bloom`` exists on your computer, it is likely that you have done this before so you should skip this section.
-
-During the release process, multiple HTTPS Git operations will be performed that require password authentication.
-To avoid being repeatedly asked for a password, a `Personal Access Token (PAT) `_ will be set up.
-If you have multi-factor authentication setup on your GitHub account, you **must** setup a Personal Access Token.
-
-Create a Personal Access Token by:
-
-#. Log in to GitHub and go to `Personal access tokens `_.
-#. Click the **Generate new token** button.
-#. In the dropdown, select **Generate new token (classic)**
-#. Set **Note** to something like ``Bloom token``.
-#. Set **Expiration** to **No expiration**.
-#. Tick the ``public_repo`` and ``workflow`` checkboxes.
-#. Click the **Generate token** button.
-
-After you have created the token, you will end up back at the *Personal access tokens* page.
-**Copy the alphanumeric token** that is highlighted in green.
-
-Save your GitHub username and PAT to a new file called ``~/.config/bloom``, with the format below:
-
-.. code-block:: text
-
- {
- "github_user": "",
- "oauth_token": ""
- }
-
-Configure in your ``~/.gitconfig`` that your GitHub account and PAT are used for all release repositories under `ros2-gbp `_:
-
-.. code-block:: ini
-
- [credential "https://github.com/ros2-gbp"]
- username = x-access-token
- helper = "!f() { test \"$1\" = get && echo \"password=\"; }; f"
-
-You can additionally use different GitHub accounts and PATs for individual release repositories:
-
-.. code-block:: ini
-
- [credential "https://github.com/ros2-gbp/my_package-release.git"]
- username = x-access-token
- helper = "!f() { test \"$1\" = get && echo \"password=\"; }; f"
+.. redirect-from::
+
+ How-To-Guides/Releasing/_Personal-Access-Token
+
+.. warning::
+
+ If the file ``~/.config/bloom`` exists on your computer, it is likely that you have done this before so you should skip this section.
+
+During the release process, multiple HTTPS Git operations will be performed that require password authentication.
+To avoid being repeatedly asked for a password, a `Personal Access Token (PAT) `_ will be set up.
+If you have multi-factor authentication setup on your GitHub account, you **must** setup a Personal Access Token.
+
+Create a Personal Access Token by:
+
+#. Log in to GitHub and go to `Personal access tokens `_.
+#. Click the **Generate new token** button.
+#. In the dropdown, select **Generate new token (classic)**
+#. Set **Note** to something like ``Bloom token``.
+#. Set **Expiration** to **No expiration**.
+#. Tick the ``public_repo`` and ``workflow`` checkboxes.
+#. Click the **Generate token** button.
+
+After you have created the token, you will end up back at the *Personal access tokens* page.
+**Copy the alphanumeric token** that is highlighted in green.
+
+Save your GitHub username and PAT to a new file called ``~/.config/bloom``, with the format below:
+
+.. code-block:: text
+
+ {
+ "github_user": "",
+ "oauth_token": ""
+ }
+
+Configure in your ``~/.gitconfig`` that your GitHub account and PAT are used for all release repositories under `ros2-gbp `_:
+
+.. code-block:: ini
+
+ [credential "https://github.com/ros2-gbp"]
+ username = x-access-token
+ helper = "!f() { test \"$1\" = get && echo \"password=\"; }; f"
+
+You can additionally use different GitHub accounts and PATs for individual release repositories:
+
+.. code-block:: ini
+
+ [credential "https://github.com/ros2-gbp/my_package-release.git"]
+ username = x-access-token
+ helper = "!f() { test \"$1\" = get && echo \"password=\"; }; f"
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Run-2-nodes-in-single-or-separate-docker-containers.rst b/source/Developer-Tools/Build/Run-2-nodes-in-single-or-separate-docker-containers.rst
index 5053a56be1c..3a8d28dd972 100644
--- a/source/Developer-Tools/Build/Run-2-nodes-in-single-or-separate-docker-containers.rst
+++ b/source/Developer-Tools/Build/Run-2-nodes-in-single-or-separate-docker-containers.rst
@@ -1,89 +1,90 @@
-.. redirect-from::
-
- Tutorials/Run-2-nodes-in-a-single-docker-container
- Tutorials/Run-2-nodes-in-two-separate-docker-containers
- Guides/Run-2-nodes-in-two-separate-docker-containers
-
-Running ROS 2 nodes in Docker [community-contributed]
-=====================================================
-
-Run two nodes in a single docker container
-------------------------------------------
-
-Pull the ROS docker image with tag "{DISTRO}-desktop".
-
-.. code-block:: console
-
- $ docker pull osrf/ros:{DISTRO}-desktop
-
-
-Run the image in a container in interactive mode.
-
-.. code-block:: console
-
- $ docker run -it osrf/ros:{DISTRO}-desktop
-
-Your best friend is the ``ros2`` command line help now.
-
-.. code-block:: console
-
- $ ros2 --help
-
-E.g. list all installed packages.
-
-.. code-block:: console
-
- $ ros2 pkg list
- (you will see a list of packages)
-
-
-E.g. list all executables:
-
-.. code-block:: console
-
- $ ros2 pkg executables
- (you will see a list of )
-
-
-Run a minimal example of 2 C++ nodes (1 topic subscriber ``listener``, 1 topic publisher ``talker``) from the package ``demo_nodes_cpp`` in this container:
-
-.. code-block:: console
-
- $ ros2 run demo_nodes_cpp listener &
- $ ros2 run demo_nodes_cpp talker
-
-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``:
-
-.. code-block:: console
-
- $ 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``:
-
-.. code-block:: console
-
- $ docker run -it --rm osrf/ros:{DISTRO}-desktop ros2 run demo_nodes_cpp listener
-
-As an alternative to the command line invocation, you can create a ``docker-compose.yml`` file (here version 2) with the following (minimal) content:
-
-.. code-block:: yaml
-
- version: '2'
-
- services:
- talker:
- image: osrf/ros:{DISTRO}-desktop
- command: ros2 run demo_nodes_cpp talker
- listener:
- image: osrf/ros:{DISTRO}-desktop
- command: ros2 run demo_nodes_cpp listener
- depends_on:
- - talker
-
-To run the containers call ``docker compose up`` in the same directory.
-You can close the containers with ``Ctrl+C``.
+.. redirect-from::
+
+ Tutorials/Run-2-nodes-in-a-single-docker-container
+ Tutorials/Run-2-nodes-in-two-separate-docker-containers
+ Guides/Run-2-nodes-in-two-separate-docker-containers
+ How-To-Guides/Run-2-nodes-in-single-or-separate-docker-containers
+
+Running ROS 2 nodes in Docker [community-contributed]
+=====================================================
+
+Run two nodes in a single docker container
+------------------------------------------
+
+Pull the ROS docker image with tag "{DISTRO}-desktop".
+
+.. code-block:: console
+
+ $ docker pull osrf/ros:{DISTRO}-desktop
+
+
+Run the image in a container in interactive mode.
+
+.. code-block:: console
+
+ $ docker run -it osrf/ros:{DISTRO}-desktop
+
+Your best friend is the ``ros2`` command line help now.
+
+.. code-block:: console
+
+ $ ros2 --help
+
+E.g. list all installed packages.
+
+.. code-block:: console
+
+ $ ros2 pkg list
+ (you will see a list of packages)
+
+
+E.g. list all executables:
+
+.. code-block:: console
+
+ $ ros2 pkg executables
+ (you will see a list of )
+
+
+Run a minimal example of 2 C++ nodes (1 topic subscriber ``listener``, 1 topic publisher ``talker``) from the package ``demo_nodes_cpp`` in this container:
+
+.. code-block:: console
+
+ $ ros2 run demo_nodes_cpp listener &
+ $ ros2 run demo_nodes_cpp talker
+
+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``:
+
+.. code-block:: console
+
+ $ 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``:
+
+.. code-block:: console
+
+ $ docker run -it --rm osrf/ros:{DISTRO}-desktop ros2 run demo_nodes_cpp listener
+
+As an alternative to the command line invocation, you can create a ``docker-compose.yml`` file (here version 2) with the following (minimal) content:
+
+.. code-block:: yaml
+
+ version: '2'
+
+ services:
+ talker:
+ image: osrf/ros:{DISTRO}-desktop
+ command: ros2 run demo_nodes_cpp talker
+ listener:
+ image: osrf/ros:{DISTRO}-desktop
+ command: ros2 run demo_nodes_cpp listener
+ depends_on:
+ - talker
+
+To run the containers call ``docker compose up`` in the same directory.
+You can close the containers with ``Ctrl+C``.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Setup-ROS-2-with-VSCode-and-Docker-Container.rst b/source/Developer-Tools/Build/Setup-ROS-2-with-VSCode-and-Docker-Container.rst
index 02d6150d0f2..2b622f41300 100644
--- a/source/Developer-Tools/Build/Setup-ROS-2-with-VSCode-and-Docker-Container.rst
+++ b/source/Developer-Tools/Build/Setup-ROS-2-with-VSCode-and-Docker-Container.rst
@@ -1,223 +1,227 @@
-Setup ROS 2 with VSCode and Docker [community-contributed]
-==========================================================
-
-
-.. contents:: Contents
- :depth: 2
- :local:
-
-
-Install VS Code and Docker
---------------------------
-
-
-Using Visual Studio Code and Docker Containers will enable you to run your favorite ROS 2 Distribution without the necessity to change your operating system or use a virtual machine.
-With this tutorial you can set up a docker container, which can be used for your future ROS 2 projects.
-
-
-Install Docker
-^^^^^^^^^^^^^^
-
-
-To install docker and set the correct user rights please use the following commands.
-
-.. code-block:: console
-
- $ sudo apt install docker.io git python3-pip
- $ pip3 install vcstool
- $ echo export PATH=$HOME/.local/bin:$PATH >> ~/.bashrc
- $ source ~/.bashrc
- $ sudo groupadd docker
- $ sudo usermod -aG docker $USER
- $ newgrp docker
-
-Now you can check if the installation was successful by running the following command:
-
-.. code-block:: console
-
- $ docker run hello-world
-
-You might need to start the Docker Daemon first, if you cannot run hello-world out of the box:
-
-.. code-block:: console
-
- $ sudo systemctl start docker
-
-Install VS Code
-^^^^^^^^^^^^^^^
-
-To install VS Code please use the following commands:
-
-.. code-block:: console
-
- $ sudo apt update
- $ sudo apt install software-properties-common apt-transport-https wget -y
- $ wget -q https://packages.microsoft.com/keys/microsoft.asc -O- | sudo apt-key add -
- $ sudo add-apt-repository "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"
- $ sudo apt install code
-
-
-You can run VS Code by typing ``code`` in a terminal.
-
-
-Install Remote Development Extension
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-
-Within VS Code search in Extensions (CTRL+SHIFT+X) for the "Remote Development" Extension and install it.
-
-
-Configure workspace in Docker and VS Code
------------------------------------------
-
-Add your ROS 2 workspace
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-
-Add a workspace in order to build and open them in a container, e.g.:
-
-.. code-block:: console
-
- $ cd ~/
- $ mkdir ws
- $ cd ws
- $ mkdir src
-
-Now create a ``.devcontainer`` folder in the root of your workspace and add a ``devcontainer.json`` and ``Dockerfile`` to this ``.devcontainer`` folder.
-The workspace structure should look like this:
-
-::
-
- ws
- ├── .devcontainer
- │ ├── devcontainer.json
- │ └── Dockerfile
- ├── src
- ├── package1
- └── package2
-
-
-With ``File->Open Folder...`` or ``Ctrl+K Ctrl+O``, open the ``ws`` folder of your workspace in VS Code.
-
-Edit ``devcontainer.json`` for your environment
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-For the Dev Container to function properly, we have to build it with the correct user.
-Therefore add the following to ``.devcontainer/devcontainer.json``:
-
-.. code-block:: json
-
- {
- "name": "ROS 2 Development Container",
- "privileged": true,
- "remoteUser": "YOUR_USERNAME",
- "build": {
- "dockerfile": "Dockerfile",
- "args": {
- "USERNAME": "YOUR_USERNAME"
- }
- },
- "workspaceFolder": "/home/ws",
- "workspaceMount": "source=${localWorkspaceFolder},target=/home/ws,type=bind",
- "customizations": {
- "vscode": {
- "extensions":[
- "ms-vscode.cpptools",
- "ms-vscode.cpptools-themes",
- "twxs.cmake",
- "donjayamanne.python-extension-pack",
- "eamodio.gitlens",
- "ms-iot.vscode-ros"
- ]
- }
- },
- "containerEnv": {
- "DISPLAY": "unix:0",
- "ROS_AUTOMATIC_DISCOVERY_RANGE": "LOCALHOST",
- "ROS_DOMAIN_ID": "42"
- },
- "runArgs": [
- "--net=host",
- "--pid=host",
- "--ipc=host",
- "-e", "DISPLAY=${env:DISPLAY}"
- ],
- "mounts": [
- "source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind,consistency=cached",
- "source=/dev/dri,target=/dev/dri,type=bind,consistency=cached"
- ],
- "postCreateCommand": "sudo rosdep update && sudo rosdep install --from-paths src --ignore-src -y && sudo chown -R $(whoami) /home/ws/"
- }
-
-
-
-Use ``Ctrl+F`` to open the search and replace menu.
-Search for ``YOUR_USERNAME`` and replace it with your ``Linux username``.
-If you do not know your username, you can find it by running ``echo $USERNAME`` in the terminal.
-
-
-Edit ``Dockerfile``
-^^^^^^^^^^^^^^^^^^^
-
-Open the Dockerfile and add the following contents:
-
-
-.. code-block:: bash
-
- FROM ros:ROS_DISTRO
- ARG USERNAME=USERNAME
- ARG USER_UID=1000
- ARG USER_GID=$USER_UID
-
- # Delete user if it exists in container (e.g Ubuntu Noble: ubuntu)
- RUN if id -u $USER_UID ; then userdel `id -un $USER_UID` ; fi
-
- # Create the user
- RUN groupadd --gid $USER_GID $USERNAME \
- && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
- #
- # [Optional] Add sudo support. Omit if you don't need to install software after connecting.
- && apt-get update \
- && apt-get install -y sudo \
- && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
- && chmod 0440 /etc/sudoers.d/$USERNAME
- RUN apt-get update && apt-get upgrade -y
- RUN apt-get install -y python3-pip
- ENV SHELL /bin/bash
-
- # ********************************************************
- # * Anything else you want to do like clean up goes here *
- # ********************************************************
-
- # [Optional] Set the default user. Omit if you want to keep the default as root.
- USER $USERNAME
- CMD ["/bin/bash"]
-
-Replace ``ROS_DISTRO`` with the ROS 2 distribution you wish to use as base image above, for example ``rolling``.
-
-
-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.
-
-
-Test Container
-^^^^^^^^^^^^^^
-
-To test if everything worked correctly, open a terminal in the container using ``View->Terminal`` or ``Ctrl+Shift+``` and ``New Terminal`` in VS Code.
-Inside the terminal do the following:
-
-.. code-block:: console
-
- $ sudo apt install ros-$ROS_DISTRO-rviz2 -y
- $ source /opt/ros/$ROS_DISTRO/setup.bash
- $ rviz2
-
-.. Note:: There might be a problem with displaying RVIZ.
- Please make sure to allow the user to access X window system with ``xhost +local:``.
- If no window still pops up, then check the value of ``echo $DISPLAY`` - if the output is 1, you can fix this problem with ``echo "export DISPLAY=unix:1" >> /etc/bash.bashrc`` and then test it again.
- You can also change the DISPLAY value in the devcontainer.json and rebuild it.
+.. redirect-from::
+
+ How-To-Guides/Setup-ROS-2-with-VSCode-and-Docker-Container
+
+Setup ROS 2 with VSCode and Docker [community-contributed]
+==========================================================
+
+
+.. contents:: Contents
+ :depth: 2
+ :local:
+
+
+Install VS Code and Docker
+--------------------------
+
+
+Using Visual Studio Code and Docker Containers will enable you to run your favorite ROS 2 Distribution without the necessity to change your operating system or use a virtual machine.
+With this tutorial you can set up a docker container, which can be used for your future ROS 2 projects.
+
+
+Install Docker
+^^^^^^^^^^^^^^
+
+
+To install docker and set the correct user rights please use the following commands.
+
+.. code-block:: console
+
+ $ sudo apt install docker.io git python3-pip
+ $ pip3 install vcstool
+ $ echo export PATH=$HOME/.local/bin:$PATH >> ~/.bashrc
+ $ source ~/.bashrc
+ $ sudo groupadd docker
+ $ sudo usermod -aG docker $USER
+ $ newgrp docker
+
+Now you can check if the installation was successful by running the following command:
+
+.. code-block:: console
+
+ $ docker run hello-world
+
+You might need to start the Docker Daemon first, if you cannot run hello-world out of the box:
+
+.. code-block:: console
+
+ $ sudo systemctl start docker
+
+Install VS Code
+^^^^^^^^^^^^^^^
+
+To install VS Code please use the following commands:
+
+.. code-block:: console
+
+ $ sudo apt update
+ $ sudo apt install software-properties-common apt-transport-https wget -y
+ $ wget -q https://packages.microsoft.com/keys/microsoft.asc -O- | sudo apt-key add -
+ $ sudo add-apt-repository "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"
+ $ sudo apt install code
+
+
+You can run VS Code by typing ``code`` in a terminal.
+
+
+Install Remote Development Extension
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+Within VS Code search in Extensions (CTRL+SHIFT+X) for the "Remote Development" Extension and install it.
+
+
+Configure workspace in Docker and VS Code
+-----------------------------------------
+
+Add your ROS 2 workspace
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+Add a workspace in order to build and open them in a container, e.g.:
+
+.. code-block:: console
+
+ $ cd ~/
+ $ mkdir ws
+ $ cd ws
+ $ mkdir src
+
+Now create a ``.devcontainer`` folder in the root of your workspace and add a ``devcontainer.json`` and ``Dockerfile`` to this ``.devcontainer`` folder.
+The workspace structure should look like this:
+
+::
+
+ ws
+ ├── .devcontainer
+ │ ├── devcontainer.json
+ │ └── Dockerfile
+ ├── src
+ ├── package1
+ └── package2
+
+
+With ``File->Open Folder...`` or ``Ctrl+K Ctrl+O``, open the ``ws`` folder of your workspace in VS Code.
+
+Edit ``devcontainer.json`` for your environment
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For the Dev Container to function properly, we have to build it with the correct user.
+Therefore add the following to ``.devcontainer/devcontainer.json``:
+
+.. code-block:: json
+
+ {
+ "name": "ROS 2 Development Container",
+ "privileged": true,
+ "remoteUser": "YOUR_USERNAME",
+ "build": {
+ "dockerfile": "Dockerfile",
+ "args": {
+ "USERNAME": "YOUR_USERNAME"
+ }
+ },
+ "workspaceFolder": "/home/ws",
+ "workspaceMount": "source=${localWorkspaceFolder},target=/home/ws,type=bind",
+ "customizations": {
+ "vscode": {
+ "extensions":[
+ "ms-vscode.cpptools",
+ "ms-vscode.cpptools-themes",
+ "twxs.cmake",
+ "donjayamanne.python-extension-pack",
+ "eamodio.gitlens",
+ "ms-iot.vscode-ros"
+ ]
+ }
+ },
+ "containerEnv": {
+ "DISPLAY": "unix:0",
+ "ROS_AUTOMATIC_DISCOVERY_RANGE": "LOCALHOST",
+ "ROS_DOMAIN_ID": "42"
+ },
+ "runArgs": [
+ "--net=host",
+ "--pid=host",
+ "--ipc=host",
+ "-e", "DISPLAY=${env:DISPLAY}"
+ ],
+ "mounts": [
+ "source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind,consistency=cached",
+ "source=/dev/dri,target=/dev/dri,type=bind,consistency=cached"
+ ],
+ "postCreateCommand": "sudo rosdep update && sudo rosdep install --from-paths src --ignore-src -y && sudo chown -R $(whoami) /home/ws/"
+ }
+
+
+
+Use ``Ctrl+F`` to open the search and replace menu.
+Search for ``YOUR_USERNAME`` and replace it with your ``Linux username``.
+If you do not know your username, you can find it by running ``echo $USERNAME`` in the terminal.
+
+
+Edit ``Dockerfile``
+^^^^^^^^^^^^^^^^^^^
+
+Open the Dockerfile and add the following contents:
+
+
+.. code-block:: bash
+
+ FROM ros:ROS_DISTRO
+ ARG USERNAME=USERNAME
+ ARG USER_UID=1000
+ ARG USER_GID=$USER_UID
+
+ # Delete user if it exists in container (e.g Ubuntu Noble: ubuntu)
+ RUN if id -u $USER_UID ; then userdel `id -un $USER_UID` ; fi
+
+ # Create the user
+ RUN groupadd --gid $USER_GID $USERNAME \
+ && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
+ #
+ # [Optional] Add sudo support. Omit if you don't need to install software after connecting.
+ && apt-get update \
+ && apt-get install -y sudo \
+ && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
+ && chmod 0440 /etc/sudoers.d/$USERNAME
+ RUN apt-get update && apt-get upgrade -y
+ RUN apt-get install -y python3-pip
+ ENV SHELL /bin/bash
+
+ # ********************************************************
+ # * Anything else you want to do like clean up goes here *
+ # ********************************************************
+
+ # [Optional] Set the default user. Omit if you want to keep the default as root.
+ USER $USERNAME
+ CMD ["/bin/bash"]
+
+Replace ``ROS_DISTRO`` with the ROS 2 distribution you wish to use as base image above, for example ``rolling``.
+
+
+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.
+
+
+Test Container
+^^^^^^^^^^^^^^
+
+To test if everything worked correctly, open a terminal in the container using ``View->Terminal`` or ``Ctrl+Shift+``` and ``New Terminal`` in VS Code.
+Inside the terminal do the following:
+
+.. code-block:: console
+
+ $ sudo apt install ros-$ROS_DISTRO-rviz2 -y
+ $ source /opt/ros/$ROS_DISTRO/setup.bash
+ $ rviz2
+
+.. Note:: There might be a problem with displaying RVIZ.
+ Please make sure to allow the user to access X window system with ``xhost +local:``.
+ If no window still pops up, then check the value of ``echo $DISPLAY`` - if the output is 1, you can fix this problem with ``echo "export DISPLAY=unix:1" >> /etc/bash.bashrc`` and then test it again.
+ You can also change the DISPLAY value in the devcontainer.json and rebuild it.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Supplementing-Custom-Rosdep-Keys.rst b/source/Developer-Tools/Build/Supplementing-Custom-Rosdep-Keys.rst
index 712777738fc..75a5dd8dba9 100644
--- a/source/Developer-Tools/Build/Supplementing-Custom-Rosdep-Keys.rst
+++ b/source/Developer-Tools/Build/Supplementing-Custom-Rosdep-Keys.rst
@@ -1,141 +1,145 @@
-Supplementing custom rosdep keys
-================================
-
-.. contents:: Contents
- :depth: 2
- :local:
-
-Overview and motivation
------------------------
-
-As explained in :doc:`../Intermediate/Rosdep`, ``rosdep`` looks for rosdep keys in ``package.xml`` files and maps them to packages to be installed for the ROS distribution and OS in use.
-Anyone can request for new rosdep keys to be added by `contributing to rosdistro `_.
-This is the preferred course of action when you have some dependency (like a ``apt`` or ``pip`` package) that you wish to be able to install via ``rosdep``.
-
-However, there are many cases when contributing your keys directly might be difficult.
-For example, if the dependency
-
-1. is not available on the target distributions default APT (or pip) repositories
-2. is a proprietary library
-3. is some niche library which is useful only for you or your organization
-4. is a ROS package you :doc:`built and packaged yourself <../../How-To-Guides/Building-a-Custom-Deb-Package>`, but don't wish to share with the broader ROS community
-
-While the option exists to :doc:`fork rosdistro <../../How-To-Guides/Using-Custom-Rosdistro>` in its entirety, this might be overkill if you just want to keep using a official ROS distribution as usual, only with some extra rosdep keys defined on top.
-This tutorial explains how to achieve this.
-
-As a word of warning though, please don't use this indiscriminately.
-It can cause very hard to debug problems because of binary incompatibilities which can manifest in silent failures, unexplained crashes, or data corruption.
-And if you're asking anyone for help on a system with this enabled, make sure to explain everything that's being added or overridden.
-
-Preliminaries: How ``rosdep`` fetches rosdep keys
--------------------------------------------------
-
-In order to get a good understanding of what we're about to do, let's first explore some relevant details about how ``rosdep`` works.
-
-``rosdep`` is similar to other tools like ``apt`` that use a sources list to maintain a local index.
-These sources are stored in ``/etc/ros/rosdep/sources.list.d``.
-This is similar to how apt stores repositories in ``/etc/apt/sources.list.d``.
-
-By default (as part of first-time setup, ``rosdep init``), you only have a single sources file: ``/etc/ros/rosdep/sources.list.d/20-default.list``.
-Inspecting its contents, you will see entries like these:
-
-.. code-block:: console
-
- $ cat /etc/ros/rosdep/sources.list.d/20-default.list
- ...
- yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/base.yaml
- yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/python.yaml
- ...
-
-These entries are what dictates where ``rosdep`` fetches rosdep keys and their mappings (rosdep **rules**) from when ``rosdep update`` is called.
-When called, ``rosdep`` compiles the relevant contents from all declared entries in all sources files into a local cached index.
-This local index is then used when installing or looking up ("resolving") rosdep keys.
-
-For example, the fact that the first entry (``base.yaml``) defines the ``libopencv-dev`` key (see `here `_) is what allows ``rosdep`` to resolve it:
-
-.. code-block:: console
-
- $ rosdep where-defined libopencv-dev
- https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/base.yaml
- $ rosdep resolve libopencv-dev
- #apt
- libopencv-dev
-
-In summary, it allows ``rosdep`` to resolve the ``libopencv-dev`` key to the ``apt`` package of the same name.
-
-Note that, from the output above, we can deduce that the command was run on a Ubuntu or Debian OS.
-On RHEL, the key instead resolves to the DNF package ``opencv-devel``:
-
-.. code-block:: console
-
- $ rosdep resolve libopencv-dev --os=rhel:9
- #dnf
- opencv-devel
-
-Extending ``rosdep`` with a custom sources file
------------------------------------------------
-
-The above hopefully makes it clear what needs to be done to get ``rosdep`` to understand new keys: add a new custom sources file!
-
-As a toy example, let's add a new sources file telling ``rosdep`` to fetch keys from a YAML file stored on the local machine.
-Fire up your favorite text editor and write the following into ``/etc/ros/rosdep/sources.list.d/30-custom.list`` (the editor will need to be launched with root privileges, e.g. via ``sudo``):
-
-.. code-block:: yaml
-
- yaml file:///etc/ros/rosdep/custom_rules.yaml
-
-Now write the following into ``/etc/ros/rosdep/custom_rules.yaml``:
-
-.. code-block:: yaml
-
- awesome_library:
- ubuntu: [awesome_library]
- that_other_library:
- ubuntu:
- pip:
- packages: [another_library]
-
-This defines two new rosdep rules:
-
-1. The key ``awesome_library``, defined only for Ubuntu, mapping to the ``apt`` package of the same name
-2. The key ``that_other_library``, defined only for Ubuntu, mapping to the ``pip`` package named ``another_library``
-
-After running ``rosdep update``, ``rosdep`` will detect the new ``30-custom.list``, prompting it to scan the contents of the ``custom_rules.yaml`` file.
-Now ``rosdep`` is set up to recognize these new keys and what they should map to:
-
-.. code-block:: console
-
- $ rosdep resolve awesome_library
- #apt
- awesome_library
- $ rosdep resolve that_other_library
- #pip
- another_library
-
-Now all you have to do is add ``awesome_library`` to your ROS packages ``package.xml``, and ``rosdep`` will know how to install the dependency!
-
-Closing remarks
----------------
-
-The toy example above only hints at what is possible with custom rosdep keys.
-
-- **Is your dependency an APT package hosted in a third party PPA?**
- Not a problem.
- Since all ``rosdep`` does is converting the key to a ``apt install`` invocation, APT will have no problem installing the package (provided you have added the PPA).
-- **Is your dependency a pip package hosted in a third party index?**
- Add the index to your ``pip.conf`` and you're good to go.
-- **Sources files don't have to point to files on the local machine.**
- Both ``file://`` and ``https://`` syntax is supported (on Linux, absolute paths start with ``/``, which leads to a triple slash like ``file:///etc/rosdep/my.file``).
-- **Sources are loaded in alphabetical order.**
- If you add a conflicting rule in the 30 prefix it will not be used.
- If you created a sources file with a 10 prefix it will override packages in the default list (prefix 20).
- If you're using packages installed from binary repositories it's highly recommended to not override dependency declarations as it will likely cause binary incompatibilities which can be very hard to debug.
-- **Merging keys is not possible.**
- It is not possible to e.g. only add a ``fedora`` installation rule to an existing rosdep key.
- Depending on the load order, such rule would either be ignored, or it would completely override the whole rosdep key, removing all other installers.
-
-Further reading
----------------
-
-- https://docs.ros.org/en/independent/api/rosdep/html/rosdep_yaml_format.html
-- https://docs.ros.org/en/independent/api/rosdep/html/contributing_rules.html
+.. redirect-from::
+
+ Tutorials/Advanced/Supplementing-Custom-Rosdep-Keys
+
+Supplementing custom rosdep keys
+================================
+
+.. contents:: Contents
+ :depth: 2
+ :local:
+
+Overview and motivation
+-----------------------
+
+As explained in :doc:`../../ROS-Framework/client-libraries/Working-with-Client-Libraries/Rosdep`, ``rosdep`` looks for rosdep keys in ``package.xml`` files and maps them to packages to be installed for the ROS distribution and OS in use.
+Anyone can request for new rosdep keys to be added by `contributing to rosdistro `_.
+This is the preferred course of action when you have some dependency (like a ``apt`` or ``pip`` package) that you wish to be able to install via ``rosdep``.
+
+However, there are many cases when contributing your keys directly might be difficult.
+For example, if the dependency
+
+1. is not available on the target distributions default APT (or pip) repositories
+2. is a proprietary library
+3. is some niche library which is useful only for you or your organization
+4. is a ROS package you :doc:`built and packaged yourself `, but don't wish to share with the broader ROS community
+
+While the option exists to :doc:`fork rosdistro <../../Migration-and-Upgrades/Using-Custom-Rosdistro>` in its entirety, this might be overkill if you just want to keep using a official ROS distribution as usual, only with some extra rosdep keys defined on top.
+This tutorial explains how to achieve this.
+
+As a word of warning though, please don't use this indiscriminately.
+It can cause very hard to debug problems because of binary incompatibilities which can manifest in silent failures, unexplained crashes, or data corruption.
+And if you're asking anyone for help on a system with this enabled, make sure to explain everything that's being added or overridden.
+
+Preliminaries: How ``rosdep`` fetches rosdep keys
+-------------------------------------------------
+
+In order to get a good understanding of what we're about to do, let's first explore some relevant details about how ``rosdep`` works.
+
+``rosdep`` is similar to other tools like ``apt`` that use a sources list to maintain a local index.
+These sources are stored in ``/etc/ros/rosdep/sources.list.d``.
+This is similar to how apt stores repositories in ``/etc/apt/sources.list.d``.
+
+By default (as part of first-time setup, ``rosdep init``), you only have a single sources file: ``/etc/ros/rosdep/sources.list.d/20-default.list``.
+Inspecting its contents, you will see entries like these:
+
+.. code-block:: console
+
+ $ cat /etc/ros/rosdep/sources.list.d/20-default.list
+ ...
+ yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/base.yaml
+ yaml https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/python.yaml
+ ...
+
+These entries are what dictates where ``rosdep`` fetches rosdep keys and their mappings (rosdep **rules**) from when ``rosdep update`` is called.
+When called, ``rosdep`` compiles the relevant contents from all declared entries in all sources files into a local cached index.
+This local index is then used when installing or looking up ("resolving") rosdep keys.
+
+For example, the fact that the first entry (``base.yaml``) defines the ``libopencv-dev`` key (see `here `_) is what allows ``rosdep`` to resolve it:
+
+.. code-block:: console
+
+ $ rosdep where-defined libopencv-dev
+ https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/base.yaml
+ $ rosdep resolve libopencv-dev
+ #apt
+ libopencv-dev
+
+In summary, it allows ``rosdep`` to resolve the ``libopencv-dev`` key to the ``apt`` package of the same name.
+
+Note that, from the output above, we can deduce that the command was run on a Ubuntu or Debian OS.
+On RHEL, the key instead resolves to the DNF package ``opencv-devel``:
+
+.. code-block:: console
+
+ $ rosdep resolve libopencv-dev --os=rhel:9
+ #dnf
+ opencv-devel
+
+Extending ``rosdep`` with a custom sources file
+-----------------------------------------------
+
+The above hopefully makes it clear what needs to be done to get ``rosdep`` to understand new keys: add a new custom sources file!
+
+As a toy example, let's add a new sources file telling ``rosdep`` to fetch keys from a YAML file stored on the local machine.
+Fire up your favorite text editor and write the following into ``/etc/ros/rosdep/sources.list.d/30-custom.list`` (the editor will need to be launched with root privileges, e.g. via ``sudo``):
+
+.. code-block:: yaml
+
+ yaml file:///etc/ros/rosdep/custom_rules.yaml
+
+Now write the following into ``/etc/ros/rosdep/custom_rules.yaml``:
+
+.. code-block:: yaml
+
+ awesome_library:
+ ubuntu: [awesome_library]
+ that_other_library:
+ ubuntu:
+ pip:
+ packages: [another_library]
+
+This defines two new rosdep rules:
+
+1. The key ``awesome_library``, defined only for Ubuntu, mapping to the ``apt`` package of the same name
+2. The key ``that_other_library``, defined only for Ubuntu, mapping to the ``pip`` package named ``another_library``
+
+After running ``rosdep update``, ``rosdep`` will detect the new ``30-custom.list``, prompting it to scan the contents of the ``custom_rules.yaml`` file.
+Now ``rosdep`` is set up to recognize these new keys and what they should map to:
+
+.. code-block:: console
+
+ $ rosdep resolve awesome_library
+ #apt
+ awesome_library
+ $ rosdep resolve that_other_library
+ #pip
+ another_library
+
+Now all you have to do is add ``awesome_library`` to your ROS packages ``package.xml``, and ``rosdep`` will know how to install the dependency!
+
+Closing remarks
+---------------
+
+The toy example above only hints at what is possible with custom rosdep keys.
+
+- **Is your dependency an APT package hosted in a third party PPA?**
+ Not a problem.
+ Since all ``rosdep`` does is converting the key to a ``apt install`` invocation, APT will have no problem installing the package (provided you have added the PPA).
+- **Is your dependency a pip package hosted in a third party index?**
+ Add the index to your ``pip.conf`` and you're good to go.
+- **Sources files don't have to point to files on the local machine.**
+ Both ``file://`` and ``https://`` syntax is supported (on Linux, absolute paths start with ``/``, which leads to a triple slash like ``file:///etc/rosdep/my.file``).
+- **Sources are loaded in alphabetical order.**
+ If you add a conflicting rule in the 30 prefix it will not be used.
+ If you created a sources file with a 10 prefix it will override packages in the default list (prefix 20).
+ If you're using packages installed from binary repositories it's highly recommended to not override dependency declarations as it will likely cause binary incompatibilities which can be very hard to debug.
+- **Merging keys is not possible.**
+ It is not possible to e.g. only add a ``fedora`` installation rule to an existing rosdep key.
+ Depending on the load order, such rule would either be ignored, or it would completely override the whole rosdep key, removing all other installers.
+
+Further reading
+---------------
+
+- https://docs.ros.org/en/independent/api/rosdep/html/rosdep_yaml_format.html
+- https://docs.ros.org/en/independent/api/rosdep/html/contributing_rules.html
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/The-Keystore.rst b/source/Developer-Tools/Build/The-Keystore.rst
index 6ac5b90c048..480c3e269f6 100644
--- a/source/Developer-Tools/Build/The-Keystore.rst
+++ b/source/Developer-Tools/Build/The-Keystore.rst
@@ -1,262 +1,263 @@
-.. redirect-from::
-
- Tutorials/Security/The-Keystore
-
-.. _The-Keystore:
-
-Understanding the security keystore
-===================================
-
-**Goal:** Explore files located in the ROS 2 security keystore.
-
-**Tutorial level:** Advanced
-
-**Time:** 15 minutes
-
-.. contents:: Contents
- :depth: 2
- :local:
-
-
-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 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
----------------------------
-
-With communications security enabled in the prior tutorial, let's take a look at the files which were created when security was enabled.
-These are the files which make encryption possible.
-
-The ``sros2`` utilities (``ros2 security ...``) separate files into public, private and enclave key materials.
-
-ROS uses the directory defined by the environmental variable ``ROS_SECURITY_KEYSTORE`` as the keystore.
-For this tutorial, we use the directory ``~/sros2_demo/demo_keystore``.
-
-
-Public Key Materials
-^^^^^^^^^^^^^^^^^^^^
-
-You will find three encryption certificates in the public directory at ``~/sros2_demo/demo_keystore/public``; however, the identity and permissions certificates are actually just a link to the Certificate Authority (CA) certificate.
-
-In a public key infrastructure, the `Certificate Authority `_ acts as a trust anchor: it validates the identities and permissions of participants.
-For ROS, that means all the nodes that participate in the ROS graph (which may extend to an entire fleet of individual robots).
-By placing the Certificate Authority's certificate (``ca.cert.pem``) in the proper location on the robot, all ROS nodes can establish mutual trust with other nodes using the same Certificate Authority.
-
-Although in our tutorials we create a Certificate Authority on-the-fly, in a production system this should be done according to a pre-defined security plan.
-Typically the Certificate Authority for a production system will be created off-line, and placed on the robot during initial setup.
-It may be unique for each robot, or shared across a fleet of robots all intended to trust each other.
-
-DDS (and ROS, by extension) supports separation of identity and permission trust chains, so each function has its own certificate authority.
-In most cases a ROS system security plan does not require a separation between these duties, so the security utilities generate a single Certificate Authority which is used for both identity and permissions.
-
-Use ``openssl`` to view this x509 certificate and display it as text:
-
-.. code-block:: console
-
- $ cd ~/sros2_demo/demo_keystore/public
- $ openssl x509 -in ca.cert.pem -text -noout
-
-The output should look similar to the following::
-
- Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 02:8e:9a:24:ea:10:55:cb:e6:ea:e8:7a:c0:5f:58:6d:37:42:78:aa
- Signature Algorithm: ecdsa-with-SHA256
- Issuer: CN = sros2CA
- Validity
- Not Before: Jun 1 16:57:37 2021 GMT
- Not After : May 31 16:57:37 2031 GMT
- Subject: CN = sros2CA
- Subject Public Key Info:
- Public Key Algorithm: id-ecPublicKey
- Public-Key: (256 bit)
- pub:
- 04:71:e9:37:d7:32:ba:b8:a0:97:66:da:9f:e3:c4:
- 08:4f:7a:13:59:24:c6:cf:6a:f7:95:c5:cd:82:c0:
- 7f:7f:e3:90:dd:7b:0f:77:d1:ee:0e:af:68:7c:76:
- a9:ca:60:d7:1e:2c:01:d7:bc:7e:e3:86:2a:9f:38:
- dc:ed:39:c5:32
- ASN1 OID: prime256v1
- NIST CURVE: P-256
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:1
- Signature Algorithm: ecdsa-with-SHA256
- 30:45:02:21:00:d4:fc:d8:45:ff:a4:51:49:98:4c:f0:c4:3f:
- e0:e7:33:19:8e:31:3c:d0:43:e7:e9:8f:36:f0:90:18:ed:d7:
- 7d:02:20:30:84:f7:04:33:87:bb:4f:d3:8b:95:61:48:df:83:
- 4b:e5:92:b3:e6:ee:3c:d5:cf:30:43:09:04:71:bd:dd:7c
-
-Some things to note about this CA certificate:
- - The certificate subject name ``sros2CA`` is the default provided by the ``sros2`` utilities.
- - This certificate is valid for ten years from time of creation
- - Like all certificates, this contains a public key used for public-private key encryption
- - As a Root Certificate Authority, this is a `self-signed certificate `_; i.e., it is signed using its own private key.
-
-Since this is a public certificate, it can be freely copied as needed to establish trust throughout your ROS system.
-
-
-Private Key Materials
-^^^^^^^^^^^^^^^^^^^^^
-
-Private key materials can be found in the keystore directory ``~/sros2_demo/demo_keystore/private``.
-Similar to the ``public`` directory, this contains one certificate authority key ``ca.key.pem`` and symbolic links to it to be used as both an Identity and a Permissions CA private key.
-
-.. warning::
-
- Protect this private key and create a secure backup of it!
-
-This is the private key associated with the public Certificate Authority which serves as the anchor for all security in your ROS system.
-You will use it to modify encryption policies for the ROS graph and to add new ROS participants.
-Depending upon your robot's security needs, the key can be protected with access permissions and locked down to another account, or it can be moved off the robot entirely and onto another system or device.
-If the file is lost, you will be unable to change access permissions and add new participants to the system.
-Similarly, any user or process with access to the file has the ability to modify system policies and participants.
-
-This file is only required for configuring the robot, but is not needed for the robot to run.
-It can safely be stored offline in another system or removable media.
-
-The ``sros2`` utilities use `elliptic curve cryptograpy `_ rather than RSA for improved security and reduced key size.
-Use the following command to show details about this elliptic curve private key:
-
-
-.. code-block:: console
-
- $ cd ~/sros2_demo/demo_keystore/private
- $ openssl ec -in ca.key.pem -text -noout
- read EC key
- Private-Key: (256 bit)
- priv:
- 93:da:76:b9:e3:91:ab:e9:42:76:f2:38:f1:9d:94:
- 90:5e:b5:96:7b:7f:71:ee:13:1b:d4:a0:f9:48:fb:
- ae:77
- pub:
- 04:71:e9:37:d7:32:ba:b8:a0:97:66:da:9f:e3:c4:
- 08:4f:7a:13:59:24:c6:cf:6a:f7:95:c5:cd:82:c0:
- 7f:7f:e3:90:dd:7b:0f:77:d1:ee:0e:af:68:7c:76:
- a9:ca:60:d7:1e:2c:01:d7:bc:7e:e3:86:2a:9f:38:
- dc:ed:39:c5:32
- ASN1 OID: prime256v1
- NIST CURVE: P-256
-
-In addition to the private key itself, note that the public key is listed, and it matches the public key listed in the Certificate Authority ``ca.cert.pem``.
-
-
-Domain Governance Policy
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-Find the domain governance policy in the enclave directory within the keystore, ``~/sros2_demo/demo_keystore/enclaves``.
-The ``enclave`` directory contains XML governance policy document ``governance.xml``, as well as a copy of the document which has been signed by the Permissions CA as ``governance.p7s``.
-
-The ``governance.p7s`` file contains domain-wide settings such as how to handle unauthenticated participants, whether to encrypt discovery, and default rules for access to topics.
-
-Use the following command to validate the `S/MIME signature `_ of the governance file:
-
-.. code-block:: console
-
- $ openssl smime -verify -in governance.p7s -CAfile ../public/permissions_ca.cert.pem
-
-This command will print out the XML document, and the last line will be ``Verification successful`` to show that the document was properly signed by the Permissions CA.
-
-
-Security Enclaves
-^^^^^^^^^^^^^^^^^
-
-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 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 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:
-
- - ``key.pem``, the private key used to encrypt and decrypt within this enclave
- - ``cert.pem``, the public certificate for this enclave; this certificate has been signed by the Identity CA
- - ``permissions.p7s``, the permissions for this enclave; this file has been signed with the Permissions CA
- - ``governance.p7s``, a link to the signed security policy file for this domain
- - ``identity_ca.cert.pem``, a link to the Identity CA for this domain
- - ``permissions_ca.cert.pem``, a link to the Permissions CA for this domain
-
-The private encryption key ``key.pem`` should be protected according to your security plan.
-This key encrypts, decrypts and validates communications within this specific enclave.
-Should the key be lost or stolen, revoke the key and create a new identity for this enclave.
-
-The file ``permissions.xml`` has also been created in this directory and can be used to recreate the signed permissions file.
-However, this file is not required to enable security since DDS uses the signed version of the file instead.
-
-
-Take the quiz!
---------------
-
-See if you can answer these questions about the ROS security keystore.
-Begin with a new terminal session and enable security with the keystore created in the prior tutorial:
-
-.. code-block:: console
-
- $ export ROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keystore
- $ export ROS_SECURITY_ENABLE=true
- $ export ROS_SECURITY_STRATEGY=Enforce
-
- $ cd ~/sros2_demo/demo_keystore/enclaves/talker_listener/listener
-
-Make a backup copy of ``permissions.p7s`` before beginning.
-
-.. tabs::
-
- .. group-tab:: Question 1
-
- Open ``permissions.p7s`` in a text editor.
- Make a negligible change to the XML content (e.g., add a space or a blank line) and save the file.
- Launch the listener node:
-
- .. code-block:: console
-
- $ ros2 run demo_nodes_cpp listener --ros-args --enclave /talker_listener/listener
-
- What do you expect to happen?
-
- Can you launch the talker node?
-
- .. code-block:: console
-
- $ ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker
-
- What is the difference between launching the listener and launching the talker?
-
- .. group-tab:: Answer 1
-
- The listener fails to launch and throws an error.
- When the ``permissions.p7s`` file was modified--however minor--the file's signature became invalid.
- A node will not launch with security enabled and enforced when the permissions file is invalid.
-
- The talker will start as expected.
- It uses the ``permissions.p7s`` file in a different enclave, and the file is still valid.
-
-.. tabs::
-
- .. group-tab:: Question 2
-
- What command lets you check to see if the signature on the modified ``permissions.p7s`` file is valid?
-
- .. group-tab:: Answer 2
-
- Check that ``permissions.p7s`` has been properly signed by the Permissions CA using the ``openssl smime`` command:
-
- .. code-block:: console
-
- $ openssl smime -verify -in permissions.p7s -CAfile permissions_ca.cert.pem
-
-Restore your original, properly signed ``permissions.p7s`` file before proceeding to the next tutorial.
+.. redirect-from::
+
+ Tutorials/Security/The-Keystore
+ Tutorials/Advanced/Security/The-Keystore
+
+.. _The-Keystore:
+
+Understanding the security keystore
+===================================
+
+**Goal:** Explore files located in the ROS 2 security keystore.
+
+**Tutorial level:** Advanced
+
+**Time:** 15 minutes
+
+.. contents:: Contents
+ :depth: 2
+ :local:
+
+
+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 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
+---------------------------
+
+With communications security enabled in the prior tutorial, let's take a look at the files which were created when security was enabled.
+These are the files which make encryption possible.
+
+The ``sros2`` utilities (``ros2 security ...``) separate files into public, private and enclave key materials.
+
+ROS uses the directory defined by the environmental variable ``ROS_SECURITY_KEYSTORE`` as the keystore.
+For this tutorial, we use the directory ``~/sros2_demo/demo_keystore``.
+
+
+Public Key Materials
+^^^^^^^^^^^^^^^^^^^^
+
+You will find three encryption certificates in the public directory at ``~/sros2_demo/demo_keystore/public``; however, the identity and permissions certificates are actually just a link to the Certificate Authority (CA) certificate.
+
+In a public key infrastructure, the `Certificate Authority `_ acts as a trust anchor: it validates the identities and permissions of participants.
+For ROS, that means all the nodes that participate in the ROS graph (which may extend to an entire fleet of individual robots).
+By placing the Certificate Authority's certificate (``ca.cert.pem``) in the proper location on the robot, all ROS nodes can establish mutual trust with other nodes using the same Certificate Authority.
+
+Although in our tutorials we create a Certificate Authority on-the-fly, in a production system this should be done according to a pre-defined security plan.
+Typically the Certificate Authority for a production system will be created off-line, and placed on the robot during initial setup.
+It may be unique for each robot, or shared across a fleet of robots all intended to trust each other.
+
+DDS (and ROS, by extension) supports separation of identity and permission trust chains, so each function has its own certificate authority.
+In most cases a ROS system security plan does not require a separation between these duties, so the security utilities generate a single Certificate Authority which is used for both identity and permissions.
+
+Use ``openssl`` to view this x509 certificate and display it as text:
+
+.. code-block:: console
+
+ $ cd ~/sros2_demo/demo_keystore/public
+ $ openssl x509 -in ca.cert.pem -text -noout
+
+The output should look similar to the following::
+
+ Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 02:8e:9a:24:ea:10:55:cb:e6:ea:e8:7a:c0:5f:58:6d:37:42:78:aa
+ Signature Algorithm: ecdsa-with-SHA256
+ Issuer: CN = sros2CA
+ Validity
+ Not Before: Jun 1 16:57:37 2021 GMT
+ Not After : May 31 16:57:37 2031 GMT
+ Subject: CN = sros2CA
+ Subject Public Key Info:
+ Public Key Algorithm: id-ecPublicKey
+ Public-Key: (256 bit)
+ pub:
+ 04:71:e9:37:d7:32:ba:b8:a0:97:66:da:9f:e3:c4:
+ 08:4f:7a:13:59:24:c6:cf:6a:f7:95:c5:cd:82:c0:
+ 7f:7f:e3:90:dd:7b:0f:77:d1:ee:0e:af:68:7c:76:
+ a9:ca:60:d7:1e:2c:01:d7:bc:7e:e3:86:2a:9f:38:
+ dc:ed:39:c5:32
+ ASN1 OID: prime256v1
+ NIST CURVE: P-256
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE, pathlen:1
+ Signature Algorithm: ecdsa-with-SHA256
+ 30:45:02:21:00:d4:fc:d8:45:ff:a4:51:49:98:4c:f0:c4:3f:
+ e0:e7:33:19:8e:31:3c:d0:43:e7:e9:8f:36:f0:90:18:ed:d7:
+ 7d:02:20:30:84:f7:04:33:87:bb:4f:d3:8b:95:61:48:df:83:
+ 4b:e5:92:b3:e6:ee:3c:d5:cf:30:43:09:04:71:bd:dd:7c
+
+Some things to note about this CA certificate:
+ - The certificate subject name ``sros2CA`` is the default provided by the ``sros2`` utilities.
+ - This certificate is valid for ten years from time of creation
+ - Like all certificates, this contains a public key used for public-private key encryption
+ - As a Root Certificate Authority, this is a `self-signed certificate `_; i.e., it is signed using its own private key.
+
+Since this is a public certificate, it can be freely copied as needed to establish trust throughout your ROS system.
+
+
+Private Key Materials
+^^^^^^^^^^^^^^^^^^^^^
+
+Private key materials can be found in the keystore directory ``~/sros2_demo/demo_keystore/private``.
+Similar to the ``public`` directory, this contains one certificate authority key ``ca.key.pem`` and symbolic links to it to be used as both an Identity and a Permissions CA private key.
+
+.. warning::
+
+ Protect this private key and create a secure backup of it!
+
+This is the private key associated with the public Certificate Authority which serves as the anchor for all security in your ROS system.
+You will use it to modify encryption policies for the ROS graph and to add new ROS participants.
+Depending upon your robot's security needs, the key can be protected with access permissions and locked down to another account, or it can be moved off the robot entirely and onto another system or device.
+If the file is lost, you will be unable to change access permissions and add new participants to the system.
+Similarly, any user or process with access to the file has the ability to modify system policies and participants.
+
+This file is only required for configuring the robot, but is not needed for the robot to run.
+It can safely be stored offline in another system or removable media.
+
+The ``sros2`` utilities use `elliptic curve cryptograpy `_ rather than RSA for improved security and reduced key size.
+Use the following command to show details about this elliptic curve private key:
+
+
+.. code-block:: console
+
+ $ cd ~/sros2_demo/demo_keystore/private
+ $ openssl ec -in ca.key.pem -text -noout
+ read EC key
+ Private-Key: (256 bit)
+ priv:
+ 93:da:76:b9:e3:91:ab:e9:42:76:f2:38:f1:9d:94:
+ 90:5e:b5:96:7b:7f:71:ee:13:1b:d4:a0:f9:48:fb:
+ ae:77
+ pub:
+ 04:71:e9:37:d7:32:ba:b8:a0:97:66:da:9f:e3:c4:
+ 08:4f:7a:13:59:24:c6:cf:6a:f7:95:c5:cd:82:c0:
+ 7f:7f:e3:90:dd:7b:0f:77:d1:ee:0e:af:68:7c:76:
+ a9:ca:60:d7:1e:2c:01:d7:bc:7e:e3:86:2a:9f:38:
+ dc:ed:39:c5:32
+ ASN1 OID: prime256v1
+ NIST CURVE: P-256
+
+In addition to the private key itself, note that the public key is listed, and it matches the public key listed in the Certificate Authority ``ca.cert.pem``.
+
+
+Domain Governance Policy
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Find the domain governance policy in the enclave directory within the keystore, ``~/sros2_demo/demo_keystore/enclaves``.
+The ``enclave`` directory contains XML governance policy document ``governance.xml``, as well as a copy of the document which has been signed by the Permissions CA as ``governance.p7s``.
+
+The ``governance.p7s`` file contains domain-wide settings such as how to handle unauthenticated participants, whether to encrypt discovery, and default rules for access to topics.
+
+Use the following command to validate the `S/MIME signature `_ of the governance file:
+
+.. code-block:: console
+
+ $ openssl smime -verify -in governance.p7s -CAfile ../public/permissions_ca.cert.pem
+
+This command will print out the XML document, and the last line will be ``Verification successful`` to show that the document was properly signed by the Permissions CA.
+
+
+Security Enclaves
+^^^^^^^^^^^^^^^^^
+
+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 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 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:
+
+ - ``key.pem``, the private key used to encrypt and decrypt within this enclave
+ - ``cert.pem``, the public certificate for this enclave; this certificate has been signed by the Identity CA
+ - ``permissions.p7s``, the permissions for this enclave; this file has been signed with the Permissions CA
+ - ``governance.p7s``, a link to the signed security policy file for this domain
+ - ``identity_ca.cert.pem``, a link to the Identity CA for this domain
+ - ``permissions_ca.cert.pem``, a link to the Permissions CA for this domain
+
+The private encryption key ``key.pem`` should be protected according to your security plan.
+This key encrypts, decrypts and validates communications within this specific enclave.
+Should the key be lost or stolen, revoke the key and create a new identity for this enclave.
+
+The file ``permissions.xml`` has also been created in this directory and can be used to recreate the signed permissions file.
+However, this file is not required to enable security since DDS uses the signed version of the file instead.
+
+
+Take the quiz!
+--------------
+
+See if you can answer these questions about the ROS security keystore.
+Begin with a new terminal session and enable security with the keystore created in the prior tutorial:
+
+.. code-block:: console
+
+ $ export ROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keystore
+ $ export ROS_SECURITY_ENABLE=true
+ $ export ROS_SECURITY_STRATEGY=Enforce
+
+ $ cd ~/sros2_demo/demo_keystore/enclaves/talker_listener/listener
+
+Make a backup copy of ``permissions.p7s`` before beginning.
+
+.. tabs::
+
+ .. group-tab:: Question 1
+
+ Open ``permissions.p7s`` in a text editor.
+ Make a negligible change to the XML content (e.g., add a space or a blank line) and save the file.
+ Launch the listener node:
+
+ .. code-block:: console
+
+ $ ros2 run demo_nodes_cpp listener --ros-args --enclave /talker_listener/listener
+
+ What do you expect to happen?
+
+ Can you launch the talker node?
+
+ .. code-block:: console
+
+ $ ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker
+
+ What is the difference between launching the listener and launching the talker?
+
+ .. group-tab:: Answer 1
+
+ The listener fails to launch and throws an error.
+ When the ``permissions.p7s`` file was modified--however minor--the file's signature became invalid.
+ A node will not launch with security enabled and enforced when the permissions file is invalid.
+
+ The talker will start as expected.
+ It uses the ``permissions.p7s`` file in a different enclave, and the file is still valid.
+
+.. tabs::
+
+ .. group-tab:: Question 2
+
+ What command lets you check to see if the signature on the modified ``permissions.p7s`` file is valid?
+
+ .. group-tab:: Answer 2
+
+ Check that ``permissions.p7s`` has been properly signed by the Permissions CA using the ``openssl smime`` command:
+
+ .. code-block:: console
+
+ $ openssl smime -verify -in permissions.p7s -CAfile permissions_ca.cert.pem
+
+Restore your original, properly signed ``permissions.p7s`` file before proceeding to the next tutorial.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Using-Python-Packages.rst b/source/Developer-Tools/Build/Using-Python-Packages.rst
index 56d2793f680..1860778fcdd 100644
--- a/source/Developer-Tools/Build/Using-Python-Packages.rst
+++ b/source/Developer-Tools/Build/Using-Python-Packages.rst
@@ -1,101 +1,102 @@
-.. redirect-from::
-
- Guides/Using-Python-Packages
- Tutorials/Using-Python-Packages
-
-.. _PythonPackages:
-
-Using Python Packages with ROS 2
-================================
-
-**Goal:** Explain how to interoperate with other Python packages from the ROS 2 ecosystem.
-
-.. contents:: Contents
- :depth: 2
- :local:
-
-.. note::
-
- A cautionary note, if you intended to use pre-packaged binaries (either ``deb`` files, or the binary archive distributions), the Python interpreter must match what was used to build the original binaries.
- If you intend to use something like ``virtualenv`` or ``pipenv``\, make sure to use the system interpreter.
- If you use something like ``conda``, it is very likely that the interpreter will not match the system interpreter and will be incompatible with ROS 2 binaries.
-
-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:
-
-* https://github.com/ros/rosdistro/blob/master/rosdep/base.yaml
-* https://github.com/ros/rosdistro/blob/master/rosdep/python.yaml
-
-These ``rosdep`` keys can be added to your ``package.xml`` file, which indicates to the build system that your package (and dependent packages) depend on those keys.
-In a new workspace, you can also quickly install all rosdep keys with:
-
-.. code-block:: console
-
- $ rosdep install -yr --from-paths ./path/to/your/workspace
-
-If there aren't currently ``rosdep`` keys for the package that you are interested in, it is possible to add them by following the `rosdep key contribution guide`_.
-
-To learn more about the ``rosdep`` tool and how it works, consult the `rosdep documentation`_.
-
-Installing via a package manager
---------------------------------
-
-If you don't want to make a rosdep key, but the package is available in your system package manager (eg ``apt``), you can install and use the package that way:
-
-.. code-block:: console
-
- $ sudo apt install python3-serial
-
-If the package is available on `The Python Package Index (PyPI) `_ and you want to install globally on your system:
-
-.. code-block:: console
-
- $ python3 -m pip install -U pyserial
-
-If the package is available on PyPI and you want to install locally to your user:
-
-.. code-block:: console
-
- $ python3 -m pip install -U --user pyserial
-
-Installing via a virtual environment
-------------------------------------
-
-First, create a Colcon workspace:
-
-.. code-block:: console
-
- $ mkdir -p ~/colcon_venv/src
- $ cd ~/colcon_venv/
-
-Then setup your virtual environment:
-
-.. code-block:: console
-
- $ virtualenv -p python3 ./venv # Make a virtual env and activate it
- $ source ./venv/bin/activate
- $ touch ./venv/COLCON_IGNORE # Make sure that colcon does not try to build the venv
-
-Next, install the Python packages that you want in your virtual environment:
-
-.. code-block:: console
-
- $ python3 -m pip install gtsam pyserial… etc
-
-Now you can build your workspace and run your python node that depends on packages installed in your virtual environment.
-
-.. code-block:: console
-
- $ source /opt/ros/{DISTRO}/setup.bash # Source {DISTRO_TITLE} and build
- $ colcon build
-
-.. note::
-
- If you want to release your package using Bloom, you should add the packages you require to ``rosdep``, see the `rosdep key contribution guide`_.
-
-.. _rosdep key contribution guide: http://docs.ros.org/en/independent/api/rosdep/html/contributing_rules.html
-
-.. _rosdep documentation: http://docs.ros.org/en/independent/api/rosdep/html/
+.. redirect-from::
+
+ Guides/Using-Python-Packages
+ Tutorials/Using-Python-Packages
+ How-To-Guides/Using-Python-Packages
+
+.. _PythonPackages:
+
+Using Python Packages with ROS 2
+================================
+
+**Goal:** Explain how to interoperate with other Python packages from the ROS 2 ecosystem.
+
+.. contents:: Contents
+ :depth: 2
+ :local:
+
+.. note::
+
+ A cautionary note, if you intended to use pre-packaged binaries (either ``deb`` files, or the binary archive distributions), the Python interpreter must match what was used to build the original binaries.
+ If you intend to use something like ``virtualenv`` or ``pipenv``\, make sure to use the system interpreter.
+ If you use something like ``conda``, it is very likely that the interpreter will not match the system interpreter and will be incompatible with ROS 2 binaries.
+
+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:
+
+* https://github.com/ros/rosdistro/blob/master/rosdep/base.yaml
+* https://github.com/ros/rosdistro/blob/master/rosdep/python.yaml
+
+These ``rosdep`` keys can be added to your ``package.xml`` file, which indicates to the build system that your package (and dependent packages) depend on those keys.
+In a new workspace, you can also quickly install all rosdep keys with:
+
+.. code-block:: console
+
+ $ rosdep install -yr --from-paths ./path/to/your/workspace
+
+If there aren't currently ``rosdep`` keys for the package that you are interested in, it is possible to add them by following the `rosdep key contribution guide`_.
+
+To learn more about the ``rosdep`` tool and how it works, consult the `rosdep documentation`_.
+
+Installing via a package manager
+--------------------------------
+
+If you don't want to make a rosdep key, but the package is available in your system package manager (eg ``apt``), you can install and use the package that way:
+
+.. code-block:: console
+
+ $ sudo apt install python3-serial
+
+If the package is available on `The Python Package Index (PyPI) `_ and you want to install globally on your system:
+
+.. code-block:: console
+
+ $ python3 -m pip install -U pyserial
+
+If the package is available on PyPI and you want to install locally to your user:
+
+.. code-block:: console
+
+ $ python3 -m pip install -U --user pyserial
+
+Installing via a virtual environment
+------------------------------------
+
+First, create a Colcon workspace:
+
+.. code-block:: console
+
+ $ mkdir -p ~/colcon_venv/src
+ $ cd ~/colcon_venv/
+
+Then setup your virtual environment:
+
+.. code-block:: console
+
+ $ virtualenv -p python3 ./venv # Make a virtual env and activate it
+ $ source ./venv/bin/activate
+ $ touch ./venv/COLCON_IGNORE # Make sure that colcon does not try to build the venv
+
+Next, install the Python packages that you want in your virtual environment:
+
+.. code-block:: console
+
+ $ python3 -m pip install gtsam pyserial… etc
+
+Now you can build your workspace and run your python node that depends on packages installed in your virtual environment.
+
+.. code-block:: console
+
+ $ source /opt/ros/{DISTRO}/setup.bash # Source {DISTRO_TITLE} and build
+ $ colcon build
+
+.. note::
+
+ If you want to release your package using Bloom, you should add the packages you require to ``rosdep``, see the `rosdep key contribution guide`_.
+
+.. _rosdep key contribution guide: http://docs.ros.org/en/independent/api/rosdep/html/contributing_rules.html
+
+.. _rosdep documentation: http://docs.ros.org/en/independent/api/rosdep/html/
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Using-Variants.rst b/source/Developer-Tools/Build/Using-Variants.rst
index bda4db07e9c..01497bd5622 100644
--- a/source/Developer-Tools/Build/Using-Variants.rst
+++ b/source/Developer-Tools/Build/Using-Variants.rst
@@ -1,68 +1,72 @@
-Using variants
-==============
-
-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
-.. [#] https://help.ubuntu.com/community/MetaPackages
-
-The different variants in ROS 2 are specified in `REP-2001 `_.
-
-In addition to the official variants, there may be metapackages for specific institutions or robots as described in `REP-108 `_.
-
-Adding variants
----------------
-
-Additional variants that are of general use to the ROS community can be proposed by contributing an update to `REP-2001 via pull request `_ describing the packages included in the new variant.
-Institution and robot specific variants can be published directly by their respective maintainers and no update to REP-2001 is required.
-
-Creating project-specific variants
-----------------------------------
-
-If you are creating ROS packages to use privately in your own projects, you can create variants specific to your projects using the official variants as examples.
-To do so you need only create two files:
-
-#. A minimal variant package is created as a package with the ``ament_cmake`` build type, a ``buildtool_depend`` on ``ament_cmake`` and ``exec_depend`` entries for each package you want to include in the variant.
-
- .. code-block:: xml
-
-
-
-
- my_project_variant
- 1.0.0
- A package to aggregate all packages in my_project.
- Maintainer Name
- Apache-2.0
-
- my_project_msgs
- my_project_services
- my_project_examples
-
-
- ament_cmake
-
-
-
-#. A minimal ament_cmake package includes a ``CMakeLists.txt`` which registers the package.xml as an ament package for use in ROS 2.
-
- .. code-block:: cmake
-
- cmake_minimum_required(VERSION 3.20)
-
- project(my_project_variant NONE)
- find_package(ament_cmake REQUIRED)
- ament_package()
-
-You can then build and install your variant package alongside your other private packages.
-
-Creating custom variants with platform-specific tools
-*****************************************************
-
-Some platforms have tools for creating basic packages that do not require a full ROS build farm environment or equivalent infrastructure.
-It is possible to use these tools to create platform-dependent variants.
-This approach does not include support for ROS packaging tools and is platform dependent but requires much less infrastructure to produce if you are creating collections of existing packages rather than a mix of public and private ROS packages.
-For example, on Debian or Ubuntu systems you can use the ``equivs`` utilities.
-The Debian Administrator's handbook has a `Section on meta-packages `_.
+.. redirect-from::
+
+ How-To-Guides/Using-Variants
+
+Using variants
+==============
+
+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
+.. [#] https://help.ubuntu.com/community/MetaPackages
+
+The different variants in ROS 2 are specified in `REP-2001 `_.
+
+In addition to the official variants, there may be metapackages for specific institutions or robots as described in `REP-108 `_.
+
+Adding variants
+---------------
+
+Additional variants that are of general use to the ROS community can be proposed by contributing an update to `REP-2001 via pull request `_ describing the packages included in the new variant.
+Institution and robot specific variants can be published directly by their respective maintainers and no update to REP-2001 is required.
+
+Creating project-specific variants
+----------------------------------
+
+If you are creating ROS packages to use privately in your own projects, you can create variants specific to your projects using the official variants as examples.
+To do so you need only create two files:
+
+#. A minimal variant package is created as a package with the ``ament_cmake`` build type, a ``buildtool_depend`` on ``ament_cmake`` and ``exec_depend`` entries for each package you want to include in the variant.
+
+ .. code-block:: xml
+
+
+
+
+ my_project_variant
+ 1.0.0
+ A package to aggregate all packages in my_project.
+ Maintainer Name
+ Apache-2.0
+
+ my_project_msgs
+ my_project_services
+ my_project_examples
+
+
+ ament_cmake
+
+
+
+#. A minimal ament_cmake package includes a ``CMakeLists.txt`` which registers the package.xml as an ament package for use in ROS 2.
+
+ .. code-block:: cmake
+
+ cmake_minimum_required(VERSION 3.20)
+
+ project(my_project_variant NONE)
+ find_package(ament_cmake REQUIRED)
+ ament_package()
+
+You can then build and install your variant package alongside your other private packages.
+
+Creating custom variants with platform-specific tools
+*****************************************************
+
+Some platforms have tools for creating basic packages that do not require a full ROS build farm environment or equivalent infrastructure.
+It is possible to use these tools to create platform-dependent variants.
+This approach does not include support for ROS packaging tools and is platform dependent but requires much less infrastructure to produce if you are creating collections of existing packages rather than a mix of public and private ROS packages.
+For example, on Debian or Ubuntu systems you can use the ``equivs`` utilities.
+The Debian Administrator's handbook has a `Section on meta-packages `_.
\ No newline at end of file
diff --git a/source/Developer-Tools/Build/Using-Xacro-to-Clean-Up-a-URDF-File.rst b/source/Developer-Tools/Build/Using-Xacro-to-Clean-Up-a-URDF-File.rst
index 8d22b025085..e5a5b59b6de 100644
--- a/source/Developer-Tools/Build/Using-Xacro-to-Clean-Up-a-URDF-File.rst
+++ b/source/Developer-Tools/Build/Using-Xacro-to-Clean-Up-a-URDF-File.rst
@@ -1,284 +1,285 @@
-.. redirect-from::
-
- Tutorials/URDF/Using-Xacro-to-Clean-Up-a-URDF-File
-
-.. _URDFXacro:
-
-Using Xacro to clean up your code
-=================================
-
-**Goal:** Learn some tricks to reduce the amount of code in a URDF file using Xacro
-
-**Tutorial level:** Intermediate
-
-**Time:** 20 minutes
-
-.. contents:: Contents
- :depth: 2
- :local:
-
-By now, if you're following all these steps at home with your own robot design, you might be sick of doing all sorts of math to get very simple robot descriptions to parse correctly.
-Fortunately, you can use the `xacro `_ package to make your life simpler.
-It does three things that are very helpful.
-
- * Constants
- * Simple Math
- * Macros
-
-In this tutorial, we take a look at all these shortcuts to help reduce the overall size of the URDF file and make it easier to read and maintain.
-
-Using Xacro
------------
-As its name implies, `xacro `_ is a macro language for XML.
-The xacro program runs all of the macros and outputs the result.
-Typical usage looks something like this:
-
-.. code-block:: console
-
- $ xacro model.xacro > model.urdf
-
-You can also automatically generate the urdf in a launch file.
-This is convenient because it stays up to date and doesn't use up hard drive space.
-However, it does take time to generate, so be aware that your launch file might take longer to start up.
-
-To run xacro within your launch file, you need to put the ``Command`` substitution as a parameter to the ``robot_state_publisher``.
-
-.. code-block:: python
-
- path_to_urdf = get_package_share_path('turtlebot3_description') / 'urdf' / 'turtlebot3_burger.urdf'
- robot_state_publisher_node = launch_ros.actions.Node(
- package='robot_state_publisher',
- executable='robot_state_publisher',
- parameters=[{
- 'robot_description': ParameterValue(
- Command(['xacro ', str(path_to_urdf)]), value_type=str
- )
- }]
- )
-
-An easier way to load the robot model is to use the `urdf_launch `_ package to automatically load the xacro/urdf.
-
-.. literalinclude:: launch/urdf_display_launch.py
- :language: python
-
-At the top of the URDF file, you must specify a namespace in order for the file to parse properly.
-For example, these are the first two lines of a valid xacro file:
-
-.. code-block:: xml
-
-
-
-
-Constants
----------
-Let's take a quick look at our base_link in R2D2.
-
-.. code-block:: xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-The information here is a little redundant.
-We specify the length and radius of the cylinder twice.
-Worse, if we want to change that, we need to do so in two different places.
-
-Fortunately, xacro allows you to specify properties which act as constants.
-Instead, of the above code, we can write this.
-
-.. code-block:: xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-* The two values are specified in the first two lines.
- They can be defined just about anywhere (assuming valid XML), at any level, before or after they are used.
- Usually they go at the top.
-* Instead of specifying the actual radius in the geometry element, we use a dollar sign and curly brackets to signify the value.
-* This code will generate the same code shown above.
-
-The value of the contents of the ${} construct are then used to replace the ${}.
-This means you can combine it with other text in the attribute.
-
-.. code-block:: xml
-
-
-
-
-This will generate
-
-.. code-block:: xml
-
-
-
-However, the contents in the ${} don't have to only be a property, which brings us to our next point...
-
-Math
-----
-You can build up arbitrarily complex expressions in the ${} construct using the four basic operations (+,-,*,/), the unary minus, and parenthesis.
-Examples:
-
-.. code-block:: xml
-
-
-
-
-You can also use more than the basic mathematical operations, like ``sin`` and ``cos``.
-
-Macros
-------
-Here's the biggest and most useful component to the xacro package.
-
-Simple Macro
-^^^^^^^^^^^^
-Let's take a look at a simple useless macro.
-
-.. code-block:: xml
-
-
-
-
-
-
-(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
-
-
-
-* The name is not technically a required element, but you need to specify it to be able to use it.
-* Every instance of the ```` is replaced with the contents of the ``xacro:macro`` tag.
-* Note that even though its not exactly the same (the two attributes have switched order), the generated XML is equivalent.
-* If the xacro with a specified name is not found, it will not be expanded and will NOT generate an error.
-
-Parameterized Macro
-^^^^^^^^^^^^^^^^^^^
-You can also parameterize macros so that they don't generate the same exact text every time.
-When combined with the math functionality, this is even more powerful.
-
-First, let's take an example of a simple macro used in R2D2.
-
-.. code-block:: xml
-
-
-
-
-
-
-
-
-This can be used with the code
-
-.. code-block:: xml
-
-
-
-The parameters act just like properties, and you can use them in expressions
-
-You can also use entire blocks as parameters too.
-
-.. code-block:: xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-* To specify a block parameter, include an asterisk before its parameter name.
-* A block can be inserted using the insert_block command
-* Insert the block as many times as you wish.
-
-Practical Usage
----------------
-The xacro language is rather flexible in what it allows you to do.
-Here are a few useful ways that xacro is used in the `R2D2 model `_, in addition to the default inertial macro shown above.
-
-To see the model generated by a xacro file, run the same command as with previous tutorials:
-
-.. code-block:: console
-
- $ ros2 launch urdf_tutorial display.launch.py model:=urdf/08-macroed.urdf.xacro
-
-(The launch file has been running the xacro command this whole time, but since there were no macros to expand, it didn't matter)
-
-Leg macro
-^^^^^^^^^
-Often you want to create multiple similar looking objects in different locations.
-You can use a macro and some simple math to reduce the amount of code you have to write, like we do with R2's two legs.
-
-.. code-block:: xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-* Common Trick 1: Use a name prefix to get two similarly named objects.
-* Common Trick 2: Use math to calculate joint origins.
- In the case that you change the size of your robot, changing a property with some math to calculate the joint offset will save a lot of trouble.
-* Common Trick 3: Using a reflect parameter, and setting it to 1 or -1.
- See how we use the reflect parameter to put the legs on either side of the body in the base_to_${prefix}_leg origin.
+.. redirect-from::
+
+ Tutorials/URDF/Using-Xacro-to-Clean-Up-a-URDF-File
+ Tutorials/Intermediate/URDF/Using-Xacro-to-Clean-Up-a-URDF-File
+
+.. _URDFXacro:
+
+Using Xacro to clean up your code
+=================================
+
+**Goal:** Learn some tricks to reduce the amount of code in a URDF file using Xacro
+
+**Tutorial level:** Intermediate
+
+**Time:** 20 minutes
+
+.. contents:: Contents
+ :depth: 2
+ :local:
+
+By now, if you're following all these steps at home with your own robot design, you might be sick of doing all sorts of math to get very simple robot descriptions to parse correctly.
+Fortunately, you can use the `xacro `_ package to make your life simpler.
+It does three things that are very helpful.
+
+ * Constants
+ * Simple Math
+ * Macros
+
+In this tutorial, we take a look at all these shortcuts to help reduce the overall size of the URDF file and make it easier to read and maintain.
+
+Using Xacro
+-----------
+As its name implies, `xacro `_ is a macro language for XML.
+The xacro program runs all of the macros and outputs the result.
+Typical usage looks something like this:
+
+.. code-block:: console
+
+ $ xacro model.xacro > model.urdf
+
+You can also automatically generate the urdf in a launch file.
+This is convenient because it stays up to date and doesn't use up hard drive space.
+However, it does take time to generate, so be aware that your launch file might take longer to start up.
+
+To run xacro within your launch file, you need to put the ``Command`` substitution as a parameter to the ``robot_state_publisher``.
+
+.. code-block:: python
+
+ path_to_urdf = get_package_share_path('turtlebot3_description') / 'urdf' / 'turtlebot3_burger.urdf'
+ robot_state_publisher_node = launch_ros.actions.Node(
+ package='robot_state_publisher',
+ executable='robot_state_publisher',
+ parameters=[{
+ 'robot_description': ParameterValue(
+ Command(['xacro ', str(path_to_urdf)]), value_type=str
+ )
+ }]
+ )
+
+An easier way to load the robot model is to use the `urdf_launch `_ package to automatically load the xacro/urdf.
+
+.. literalinclude:: launch/urdf_display_launch.py
+ :language: python
+
+At the top of the URDF file, you must specify a namespace in order for the file to parse properly.
+For example, these are the first two lines of a valid xacro file:
+
+.. code-block:: xml
+
+
+
+
+Constants
+---------
+Let's take a quick look at our base_link in R2D2.
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+The information here is a little redundant.
+We specify the length and radius of the cylinder twice.
+Worse, if we want to change that, we need to do so in two different places.
+
+Fortunately, xacro allows you to specify properties which act as constants.
+Instead, of the above code, we can write this.
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+* The two values are specified in the first two lines.
+ They can be defined just about anywhere (assuming valid XML), at any level, before or after they are used.
+ Usually they go at the top.
+* Instead of specifying the actual radius in the geometry element, we use a dollar sign and curly brackets to signify the value.
+* This code will generate the same code shown above.
+
+The value of the contents of the ${} construct are then used to replace the ${}.
+This means you can combine it with other text in the attribute.
+
+.. code-block:: xml
+
+
+
+
+This will generate
+
+.. code-block:: xml
+
+
+
+However, the contents in the ${} don't have to only be a property, which brings us to our next point...
+
+Math
+----
+You can build up arbitrarily complex expressions in the ${} construct using the four basic operations (+,-,*,/), the unary minus, and parenthesis.
+Examples:
+
+.. code-block:: xml
+
+
+
+
+You can also use more than the basic mathematical operations, like ``sin`` and ``cos``.
+
+Macros
+------
+Here's the biggest and most useful component to the xacro package.
+
+Simple Macro
+^^^^^^^^^^^^
+Let's take a look at a simple useless macro.
+
+.. code-block:: xml
+
+
+
+
+
+
+(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
+
+
+
+* The name is not technically a required element, but you need to specify it to be able to use it.
+* Every instance of the ```` is replaced with the contents of the ``xacro:macro`` tag.
+* Note that even though its not exactly the same (the two attributes have switched order), the generated XML is equivalent.
+* If the xacro with a specified name is not found, it will not be expanded and will NOT generate an error.
+
+Parameterized Macro
+^^^^^^^^^^^^^^^^^^^
+You can also parameterize macros so that they don't generate the same exact text every time.
+When combined with the math functionality, this is even more powerful.
+
+First, let's take an example of a simple macro used in R2D2.
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+This can be used with the code
+
+.. code-block:: xml
+
+
+
+The parameters act just like properties, and you can use them in expressions
+
+You can also use entire blocks as parameters too.
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+* To specify a block parameter, include an asterisk before its parameter name.
+* A block can be inserted using the insert_block command
+* Insert the block as many times as you wish.
+
+Practical Usage
+---------------
+The xacro language is rather flexible in what it allows you to do.
+Here are a few useful ways that xacro is used in the `R2D2 model `_, in addition to the default inertial macro shown above.
+
+To see the model generated by a xacro file, run the same command as with previous tutorials:
+
+.. code-block:: console
+
+ $ ros2 launch urdf_tutorial display.launch.py model:=urdf/08-macroed.urdf.xacro
+
+(The launch file has been running the xacro command this whole time, but since there were no macros to expand, it didn't matter)
+
+Leg macro
+^^^^^^^^^
+Often you want to create multiple similar looking objects in different locations.
+You can use a macro and some simple math to reduce the amount of code you have to write, like we do with R2's two legs.
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+* Common Trick 1: Use a name prefix to get two similarly named objects.
+* Common Trick 2: Use math to calculate joint origins.
+ In the case that you change the size of your robot, changing a property with some math to calculate the joint offset will save a lot of trouble.
+* Common Trick 3: Using a reflect parameter, and setting it to 1 or -1.
+ See how we use the reflect parameter to put the legs on either side of the body in the base_to_${prefix}_leg origin.
\ No newline at end of file
diff --git a/source/Developer-Tools/Debugging/Building-ROS-2-with-Tracing.rst b/source/Developer-Tools/Debugging/Building-ROS-2-with-Tracing.rst
index 988e1486e06..7709c6608f5 100644
--- a/source/Developer-Tools/Debugging/Building-ROS-2-with-Tracing.rst
+++ b/source/Developer-Tools/Debugging/Building-ROS-2-with-Tracing.rst
@@ -1,102 +1,103 @@
-.. redirect-from::
-
- How-To-Guides/Building-ROS-2-with-Tracing-Instrumentation
-
-Building ROS 2 with tracing
-===========================
-
-.. contents:: Table of Contents
- :depth: 2
- :local:
-
-Tracing instrumentation is included in the ROS 2 source code, and Linux installations of ROS 2 include the LTTng tracer as a dependency.
-Therefore, ROS 2 can be traced out-of-the-box on Linux.
-
-However, ROS 2 can be built from source to remove the tracepoints or completely remove the instrumentation.
-This guide shows how to do that.
-For more information, see `the repository `__.
-
-.. note::
-
- This guide only applies to Linux systems.
-
-Prerequisites
--------------
-
-Set up your system to build ROS 2 from source.
-See :doc:`the source installation page <../Installation/Alternatives/Ubuntu-Development-Setup>` for more information.
-
-Build configurations
---------------------
-
-The ROS 2 tracing instrumentation is split into two components: function instrumentation and tracepoints.
-First, a ROS 2 core package (e.g., ``rclcpp``) calls a function provided by the ``tracetools`` package.
-Then, that function triggers a tracepoint, which records data if the tracepoint is enabled at runtime.
-
-By default, if the tracer is not `configured to trace or if the tracepoints are not enabled `__, they will have virtually no impact on the execution.
-However, the tracepoints can still be removed through a CMake option.
-Furthermore, the functions can be completely removed through a CMake option, which implies that tracepoints are also removed.
-
-Building without tracepoints
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This step depends on whether you are :doc:`building ROS 2 from source <../Installation/Alternatives/Ubuntu-Development-Setup>` or using ROS 2 binaries (:doc:`deb packages <../Installation/Ubuntu-Install-Debs>` or :doc:`binary archive <../Installation/Alternatives/Ubuntu-Install-Binary>`).
-To remove the tracepoints, (re)build ``tracetools`` and set the ``TRACETOOLS_TRACEPOINTS_EXCLUDED`` CMake option to ``ON``:
-
-.. tabs::
-
- .. group-tab:: Source installation
-
- .. code-block:: console
-
- $ cd ~/ros2_{DISTRO}
- $ colcon build --packages-select tracetools --cmake-clean-cache --cmake-args -DTRACETOOLS_TRACEPOINTS_EXCLUDED=ON
-
- .. group-tab:: Binary installation
-
- Clone the ``ros2_tracing`` repository into your workspace and build:
-
- .. code-block:: console
-
- $ cd ~/ws
- $ git clone https://github.com/ros2/ros2_tracing.git -b {DISTRO} src/ros2_tracing
- $ colcon build --packages-select tracetools --cmake-args -DTRACETOOLS_TRACEPOINTS_EXCLUDED=ON
-
-Building without instrumentation
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-To completely remove both tracepoints and function calls, :doc:`build ROS 2 from source <../Installation/Alternatives/Ubuntu-Development-Setup>` and set the ``TRACETOOLS_DISABLED`` CMake option to ``ON``:
-
-.. code-block:: console
-
- $ cd ~/ros2_{DISTRO}
- $ colcon build --cmake-args -DTRACETOOLS_DISABLED=ON --no-warn-unused-cli
-
-Validating
-----------
-
-Validate that tracing is disabled:
-
-.. code-block:: console
-
- $ cd ~/ws
- $ source install/setup.bash
- $ ros2 run tracetools status
-
-It should print out:
-
-.. tabs::
-
- .. group-tab:: Without tracepoints
-
- .. code-block:: bash
-
- Tracing disabled
-
- .. group-tab:: Without instrumentation
-
- .. code-block:: bash
-
- Tracing disabled through configuration
-
-If something else is printed, then something went wrong.
+.. redirect-from::
+
+ How-To-Guides/Building-ROS-2-with-Tracing-Instrumentation
+ How-To-Guides/Building-ROS-2-with-Tracing
+
+Building ROS 2 with tracing
+===========================
+
+.. contents:: Table of Contents
+ :depth: 2
+ :local:
+
+Tracing instrumentation is included in the ROS 2 source code, and Linux installations of ROS 2 include the LTTng tracer as a dependency.
+Therefore, ROS 2 can be traced out-of-the-box on Linux.
+
+However, ROS 2 can be built from source to remove the tracepoints or completely remove the instrumentation.
+This guide shows how to do that.
+For more information, see `the repository `__.
+
+.. note::
+
+ This guide only applies to Linux systems.
+
+Prerequisites
+-------------
+
+Set up your system to build ROS 2 from source.
+See :doc:`the source installation page <../../Get-Started/Installation/Alternatives/Ubuntu-Development-Setup>` for more information.
+
+Build configurations
+--------------------
+
+The ROS 2 tracing instrumentation is split into two components: function instrumentation and tracepoints.
+First, a ROS 2 core package (e.g., ``rclcpp``) calls a function provided by the ``tracetools`` package.
+Then, that function triggers a tracepoint, which records data if the tracepoint is enabled at runtime.
+
+By default, if the tracer is not `configured to trace or if the tracepoints are not enabled `__, they will have virtually no impact on the execution.
+However, the tracepoints can still be removed through a CMake option.
+Furthermore, the functions can be completely removed through a CMake option, which implies that tracepoints are also removed.
+
+Building without tracepoints
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This step depends on whether you are :doc:`building ROS 2 from source <../../Get-Started/Installation/Alternatives/Ubuntu-Development-Setup>` or using ROS 2 binaries (:doc:`deb packages <../../Get-Started/Installation/Ubuntu-Install-Debs>` or :doc:`binary archive <../../Get-Started/Installation/Alternatives/Ubuntu-Install-Binary>`).
+To remove the tracepoints, (re)build ``tracetools`` and set the ``TRACETOOLS_TRACEPOINTS_EXCLUDED`` CMake option to ``ON``:
+
+.. tabs::
+
+ .. group-tab:: Source installation
+
+ .. code-block:: console
+
+ $ cd ~/ros2_{DISTRO}
+ $ colcon build --packages-select tracetools --cmake-clean-cache --cmake-args -DTRACETOOLS_TRACEPOINTS_EXCLUDED=ON
+
+ .. group-tab:: Binary installation
+
+ Clone the ``ros2_tracing`` repository into your workspace and build:
+
+ .. code-block:: console
+
+ $ cd ~/ws
+ $ git clone https://github.com/ros2/ros2_tracing.git -b {DISTRO} src/ros2_tracing
+ $ colcon build --packages-select tracetools --cmake-args -DTRACETOOLS_TRACEPOINTS_EXCLUDED=ON
+
+Building without instrumentation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To completely remove both tracepoints and function calls, :doc:`build ROS 2 from source <../../Get-Started/Installation/Alternatives/Ubuntu-Development-Setup>` and set the ``TRACETOOLS_DISABLED`` CMake option to ``ON``:
+
+.. code-block:: console
+
+ $ cd ~/ros2_{DISTRO}
+ $ colcon build --cmake-args -DTRACETOOLS_DISABLED=ON --no-warn-unused-cli
+
+Validating
+----------
+
+Validate that tracing is disabled:
+
+.. code-block:: console
+
+ $ cd ~/ws
+ $ source install/setup.bash
+ $ ros2 run tracetools status
+
+It should print out:
+
+.. tabs::
+
+ .. group-tab:: Without tracepoints
+
+ .. code-block:: bash
+
+ Tracing disabled
+
+ .. group-tab:: Without instrumentation
+
+ .. code-block:: bash
+
+ Tracing disabled through configuration
+
+If something else is printed, then something went wrong.
\ No newline at end of file
diff --git a/source/Developer-Tools/Debugging/Debugging-Tf2-Problems.rst b/source/Developer-Tools/Debugging/Debugging-Tf2-Problems.rst
index 8c33936f203..0905580285f 100644
--- a/source/Developer-Tools/Debugging/Debugging-Tf2-Problems.rst
+++ b/source/Developer-Tools/Debugging/Debugging-Tf2-Problems.rst
@@ -1,318 +1,319 @@
-.. redirect-from::
-
- Tutorials/Tf2/Debugging-Tf2-Problems
-
-.. _DebuggingTf2Problems:
-
-Debugging
-=========
-
-**Goal:** Learn how to use a systematic approach for debugging tf2 related problems.
-
-**Tutorial level:** Intermediate
-
-**Time:** 10 minutes
-
-.. contents:: Contents
- :depth: 2
- :local:
-
-Background
-----------
-
-This tutorial walks you through the steps to debug a typical tf2 problem.
-It will also use many of the tf2 debugging tools, such as ``tf2_echo``, ``tf2_monitor``, and ``view_frames``.
-This tutorial assumes you have completed the :doc:`learning tf2 <./Tf2-Main>` tutorials.
-
-Debugging example
------------------
-
-1 Setting and starting the example
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-For this tutorial we will set up a demo application that has a number of problems.
-The goal of this tutorial is to apply a systematic approach to find and tackle these problems.
-First, let's create the source file.
-
-Go to the ``learning_tf2_cpp`` package we created in :doc:`tf2 tutorials <./Tf2-Main>`.
-Inside the ``src`` directory make a copy of the source file ``turtle_tf2_listener.cpp`` and rename it to ``turtle_tf2_listener_debug.cpp``.
-
-Open the file using your preferred text editor, and change line 65 from
-
-.. code-block:: C++
-
- std::string toFrameRel = "turtle2";
-
-to
-
-.. code-block:: C++
-
- std::string toFrameRel = "turtle3";
-
-and change ``lookupTransform()`` call in lines 73-77 from
-
-.. code-block:: C++
-
- try {
- t = tf_buffer_->lookupTransform(
- toFrameRel, fromFrameRel,
- tf2::TimePointZero);
- } catch (const tf2::TransformException & ex) {
-
-to
-
-.. code-block:: C++
-
- try {
- t = tf_buffer_->lookupTransform(
- toFrameRel, fromFrameRel,
- this->now());
- } catch (const tf2::TransformException & ex) {
-
-And save changes to the file.
-In order to run this demo, we need to create a launch file ``start_tf2_debug_demo_launch`` with extension ``.py``, ``.xml``, or ``.yaml`` in the ``launch`` subdirectory of package ``learning_tf2_cpp``:
-
-.. tabs::
-
- .. group-tab:: Python
-
- .. literalinclude:: launch/start_tf2_debug_demo_launch.py
- :language: python
-
- .. group-tab:: XML
-
- .. literalinclude:: launch/start_tf2_debug_demo_launch.xml
- :language: xml
-
- .. group-tab:: YAML
-
- .. literalinclude:: launch/start_tf2_debug_demo_launch.yaml
- :language: yaml
-
-Don't forget to add the ``turtle_tf2_listener_debug`` executable to the ``CMakeLists.txt`` and build the package.
-
-Now let's run it to see what happens:
-
-.. tabs::
-
- .. group-tab:: XML
-
- .. code-block:: console
-
- $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.xml
-
- .. group-tab:: YAML
-
- .. code-block:: console
-
- $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.yaml
-
- .. group-tab:: Python
-
- .. code-block:: console
-
- $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.py
-
-You will now see that the turtlesim came up.
-At the same time, if you run the ``turtle_teleop_key`` in another terminal window, you can use the arrow keys to drive the ``turtle1`` around.
-
-.. code-block:: console
-
- $ ros2 run turtlesim turtle_teleop_key
- [turtle_tf2_listener_debug-4] [INFO] [1630223454.942322623] [listener_debug]: Could not
- transform turtle3 to turtle1: "turtle3" passed to lookupTransform argument target_frame
- does not exist
-
-You will also notice that there is a second turtle in the lower, left corner.
-If the demo would be working correctly, this second turtle should be following the turtle you can command with the arrow keys.
-However, it is not the case because we have to solve some problems first.
-
-2 Finding the tf2 request
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Firstly, we need to find out what exactly we are asking tf2 to do.
-Therefore, we go into the part of the code that is using tf2.
-Open the ``src/turtle_tf2_listener_debug.cpp`` file, and take a look at line 65:
-
-.. code-block:: C++
-
- std::string toFrameRel = "turtle3";
-
-and lines 73-77:
-
-.. code-block:: C++
-
- try {
- t = tf_buffer_->lookupTransform(
- toFrameRel, fromFrameRel,
- this->now());
- } catch (const tf2::TransformException & ex) {
-
-Here we do the actual request to tf2.
-The three arguments tell us directly what we are asking tf2: transform from frame ``turtle3`` to frame ``turtle1`` at time ``now``.
-
-Now, let's take a look at why this request to tf2 is failing.
-
-3 Checking the frames
-^^^^^^^^^^^^^^^^^^^^^
-
-Firstly, to find out if tf2 knows about our transform between ``turtle3`` and ``turtle1``, we will use ``tf2_echo`` tool.
-
-.. code-block:: console
-
- $ ros2 run tf2_ros tf2_echo turtle3 turtle1
- [INFO] [1630223557.477636052] [tf2_echo]: Waiting for transform turtle3 -> turtle1:
- Invalid frame ID "turtle3" passed to canTransform argument target_frame - frame does
- not exist
-
-The output tells us that frame ``turtle3`` does not exist.
-
-Then what frames do exist?
-If you like to get a graphical representation of this, use ``view_frames`` tool.
-
-.. code-block:: console
-
- $ ros2 run tf2_tools view_frames
-
-Open the generated ``frames.pdf`` file to see the following output:
-
-.. image:: images/turtlesim_frames.png
-
-So obviously the problem is that we are requesting transform from frame ``turtle3``, which does not exist.
-To fix this bug, just replace ``turtle3`` with ``turtle2`` in line 65.
-
-And now stop the running demo, build it, and run it again:
-
-.. tabs::
-
- .. group-tab:: XML
-
- .. code-block:: console
-
- $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.xml
- [turtle_tf2_listener_debug-4] [INFO] [1630223704.617382464] [listener_debug]: Could not
- transform turtle2 to turtle1: Lookup would require extrapolation into the future. Requested
- time 1630223704.617054 but the latest data is at time 1630223704.616726, when looking up
- transform from frame [turtle1] to frame [turtle2]
-
- .. group-tab:: YAML
-
- .. code-block:: console
-
- $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.yaml
- [turtle_tf2_listener_debug-4] [INFO] [1630223704.617382464] [listener_debug]: Could not
- transform turtle2 to turtle1: Lookup would require extrapolation into the future. Requested
- time 1630223704.617054 but the latest data is at time 1630223704.616726, when looking up
- transform from frame [turtle1] to frame [turtle2]
-
- .. group-tab:: Python
-
- .. code-block:: console
-
- $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.py
- [turtle_tf2_listener_debug-4] [INFO] [1630223704.617382464] [listener_debug]: Could not
- transform turtle2 to turtle1: Lookup would require extrapolation into the future. Requested
- time 1630223704.617054 but the latest data is at time 1630223704.616726, when looking up
- transform from frame [turtle1] to frame [turtle2]
-
-And right away we run into the next problem.
-
-4 Checking the timestamp
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-Now that we solved the frame name problem, it is time to look at the timestamps.
-Remember, we are trying to get the transform between ``turtle2`` and ``turtle1`` at the current time (i.e., ``now``).
-To get statistics on the timing, call ``tf2_monitor`` with corresponding frames.
-
-.. code-block:: console
-
- $ ros2 run tf2_ros tf2_monitor turtle2 turtle1
- RESULTS: for turtle2 to turtle1
- Chain is: turtle1
- Net delay avg = 0.00287347: max = 0.0167241
-
- Frames:
- Frame: turtle1, published by , Average Delay: 0.000295833, Max Delay: 0.000755072
-
- All Broadcasters:
- Node: 125.246 Hz, Average Delay: 0.000290237 Max Delay: 0.000786781
-
-The key part here is the delay for the chain from ``turtle2`` to ``turtle1``.
-The output shows there is an average delay of about 3 milliseconds.
-This means that tf2 can only transform between the turtles after 3 milliseconds are passed.
-So, if we would be asking tf2 for the transformation between the turtles 3 milliseconds ago instead of ``now``, tf2 would be able to give us an answer sometimes.
-Let's test this quickly by changing lines 73-77 to:
-
-.. code-block:: C++
-
- try {
- t = tf_buffer_->lookupTransform(
- toFrameRel, fromFrameRel,
- this->now() - rclcpp::Duration::from_seconds(0.1));
- } catch (const tf2::TransformException & ex) {
-
-In the new code we are asking for the transform between the turtles 100 milliseconds ago.
-It is usual to use a longer periods, just to make sure that the transform will arrive.
-Stop the demo, build and run:
-
-.. tabs::
-
- .. group-tab:: XML
-
- .. code-block:: console
-
- $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.xml
-
- .. group-tab:: YAML
-
- .. code-block:: console
-
- $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.yaml
-
- .. group-tab:: Python
-
- .. code-block:: console
-
- $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.py
-
-And you should finally see the turtle move!
-
-.. image:: images/turtlesim_follow1.png
-
-That last fix we made is not really what you want to do, it was just to make sure that was our problem.
-The real fix would look like this:
-
-.. code-block:: C++
-
- try {
- t = tf_buffer_->lookupTransform(
- toFrameRel, fromFrameRel,
- tf2::TimePointZero);
- } catch (const tf2::TransformException & ex) {
-
-Or like this:
-
-.. code-block:: C++
-
- try {
- t = tf_buffer_->lookupTransform(
- toFrameRel, fromFrameRel,
- tf2::TimePoint());
- } catch (const tf2::TransformException & ex) {
-
-You can learn more about timeouts in the :doc:`Using time <./Learning-About-Tf2-And-Time-Cpp>` tutorial, and use them as below:
-
-.. code-block:: C++
-
- try {
- t = tf_buffer_->lookupTransform(
- toFrameRel, fromFrameRel,
- this->now(),
- rclcpp::Duration::from_seconds(0.05));
- } catch (const tf2::TransformException & ex) {
-
-Summary
--------
-
-In this tutorial you learned how to use a systematic approach for debugging tf2 related problems.
-You also learned how to use tf2 debugging tools, such as ``tf2_echo``, ``tf2_monitor``, and ``view_frames`` to help you debug those tf2 problems.
+.. redirect-from::
+
+ Tutorials/Tf2/Debugging-Tf2-Problems
+ Tutorials/Intermediate/Tf2/Debugging-Tf2-Problems
+
+.. _DebuggingTf2Problems:
+
+Debugging
+=========
+
+**Goal:** Learn how to use a systematic approach for debugging tf2 related problems.
+
+**Tutorial level:** Intermediate
+
+**Time:** 10 minutes
+
+.. contents:: Contents
+ :depth: 2
+ :local:
+
+Background
+----------
+
+This tutorial walks you through the steps to debug a typical tf2 problem.
+It will also use many of the tf2 debugging tools, such as ``tf2_echo``, ``tf2_monitor``, and ``view_frames``.
+This tutorial assumes you have completed the :doc:`learning tf2 <../../ROS-Framework/client-libraries/Working-with-Client-Libraries/Tf2/Tf2-Main>` tutorials.
+
+Debugging example
+-----------------
+
+1 Setting and starting the example
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For this tutorial we will set up a demo application that has a number of problems.
+The goal of this tutorial is to apply a systematic approach to find and tackle these problems.
+First, let's create the source file.
+
+Go to the ``learning_tf2_cpp`` package we created in :doc:`tf2 tutorials <../../ROS-Framework/client-libraries/Working-with-Client-Libraries/Tf2/Tf2-Main>`.
+Inside the ``src`` directory make a copy of the source file ``turtle_tf2_listener.cpp`` and rename it to ``turtle_tf2_listener_debug.cpp``.
+
+Open the file using your preferred text editor, and change line 65 from
+
+.. code-block:: C++
+
+ std::string toFrameRel = "turtle2";
+
+to
+
+.. code-block:: C++
+
+ std::string toFrameRel = "turtle3";
+
+and change ``lookupTransform()`` call in lines 73-77 from
+
+.. code-block:: C++
+
+ try {
+ t = tf_buffer_->lookupTransform(
+ toFrameRel, fromFrameRel,
+ tf2::TimePointZero);
+ } catch (const tf2::TransformException & ex) {
+
+to
+
+.. code-block:: C++
+
+ try {
+ t = tf_buffer_->lookupTransform(
+ toFrameRel, fromFrameRel,
+ this->now());
+ } catch (const tf2::TransformException & ex) {
+
+And save changes to the file.
+In order to run this demo, we need to create a launch file ``start_tf2_debug_demo_launch`` with extension ``.py``, ``.xml``, or ``.yaml`` in the ``launch`` subdirectory of package ``learning_tf2_cpp``:
+
+.. tabs::
+
+ .. group-tab:: Python
+
+ .. literalinclude:: launch/start_tf2_debug_demo_launch.py
+ :language: python
+
+ .. group-tab:: XML
+
+ .. literalinclude:: launch/start_tf2_debug_demo_launch.xml
+ :language: xml
+
+ .. group-tab:: YAML
+
+ .. literalinclude:: launch/start_tf2_debug_demo_launch.yaml
+ :language: yaml
+
+Don't forget to add the ``turtle_tf2_listener_debug`` executable to the ``CMakeLists.txt`` and build the package.
+
+Now let's run it to see what happens:
+
+.. tabs::
+
+ .. group-tab:: XML
+
+ .. code-block:: console
+
+ $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.xml
+
+ .. group-tab:: YAML
+
+ .. code-block:: console
+
+ $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.yaml
+
+ .. group-tab:: Python
+
+ .. code-block:: console
+
+ $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.py
+
+You will now see that the turtlesim came up.
+At the same time, if you run the ``turtle_teleop_key`` in another terminal window, you can use the arrow keys to drive the ``turtle1`` around.
+
+.. code-block:: console
+
+ $ ros2 run turtlesim turtle_teleop_key
+ [turtle_tf2_listener_debug-4] [INFO] [1630223454.942322623] [listener_debug]: Could not
+ transform turtle3 to turtle1: "turtle3" passed to lookupTransform argument target_frame
+ does not exist
+
+You will also notice that there is a second turtle in the lower, left corner.
+If the demo would be working correctly, this second turtle should be following the turtle you can command with the arrow keys.
+However, it is not the case because we have to solve some problems first.
+
+2 Finding the tf2 request
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Firstly, we need to find out what exactly we are asking tf2 to do.
+Therefore, we go into the part of the code that is using tf2.
+Open the ``src/turtle_tf2_listener_debug.cpp`` file, and take a look at line 65:
+
+.. code-block:: C++
+
+ std::string toFrameRel = "turtle3";
+
+and lines 73-77:
+
+.. code-block:: C++
+
+ try {
+ t = tf_buffer_->lookupTransform(
+ toFrameRel, fromFrameRel,
+ this->now());
+ } catch (const tf2::TransformException & ex) {
+
+Here we do the actual request to tf2.
+The three arguments tell us directly what we are asking tf2: transform from frame ``turtle3`` to frame ``turtle1`` at time ``now``.
+
+Now, let's take a look at why this request to tf2 is failing.
+
+3 Checking the frames
+^^^^^^^^^^^^^^^^^^^^^
+
+Firstly, to find out if tf2 knows about our transform between ``turtle3`` and ``turtle1``, we will use ``tf2_echo`` tool.
+
+.. code-block:: console
+
+ $ ros2 run tf2_ros tf2_echo turtle3 turtle1
+ [INFO] [1630223557.477636052] [tf2_echo]: Waiting for transform turtle3 -> turtle1:
+ Invalid frame ID "turtle3" passed to canTransform argument target_frame - frame does
+ not exist
+
+The output tells us that frame ``turtle3`` does not exist.
+
+Then what frames do exist?
+If you like to get a graphical representation of this, use ``view_frames`` tool.
+
+.. code-block:: console
+
+ $ ros2 run tf2_tools view_frames
+
+Open the generated ``frames.pdf`` file to see the following output:
+
+.. image:: images/turtlesim_frames.png
+
+So obviously the problem is that we are requesting transform from frame ``turtle3``, which does not exist.
+To fix this bug, just replace ``turtle3`` with ``turtle2`` in line 65.
+
+And now stop the running demo, build it, and run it again:
+
+.. tabs::
+
+ .. group-tab:: XML
+
+ .. code-block:: console
+
+ $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.xml
+ [turtle_tf2_listener_debug-4] [INFO] [1630223704.617382464] [listener_debug]: Could not
+ transform turtle2 to turtle1: Lookup would require extrapolation into the future. Requested
+ time 1630223704.617054 but the latest data is at time 1630223704.616726, when looking up
+ transform from frame [turtle1] to frame [turtle2]
+
+ .. group-tab:: YAML
+
+ .. code-block:: console
+
+ $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.yaml
+ [turtle_tf2_listener_debug-4] [INFO] [1630223704.617382464] [listener_debug]: Could not
+ transform turtle2 to turtle1: Lookup would require extrapolation into the future. Requested
+ time 1630223704.617054 but the latest data is at time 1630223704.616726, when looking up
+ transform from frame [turtle1] to frame [turtle2]
+
+ .. group-tab:: Python
+
+ .. code-block:: console
+
+ $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.py
+ [turtle_tf2_listener_debug-4] [INFO] [1630223704.617382464] [listener_debug]: Could not
+ transform turtle2 to turtle1: Lookup would require extrapolation into the future. Requested
+ time 1630223704.617054 but the latest data is at time 1630223704.616726, when looking up
+ transform from frame [turtle1] to frame [turtle2]
+
+And right away we run into the next problem.
+
+4 Checking the timestamp
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Now that we solved the frame name problem, it is time to look at the timestamps.
+Remember, we are trying to get the transform between ``turtle2`` and ``turtle1`` at the current time (i.e., ``now``).
+To get statistics on the timing, call ``tf2_monitor`` with corresponding frames.
+
+.. code-block:: console
+
+ $ ros2 run tf2_ros tf2_monitor turtle2 turtle1
+ RESULTS: for turtle2 to turtle1
+ Chain is: turtle1
+ Net delay avg = 0.00287347: max = 0.0167241
+
+ Frames:
+ Frame: turtle1, published by , Average Delay: 0.000295833, Max Delay: 0.000755072
+
+ All Broadcasters:
+ Node: 125.246 Hz, Average Delay: 0.000290237 Max Delay: 0.000786781
+
+The key part here is the delay for the chain from ``turtle2`` to ``turtle1``.
+The output shows there is an average delay of about 3 milliseconds.
+This means that tf2 can only transform between the turtles after 3 milliseconds are passed.
+So, if we would be asking tf2 for the transformation between the turtles 3 milliseconds ago instead of ``now``, tf2 would be able to give us an answer sometimes.
+Let's test this quickly by changing lines 73-77 to:
+
+.. code-block:: C++
+
+ try {
+ t = tf_buffer_->lookupTransform(
+ toFrameRel, fromFrameRel,
+ this->now() - rclcpp::Duration::from_seconds(0.1));
+ } catch (const tf2::TransformException & ex) {
+
+In the new code we are asking for the transform between the turtles 100 milliseconds ago.
+It is usual to use a longer periods, just to make sure that the transform will arrive.
+Stop the demo, build and run:
+
+.. tabs::
+
+ .. group-tab:: XML
+
+ .. code-block:: console
+
+ $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.xml
+
+ .. group-tab:: YAML
+
+ .. code-block:: console
+
+ $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.yaml
+
+ .. group-tab:: Python
+
+ .. code-block:: console
+
+ $ ros2 launch learning_tf2_cpp start_tf2_debug_demo_launch.py
+
+And you should finally see the turtle move!
+
+.. image:: images/turtlesim_follow1.png
+
+That last fix we made is not really what you want to do, it was just to make sure that was our problem.
+The real fix would look like this:
+
+.. code-block:: C++
+
+ try {
+ t = tf_buffer_->lookupTransform(
+ toFrameRel, fromFrameRel,
+ tf2::TimePointZero);
+ } catch (const tf2::TransformException & ex) {
+
+Or like this:
+
+.. code-block:: C++
+
+ try {
+ t = tf_buffer_->lookupTransform(
+ toFrameRel, fromFrameRel,
+ tf2::TimePoint());
+ } catch (const tf2::TransformException & ex) {
+
+You can learn more about timeouts in the :doc:`Using time <../../ROS-Framework/client-libraries/Working-with-Client-Libraries/Tf2/Learning-About-Tf2-And-Time-Cpp>` tutorial, and use them as below:
+
+.. code-block:: C++
+
+ try {
+ t = tf_buffer_->lookupTransform(
+ toFrameRel, fromFrameRel,
+ this->now(),
+ rclcpp::Duration::from_seconds(0.05));
+ } catch (const tf2::TransformException & ex) {
+
+Summary
+-------
+
+In this tutorial you learned how to use a systematic approach for debugging tf2 related problems.
+You also learned how to use tf2 debugging tools, such as ``tf2_echo``, ``tf2_monitor``, and ``view_frames`` to help you debug those tf2 problems.
\ No newline at end of file
diff --git a/source/Developer-Tools/Debugging/Getting-Backtraces-in-ROS-2.rst b/source/Developer-Tools/Debugging/Getting-Backtraces-in-ROS-2.rst
index c66f5799d7e..adfe1a01a96 100644
--- a/source/Developer-Tools/Debugging/Getting-Backtraces-in-ROS-2.rst
+++ b/source/Developer-Tools/Debugging/Getting-Backtraces-in-ROS-2.rst
@@ -1,353 +1,357 @@
-Getting Backtraces in ROS 2
-###########################
-
-.. contents:: Table of Contents
- :local:
-
-**Goal:** Show various methods for getting backtraces in ROS 2
-
-**Tutorial level:** Intermediate
-
-**Time:** 15 minutes
-
-The following steps show ROS 2 users how to get backtraces when they encounter a problem.
-
-Overview
---------
-
-**What is a Backtrace ?**
-
-- Imagine your program is like a stack of pancakes where each pancake represents a function it's currently executing.
- A backtrace is like a photo of the collapsed pancake stack, showing you the order they were in, revealing how the program ended up with the failure.
-- It lists out the sequence of functions that were called, one on top of the other, leading up to the point of failure.
-
-**Why is it Useful?**
-
-- **Pinpoints the Problem:** Instead of guessing where in your code an error occurred, the backtrace shows you the exact line number responsible for the crash.
-- **Reveals Context:** You can see the chain of events (functions calling other functions) that ultimately triggered the failure.
- This helps you understand not just where things went wrong, but also why.
-
-**Visual Analogy**: Stack of Pancakes
-
-1. Each Pancake is a Function: Imagine each pancake in a stack represents a function that your program is currently executing.
- The pancake at the bottom is your main() function, where it all begins.
-
-2. Adding Pancakes: Every time a function calls another function, a new pancake is placed on top of the stack.
-
-3. The Crash: A crash is like the plate slipping out from the bottom of the stack – something went disastrously wrong in the function currently executing.
-
-4. The Backtrace: The backtrace is like a photo of that fallen pancake stack.
- It shows the order of pancakes (functions) from top to bottom, revealing how you ended up at the crash site.
-
-
-**Code Example:**
-
-.. code-block:: cpp
-
- void functionC() {
- // Something bad happens here, causing a crash
- }
-
- void functionB() {
- functionC();
- }
-
- void functionA() {
- functionB();
- }
-
- int main() {
- functionA();
- return 0;
- }
-
-**Backtrace from the Crash:**
-
-.. code-block:: bash
-
- #0 functionC() at file.cpp:3 // Crash occurred here
- #1 functionB() at file.cpp:8
- #2 functionA() at file.cpp:13
- #3 main() at file.cpp:18
-
-**How the Backtrace Helps:**
-
-- **Crash Origin:** Shows you the exact line in ``functionC()`` that triggered the crash.
-- **Call Sequence:** Reveals that ``main()`` called ``functionA()``, which called ``functionB()``, which ultimately led to the error in ``functionC()``.
-
-The above example gave us a clear picture of what is a backtrace and how it can be useful.
-Now, the following steps show ROS 2 users how to get traces from specific nodes when they encounter a problem.
-This tutorial applies to both simulated and physical robots.
-
-This will cover how to get a backtrace from a specific node using ``ros2 run``, from a launch file representing a single node using ``ros2 launch``, and from a more complex orchestration of nodes.
-By the end of this tutorial, you should be able to get a backtrace when you notice a node crashing in ROS 2.
-
-Preliminaries
--------------
-
-GDB is the most popular debugger for C/C++ on Unix systems.
-It can be used to determine the reason for a crash and track threads.
-It may also be used to add breakpoints in your code to check values in memory at particular points in your software.
-
-Using GDB is a critical skill for all software developers working on C/C++.
-While many IDEs have some kind of debugger or profiler built in, it is important to understand how to use these raw tools you have available rather than relying on an IDE to provide them.
-Understanding these tools is a fundamental skill of C/C++ development and leaving it up to your IDE can be problematic if you change roles and no longer have access to it or are doing development on the fly through an ssh session to a remote asset.
-
-Using GDB luckily is fairly simple after you have the basics under your belt.
-Here's how to ensure your ROS2 code is ready for debugging:
-
-- By using ``--cmake-args``: The easiest way to include debug symbols is by adding ``--cmake-args -DCMAKE_BUILD_TYPE=Debug`` to your ``colcon build`` command:
-
-.. code-block:: console
-
- $ colcon build --packages-up-to --cmake-args -DCMAKE_BUILD_TYPE=Debug
-
-- By editing ``CMakeLists.txt`` : Another way is to add ``-g`` to your compiler flags for the ROS package you want to profile / debug.
- This flag builds debug symbols that GDB can read to tell you specific lines of code in your project are failing and why.
- If you do not set this flag, you can still get backtraces but it will not provide line numbers for failures.
-
-Now you're ready to debug your code!
-If this was a non-ROS project, at this point you might do something like below.
-Here we're launching a GDB session and telling our program to immediately run.
-Once your program crashes, it will return a gdb session prompt denoted by ``(gdb)``.
-At this prompt you can access the information you're interested in.
-However, since this is a ROS project with lots of node configurations and other things going on, this isn't a great option for beginners or those that don't like tons of commandline work and understanding the filesystem.
-
-.. code-block:: console
-
- $ gdb ex run --args /path/to/exe/program
-
-Below are sections to describe the three major situations you could run into with ROS 2-based systems.
-Read the section that best describes the problem you're attempting to solve.
-
-Debugging a specific node with GDB
-----------------------------------
-
-To easily set up a GDB session before launching a ROS 2 node, leverage the ``--prefix`` option to easily set up a GDB session before launching a ROS 2 node.
-For GDB debugging, use it as follows:
-
-.. note::
-
- Keep in mind that a ROS 2 executable might contain multiple nodes.
- The ``--prefix`` approach ensures you're debugging the correct node within the process.
-
-**Why Direct GDB Usage Can Be Tricky**
-
-``--prefix`` will execute some bits of code before our ROS 2 command allowing us to insert some information.
-If you attempted to do ``gdb ex run --args ros2 run `` as analog to our example in the preliminaries, you'd find that it couldn't find the ``ros2`` command.
-Additionally, trying to source your workspace within GDB would fail for similar reasons.
-This is because GDB, when launched this way, lacks the environment setup that normally makes the ``ros2`` command available.
-
-**Simplifying the Process with --prefix**
-
-Rather than having to revert to finding the install path of the executable and typing it all out, we can instead use ``--prefix``.
-This allows us to use the same ``ros2 run`` syntax you're used to without having to worry about some of the GDB details.
-
-.. code-block:: console
-
- $ ros2 run --prefix 'gdb -ex run --args' --all-other-launch arguments
-
-**The GDB Experience**
-
-Just as before, this prefix will launch a GDB session and run the node you requested with all the additional command-line arguments.
-You should now have your node running and should be chugging along with some debug printing.
-
-Reading the Stack Trace
------------------------
-
-After you obtain a backtrace using GDB, here's how to interpret it:
-
-- Start at the Bottom: Backtraces list function calls in reverse chronological order.
- The function at the bottom is where the crash originates.
-
-- Follow the Stack Upwards: Each line above represents the function that called the function below it.
- Trace upwards until you reach a line of code within your own project.
- This often reveals where the problem initiated.
-
-- Debugging Clues: Function names and their arguments can provide valuable clues about what went wrong.
-
-**How to Debug once your Node Crashes**
-
-Once your node crashes, you'll see a prompt like below.
-At this point you can get a backtrace.
-
-.. code-block:: bash
-
- (gdb)
-
-In this session, type ``backtrace`` and it will provide you with a backtrace.
-Copy this for your needs.
-
-
-**Example backtrace**
-
-.. code-block:: bash
-
- (gdb) backtrace
- #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
- #1 0x00007ffff79cc859 in __GI_abort () at abort.c:79
- #2 0x00007ffff7c52951 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
- #3 0x00007ffff7c5e47c in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
- #4 0x00007ffff7c5e4e7 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
- #5 0x00007ffff7c5e799 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
- #6 0x00007ffff7c553eb in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
- #7 0x000055555555936c in std::vector >::_M_range_check (
- this=0x5555555cfdb0, __n=100) at /usr/include/c++/9/bits/stl_vector.h:1070
- #8 0x0000555555558e1d in std::vector >::at (this=0x5555555cfdb0,
- __n=100) at /usr/include/c++/9/bits/stl_vector.h:1091
- #9 0x000055555555828b in GDBTester::VectorCrash (this=0x5555555cfb40)
- at /home/steve/Documents/nav2_ws/src/gdb_test_pkg/src/gdb_test_node.cpp:44
- #10 0x0000555555559cfc in main (argc=1, argv=0x7fffffffc108)
- at /home/steve/Documents/nav2_ws/src/gdb_test_pkg/src/main.cpp:25
-
-In this example you should read this in the following way, starting at the bottom:
-
-- In the main function, on line 25 we call a function VectorCrash.
-
-- In VectorCrash, on line 44, we crashed in the Vector's ``at()`` method with input ``100``.
-
-- It crashed in ``at()`` on STL vector line 1091 after throwing an exception from a range check failure.
-
-These traces take some time to get used to reading, but in general, start at the bottom and follow it up the stack until you see the line it crashed on.
-Then you can deduce why it crashed.
-When you are done with GDB, type ``quit`` and it will exit the session and kill any processes still up.
-It may ask you if you want to kill some threads at the end, say yes.
-
-From a Launch File
-------------------
-
-Just as in our non-ROS example, we need to setup a GDB session before launching our ROS 2 launch file.
-While we could set this up through the commandline, we can instead make use of the same mechanics that we did in the ``ros2 run`` node example, now using a launch file.
-
-In your launch file, find the node that you're interested in debugging.
-For this section, we assume that your launch file contains only a single node (and potentially other information as well).
-The ``Node`` function used in the ``launch_ros`` package will take in a field prefix taking a list of prefix arguments.
-We will insert the GDB snippet here.
-
-**Consider the following approaches, depending on your setup:**
-
-- **Local Debugging with GUI :** If you are debugging locally and have a GUI system available, use:
-
-.. code-block:: python
-
- prefix=['xterm -e gdb -ex run --args']
-
-This will provide a more interactive debugging experience.
-Example usecase for debugging building upon ``'start_sync_slam_toolbox_node'`` -
-
-.. code-block:: python
-
- start_sync_slam_toolbox_node = Node(
- parameters=[
- get_package_share_directory("slam_toolbox") + '/config/mapper_params_online_sync.yaml',
- {'use_sim_time': use_sim_time}
- ],
- package='slam_toolbox',
- executable='sync_slam_toolbox_node',
- name='slam_toolbox',
- prefix=['xterm -e gdb -ex run --args'], # For interactive GDB in a separate window/GUI
- output='screen')
-
-- **Remote Debugging (without GUI):** If debugging without GUI, omit ``xterm -e`` :
-
-.. code-block:: bash
-
- prefix=['gdb -ex run --args']
-
-GDB's output and interaction will happen within the terminal session where you launched the ROS 2 application.
-Here's an similar example for the ``'start_sync_slam_toolbox_node'`` -
-
-.. code-block:: python
-
- start_sync_slam_toolbox_node = Node(
- parameters=[
- get_package_share_directory("slam_toolbox") + '/config/mapper_params_online_sync.yaml',
- {'use_sim_time': use_sim_time}
- ],
- package='slam_toolbox',
- executable='sync_slam_toolbox_node',
- name='slam_toolbox',
- prefix=['gdb -ex run --args'], # For GDB within the launch terminal
- output='screen')
-
-Just as before, this prefix will launch a GDB session, now in ``xterm`` and run the launch file you requested with all the additional launch arguments defined.
-
-Once your node crashes, you'll see a prompt like below, now in the ``xterm`` session.
-At this point you can now get a backtrace, and read it using the instructions in `Reading the Stack Trace`_.
-
-From a Large Project
---------------------
-Working with launch files with multiple nodes is a little different so you can interact with your GDB session without being bogged down by other logging in the same terminal.
-For this reason, when working with larger launch files, it is a good idea to pull out the specific node you're interested in and launch it separately.
-
-If your node of interest is being launched from a nested launch file (e.g. an included launch file) you may want to do the following:
-
-- Comment out the launch file inclusion from the parent launch file
-
-- Recompile the package of interest with ``-g`` flag for debug symbols
-
-- Launch the parent launch file in a terminal
-
-- Launch the node's launch file in another terminal following the instructions in `From a Launch File`_.
-
-Alternatively, if your node of interest is being launched in these files directly (e.g. you see a ``Node``, ``LifecycleNode``, or inside a ``ComponentContainer``), you will need to separate this from the others:
-
-- Comment out the node's inclusion from the parent launch file
-
-- Recompile the package of interest with ``-g`` flag for debug symbols
-
-- Launch the parent launch file in a terminal
-
-- Launch the node in another terminal following the instructions in `Debugging a specific node with GDB`_.
-
-.. note::
-
- In this case you may need to remap or provide parameter files to this node if it was previously provided by the launch file.
- Using ``--ros-args`` you can give it the path to the new parameters file, remaps, or names.
- See :doc:`this tutorial <../../How-To-Guides/Node-arguments>` for the commandline arguments required.
-
- We understand this can be a pain, so it might encourage you to rather have each node possible as a separately included launch file to make debugging easier.
- An example set of arguments might be ``--ros-args -r __node:= --params-file /absolute/path/to/params.yaml`` (as a template).
-
-Once your node crashes, you'll see a prompt like below in the terminal of the specific node.
-At this point you can now get a backtrace, and read it using the instructions in `Reading the Stack Trace`_.
-
-Debugging tests with GDB
-------------------------
-
-If a C++ test is failing, GDB can be used directly on the test executable in the build directory.
-Ensure to build the code in debug mode.
-Since the previous build type may be cached by CMake, clean the cache and rebuild.
-
-.. code-block:: console
-
- $ colcon build --cmake-clean-cache --mixin debug
-
-In order for GDB to load debug symbols for any shared libraries called, make sure to source your environment.
-This configures the value of ``LD_LIBRARY_PATH``.
-
-.. code-block:: console
-
- $ source install/setup.bash
-
-Finally, run the test directly through GDB.
-For example:
-
-.. code-block:: console
-
- $ gdb -ex run ./build/rcl/test/test_logging
-
-If the code is throwing an unhandled exception, you can catch it in GDB before gtest handles it.
-
-.. code-block:: console
-
- $ gdb ./build/rcl/test/test_logging
- $ catch throw
- $ run
-
-Automatic backtrace on crash
-----------------------------
-
-The `backward-cpp `_ library provides beautiful stack traces, and the `backward_ros `_ wrapper simplifies its integration.
-
-Just add it as a dependency and ``find_package`` it in your CMakeLists and the backward libraries will be injected in all your executables and libraries.
+.. redirect-from::
+
+ How-To-Guides/Getting-Backtraces-in-ROS-2
+
+Getting Backtraces in ROS 2
+###########################
+
+.. contents:: Table of Contents
+ :local:
+
+**Goal:** Show various methods for getting backtraces in ROS 2
+
+**Tutorial level:** Intermediate
+
+**Time:** 15 minutes
+
+The following steps show ROS 2 users how to get backtraces when they encounter a problem.
+
+Overview
+--------
+
+**What is a Backtrace ?**
+
+- Imagine your program is like a stack of pancakes where each pancake represents a function it's currently executing.
+ A backtrace is like a photo of the collapsed pancake stack, showing you the order they were in, revealing how the program ended up with the failure.
+- It lists out the sequence of functions that were called, one on top of the other, leading up to the point of failure.
+
+**Why is it Useful?**
+
+- **Pinpoints the Problem:** Instead of guessing where in your code an error occurred, the backtrace shows you the exact line number responsible for the crash.
+- **Reveals Context:** You can see the chain of events (functions calling other functions) that ultimately triggered the failure.
+ This helps you understand not just where things went wrong, but also why.
+
+**Visual Analogy**: Stack of Pancakes
+
+1. Each Pancake is a Function: Imagine each pancake in a stack represents a function that your program is currently executing.
+ The pancake at the bottom is your main() function, where it all begins.
+
+2. Adding Pancakes: Every time a function calls another function, a new pancake is placed on top of the stack.
+
+3. The Crash: A crash is like the plate slipping out from the bottom of the stack – something went disastrously wrong in the function currently executing.
+
+4. The Backtrace: The backtrace is like a photo of that fallen pancake stack.
+ It shows the order of pancakes (functions) from top to bottom, revealing how you ended up at the crash site.
+
+
+**Code Example:**
+
+.. code-block:: cpp
+
+ void functionC() {
+ // Something bad happens here, causing a crash
+ }
+
+ void functionB() {
+ functionC();
+ }
+
+ void functionA() {
+ functionB();
+ }
+
+ int main() {
+ functionA();
+ return 0;
+ }
+
+**Backtrace from the Crash:**
+
+.. code-block:: bash
+
+ #0 functionC() at file.cpp:3 // Crash occurred here
+ #1 functionB() at file.cpp:8
+ #2 functionA() at file.cpp:13
+ #3 main() at file.cpp:18
+
+**How the Backtrace Helps:**
+
+- **Crash Origin:** Shows you the exact line in ``functionC()`` that triggered the crash.
+- **Call Sequence:** Reveals that ``main()`` called ``functionA()``, which called ``functionB()``, which ultimately led to the error in ``functionC()``.
+
+The above example gave us a clear picture of what is a backtrace and how it can be useful.
+Now, the following steps show ROS 2 users how to get traces from specific nodes when they encounter a problem.
+This tutorial applies to both simulated and physical robots.
+
+This will cover how to get a backtrace from a specific node using ``ros2 run``, from a launch file representing a single node using ``ros2 launch``, and from a more complex orchestration of nodes.
+By the end of this tutorial, you should be able to get a backtrace when you notice a node crashing in ROS 2.
+
+Preliminaries
+-------------
+
+GDB is the most popular debugger for C/C++ on Unix systems.
+It can be used to determine the reason for a crash and track threads.
+It may also be used to add breakpoints in your code to check values in memory at particular points in your software.
+
+Using GDB is a critical skill for all software developers working on C/C++.
+While many IDEs have some kind of debugger or profiler built in, it is important to understand how to use these raw tools you have available rather than relying on an IDE to provide them.
+Understanding these tools is a fundamental skill of C/C++ development and leaving it up to your IDE can be problematic if you change roles and no longer have access to it or are doing development on the fly through an ssh session to a remote asset.
+
+Using GDB luckily is fairly simple after you have the basics under your belt.
+Here's how to ensure your ROS2 code is ready for debugging:
+
+- By using ``--cmake-args``: The easiest way to include debug symbols is by adding ``--cmake-args -DCMAKE_BUILD_TYPE=Debug`` to your ``colcon build`` command:
+
+.. code-block:: console
+
+ $ colcon build --packages-up-to --cmake-args -DCMAKE_BUILD_TYPE=Debug
+
+- By editing ``CMakeLists.txt`` : Another way is to add ``-g`` to your compiler flags for the ROS package you want to profile / debug.
+ This flag builds debug symbols that GDB can read to tell you specific lines of code in your project are failing and why.
+ If you do not set this flag, you can still get backtraces but it will not provide line numbers for failures.
+
+Now you're ready to debug your code!
+If this was a non-ROS project, at this point you might do something like below.
+Here we're launching a GDB session and telling our program to immediately run.
+Once your program crashes, it will return a gdb session prompt denoted by ``(gdb)``.
+At this prompt you can access the information you're interested in.
+However, since this is a ROS project with lots of node configurations and other things going on, this isn't a great option for beginners or those that don't like tons of commandline work and understanding the filesystem.
+
+.. code-block:: console
+
+ $ gdb ex run --args /path/to/exe/program
+
+Below are sections to describe the three major situations you could run into with ROS 2-based systems.
+Read the section that best describes the problem you're attempting to solve.
+
+Debugging a specific node with GDB
+----------------------------------
+
+To easily set up a GDB session before launching a ROS 2 node, leverage the ``--prefix`` option to easily set up a GDB session before launching a ROS 2 node.
+For GDB debugging, use it as follows:
+
+.. note::
+
+ Keep in mind that a ROS 2 executable might contain multiple nodes.
+ The ``--prefix`` approach ensures you're debugging the correct node within the process.
+
+**Why Direct GDB Usage Can Be Tricky**
+
+``--prefix`` will execute some bits of code before our ROS 2 command allowing us to insert some information.
+If you attempted to do ``gdb ex run --args ros2 run `` as analog to our example in the preliminaries, you'd find that it couldn't find the ``ros2`` command.
+Additionally, trying to source your workspace within GDB would fail for similar reasons.
+This is because GDB, when launched this way, lacks the environment setup that normally makes the ``ros2`` command available.
+
+**Simplifying the Process with --prefix**
+
+Rather than having to revert to finding the install path of the executable and typing it all out, we can instead use ``--prefix``.
+This allows us to use the same ``ros2 run`` syntax you're used to without having to worry about some of the GDB details.
+
+.. code-block:: console
+
+ $ ros2 run --prefix 'gdb -ex run --args' --all-other-launch arguments
+
+**The GDB Experience**
+
+Just as before, this prefix will launch a GDB session and run the node you requested with all the additional command-line arguments.
+You should now have your node running and should be chugging along with some debug printing.
+
+Reading the Stack Trace
+-----------------------
+
+After you obtain a backtrace using GDB, here's how to interpret it:
+
+- Start at the Bottom: Backtraces list function calls in reverse chronological order.
+ The function at the bottom is where the crash originates.
+
+- Follow the Stack Upwards: Each line above represents the function that called the function below it.
+ Trace upwards until you reach a line of code within your own project.
+ This often reveals where the problem initiated.
+
+- Debugging Clues: Function names and their arguments can provide valuable clues about what went wrong.
+
+**How to Debug once your Node Crashes**
+
+Once your node crashes, you'll see a prompt like below.
+At this point you can get a backtrace.
+
+.. code-block:: bash
+
+ (gdb)
+
+In this session, type ``backtrace`` and it will provide you with a backtrace.
+Copy this for your needs.
+
+
+**Example backtrace**
+
+.. code-block:: bash
+
+ (gdb) backtrace
+ #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
+ #1 0x00007ffff79cc859 in __GI_abort () at abort.c:79
+ #2 0x00007ffff7c52951 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
+ #3 0x00007ffff7c5e47c in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
+ #4 0x00007ffff7c5e4e7 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
+ #5 0x00007ffff7c5e799 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
+ #6 0x00007ffff7c553eb in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
+ #7 0x000055555555936c in std::vector >::_M_range_check (
+ this=0x5555555cfdb0, __n=100) at /usr/include/c++/9/bits/stl_vector.h:1070
+ #8 0x0000555555558e1d in std::vector >::at (this=0x5555555cfdb0,
+ __n=100) at /usr/include/c++/9/bits/stl_vector.h:1091
+ #9 0x000055555555828b in GDBTester::VectorCrash (this=0x5555555cfb40)
+ at /home/steve/Documents/nav2_ws/src/gdb_test_pkg/src/gdb_test_node.cpp:44
+ #10 0x0000555555559cfc in main (argc=1, argv=0x7fffffffc108)
+ at /home/steve/Documents/nav2_ws/src/gdb_test_pkg/src/main.cpp:25
+
+In this example you should read this in the following way, starting at the bottom:
+
+- In the main function, on line 25 we call a function VectorCrash.
+
+- In VectorCrash, on line 44, we crashed in the Vector's ``at()`` method with input ``100``.
+
+- It crashed in ``at()`` on STL vector line 1091 after throwing an exception from a range check failure.
+
+These traces take some time to get used to reading, but in general, start at the bottom and follow it up the stack until you see the line it crashed on.
+Then you can deduce why it crashed.
+When you are done with GDB, type ``quit`` and it will exit the session and kill any processes still up.
+It may ask you if you want to kill some threads at the end, say yes.
+
+From a Launch File
+------------------
+
+Just as in our non-ROS example, we need to setup a GDB session before launching our ROS 2 launch file.
+While we could set this up through the commandline, we can instead make use of the same mechanics that we did in the ``ros2 run`` node example, now using a launch file.
+
+In your launch file, find the node that you're interested in debugging.
+For this section, we assume that your launch file contains only a single node (and potentially other information as well).
+The ``Node`` function used in the ``launch_ros`` package will take in a field prefix taking a list of prefix arguments.
+We will insert the GDB snippet here.
+
+**Consider the following approaches, depending on your setup:**
+
+- **Local Debugging with GUI :** If you are debugging locally and have a GUI system available, use:
+
+.. code-block:: python
+
+ prefix=['xterm -e gdb -ex run --args']
+
+This will provide a more interactive debugging experience.
+Example usecase for debugging building upon ``'start_sync_slam_toolbox_node'`` -
+
+.. code-block:: python
+
+ start_sync_slam_toolbox_node = Node(
+ parameters=[
+ get_package_share_directory("slam_toolbox") + '/config/mapper_params_online_sync.yaml',
+ {'use_sim_time': use_sim_time}
+ ],
+ package='slam_toolbox',
+ executable='sync_slam_toolbox_node',
+ name='slam_toolbox',
+ prefix=['xterm -e gdb -ex run --args'], # For interactive GDB in a separate window/GUI
+ output='screen')
+
+- **Remote Debugging (without GUI):** If debugging without GUI, omit ``xterm -e`` :
+
+.. code-block:: bash
+
+ prefix=['gdb -ex run --args']
+
+GDB's output and interaction will happen within the terminal session where you launched the ROS 2 application.
+Here's an similar example for the ``'start_sync_slam_toolbox_node'`` -
+
+.. code-block:: python
+
+ start_sync_slam_toolbox_node = Node(
+ parameters=[
+ get_package_share_directory("slam_toolbox") + '/config/mapper_params_online_sync.yaml',
+ {'use_sim_time': use_sim_time}
+ ],
+ package='slam_toolbox',
+ executable='sync_slam_toolbox_node',
+ name='slam_toolbox',
+ prefix=['gdb -ex run --args'], # For GDB within the launch terminal
+ output='screen')
+
+Just as before, this prefix will launch a GDB session, now in ``xterm`` and run the launch file you requested with all the additional launch arguments defined.
+
+Once your node crashes, you'll see a prompt like below, now in the ``xterm`` session.
+At this point you can now get a backtrace, and read it using the instructions in `Reading the Stack Trace`_.
+
+From a Large Project
+--------------------
+Working with launch files with multiple nodes is a little different so you can interact with your GDB session without being bogged down by other logging in the same terminal.
+For this reason, when working with larger launch files, it is a good idea to pull out the specific node you're interested in and launch it separately.
+
+If your node of interest is being launched from a nested launch file (e.g. an included launch file) you may want to do the following:
+
+- Comment out the launch file inclusion from the parent launch file
+
+- Recompile the package of interest with ``-g`` flag for debug symbols
+
+- Launch the parent launch file in a terminal
+
+- Launch the node's launch file in another terminal following the instructions in `From a Launch File`_.
+
+Alternatively, if your node of interest is being launched in these files directly (e.g. you see a ``Node``, ``LifecycleNode``, or inside a ``ComponentContainer``), you will need to separate this from the others:
+
+- Comment out the node's inclusion from the parent launch file
+
+- Recompile the package of interest with ``-g`` flag for debug symbols
+
+- Launch the parent launch file in a terminal
+
+- Launch the node in another terminal following the instructions in `Debugging a specific node with GDB`_.
+
+.. note::
+
+ In this case you may need to remap or provide parameter files to this node if it was previously provided by the launch file.
+ Using ``--ros-args`` you can give it the path to the new parameters file, remaps, or names.
+ See :doc:`this tutorial <../../How-To-Guides/Node-arguments>` for the commandline arguments required.
+
+ We understand this can be a pain, so it might encourage you to rather have each node possible as a separately included launch file to make debugging easier.
+ An example set of arguments might be ``--ros-args -r __node:= --params-file /absolute/path/to/params.yaml`` (as a template).
+
+Once your node crashes, you'll see a prompt like below in the terminal of the specific node.
+At this point you can now get a backtrace, and read it using the instructions in `Reading the Stack Trace`_.
+
+Debugging tests with GDB
+------------------------
+
+If a C++ test is failing, GDB can be used directly on the test executable in the build directory.
+Ensure to build the code in debug mode.
+Since the previous build type may be cached by CMake, clean the cache and rebuild.
+
+.. code-block:: console
+
+ $ colcon build --cmake-clean-cache --mixin debug
+
+In order for GDB to load debug symbols for any shared libraries called, make sure to source your environment.
+This configures the value of ``LD_LIBRARY_PATH``.
+
+.. code-block:: console
+
+ $ source install/setup.bash
+
+Finally, run the test directly through GDB.
+For example:
+
+.. code-block:: console
+
+ $ gdb -ex run ./build/rcl/test/test_logging
+
+If the code is throwing an unhandled exception, you can catch it in GDB before gtest handles it.
+
+.. code-block:: console
+
+ $ gdb ./build/rcl/test/test_logging
+ $ catch throw
+ $ run
+
+Automatic backtrace on crash
+----------------------------
+
+The `backward-cpp `_ library provides beautiful stack traces, and the `backward_ros `_ wrapper simplifies its integration.
+
+Just add it as a dependency and ``find_package`` it in your CMakeLists and the backward libraries will be injected in all your executables and libraries.
\ No newline at end of file
diff --git a/source/Developer-Tools/Debugging/ROS-2-IDEs.rst b/source/Developer-Tools/Debugging/ROS-2-IDEs.rst
index 06601c64de1..d25c6b9f171 100644
--- a/source/Developer-Tools/Debugging/ROS-2-IDEs.rst
+++ b/source/Developer-Tools/Debugging/ROS-2-IDEs.rst
@@ -1,266 +1,270 @@
-IDEs and Debugging [community-contributed]
-==========================================
-
-ROS 2 is not made around a specific development environment and the main focus is on building / running from the command line.
-Nonetheless Integrated Development Environments (IDEs) can be used to develop, run and/or debug ROS 2 nodes.
-
-Below are listed some IDEs and instructions on how to use them with ROS 2.
-
-
-.. contents:: Contents
- :depth: 2
- :local:
-
-
-General
--------
-
-
-.. _InstalledPythonCode:
-
-Installed Python Code
-^^^^^^^^^^^^^^^^^^^^^
-
-By default, when building workspaces with:
-
-.. code-block:: console
-
- $ colcon build
-
-The Python code will be coped over into the ``build``/``install`` directories.
-So when attaching a debugger to a ``ros2 run`` command from within an IDE, the code being run (from the ``build``/``install``) is not the same as the files opened in the IDE project.
-
-There are 2 options to deal with this:
-
-* Open the source files from ``build``/``install`` directory and place breakpoints there.
-* Build the workspace with the `--symlink-install `__ flag to colcon, which will symlink the source files to the ``build``/``install`` directory instead.
-
-
-Visual Studio Code
-------------------
-
-`VSCode `_ is a versatile and free development environment.
-
-VSCode is relatively easy to use with ROS 2.
-Simply activate your environment in a command line and start the VSCode application from the same terminal and use as normal.
-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.
-
-.. tabs::
-
- .. group-tab:: Linux
-
- .. code-block:: console
-
- $ source /opt/ros/{DISTRO}/setup.bash
- $ cd ~/dev_ws
- $ source ./install/setup.bash
- $ /usr/bin/code ./src/my_node/
-
- .. group-tab:: macOS
-
- .. code-block:: console
-
- $ . ~/ros2_install/ros2-osx/setup.bash
- $ cd ~/dev_ws
- $ . ./install/setup.bash
- $ /Applications/Visual Studio Code.app/Contents/Resources/app/bin/code ./src/my_node/
-
- .. group-tab:: Windows
-
- In a Windows command line interface:
-
- .. code-block:: console
-
- $ call C:\dev\ros2\local_setup.bat
- $ cd C:\dev_ws
- $ call .\install\local_setup.bat
- $ "C:\Program Files\Microsoft VS Code\Code.exe" .\src\my_node\
-
- Or in powershell:
-
- .. code-block:: console
-
- $ C:\dev\ros2\local_setup.ps1
- $ cd C:\dev_ws
- $ .\install\local_setup.ps1
- $ & "C:\Program Files\Microsoft VS Code\Code.exe" .\src\my_node\
-
-
-VSCode and any terminal created inside VSCode will correctly inherit from the parent environment and should have ROS and installed package available.
-
-.. note::
-
- After adding packages or making major changes you might need to source your install again.
- The simplest way to do this is to close VSCode and restart it as above.
-
-
-Python
-^^^^^^
-
-In your workspace, verify the correct interpreter is used.
-Through sourcing the basic command ``python`` should be correct, but VSCode likes to resort to an absolute path for Python.
-In the bottom right corner click on "Selected Python Interpreter" to change it.
-
-If your ROS 2 Python version is from a virtual environment, VSCode will try to source it at each run command.
-But we already started VSCode from a sourced environment, so this extra step is not necessary.
-You can disable this for the current workspace by finding "Settings" > "Extensions" > "Python" > "Activate Environment" and disabling the check.
-
-Now simply run a file or create a configuration in ``launch.json``.
-Debugging a node is easiest by creating a configuration like a ``python ...`` command, instead of ``ros2 run/launch ...``.
-An example of ``launch.json`` could be:
-
-.. code-block::
-
- {
- "version": "0.2.0",
- "configurations": [
- {
- "name": "Python: File",
- "type": "python",
- "request": "launch",
- "program": "my_node.py"
- },
- ]
- }
-
-
-Instead you could also create a configuration for attaching to a running process, under "Attach using Process Id".
-
-
-See :doc:`Setup ROS 2 with VSCode and Docker` for full instructions on how to use VSCode, in combination with Docker.
-
-
-PyCharm
--------
-
-`PyCharm `_ is an IDE specifically for Python.
-
-Of course it can only be meaningfully used for nodes made in Python.
-
-With PyCharm you can either attach to an existing process (probably started by you via ``ros2 run ...`` or ``ros2 launch ...``) or run the node directly from Python (equivalent to ``python [file.py]``.
-
-
-Integrate for code inspection
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-You can setup your PyCharm project such that it is fully aware of ROS 2 code, allowing code completion and suggestion.
-
-
-Linux
-"""""
-
-Open a terminal, source ROS and start PyCharm:
-
-.. code-block:: console
-
- $ source /opt/ros/humble/setup.bash
- $ cd path/to/dev_ws
- $ /opt/pycharm/bin/pycharm.sh
-
-After selecting the correct interpreter, everything should work.
-
-.. note::
-
- This is untested.
-
-
-Windows
-"""""""
-
-First sourcing ROS and then starting PyCharm from the command line seems to have no effect on Windows.
-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``.
-#. 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``).
-
- * If you now open one of your code files, you will see warnings about missing imports.
- Trying to run the file will confirm these issues.
-
-#. Under the "Python Interpreters" window, find and select your ROS interpreter.
- Edit the name to something recognizable.
- More importantly, now click the "Show Interpreter Paths" button.
-#. In the new window, you will see the paths already associated with this interpreter.
- Click the "+" button and add two more paths (according to your ROS install):
-
- * ``C:\dev\ros2_humble\bin``
- * ``C:\dev\ros2_humble\Lib\site-packages``
-
-PyCharm will re-index and when finished it should correctly interpret your project, recognising the ROS 2 system packages.
-You can navigate through code, get completion and read doc blurbs as expected.
-
-
-If there are dependencies built alongside with your package, they are probably not yet recognized and result in invalid IDE warnings and runtime errors.
-
-Resolve this by:
-
-* Making sure the ``PATH`` override in the run/debug configuration includes both the ROS 2 install and your workspace, e.g.:
-
- .. code-block:: console
-
- $ C:\dev\ros2_humble\local_setup.ps1
- $ C:\dev_ws\install\local_setup.ps1
- $ echo $ENV:Path
-
-* Adding the relevant folders from the ``install/`` directory to your project sources.
-
- Go to "Settings..." and under "Project: " > "Project Structure" click "Add content root".
- Add all the relevant ``site-packages`` folders under ``install/Lib/*``.
-
- Finally, make sure your run/debug configuration has the option "include content roots in PYTHONPATH" enabled.
-
-.. tip::
-
- Using the `--merge-install `__ option with your colcon build will limit the number of depending directories, making it easier to configure PyCharm.
-
-
-Attach to Process
-^^^^^^^^^^^^^^^^^
-
-Even without any configuration to PyCharm, you can always just attach to a running Python node.
-Open your project source and simply run your node as usual:
-
-.. code-block:: console
-
- $ ros2 run my_node main
-
-Then in PyCharm select "Run" > "Attach to Process...".
-It might take a second, but a small window should show listing the currently running Python instances, including your node.
-There can be multiple Python processes, so there may be some trial-and-error to find the right one.
-
-After selecting an instance, the usual debugging tools are available.
-You can pause it or create breakpoints in the code and step through it.
-
-.. note::
-
- The code in your project might not be the files being executed, see :ref:`this`.
-
-
-Run/Debug
-^^^^^^^^^
-
-Follow the steps for integration first.
-
-Running your Python file from PyCharm will likely result in import errors.
-This is because PyCharm extends the ``PYTHONPATH`` environment variable, but it leaves ``PATH`` untouched.
-Necessary library files in ``ros/bin`` are not found.
-
-Edit the run/debug configuration for your file and under "Environment Variables:" add a new variable.
-It is currently not supported to extend the existing ``PATH``, so we need to override it.
-From a sourced ROS terminal, export the content of ``PATH`` with: ``echo $Env:PATH``.
-Copy the result.
-
-Back in PyCharm, paste it as ``PATH``, apply changes and run or debug your node.
-It should work like any Python project now, allowing easy additions of breakpoints and other debug methods.
-
-.. note::
-
- On Windows it seems the capitalization of the ``PATH`` variable under "Environment Variables:" must be "path" (all lowercase) in order to work.
+.. redirect-from::
+
+ How-To-Guides/ROS-2-IDEs
+
+IDEs and Debugging [community-contributed]
+==========================================
+
+ROS 2 is not made around a specific development environment and the main focus is on building / running from the command line.
+Nonetheless Integrated Development Environments (IDEs) can be used to develop, run and/or debug ROS 2 nodes.
+
+Below are listed some IDEs and instructions on how to use them with ROS 2.
+
+
+.. contents:: Contents
+ :depth: 2
+ :local:
+
+
+General
+-------
+
+
+.. _InstalledPythonCode:
+
+Installed Python Code
+^^^^^^^^^^^^^^^^^^^^^
+
+By default, when building workspaces with:
+
+.. code-block:: console
+
+ $ colcon build
+
+The Python code will be coped over into the ``build``/``install`` directories.
+So when attaching a debugger to a ``ros2 run`` command from within an IDE, the code being run (from the ``build``/``install``) is not the same as the files opened in the IDE project.
+
+There are 2 options to deal with this:
+
+* Open the source files from ``build``/``install`` directory and place breakpoints there.
+* Build the workspace with the `--symlink-install `__ flag to colcon, which will symlink the source files to the ``build``/``install`` directory instead.
+
+
+Visual Studio Code
+------------------
+
+`VSCode `_ is a versatile and free development environment.
+
+VSCode is relatively easy to use with ROS 2.
+Simply activate your environment in a command line and start the VSCode application from the same terminal and use as normal.
+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.
+
+.. tabs::
+
+ .. group-tab:: Linux
+
+ .. code-block:: console
+
+ $ source /opt/ros/{DISTRO}/setup.bash
+ $ cd ~/dev_ws
+ $ source ./install/setup.bash
+ $ /usr/bin/code ./src/my_node/
+
+ .. group-tab:: macOS
+
+ .. code-block:: console
+
+ $ . ~/ros2_install/ros2-osx/setup.bash
+ $ cd ~/dev_ws
+ $ . ./install/setup.bash
+ $ /Applications/Visual Studio Code.app/Contents/Resources/app/bin/code ./src/my_node/
+
+ .. group-tab:: Windows
+
+ In a Windows command line interface:
+
+ .. code-block:: console
+
+ $ call C:\dev\ros2\local_setup.bat
+ $ cd C:\dev_ws
+ $ call .\install\local_setup.bat
+ $ "C:\Program Files\Microsoft VS Code\Code.exe" .\src\my_node\
+
+ Or in powershell:
+
+ .. code-block:: console
+
+ $ C:\dev\ros2\local_setup.ps1
+ $ cd C:\dev_ws
+ $ .\install\local_setup.ps1
+ $ & "C:\Program Files\Microsoft VS Code\Code.exe" .\src\my_node\
+
+
+VSCode and any terminal created inside VSCode will correctly inherit from the parent environment and should have ROS and installed package available.
+
+.. note::
+
+ After adding packages or making major changes you might need to source your install again.
+ The simplest way to do this is to close VSCode and restart it as above.
+
+
+Python
+^^^^^^
+
+In your workspace, verify the correct interpreter is used.
+Through sourcing the basic command ``python`` should be correct, but VSCode likes to resort to an absolute path for Python.
+In the bottom right corner click on "Selected Python Interpreter" to change it.
+
+If your ROS 2 Python version is from a virtual environment, VSCode will try to source it at each run command.
+But we already started VSCode from a sourced environment, so this extra step is not necessary.
+You can disable this for the current workspace by finding "Settings" > "Extensions" > "Python" > "Activate Environment" and disabling the check.
+
+Now simply run a file or create a configuration in ``launch.json``.
+Debugging a node is easiest by creating a configuration like a ``python ...`` command, instead of ``ros2 run/launch ...``.
+An example of ``launch.json`` could be:
+
+.. code-block::
+
+ {
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Python: File",
+ "type": "python",
+ "request": "launch",
+ "program": "my_node.py"
+ },
+ ]
+ }
+
+
+Instead you could also create a configuration for attaching to a running process, under "Attach using Process Id".
+
+
+See :doc:`Setup ROS 2 with VSCode and Docker` for full instructions on how to use VSCode, in combination with Docker.
+
+
+PyCharm
+-------
+
+`PyCharm `_ is an IDE specifically for Python.
+
+Of course it can only be meaningfully used for nodes made in Python.
+
+With PyCharm you can either attach to an existing process (probably started by you via ``ros2 run ...`` or ``ros2 launch ...``) or run the node directly from Python (equivalent to ``python [file.py]``.
+
+
+Integrate for code inspection
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can setup your PyCharm project such that it is fully aware of ROS 2 code, allowing code completion and suggestion.
+
+
+Linux
+"""""
+
+Open a terminal, source ROS and start PyCharm:
+
+.. code-block:: console
+
+ $ source /opt/ros/humble/setup.bash
+ $ cd path/to/dev_ws
+ $ /opt/pycharm/bin/pycharm.sh
+
+After selecting the correct interpreter, everything should work.
+
+.. note::
+
+ This is untested.
+
+
+Windows
+"""""""
+
+First sourcing ROS and then starting PyCharm from the command line seems to have no effect on Windows.
+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``.
+#. 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``).
+
+ * If you now open one of your code files, you will see warnings about missing imports.
+ Trying to run the file will confirm these issues.
+
+#. Under the "Python Interpreters" window, find and select your ROS interpreter.
+ Edit the name to something recognizable.
+ More importantly, now click the "Show Interpreter Paths" button.
+#. In the new window, you will see the paths already associated with this interpreter.
+ Click the "+" button and add two more paths (according to your ROS install):
+
+ * ``C:\dev\ros2_humble\bin``
+ * ``C:\dev\ros2_humble\Lib\site-packages``
+
+PyCharm will re-index and when finished it should correctly interpret your project, recognising the ROS 2 system packages.
+You can navigate through code, get completion and read doc blurbs as expected.
+
+
+If there are dependencies built alongside with your package, they are probably not yet recognized and result in invalid IDE warnings and runtime errors.
+
+Resolve this by:
+
+* Making sure the ``PATH`` override in the run/debug configuration includes both the ROS 2 install and your workspace, e.g.:
+
+ .. code-block:: console
+
+ $ C:\dev\ros2_humble\local_setup.ps1
+ $ C:\dev_ws\install\local_setup.ps1
+ $ echo $ENV:Path
+
+* Adding the relevant folders from the ``install/`` directory to your project sources.
+
+ Go to "Settings..." and under "Project: " > "Project Structure" click "Add content root".
+ Add all the relevant ``site-packages`` folders under ``install/Lib/*``.
+
+ Finally, make sure your run/debug configuration has the option "include content roots in PYTHONPATH" enabled.
+
+.. tip::
+
+ Using the `--merge-install `__ option with your colcon build will limit the number of depending directories, making it easier to configure PyCharm.
+
+
+Attach to Process
+^^^^^^^^^^^^^^^^^
+
+Even without any configuration to PyCharm, you can always just attach to a running Python node.
+Open your project source and simply run your node as usual:
+
+.. code-block:: console
+
+ $ ros2 run my_node main
+
+Then in PyCharm select "Run" > "Attach to Process...".
+It might take a second, but a small window should show listing the currently running Python instances, including your node.
+There can be multiple Python processes, so there may be some trial-and-error to find the right one.
+
+After selecting an instance, the usual debugging tools are available.
+You can pause it or create breakpoints in the code and step through it.
+
+.. note::
+
+ The code in your project might not be the files being executed, see :ref:`this`.
+
+
+Run/Debug
+^^^^^^^^^
+
+Follow the steps for integration first.
+
+Running your Python file from PyCharm will likely result in import errors.
+This is because PyCharm extends the ``PYTHONPATH`` environment variable, but it leaves ``PATH`` untouched.
+Necessary library files in ``ros/bin`` are not found.
+
+Edit the run/debug configuration for your file and under "Environment Variables:" add a new variable.
+It is currently not supported to extend the existing ``PATH``, so we need to override it.
+From a sourced ROS terminal, export the content of ``PATH`` with: ``echo $Env:PATH``.
+Copy the result.
+
+Back in PyCharm, paste it as ``PATH``, apply changes and run or debug your node.
+It should work like any Python project now, allowing easy additions of breakpoints and other debug methods.
+
+.. note::
+
+ On Windows it seems the capitalization of the ``PATH`` variable under "Environment Variables:" must be "path" (all lowercase) in order to work.
\ No newline at end of file
diff --git a/source/Developer-Tools/Introspection-and-analysis/About-Command-Line-Tools.rst b/source/Developer-Tools/Introspection-and-analysis/About-Command-Line-Tools.rst
index ecab8b362d8..a4fdbcb4ed8 100644
--- a/source/Developer-Tools/Introspection-and-analysis/About-Command-Line-Tools.rst
+++ b/source/Developer-Tools/Introspection-and-analysis/About-Command-Line-Tools.rst
@@ -1,94 +1,95 @@
-.. redirect-from::
-
- Introspection-with-command-line-tools
- Tutorials/Introspection-with-command-line-tools
- Concepts/About-Command-Line-Tools
-
-Introspection with command line tools
-=====================================
-
-.. contents:: Table of Contents
- :local:
-
-ROS 2 includes a suite of command-line tools for introspecting a ROS 2 system.
-
-Usage
------
-
-The main entry point for the tools is the command ``ros2``, which itself has various sub-commands for introspecting and working with nodes, topics, services, and more.
-
-To see all available sub-commands run:
-
-.. code-block:: console
-
- $ ros2 --help
-
-Examples of sub-commands that are available include:
-
-* ``action``: Introspect/interact with ROS actions
-* ``bag``: Record/play a rosbag
-* ``component``: Manage component containers
-* ``daemon``: Introspect/configure the ROS 2 daemon
-* ``doctor``: Check ROS setup for potential issues
-* ``interface``: Show information about ROS interfaces
-* ``launch``: Run/introspect a launch file
-* ``lifecycle``: Introspect/manage nodes with managed lifecycles
-* ``multicast``: Multicast debugging commands
-* ``node``: Introspect ROS nodes
-* ``param``: Introspect/configure parameters on a node
-* ``pkg``: Introspect ROS packages
-* ``plugin``: Introspect ROS plugins
-* ``run``: Run ROS nodes
-* ``security``: Configure security settings
-* ``service``: Introspect/call ROS services
-* ``test``: Run a ROS launch test
-* ``topic``: Introspect/publish ROS topics
-* ``trace``: Tracing tools to get information on ROS nodes execution (only available on Linux)
-
-Example
--------
-
-To produce the typical talker-listener example using command-line tools, the ``topic`` sub-command can be used to publish and echo messages on a topic.
-
-Publish messages in one terminal with:
-
-.. code-block:: console
-
- $ ros2 topic pub /chatter std_msgs/msg/String "data: Hello world"
- publisher: beginning loop
- publishing #1: std_msgs.msg.String(data='Hello world')
-
- publishing #2: std_msgs.msg.String(data='Hello world')
-
-Echo messages received in another terminal with:
-
-.. code-block:: console
-
- $ ros2 topic echo /chatter
- data: Hello world
-
- data: Hello world
-
-ROS 2 Daemon: Background Discovery Service
-------------------------------------------
-
-ROS 2 uses a distributed discovery process for nodes to connect to each other.
-As this process purposefully does not use a centralized discovery mechanism, it can take time for ROS nodes to discover all other participants in the ROS graph.
-To address this, ROS 2 runs a background daemon process that maintains information about the ROS graph to provide faster responses to queries, such as the list of node names.
-
-The ROS 2 daemon is automatically started when you first use command-line tools like ``ros2 node list``, ``ros2 topic list``, or other introspection commands.
-If no daemon is running, these tools will instantiate a new daemon process in the background before executing the requested command.
-
-The daemon communicates using the localhost network interface (127.0.0.1) and uses the :doc:`ROS_DOMAIN_ID <../Intermediate/About-Domain-ID>` environment variable as a port number offset.
-This means that if you want to control a specific daemon instance (for example, using ``ros2 daemon stop``), you must ensure that your :doc:`ROS_DOMAIN_ID <../Intermediate/About-Domain-ID>` matches the domain ID used by that daemon.
-Different :doc:`ROS_DOMAIN_ID <../Intermediate/About-Domain-ID>` values will result in separate daemon instances running on different ports.
-
-You can run ``ros2 daemon --help`` for more options for interacting with the daemon, including commands to start, stop, or check the status of the daemon process.
-
-Implementation
---------------
-
-The source code for the ``ros2`` command is available at https://github.com/ros2/ros2cli.
-
-The ``ros2`` tool has been implemented as a framework that can be extended via plugins.
-For example, the `sros2 `__ package provides a ``security`` sub-command that is automatically detected by the ``ros2`` tool if the ``sros2`` package is installed.
+.. redirect-from::
+
+ Introspection-with-command-line-tools
+ Tutorials/Introspection-with-command-line-tools
+ Concepts/About-Command-Line-Tools
+ Concepts/Basic/About-Command-Line-Tools
+
+Introspection with command line tools
+=====================================
+
+.. contents:: Table of Contents
+ :local:
+
+ROS 2 includes a suite of command-line tools for introspecting a ROS 2 system.
+
+Usage
+-----
+
+The main entry point for the tools is the command ``ros2``, which itself has various sub-commands for introspecting and working with nodes, topics, services, and more.
+
+To see all available sub-commands run:
+
+.. code-block:: console
+
+ $ ros2 --help
+
+Examples of sub-commands that are available include:
+
+* ``action``: Introspect/interact with ROS actions
+* ``bag``: Record/play a rosbag
+* ``component``: Manage component containers
+* ``daemon``: Introspect/configure the ROS 2 daemon
+* ``doctor``: Check ROS setup for potential issues
+* ``interface``: Show information about ROS interfaces
+* ``launch``: Run/introspect a launch file
+* ``lifecycle``: Introspect/manage nodes with managed lifecycles
+* ``multicast``: Multicast debugging commands
+* ``node``: Introspect ROS nodes
+* ``param``: Introspect/configure parameters on a node
+* ``pkg``: Introspect ROS packages
+* ``plugin``: Introspect ROS plugins
+* ``run``: Run ROS nodes
+* ``security``: Configure security settings
+* ``service``: Introspect/call ROS services
+* ``test``: Run a ROS launch test
+* ``topic``: Introspect/publish ROS topics
+* ``trace``: Tracing tools to get information on ROS nodes execution (only available on Linux)
+
+Example
+-------
+
+To produce the typical talker-listener example using command-line tools, the ``topic`` sub-command can be used to publish and echo messages on a topic.
+
+Publish messages in one terminal with:
+
+.. code-block:: console
+
+ $ ros2 topic pub /chatter std_msgs/msg/String "data: Hello world"
+ publisher: beginning loop
+ publishing #1: std_msgs.msg.String(data='Hello world')
+
+ publishing #2: std_msgs.msg.String(data='Hello world')
+
+Echo messages received in another terminal with:
+
+.. code-block:: console
+
+ $ ros2 topic echo /chatter
+ data: Hello world
+
+ data: Hello world
+
+ROS 2 Daemon: Background Discovery Service
+------------------------------------------
+
+ROS 2 uses a distributed discovery process for nodes to connect to each other.
+As this process purposefully does not use a centralized discovery mechanism, it can take time for ROS nodes to discover all other participants in the ROS graph.
+To address this, ROS 2 runs a background daemon process that maintains information about the ROS graph to provide faster responses to queries, such as the list of node names.
+
+The ROS 2 daemon is automatically started when you first use command-line tools like ``ros2 node list``, ``ros2 topic list``, or other introspection commands.
+If no daemon is running, these tools will instantiate a new daemon process in the background before executing the requested command.
+
+The daemon communicates using the localhost network interface (127.0.0.1) and uses the :doc:`ROS_DOMAIN_ID <../../ROS-Framework/nodes/About-Domain-ID>` environment variable as a port number offset.
+This means that if you want to control a specific daemon instance (for example, using ``ros2 daemon stop``), you must ensure that your :doc:`ROS_DOMAIN_ID <../../ROS-Framework/nodes/About-Domain-ID>` matches the domain ID used by that daemon.
+Different :doc:`ROS_DOMAIN_ID <../../ROS-Framework/nodes/About-Domain-ID>` values will result in separate daemon instances running on different ports.
+
+You can run ``ros2 daemon --help`` for more options for interacting with the daemon, including commands to start, stop, or check the status of the daemon process.
+
+Implementation
+--------------
+
+The source code for the ``ros2`` command is available at https://github.com/ros2/ros2cli.
+
+The ``ros2`` tool has been implemented as a framework that can be extended via plugins.
+For example, the `sros2 `__ package provides a ``security`` sub-command that is automatically detected by the ``ros2`` tool if the ``sros2`` package is installed.
\ No newline at end of file
diff --git a/source/Developer-Tools/Introspection-and-analysis/About-Security.rst b/source/Developer-Tools/Introspection-and-analysis/About-Security.rst
index a52066c4a4e..41f062271c5 100644
--- a/source/Developer-Tools/Introspection-and-analysis/About-Security.rst
+++ b/source/Developer-Tools/Introspection-and-analysis/About-Security.rst
@@ -1,94 +1,95 @@
-.. redirect-from::
-
- Concepts/About-Security
-
-ROS 2 Security
-==============
-
-.. contents:: Table of Contents
- :local:
-
-Overview
---------
-
-ROS 2 includes the ability to secure communications among nodes within the ROS 2 computational graph.
-Similar to discovery, security happens through the underlying ROS 2 middleware (provided it has support for the corresponding security plugins).
-No additional software installation is needed to enable security; however, the middleware requires configuration files for each ROS graph participant.
-These files enable encryption and authentication, and define policies both for individual nodes and for the overall ROS graph.
-ROS 2 also adds a master "on/off" switch to control security behavior.
-
-ROS utilities can create the authoritative `trust anchor