From e3715c37e4c369a52c7287bbf2863acc075a080f Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 22:18:49 +0100 Subject: [PATCH 1/4] Add documentation on `ros2_control_node` and make lock_memory false by default (backport #1890) (#1895) --- controller_manager/doc/userdoc.rst | 32 ++++++++++++++++++++ controller_manager/src/ros2_control_node.cpp | 3 +- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/controller_manager/doc/userdoc.rst b/controller_manager/doc/userdoc.rst index d21cd0a3b2..27ded48e5e 100644 --- a/controller_manager/doc/userdoc.rst +++ b/controller_manager/doc/userdoc.rst @@ -262,6 +262,38 @@ The workaround for this is to specify another node name remap rule in the ``Node auto cm = std::make_shared( executor, "_target_node_name", "some_optional_namespace", options); +Launching controller_manager with ros2_control_node +--------------------------------------------------- + +The controller_manager can be launched with the ros2_control_node executable. The following example shows how to launch the controller_manager with the ros2_control_node executable: + +.. code-block:: python + + control_node = Node( + package="controller_manager", + executable="ros2_control_node", + parameters=[robot_controllers], + output="both", + ) + +The ros2_control_node executable uses the following parameters from the ``controller_manager`` node: + +lock_memory (optional; bool; default: false for a non-realtime kernel, true for a realtime kernel) + Locks the memory of the ``controller_manager`` node at startup to physical RAM in order to avoid page faults + and to prevent the node from being swapped out to disk. + Find more information about the setup for memory locking in the following link : `How to set ulimit values `_ + The following command can be used to set the memory locking limit temporarily : ``ulimit -l unlimited``. + +cpu_affinity (optional; int; default: -1) + Sets the CPU affinity of the ``controller_manager`` node to the specified CPU core. + The value of -1 means that the CPU affinity is not set. + +thread_priority (optional; int; default: 50) + Sets the thread priority of the ``controller_manager`` node to the specified value. The value must be between 0 and 99. + +use_sim_time (optional; bool; default: false) + Enables the use of simulation time in the ``controller_manager`` node. + Concepts ----------- diff --git a/controller_manager/src/ros2_control_node.cpp b/controller_manager/src/ros2_control_node.cpp index 3200fc926e..d6a0b0f3dd 100644 --- a/controller_manager/src/ros2_control_node.cpp +++ b/controller_manager/src/ros2_control_node.cpp @@ -56,7 +56,8 @@ int main(int argc, char ** argv) cm->get_logger(), "Unable to set the CPU affinity : '%s'", affinity_result.second.c_str()); } } - const bool lock_memory = cm->get_parameter_or("lock_memory", true); + const bool has_realtime = realtime_tools::has_realtime_kernel(); + const bool lock_memory = cm->get_parameter_or("lock_memory", has_realtime); std::string message; if (lock_memory && !realtime_tools::lock_memory(message)) { From 8164fc516b5b19e7f5d98e18f2406e69bd9f3714 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:13:32 +0100 Subject: [PATCH 2/4] [CI] Add clang job, setup concurrency, use rt_tools humble branch (backport #1910) (#1924) --- .../workflows/humble-abi-compatibility.yml | 5 +++++ .github/workflows/humble-binary-build.yml | 5 +++++ .github/workflows/humble-check-docs.yml | 4 ++++ .github/workflows/humble-coverage-build.yml | 5 +++++ .github/workflows/humble-debian-build.yml | 4 ++++ .github/workflows/humble-pre-commit.yml | 4 ++++ .../workflows/humble-rhel-binary-build.yml | 5 +++++ .../workflows/humble-semi-binary-build.yml | 20 ++++++++++++++++-- .github/workflows/jazzy-abi-compatibility.yml | 5 +++++ .github/workflows/jazzy-binary-build.yml | 5 +++++ .github/workflows/jazzy-check-docs.yml | 4 ++++ .github/workflows/jazzy-debian-build.yml | 4 ++++ .github/workflows/jazzy-pre-commit.yml | 4 ++++ .github/workflows/jazzy-rhel-binary-build.yml | 5 +++++ .github/workflows/jazzy-semi-binary-build.yml | 20 ++++++++++++++++-- .../workflows/rolling-abi-compatibility.yml | 5 +++++ .github/workflows/rolling-binary-build.yml | 5 +++++ .github/workflows/rolling-check-docs.yml | 4 ++++ ...ling-compatibility-humble-binary-build.yml | 5 +++++ ...lling-compatibility-jazzy-binary-build.yml | 5 +++++ .github/workflows/rolling-coverage-build.yml | 5 +++++ .github/workflows/rolling-debian-build.yml | 5 +++++ .github/workflows/rolling-pre-commit.yml | 4 ++++ .../workflows/rolling-rhel-binary-build.yml | 4 ++++ .../workflows/rolling-semi-binary-build.yml | 21 +++++++++++++++++-- .github/workflows/rosdoc2.yml | 3 +++ .../force_torque_sensor.hpp | 4 ++-- hardware_interface/src/component_parser.cpp | 2 +- .../src/mock_components/generic_system.cpp | 17 ++++++++------- .../test/test_component_interfaces.cpp | 6 +++--- hardware_interface/test/test_macros.cpp | 2 +- ros2_control.humble.repos | 2 +- 32 files changed, 177 insertions(+), 21 deletions(-) diff --git a/.github/workflows/humble-abi-compatibility.yml b/.github/workflows/humble-abi-compatibility.yml index 61a5f1f29c..844a4559e2 100644 --- a/.github/workflows/humble-abi-compatibility.yml +++ b/.github/workflows/humble-abi-compatibility.yml @@ -14,6 +14,11 @@ on: - '**/CMakeLists.txt' - 'ros2_control-not-released.humble.repos' +concurrency: + # cancel previous runs of the same workflow, except for pushes on humble branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: abi_check: runs-on: ubuntu-latest diff --git a/.github/workflows/humble-binary-build.yml b/.github/workflows/humble-binary-build.yml index 6392ba8e68..0fabfda92f 100644 --- a/.github/workflows/humble-binary-build.yml +++ b/.github/workflows/humble-binary-build.yml @@ -32,6 +32,11 @@ on: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on humble branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: binary: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master diff --git a/.github/workflows/humble-check-docs.yml b/.github/workflows/humble-check-docs.yml index f3c31703cd..078a541bf0 100644 --- a/.github/workflows/humble-check-docs.yml +++ b/.github/workflows/humble-check-docs.yml @@ -10,6 +10,10 @@ on: - '**.md' - '**.yaml' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: check-docs: name: Check Docs diff --git a/.github/workflows/humble-coverage-build.yml b/.github/workflows/humble-coverage-build.yml index 209c931d4e..8255b02bb4 100644 --- a/.github/workflows/humble-coverage-build.yml +++ b/.github/workflows/humble-coverage-build.yml @@ -28,6 +28,11 @@ on: - 'ros2_control.humble.repos' - 'codecov.yml' +concurrency: + # cancel previous runs of the same workflow, except for pushes on humble branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: coverage_humble: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-build-coverage.yml@master diff --git a/.github/workflows/humble-debian-build.yml b/.github/workflows/humble-debian-build.yml index 0ce72a3184..301befbcab 100644 --- a/.github/workflows/humble-debian-build.yml +++ b/.github/workflows/humble-debian-build.yml @@ -17,6 +17,10 @@ on: # Run every day to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on humble branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} jobs: debian_source_build: diff --git a/.github/workflows/humble-pre-commit.yml b/.github/workflows/humble-pre-commit.yml index 5bb2408578..38a76ee025 100644 --- a/.github/workflows/humble-pre-commit.yml +++ b/.github/workflows/humble-pre-commit.yml @@ -6,6 +6,10 @@ on: branches: - humble +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: pre-commit: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-pre-commit.yml@master diff --git a/.github/workflows/humble-rhel-binary-build.yml b/.github/workflows/humble-rhel-binary-build.yml index 62c5cd62ba..e986bf361e 100644 --- a/.github/workflows/humble-rhel-binary-build.yml +++ b/.github/workflows/humble-rhel-binary-build.yml @@ -17,6 +17,11 @@ on: # Run every day to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on humble branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: rhel_semi_binary_build: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master diff --git a/.github/workflows/humble-semi-binary-build.yml b/.github/workflows/humble-semi-binary-build.yml index 96938467f9..7b0c5f1fd3 100644 --- a/.github/workflows/humble-semi-binary-build.yml +++ b/.github/workflows/humble-semi-binary-build.yml @@ -1,6 +1,6 @@ name: Humble Semi-Binary Build # author: Denis Štogl -# description: 'Build & test all dependencies from released (binary) packages.' +# description: 'Build & test all ros2_control dependencies from source.' on: workflow_dispatch: @@ -32,8 +32,13 @@ on: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on humble branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: - binary: + semi-binary: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -45,3 +50,14 @@ jobs: ros_repo: ${{ matrix.ROS_REPO }} upstream_workspace: ros2_control.${{ matrix.ROS_DISTRO }}.repos ref_for_scheduled_build: humble + semi-binary-clang: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + with: + ros_distro: humble + ros_repo: testing + upstream_workspace: ros2_control.humble.repos + ref_for_scheduled_build: humble + additional_debs: clang + c_compiler: clang + cxx_compiler: clang++ + not_test_build: true diff --git a/.github/workflows/jazzy-abi-compatibility.yml b/.github/workflows/jazzy-abi-compatibility.yml index 367b3736fb..aa0fe81e63 100644 --- a/.github/workflows/jazzy-abi-compatibility.yml +++ b/.github/workflows/jazzy-abi-compatibility.yml @@ -14,6 +14,11 @@ on: - '**/CMakeLists.txt' - 'ros2_control-not-released.jazzy.repos' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: abi_check: runs-on: ubuntu-latest diff --git a/.github/workflows/jazzy-binary-build.yml b/.github/workflows/jazzy-binary-build.yml index 5be853ebfc..599a075d9a 100644 --- a/.github/workflows/jazzy-binary-build.yml +++ b/.github/workflows/jazzy-binary-build.yml @@ -32,6 +32,11 @@ on: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: binary: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master diff --git a/.github/workflows/jazzy-check-docs.yml b/.github/workflows/jazzy-check-docs.yml index cbdf6c30bd..7910cde0b5 100644 --- a/.github/workflows/jazzy-check-docs.yml +++ b/.github/workflows/jazzy-check-docs.yml @@ -10,6 +10,10 @@ on: - '**.md' - '**.yaml' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: check-docs: name: Check Docs diff --git a/.github/workflows/jazzy-debian-build.yml b/.github/workflows/jazzy-debian-build.yml index 4ec6a29fff..0f695ed8bc 100644 --- a/.github/workflows/jazzy-debian-build.yml +++ b/.github/workflows/jazzy-debian-build.yml @@ -17,6 +17,10 @@ on: # Run every day to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} jobs: debian_source_build: diff --git a/.github/workflows/jazzy-pre-commit.yml b/.github/workflows/jazzy-pre-commit.yml index d9ec610bbc..aab5ba52ac 100644 --- a/.github/workflows/jazzy-pre-commit.yml +++ b/.github/workflows/jazzy-pre-commit.yml @@ -6,6 +6,10 @@ on: branches: - master +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: pre-commit: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-pre-commit.yml@master diff --git a/.github/workflows/jazzy-rhel-binary-build.yml b/.github/workflows/jazzy-rhel-binary-build.yml index 0dcc912dab..a6404d2dbd 100644 --- a/.github/workflows/jazzy-rhel-binary-build.yml +++ b/.github/workflows/jazzy-rhel-binary-build.yml @@ -17,6 +17,11 @@ on: # Run every day to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: rhel_semi_binary_build: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master diff --git a/.github/workflows/jazzy-semi-binary-build.yml b/.github/workflows/jazzy-semi-binary-build.yml index 12769eb740..d5e3a96835 100644 --- a/.github/workflows/jazzy-semi-binary-build.yml +++ b/.github/workflows/jazzy-semi-binary-build.yml @@ -1,6 +1,6 @@ name: Jazzy Semi-Binary Build # author: Denis Štogl -# description: 'Build & test all dependencies from released (binary) packages.' +# description: 'Build & test all ros2_control dependencies from source.' on: workflow_dispatch: @@ -32,8 +32,13 @@ on: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: - binary: + semi-binary: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -45,3 +50,14 @@ jobs: ros_repo: ${{ matrix.ROS_REPO }} upstream_workspace: ros2_control.${{ matrix.ROS_DISTRO }}.repos ref_for_scheduled_build: master + semi-binary-clang: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + with: + ros_distro: jazzy + ros_repo: testing + upstream_workspace: ros2_control.jazzy.repos + ref_for_scheduled_build: master + additional_debs: clang + c_compiler: clang + cxx_compiler: clang++ + not_test_build: true diff --git a/.github/workflows/rolling-abi-compatibility.yml b/.github/workflows/rolling-abi-compatibility.yml index a07fecc660..3e30571ea1 100644 --- a/.github/workflows/rolling-abi-compatibility.yml +++ b/.github/workflows/rolling-abi-compatibility.yml @@ -14,6 +14,11 @@ on: - '**/CMakeLists.txt' - 'ros2_control-not-released.rolling.repos' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: abi_check: runs-on: ubuntu-latest diff --git a/.github/workflows/rolling-binary-build.yml b/.github/workflows/rolling-binary-build.yml index 24a28f16ae..0859169b15 100644 --- a/.github/workflows/rolling-binary-build.yml +++ b/.github/workflows/rolling-binary-build.yml @@ -32,6 +32,11 @@ on: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: binary: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master diff --git a/.github/workflows/rolling-check-docs.yml b/.github/workflows/rolling-check-docs.yml index 80e8287abd..8dc02f65c1 100644 --- a/.github/workflows/rolling-check-docs.yml +++ b/.github/workflows/rolling-check-docs.yml @@ -10,6 +10,10 @@ on: - '**.md' - '**.yaml' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: check-docs: name: Check Docs diff --git a/.github/workflows/rolling-compatibility-humble-binary-build.yml b/.github/workflows/rolling-compatibility-humble-binary-build.yml index b55091521e..35957bbc0e 100644 --- a/.github/workflows/rolling-compatibility-humble-binary-build.yml +++ b/.github/workflows/rolling-compatibility-humble-binary-build.yml @@ -29,6 +29,11 @@ on: - '**/CMakeLists.txt' - 'ros2_control.rolling.repos' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: build-on-humble: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master diff --git a/.github/workflows/rolling-compatibility-jazzy-binary-build.yml b/.github/workflows/rolling-compatibility-jazzy-binary-build.yml index 621ffb6a26..bddbd14878 100644 --- a/.github/workflows/rolling-compatibility-jazzy-binary-build.yml +++ b/.github/workflows/rolling-compatibility-jazzy-binary-build.yml @@ -29,6 +29,11 @@ on: - '**/CMakeLists.txt' - 'ros2_control.rolling.repos' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: build-on-jazzy: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master diff --git a/.github/workflows/rolling-coverage-build.yml b/.github/workflows/rolling-coverage-build.yml index 45b10876e7..ad4e467606 100644 --- a/.github/workflows/rolling-coverage-build.yml +++ b/.github/workflows/rolling-coverage-build.yml @@ -28,6 +28,11 @@ on: - 'ros2_control.rolling.repos' - 'codecov.yml' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: coverage_rolling: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-build-coverage.yml@master diff --git a/.github/workflows/rolling-debian-build.yml b/.github/workflows/rolling-debian-build.yml index 00d4ad844b..a54e7ad0d1 100644 --- a/.github/workflows/rolling-debian-build.yml +++ b/.github/workflows/rolling-debian-build.yml @@ -17,6 +17,11 @@ on: # Run every day to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: debian_source_build: diff --git a/.github/workflows/rolling-pre-commit.yml b/.github/workflows/rolling-pre-commit.yml index 7bc07ba802..792278d6d2 100644 --- a/.github/workflows/rolling-pre-commit.yml +++ b/.github/workflows/rolling-pre-commit.yml @@ -6,6 +6,10 @@ on: branches: - master +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: pre-commit: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-pre-commit.yml@master diff --git a/.github/workflows/rolling-rhel-binary-build.yml b/.github/workflows/rolling-rhel-binary-build.yml index b8b572f921..95d6759da6 100644 --- a/.github/workflows/rolling-rhel-binary-build.yml +++ b/.github/workflows/rolling-rhel-binary-build.yml @@ -17,6 +17,10 @@ on: # Run every day to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} jobs: rhel_semi_binary_build: diff --git a/.github/workflows/rolling-semi-binary-build.yml b/.github/workflows/rolling-semi-binary-build.yml index 492da45ab9..6431b9f4fa 100644 --- a/.github/workflows/rolling-semi-binary-build.yml +++ b/.github/workflows/rolling-semi-binary-build.yml @@ -1,6 +1,6 @@ name: Rolling Semi-Binary Build # author: Denis Štogl -# description: 'Build & test all dependencies from released (binary) packages.' +# description: 'Build & test all ros2_control dependencies from source.' on: workflow_dispatch: @@ -32,8 +32,13 @@ on: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * *' +concurrency: + # cancel previous runs of the same workflow, except for pushes on master branch + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + jobs: - binary: + semi-binary: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -45,3 +50,15 @@ jobs: ros_repo: ${{ matrix.ROS_REPO }} upstream_workspace: ros2_control.${{ matrix.ROS_DISTRO }}.repos ref_for_scheduled_build: master + semi-binary-clang: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + with: + # job for building only, no tests -> one distro is enough + ros_distro: rolling + ros_repo: testing + upstream_workspace: ros2_control.rolling.repos + ref_for_scheduled_build: master + additional_debs: clang + c_compiler: clang + cxx_compiler: clang++ + not_test_build: true diff --git a/.github/workflows/rosdoc2.yml b/.github/workflows/rosdoc2.yml index 07a9e2904a..3452796f55 100644 --- a/.github/workflows/rosdoc2.yml +++ b/.github/workflows/rosdoc2.yml @@ -8,6 +8,9 @@ on: - ros2_control/rosdoc2.yaml - ros2_control/package.xml +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: check: diff --git a/controller_interface/include/semantic_components/force_torque_sensor.hpp b/controller_interface/include/semantic_components/force_torque_sensor.hpp index ab55a537ad..c749ed1db8 100644 --- a/controller_interface/include/semantic_components/force_torque_sensor.hpp +++ b/controller_interface/include/semantic_components/force_torque_sensor.hpp @@ -62,7 +62,7 @@ class ForceTorqueSensor : public SemanticComponentInterface(std::count(existing_axes_.begin(), existing_axes_.begin() + 3, true)); for (size_t i = 3; i < 6; ++i) { diff --git a/hardware_interface/src/component_parser.cpp b/hardware_interface/src/component_parser.cpp index e087d39c95..45ee52c852 100644 --- a/hardware_interface/src/component_parser.cpp +++ b/hardware_interface/src/component_parser.cpp @@ -174,7 +174,7 @@ std::size_t parse_size_attribute(const tinyxml2::XMLElement * elem) std::regex int_re("[1-9][0-9]*"); if (std::regex_match(s, int_re)) { - size = std::stoi(s); + size = static_cast(std::stoi(s)); } else { diff --git a/hardware_interface/src/mock_components/generic_system.cpp b/hardware_interface/src/mock_components/generic_system.cpp index fb91961d60..3fb9999b24 100644 --- a/hardware_interface/src/mock_components/generic_system.cpp +++ b/hardware_interface/src/mock_components/generic_system.cpp @@ -144,7 +144,7 @@ CallbackReturn GenericSystem::on_init(const hardware_interface::HardwareInfo & i custom_interface_with_following_offset_ = it->second; } } - // its extremlly improbably that std::distance results int this value - therefore default + // it's extremely improbable that std::distance results in this value - therefore default index_custom_interface_with_following_offset_ = std::numeric_limits::max(); // Initialize storage for standard interfaces @@ -179,7 +179,8 @@ CallbackReturn GenericSystem::on_init(const hardware_interface::HardwareInfo & i } MimicJoint mimic_joint; mimic_joint.joint_index = i; - mimic_joint.mimicked_joint_index = std::distance(info_.joints.begin(), mimicked_joint_it); + mimic_joint.mimicked_joint_index = + static_cast(std::distance(info_.joints.begin(), mimicked_joint_it)); auto param_it = joint.parameters.find("multiplier"); if (param_it != joint.parameters.end()) { @@ -210,7 +211,7 @@ CallbackReturn GenericSystem::on_init(const hardware_interface::HardwareInfo & i if (if_it != other_interfaces_.end()) { index_custom_interface_with_following_offset_ = - std::distance(other_interfaces_.begin(), if_it); + static_cast(std::distance(other_interfaces_.begin(), if_it)); RCUTILS_LOG_INFO_NAMED( "mock_generic_system", "Custom interface with following offset '%s' found at index: %zu.", custom_interface_with_following_offset_.c_str(), @@ -395,7 +396,8 @@ return_type GenericSystem::prepare_command_mode_switch( if (joint_it_found != info_.joints.end()) { - const size_t joint_index = std::distance(info_.joints.begin(), joint_it_found); + const size_t joint_index = + static_cast(std::distance(info_.joints.begin(), joint_it_found)); if (joint_found_in_x_requests_[joint_index] == 0) { joint_found_in_x_requests_[joint_index] = FOUND_ONCE_FLAG; @@ -483,7 +485,8 @@ return_type GenericSystem::perform_command_mode_switch( if (joint_it_found != info_.joints.end()) { - const size_t joint_index = std::distance(info_.joints.begin(), joint_it_found); + const size_t joint_index = + static_cast(std::distance(info_.joints.begin(), joint_it_found)); if (key == info_.joints[joint_index].name + "/" + hardware_interface::HW_IF_POSITION) { @@ -673,7 +676,7 @@ bool GenericSystem::get_interface( auto it = std::find(interface_list.begin(), interface_list.end(), interface_name); if (it != interface_list.end()) { - auto j = std::distance(interface_list.begin(), it); + auto j = static_cast(std::distance(interface_list.begin(), it)); interfaces.emplace_back(name, *it, &values[j][vector_index]); return true; } @@ -706,7 +709,7 @@ void GenericSystem::initialize_storage_vectors( // If interface name is found in the interfaces list if (it != interfaces.end()) { - auto index = std::distance(interfaces.begin(), it); + auto index = static_cast(std::distance(interfaces.begin(), it)); // Check the initial_value param is used if (!interface.initial_value.empty()) diff --git a/hardware_interface/test/test_component_interfaces.cpp b/hardware_interface/test/test_component_interfaces.cpp index d90756c324..6028b2f4cf 100644 --- a/hardware_interface/test/test_component_interfaces.cpp +++ b/hardware_interface/test/test_component_interfaces.cpp @@ -308,7 +308,7 @@ class DummySystem : public hardware_interface::SystemInterface return hardware_interface::return_type::ERROR; } - for (auto i = 0; i < 3; ++i) + for (size_t i = 0; i < 3; ++i) { position_state_[i] += velocity_command_[0]; velocity_state_[i] = velocity_command_[0]; @@ -318,7 +318,7 @@ class DummySystem : public hardware_interface::SystemInterface CallbackReturn on_shutdown(const rclcpp_lifecycle::State & /*previous_state*/) override { - for (auto i = 0ul; i < 3; ++i) + for (size_t i = 0; i < 3; ++i) { velocity_state_[i] = 0.0; } @@ -346,7 +346,7 @@ class DummySystem : public hardware_interface::SystemInterface std::array velocity_state_ = { std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; - std::array velocity_command_ = {0.0, 0.0, 0.0}; + std::array velocity_command_ = {{0.0, 0.0, 0.0}}; // Helper variables to initiate error on read unsigned int read_calls_ = 0; diff --git a/hardware_interface/test/test_macros.cpp b/hardware_interface/test/test_macros.cpp index a7c56849d1..7dc707d58b 100644 --- a/hardware_interface/test/test_macros.cpp +++ b/hardware_interface/test/test_macros.cpp @@ -62,7 +62,7 @@ TEST_F(TestMacros, throw_on_not_null) EXPECT_ANY_THROW(THROW_ON_NOT_NULLPTR(a_ptr)); std::vector vec_ptr; - for (auto i : {0, 1, 2}) + for (size_t i = 0; i < 3; ++i) { vec_ptr.push_back(i_ptr); EXPECT_ANY_THROW(THROW_ON_NOT_NULLPTR(vec_ptr[i])); diff --git a/ros2_control.humble.repos b/ros2_control.humble.repos index 98b2866d38..af5cbc3c26 100644 --- a/ros2_control.humble.repos +++ b/ros2_control.humble.repos @@ -2,7 +2,7 @@ repositories: ros-controls/realtime_tools: type: git url: https://github.com/ros-controls/realtime_tools.git - version: master + version: humble ros-controls/control_msgs: type: git url: https://github.com/ros-controls/control_msgs.git From 5bce7bfde1b4056a2c128dc1e8dc94a972da8574 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:19:38 +0100 Subject: [PATCH 3/4] generate version.h file per package using the ament_generate_version_header (backport #1449) (#1938) --- controller_interface/CMakeLists.txt | 1 + controller_interface/package.xml | 1 + controller_manager/CMakeLists.txt | 1 + controller_manager/package.xml | 1 + hardware_interface/CMakeLists.txt | 1 + hardware_interface/package.xml | 1 + joint_limits/CMakeLists.txt | 22 ++++++++++++++++++++++ joint_limits/package.xml | 1 + transmission_interface/CMakeLists.txt | 1 + transmission_interface/package.xml | 1 + 10 files changed, 31 insertions(+) diff --git a/controller_interface/CMakeLists.txt b/controller_interface/CMakeLists.txt index 4d5454430f..0a380d5a13 100644 --- a/controller_interface/CMakeLists.txt +++ b/controller_interface/CMakeLists.txt @@ -110,3 +110,4 @@ ament_export_libraries( ${PROJECT_NAME} ) ament_package() +ament_generate_version_header(${PROJECT_NAME}) diff --git a/controller_interface/package.xml b/controller_interface/package.xml index f2cdfa56d2..2edf44e015 100644 --- a/controller_interface/package.xml +++ b/controller_interface/package.xml @@ -9,6 +9,7 @@ Apache License 2.0 ament_cmake + ament_cmake_gen_version_h hardware_interface rclcpp_lifecycle diff --git a/controller_manager/CMakeLists.txt b/controller_manager/CMakeLists.txt index 2d46561492..1a53d69bde 100644 --- a/controller_manager/CMakeLists.txt +++ b/controller_manager/CMakeLists.txt @@ -223,3 +223,4 @@ ament_export_dependencies( ${THIS_PACKAGE_INCLUDE_DEPENDS} ) ament_package() +ament_generate_version_header(${PROJECT_NAME}) diff --git a/controller_manager/package.xml b/controller_manager/package.xml index befcf47907..48290c16c5 100644 --- a/controller_manager/package.xml +++ b/controller_manager/package.xml @@ -9,6 +9,7 @@ Apache License 2.0 ament_cmake + ament_cmake_gen_version_h ament_cmake_python ament_index_cpp diff --git a/hardware_interface/CMakeLists.txt b/hardware_interface/CMakeLists.txt index 404fd23101..54474889f8 100644 --- a/hardware_interface/CMakeLists.txt +++ b/hardware_interface/CMakeLists.txt @@ -172,3 +172,4 @@ ament_export_libraries( ) ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS}) ament_package() +ament_generate_version_header(${PROJECT_NAME}) diff --git a/hardware_interface/package.xml b/hardware_interface/package.xml index 24a9c67fe9..f971de3731 100644 --- a/hardware_interface/package.xml +++ b/hardware_interface/package.xml @@ -8,6 +8,7 @@ Apache License 2.0 ament_cmake + ament_cmake_gen_version_h control_msgs lifecycle_msgs diff --git a/joint_limits/CMakeLists.txt b/joint_limits/CMakeLists.txt index f67ce32fc1..9356a96ea4 100644 --- a/joint_limits/CMakeLists.txt +++ b/joint_limits/CMakeLists.txt @@ -17,6 +17,14 @@ find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(rclcpp_lifecycle REQUIRED) +add_library(joint_limits INTERFACE) +target_compile_features(joint_limits INTERFACE cxx_std_17) +target_include_directories(joint_limits INTERFACE + $ + $ +) +ament_target_dependencies(joint_limits INTERFACE ${THIS_PACKAGE_INCLUDE_DEPENDS}) + install(DIRECTORY include/ DESTINATION include ) @@ -45,8 +53,21 @@ if(BUILD_TESTING) endif() +install( + DIRECTORY include/ + DESTINATION include/joint_limits +) +install(TARGETS joint_limits + EXPORT export_joint_limits + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin +) + +ament_export_targets(export_joint_limits HAS_LIBRARY_TARGET) ament_export_dependencies( rclcpp + rclcpp_lifecycle ) ament_export_include_directories( @@ -54,3 +75,4 @@ ament_export_include_directories( ) ament_package() +ament_generate_version_header(${PROJECT_NAME}) diff --git a/joint_limits/package.xml b/joint_limits/package.xml index e3bb18e672..bc2a840efd 100644 --- a/joint_limits/package.xml +++ b/joint_limits/package.xml @@ -13,6 +13,7 @@ https://github.com/ros-controls/ros2_control ament_cmake + ament_cmake_gen_version_h rclcpp rclcpp_lifecycle diff --git a/transmission_interface/CMakeLists.txt b/transmission_interface/CMakeLists.txt index 9e8e1e87eb..f7dd4444b3 100644 --- a/transmission_interface/CMakeLists.txt +++ b/transmission_interface/CMakeLists.txt @@ -106,3 +106,4 @@ ament_export_libraries( ) ament_package() +ament_generate_version_header(${PROJECT_NAME}) diff --git a/transmission_interface/package.xml b/transmission_interface/package.xml index 74d7796a4c..673d4868a9 100644 --- a/transmission_interface/package.xml +++ b/transmission_interface/package.xml @@ -9,6 +9,7 @@ Apache License 2.0 ament_cmake + ament_cmake_gen_version_h hardware_interface pluginlib From 38a56002fd3ffa946445cc065b456548a78fafb2 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 13 Dec 2024 15:35:17 +0100 Subject: [PATCH 4/4] Fix the spawner to support full wildcard parameter entries (backport #1933) (#1939) --- controller_manager/CMakeLists.txt | 3 + .../controller_manager_services.py | 7 ++ controller_manager/doc/userdoc.rst | 86 ++++++++++++------- ...t_controller_spawner_wildcard_entries.yaml | 10 +++ .../test/test_spawner_unspawner.cpp | 65 ++++++++++++++ 5 files changed, 138 insertions(+), 33 deletions(-) create mode 100644 controller_manager/test/test_controller_spawner_wildcard_entries.yaml diff --git a/controller_manager/CMakeLists.txt b/controller_manager/CMakeLists.txt index 1a53d69bde..72b63962da 100644 --- a/controller_manager/CMakeLists.txt +++ b/controller_manager/CMakeLists.txt @@ -192,6 +192,9 @@ if(BUILD_TESTING) install(FILES test/test_controller_overriding_parameters.yaml DESTINATION test) + install(FILES test/test_controller_spawner_wildcard_entries.yaml + DESTINATION test) + ament_add_gmock( test_hardware_management_srvs test/test_hardware_management_srvs.cpp diff --git a/controller_manager/controller_manager/controller_manager_services.py b/controller_manager/controller_manager/controller_manager_services.py index a5148098f0..a401258ab0 100644 --- a/controller_manager/controller_manager/controller_manager_services.py +++ b/controller_manager/controller_manager/controller_manager_services.py @@ -256,6 +256,7 @@ def get_params_files_with_controller_parameters( f"/{controller_name}" if namespace == "/" else f"{namespace}/{controller_name}" ) WILDCARD_KEY = "/**" + ROS_PARAMS_KEY = "ros__parameters" parameters = yaml.safe_load(f) # check for the parameter in 'controller_name' or 'namespaced_controller' or '/**/namespaced_controller' or '/**/controller_name' for key in [ @@ -264,6 +265,8 @@ def get_params_files_with_controller_parameters( f"{WILDCARD_KEY}/{controller_name}", f"{WILDCARD_KEY}{namespaced_controller}", ]: + if parameter_file in controller_parameter_files: + break if key in parameters: if key == controller_name and namespace != "/": node.get_logger().fatal( @@ -274,6 +277,8 @@ def get_params_files_with_controller_parameters( if WILDCARD_KEY in parameters and key in parameters[WILDCARD_KEY]: controller_parameter_files.append(parameter_file) + if WILDCARD_KEY in parameters and ROS_PARAMS_KEY in parameters[WILDCARD_KEY]: + controller_parameter_files.append(parameter_file) return controller_parameter_files @@ -306,6 +311,8 @@ def get_parameter_from_param_files( if WILDCARD_KEY in parameters and key in parameters[WILDCARD_KEY]: controller_param_dict = parameters[WILDCARD_KEY][key] + if WILDCARD_KEY in parameters and ROS_PARAMS_KEY in parameters[WILDCARD_KEY]: + controller_param_dict = parameters[WILDCARD_KEY] if controller_param_dict and ( not isinstance(controller_param_dict, dict) diff --git a/controller_manager/doc/userdoc.rst b/controller_manager/doc/userdoc.rst index 27ded48e5e..dc81c8adef 100644 --- a/controller_manager/doc/userdoc.rst +++ b/controller_manager/doc/userdoc.rst @@ -122,57 +122,77 @@ There are two scripts to interact with controller manager from launch files: The parsed controller config file can follow the same conventions as the typical ROS 2 parameter file format. Now, the spawner can handle config files with wildcard entries and also the controller name in the absolute namespace. See the following examples on the config files: + .. code-block:: yaml + + /**: + ros__parameters: + type: joint_trajectory_controller/JointTrajectoryController + + command_interfaces: + - position + ..... + + position_trajectory_controller_joint1: + ros__parameters: + joints: + - joint1 + + position_trajectory_controller_joint2: + ros__parameters: + joints: + - joint2 + .. code-block:: yaml /**/position_trajectory_controller: - ros__parameters: - type: joint_trajectory_controller/JointTrajectoryController - joints: - - joint1 - - joint2 + ros__parameters: + type: joint_trajectory_controller/JointTrajectoryController + joints: + - joint1 + - joint2 - command_interfaces: - - position - ..... + command_interfaces: + - position + ..... .. code-block:: yaml /position_trajectory_controller: - ros__parameters: - type: joint_trajectory_controller/JointTrajectoryController - joints: - - joint1 - - joint2 + ros__parameters: + type: joint_trajectory_controller/JointTrajectoryController + joints: + - joint1 + - joint2 - command_interfaces: - - position - ..... + command_interfaces: + - position + ..... .. code-block:: yaml position_trajectory_controller: - ros__parameters: - type: joint_trajectory_controller/JointTrajectoryController - joints: - - joint1 - - joint2 + ros__parameters: + type: joint_trajectory_controller/JointTrajectoryController + joints: + - joint1 + - joint2 - command_interfaces: - - position - ..... + command_interfaces: + - position + ..... .. code-block:: yaml /rrbot_1/position_trajectory_controller: - ros__parameters: - type: joint_trajectory_controller/JointTrajectoryController - joints: - - joint1 - - joint2 - - command_interfaces: - - position - ..... + ros__parameters: + type: joint_trajectory_controller/JointTrajectoryController + joints: + - joint1 + - joint2 + + command_interfaces: + - position + ..... ``unspawner`` ^^^^^^^^^^^^^^^^ diff --git a/controller_manager/test/test_controller_spawner_wildcard_entries.yaml b/controller_manager/test/test_controller_spawner_wildcard_entries.yaml new file mode 100644 index 0000000000..1a05ac03d6 --- /dev/null +++ b/controller_manager/test/test_controller_spawner_wildcard_entries.yaml @@ -0,0 +1,10 @@ +/**: + ros__parameters: + type: "controller_manager/test_controller" + joint_names: ["joint1"] + param1: 1.0 + param2: 2.0 + +wildcard_ctrl_3: + ros__parameters: + param3: 3.0 diff --git a/controller_manager/test/test_spawner_unspawner.cpp b/controller_manager/test/test_spawner_unspawner.cpp index a21c3b3b2c..8a0c35a6a3 100644 --- a/controller_manager/test/test_spawner_unspawner.cpp +++ b/controller_manager/test/test_spawner_unspawner.cpp @@ -346,6 +346,71 @@ TEST_F(TestLoadController, spawner_test_type_in_params_file) test_file_path); } +TEST_F(TestLoadController, spawner_test_with_wildcard_entries_with_no_ctrl_name) +{ + const std::string test_file_path = ament_index_cpp::get_package_prefix("controller_manager") + + "/test/test_controller_spawner_wildcard_entries.yaml"; + + ControllerManagerRunner cm_runner(this); + // Provide controller type via the parsed file + EXPECT_EQ( + call_spawner( + "wildcard_ctrl_1 wildcard_ctrl_2 wildcard_ctrl_3 -c test_controller_manager " + "--controller-manager-timeout 1.0 " + "-p " + + test_file_path), + 0); + + auto verify_ctrl_parameter = [](const auto & ctrl_node, bool has_param_3) + { + if (!ctrl_node->has_parameter("joint_names")) + { + ctrl_node->declare_parameter("joint_names", std::vector({"random_joint"})); + } + ASSERT_THAT( + ctrl_node->get_parameter("joint_names").as_string_array(), + std::vector({"joint1"})); + + if (!ctrl_node->has_parameter("param1")) + { + ctrl_node->declare_parameter("param1", -10.0); + } + ASSERT_THAT(ctrl_node->get_parameter("param1").as_double(), 1.0); + + if (!ctrl_node->has_parameter("param2")) + { + ctrl_node->declare_parameter("param2", -10.0); + } + ASSERT_THAT(ctrl_node->get_parameter("param2").as_double(), 2.0); + + if (!ctrl_node->has_parameter("param3")) + { + ctrl_node->declare_parameter("param3", -10.0); + } + ASSERT_THAT(ctrl_node->get_parameter("param3").as_double(), has_param_3 ? 3.0 : -10.0); + }; + + ASSERT_EQ(cm_->get_loaded_controllers().size(), 3ul); + + auto wildcard_ctrl_1 = cm_->get_loaded_controllers()[0]; + ASSERT_EQ(wildcard_ctrl_1.info.name, "wildcard_ctrl_1"); + ASSERT_EQ(wildcard_ctrl_1.info.type, test_controller::TEST_CONTROLLER_CLASS_NAME); + ASSERT_EQ(wildcard_ctrl_1.c->get_state().id(), lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE); + verify_ctrl_parameter(wildcard_ctrl_1.c->get_node(), false); + + auto wildcard_ctrl_2 = cm_->get_loaded_controllers()[1]; + ASSERT_EQ(wildcard_ctrl_2.info.name, "wildcard_ctrl_2"); + ASSERT_EQ(wildcard_ctrl_2.info.type, test_controller::TEST_CONTROLLER_CLASS_NAME); + ASSERT_EQ(wildcard_ctrl_2.c->get_state().id(), lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE); + verify_ctrl_parameter(wildcard_ctrl_2.c->get_node(), false); + + auto wildcard_ctrl_3 = cm_->get_loaded_controllers()[2]; + ASSERT_EQ(wildcard_ctrl_3.info.name, "wildcard_ctrl_3"); + ASSERT_EQ(wildcard_ctrl_3.info.type, test_controller::TEST_CONTROLLER_CLASS_NAME); + ASSERT_EQ(wildcard_ctrl_3.c->get_state().id(), lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE); + verify_ctrl_parameter(wildcard_ctrl_3.c->get_node(), true); +} + TEST_F(TestLoadController, unload_on_kill) { // Launch spawner with unload on kill