From 5954dc4d39922efe2e0b19635101bd704b6c622d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 21:21:45 +0200 Subject: [PATCH 001/108] Add Kilted Kaiju and branch for Jazzy (backport #1646) (#1679) --- .github/mergify.yml | 9 +++ .github/workflows/humble-source-build.yml | 1 - .github/workflows/jazzy-abi-compatibility.yml | 4 +- .github/workflows/jazzy-binary-build.yml | 8 +-- .github/workflows/jazzy-check-docs.yml | 2 +- .github/workflows/jazzy-coverage-build.yml | 63 +++++++++---------- .github/workflows/jazzy-debian-build.yml | 6 +- .github/workflows/jazzy-pre-commit.yml | 2 +- .../jazzy-rhel-semi-binary-build.yml | 6 +- .github/workflows/jazzy-semi-binary-build.yml | 10 +-- .../jazzy-semi-binary-downstream-build.yml | 6 +- .github/workflows/jazzy-source-build.yml | 5 +- .../workflows/rolling-abi-compatibility.yml | 7 ++- .github/workflows/rolling-binary-build.yml | 7 ++- ...ling-compatibility-kilted-binary-build.yml | 50 +++++++++++++++ .github/workflows/rolling-debian-build.yml | 9 ++- .github/workflows/rolling-pre-commit.yml | 6 +- .../rolling-rhel-semi-binary-build.yml | 9 ++- .../workflows/rolling-semi-binary-build.yml | 18 ++++-- .../rolling-semi-binary-downstream-build.yml | 5 +- .github/workflows/rolling-source-build.yml | 8 ++- README.md | 7 ++- doc/migration.rst | 4 +- doc/release_notes.rst | 4 +- downstream.kilted.repos | 5 ++ ros2_controllers-not-released.kilted.repos | 6 ++ ros2_controllers.jazzy.repos | 2 +- ros2_controllers.kilted.repos | 25 ++++++++ ros_controls.kilted.repos | 9 +++ 29 files changed, 221 insertions(+), 82 deletions(-) create mode 100644 .github/workflows/rolling-compatibility-kilted-binary-build.yml create mode 100644 downstream.kilted.repos create mode 100644 ros2_controllers-not-released.kilted.repos create mode 100644 ros2_controllers.kilted.repos create mode 100644 ros_controls.kilted.repos diff --git a/.github/mergify.yml b/.github/mergify.yml index 84ad380e90..44f51cf58f 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -8,6 +8,15 @@ pull_request_rules: branches: - humble + - name: Backport to jazzy at reviewers discretion + conditions: + - base=master + - "label=backport-jazzy" + actions: + backport: + branches: + - jazzy + - name: Ask to resolve conflict conditions: - conflict diff --git a/.github/workflows/humble-source-build.yml b/.github/workflows/humble-source-build.yml index 841aa86bfe..5a56849e9b 100644 --- a/.github/workflows/humble-source-build.yml +++ b/.github/workflows/humble-source-build.yml @@ -25,5 +25,4 @@ jobs: with: ros_distro: humble ref: humble - ros2_repo_branch: humble os_name: ubuntu-22.04 diff --git a/.github/workflows/jazzy-abi-compatibility.yml b/.github/workflows/jazzy-abi-compatibility.yml index 82fadb55a1..f4647b334a 100644 --- a/.github/workflows/jazzy-abi-compatibility.yml +++ b/.github/workflows/jazzy-abi-compatibility.yml @@ -3,7 +3,7 @@ on: workflow_dispatch: pull_request: branches: - - master + - jazzy paths: - '**.hpp' - '**.h' @@ -16,7 +16,7 @@ on: - '**.xml' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on jazzy branch group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} diff --git a/.github/workflows/jazzy-binary-build.yml b/.github/workflows/jazzy-binary-build.yml index fb68d930e4..7cf26806a7 100644 --- a/.github/workflows/jazzy-binary-build.yml +++ b/.github/workflows/jazzy-binary-build.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: pull_request: branches: - - master + - jazzy - '*feature*' - '*feature/**' paths: @@ -22,7 +22,7 @@ on: - '**.xml' push: branches: - - master + - jazzy paths: - '**.hpp' - '**.h' @@ -38,7 +38,7 @@ on: - cron: '03 1 * * *' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on jazzy branch group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} @@ -53,4 +53,4 @@ jobs: ros_distro: jazzy ros_repo: ${{ matrix.ROS_REPO }} upstream_workspace: ros2_controllers-not-released.jazzy.repos - ref_for_scheduled_build: master + ref_for_scheduled_build: jazzy diff --git a/.github/workflows/jazzy-check-docs.yml b/.github/workflows/jazzy-check-docs.yml index cfc67a3eac..72a5332d89 100644 --- a/.github/workflows/jazzy-check-docs.yml +++ b/.github/workflows/jazzy-check-docs.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: pull_request: branches: - - master + - jazzy paths: - '**.rst' - '**.md' diff --git a/.github/workflows/jazzy-coverage-build.yml b/.github/workflows/jazzy-coverage-build.yml index 2f587c7003..3e4d617ced 100644 --- a/.github/workflows/jazzy-coverage-build.yml +++ b/.github/workflows/jazzy-coverage-build.yml @@ -1,40 +1,39 @@ name: Coverage Build - Jazzy on: workflow_dispatch: - # TODO(anyone) activate when branched for Jazzy - # push: - # branches: - # - master - # paths: - # - '**.hpp' - # - '**.h' - # - '**.cpp' - # - '.github/workflows/jazzy-coverage-build.yml' - # - '**.yaml' - # - '**/package.xml' - # - '**/CMakeLists.txt' - # - 'codecov.yml' - # - '**/package.xml' - # - '**/CMakeLists.txt' - # - 'ros2_controllers.jazzy.repos' - # pull_request: - # branches: - # - master - # paths: - # - '**.hpp' - # - '**.h' - # - '**.cpp' - # - '.github/workflows/jazzy-coverage-build.yml' - # - '**.yaml' - # - '**/package.xml' - # - '**/CMakeLists.txt' - # - 'codecov.yml' - # - '**/package.xml' - # - '**/CMakeLists.txt' - # - 'ros2_controllers.jazzy.repos' + push: + branches: + - jazzy + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '.github/workflows/jazzy-coverage-build.yml' + - '**.yaml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'codecov.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.jazzy.repos' + pull_request: + branches: + - jazzy + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '.github/workflows/jazzy-coverage-build.yml' + - '**.yaml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'codecov.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.jazzy.repos' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on jazzy branch group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} diff --git a/.github/workflows/jazzy-debian-build.yml b/.github/workflows/jazzy-debian-build.yml index ef1b42da8d..4fa94e190f 100644 --- a/.github/workflows/jazzy-debian-build.yml +++ b/.github/workflows/jazzy-debian-build.yml @@ -3,7 +3,7 @@ on: workflow_dispatch: pull_request: branches: - - master + - jazzy paths: - '**.hpp' - '**.h' @@ -20,7 +20,7 @@ on: - cron: '03 1 * * *' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on jazzy branch group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} @@ -31,5 +31,5 @@ jobs: with: ros_distro: jazzy upstream_workspace: ros2_controllers.jazzy.repos - ref_for_scheduled_build: master + ref_for_scheduled_build: jazzy skip_packages: rqt_joint_trajectory_controller diff --git a/.github/workflows/jazzy-pre-commit.yml b/.github/workflows/jazzy-pre-commit.yml index aab5ba52ac..44d825a34a 100644 --- a/.github/workflows/jazzy-pre-commit.yml +++ b/.github/workflows/jazzy-pre-commit.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: pull_request: branches: - - master + - jazzy concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/jazzy-rhel-semi-binary-build.yml b/.github/workflows/jazzy-rhel-semi-binary-build.yml index ed09d0efb9..f5e8aedc14 100644 --- a/.github/workflows/jazzy-rhel-semi-binary-build.yml +++ b/.github/workflows/jazzy-rhel-semi-binary-build.yml @@ -3,7 +3,7 @@ on: workflow_dispatch: pull_request: branches: - - master + - jazzy paths: - '**.hpp' - '**.h' @@ -20,7 +20,7 @@ on: - cron: '03 1 * * *' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on jazzy branch group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} @@ -30,5 +30,5 @@ jobs: with: ros_distro: jazzy upstream_workspace: ros2_controllers.jazzy.repos - ref_for_scheduled_build: master + ref_for_scheduled_build: jazzy skip_packages: rqt_joint_trajectory_controller diff --git a/.github/workflows/jazzy-semi-binary-build.yml b/.github/workflows/jazzy-semi-binary-build.yml index 5a39ea5393..a150580bbc 100644 --- a/.github/workflows/jazzy-semi-binary-build.yml +++ b/.github/workflows/jazzy-semi-binary-build.yml @@ -5,7 +5,7 @@ on: workflow_dispatch: pull_request: branches: - - master + - jazzy - '*feature*' - '*feature/**' paths: @@ -21,7 +21,7 @@ on: - '**.xml' push: branches: - - master + - jazzy paths: - '**.hpp' - '**.h' @@ -38,7 +38,7 @@ on: - cron: '33 1 * * *' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on jazzy branch group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} @@ -49,14 +49,14 @@ jobs: ros_distro: jazzy ros_repo: testing upstream_workspace: ros2_controllers.jazzy.repos - ref_for_scheduled_build: master + ref_for_scheduled_build: jazzy 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_controllers.jazzy.repos - ref_for_scheduled_build: master + ref_for_scheduled_build: jazzy additional_debs: clang c_compiler: clang cxx_compiler: clang++ diff --git a/.github/workflows/jazzy-semi-binary-downstream-build.yml b/.github/workflows/jazzy-semi-binary-downstream-build.yml index a2db0ef7b6..d1627ccc42 100644 --- a/.github/workflows/jazzy-semi-binary-downstream-build.yml +++ b/.github/workflows/jazzy-semi-binary-downstream-build.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: pull_request: branches: - - master + - jazzy paths: - '**.hpp' - '**.h' @@ -29,7 +29,7 @@ jobs: with: ros_distro: jazzy ros_repo: testing - ref_for_scheduled_build: master + ref_for_scheduled_build: jazzy upstream_workspace: ros2_controllers.jazzy.repos # we don't test this repository, we just build it not_test_build: true @@ -41,7 +41,7 @@ jobs: with: ros_distro: jazzy ros_repo: testing - ref_for_scheduled_build: master + ref_for_scheduled_build: jazzy upstream_workspace: ros2_controllers.jazzy.repos # we don't test this repository, we just build it not_test_build: true diff --git a/.github/workflows/jazzy-source-build.yml b/.github/workflows/jazzy-source-build.yml index 76c9bd2892..bd521c9b59 100644 --- a/.github/workflows/jazzy-source-build.yml +++ b/.github/workflows/jazzy-source-build.yml @@ -3,7 +3,7 @@ on: workflow_dispatch: push: branches: - - master + - jazzy paths: - '**.hpp' - '**.h' @@ -24,6 +24,5 @@ jobs: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-ros-tooling-source-build.yml@master with: ros_distro: jazzy - ref: master - ros2_repo_branch: jazzy + ref: jazzy container: ubuntu:24.04 diff --git a/.github/workflows/rolling-abi-compatibility.yml b/.github/workflows/rolling-abi-compatibility.yml index e3cd45c970..56b7894308 100644 --- a/.github/workflows/rolling-abi-compatibility.yml +++ b/.github/workflows/rolling-abi-compatibility.yml @@ -13,6 +13,7 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers-not-released.rolling.repos' + - 'ros2_controllers-not-released.kilted.repos' - '**.xml' concurrency: @@ -23,5 +24,9 @@ concurrency: jobs: abi_check: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-abi-check.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [kilted, rolling] with: - ros_distro: rolling + ros_distro: ${{ matrix.ROS_DISTRO }} diff --git a/.github/workflows/rolling-binary-build.yml b/.github/workflows/rolling-binary-build.yml index 1fd126f43c..701bc170a7 100644 --- a/.github/workflows/rolling-binary-build.yml +++ b/.github/workflows/rolling-binary-build.yml @@ -19,6 +19,7 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers-not-released.rolling.repos' + - 'ros2_controllers-not-released.kilted.repos' - '**.xml' push: branches: @@ -33,6 +34,7 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers-not-released.rolling.repos' + - 'ros2_controllers-not-released.kilted.repos' - '**.xml' schedule: # Run every morning to detect flakiness and broken dependencies @@ -49,9 +51,10 @@ jobs: strategy: fail-fast: false matrix: + ROS_DISTRO: [kilted, rolling] ROS_REPO: [main, testing] with: - ros_distro: rolling + ros_distro: ${{ matrix.ROS_DISTRO }} ros_repo: ${{ matrix.ROS_REPO }} - upstream_workspace: ros2_controllers-not-released.rolling.repos + upstream_workspace: ros2_controllers-not-released.${{ matrix.ROS_DISTRO }}.repos ref_for_scheduled_build: master diff --git a/.github/workflows/rolling-compatibility-kilted-binary-build.yml b/.github/workflows/rolling-compatibility-kilted-binary-build.yml new file mode 100644 index 0000000000..44ff443346 --- /dev/null +++ b/.github/workflows/rolling-compatibility-kilted-binary-build.yml @@ -0,0 +1,50 @@ +name: Check Rolling Compatibility on Kilted +# author: Christoph Froehlich +# description: 'Build & test the rolling version on Kilted distro.' + +on: + workflow_dispatch: + pull_request: + branches: + - master + - '*feature*' + - '*feature/**' + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '**.yaml' + - '.github/workflows/rolling-compatibility-kilted-binary-build.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.rolling.repos' + - '**.xml' + push: + branches: + - master + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '**.yaml' + - '.github/workflows/rolling-compatibility-kilted-binary-build.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.rolling.repos' + - '**.xml' + +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-kilted: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + with: + ros_distro: kilted + ros_repo: testing + upstream_workspace: ros2_controllers.rolling.repos + ref_for_scheduled_build: master diff --git a/.github/workflows/rolling-debian-build.yml b/.github/workflows/rolling-debian-build.yml index 23c9aaf834..059b71cfed 100644 --- a/.github/workflows/rolling-debian-build.yml +++ b/.github/workflows/rolling-debian-build.yml @@ -14,6 +14,7 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers.rolling.repos' + - 'ros2_controllers.kilted.repos' - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies @@ -28,8 +29,12 @@ jobs: rolling_debian: name: Rolling debian build uses: ros-controls/ros2_control_ci/.github/workflows/reusable-debian-build.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [kilted, rolling] with: - ros_distro: rolling - upstream_workspace: ros2_controllers.rolling.repos + ros_distro: ${{ matrix.ROS_DISTRO }} + upstream_workspace: ros2_controllers.${{ matrix.ROS_DISTRO }}.repos ref_for_scheduled_build: master skip_packages: rqt_joint_trajectory_controller diff --git a/.github/workflows/rolling-pre-commit.yml b/.github/workflows/rolling-pre-commit.yml index 792278d6d2..f323ebfe73 100644 --- a/.github/workflows/rolling-pre-commit.yml +++ b/.github/workflows/rolling-pre-commit.yml @@ -13,5 +13,9 @@ concurrency: jobs: pre-commit: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-pre-commit.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [kilted, rolling] with: - ros_distro: rolling + ros_distro: ${{ matrix.ROS_DISTRO }} diff --git a/.github/workflows/rolling-rhel-semi-binary-build.yml b/.github/workflows/rolling-rhel-semi-binary-build.yml index c1abdb3c5c..e7d80da8fc 100644 --- a/.github/workflows/rolling-rhel-semi-binary-build.yml +++ b/.github/workflows/rolling-rhel-semi-binary-build.yml @@ -14,6 +14,7 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers.rolling.repos' + - 'ros2_controllers.kilted.repos' - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies @@ -27,8 +28,12 @@ concurrency: jobs: rolling_rhel: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [kilted, rolling] with: - ros_distro: rolling - upstream_workspace: ros2_controllers.rolling.repos + ros_distro: ${{ matrix.ROS_DISTRO }} + upstream_workspace: ros2_controllers.${{ matrix.ROS_DISTRO }}.repos ref_for_scheduled_build: master skip_packages: rqt_joint_trajectory_controller diff --git a/.github/workflows/rolling-semi-binary-build.yml b/.github/workflows/rolling-semi-binary-build.yml index 6521e90b5c..631e478e02 100644 --- a/.github/workflows/rolling-semi-binary-build.yml +++ b/.github/workflows/rolling-semi-binary-build.yml @@ -18,6 +18,7 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers.rolling.repos' + - 'ros2_controllers.kilted.repos' - '**.xml' push: branches: @@ -32,6 +33,7 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers.rolling.repos' + - 'ros2_controllers.kilted.repos' - '**.xml' schedule: # Run every morning to detect flakiness and broken dependencies @@ -45,17 +47,25 @@ concurrency: jobs: semi_binary: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [kilted, rolling] with: - ros_distro: rolling + ros_distro: ${{ matrix.ROS_DISTRO }} ros_repo: testing - upstream_workspace: ros2_controllers.rolling.repos + upstream_workspace: ros2_controllers.${{ 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 + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [kilted, rolling] with: - ros_distro: rolling + ros_distro: ${{ matrix.ROS_DISTRO }} ros_repo: testing - upstream_workspace: ros2_controllers.rolling.repos + upstream_workspace: ros2_controllers.${{ matrix.ROS_DISTRO }}.repos ref_for_scheduled_build: master additional_debs: clang c_compiler: clang diff --git a/.github/workflows/rolling-semi-binary-downstream-build.yml b/.github/workflows/rolling-semi-binary-downstream-build.yml index 02ed08578b..a392336c7f 100644 --- a/.github/workflows/rolling-semi-binary-downstream-build.yml +++ b/.github/workflows/rolling-semi-binary-downstream-build.yml @@ -17,6 +17,7 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros_controls.rolling.repos' + - 'ros_controls.kilted.repos' - '**.xml' concurrency: @@ -29,7 +30,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [rolling] + ROS_DISTRO: [kilted, rolling] with: ros_distro: ${{ matrix.ROS_DISTRO }} ros_repo: testing @@ -45,7 +46,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [rolling] + ROS_DISTRO: [kilted, rolling] with: ros_distro: ${{ matrix.ROS_DISTRO }} ros_repo: testing diff --git a/.github/workflows/rolling-source-build.yml b/.github/workflows/rolling-source-build.yml index e409150974..26a50dc47e 100644 --- a/.github/workflows/rolling-source-build.yml +++ b/.github/workflows/rolling-source-build.yml @@ -14,6 +14,7 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers.rolling.repos' + - 'ros2_controllers.kilted.repos' - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies @@ -22,8 +23,11 @@ on: jobs: source: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-ros-tooling-source-build.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [kilted, rolling] with: - ros_distro: rolling + ros_distro: ${{ matrix.ROS_DISTRO }} ref: master - ros2_repo_branch: rolling container: ubuntu:24.04 diff --git a/README.md b/README.md index bbc9d52c34..fe82c65629 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,10 @@ If you are new to the project, please read the [contributing guide](https://cont ROS2 Distro | Branch | Build status | Documentation | Released packages :---------: | :----: | :----------: | :-----------: | :---------------: -**Rolling** | [`master`](https://github.com/ros-controls/ros2_controllers/tree/master) | [![Rolling Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-binary-build.yml?branch=master)
[![Rolling Semi-Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-semi-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-semi-binary-build.yml?branch=master)
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Rdev__ros2_controllers__ubuntu_noble_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Rdev__ros2_controllers__ubuntu_noble_amd64/) | [control.ros.org](https://control.ros.org/master/doc/ros2_controllers/doc/controllers_index.html) | [ros2_controllers](https://index.ros.org/p/ros2_controllers/#rolling) -**Jazzy** | [`master`](https://github.com/ros-controls/ros2_controllers/tree/master) | [![Jazzy Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-binary-build.yml?branch=master)
[![Jazzy Semi-Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-semi-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-semi-binary-build.yml?branch=master)
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Jdev__ros2_controllers__ubuntu_noble_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Jdev__ros2_controllers__ubuntu_noble_amd64/) | [control.ros.org](https://control.ros.org/jazzy/doc/ros2_controllers/doc/controllers_index.html) | [ros2_controllers](https://index.ros.org/p/ros2_controllers/#jazzy) -**Humble** | [`humble`](https://github.com/ros-controls/ros2_controllers/tree/humble) | [![Humble Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-binary-build.yml?branch=master)
[![Humble Semi-Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-semi-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-semi-binary-build.yml?branch=master)
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Hdev__ros2_controllers__ubuntu_jammy_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Hdev__ros2_controllers__ubuntu_jammy_amd64/) | [control.ros.org](https://control.ros.org/humble/doc/ros2_controllers/doc/controllers_index.html) | [ros2_controllers](https://index.ros.org/p/ros2_controllers/#humble) +**Rolling** | [`master`](https://github.com/ros-controls/ros2_controllers/tree/master) | [![Rolling Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-binary-build.yml?branch=master)
[![Rolling Semi-Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-semi-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-semi-binary-build.yml?branch=master)
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Rdev__ros2_controllers__ubuntu_noble_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Rdev__ros2_controllers__ubuntu_noble_amd64/) | [control.ros.org](https://control.ros.org/master/doc/ros2_controllers/doc/controllers_index.html) | [![Build Status](https://build.ros2.org/buildStatus/icon?job=Rbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary)](https://build.ros2.org/job/Rbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary/) +**Kilted** | [`master`](https://github.com/ros-controls/ros2_controllers/tree/master) | see above
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Kdev__ros2_controllers__ubuntu_noble_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Kdev__ros2_controllers__ubuntu_noble_amd64/) | [control.ros.org](https://control.ros.org/master/doc/ros2_controllers/doc/controllers_index.html) | [![Build Status](https://build.ros2.org/buildStatus/icon?job=Kbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary)](https://build.ros2.org/job/Kbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary/) +**Jazzy** | [`jazzy`](https://github.com/ros-controls/ros2_controllers/tree/jazzy) | [![Jazzy Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-binary-build.yml?branch=master)
[![Jazzy Semi-Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-semi-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-semi-binary-build.yml?branch=master)
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Jdev__ros2_controllers__ubuntu_noble_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Jdev__ros2_controllers__ubuntu_noble_amd64/) | [control.ros.org](https://control.ros.org/jazzy/doc/ros2_controllers/doc/controllers_index.html) | [![Build Status](https://build.ros2.org/buildStatus/icon?job=Jbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary)](https://build.ros2.org/job/Jbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary/) +**Humble** | [`humble`](https://github.com/ros-controls/ros2_controllers/tree/humble) | [![Humble Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-binary-build.yml?branch=master)
[![Humble Semi-Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-semi-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-semi-binary-build.yml?branch=master)
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Hdev__ros2_controllers__ubuntu_jammy_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Hdev__ros2_controllers__ubuntu_jammy_amd64/) | [control.ros.org](https://control.ros.org/humble/doc/ros2_controllers/doc/controllers_index.html) | [![Build Status](https://build.ros2.org/buildStatus/icon?job=Hbin_uJ64__ros2_controllers__ubuntu_jammy_amd64__binary)](https://build.ros2.org/job/Hbin_uJ64__ros2_controllers__ubuntu_jammy_amd64__binary/) ## Acknowledgements diff --git a/doc/migration.rst b/doc/migration.rst index 34c4eaa419..ee553e9d26 100644 --- a/doc/migration.rst +++ b/doc/migration.rst @@ -1,8 +1,8 @@ :github_url: https://github.com/ros-controls/ros2_controllers/blob/{REPOS_FILE_BRANCH}/doc/migration.rst -Migration Guides: Iron to Jazzy +Migration Guides: Humble to Jazzy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This list summarizes important changes between Iron (previous) and Jazzy (current) releases, where changes to user code might be necessary. +This list summarizes important changes between Humble (previous) and Jazzy (current) releases, where changes to user code might be necessary. diff_drive_controller diff --git a/doc/release_notes.rst b/doc/release_notes.rst index d407917374..0cbf4a3524 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -1,8 +1,8 @@ :github_url: https://github.com/ros-controls/ros2_controllers/blob/{REPOS_FILE_BRANCH}/doc/release_notes.rst -Release Notes: Iron to Jazzy +Release Notes: Humble to Jazzy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This list summarizes the changes between Iron (previous) and Jazzy (current) releases. +This list summarizes the changes between Humble (previous) and Jazzy (current) releases. admittance_controller ************************ diff --git a/downstream.kilted.repos b/downstream.kilted.repos new file mode 100644 index 0000000000..e5a26574b7 --- /dev/null +++ b/downstream.kilted.repos @@ -0,0 +1,5 @@ +repositories: + UniversalRobots/Universal_Robots_ROS2_Driver: + type: git + url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver.git + version: main diff --git a/ros2_controllers-not-released.kilted.repos b/ros2_controllers-not-released.kilted.repos new file mode 100644 index 0000000000..1b3910e7e7 --- /dev/null +++ b/ros2_controllers-not-released.kilted.repos @@ -0,0 +1,6 @@ +repositories: + ## EXAMPLE DEPENDENCY +# : +# type: git +# url: git@github.com:/.git +# version: master diff --git a/ros2_controllers.jazzy.repos b/ros2_controllers.jazzy.repos index d4db80a0ae..c1f9472e57 100644 --- a/ros2_controllers.jazzy.repos +++ b/ros2_controllers.jazzy.repos @@ -2,7 +2,7 @@ repositories: ros2_control: type: git url: https://github.com/ros-controls/ros2_control.git - version: master + version: jazzy realtime_tools: type: git url: https://github.com/ros-controls/realtime_tools.git diff --git a/ros2_controllers.kilted.repos b/ros2_controllers.kilted.repos new file mode 100644 index 0000000000..f6462c4b4f --- /dev/null +++ b/ros2_controllers.kilted.repos @@ -0,0 +1,25 @@ +repositories: + ros2_control: + type: git + url: https://github.com/ros-controls/ros2_control.git + version: master + realtime_tools: + type: git + url: https://github.com/ros-controls/realtime_tools.git + version: master + control_msgs: + type: git + url: https://github.com/ros-controls/control_msgs.git + version: master + control_toolbox: + type: git + url: https://github.com/ros-controls/control_toolbox.git + version: ros2-master + kinematics_interface: + type: git + url: https://github.com/ros-controls/kinematics_interface.git + version: master + ros2_control_cmake: + type: git + url: https://github.com/ros-controls/ros2_control_cmake.git + version: master diff --git a/ros_controls.kilted.repos b/ros_controls.kilted.repos new file mode 100644 index 0000000000..da64a510fd --- /dev/null +++ b/ros_controls.kilted.repos @@ -0,0 +1,9 @@ +repositories: + ros-controls/gz_ros2_control: + type: git + url: https://github.com/ros-controls/gz_ros2_control.git + version: rolling + ros-controls/ros2_control_demos: + type: git + url: https://github.com/ros-controls/ros2_control_demos.git + version: master From 0e84da49f54f0914c545f1169fd47494d8ba08e6 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 18:16:14 +0200 Subject: [PATCH 002/108] Simplify `on_set_chained_mode` avoiding cpplint warnings (backport #1564) (#1688) Co-authored-by: Bhagyesh Agresar <82998852+bhagyeshagresar@users.noreply.github.com> --- diff_drive_controller/src/diff_drive_controller.cpp | 6 +----- mecanum_drive_controller/src/mecanum_drive_controller.cpp | 6 +----- pid_controller/src/pid_controller.cpp | 6 +----- .../src/steering_controllers_library.cpp | 6 +----- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/diff_drive_controller/src/diff_drive_controller.cpp b/diff_drive_controller/src/diff_drive_controller.cpp index c3554dfecb..fdc79c131d 100644 --- a/diff_drive_controller/src/diff_drive_controller.cpp +++ b/diff_drive_controller/src/diff_drive_controller.cpp @@ -703,11 +703,7 @@ controller_interface::CallbackReturn DiffDriveController::configure_side( return controller_interface::CallbackReturn::SUCCESS; } -bool DiffDriveController::on_set_chained_mode(bool chained_mode) -{ - // Always accept switch to/from chained mode (without linting type-cast error) - return true || chained_mode; -} +bool DiffDriveController::on_set_chained_mode(bool /*chained_mode*/) { return true; } std::vector DiffDriveController::on_export_reference_interfaces() diff --git a/mecanum_drive_controller/src/mecanum_drive_controller.cpp b/mecanum_drive_controller/src/mecanum_drive_controller.cpp index 3ec118bf8c..0d0f1e49f8 100644 --- a/mecanum_drive_controller/src/mecanum_drive_controller.cpp +++ b/mecanum_drive_controller/src/mecanum_drive_controller.cpp @@ -298,11 +298,7 @@ MecanumDriveController::on_export_reference_interfaces() return reference_interfaces; } -bool MecanumDriveController::on_set_chained_mode(bool chained_mode) -{ - // Always accept switch to/from chained mode - return true || chained_mode; -} +bool MecanumDriveController::on_set_chained_mode(bool /*chained_mode*/) { return true; } controller_interface::CallbackReturn MecanumDriveController::on_activate( const rclcpp_lifecycle::State & /*previous_state*/) diff --git a/pid_controller/src/pid_controller.cpp b/pid_controller/src/pid_controller.cpp index e0ef70ffac..c267f11bb2 100644 --- a/pid_controller/src/pid_controller.cpp +++ b/pid_controller/src/pid_controller.cpp @@ -425,11 +425,7 @@ std::vector PidController::on_export_state_i return state_interfaces; } -bool PidController::on_set_chained_mode(bool chained_mode) -{ - // Always accept switch to/from chained mode - return true || chained_mode; -} +bool PidController::on_set_chained_mode(bool /*chained_mode*/) { return true; } controller_interface::CallbackReturn PidController::on_activate( const rclcpp_lifecycle::State & /*previous_state*/) diff --git a/steering_controllers_library/src/steering_controllers_library.cpp b/steering_controllers_library/src/steering_controllers_library.cpp index 3840e2803b..f34b3a78e0 100644 --- a/steering_controllers_library/src/steering_controllers_library.cpp +++ b/steering_controllers_library/src/steering_controllers_library.cpp @@ -513,11 +513,7 @@ SteeringControllersLibrary::on_export_reference_interfaces() return reference_interfaces; } -bool SteeringControllersLibrary::on_set_chained_mode(bool chained_mode) -{ - // Always accept switch to/from chained mode - return true || chained_mode; -} +bool SteeringControllersLibrary::on_set_chained_mode(bool /*chained_mode*/) { return true; } controller_interface::CallbackReturn SteeringControllersLibrary::on_activate( const rclcpp_lifecycle::State & /*previous_state*/) From 2d4359c4616a1c8724bd8dbebb674f4d6cb7d949 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 18:18:30 +0200 Subject: [PATCH 003/108] Add multiplier support to ForceTorqueSensorBroadcaster (backport #1647) (#1686) Co-authored-by: edward.ix --- doc/release_notes.rst | 4 ++ .../force_torque_sensor_broadcaster.hpp | 1 + .../src/force_torque_sensor_broadcaster.cpp | 12 ++++ ..._torque_sensor_broadcaster_parameters.yaml | 33 +++++++++ .../test_force_torque_sensor_broadcaster.cpp | 70 +++++++++++++++++++ 5 files changed, 120 insertions(+) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 0cbf4a3524..fe2f7e5d5b 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -80,3 +80,7 @@ tricycle_controller gpio_controllers ************************ * The GPIO command controller was added 🎉 (`#1251 `_). + +force_torque_sensor_broadcaster +******************************* +* Multiplier support was added. Users can now specify per–axis scaling factors for both force and torque readings, applied after the existing offset logic. (`#1647 `__. diff --git a/force_torque_sensor_broadcaster/include/force_torque_sensor_broadcaster/force_torque_sensor_broadcaster.hpp b/force_torque_sensor_broadcaster/include/force_torque_sensor_broadcaster/force_torque_sensor_broadcaster.hpp index 34b7f242ee..0c8ce438f1 100644 --- a/force_torque_sensor_broadcaster/include/force_torque_sensor_broadcaster/force_torque_sensor_broadcaster.hpp +++ b/force_torque_sensor_broadcaster/include/force_torque_sensor_broadcaster/force_torque_sensor_broadcaster.hpp @@ -61,6 +61,7 @@ class ForceTorqueSensorBroadcaster : public controller_interface::ChainableContr protected: void apply_sensor_offset(const Params & params, geometry_msgs::msg::WrenchStamped & msg); + void apply_sensor_multiplier(const Params & params, geometry_msgs::msg::WrenchStamped & msg); std::shared_ptr param_listener_; Params params_; diff --git a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp index ef5e74e89b..8f8d419af1 100644 --- a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp @@ -175,6 +175,7 @@ controller_interface::return_type ForceTorqueSensorBroadcaster::update_and_write realtime_publisher_->msg_.header.stamp = time; force_torque_sensor_->get_values_as_message(realtime_publisher_->msg_.wrench); this->apply_sensor_offset(params_, realtime_publisher_->msg_); + this->apply_sensor_multiplier(params_, realtime_publisher_->msg_); realtime_publisher_->unlockAndPublish(); } @@ -267,6 +268,17 @@ void ForceTorqueSensorBroadcaster::apply_sensor_offset( msg.wrench.torque.y += params.offset.torque.y; msg.wrench.torque.z += params.offset.torque.z; } + +void ForceTorqueSensorBroadcaster::apply_sensor_multiplier( + const Params & params, geometry_msgs::msg::WrenchStamped & msg) +{ + msg.wrench.force.x *= params.multiplier.force.x; + msg.wrench.force.y *= params.multiplier.force.y; + msg.wrench.force.z *= params.multiplier.force.z; + msg.wrench.torque.x *= params.multiplier.torque.x; + msg.wrench.torque.y *= params.multiplier.torque.y; + msg.wrench.torque.z *= params.multiplier.torque.z; +} } // namespace force_torque_sensor_broadcaster #include "pluginlib/class_list_macros.hpp" diff --git a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster_parameters.yaml b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster_parameters.yaml index 0869f5cf3c..47c36b3b14 100644 --- a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster_parameters.yaml +++ b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster_parameters.yaml @@ -79,3 +79,36 @@ force_torque_sensor_broadcaster: default_value: 0.0, description: "The offset of torque values around 'z' axis.", } + multiplier: + force: + x: { + type: double, + default_value: 1.0, + description: "The multiplier of force value on 'x' axis.", + } + y: { + type: double, + default_value: 1.0, + description: "The multiplier of force value on 'y' axis.", + } + z: { + type: double, + default_value: 1.0, + description: "The multiplier of force value on 'z' axis.", + } + torque: + x: { + type: double, + default_value: 1.0, + description: "The multiplier of torque value around 'x' axis.", + } + y: { + type: double, + default_value: 1.0, + description: "The multiplier of torque value around 'y' axis.", + } + z: { + type: double, + default_value: 1.0, + description: "The multiplier of torque value around 'z' axis.", + } diff --git a/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp b/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp index f6781aab04..60acf093e8 100644 --- a/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp @@ -355,6 +355,76 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success_with_Offsets } } +TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success_with_Multipliers) +{ + SetUpFTSBroadcaster(); + + // some non‐trivial multipliers + std::array force_multipliers = {{2.0, 0.5, -1.0}}; + std::array torque_multipliers = {{-2.0, 3.0, 0.0}}; + + // Set the required params + fts_broadcaster_->get_node()->set_parameter({"sensor_name", sensor_name_}); + fts_broadcaster_->get_node()->set_parameter({"frame_id", frame_id_}); + + // Set all multiplier parameters + fts_broadcaster_->get_node()->set_parameter({"multiplier.force.x", force_multipliers[0]}); + fts_broadcaster_->get_node()->set_parameter({"multiplier.force.y", force_multipliers[1]}); + fts_broadcaster_->get_node()->set_parameter({"multiplier.force.z", force_multipliers[2]}); + fts_broadcaster_->get_node()->set_parameter({"multiplier.torque.x", torque_multipliers[0]}); + fts_broadcaster_->get_node()->set_parameter({"multiplier.torque.y", torque_multipliers[1]}); + fts_broadcaster_->get_node()->set_parameter({"multiplier.torque.z", torque_multipliers[2]}); + + // Configure & activate + ASSERT_EQ(fts_broadcaster_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_EQ(fts_broadcaster_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); + + // Publish & grab the message + geometry_msgs::msg::WrenchStamped wrench_msg; + subscribe_and_get_message(wrench_msg); + + // Check header + ASSERT_EQ(wrench_msg.header.frame_id, frame_id_); + + // Check that each field was scaled accordingly + ASSERT_EQ(wrench_msg.wrench.force.x, sensor_values_[0] * force_multipliers[0]); + ASSERT_EQ(wrench_msg.wrench.force.y, sensor_values_[1] * force_multipliers[1]); + ASSERT_EQ(wrench_msg.wrench.force.z, sensor_values_[2] * force_multipliers[2]); + ASSERT_EQ(wrench_msg.wrench.torque.x, sensor_values_[3] * torque_multipliers[0]); + ASSERT_EQ(wrench_msg.wrench.torque.y, sensor_values_[4] * torque_multipliers[1]); + ASSERT_EQ(wrench_msg.wrench.torque.z, sensor_values_[5] * torque_multipliers[2]); + + // the exported state interfaces reflect the same scaled values + const auto exported_state_interfaces = fts_broadcaster_->export_state_interfaces(); + ASSERT_EQ(exported_state_interfaces.size(), 6u); + + const std::string controller_name = fts_broadcaster_->get_node()->get_name(); + ASSERT_EQ( + exported_state_interfaces[0]->get_name(), controller_name + "/" + sensor_name_ + "/force.x"); + ASSERT_EQ( + exported_state_interfaces[1]->get_name(), controller_name + "/" + sensor_name_ + "/force.y"); + ASSERT_EQ( + exported_state_interfaces[2]->get_name(), controller_name + "/" + sensor_name_ + "/force.z"); + ASSERT_EQ( + exported_state_interfaces[3]->get_name(), controller_name + "/" + sensor_name_ + "/torque.x"); + ASSERT_EQ( + exported_state_interfaces[4]->get_name(), controller_name + "/" + sensor_name_ + "/torque.y"); + ASSERT_EQ( + exported_state_interfaces[5]->get_name(), controller_name + "/" + sensor_name_ + "/torque.z"); + ASSERT_EQ(exported_state_interfaces[0]->get_interface_name(), "force.x"); + ASSERT_EQ(exported_state_interfaces[1]->get_interface_name(), "force.y"); + ASSERT_EQ(exported_state_interfaces[2]->get_interface_name(), "force.z"); + ASSERT_EQ(exported_state_interfaces[3]->get_interface_name(), "torque.x"); + ASSERT_EQ(exported_state_interfaces[4]->get_interface_name(), "torque.y"); + ASSERT_EQ(exported_state_interfaces[5]->get_interface_name(), "torque.z"); + for (size_t i = 0; i < 6; ++i) + { + ASSERT_EQ( + exported_state_interfaces[i]->get_value(), + sensor_values_[i] * (i < 3 ? force_multipliers[i] : torque_multipliers[i - 3])); + } +} + TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_Publish_Success) { SetUpFTSBroadcaster(); From b0128fed7b02d03224a63d68984fb1a4fcb5ee09 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 17 May 2025 23:18:54 +0200 Subject: [PATCH 004/108] [Pid] Add enable_feedforward parameter (backport #1553) (#1689) Co-authored-by: Pascal Auf der Maur <47889885+pascalau@users.noreply.github.com> --- pid_controller/doc/userdoc.rst | 7 ++ .../include/pid_controller/pid_controller.hpp | 8 +- pid_controller/src/pid_controller.cpp | 22 +++--- pid_controller/src/pid_controller.yaml | 5 ++ pid_controller/test/test_pid_controller.cpp | 77 +++++++++++++++---- pid_controller/test/test_pid_controller.hpp | 1 + .../test_pid_controller_dual_interface.cpp | 6 +- .../test/test_pid_controller_preceding.cpp | 2 - 8 files changed, 89 insertions(+), 39 deletions(-) diff --git a/pid_controller/doc/userdoc.rst b/pid_controller/doc/userdoc.rst index fc94357ab3..3d476e5eb4 100644 --- a/pid_controller/doc/userdoc.rst +++ b/pid_controller/doc/userdoc.rst @@ -74,6 +74,9 @@ Services - /set_feedforward_control [std_srvs/srv/SetBool] +.. warning:: + This service is being deprecated in favour of setting the ``feedforward_gain`` parameter to a non-zero value. + Publishers ,,,,,,,,,,, - /controller_state [control_msgs/msg/MultiDOFStateStamped] @@ -85,6 +88,10 @@ The PID controller uses the `generate_parameter_library > measured_state_; rclcpp::Service::SharedPtr set_feedforward_control_service_; - realtime_tools::RealtimeBuffer control_mode_; + realtime_tools::RealtimeBuffer feedforward_mode_enabled_; using ControllerStatePublisher = realtime_tools::RealtimePublisher; diff --git a/pid_controller/src/pid_controller.cpp b/pid_controller/src/pid_controller.cpp index c267f11bb2..b1cb29e7c6 100644 --- a/pid_controller/src/pid_controller.cpp +++ b/pid_controller/src/pid_controller.cpp @@ -74,7 +74,7 @@ PidController::PidController() : controller_interface::ChainableControllerInterf controller_interface::CallbackReturn PidController::on_init() { - control_mode_.initRT(feedforward_mode_type::OFF); + feedforward_mode_enabled_.initRT(false); try { @@ -96,6 +96,8 @@ void PidController::update_parameters() return; } params_ = param_listener_->get_params(); + + feedforward_mode_enabled_.writeFromNonRT(params_.enable_feedforward); } controller_interface::CallbackReturn PidController::configure_parameters() @@ -230,6 +232,7 @@ controller_interface::CallbackReturn PidController::on_configure( measured_state_subscriber_ = get_node()->create_subscription( "~/measured_state", subscribers_qos, measured_state_callback); } + std::shared_ptr measured_state_msg = std::make_shared(); reset_controller_measured_state_msg(measured_state_msg, reference_and_state_dof_names_); @@ -243,14 +246,13 @@ controller_interface::CallbackReturn PidController::on_configure( const std::shared_ptr request, std::shared_ptr response) { - if (request->data) - { - control_mode_.writeFromNonRT(feedforward_mode_type::ON); - } - else - { - control_mode_.writeFromNonRT(feedforward_mode_type::OFF); - } + feedforward_mode_enabled_.writeFromNonRT(request->data); + + RCLCPP_WARN( + get_node()->get_logger(), + "This service will be deprecated in favour of setting the ``feedforward_gain`` parameter to " + "a non-zero value."); + response->success = true; }; @@ -510,7 +512,7 @@ controller_interface::return_type PidController::update_and_write_commands( if (std::isfinite(reference_interfaces_[i]) && std::isfinite(measured_state_values_[i])) { // calculate feed-forward - if (*(control_mode_.readFromRT()) == feedforward_mode_type::ON) + if (*(feedforward_mode_enabled_.readFromRT())) { // two interfaces if (reference_interfaces_.size() == 2 * dof_) diff --git a/pid_controller/src/pid_controller.yaml b/pid_controller/src/pid_controller.yaml index 02448f2a19..8903085667 100644 --- a/pid_controller/src/pid_controller.yaml +++ b/pid_controller/src/pid_controller.yaml @@ -43,6 +43,11 @@ pid_controller: default_value: false, description: "Use external states from a topic instead from state interfaces." } + enable_feedforward: { + type: bool, + default_value: false, + description: "Enables feedforward gain. (Will be deprecated in favour of setting feedforward_gain to a non-zero value.)" + } gains: __map_dof_names: p: { diff --git a/pid_controller/test/test_pid_controller.cpp b/pid_controller/test/test_pid_controller.cpp index 1c0494a002..2a3b99e969 100644 --- a/pid_controller/test/test_pid_controller.cpp +++ b/pid_controller/test/test_pid_controller.cpp @@ -21,8 +21,6 @@ #include #include -using pid_controller::feedforward_mode_type; - class PidControllerTest : public PidControllerFixture { }; @@ -205,21 +203,68 @@ TEST_F(PidControllerTest, test_feedforward_mode_service) executor.add_node(service_caller_node_->get_node_base_interface()); // initially set to OFF - ASSERT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::OFF); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); // should stay false - ASSERT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::OFF); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); // set to true ASSERT_NO_THROW(call_service(true, executor)); - ASSERT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::ON); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), true); // set back to false ASSERT_NO_THROW(call_service(false, executor)); - ASSERT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::OFF); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); +} + +TEST_F(PidControllerTest, test_feedforward_mode_parameter) +{ + SetUpController(); + + // Check updating mode during on_configure + + // initially set to OFF + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); + + // Reconfigure after setting parameter to true + ASSERT_EQ(controller_->on_cleanup(rclcpp_lifecycle::State()), NODE_SUCCESS); + EXPECT_TRUE(controller_->get_node()->set_parameter({"enable_feedforward", true}).successful); + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), true); + ASSERT_EQ(controller_->on_cleanup(rclcpp_lifecycle::State()), NODE_SUCCESS); + EXPECT_TRUE(controller_->get_node()->set_parameter({"enable_feedforward", false}).successful); + + // initially set to ON + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), true); + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); + + // Check updating mode during update_and_write_commands + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); + + // Switch to ON + ASSERT_EQ( + controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); + EXPECT_TRUE(controller_->get_node()->set_parameter({"enable_feedforward", true}).successful); + ASSERT_EQ( + controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), true); + + // Switch to OFF + EXPECT_TRUE(controller_->get_node()->set_parameter({"enable_feedforward", false}).successful); + ASSERT_EQ( + controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); } /** @@ -239,7 +284,7 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_off) ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_FALSE(controller_->is_in_chained_mode()); EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->values[0])); - EXPECT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::OFF); + EXPECT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); for (const auto & interface : controller_->reference_interfaces_) { EXPECT_TRUE(std::isnan(interface)); @@ -258,7 +303,7 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_off) controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::OK); - EXPECT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::OFF); + EXPECT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); EXPECT_EQ( controller_->reference_interfaces_.size(), dof_names_.size() * state_interfaces_.size()); EXPECT_EQ(controller_->reference_interfaces_.size(), dof_state_values_.size()); @@ -293,7 +338,7 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_FALSE(controller_->is_in_chained_mode()); EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->values[0])); - EXPECT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::OFF); + EXPECT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); for (const auto & interface : controller_->reference_interfaces_) { EXPECT_TRUE(std::isnan(interface)); @@ -301,8 +346,8 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward controller_->set_reference(dof_command_values_); - controller_->control_mode_.writeFromNonRT(feedforward_mode_type::ON); - EXPECT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::ON); + controller_->feedforward_mode_enabled_.writeFromNonRT(true); + EXPECT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), true); for (size_t i = 0; i < dof_command_values_.size(); ++i) { @@ -315,7 +360,7 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::OK); - EXPECT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::ON); + EXPECT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), true); EXPECT_EQ( controller_->reference_interfaces_.size(), dof_names_.size() * state_interfaces_.size()); EXPECT_EQ(controller_->reference_interfaces_.size(), dof_state_values_.size()); @@ -355,7 +400,7 @@ TEST_F(PidControllerTest, test_update_logic_chainable_not_use_subscriber_update) ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_TRUE(controller_->is_in_chained_mode()); // feedforward mode is off as default, use this for convenience - EXPECT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::OFF); + EXPECT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); // update reference interface which will be used for calculation const double ref_interface_value = 5.0; @@ -567,8 +612,8 @@ TEST_F(PidControllerTest, test_update_chained_feedforward_with_gain) ASSERT_TRUE(controller_->is_in_chained_mode()); // turn on feedforward - controller_->control_mode_.writeFromNonRT(feedforward_mode_type::ON); - ASSERT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::ON); + controller_->feedforward_mode_enabled_.writeFromNonRT(true); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), true); // send a message to update reference interface controller_->set_reference({target_value}); @@ -626,7 +671,7 @@ TEST_F(PidControllerTest, test_update_chained_feedforward_off_with_gain) ASSERT_TRUE(controller_->is_in_chained_mode()); // feedforward by default is OFF - ASSERT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::OFF); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); // send a message to update reference interface controller_->set_reference({target_value}); diff --git a/pid_controller/test/test_pid_controller.hpp b/pid_controller/test/test_pid_controller.hpp index 87b9e1de9a..1eb55ec878 100644 --- a/pid_controller/test/test_pid_controller.hpp +++ b/pid_controller/test/test_pid_controller.hpp @@ -54,6 +54,7 @@ class TestablePidController : public pid_controller::PidController FRIEND_TEST(PidControllerTest, activate_success); FRIEND_TEST(PidControllerTest, reactivate_success); FRIEND_TEST(PidControllerTest, test_feedforward_mode_service); + FRIEND_TEST(PidControllerTest, test_feedforward_mode_parameter); FRIEND_TEST(PidControllerTest, test_update_logic_feedforward_off); FRIEND_TEST(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward_gain); FRIEND_TEST(PidControllerTest, test_update_logic_chainable_not_use_subscriber_update); diff --git a/pid_controller/test/test_pid_controller_dual_interface.cpp b/pid_controller/test/test_pid_controller_dual_interface.cpp index e006986473..6db9171bcb 100644 --- a/pid_controller/test/test_pid_controller_dual_interface.cpp +++ b/pid_controller/test/test_pid_controller_dual_interface.cpp @@ -20,8 +20,6 @@ #include #include -using pid_controller::feedforward_mode_type; - class PidControllerDualInterfaceTest : public PidControllerFixture { public: @@ -80,8 +78,8 @@ TEST_F(PidControllerDualInterfaceTest, test_chained_feedforward_with_gain_dual_i ASSERT_TRUE(controller_->is_in_chained_mode()); // turn on feedforward - controller_->control_mode_.writeFromNonRT(feedforward_mode_type::ON); - ASSERT_EQ(*(controller_->control_mode_.readFromRT()), feedforward_mode_type::ON); + controller_->feedforward_mode_enabled_.writeFromNonRT(true); + ASSERT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), true); // set up the reference interface, controller_->reference_interfaces_ = { diff --git a/pid_controller/test/test_pid_controller_preceding.cpp b/pid_controller/test/test_pid_controller_preceding.cpp index 602303ef9e..31629ed7b7 100644 --- a/pid_controller/test/test_pid_controller_preceding.cpp +++ b/pid_controller/test/test_pid_controller_preceding.cpp @@ -21,8 +21,6 @@ #include #include -using pid_controller::feedforward_mode_type; - class PidControllerTest : public PidControllerFixture { }; From 2a19c4df7ccee17c07bcb4be84bca575a9515ad0 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sun, 18 May 2025 00:08:00 +0200 Subject: [PATCH 005/108] Use `warning` attribute of RcutilsLogger (backport #1690) (#1691) Co-authored-by: Sai Kishor Kothakota --- .../publisher_joint_trajectory_controller.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ros2_controllers_test_nodes/ros2_controllers_test_nodes/publisher_joint_trajectory_controller.py b/ros2_controllers_test_nodes/ros2_controllers_test_nodes/publisher_joint_trajectory_controller.py index cf38890407..47013a11cb 100644 --- a/ros2_controllers_test_nodes/ros2_controllers_test_nodes/publisher_joint_trajectory_controller.py +++ b/ros2_controllers_test_nodes/ros2_controllers_test_nodes/publisher_joint_trajectory_controller.py @@ -111,7 +111,7 @@ def get_sub_param(sub_param): self.get_logger().info(f'Goal "{name}" has definition {point}') else: - self.get_logger().warn( + self.get_logger().warning( f'Goal "{name}" definition is wrong. This goal will not be used. ' "Use the following structure: \n:\n " "positions: [joint1, joint2, joint3, ...]\n " @@ -150,11 +150,11 @@ def timer_callback(self): self.i %= len(self.goals) elif self.check_starting_point and not self.joint_state_msg_received: - self.get_logger().warn( + self.get_logger().warning( 'Start configuration could not be checked! Check "joint_state" topic!' ) else: - self.get_logger().warn("Start configuration is not within configured limits!") + self.get_logger().warning("Start configuration is not within configured limits!") def joint_state_callback(self, msg): @@ -166,7 +166,7 @@ def joint_state_callback(self, msg): if (msg.position[idx] < self.starting_point[enum][0]) or ( msg.position[idx] > self.starting_point[enum][1] ): - self.get_logger().warn(f"Starting point limits exceeded for joint {enum} !") + self.get_logger().warning(f"Starting point limits exceeded for joint {enum} !") limit_exceeded[idx] = True if any(limit_exceeded): From 84450dd9715c3c92195a9b55b85d543362d51490 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Sat, 17 May 2025 22:10:45 +0000 Subject: [PATCH 006/108] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 3 +++ admittance_controller/CHANGELOG.rst | 3 +++ bicycle_steering_controller/CHANGELOG.rst | 3 +++ diff_drive_controller/CHANGELOG.rst | 6 ++++++ effort_controllers/CHANGELOG.rst | 3 +++ force_torque_sensor_broadcaster/CHANGELOG.rst | 5 +++++ forward_command_controller/CHANGELOG.rst | 3 +++ gpio_controllers/CHANGELOG.rst | 3 +++ gps_sensor_broadcaster/CHANGELOG.rst | 3 +++ gripper_controllers/CHANGELOG.rst | 3 +++ imu_sensor_broadcaster/CHANGELOG.rst | 3 +++ joint_state_broadcaster/CHANGELOG.rst | 3 +++ joint_trajectory_controller/CHANGELOG.rst | 3 +++ mecanum_drive_controller/CHANGELOG.rst | 6 ++++++ parallel_gripper_controller/CHANGELOG.rst | 3 +++ pid_controller/CHANGELOG.rst | 6 ++++++ pose_broadcaster/CHANGELOG.rst | 3 +++ position_controllers/CHANGELOG.rst | 3 +++ range_sensor_broadcaster/CHANGELOG.rst | 3 +++ ros2_controllers/CHANGELOG.rst | 3 +++ ros2_controllers_test_nodes/CHANGELOG.rst | 5 +++++ rqt_joint_trajectory_controller/CHANGELOG.rst | 3 +++ steering_controllers_library/CHANGELOG.rst | 5 +++++ tricycle_controller/CHANGELOG.rst | 5 +++++ tricycle_steering_controller/CHANGELOG.rst | 3 +++ velocity_controllers/CHANGELOG.rst | 3 +++ 26 files changed, 95 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 03397c56ac..bc1c8d61df 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Rename ackermann msg to controller state msg type (`#1662 `_) diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 3e0971c8df..b5268c10ec 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 255a07c6f4..00c387d407 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Rename ackermann msg to controller state msg type (`#1662 `_) diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 50347022c1..6cb4588623 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Simplify `on_set_chained_mode` avoiding cpplint warnings (backport `#1564 `_) (`#1688 `_) +* Deprecating tf2 C Headers (`#1325 `_) +* Contributors: Lucas Wendland, mergify[bot], Bhagyesh Agresar + 4.24.0 (2025-04-27) ------------------- * Call `configure()` of base class instead of node (`#1659 `_) diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 62da945091..2f3b4f1076 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Call `configure()` of base class instead of node (`#1659 `_) diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index d52c436cc4..158d3b0c3a 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Add multiplier support to ForceTorqueSensorBroadcaster (backport `#1647 `_) (`#1686 `_) +* Contributors: mergify[bot], edward.ix + 4.24.0 (2025-04-27) ------------------- * [CI] test_force_torque_sensor_broadcaster regularily times out (`#1639 `_) diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 39c997c65f..cac2a756d5 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Call `configure()` of base class instead of node (`#1659 `_) diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index f73c54d23d..e945c1f55c 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Use smart pointer of ctrl in GpsSensor and GpioCommandController tests (`#1658 `_) diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 95847008d5..562ba5cb85 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Use smart pointer of ctrl in GpsSensor and GpioCommandController tests (`#1658 `_) diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 8c0b5cd98e..799a7f66c7 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 1d469d5d89..a125483bc8 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 7c8de6e944..c7a23122bc 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Call `configure()` of base class instead of node (`#1659 `_) diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 881fe3b12f..e22459fa03 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Call `configure()` of base class instead of node (`#1659 `_) diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index a28632e131..d3a61082a0 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Simplify `on_set_chained_mode` avoiding cpplint warnings (backport `#1564 `_) (`#1688 `_) +* Deprecating tf2 C Headers (`#1325 `_) +* Contributors: Lucas Wendland, mergify[bot], Bhagyesh Agresar + 4.24.0 (2025-04-27) ------------------- * Fix preceeding->preceding typos (`#1655 `_) diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 60258ceaf9..9ec48c6d42 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 6467cbae80..5d3238b0de 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* [Pid] Add enable_feedforward parameter (backport `#1553 `_) (`#1689 `_) +* Simplify `on_set_chained_mode` avoiding cpplint warnings (backport `#1564 `_) (`#1688 `_) +* Contributors: mergify[bot], Pascal Auf der Maur, hagyesh Agresar + 4.24.0 (2025-04-27) ------------------- diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index ccc11ff790..696d0cd7e7 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Deprecate tf.publish_rate parameter for pose_broadcaster (`#1614 `_) diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index fbb0a227be..d7cefdc45f 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Call `configure()` of base class instead of node (`#1659 `_) diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 11da4e0d3a..fe104f2d8d 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index f9cacf45e6..63d84a5528 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 2a0be0f257..911d16b1ae 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use `warning` attribute of RcutilsLogger (backport `#1690 `_) (`#1691 `_) +* Contributors: mergify[bot], Sai Kishor Kothakota + 4.24.0 (2025-04-27) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index b6960a2a7b..774b0779b5 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 477b654066..0d1b47b61e 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Simplify `on_set_chained_mode` avoiding cpplint warnings (backport `#1564 `_) (`#1688 `_) +* Contributors: mergify[bot], Bhagyesh Agresar + 4.24.0 (2025-04-27) ------------------- * Rename ackermann msg to controller state msg type (`#1662 `_) diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 3f2ff8cf11..f514bbf145 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Deprecating tf2 C Headers (`#1325 `_) +* Contributors: Lucas Wendland + 4.24.0 (2025-04-27) ------------------- * Call `configure()` of base class instead of node (`#1659 `_) diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 9bffdc6314..1b7caa7e00 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Rename ackermann msg to controller state msg type (`#1662 `_) diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 1d0e64b281..114a7b2be6 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.24.0 (2025-04-27) ------------------- * Call `configure()` of base class instead of node (`#1659 `_) From 6efe7238d34b398169a34d048f5d3624aaea8fe2 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Sat, 17 May 2025 22:11:02 +0000 Subject: [PATCH 007/108] 4.25.0 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 54 files changed, 80 insertions(+), 80 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index bc1c8d61df..a93c0d1da5 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index fc0eba497d..c9c2b85262 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.24.0 + 4.25.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index b5268c10ec..8cdb1d867e 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index cb5201424e..fb0d3f3748 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.24.0 + 4.25.0 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 00c387d407..13ddae4361 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index 07e72e096f..f80bba80a6 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.24.0 + 4.25.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 6cb4588623..ff5e70d6c8 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- * Simplify `on_set_chained_mode` avoiding cpplint warnings (backport `#1564 `_) (`#1688 `_) * Deprecating tf2 C Headers (`#1325 `_) * Contributors: Lucas Wendland, mergify[bot], Bhagyesh Agresar diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index dded814eb9..847156c3c3 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.24.0 + 4.25.0 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 2f3b4f1076..150b8d49fa 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index 35ae9741b2..c2666cc630 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.24.0 + 4.25.0 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 158d3b0c3a..48276f8860 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- * Add multiplier support to ForceTorqueSensorBroadcaster (backport `#1647 `_) (`#1686 `_) * Contributors: mergify[bot], edward.ix diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 8c98f892ff..f88520ce9a 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.24.0 + 4.25.0 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index cac2a756d5..58b521e5bf 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index 097d8865a0..7e7f83d4a4 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.24.0 + 4.25.0 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index e945c1f55c..7e930008a3 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index cd761658a2..569bce8ab2 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.24.0 + 4.25.0 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 562ba5cb85..e0eb1a11b4 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index e65d25429f..9cc2c668c7 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.24.0 + 4.25.0 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 799a7f66c7..3df1b79faf 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index d7decaac37..46c1bc8171 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.24.0 + 4.25.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index a125483bc8..0e5fb0feb9 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index 14911df8b0..ce79276d35 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.24.0 + 4.25.0 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index c7a23122bc..fe925258f1 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index a3bea0f44b..6c20c02b3c 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.24.0 + 4.25.0 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index e22459fa03..4aac99c6a4 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 48f5e052d2..b39002a43c 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.24.0 + 4.25.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index d3a61082a0..52be81d145 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- * Simplify `on_set_chained_mode` avoiding cpplint warnings (backport `#1564 `_) (`#1688 `_) * Deprecating tf2 C Headers (`#1325 `_) * Contributors: Lucas Wendland, mergify[bot], Bhagyesh Agresar diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index 847e8affcd..720b81a8f4 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.24.0 + 4.25.0 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 9ec48c6d42..f95d7b395e 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index 7c6e05bbd6..8055c11fa9 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.24.0 + 4.25.0 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 5d3238b0de..f6252e3d63 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- * [Pid] Add enable_feedforward parameter (backport `#1553 `_) (`#1689 `_) * Simplify `on_set_chained_mode` avoiding cpplint warnings (backport `#1564 `_) (`#1688 `_) * Contributors: mergify[bot], Pascal Auf der Maur, hagyesh Agresar diff --git a/pid_controller/package.xml b/pid_controller/package.xml index f4acb87f2b..865499de85 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.24.0 + 4.25.0 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 696d0cd7e7..66a47971ac 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index d7ac7a9dd7..6ea45a1f1c 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.24.0 + 4.25.0 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index d7cefdc45f..3914f3e3dd 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index aa132074c9..556423cbee 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.24.0 + 4.25.0 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index fe104f2d8d..3bbc4f607c 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index 6f627c5708..ff02605a3b 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.24.0 + 4.25.0 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 63d84a5528..6b01ee1910 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index a9cb03e85c..0905b6445d 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.24.0 + 4.25.0 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 911d16b1ae..93e2c75765 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- * Use `warning` attribute of RcutilsLogger (backport `#1690 `_) (`#1691 `_) * Contributors: mergify[bot], Sai Kishor Kothakota diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 3b7a6f776d..5dc88545d4 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.24.0 + 4.25.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index a23a614bfe..e2f552d3ab 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.24.0", + version="4.25.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 774b0779b5..01dfc2c101 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 14763a2ce7..599d35cb63 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.24.0 + 4.25.0 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index 559fa53dc2..421acd82a3 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.24.0", + version="4.25.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 0d1b47b61e..7edc41616b 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- * Simplify `on_set_chained_mode` avoiding cpplint warnings (backport `#1564 `_) (`#1688 `_) * Contributors: mergify[bot], Bhagyesh Agresar diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index ed112d1086..9bd4ec3ef2 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.24.0 + 4.25.0 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index f514bbf145..c303d8c7a5 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- * Deprecating tf2 C Headers (`#1325 `_) * Contributors: Lucas Wendland diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index b57aae052a..c71364b164 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.24.0 + 4.25.0 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 1b7caa7e00..666e1e62a5 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index eb6be5b584..40491f5f82 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.24.0 + 4.25.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 114a7b2be6..ec427e2971 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.25.0 (2025-05-17) +------------------- 4.24.0 (2025-04-27) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index f0883b4920..81a27a6b28 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.24.0 + 4.25.0 Generic controller for forwarding commands. Bence Magyar From 9f128a3d997cb8df4d0d315cb59108caa858f36a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 24 May 2025 20:55:51 +0200 Subject: [PATCH 008/108] Use target_link_libraries instead of ament_target_dependencies (backport #1697) (#1699) Co-authored-by: Sai Kishor Kothakota --- ackermann_steering_controller/CMakeLists.txt | 29 ++++++------- admittance_controller/CMakeLists.txt | 42 ++++++++++++------- bicycle_steering_controller/CMakeLists.txt | 29 ++++++------- diff_drive_controller/CMakeLists.txt | 31 +++++++------- effort_controllers/CMakeLists.txt | 12 +++--- .../CMakeLists.txt | 22 +++++----- forward_command_controller/CMakeLists.txt | 27 ++++++------ gpio_controllers/CMakeLists.txt | 41 ++++++++---------- gps_sensor_broadcaster/CMakeLists.txt | 23 +++++----- imu_sensor_broadcaster/CMakeLists.txt | 21 +++++----- joint_state_broadcaster/CMakeLists.txt | 28 ++++++------- joint_trajectory_controller/CMakeLists.txt | 34 ++++++++------- mecanum_drive_controller/CMakeLists.txt | 32 +++++++------- parallel_gripper_controller/CMakeLists.txt | 19 ++++++--- pid_controller/CMakeLists.txt | 38 +++++++---------- pose_broadcaster/CMakeLists.txt | 23 +++++----- position_controllers/CMakeLists.txt | 11 ++--- range_sensor_broadcaster/CMakeLists.txt | 24 +++++------ steering_controllers_library/CMakeLists.txt | 22 ++++++---- tricycle_controller/CMakeLists.txt | 34 ++++++++------- tricycle_steering_controller/CMakeLists.txt | 29 ++++++------- velocity_controllers/CMakeLists.txt | 11 ++--- 22 files changed, 300 insertions(+), 282 deletions(-) diff --git a/ackermann_steering_controller/CMakeLists.txt b/ackermann_steering_controller/CMakeLists.txt index 3f49ab86ee..d9dca4c145 100644 --- a/ackermann_steering_controller/CMakeLists.txt +++ b/ackermann_steering_controller/CMakeLists.txt @@ -40,8 +40,15 @@ target_include_directories(ackermann_steering_controller PUBLIC $ $) target_link_libraries(ackermann_steering_controller PUBLIC - ackermann_steering_controller_parameters) -ament_target_dependencies(ackermann_steering_controller PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + ackermann_steering_controller_parameters + steering_controllers_library::steering_controllers_library + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + ${std_srvs_TARGETS}) pluginlib_export_plugin_description_file( controller_interface ackermann_steering_controller.xml) @@ -55,10 +62,10 @@ if(BUILD_TESTING) add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") ament_add_gmock(test_load_ackermann_steering_controller test/test_load_ackermann_steering_controller.cpp) - ament_target_dependencies(test_load_ackermann_steering_controller - controller_manager - hardware_interface - ros2_control_test_assets + target_link_libraries(test_load_ackermann_steering_controller + controller_manager::controller_manager + hardware_interface::hardware_interface + ros2_control_test_assets::ros2_control_test_assets ) add_rostest_with_parameters_gmock(test_ackermann_steering_controller @@ -67,22 +74,12 @@ if(BUILD_TESTING) ) target_include_directories(test_ackermann_steering_controller PRIVATE include) target_link_libraries(test_ackermann_steering_controller ackermann_steering_controller) - ament_target_dependencies( - test_ackermann_steering_controller - controller_interface - hardware_interface - ) add_rostest_with_parameters_gmock( test_ackermann_steering_controller_preceding test/test_ackermann_steering_controller_preceding.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/ackermann_steering_controller_preceding_params.yaml) target_include_directories(test_ackermann_steering_controller_preceding PRIVATE include) target_link_libraries(test_ackermann_steering_controller_preceding ackermann_steering_controller) - ament_target_dependencies( - test_ackermann_steering_controller_preceding - controller_interface - hardware_interface - ) endif() install( diff --git a/admittance_controller/CMakeLists.txt b/admittance_controller/CMakeLists.txt index c71bf11bfb..6cd1ba6385 100644 --- a/admittance_controller/CMakeLists.txt +++ b/admittance_controller/CMakeLists.txt @@ -46,10 +46,26 @@ target_include_directories(admittance_controller PUBLIC $ ) target_link_libraries(admittance_controller PUBLIC - admittance_controller_parameters - Eigen3::Eigen -) -ament_target_dependencies(admittance_controller PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + admittance_controller_parameters + Eigen3::Eigen + control_toolbox::control_toolbox + controller_interface::controller_interface + hardware_interface::hardware_interface + kinematics_interface::kinematics_interface + pluginlib::pluginlib + rclcpp::rclcpp + angles::angles + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + tf2::tf2 + tf2_eigen::tf2_eigen + tf2_geometry_msgs::tf2_geometry_msgs + tf2_kdl::tf2_kdl + tf2_ros::tf2_ros + ${geometry_msgs_TARGETS} + ${trajectory_msgs_TARGETS} + ${control_msgs_TARGETS} + ${tf2_geometry_msgs_TARGETS}) pluginlib_export_plugin_description_file(controller_interface admittance_controller.xml) @@ -64,10 +80,10 @@ if(BUILD_TESTING) # test loading admittance controller add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") ament_add_gmock(test_load_admittance_controller test/test_load_admittance_controller.cpp) - ament_target_dependencies(test_load_admittance_controller - controller_manager - hardware_interface - ros2_control_test_assets + target_link_libraries(test_load_admittance_controller + controller_manager::controller_manager + hardware_interface::hardware_interface + ros2_control_test_assets::ros2_control_test_assets ) # test admittance controller function @@ -75,13 +91,9 @@ if(BUILD_TESTING) test/test_admittance_controller.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/test_params.yaml ) - target_link_libraries(test_admittance_controller admittance_controller) - ament_target_dependencies(test_admittance_controller - control_msgs - controller_interface - hardware_interface - ros2_control_test_assets - ) + target_link_libraries(test_admittance_controller + admittance_controller + ros2_control_test_assets::ros2_control_test_assets) endif() install( diff --git a/bicycle_steering_controller/CMakeLists.txt b/bicycle_steering_controller/CMakeLists.txt index 0ad9dd193e..dec1544eed 100644 --- a/bicycle_steering_controller/CMakeLists.txt +++ b/bicycle_steering_controller/CMakeLists.txt @@ -40,8 +40,15 @@ target_include_directories(bicycle_steering_controller PUBLIC "$" "$") target_link_libraries(bicycle_steering_controller PUBLIC - bicycle_steering_controller_parameters) -ament_target_dependencies(bicycle_steering_controller PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + bicycle_steering_controller_parameters + steering_controllers_library::steering_controllers_library + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + ${std_srvs_TARGETS}) pluginlib_export_plugin_description_file( controller_interface bicycle_steering_controller.xml) @@ -54,10 +61,10 @@ if(BUILD_TESTING) add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") ament_add_gmock(test_load_bicycle_steering_controller test/test_load_bicycle_steering_controller.cpp) - ament_target_dependencies(test_load_bicycle_steering_controller - controller_manager - hardware_interface - ros2_control_test_assets + target_link_libraries(test_load_bicycle_steering_controller + controller_manager::controller_manager + hardware_interface::hardware_interface + ros2_control_test_assets::ros2_control_test_assets ) add_rostest_with_parameters_gmock( @@ -65,22 +72,12 @@ if(BUILD_TESTING) ${CMAKE_CURRENT_SOURCE_DIR}/test/bicycle_steering_controller_params.yaml) target_include_directories(test_bicycle_steering_controller PRIVATE include) target_link_libraries(test_bicycle_steering_controller bicycle_steering_controller) - ament_target_dependencies( - test_bicycle_steering_controller - controller_interface - hardware_interface - ) add_rostest_with_parameters_gmock( test_bicycle_steering_controller_preceding test/test_bicycle_steering_controller_preceding.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/bicycle_steering_controller_preceding_params.yaml) target_include_directories(test_bicycle_steering_controller_preceding PRIVATE include) target_link_libraries(test_bicycle_steering_controller_preceding bicycle_steering_controller) - ament_target_dependencies( - test_bicycle_steering_controller_preceding - controller_interface - hardware_interface - ) endif() install( diff --git a/diff_drive_controller/CMakeLists.txt b/diff_drive_controller/CMakeLists.txt index 2acbf8b69e..7d57720a26 100644 --- a/diff_drive_controller/CMakeLists.txt +++ b/diff_drive_controller/CMakeLists.txt @@ -48,8 +48,19 @@ target_include_directories(diff_drive_controller PUBLIC target_link_libraries(diff_drive_controller PUBLIC diff_drive_controller_parameters - control_toolbox::rate_limiter_parameters) -ament_target_dependencies(diff_drive_controller PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + control_toolbox::rate_limiter_parameters + control_toolbox::control_toolbox + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + rcpputils::rcpputils + realtime_tools::realtime_tools + tf2::tf2 + ${tf2_msgs_TARGETS} + ${geometry_msgs_TARGETS} + ${nav_msgs_TARGETS}) pluginlib_export_plugin_description_file(controller_interface diff_drive_plugin.xml) if(BUILD_TESTING) @@ -63,22 +74,12 @@ if(BUILD_TESTING) target_link_libraries(test_diff_drive_controller diff_drive_controller ) - ament_target_dependencies(test_diff_drive_controller - geometry_msgs - hardware_interface - nav_msgs - rclcpp - rclcpp_lifecycle - realtime_tools - tf2 - tf2_msgs - ) add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") ament_add_gmock(test_load_diff_drive_controller test/test_load_diff_drive_controller.cpp) - ament_target_dependencies(test_load_diff_drive_controller - controller_manager - ros2_control_test_assets + target_link_libraries(test_load_diff_drive_controller + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) endif() diff --git a/effort_controllers/CMakeLists.txt b/effort_controllers/CMakeLists.txt index 32b975ffca..be047b1321 100644 --- a/effort_controllers/CMakeLists.txt +++ b/effort_controllers/CMakeLists.txt @@ -25,7 +25,11 @@ target_include_directories(effort_controllers PUBLIC $ $ ) -ament_target_dependencies(effort_controllers PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) +target_link_libraries(effort_controllers PUBLIC + forward_command_controller::forward_command_controller + pluginlib::pluginlib + rclcpp::rclcpp +) pluginlib_export_plugin_description_file(controller_interface effort_controllers_plugins.xml) @@ -39,10 +43,8 @@ if(BUILD_TESTING) ) target_link_libraries(test_load_joint_group_effort_controller effort_controllers - ) - ament_target_dependencies(test_load_joint_group_effort_controller - controller_manager - ros2_control_test_assets + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) ament_add_gmock(test_joint_group_effort_controller diff --git a/force_torque_sensor_broadcaster/CMakeLists.txt b/force_torque_sensor_broadcaster/CMakeLists.txt index 3e3786a9f1..c7d8e3beb8 100644 --- a/force_torque_sensor_broadcaster/CMakeLists.txt +++ b/force_torque_sensor_broadcaster/CMakeLists.txt @@ -35,9 +35,14 @@ target_include_directories(force_torque_sensor_broadcaster PUBLIC $ ) target_link_libraries(force_torque_sensor_broadcaster PUBLIC - force_torque_sensor_broadcaster_parameters -) -ament_target_dependencies(force_torque_sensor_broadcaster PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + force_torque_sensor_broadcaster_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + ${geometry_msgs_TARGETS}) pluginlib_export_plugin_description_file( controller_interface force_torque_sensor_broadcaster.xml) @@ -53,11 +58,9 @@ if(BUILD_TESTING) target_include_directories(test_load_force_torque_sensor_broadcaster PRIVATE include) target_link_libraries(test_load_force_torque_sensor_broadcaster force_torque_sensor_broadcaster - ) - ament_target_dependencies(test_load_force_torque_sensor_broadcaster - controller_manager - hardware_interface - ros2_control_test_assets + controller_manager::controller_manager + hardware_interface::hardware_interface + ros2_control_test_assets::ros2_control_test_assets ) add_rostest_with_parameters_gmock(test_force_torque_sensor_broadcaster @@ -67,9 +70,6 @@ if(BUILD_TESTING) target_link_libraries(test_force_torque_sensor_broadcaster force_torque_sensor_broadcaster ) - ament_target_dependencies(test_force_torque_sensor_broadcaster - hardware_interface - ) endif() install( diff --git a/forward_command_controller/CMakeLists.txt b/forward_command_controller/CMakeLists.txt index 06888549c4..542fa45537 100644 --- a/forward_command_controller/CMakeLists.txt +++ b/forward_command_controller/CMakeLists.txt @@ -42,10 +42,15 @@ target_include_directories(forward_command_controller PUBLIC $ ) target_link_libraries(forward_command_controller PUBLIC - forward_command_controller_parameters - multi_interface_forward_command_controller_parameters -) -ament_target_dependencies(forward_command_controller PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + forward_command_controller_parameters + multi_interface_forward_command_controller_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + ${std_msgs_TARGETS}) pluginlib_export_plugin_description_file(controller_interface forward_command_plugin.xml) if(BUILD_TESTING) @@ -58,11 +63,8 @@ if(BUILD_TESTING) ) target_link_libraries(test_load_forward_command_controller forward_command_controller - ) - ament_target_dependencies(test_load_forward_command_controller - controller_manager - hardware_interface - ros2_control_test_assets + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) ament_add_gmock(test_forward_command_controller @@ -77,11 +79,8 @@ if(BUILD_TESTING) ) target_link_libraries(test_load_multi_interface_forward_command_controller forward_command_controller - ) - ament_target_dependencies(test_load_multi_interface_forward_command_controller - controller_manager - hardware_interface - ros2_control_test_assets + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) ament_add_gmock(test_multi_interface_forward_command_controller diff --git a/gpio_controllers/CMakeLists.txt b/gpio_controllers/CMakeLists.txt index 0466dbae19..56dfd29b25 100644 --- a/gpio_controllers/CMakeLists.txt +++ b/gpio_controllers/CMakeLists.txt @@ -25,17 +25,18 @@ add_library(gpio_controllers src/gpio_command_controller.cpp ) target_include_directories(gpio_controllers PRIVATE include) -target_link_libraries(gpio_controllers PUBLIC gpio_command_controller_parameters) -ament_target_dependencies(gpio_controllers PUBLIC - builtin_interfaces - controller_interface - hardware_interface - pluginlib - rclcpp_lifecycle - rcutils - realtime_tools - control_msgs -) +target_link_libraries(gpio_controllers PUBLIC + gpio_command_controller_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + rcutils::rcutils + realtime_tools::realtime_tools + ${control_msgs_TARGETS} + ${builtin_interfaces_TARGETS}) + pluginlib_export_plugin_description_file(controller_interface gpio_controllers_plugin.xml) install( @@ -63,10 +64,10 @@ if(BUILD_TESTING) ) target_include_directories(test_load_gpio_command_controller PRIVATE include) - ament_target_dependencies(test_load_gpio_command_controller - controller_manager - hardware_interface - ros2_control_test_assets + target_link_libraries(test_load_gpio_command_controller + controller_manager::controller_manager + hardware_interface::hardware_interface + ros2_control_test_assets::ros2_control_test_assets ) ament_add_gmock( @@ -76,15 +77,7 @@ if(BUILD_TESTING) target_include_directories(test_gpio_command_controller PRIVATE include) target_link_libraries(test_gpio_command_controller gpio_controllers - ) - ament_target_dependencies(test_gpio_command_controller - controller_interface - hardware_interface - rclcpp - rclcpp_lifecycle - realtime_tools - ros2_control_test_assets - control_msgs + ros2_control_test_assets::ros2_control_test_assets ) endif() diff --git a/gps_sensor_broadcaster/CMakeLists.txt b/gps_sensor_broadcaster/CMakeLists.txt index 80928a223d..7cc818d1fe 100644 --- a/gps_sensor_broadcaster/CMakeLists.txt +++ b/gps_sensor_broadcaster/CMakeLists.txt @@ -40,8 +40,15 @@ target_include_directories(gps_sensor_broadcaster PUBLIC $ ) -target_link_libraries(gps_sensor_broadcaster PUBLIC gps_sensor_broadcaster_parameters) -ament_target_dependencies(gps_sensor_broadcaster PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) +target_link_libraries(gps_sensor_broadcaster PUBLIC + gps_sensor_broadcaster_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + ${sensor_msgs_TARGETS}) pluginlib_export_plugin_description_file( controller_interface gps_sensor_broadcaster.xml) @@ -59,11 +66,8 @@ if(BUILD_TESTING) target_include_directories(test_load_gps_sensor_broadcaster PRIVATE include) target_link_libraries(test_load_gps_sensor_broadcaster gps_sensor_broadcaster - ) - ament_target_dependencies(test_load_gps_sensor_broadcaster - controller_manager - hardware_interface - ros2_control_test_assets + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) ament_add_gmock(test_gps_sensor_broadcaster @@ -72,10 +76,7 @@ if(BUILD_TESTING) target_include_directories(test_gps_sensor_broadcaster PRIVATE include) target_link_libraries(test_gps_sensor_broadcaster gps_sensor_broadcaster - ) - ament_target_dependencies(test_gps_sensor_broadcaster - hardware_interface - ros2_control_test_assets + ros2_control_test_assets::ros2_control_test_assets ) endif() diff --git a/imu_sensor_broadcaster/CMakeLists.txt b/imu_sensor_broadcaster/CMakeLists.txt index e63f0bb328..9d7727e33d 100644 --- a/imu_sensor_broadcaster/CMakeLists.txt +++ b/imu_sensor_broadcaster/CMakeLists.txt @@ -35,9 +35,14 @@ target_include_directories(imu_sensor_broadcaster PUBLIC $ ) target_link_libraries(imu_sensor_broadcaster PUBLIC - imu_sensor_broadcaster_parameters -) -ament_target_dependencies(imu_sensor_broadcaster PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + imu_sensor_broadcaster_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + ${sensor_msgs_TARGETS}) pluginlib_export_plugin_description_file( controller_interface imu_sensor_broadcaster.xml) @@ -53,11 +58,8 @@ if(BUILD_TESTING) target_include_directories(test_load_imu_sensor_broadcaster PRIVATE include) target_link_libraries(test_load_imu_sensor_broadcaster imu_sensor_broadcaster - ) - ament_target_dependencies(test_load_imu_sensor_broadcaster - controller_manager - hardware_interface - ros2_control_test_assets + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) add_rostest_with_parameters_gmock(test_imu_sensor_broadcaster @@ -67,9 +69,6 @@ if(BUILD_TESTING) target_link_libraries(test_imu_sensor_broadcaster imu_sensor_broadcaster ) - ament_target_dependencies(test_imu_sensor_broadcaster - hardware_interface - ) endif() install( diff --git a/joint_state_broadcaster/CMakeLists.txt b/joint_state_broadcaster/CMakeLists.txt index 54a033e553..df6c67c89e 100644 --- a/joint_state_broadcaster/CMakeLists.txt +++ b/joint_state_broadcaster/CMakeLists.txt @@ -37,9 +37,18 @@ target_include_directories(joint_state_broadcaster PUBLIC $ ) target_link_libraries(joint_state_broadcaster PUBLIC - joint_state_broadcaster_parameters -) -ament_target_dependencies(joint_state_broadcaster PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + joint_state_broadcaster_parameters + controller_manager::controller_manager + controller_interface::controller_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + urdf::urdf + rcutils::rcutils + ${sensor_msgs_TARGETS} + ${control_msgs_TARGETS} + ${builtin_interfaces_TARGETS}) pluginlib_export_plugin_description_file(controller_interface joint_state_plugin.xml) if(BUILD_TESTING) @@ -54,23 +63,14 @@ if(BUILD_TESTING) ) target_link_libraries(test_load_joint_state_broadcaster joint_state_broadcaster - ) - ament_target_dependencies(test_load_joint_state_broadcaster - controller_manager - hardware_interface - ros2_control_test_assets - ) + ros2_control_test_assets::ros2_control_test_assets) ament_add_gmock(test_joint_state_broadcaster test/test_joint_state_broadcaster.cpp ) target_link_libraries(test_joint_state_broadcaster joint_state_broadcaster - ) - ament_target_dependencies(test_joint_state_broadcaster - hardware_interface - ros2_control_test_assets - ) + ros2_control_test_assets::ros2_control_test_assets) endif() install( diff --git a/joint_trajectory_controller/CMakeLists.txt b/joint_trajectory_controller/CMakeLists.txt index 58a6378e19..8b3f109b07 100644 --- a/joint_trajectory_controller/CMakeLists.txt +++ b/joint_trajectory_controller/CMakeLists.txt @@ -43,9 +43,20 @@ target_include_directories(joint_trajectory_controller PUBLIC $ ) target_link_libraries(joint_trajectory_controller PUBLIC - joint_trajectory_controller_parameters -) -ament_target_dependencies(joint_trajectory_controller PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + joint_trajectory_controller_parameters + control_toolbox::control_toolbox + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + rsl::rsl + tl_expected::tl_expected + urdf::urdf + angles::angles + ${trajectory_msgs_TARGETS} + ${control_msgs_TARGETS}) pluginlib_export_plugin_description_file(controller_interface joint_trajectory_plugin.xml) @@ -56,12 +67,12 @@ if(BUILD_TESTING) ament_add_gmock(test_trajectory test/test_trajectory.cpp) target_link_libraries(test_trajectory joint_trajectory_controller) - ament_target_dependencies(test_trajectory ros2_control_test_assets) + target_link_libraries(test_trajectory ros2_control_test_assets::ros2_control_test_assets) target_compile_definitions(test_trajectory PRIVATE _USE_MATH_DEFINES) ament_add_gmock(test_tolerances test/test_tolerances.cpp) target_link_libraries(test_tolerances joint_trajectory_controller) - ament_target_dependencies(test_tolerances ros2_control_test_assets) + target_link_libraries(test_tolerances ros2_control_test_assets::ros2_control_test_assets) target_compile_definitions(test_tolerances PRIVATE _USE_MATH_DEFINES) ament_add_gmock(test_trajectory_controller @@ -70,7 +81,7 @@ if(BUILD_TESTING) target_link_libraries(test_trajectory_controller joint_trajectory_controller ) - ament_target_dependencies(test_trajectory_controller ros2_control_test_assets) + target_link_libraries(test_trajectory_controller ros2_control_test_assets::ros2_control_test_assets) target_compile_definitions(joint_trajectory_controller PRIVATE _USE_MATH_DEFINES) add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") @@ -79,12 +90,8 @@ if(BUILD_TESTING) ) target_link_libraries(test_load_joint_trajectory_controller joint_trajectory_controller - ) - ament_target_dependencies(test_load_joint_trajectory_controller - controller_manager - control_toolbox - realtime_tools - ros2_control_test_assets + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) ament_add_gmock(test_trajectory_actions @@ -93,8 +100,7 @@ if(BUILD_TESTING) set_tests_properties(test_trajectory_actions PROPERTIES TIMEOUT 300) target_link_libraries(test_trajectory_actions joint_trajectory_controller - ) - ament_target_dependencies(test_trajectory_actions ros2_control_test_assets) + ros2_control_test_assets::ros2_control_test_assets) endif() diff --git a/mecanum_drive_controller/CMakeLists.txt b/mecanum_drive_controller/CMakeLists.txt index 5e9d2227b6..3755d86e17 100644 --- a/mecanum_drive_controller/CMakeLists.txt +++ b/mecanum_drive_controller/CMakeLists.txt @@ -42,8 +42,18 @@ target_include_directories(mecanum_drive_controller PUBLIC "$" "$") target_link_libraries(mecanum_drive_controller PUBLIC - mecanum_drive_controller_parameters) -ament_target_dependencies(mecanum_drive_controller PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + mecanum_drive_controller_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + tf2::tf2 + ${tf2_geometry_msgs_TARGETS} + ${tf2_msgs_TARGETS} + ${nav_msgs_TARGETS} + ${std_srvs_TARGETS}) pluginlib_export_plugin_description_file( controller_interface mecanum_drive_controller.xml) @@ -57,10 +67,10 @@ if(BUILD_TESTING) add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") ament_add_gmock(test_load_mecanum_drive_controller test/test_load_mecanum_drive_controller.cpp) - ament_target_dependencies(test_load_mecanum_drive_controller - controller_manager - hardware_interface - ros2_control_test_assets + target_link_libraries(test_load_mecanum_drive_controller + controller_manager::controller_manager + hardware_interface::hardware_interface + ros2_control_test_assets::ros2_control_test_assets ) add_rostest_with_parameters_gmock( @@ -68,22 +78,12 @@ if(BUILD_TESTING) ${CMAKE_CURRENT_SOURCE_DIR}/test/mecanum_drive_controller_params.yaml) target_include_directories(test_mecanum_drive_controller PRIVATE include) target_link_libraries(test_mecanum_drive_controller mecanum_drive_controller) - ament_target_dependencies( - test_mecanum_drive_controller - controller_interface - hardware_interface - ) add_rostest_with_parameters_gmock( test_mecanum_drive_controller_preceding test/test_mecanum_drive_controller_preceding.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/mecanum_drive_controller_preceding_params.yaml) target_include_directories(test_mecanum_drive_controller_preceding PRIVATE include) target_link_libraries(test_mecanum_drive_controller_preceding mecanum_drive_controller) - ament_target_dependencies( - test_mecanum_drive_controller_preceding - controller_interface - hardware_interface - ) endif() install( diff --git a/parallel_gripper_controller/CMakeLists.txt b/parallel_gripper_controller/CMakeLists.txt index 2235863f68..716d2b11f5 100644 --- a/parallel_gripper_controller/CMakeLists.txt +++ b/parallel_gripper_controller/CMakeLists.txt @@ -36,9 +36,16 @@ target_include_directories(parallel_gripper_action_controller PUBLIC $ ) target_link_libraries(parallel_gripper_action_controller PUBLIC - parallel_gripper_action_controller_parameters -) -ament_target_dependencies(parallel_gripper_action_controller PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + parallel_gripper_action_controller_parameters + control_toolbox::control_toolbox + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_action::rclcpp_action + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + ${control_msgs_TARGETS}) pluginlib_export_plugin_description_file(controller_interface ros_control_plugins.xml) @@ -50,9 +57,9 @@ if(BUILD_TESTING) add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") ament_add_gmock(test_load_parallel_gripper_action_controllers test/test_load_parallel_gripper_action_controller.cpp) target_include_directories(test_load_parallel_gripper_action_controllers PRIVATE include) - ament_target_dependencies(test_load_parallel_gripper_action_controllers - controller_manager - ros2_control_test_assets + target_link_libraries(test_load_parallel_gripper_action_controllers + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) add_rostest_with_parameters_gmock(test_parallel_gripper_controller diff --git a/pid_controller/CMakeLists.txt b/pid_controller/CMakeLists.txt index 20397570b0..afe6ebf5f0 100644 --- a/pid_controller/CMakeLists.txt +++ b/pid_controller/CMakeLists.txt @@ -49,9 +49,19 @@ target_include_directories(pid_controller PUBLIC $ ) target_link_libraries(pid_controller PUBLIC - pid_controller_parameters -) -ament_target_dependencies(pid_controller PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + pid_controller_parameters + angles::angles + control_toolbox::control_toolbox + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + ${std_srvs_TARGETS} + ${control_msgs_TARGETS} + ${parameter_traits_TARGETS} + ${std_srvs_TARGETS}) pluginlib_export_plugin_description_file(controller_interface pid_controller.xml) @@ -67,11 +77,6 @@ if(BUILD_TESTING) ) target_include_directories(test_pid_controller PRIVATE include) target_link_libraries(test_pid_controller pid_controller) - ament_target_dependencies( - test_pid_controller - controller_interface - hardware_interface - ) add_rostest_with_parameters_gmock( test_pid_controller_preceding @@ -80,11 +85,6 @@ if(BUILD_TESTING) ) target_include_directories(test_pid_controller_preceding PRIVATE include) target_link_libraries(test_pid_controller_preceding pid_controller) - ament_target_dependencies( - test_pid_controller_preceding - controller_interface - hardware_interface - ) add_rostest_with_parameters_gmock( test_pid_controller_dual_interface @@ -93,18 +93,12 @@ if(BUILD_TESTING) ) target_include_directories(test_pid_controller_dual_interface PRIVATE include) target_link_libraries(test_pid_controller_dual_interface pid_controller) - ament_target_dependencies( - test_pid_controller_dual_interface - controller_interface - hardware_interface - ) ament_add_gmock(test_load_pid_controller test/test_load_pid_controller.cpp) target_include_directories(test_load_pid_controller PRIVATE include) - ament_target_dependencies( - test_load_pid_controller - controller_manager - ros2_control_test_assets + target_link_libraries(test_load_pid_controller + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) endif() diff --git a/pose_broadcaster/CMakeLists.txt b/pose_broadcaster/CMakeLists.txt index de4408ae26..fd3254b96d 100644 --- a/pose_broadcaster/CMakeLists.txt +++ b/pose_broadcaster/CMakeLists.txt @@ -38,11 +38,15 @@ target_include_directories(pose_broadcaster PUBLIC $ ) target_link_libraries(pose_broadcaster PUBLIC - pose_broadcaster_parameters -) -ament_target_dependencies(pose_broadcaster PUBLIC - ${THIS_PACKAGE_INCLUDE_DEPENDS} -) + pose_broadcaster_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + ${tf2_msgs_TARGETS} + ${geometry_msgs_TARGETS}) pluginlib_export_plugin_description_file( controller_interface pose_broadcaster.xml @@ -60,10 +64,8 @@ if(BUILD_TESTING) ) target_link_libraries(test_load_pose_broadcaster pose_broadcaster - ) - ament_target_dependencies(test_load_pose_broadcaster - controller_manager - ros2_control_test_assets + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) add_rostest_with_parameters_gmock(test_pose_broadcaster @@ -73,9 +75,6 @@ if(BUILD_TESTING) target_link_libraries(test_pose_broadcaster pose_broadcaster ) - ament_target_dependencies(test_pose_broadcaster - hardware_interface - ) endif() install( diff --git a/position_controllers/CMakeLists.txt b/position_controllers/CMakeLists.txt index a49f073348..fa103c096d 100644 --- a/position_controllers/CMakeLists.txt +++ b/position_controllers/CMakeLists.txt @@ -25,7 +25,10 @@ target_include_directories(position_controllers PUBLIC $ $ ) -ament_target_dependencies(position_controllers PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) +target_link_libraries(position_controllers PUBLIC + forward_command_controller::forward_command_controller + pluginlib::pluginlib + rclcpp::rclcpp) pluginlib_export_plugin_description_file(controller_interface position_controllers_plugins.xml) @@ -39,10 +42,8 @@ if(BUILD_TESTING) ) target_link_libraries(test_load_joint_group_position_controller position_controllers - ) - ament_target_dependencies(test_load_joint_group_position_controller - controller_manager - ros2_control_test_assets + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) ament_add_gmock(test_joint_group_position_controller diff --git a/range_sensor_broadcaster/CMakeLists.txt b/range_sensor_broadcaster/CMakeLists.txt index cdc63f2751..8782abe97d 100644 --- a/range_sensor_broadcaster/CMakeLists.txt +++ b/range_sensor_broadcaster/CMakeLists.txt @@ -42,10 +42,15 @@ target_include_directories(range_sensor_broadcaster PRIVATE $ PRIVATE $ ) -ament_target_dependencies(range_sensor_broadcaster ${THIS_PACKAGE_INCLUDE_DEPENDS}) -target_link_libraries(range_sensor_broadcaster - range_sensor_broadcaster_parameters -) +target_link_libraries(range_sensor_broadcaster PUBLIC + range_sensor_broadcaster_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + ${sensor_msgs_TARGETS}) pluginlib_export_plugin_description_file( controller_interface range_sensor_broadcaster.xml) @@ -61,11 +66,9 @@ if(BUILD_TESTING) target_include_directories(test_load_range_sensor_broadcaster PRIVATE include) target_link_libraries(test_load_range_sensor_broadcaster range_sensor_broadcaster - ) - ament_target_dependencies(test_load_range_sensor_broadcaster - controller_manager - hardware_interface - ros2_control_test_assets + controller_manager::controller_manager + hardware_interface::hardware_interface + ros2_control_test_assets::ros2_control_test_assets ) add_rostest_with_parameters_gmock(test_range_sensor_broadcaster @@ -75,9 +78,6 @@ if(BUILD_TESTING) target_link_libraries(test_range_sensor_broadcaster range_sensor_broadcaster ) - ament_target_dependencies(test_range_sensor_broadcaster - hardware_interface - ) endif() install( diff --git a/steering_controllers_library/CMakeLists.txt b/steering_controllers_library/CMakeLists.txt index 9599e01d55..d57b00d278 100644 --- a/steering_controllers_library/CMakeLists.txt +++ b/steering_controllers_library/CMakeLists.txt @@ -46,8 +46,20 @@ target_include_directories(steering_controllers_library PUBLIC "$" "$") target_link_libraries(steering_controllers_library PUBLIC - steering_controllers_library_parameters) -ament_target_dependencies(steering_controllers_library PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + steering_controllers_library_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + tf2::tf2 + tf2_geometry_msgs::tf2_geometry_msgs + ${tf2_msgs_TARGETS} + ${geometry_msgs_TARGETS} + ${control_msgs_TARGETS} + ${nav_msgs_TARGETS} + ${std_srvs_TARGETS}) if(BUILD_TESTING) find_package(ament_cmake_gmock REQUIRED) @@ -59,11 +71,7 @@ if(BUILD_TESTING) ${CMAKE_CURRENT_SOURCE_DIR}/test/steering_controllers_library_params.yaml) target_include_directories(test_steering_controllers_library PRIVATE include) target_link_libraries(test_steering_controllers_library steering_controllers_library) - ament_target_dependencies( - test_steering_controllers_library - controller_interface - hardware_interface - ) + ament_add_gmock(test_steering_odometry test/test_steering_odometry.cpp) target_link_libraries(test_steering_odometry steering_controllers_library) diff --git a/tricycle_controller/CMakeLists.txt b/tricycle_controller/CMakeLists.txt index 7192afa5cc..0c71042d63 100644 --- a/tricycle_controller/CMakeLists.txt +++ b/tricycle_controller/CMakeLists.txt @@ -46,8 +46,22 @@ target_include_directories(tricycle_controller PUBLIC $ $ ) -target_link_libraries(tricycle_controller PUBLIC tricycle_controller_parameters) -ament_target_dependencies(tricycle_controller PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) +target_link_libraries(tricycle_controller PUBLIC + tricycle_controller_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + tf2::tf2 + rcpputils::rcpputils + ${ackermann_msgs_TARGETS} + ${nav_msgs_TARGETS} + ${geometry_msgs_TARGETS} + ${tf2_msgs_TARGETS} + ${std_srvs_TARGETS} + ${builtin_interfaces_TARGETS}) pluginlib_export_plugin_description_file(controller_interface tricycle_controller.xml) @@ -61,25 +75,15 @@ if(BUILD_TESTING) target_link_libraries(test_tricycle_controller tricycle_controller ) - ament_target_dependencies(test_tricycle_controller - geometry_msgs - hardware_interface - nav_msgs - rclcpp - rclcpp_lifecycle - realtime_tools - tf2 - tf2_msgs - ) add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") ament_add_gmock(test_load_tricycle_controller test/test_load_tricycle_controller.cpp) target_link_libraries(test_load_tricycle_controller tricycle_controller ) - ament_target_dependencies(test_load_tricycle_controller - controller_manager - ros2_control_test_assets + target_link_libraries(test_load_tricycle_controller + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) ament_add_gmock(test_traction_limiter diff --git a/tricycle_steering_controller/CMakeLists.txt b/tricycle_steering_controller/CMakeLists.txt index ef8901f674..22eb46bbea 100644 --- a/tricycle_steering_controller/CMakeLists.txt +++ b/tricycle_steering_controller/CMakeLists.txt @@ -40,8 +40,15 @@ target_include_directories(tricycle_steering_controller PUBLIC "$" "$") target_link_libraries(tricycle_steering_controller PUBLIC - tricycle_steering_controller_parameters) -ament_target_dependencies(tricycle_steering_controller PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) + tricycle_steering_controller_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + steering_controllers_library::steering_controllers_library + ${std_srvs_TARGETS}) pluginlib_export_plugin_description_file( controller_interface tricycle_steering_controller.xml) @@ -54,10 +61,10 @@ if(BUILD_TESTING) add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") ament_add_gmock(test_load_tricycle_steering_controller test/test_load_tricycle_steering_controller.cpp) - ament_target_dependencies(test_load_tricycle_steering_controller - controller_manager - hardware_interface - ros2_control_test_assets + target_link_libraries(test_load_tricycle_steering_controller + controller_manager::controller_manager + hardware_interface::hardware_interface + ros2_control_test_assets::ros2_control_test_assets ) add_rostest_with_parameters_gmock( @@ -65,22 +72,12 @@ if(BUILD_TESTING) ${CMAKE_CURRENT_SOURCE_DIR}/test/tricycle_steering_controller_params.yaml) target_include_directories(test_tricycle_steering_controller PRIVATE include) target_link_libraries(test_tricycle_steering_controller tricycle_steering_controller) - ament_target_dependencies( - test_tricycle_steering_controller - controller_interface - hardware_interface - ) add_rostest_with_parameters_gmock( test_tricycle_steering_controller_preceding test/test_tricycle_steering_controller_preceding.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test/tricycle_steering_controller_preceding_params.yaml) target_include_directories(test_tricycle_steering_controller_preceding PRIVATE include) target_link_libraries(test_tricycle_steering_controller_preceding tricycle_steering_controller) - ament_target_dependencies( - test_tricycle_steering_controller_preceding - controller_interface - hardware_interface - ) endif() install( diff --git a/velocity_controllers/CMakeLists.txt b/velocity_controllers/CMakeLists.txt index dc89696b03..153a8c13ed 100644 --- a/velocity_controllers/CMakeLists.txt +++ b/velocity_controllers/CMakeLists.txt @@ -25,7 +25,10 @@ target_include_directories(velocity_controllers PUBLIC $ $ ) -ament_target_dependencies(velocity_controllers PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS}) +target_link_libraries(velocity_controllers PUBLIC + forward_command_controller::forward_command_controller + pluginlib::pluginlib + rclcpp::rclcpp) pluginlib_export_plugin_description_file(controller_interface velocity_controllers_plugins.xml) @@ -39,10 +42,8 @@ if(BUILD_TESTING) ) target_link_libraries(test_load_joint_group_velocity_controller velocity_controllers - ) - ament_target_dependencies(test_load_joint_group_velocity_controller - controller_manager - ros2_control_test_assets + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets ) ament_add_gmock(test_joint_group_velocity_controller From 2c6c3c8ed5811a30b512472d736b88fac282fb50 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sun, 25 May 2025 20:20:08 +0200 Subject: [PATCH 009/108] Cleanup and grooming of CI (backport #1701) (#1703) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christoph Fröhlich --- .github/workflows/humble-binary-build.yml | 2 +- .github/workflows/humble-debian-build.yml | 6 +-- .../humble-rhel-semi-binary-build.yml | 6 +-- .../workflows/humble-semi-binary-build.yml | 2 +- .github/workflows/humble-source-build.yml | 2 +- .github/workflows/jazzy-binary-build.yml | 2 +- .github/workflows/jazzy-debian-build.yml | 6 +-- .../jazzy-rhel-semi-binary-build.yml | 6 +-- .github/workflows/jazzy-semi-binary-build.yml | 2 +- .github/workflows/jazzy-source-build.yml | 2 +- .github/workflows/prerelease-check.yml | 37 ------------------- .github/workflows/rolling-binary-build.yml | 2 +- .github/workflows/rolling-debian-build.yml | 6 +-- .../rolling-rhel-semi-binary-build.yml | 6 +-- .../workflows/rolling-semi-binary-build.yml | 2 +- .github/workflows/rolling-source-build.yml | 2 +- 16 files changed, 27 insertions(+), 64 deletions(-) delete mode 100644 .github/workflows/prerelease-check.yml diff --git a/.github/workflows/humble-binary-build.yml b/.github/workflows/humble-binary-build.yml index 069a5240f5..e0fccb05cb 100644 --- a/.github/workflows/humble-binary-build.yml +++ b/.github/workflows/humble-binary-build.yml @@ -34,7 +34,7 @@ on: - '**.xml' schedule: # Run every morning to detect flakiness and broken dependencies - - cron: '03 1 * * *' + - cron: '03 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on humble branch diff --git a/.github/workflows/humble-debian-build.yml b/.github/workflows/humble-debian-build.yml index bc92501862..195f1b084c 100644 --- a/.github/workflows/humble-debian-build.yml +++ b/.github/workflows/humble-debian-build.yml @@ -1,4 +1,4 @@ -name: Debian Humble Source Build +name: Humble - Debian Semi-Binary Build on: workflow_dispatch: pull_request: @@ -17,7 +17,7 @@ on: - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies - - cron: '03 1 * * *' + - cron: '03 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on humble branch @@ -25,7 +25,7 @@ concurrency: cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} jobs: - humble_debian: + debian_semi_binary_build: name: Humble debian build uses: ros-controls/ros2_control_ci/.github/workflows/reusable-debian-build.yml@master with: diff --git a/.github/workflows/humble-rhel-semi-binary-build.yml b/.github/workflows/humble-rhel-semi-binary-build.yml index 46d3dd1989..3e11c5e681 100644 --- a/.github/workflows/humble-rhel-semi-binary-build.yml +++ b/.github/workflows/humble-rhel-semi-binary-build.yml @@ -1,4 +1,4 @@ -name: RHEL Humble Binary Build +name: Humble - RHEL Semi-Binary Build on: workflow_dispatch: pull_request: @@ -17,7 +17,7 @@ on: - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies - - cron: '03 1 * * *' + - cron: '03 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on humble branch @@ -25,7 +25,7 @@ concurrency: cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} jobs: - humble_rhel_binary: + rhel_semi_binary_build: name: Humble RHEL binary build uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master with: diff --git a/.github/workflows/humble-semi-binary-build.yml b/.github/workflows/humble-semi-binary-build.yml index 1fa14dfdfa..d74dd9ff79 100644 --- a/.github/workflows/humble-semi-binary-build.yml +++ b/.github/workflows/humble-semi-binary-build.yml @@ -33,7 +33,7 @@ on: - '**.xml' schedule: # Run every morning to detect flakiness and broken dependencies - - cron: '33 1 * * *' + - cron: '33 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on humble branch diff --git a/.github/workflows/humble-source-build.yml b/.github/workflows/humble-source-build.yml index 5a56849e9b..de3987ce15 100644 --- a/.github/workflows/humble-source-build.yml +++ b/.github/workflows/humble-source-build.yml @@ -17,7 +17,7 @@ on: - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies - - cron: '03 3 * * *' + - cron: '03 3 * * MON-FRI' jobs: source: diff --git a/.github/workflows/jazzy-binary-build.yml b/.github/workflows/jazzy-binary-build.yml index 7cf26806a7..b258c54443 100644 --- a/.github/workflows/jazzy-binary-build.yml +++ b/.github/workflows/jazzy-binary-build.yml @@ -35,7 +35,7 @@ on: - '**.xml' schedule: # Run every morning to detect flakiness and broken dependencies - - cron: '03 1 * * *' + - cron: '03 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on jazzy branch diff --git a/.github/workflows/jazzy-debian-build.yml b/.github/workflows/jazzy-debian-build.yml index 4fa94e190f..ed30fc88fc 100644 --- a/.github/workflows/jazzy-debian-build.yml +++ b/.github/workflows/jazzy-debian-build.yml @@ -1,4 +1,4 @@ -name: Debian Jazzy Source Build +name: Jazzy - Debian Semi-Binary Build on: workflow_dispatch: pull_request: @@ -17,7 +17,7 @@ on: - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies - - cron: '03 1 * * *' + - cron: '03 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on jazzy branch @@ -25,7 +25,7 @@ concurrency: cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} jobs: - jazzy_debian: + debian_semi_binary_build: name: Rolling debian build uses: ros-controls/ros2_control_ci/.github/workflows/reusable-debian-build.yml@master with: diff --git a/.github/workflows/jazzy-rhel-semi-binary-build.yml b/.github/workflows/jazzy-rhel-semi-binary-build.yml index f5e8aedc14..c6beef4f63 100644 --- a/.github/workflows/jazzy-rhel-semi-binary-build.yml +++ b/.github/workflows/jazzy-rhel-semi-binary-build.yml @@ -1,4 +1,4 @@ -name: RHEL Jazzy Semi-Binary Build +name: Jazzy - RHEL Semi-Binary Build on: workflow_dispatch: pull_request: @@ -17,7 +17,7 @@ on: - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies - - cron: '03 1 * * *' + - cron: '03 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on jazzy branch @@ -25,7 +25,7 @@ concurrency: cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} jobs: - jazzy_rhel: + rhel_semi_binary_build: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master with: ros_distro: jazzy diff --git a/.github/workflows/jazzy-semi-binary-build.yml b/.github/workflows/jazzy-semi-binary-build.yml index a150580bbc..c0666f5009 100644 --- a/.github/workflows/jazzy-semi-binary-build.yml +++ b/.github/workflows/jazzy-semi-binary-build.yml @@ -35,7 +35,7 @@ on: - '**.xml' schedule: # Run every morning to detect flakiness and broken dependencies - - cron: '33 1 * * *' + - cron: '33 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on jazzy branch diff --git a/.github/workflows/jazzy-source-build.yml b/.github/workflows/jazzy-source-build.yml index bd521c9b59..ffff45184f 100644 --- a/.github/workflows/jazzy-source-build.yml +++ b/.github/workflows/jazzy-source-build.yml @@ -17,7 +17,7 @@ on: - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies - - cron: '03 3 * * *' + - cron: '03 3 * * MON-FRI' jobs: source: diff --git a/.github/workflows/prerelease-check.yml b/.github/workflows/prerelease-check.yml deleted file mode 100644 index 182df6e22b..0000000000 --- a/.github/workflows/prerelease-check.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Pre-Release Check - -on: - workflow_dispatch: - inputs: - ros_distro: - description: 'Chose ROS distribution' - required: true - default: 'rolling' - type: choice - options: - - humble - - iron - - rolling - branch: - description: 'Chose branch for distro' - required: true - default: 'master' - type: choice - options: - - humble - - iron - - master - -jobs: - pre_release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.branch }} - - name: industrial_ci - uses: ros-industrial/industrial_ci@master - env: - ROS_DISTRO: ${{ github.event.inputs.ros_distro }} - PRERELEASE: true - BASEDIR: ${{ github.workspace }}/.work diff --git a/.github/workflows/rolling-binary-build.yml b/.github/workflows/rolling-binary-build.yml index 701bc170a7..4be5a36c05 100644 --- a/.github/workflows/rolling-binary-build.yml +++ b/.github/workflows/rolling-binary-build.yml @@ -38,7 +38,7 @@ on: - '**.xml' schedule: # Run every morning to detect flakiness and broken dependencies - - cron: '03 1 * * *' + - cron: '03 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on master branch diff --git a/.github/workflows/rolling-debian-build.yml b/.github/workflows/rolling-debian-build.yml index 059b71cfed..9de2912060 100644 --- a/.github/workflows/rolling-debian-build.yml +++ b/.github/workflows/rolling-debian-build.yml @@ -1,4 +1,4 @@ -name: Debian Rolling Source Build +name: Rolling - Debian Semi-Binary Build on: workflow_dispatch: pull_request: @@ -18,7 +18,7 @@ on: - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies - - cron: '03 1 * * *' + - cron: '03 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on master branch @@ -26,7 +26,7 @@ concurrency: cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} jobs: - rolling_debian: + debian_semi_binary_build: name: Rolling debian build uses: ros-controls/ros2_control_ci/.github/workflows/reusable-debian-build.yml@master strategy: diff --git a/.github/workflows/rolling-rhel-semi-binary-build.yml b/.github/workflows/rolling-rhel-semi-binary-build.yml index e7d80da8fc..f2f60c6c6d 100644 --- a/.github/workflows/rolling-rhel-semi-binary-build.yml +++ b/.github/workflows/rolling-rhel-semi-binary-build.yml @@ -1,4 +1,4 @@ -name: RHEL Rolling Semi-Binary Build +name: Rolling - RHEL Semi-Binary Build on: workflow_dispatch: pull_request: @@ -18,7 +18,7 @@ on: - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies - - cron: '03 1 * * *' + - cron: '03 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on master branch @@ -26,7 +26,7 @@ concurrency: cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} jobs: - rolling_rhel: + rhel_semi_binary_build: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master strategy: fail-fast: false diff --git a/.github/workflows/rolling-semi-binary-build.yml b/.github/workflows/rolling-semi-binary-build.yml index 631e478e02..987c341a60 100644 --- a/.github/workflows/rolling-semi-binary-build.yml +++ b/.github/workflows/rolling-semi-binary-build.yml @@ -37,7 +37,7 @@ on: - '**.xml' schedule: # Run every morning to detect flakiness and broken dependencies - - cron: '33 1 * * *' + - cron: '33 1 * * MON-FRI' concurrency: # cancel previous runs of the same workflow, except for pushes on master branch diff --git a/.github/workflows/rolling-source-build.yml b/.github/workflows/rolling-source-build.yml index 26a50dc47e..e62849f22e 100644 --- a/.github/workflows/rolling-source-build.yml +++ b/.github/workflows/rolling-source-build.yml @@ -18,7 +18,7 @@ on: - '**.xml' schedule: # Run every day to detect flakiness and broken dependencies - - cron: '03 3 * * *' + - cron: '03 3 * * MON-FRI' jobs: source: From 90ed757e70a384268bf1c3785f9b24ad4fd1d5c8 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 26 May 2025 08:25:12 +0200 Subject: [PATCH 010/108] Remove CMAKE_CXX_STANDARD (backport #1704) (#1706) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christoph Fröhlich --- range_sensor_broadcaster/CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/range_sensor_broadcaster/CMakeLists.txt b/range_sensor_broadcaster/CMakeLists.txt index 8782abe97d..4ef234f812 100644 --- a/range_sensor_broadcaster/CMakeLists.txt +++ b/range_sensor_broadcaster/CMakeLists.txt @@ -1,12 +1,6 @@ cmake_minimum_required(VERSION 3.8) project(range_sensor_broadcaster) -# Default to C++17 -if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) -endif() - find_package(ros2_control_cmake REQUIRED) set_compiler_options() export_windows_symbols() From 080299a7439a022f902dc6493218b9ffb45f0fcf Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 26 May 2025 09:01:20 +0200 Subject: [PATCH 011/108] Fix JSB+GPIO CMakeLists and dependencies (backport #1705) (#1707) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christoph Fröhlich --- gpio_controllers/CMakeLists.txt | 1 - joint_state_broadcaster/CMakeLists.txt | 6 +++--- joint_state_broadcaster/package.xml | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/gpio_controllers/CMakeLists.txt b/gpio_controllers/CMakeLists.txt index 56dfd29b25..3ceafb990a 100644 --- a/gpio_controllers/CMakeLists.txt +++ b/gpio_controllers/CMakeLists.txt @@ -32,7 +32,6 @@ target_link_libraries(gpio_controllers PUBLIC pluginlib::pluginlib rclcpp::rclcpp rclcpp_lifecycle::rclcpp_lifecycle - rcutils::rcutils realtime_tools::realtime_tools ${control_msgs_TARGETS} ${builtin_interfaces_TARGETS}) diff --git a/joint_state_broadcaster/CMakeLists.txt b/joint_state_broadcaster/CMakeLists.txt index df6c67c89e..d7f5890659 100644 --- a/joint_state_broadcaster/CMakeLists.txt +++ b/joint_state_broadcaster/CMakeLists.txt @@ -12,7 +12,6 @@ set(THIS_PACKAGE_INCLUDE_DEPENDS generate_parameter_library pluginlib rclcpp_lifecycle - rcutils realtime_tools sensor_msgs urdf @@ -38,14 +37,12 @@ target_include_directories(joint_state_broadcaster PUBLIC ) target_link_libraries(joint_state_broadcaster PUBLIC joint_state_broadcaster_parameters - controller_manager::controller_manager controller_interface::controller_interface pluginlib::pluginlib rclcpp::rclcpp rclcpp_lifecycle::rclcpp_lifecycle realtime_tools::realtime_tools urdf::urdf - rcutils::rcutils ${sensor_msgs_TARGETS} ${control_msgs_TARGETS} ${builtin_interfaces_TARGETS}) @@ -63,6 +60,9 @@ if(BUILD_TESTING) ) target_link_libraries(test_load_joint_state_broadcaster joint_state_broadcaster + controller_manager::controller_manager + hardware_interface::hardware_interface + rclcpp::rclcpp ros2_control_test_assets::ros2_control_test_assets) ament_add_gmock(test_joint_state_broadcaster diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index 6c20c02b3c..12bd7a095b 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -30,7 +30,6 @@ pluginlib rclcpp_lifecycle rclcpp - rcutils realtime_tools sensor_msgs urdf From 7df20f687beca74500c88e97d5331fe1707342b7 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 12:08:27 +0200 Subject: [PATCH 012/108] Reset both sec and nanosec in time_from_start (backport #1709) (#1711) Co-authored-by: Arnav Kapoor --- .../src/joint_trajectory_controller.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index 6890cea55e..71425da399 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -167,7 +167,8 @@ controller_interface::return_type JointTrajectoryController::update( } // current state update - state_current_.time_from_start.set__sec(0); + state_current_.time_from_start.sec = 0; + state_current_.time_from_start.nanosec = 0; read_state_from_state_interfaces(state_current_); // currently carrying out a trajectory From 4b50c763edf46c2429e20bfa03630ad9459408de Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 28 May 2025 14:31:46 +0200 Subject: [PATCH 013/108] Add missing github_url to rst files (backport #1717) (#1719) --- gpio_controllers/doc/userdoc.rst | 2 ++ mecanum_drive_controller/doc/userdoc.rst | 2 ++ 2 files changed, 4 insertions(+) diff --git a/gpio_controllers/doc/userdoc.rst b/gpio_controllers/doc/userdoc.rst index 199a4bd208..a59da906bb 100644 --- a/gpio_controllers/doc/userdoc.rst +++ b/gpio_controllers/doc/userdoc.rst @@ -1,3 +1,5 @@ +:github_url: https://github.com/ros-controls/ros2_controllers/blob/{REPOS_FILE_BRANCH}/gpio_controllers/doc/userdoc.rst + .. _gpio_controllers_userdoc: gpio_controllers diff --git a/mecanum_drive_controller/doc/userdoc.rst b/mecanum_drive_controller/doc/userdoc.rst index e22bcb6cdc..d823281110 100644 --- a/mecanum_drive_controller/doc/userdoc.rst +++ b/mecanum_drive_controller/doc/userdoc.rst @@ -1,3 +1,5 @@ +:github_url: https://github.com/ros-controls/ros2_controllers/blob/{REPOS_FILE_BRANCH}/mecanum_drive_controller/doc/userdoc.rst + .. _mecanum_drive_controller_userdoc: mecanum_drive_controller From fa4f95b7ce243624eecdf0e25ca3826ffb1700a8 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 2 Jun 2025 13:18:50 +0200 Subject: [PATCH 014/108] Bump version of pre-commit hooks (backport #1725) (#1727) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ee0e31793a..9f9dc20516 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: # Python hooks - repo: https://github.com/asottile/pyupgrade - rev: v3.19.1 + rev: v3.20.0 hooks: - id: pyupgrade args: [--py36-plus] @@ -63,7 +63,7 @@ repos: # CPP hooks - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v20.1.3 + rev: v20.1.5 hooks: - id: clang-format args: ['-fallback-style=none', '-i'] From e188bf9fff615ae47af3c84635467e801453460f Mon Sep 17 00:00:00 2001 From: Jasper van Brakel <36795178+SuperJappie08@users.noreply.github.com> Date: Tue, 3 Jun 2025 08:04:38 +0200 Subject: [PATCH 015/108] Fix DiffDrive claiming state when open_loop is set (#1730) --- diff_drive_controller/doc/userdoc.rst | 1 + .../diff_drive_controller.hpp | 2 +- .../src/diff_drive_controller.cpp | 50 ++++++++----- .../test/test_diff_drive_controller.cpp | 70 +++++++++++++++++++ 4 files changed, 103 insertions(+), 20 deletions(-) diff --git a/diff_drive_controller/doc/userdoc.rst b/diff_drive_controller/doc/userdoc.rst index 2fce07a31b..f2ec74f7d9 100644 --- a/diff_drive_controller/doc/userdoc.rst +++ b/diff_drive_controller/doc/userdoc.rst @@ -41,6 +41,7 @@ Feedback ,,,,,,,,,,,,,, As feedback interface type the joints' position (``hardware_interface::HW_IF_POSITION``) or velocity (``hardware_interface::HW_IF_VELOCITY``,if parameter ``position_feedback=false``) are used. +Unless the parameter ``open_loop=true`` is set, then no external state interfaces are used (the commanded velocity is used for odometry instead). Output ,,,,,,,,, diff --git a/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp b/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp index 665203c1c9..c736c0032a 100644 --- a/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp +++ b/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp @@ -83,7 +83,7 @@ class DiffDriveController : public controller_interface::ChainableControllerInte struct WheelHandle { - std::reference_wrapper feedback; + std::optional> feedback; std::reference_wrapper velocity; }; diff --git a/diff_drive_controller/src/diff_drive_controller.cpp b/diff_drive_controller/src/diff_drive_controller.cpp index fdc79c131d..6ad267ec4e 100644 --- a/diff_drive_controller/src/diff_drive_controller.cpp +++ b/diff_drive_controller/src/diff_drive_controller.cpp @@ -85,6 +85,11 @@ InterfaceConfiguration DiffDriveController::command_interface_configuration() co InterfaceConfiguration DiffDriveController::state_interface_configuration() const { + if (params_.open_loop) + { + return {interface_configuration_type::NONE, {}}; + } + std::vector conf_names; for (const auto & joint_name : params_.left_wheel_names) { @@ -168,9 +173,9 @@ controller_interface::return_type DiffDriveController::update_and_write_commands for (size_t index = 0; index < static_cast(wheels_per_side_); ++index) { const auto left_feedback_op = - registered_left_wheel_handles_[index].feedback.get().get_optional(); + registered_left_wheel_handles_[index].feedback.value().get().get_optional(); const auto right_feedback_op = - registered_right_wheel_handles_[index].feedback.get().get_optional(); + registered_right_wheel_handles_[index].feedback.value().get().get_optional(); if (!left_feedback_op.has_value() || !right_feedback_op.has_value()) { @@ -667,21 +672,6 @@ controller_interface::CallbackReturn DiffDriveController::configure_side( registered_handles.reserve(wheel_names.size()); for (const auto & wheel_name : wheel_names) { - const auto interface_name = feedback_type(); - const auto state_handle = std::find_if( - state_interfaces_.cbegin(), state_interfaces_.cend(), - [&wheel_name, &interface_name](const auto & interface) - { - return interface.get_prefix_name() == wheel_name && - interface.get_interface_name() == interface_name; - }); - - if (state_handle == state_interfaces_.cend()) - { - RCLCPP_ERROR(logger, "Unable to obtain joint state handle for %s", wheel_name.c_str()); - return controller_interface::CallbackReturn::ERROR; - } - const auto command_handle = std::find_if( command_interfaces_.begin(), command_interfaces_.end(), [&wheel_name](const auto & interface) @@ -696,8 +686,30 @@ controller_interface::CallbackReturn DiffDriveController::configure_side( return controller_interface::CallbackReturn::ERROR; } - registered_handles.emplace_back( - WheelHandle{std::ref(*state_handle), std::ref(*command_handle)}); + if (params_.open_loop) + { + registered_handles.emplace_back(WheelHandle{std::nullopt, std::ref(*command_handle)}); + } + else + { + const auto interface_name = feedback_type(); + const auto state_handle = std::find_if( + state_interfaces_.cbegin(), state_interfaces_.cend(), + [&wheel_name, &interface_name](const auto & interface) + { + return interface.get_prefix_name() == wheel_name && + interface.get_interface_name() == interface_name; + }); + + if (state_handle == state_interfaces_.cend()) + { + RCLCPP_ERROR(logger, "Unable to obtain joint state handle for %s", wheel_name.c_str()); + return controller_interface::CallbackReturn::ERROR; + } + + registered_handles.emplace_back( + WheelHandle{{std::ref(*state_handle)}, std::ref(*command_handle)}); + } } return controller_interface::CallbackReturn::SUCCESS; diff --git a/diff_drive_controller/test/test_diff_drive_controller.cpp b/diff_drive_controller/test/test_diff_drive_controller.cpp index 1b01e5b067..4cd64bdd6d 100644 --- a/diff_drive_controller/test/test_diff_drive_controller.cpp +++ b/diff_drive_controller/test/test_diff_drive_controller.cpp @@ -175,6 +175,15 @@ class TestDiffDriveController : public ::testing::Test controller_->assign_interfaces(std::move(command_ifs), std::move(state_ifs)); } + void assignResourcesNoFeedback() + { + std::vector command_ifs; + command_ifs.emplace_back(left_wheel_vel_cmd_); + command_ifs.emplace_back(right_wheel_vel_cmd_); + + controller_->assign_interfaces(std::move(command_ifs), {}); + } + controller_interface::return_type InitController( const std::vector left_wheel_joints_init = left_wheel_names, const std::vector right_wheel_joints_init = right_wheel_names, @@ -262,6 +271,26 @@ TEST_F( EXPECT_EQ(cmd_if_conf.type, controller_interface::interface_configuration_type::INDIVIDUAL); } +TEST_F( + TestDiffDriveController, + command_and_state_interface_configuration_succeeds_when_wheels_and_open_loop_are_specified) +{ + ASSERT_EQ( + InitController( + left_wheel_names, right_wheel_names, + {rclcpp::Parameter("open_loop", rclcpp::ParameterValue(true))}), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + + auto state_if_conf = controller_->state_interface_configuration(); + ASSERT_THAT(state_if_conf.names, SizeIs(0)); + EXPECT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::NONE); + auto cmd_if_conf = controller_->command_interface_configuration(); + ASSERT_THAT(cmd_if_conf.names, SizeIs(left_wheel_names.size() + right_wheel_names.size())); + EXPECT_EQ(cmd_if_conf.type, controller_interface::interface_configuration_type::INDIVIDUAL); +} + TEST_F(TestDiffDriveController, configure_succeeds_tf_test_prefix_false_no_namespace) { std::string odom_id = "odom"; @@ -458,6 +487,19 @@ TEST_F(TestDiffDriveController, activate_succeeds_with_vel_resources_assigned) ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); } +TEST_F(TestDiffDriveController, activate_succeeds_with_open_loop_assigned) +{ + ASSERT_EQ( + InitController( + left_wheel_names, right_wheel_names, + {rclcpp::Parameter("open_loop", rclcpp::ParameterValue(true))}), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + assignResourcesNoFeedback(); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); +} + TEST_F(TestDiffDriveController, test_speed_limiter) { // If you send a linear velocity command without acceleration limits, @@ -690,6 +732,34 @@ TEST_F(TestDiffDriveController, activate_fails_with_wrong_resources_assigned_2) ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), CallbackReturn::ERROR); } +TEST_F(TestDiffDriveController, activate_silently_ignores_with_unnecessary_resources_assigned_1) +{ + ASSERT_EQ( + InitController( + left_wheel_names, right_wheel_names, + {rclcpp::Parameter("open_loop", rclcpp::ParameterValue(true)), + rclcpp::Parameter("position_feedback", rclcpp::ParameterValue(false))}), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + assignResourcesPosFeedback(); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); +} + +TEST_F(TestDiffDriveController, activate_silently_ignores_with_unnecessary_resources_assigned_2) +{ + ASSERT_EQ( + InitController( + left_wheel_names, right_wheel_names, + {rclcpp::Parameter("open_loop", rclcpp::ParameterValue(true)), + rclcpp::Parameter("position_feedback", rclcpp::ParameterValue(true))}), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + assignResourcesVelFeedback(); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); +} + TEST_F(TestDiffDriveController, cleanup) { ASSERT_EQ( From ae05ed42c0f6707dbec0cefbcadf7c978e012158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Thu, 5 Jun 2025 15:44:37 +0200 Subject: [PATCH 016/108] Fix steering_controllers_library docs (#1734) --- steering_controllers_library/doc/userdoc.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/steering_controllers_library/doc/userdoc.rst b/steering_controllers_library/doc/userdoc.rst index 487cf94bb9..1aac29d543 100644 --- a/steering_controllers_library/doc/userdoc.rst +++ b/steering_controllers_library/doc/userdoc.rst @@ -64,7 +64,7 @@ Command interfaces ,,,,,,,,,,,,,,,,,,, - ``/position`` double, in rad -- ``/velocity`` double, in m/s +- ``/velocity`` double, in rad/s State interfaces ,,,,,,,,,,,,,,,,, @@ -77,7 +77,7 @@ Depending on the ``position_feedback``, different feedback types are expected With the following state interfaces: - ``/position`` double, in rad -- ``/`` double, in m or m/s +- ``/`` double, in rad or rad/s Subscribers ,,,,,,,,,,,, From ccc91f32871bfd0a30b860148914d0870786bca7 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 5 Jun 2025 15:46:02 +0200 Subject: [PATCH 017/108] JTC: Use std::atomic (backport #1720) (#1723) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christoph Fröhlich Co-authored-by: Sai Kishor Kothakota --- .../joint_trajectory_controller.hpp | 5 +-- .../src/joint_trajectory_controller.cpp | 36 +++++++++---------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp index ad4abb6335..19e74af61d 100644 --- a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp +++ b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp @@ -15,6 +15,7 @@ #ifndef JOINT_TRAJECTORY_CONTROLLER__JOINT_TRAJECTORY_CONTROLLER_HPP_ #define JOINT_TRAJECTORY_CONTROLLER__JOINT_TRAJECTORY_CONTROLLER_HPP_ +#include #include // for std::reference_wrapper #include #include @@ -152,7 +153,7 @@ class JointTrajectoryController : public controller_interface::ControllerInterfa // Timeout to consider commands old double cmd_timeout_; // True if holding position or repeating last trajectory point in case of success - realtime_tools::RealtimeBuffer rt_is_holding_; + std::atomic rt_is_holding_; // TODO(karsten1987): eventually activate and deactivate subscriber directly when its supported bool subscriber_is_active_ = false; rclcpp::Subscription::SharedPtr joint_command_subscriber_ = @@ -179,7 +180,7 @@ class JointTrajectoryController : public controller_interface::ControllerInterfa rclcpp_action::Server::SharedPtr action_server_; RealtimeGoalHandleBuffer rt_active_goal_; ///< Currently active action goal, if any. - realtime_tools::RealtimeBuffer rt_has_pending_goal_; ///< Is there a pending action goal? + std::atomic rt_has_pending_goal_; ///< Is there a pending action goal? rclcpp::TimerBase::SharedPtr goal_handle_timer_; rclcpp::Duration action_monitor_period_ = rclcpp::Duration(50ms); diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index 71425da399..403df0563c 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -157,8 +157,7 @@ controller_interface::return_type JointTrajectoryController::update( auto new_external_msg = new_trajectory_msg_.readFromRT(); // Discard, if a goal is pending but still not active (somewhere stuck in goal_handle_timer_) if ( - current_trajectory_msg != *new_external_msg && - (*(rt_has_pending_goal_.readFromRT()) && !active_goal) == false) + current_trajectory_msg != *new_external_msg && (rt_has_pending_goal_ && !active_goal) == false) { fill_partial_goal(*new_external_msg); sort_to_local_joint_order(*new_external_msg); @@ -230,7 +229,7 @@ controller_interface::return_type JointTrajectoryController::update( // have we reached the end, are not holding position, and is a timeout configured? // Check independently of other tolerances if ( - !before_last_point && *(rt_is_holding_.readFromRT()) == false && cmd_timeout_ > 0.0 && + !before_last_point && !rt_is_holding_ && cmd_timeout_ > 0.0 && time_difference > cmd_timeout_) { RCLCPP_WARN(logger, "Aborted due to command timeout"); @@ -248,7 +247,7 @@ controller_interface::return_type JointTrajectoryController::update( // is the last point // print output per default, goal will be aborted afterwards if ( - (before_last_point || first_sample) && *(rt_is_holding_.readFromRT()) == false && + (before_last_point || first_sample) && !rt_is_holding_ && !check_state_tolerance_per_joint( state_error_, index, active_tol->state_tolerance[index], true /* show_errors */)) { @@ -256,7 +255,7 @@ controller_interface::return_type JointTrajectoryController::update( } // past the final point, check that we end up inside goal tolerance if ( - !before_last_point && *(rt_is_holding_.readFromRT()) == false && + !before_last_point && !rt_is_holding_ && !check_state_tolerance_per_joint( state_error_, index, active_tol->goal_state_tolerance[index], false /* show_errors */)) { @@ -357,7 +356,7 @@ controller_interface::return_type JointTrajectoryController::update( // TODO(matthew-reynolds): Need a lock-free write here // See https://github.com/ros-controls/ros2_controllers/issues/168 rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr()); - rt_has_pending_goal_.writeFromNonRT(false); + rt_has_pending_goal_ = false; RCLCPP_WARN(logger, "Aborted due to state tolerance violation"); @@ -376,7 +375,7 @@ controller_interface::return_type JointTrajectoryController::update( // TODO(matthew-reynolds): Need a lock-free write here // See https://github.com/ros-controls/ros2_controllers/issues/168 rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr()); - rt_has_pending_goal_.writeFromNonRT(false); + rt_has_pending_goal_ = false; RCLCPP_INFO(logger, "Goal reached, success!"); @@ -395,7 +394,7 @@ controller_interface::return_type JointTrajectoryController::update( // TODO(matthew-reynolds): Need a lock-free write here // See https://github.com/ros-controls/ros2_controllers/issues/168 rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr()); - rt_has_pending_goal_.writeFromNonRT(false); + rt_has_pending_goal_ = false; RCLCPP_WARN(logger, "%s", error_string.c_str()); @@ -404,7 +403,7 @@ controller_interface::return_type JointTrajectoryController::update( } } } - else if (tolerance_violated_while_moving && *(rt_has_pending_goal_.readFromRT()) == false) + else if (tolerance_violated_while_moving && !rt_has_pending_goal_) { // we need to ensure that there is no pending goal -> we get a race condition otherwise RCLCPP_ERROR(logger, "Holding position due to state tolerance violation"); @@ -412,8 +411,7 @@ controller_interface::return_type JointTrajectoryController::update( new_trajectory_msg_.reset(); new_trajectory_msg_.initRT(set_hold_position()); } - else if ( - !before_last_point && !within_goal_time && *(rt_has_pending_goal_.readFromRT()) == false) + else if (!before_last_point && !within_goal_time && !rt_has_pending_goal_) { RCLCPP_ERROR(logger, "Exceeded goal_time_tolerance: holding position..."); @@ -1038,7 +1036,7 @@ controller_interface::CallbackReturn JointTrajectoryController::on_activate( // The controller should start by holding position at the beginning of active state add_new_trajectory_msg(set_hold_position()); - rt_is_holding_.writeFromNonRT(true); + rt_is_holding_ = true; // parse timeout parameter if (params_.cmd_timeout > 0.0) @@ -1070,7 +1068,7 @@ controller_interface::CallbackReturn JointTrajectoryController::on_deactivate( const auto active_goal = *rt_active_goal_.readFromNonRT(); if (active_goal) { - rt_has_pending_goal_.writeFromNonRT(false); + rt_has_pending_goal_ = false; auto action_res = std::make_shared(); action_res->set__error_code(FollowJTrajAction::Result::INVALID_GOAL); action_res->set__error_string("Current goal cancelled during deactivate transition."); @@ -1188,7 +1186,7 @@ void JointTrajectoryController::topic_callback( if (subscriber_is_active_) { add_new_trajectory_msg(msg); - rt_is_holding_.writeFromNonRT(false); + rt_is_holding_ = false; } }; @@ -1227,7 +1225,7 @@ rclcpp_action::CancelResponse JointTrajectoryController::goal_cancelled_callback get_node()->get_logger(), "Canceling active action goal because cancel callback received."); // Mark the current goal as canceled - rt_has_pending_goal_.writeFromNonRT(false); + rt_has_pending_goal_ = false; auto action_res = std::make_shared(); active_goal->setCanceled(action_res); rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr()); @@ -1242,7 +1240,7 @@ void JointTrajectoryController::goal_accepted_callback( std::shared_ptr> goal_handle) { // mark a pending goal - rt_has_pending_goal_.writeFromNonRT(true); + rt_has_pending_goal_ = true; // Update new trajectory { @@ -1251,7 +1249,7 @@ void JointTrajectoryController::goal_accepted_callback( std::make_shared(goal_handle->get_goal()->trajectory); add_new_trajectory_msg(traj_msg); - rt_is_holding_.writeFromNonRT(false); + rt_is_holding_ = false; } // Update the active goal @@ -1603,7 +1601,7 @@ JointTrajectoryController::set_hold_position() hold_position_msg_ptr_->points[0].positions = state_current_.positions; // set flag, otherwise tolerances will be checked with holding position too - rt_is_holding_.writeFromNonRT(true); + rt_is_holding_ = true; return hold_position_msg_ptr_; } @@ -1617,7 +1615,7 @@ JointTrajectoryController::set_success_trajectory_point() hold_position_msg_ptr_->points[0].time_from_start = rclcpp::Duration(0, 0); // set flag, otherwise tolerances will be checked with success_trajectory_point too - rt_is_holding_.writeFromNonRT(true); + rt_is_holding_ = true; return hold_position_msg_ptr_; } From d90d2e6f278af61e224c3ba713e99e55cc44a9da Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Fri, 6 Jun 2025 22:44:36 +0100 Subject: [PATCH 018/108] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 5 +++++ admittance_controller/CHANGELOG.rst | 5 +++++ bicycle_steering_controller/CHANGELOG.rst | 5 +++++ diff_drive_controller/CHANGELOG.rst | 6 ++++++ effort_controllers/CHANGELOG.rst | 5 +++++ force_torque_sensor_broadcaster/CHANGELOG.rst | 5 +++++ forward_command_controller/CHANGELOG.rst | 5 +++++ gpio_controllers/CHANGELOG.rst | 7 +++++++ gps_sensor_broadcaster/CHANGELOG.rst | 5 +++++ gripper_controllers/CHANGELOG.rst | 3 +++ imu_sensor_broadcaster/CHANGELOG.rst | 5 +++++ joint_state_broadcaster/CHANGELOG.rst | 6 ++++++ joint_trajectory_controller/CHANGELOG.rst | 7 +++++++ mecanum_drive_controller/CHANGELOG.rst | 6 ++++++ parallel_gripper_controller/CHANGELOG.rst | 5 +++++ pid_controller/CHANGELOG.rst | 5 +++++ pose_broadcaster/CHANGELOG.rst | 5 +++++ position_controllers/CHANGELOG.rst | 5 +++++ range_sensor_broadcaster/CHANGELOG.rst | 6 ++++++ ros2_controllers/CHANGELOG.rst | 3 +++ ros2_controllers_test_nodes/CHANGELOG.rst | 3 +++ rqt_joint_trajectory_controller/CHANGELOG.rst | 3 +++ steering_controllers_library/CHANGELOG.rst | 6 ++++++ tricycle_controller/CHANGELOG.rst | 5 +++++ tricycle_steering_controller/CHANGELOG.rst | 5 +++++ velocity_controllers/CHANGELOG.rst | 5 +++++ 26 files changed, 131 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index a93c0d1da5..e708192b8a 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 8cdb1d867e..e52faf070d 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 13ddae4361..ce5bbd19eb 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index ff5e70d6c8..273152d97f 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix DiffDrive claiming state when open_loop is set (`#1730 `_) +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: Jasper van Brakel, mergify[bot] + 4.25.0 (2025-05-17) ------------------- * Simplify `on_set_chained_mode` avoiding cpplint warnings (backport `#1564 `_) (`#1688 `_) diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 150b8d49fa..46409b1da4 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 48276f8860..38887555e4 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- * Add multiplier support to ForceTorqueSensorBroadcaster (backport `#1647 `_) (`#1686 `_) diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 58b521e5bf..a27fc496b6 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 7e930008a3..d94339a3db 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Add missing github_url to rst files (backport `#1717 `_) (`#1719 `_) +* Fix JSB+GPIO CMakeLists and dependencies (backport `#1705 `_) (`#1707 `_) +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index e0eb1a11b4..d83b0dd332 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 3df1b79faf..f93bd8b0ae 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.25.0 (2025-05-17) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 0e5fb0feb9..c994c36015 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index fe925258f1..e427bd6f84 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix JSB+GPIO CMakeLists and dependencies (backport `#1705 `_) (`#1707 `_) +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 4aac99c6a4..304f734bda 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* JTC: Use std::atomic (backport `#1720 `_) (`#1723 `_) +* Reset both sec and nanosec in time_from_start (backport `#1709 `_) (`#1711 `_) +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 52be81d145..d47eec8601 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Add missing github_url to rst files (backport `#1717 `_) (`#1719 `_) +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- * Simplify `on_set_chained_mode` avoiding cpplint warnings (backport `#1564 `_) (`#1688 `_) diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index f95d7b395e..8366ce35a3 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index f6252e3d63..6afb82c065 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- * [Pid] Add enable_feedforward parameter (backport `#1553 `_) (`#1689 `_) diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 66a47971ac..bd4cab3e6f 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 3914f3e3dd..0574c77e28 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 3bbc4f607c..4ab72cd634 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Remove CMAKE_CXX_STANDARD (backport `#1704 `_) (`#1706 `_) +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 6b01ee1910..018193ee56 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.25.0 (2025-05-17) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 93e2c75765..aba70d2bf7 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.25.0 (2025-05-17) ------------------- * Use `warning` attribute of RcutilsLogger (backport `#1690 `_) (`#1691 `_) diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 01dfc2c101..aca43c2974 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.25.0 (2025-05-17) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 7edc41616b..18a93bde9e 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix steering_controllers_library docs (`#1734 `_) +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: Christoph Fröhlich, mergify[bot] + 4.25.0 (2025-05-17) ------------------- * Simplify `on_set_chained_mode` avoiding cpplint warnings (backport `#1564 `_) (`#1688 `_) diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index c303d8c7a5..02bfccc1ab 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- * Deprecating tf2 C Headers (`#1325 `_) diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 666e1e62a5..cd4e28ac23 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index ec427e2971..f8ef539a5a 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) +* Contributors: mergify[bot] + 4.25.0 (2025-05-17) ------------------- From c18c7f5401ccd385f5d4749ea1fcdc356736d252 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Fri, 6 Jun 2025 22:45:10 +0100 Subject: [PATCH 019/108] 4.26.0 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 54 files changed, 80 insertions(+), 80 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index e708192b8a..674e98a6de 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index c9c2b85262..bb99a8acc2 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.25.0 + 4.26.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index e52faf070d..2ae6992e36 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index fb0d3f3748..a8a90ad09b 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.25.0 + 4.26.0 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index ce5bbd19eb..6722fdeb4b 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index f80bba80a6..50a612fe84 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.25.0 + 4.26.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 273152d97f..cd57c2bf16 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Fix DiffDrive claiming state when open_loop is set (`#1730 `_) * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: Jasper van Brakel, mergify[bot] diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 847156c3c3..a0b32df388 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.25.0 + 4.26.0 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 46409b1da4..7036a2f15f 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index c2666cc630..8e2c1f918e 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.25.0 + 4.26.0 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 38887555e4..41efdd9544 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index f88520ce9a..4206d872aa 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.25.0 + 4.26.0 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index a27fc496b6..3183476c29 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index 7e7f83d4a4..31ad98d692 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.25.0 + 4.26.0 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index d94339a3db..b1da4c9c66 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Add missing github_url to rst files (backport `#1717 `_) (`#1719 `_) * Fix JSB+GPIO CMakeLists and dependencies (backport `#1705 `_) (`#1707 `_) * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index 569bce8ab2..652429431a 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.25.0 + 4.26.0 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index d83b0dd332..76b78e599a 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index 9cc2c668c7..5d5ce1f1d9 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.25.0 + 4.26.0 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index f93bd8b0ae..bcf5f27ac4 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- 4.25.0 (2025-05-17) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index 46c1bc8171..0e324fa654 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.25.0 + 4.26.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index c994c36015..9bd9b1e14e 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index ce79276d35..8362df235c 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.25.0 + 4.26.0 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index e427bd6f84..431d28eb23 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Fix JSB+GPIO CMakeLists and dependencies (backport `#1705 `_) (`#1707 `_) * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index 12bd7a095b..4807f1db6d 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.25.0 + 4.26.0 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 304f734bda..696b22d311 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * JTC: Use std::atomic (backport `#1720 `_) (`#1723 `_) * Reset both sec and nanosec in time_from_start (backport `#1709 `_) (`#1711 `_) * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index b39002a43c..04a246ef7f 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.25.0 + 4.26.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index d47eec8601..0e0e6f4b30 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Add missing github_url to rst files (backport `#1717 `_) (`#1719 `_) * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index 720b81a8f4..2e32fec079 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.25.0 + 4.26.0 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 8366ce35a3..b4919fd1e1 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index 8055c11fa9..69f2bd1e53 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.25.0 + 4.26.0 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 6afb82c065..d8b1ac6f3c 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/pid_controller/package.xml b/pid_controller/package.xml index 865499de85..0eced4f730 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.25.0 + 4.26.0 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index bd4cab3e6f..067ecf5a4d 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index 6ea45a1f1c..9fe7706263 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.25.0 + 4.26.0 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 0574c77e28..45aed6c2ec 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/position_controllers/package.xml b/position_controllers/package.xml index 556423cbee..f9cbe6da03 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.25.0 + 4.26.0 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 4ab72cd634..6bc8ef7403 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Remove CMAKE_CXX_STANDARD (backport `#1704 `_) (`#1706 `_) * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index ff02605a3b..ae0abc331e 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.25.0 + 4.26.0 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 018193ee56..949aaa5f92 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- 4.25.0 (2025-05-17) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 0905b6445d..33606fdb99 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.25.0 + 4.26.0 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index aba70d2bf7..7cb270d9bd 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- 4.25.0 (2025-05-17) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 5dc88545d4..ef2c09c2ab 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.25.0 + 4.26.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index e2f552d3ab..bd447d311a 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.25.0", + version="4.26.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index aca43c2974..d15b78b3ce 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- 4.25.0 (2025-05-17) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 599d35cb63..5a9cfbdc85 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.25.0 + 4.26.0 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index 421acd82a3..34f28f05bc 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.25.0", + version="4.26.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 18a93bde9e..59b7829ab6 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Fix steering_controllers_library docs (`#1734 `_) * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: Christoph Fröhlich, mergify[bot] diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index 9bd4ec3ef2..fda8ec789e 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.25.0 + 4.26.0 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 02bfccc1ab..47127f2484 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index c71364b164..a48f75ae86 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.25.0 + 4.26.0 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index cd4e28ac23..1d3385230a 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index 40491f5f82..65df53929c 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.25.0 + 4.26.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index f8ef539a5a..1058ddeaa9 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.26.0 (2025-06-06) +------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) * Contributors: mergify[bot] diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index 81a27a6b28..39e6a89d1f 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.25.0 + 4.26.0 Generic controller for forwarding commands. Bence Magyar From 9683ad48b230712c9ae6a5b5c0986f2feda3693f Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 7 Jun 2025 21:34:39 +0200 Subject: [PATCH 020/108] Set enable_feedforward parameter in the respective tests (backport #1743) (#1744) Co-authored-by: Sai Kishor Kothakota --- pid_controller/test/test_pid_controller.cpp | 2 ++ pid_controller/test/test_pid_controller_dual_interface.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/pid_controller/test/test_pid_controller.cpp b/pid_controller/test/test_pid_controller.cpp index 2a3b99e969..3b74e2c094 100644 --- a/pid_controller/test/test_pid_controller.cpp +++ b/pid_controller/test/test_pid_controller.cpp @@ -346,6 +346,7 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward controller_->set_reference(dof_command_values_); + controller_->get_node()->set_parameter(rclcpp::Parameter("enable_feedforward", true)); controller_->feedforward_mode_enabled_.writeFromNonRT(true); EXPECT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), true); @@ -586,6 +587,7 @@ TEST_F(PidControllerTest, test_update_chained_feedforward_with_gain) const double expected_command_value = 6.95; SetUpController("test_pid_controller_with_feedforward_gain"); + controller_->get_node()->set_parameter(rclcpp::Parameter("enable_feedforward", true)); ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); // check on interfaces & pid gain parameters diff --git a/pid_controller/test/test_pid_controller_dual_interface.cpp b/pid_controller/test/test_pid_controller_dual_interface.cpp index 6db9171bcb..2cf6ae8a20 100644 --- a/pid_controller/test/test_pid_controller_dual_interface.cpp +++ b/pid_controller/test/test_pid_controller_dual_interface.cpp @@ -56,6 +56,7 @@ class PidControllerDualInterfaceTest : public PidControllerFixtureget_node()->set_parameter(rclcpp::Parameter("enable_feedforward", true)); ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); // check on interfaces & pid gain parameters From 9bc49d00732a5447cbaa6908eeffbe46d9c68a8f Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 7 Jun 2025 23:49:45 +0200 Subject: [PATCH 021/108] Revert temporary logging changes added for CI timeout investigation (backport #1741) (#1747) Co-authored-by: Julia Jia --- .../src/force_torque_sensor_broadcaster.cpp | 24 +------------------ .../test_force_torque_sensor_broadcaster.cpp | 15 +----------- 2 files changed, 2 insertions(+), 37 deletions(-) diff --git a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp index 8f8d419af1..9605cd8c2a 100644 --- a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp @@ -76,12 +76,6 @@ controller_interface::CallbackReturn ForceTorqueSensorBroadcaster::on_configure( { force_torque_sensor_ = std::make_unique( semantic_components::ForceTorqueSensor(params_.sensor_name)); - - // TODO(juliaj): remove the logging after resolving - // https://github.com/ros-controls/ros2_controllers/issues/1574 - RCLCPP_INFO( - get_node()->get_logger(), "Initialized force_torque_sensor with sensor name %s", - params_.sensor_name.c_str()); } else { @@ -91,14 +85,6 @@ controller_interface::CallbackReturn ForceTorqueSensorBroadcaster::on_configure( semantic_components::ForceTorqueSensor( force_names.x, force_names.y, force_names.z, torque_names.x, torque_names.y, torque_names.z)); - - // TODO(juliaj): remove the logging after resolving - // https://github.com/ros-controls/ros2_controllers/issues/1574 - RCLCPP_INFO( - get_node()->get_logger(), - "Initialized force_torque_sensor with interface names %s, %s, %s, %s, %s, %s", - force_names.x.c_str(), force_names.y.c_str(), force_names.z.c_str(), torque_names.x.c_str(), - torque_names.y.c_str(), torque_names.z.c_str()); } try @@ -116,19 +102,11 @@ controller_interface::CallbackReturn ForceTorqueSensorBroadcaster::on_configure( return controller_interface::CallbackReturn::ERROR; } - // TODO(juliaj): remove the logging after resolving - // https://github.com/ros-controls/ros2_controllers/issues/1574 - RCLCPP_INFO(get_node()->get_logger(), "Locking realtime publisher"); realtime_publisher_->lock(); - RCLCPP_INFO(get_node()->get_logger(), "Locked realtime publisher"); - realtime_publisher_->msg_.header.frame_id = params_.frame_id; - - RCLCPP_INFO(get_node()->get_logger(), "Unlocking realtime publisher"); realtime_publisher_->unlock(); - RCLCPP_INFO(get_node()->get_logger(), "Unlocked realtime publisher"); - RCLCPP_INFO(get_node()->get_logger(), "Configure successful"); + RCLCPP_INFO(get_node()->get_logger(), "configure successful"); return controller_interface::CallbackReturn::SUCCESS; } diff --git a/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp b/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp index 60acf093e8..053eec35d1 100644 --- a/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp @@ -48,13 +48,7 @@ void ForceTorqueSensorBroadcasterTest::SetUp() fts_broadcaster_ = std::make_unique(); } -void ForceTorqueSensorBroadcasterTest::TearDown() -{ - // TODO(juliaj): remove the logging after resolving - // https://github.com/ros-controls/ros2_controllers/issues/1574 - RCLCPP_INFO(fts_broadcaster_->get_node()->get_logger(), "In TearDown"); - fts_broadcaster_.reset(nullptr); -} +void ForceTorqueSensorBroadcasterTest::TearDown() { fts_broadcaster_.reset(nullptr); } void ForceTorqueSensorBroadcasterTest::SetUpFTSBroadcaster() { @@ -72,9 +66,6 @@ void ForceTorqueSensorBroadcasterTest::SetUpFTSBroadcaster() state_ifs.emplace_back(fts_torque_z_); fts_broadcaster_->assign_interfaces({}, std::move(state_ifs)); - // TODO(juliaj): remove the logging after resolving - // https://github.com/ros-controls/ros2_controllers/issues/1574 - RCLCPP_INFO(fts_broadcaster_->get_node()->get_logger(), "FTSBroadcaster setup done"); } void ForceTorqueSensorBroadcasterTest::subscribe_and_get_message( @@ -189,10 +180,6 @@ TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_Configure_Success) { SetUpFTSBroadcaster(); - // TODO(juliaj): remove the logging after resolving - // https://github.com/ros-controls/ros2_controllers/issues/1574 - RCLCPP_INFO(fts_broadcaster_->get_node()->get_logger(), "Setting up interface names"); - // set the 'interface_names' fts_broadcaster_->get_node()->set_parameter({"interface_names.force.x", "fts_sensor/force.x"}); fts_broadcaster_->get_node()->set_parameter({"interface_names.torque.z", "fts_sensor/torque.z"}); From 621e8962a6b1da3a0454716a8fe9cb522a41b03f Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 13:46:57 +0200 Subject: [PATCH 022/108] [JTC Doc] Update PID documentation for effort related command interface support (backport #1748) (#1752) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Julia Jia Co-authored-by: Christoph Fröhlich --- .../doc/parameters_context.yaml | 24 ++++++++++++++----- joint_trajectory_controller/doc/userdoc.rst | 6 ++--- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/joint_trajectory_controller/doc/parameters_context.yaml b/joint_trajectory_controller/doc/parameters_context.yaml index 9623899245..9d3f8753f2 100644 --- a/joint_trajectory_controller/doc/parameters_context.yaml +++ b/joint_trajectory_controller/doc/parameters_context.yaml @@ -2,17 +2,29 @@ constraints: Default values for tolerances if no explicit values are set in the ``JointTrajectory`` message. gains: | - If ``velocity`` is the only command interface for all joints or an ``effort`` command interface is configured, PID controllers are used for every joint. - This structure contains the controller gains for every joint with the control law + The parameters are used to configure PID loops for the ``velocity`` or ``effort``-only command interfaces. This structure contains the controller gains for every joint with following the control laws - .. math:: u = k_{ff} v_d + k_p e + k_i \sum e dt + k_d (v_d - v) + * If ``velocity`` is the only command interface: - with the desired velocity :math:`v_d`, the measured velocity :math:`v`, the position error :math:`e` (definition see below), - the controller period :math:`dt`, and the ``velocity`` or ``effort`` manipulated variable (control variable) :math:`u`, respectively. + .. math:: + + u = k_{ff} v_d + k_p e + k_i \sum e dt + k_d (v_d - v) + + with the desired velocity :math:`v_d`, the measured velocity :math:`v`, the position error :math:`e` (definition see below), + the controller period :math:`dt`, and the ``velocity`` manipulated variable (control variable) :math:`u`, respectively. + + * If ``effort`` is the only command interface: + + .. math:: + + u = k_{ff} v_d + \delta_d + k_p e + k_i \sum e dt + k_d (v_d - v) + + with the desired velocity :math:`v_d`, the desired effort :math:`\delta_d` if provided in the trajectory (or 0 otherwise), the measured velocity :math:`v`, the position error :math:`e` (definition see below), + the controller period :math:`dt`, and the ``effort`` manipulated variable (control variable) :math:`u`, respectively. If the joint is of continuous type, the position error :math:`e = normalize(s_d - s)` is normalized between :math:`-\pi, \pi`, i.e., the shortest rotation to the target position is the desired motion. Otherwise :math:`e = s_d - s` is used, with the desired position :math:`s_d` and the measured position :math:`s` from the state interface. - If you want to turn off the PIDs (open loop control), set the feedback gains to zero. + If you want to turn off the PIDs (open loop control), set the feedback gains to zero and an appropriate value for feed-forward gain :math:`k_{ff}`. diff --git a/joint_trajectory_controller/doc/userdoc.rst b/joint_trajectory_controller/doc/userdoc.rst index c1a244bc88..357afbabf1 100644 --- a/joint_trajectory_controller/doc/userdoc.rst +++ b/joint_trajectory_controller/doc/userdoc.rst @@ -30,9 +30,9 @@ This means that the joints can have one or more command interfaces, where the fo * For command interfaces ``position``, the desired positions are simply forwarded to the joints, * For command interfaces ``acceleration``, desired accelerations are simply forwarded to the joints. -* For ``velocity`` (``effort``) command interfaces, the position+velocity trajectory following error is mapped to ``velocity`` (``effort``) commands through a PID loop if it is configured (:ref:`parameters`). -* For ``effort`` command interface (without ``position`` command interface), if the trajectory contains effort, this will be added to the PID commands as a feed forward effort. -* For ``position, effort`` command interface, if the trajectory contains effort, this will be passed directly to the ``effort`` interface (PID won't be used) while the positions will be passed to the ``position`` interface. +* For ``velocity`` command interfaces, the position+velocity trajectory following error is mapped to ``velocity`` commands through a PID loop if it is configured (:ref:`parameters`). +* For ``effort`` command interface (without ``position`` command interface), the position+velocity trajectory following error is mapped to ``effort`` commands through a PID loop if it is configured (:ref:`parameters`). In addition, it adds trajectory's effort as feedforward effort to the PID output. +* For ``position, effort`` command interface, PID loop is not used. If the trajectory contains effort, its value will be passed directly to the ``effort`` interface while the desired positions will be forwarded to the ``position`` interface. This could be useful for manipulation tasks where you need to add that extra force to maintain contact. This leads to the following allowed combinations of command and state interfaces: From 8f8880ee079a48b2dba74673e6291478a23d970e Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 18 Jun 2025 10:42:06 +0200 Subject: [PATCH 023/108] Add new AntiWindup parameters to JTC (backport #1759) (#1762) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christoph Fröhlich Co-authored-by: Sai Kishor Kothakota --- doc/release_notes.rst | 4 +- .../src/joint_trajectory_controller.cpp | 11 ++++- ...oint_trajectory_controller_parameters.yaml | 47 +++++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index fe2f7e5d5b..a199c8b8af 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -54,6 +54,8 @@ joint_trajectory_controller * Add the boolean parameter ``set_last_command_interface_value_as_state_on_activation``. When set to ``true``, the last command interface value is used as both the current state and the last commanded state upon activation. When set to ``false``, the current state is used for both (`#1231 `_). * Feed-forward effort trajectories are supported now (`#1200 `_). * Parameter ``open_loop_control`` is replaced by ``interpolate_from_desired_state`` and setting the feedback gains to zero (`#1525 `_). +* The controller now supports the new anti-windup strategy of the PID class, which allows for more flexible control of the anti-windup behavior. (`#1759 `__). + mecanum_drive_controller ************************ @@ -83,4 +85,4 @@ gpio_controllers force_torque_sensor_broadcaster ******************************* -* Multiplier support was added. Users can now specify per–axis scaling factors for both force and torque readings, applied after the existing offset logic. (`#1647 `__. +* Multiplier support was added. Users can now specify per–axis scaling factors for both force and torque readings, applied after the existing offset logic. (`#1647 `__). diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index 403df0563c..dfcbc02d76 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -1673,16 +1673,23 @@ void JointTrajectoryController::update_pids() for (size_t i = 0; i < num_cmd_joints_; ++i) { const auto & gains = params_.gains.joints_map.at(params_.joints.at(map_cmd_to_joints_[i])); + control_toolbox::AntiWindupStrategy antiwindup_strat; + antiwindup_strat.set_type(gains.antiwindup_strategy); + antiwindup_strat.i_max = gains.i_clamp; + antiwindup_strat.i_min = -gains.i_clamp; + antiwindup_strat.error_deadband = gains.error_deadband; + antiwindup_strat.tracking_time_constant = gains.tracking_time_constant; if (pids_[i]) { // update PIDs with gains from ROS parameters - pids_[i]->set_gains(gains.p, gains.i, gains.d, gains.i_clamp, -gains.i_clamp); + pids_[i]->set_gains( + gains.p, gains.i, gains.d, gains.u_clamp_max, gains.u_clamp_min, antiwindup_strat); } else { // Init PIDs with gains from ROS parameters pids_[i] = std::make_shared( - gains.p, gains.i, gains.d, gains.i_clamp, -gains.i_clamp); + gains.p, gains.i, gains.d, gains.u_clamp_max, gains.u_clamp_min, antiwindup_strat); } ff_velocity_scale_[i] = gains.ff_velocity_scale; } diff --git a/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml b/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml index 926366cde6..44748368ef 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml +++ b/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml @@ -140,6 +140,53 @@ joint_trajectory_controller: default_value: 0.0, description: "Feed-forward scaling :math:`k_{ff}` of velocity" } + u_clamp_max: { + type: double, + default_value: .inf, + description: "Upper output clamp." + } + u_clamp_min: { + type: double, + default_value: -.inf, + description: "Lower output clamp." + } + i_clamp_max: { + type: double, + default_value: 0.0, + description: "[Deprecated, see antiwindup_strategy] Upper integral clamp." + } + i_clamp_min: { + type: double, + default_value: 0.0, + description: "[Deprecated, see antiwindup_strategy] Lower integral clamp." + } + antiwindup_strategy: { + type: string, + default_value: "legacy", + read_only: true, + description: "Specifies the anti-windup strategy. Options: 'back_calculation', + 'conditional_integration', 'legacy' or 'none'. Note that the 'back_calculation' strategy use the + tracking_time_constant parameter to tune the anti-windup behavior.", + validation: { + one_of<>: [[ + "back_calculation", + "conditional_integration", + "legacy", + "none" + ]] + } + } + tracking_time_constant: { + type: double, + default_value: 0.0, + description: "Specifies the tracking time constant for the 'back_calculation' strategy. If + set to 0.0 when this strategy is selected, a recommended default value will be applied." + } + error_deadband: { + type: double, + default_value: 0.0, + description: "Is used to stop integration when the error is within the given range." + } constraints: stopped_velocity_tolerance: { type: double, From 22e925d3945a1998ac2170414e135e04618f42e8 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 18 Jun 2025 21:03:09 +0200 Subject: [PATCH 024/108] Fix atomic variables in JTC (backport #1749) (#1766) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christoph Fröhlich --- .../joint_trajectory_controller.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp index 19e74af61d..fecfa3af28 100644 --- a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp +++ b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp @@ -153,9 +153,9 @@ class JointTrajectoryController : public controller_interface::ControllerInterfa // Timeout to consider commands old double cmd_timeout_; // True if holding position or repeating last trajectory point in case of success - std::atomic rt_is_holding_; + std::atomic rt_is_holding_{false}; // TODO(karsten1987): eventually activate and deactivate subscriber directly when its supported - bool subscriber_is_active_ = false; + std::atomic subscriber_is_active_{false}; rclcpp::Subscription::SharedPtr joint_command_subscriber_ = nullptr; @@ -179,8 +179,8 @@ class JointTrajectoryController : public controller_interface::ControllerInterfa using RealtimeGoalHandleBuffer = realtime_tools::RealtimeBuffer; rclcpp_action::Server::SharedPtr action_server_; - RealtimeGoalHandleBuffer rt_active_goal_; ///< Currently active action goal, if any. - std::atomic rt_has_pending_goal_; ///< Is there a pending action goal? + RealtimeGoalHandleBuffer rt_active_goal_; ///< Currently active action goal, if any. + std::atomic rt_has_pending_goal_{false}; ///< Is there a pending action goal? rclcpp::TimerBase::SharedPtr goal_handle_timer_; rclcpp::Duration action_monitor_period_ = rclcpp::Duration(50ms); From e434fe2c1d3a837afebec9335d78ba7bcea36a45 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 08:59:19 +0200 Subject: [PATCH 025/108] Add new members for PID controller parameters (backport #1585) (#1769) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Victor Coutinho Vieira Santos <69547580+ViktorCVS@users.noreply.github.com> Co-authored-by: Christoph Fröhlich --- doc/migration.rst | 7 ++++- doc/release_notes.rst | 4 +++ pid_controller/src/pid_controller.yaml | 42 ++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/doc/migration.rst b/doc/migration.rst index ee553e9d26..2a7e197711 100644 --- a/doc/migration.rst +++ b/doc/migration.rst @@ -12,7 +12,6 @@ diff_drive_controller joint_trajectory_controller ***************************** - * Parameter ``allow_nonzero_velocity_at_trajectory_end`` is now per default ``false`` (`#834 `_). * The parameter ``start_with_holding`` is removed, it now always holds the position at activation (`#839 `_). * Goals are now cancelled in ``on_deactivate`` transition (`#962 `_). @@ -22,6 +21,12 @@ joint_trajectory_controller * Tolerances sent with the action goal were not used before, but are now processed and used for the upcoming action. (`#716 `_). Adaptions to the action goal might be necessary. * Parameter ``open_loop_control`` is replaced by ``interpolate_from_desired_state`` and setting the feedback gains to zero (`#1525 `_). +pid_controller +************************ +* Parameters ``enable_feedforward`` and service ``set_feedforward_control`` are deprecated. Instead, set the feedforward_gain to zero or a non-zero value. (`#1553 `_). +* The legacy ``antiwindup`` boolean and integral clamp parameters ``i_clamp_max``/``i_clamp_min`` have + been deprecated in favor of the new ``antiwindup_strategy`` parameter (`#1585 `__). Choose a suitable anti-windup strategy and set the parameters accordingly. + steering_controllers_library ******************************** * ``front_steering`` parameter was removed (`#1166 `_). Now every kinematics type (bicycle, tricycle, Ackermann) has dedicated parameters for steering or traction wheels instead of front/rear wheels. diff --git a/doc/release_notes.rst b/doc/release_notes.rst index a199c8b8af..21dddda580 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -65,6 +65,10 @@ pid_controller ************************ * 🚀 The PID controller was added 🎉 (`#434 `_). * Add ``save_i_term`` parameter to control retention of integral state after re-activation (`#1507 `_). +* The controller now supports the new anti-windup strategy of the PID class, which allows for more flexible control of the anti-windup behavior (`#1585 `__). + * Output clamping via ``u_clamp_max`` and ``u_clamp_min`` was added, allowing users to bound the controller output. + * The legacy ``antiwindup`` boolean and integral clamp parameters ``i_clamp_max``/``i_clamp_min`` have been deprecated in favor of the new ``antiwindup_strategy`` parameter. A ``tracking_time_constant`` parameter has also been introduced to configure the back-calculation strategy. + * A new ``error_deadband`` parameter stops integration when the error is within a specified range. steering_controllers_library ******************************** diff --git a/pid_controller/src/pid_controller.yaml b/pid_controller/src/pid_controller.yaml index 8903085667..459c935d08 100644 --- a/pid_controller/src/pid_controller.yaml +++ b/pid_controller/src/pid_controller.yaml @@ -65,10 +65,20 @@ pid_controller: default_value: 0.0, description: "Derivative gain for PID" } + u_clamp_max: { + type: double, + default_value: .inf, + description: "Upper output clamp." + } + u_clamp_min: { + type: double, + default_value: -.inf, + description: "Lower output clamp." + } antiwindup: { type: bool, default_value: false, - description: "Antiwindup functionality. When set to true, limits + description: "[Deprecated, see antiwindup_strategy] Anti-windup functionality. When set to true, limits the integral error to prevent windup; otherwise, constrains the integral contribution to the control output. i_clamp_max and i_clamp_min are applied in both scenarios." @@ -76,12 +86,38 @@ pid_controller: i_clamp_max: { type: double, default_value: 0.0, - description: "Upper integral clamp." + description: "[Deprecated, see antiwindup_strategy] Upper integral clamp." } i_clamp_min: { type: double, default_value: 0.0, - description: "Lower integral clamp." + description: "[Deprecated, see antiwindup_strategy] Lower integral clamp." + } + antiwindup_strategy: { + type: string, + default_value: "legacy", + description: "Specifies the anti-windup strategy. Options: 'back_calculation', + 'conditional_integration', 'legacy' or 'none'. Note that the 'back_calculation' strategy use the + tracking_time_constant parameter to tune the anti-windup behavior.", + validation: { + one_of<>: [[ + "back_calculation", + "conditional_integration", + "legacy", + "none" + ]] + } + } + tracking_time_constant: { + type: double, + default_value: 0.0, + description: "Specifies the tracking time constant for the 'back_calculation' strategy. If + set to 0.0 when this strategy is selected, a recommended default value will be applied." + } + error_deadband: { + type: double, + default_value: 1.e-16, + description: "Is used to stop integration when the error is within the given range." } feedforward_gain: { type: double, From 5dd920a8deb07912dacea410bb63f96fb8ee6edd Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 14:13:31 +0200 Subject: [PATCH 026/108] Added Swerve Drive Kinematics in mobile_robot_kinematics.rst (backport #1712) (#1771) Co-authored-by: Nitin Maurya <97148529+nitin2606@users.noreply.github.com> Co-authored-by: Christoph Froehlich --- .pre-commit-config.yaml | 1 + doc/images/swerve_drive.drawio | 664 ++++++++++++++++++++++++++++++++ doc/images/swerve_drive.svg | 4 + doc/mobile_robot_kinematics.rst | 85 ++++ 4 files changed, 754 insertions(+) create mode 100644 doc/images/swerve_drive.drawio create mode 100644 doc/images/swerve_drive.svg diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9f9dc20516..839de8bf23 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,6 +29,7 @@ repos: args: ["--allow-multiple-documents"] - id: debug-statements - id: end-of-file-fixer + exclude_types: [svg] - id: mixed-line-ending - id: trailing-whitespace exclude_types: [rst] diff --git a/doc/images/swerve_drive.drawio b/doc/images/swerve_drive.drawio new file mode 100644 index 0000000000..7f79cad6a5 --- /dev/null +++ b/doc/images/swerve_drive.drawio @@ -0,0 +1,664 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/images/swerve_drive.svg b/doc/images/swerve_drive.svg new file mode 100644 index 0000000000..7afefd3c18 --- /dev/null +++ b/doc/images/swerve_drive.svg @@ -0,0 +1,4 @@ + + + +
0
1
2
3
l
0
1
2
3
Rotating Clockwise
w
0
1
2
3
Moving Forward
%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bfont%20style%3D%26quot%3Bcolor%3A%20light-dark(rgb(255%2C%20255%2C%20255)%2C%20rgb(255%2C%20255%2C%20255))%3B%26quot%3B%26gt%3B0%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22text%3Bhtml%3D1%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3Bresizable%3D0%3Bpoints%3D%5B%5D%3Bautosize%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%2282%22%20y%3D%22185%22%20width%3D%2230%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bfont%20style%3D%26quot%3Bcolor%3A%20light-dark(rgb(255%2C%20255%2C%20255)%2C%20rgb(255%2C%20255%2C%20255))%3B%26quot%3B%26gt%3B0%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22text%3Bhtml%3D1%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3Bresizable%3D0%3Bpoints%3D%5B%5D%3Bautosize%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%2282%22%20y%3D%22185%22%20width%3D%2230%22%20height%3D%2230%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E
0
1
2
3
Moving Right
0
1
2
3
Moving Left
\ No newline at end of file diff --git a/doc/mobile_robot_kinematics.rst b/doc/mobile_robot_kinematics.rst index b861733ee7..4bf285972e 100644 --- a/doc/mobile_robot_kinematics.rst +++ b/doc/mobile_robot_kinematics.rst @@ -109,6 +109,91 @@ The body twist of the robot can be obtained from the wheel velocities by using t \omega_n \end{bmatrix} + + +Swerve Drive Robots +,,,,,,,,,,,,,,,,,,, + +The below explains the kinematics of omnidirectional drive robots using four swerve modules, each with independently controlled steering and driving motors. It follows the coordinate conventions defined in `REP-103 `__. + +.. image:: images/swerve_drive.svg + :align: center + :alt: Swerve Drive Robot + +* :math:`x_b, y_b` is the robot's body-frame coordinate system, located at the geometric center of the robot. +* :math:`x_w, y_w` is the world coordinate system. +* :math:`v_{b,x}` is the robot's linear velocity on the x-axis. +* :math:`v_{b,y}` is the robot's linear velocity on the y-axis. +* :math:`\omega_{b,z}` is the robot's angular velocity on the z-axis. +* :math:`l` is the wheelbase (distance between front and rear wheels). +* :math:`w` is the track width (distance between left and right wheels). +* Red arrows on wheel :math:`i` signify the direction of the wheel's velocity :math:`v_i`. + +Each swerve module :math:`i`, for :math:`i = 0, 1, 2, 3` (typically front-left, front-right, back-left, back-right) is located at :math:`(l_{i,x}, l_{i,y})` relative to the center, typically: + +* Front-left: :math:`(l/2, w/2)` +* Front-right: :math:`(l/2, -w/2)` +* Back-left: :math:`(-l/2, w/2)` +* Back-right: :math:`(-l/2, -w/2)` + +**Inverse Kinematics** + +For each module :math:`i` at position :math:`(l_{i,x}, l_{i,y})`, the velocity vector is: + +.. math:: + + \begin{bmatrix} + v_{i,x} \\ + v_{i,y} + \end{bmatrix} + = + \begin{bmatrix} + v_{b,x} - \omega_{b,z} l_{i,y} \\ + v_{b,y} + \omega_{b,z} l_{i,x} + \end{bmatrix} + +The wheel velocity :math:`v_i` and steering angle :math:`\phi_i` are: + +.. math:: + + v_i = \sqrt{v_{i,x}^2 + v_{i,y}^2} + +.. math:: + + \phi_i = \arctan2(v_{i,y}, v_{i,x}) + + +**Odometry** + +The body twist of the robot is computed from the wheel velocities :math:`v_i` and steering angles :math:`\phi_i`. Each module’s velocity components in the body frame are: + +.. math:: + + v_{i,x} = v_i \cos(\phi_i), \quad v_{i,y} = v_i \sin(\phi_i) + +The chassis velocities are calculated as: + +.. math:: + + v_{b,x} = \frac{1}{4} \sum_{i=0}^{3} v_{i,x}, \quad v_{b,y} = \frac{1}{4} \sum_{i=0}^{3} v_{i,y} + +.. math:: + + \omega_{b,z} = \frac{\sum_{i=0}^{3} (v_{i,y} l_{i,x} - v_{i,x} l_{i,y})}{\sum_{i=0}^{3} (l_{i,x}^2 + l_{i,y}^2)} + + + +Odometry updates the robot’s pose (:math:`x`, :math:`y`, :math:`\theta`) in the global frame using the computed chassis velocities. The global velocities are: + +.. math:: + + v_{x,\text{global}} = v_{b,x} \cos(\theta) - v_{b,y} \sin(\theta) + +.. math:: + + v_{y,\text{global}} = v_{b,x} \sin(\theta) + v_{b,y} \cos(\theta) + + Nonholonomic Wheeled Mobile Robots ..................................... From 7c06eb8ed2d03e5d8825b68ba8ff0524d22be232 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Mon, 23 Jun 2025 19:12:13 +0000 Subject: [PATCH 027/108] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 3 +++ admittance_controller/CHANGELOG.rst | 3 +++ bicycle_steering_controller/CHANGELOG.rst | 3 +++ diff_drive_controller/CHANGELOG.rst | 3 +++ effort_controllers/CHANGELOG.rst | 3 +++ force_torque_sensor_broadcaster/CHANGELOG.rst | 5 +++++ forward_command_controller/CHANGELOG.rst | 3 +++ gpio_controllers/CHANGELOG.rst | 3 +++ gps_sensor_broadcaster/CHANGELOG.rst | 3 +++ gripper_controllers/CHANGELOG.rst | 3 +++ imu_sensor_broadcaster/CHANGELOG.rst | 3 +++ joint_state_broadcaster/CHANGELOG.rst | 3 +++ joint_trajectory_controller/CHANGELOG.rst | 7 +++++++ mecanum_drive_controller/CHANGELOG.rst | 3 +++ parallel_gripper_controller/CHANGELOG.rst | 3 +++ pid_controller/CHANGELOG.rst | 6 ++++++ pose_broadcaster/CHANGELOG.rst | 3 +++ position_controllers/CHANGELOG.rst | 3 +++ range_sensor_broadcaster/CHANGELOG.rst | 3 +++ ros2_controllers/CHANGELOG.rst | 3 +++ ros2_controllers_test_nodes/CHANGELOG.rst | 3 +++ rqt_joint_trajectory_controller/CHANGELOG.rst | 3 +++ steering_controllers_library/CHANGELOG.rst | 3 +++ tricycle_controller/CHANGELOG.rst | 3 +++ tricycle_steering_controller/CHANGELOG.rst | 3 +++ velocity_controllers/CHANGELOG.rst | 3 +++ 26 files changed, 87 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 674e98a6de..c719217051 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 2ae6992e36..4733957f32 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 6722fdeb4b..aebf085551 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index cd57c2bf16..1f5602588c 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Fix DiffDrive claiming state when open_loop is set (`#1730 `_) diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 7036a2f15f..c6a91b32c9 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 41efdd9544..c6a4d92f68 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Revert temporary logging changes added for CI timeout investigation (backport `#1741 `_) (`#1747 `_) +* Contributors: Julia Jia + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 3183476c29..b5e866f24d 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index b1da4c9c66..33dff9407f 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Add missing github_url to rst files (backport `#1717 `_) (`#1719 `_) diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 76b78e599a..2d3fed45ba 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index bcf5f27ac4..6a253a0b8d 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 9bd9b1e14e..fee7852d99 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 431d28eb23..25a8ffd07c 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Fix JSB+GPIO CMakeLists and dependencies (backport `#1705 `_) (`#1707 `_) diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 696b22d311..d266de91b0 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix atomic variables in JTC (backport `#1749 `_) (`#1766 `_) +* Add new AntiWindup parameters to JTC (backport `#1759 `_) (`#1762 `_) +* [JTC Doc] Update PID documentation for effort related command interface support (backport `#1748 `_) (`#1752 `_) +* Contributors: Julia Jia, Christoph Fröhlich, Sai Kishor Kothakota + 4.26.0 (2025-06-06) ------------------- * JTC: Use std::atomic (backport `#1720 `_) (`#1723 `_) diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 0e0e6f4b30..50f4b59954 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Add missing github_url to rst files (backport `#1717 `_) (`#1719 `_) diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index b4919fd1e1..38e3b883d5 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index d8b1ac6f3c..85b10838fd 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Add new members for PID controller parameters (backport `#1585 `_) (`#1769 `_) +* Set enable_feedforward parameter in the respective tests (backport `#1743 `_) (`#1744 `_) +* Contributors: Victor Coutinho Vieira Santos, Sai Kishor Kothakota, Christoph Fröhlich + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 067ecf5a4d..ed0b4da806 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 45aed6c2ec..d9fd2e966d 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 6bc8ef7403..6b2200cfe3 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Remove CMAKE_CXX_STANDARD (backport `#1704 `_) (`#1706 `_) diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 949aaa5f92..85e8108c49 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 7cb270d9bd..ac88aabf14 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index d15b78b3ce..306e969f3d 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 59b7829ab6..e49750a3e7 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Fix steering_controllers_library docs (`#1734 `_) diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 47127f2484..1630b54d13 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 1d3385230a..6b9a2bc038 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 1058ddeaa9..2036bb6c86 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.26.0 (2025-06-06) ------------------- * Use target_link_libraries instead of ament_target_dependencies (backport `#1697 `_) (`#1699 `_) From 9c48a5dabe160e2446878a7ba59a0ecab316e68f Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Mon, 23 Jun 2025 19:12:30 +0000 Subject: [PATCH 028/108] 4.27.0 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 54 files changed, 80 insertions(+), 80 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index c719217051..1f56fccb6a 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index bb99a8acc2..2e93da74fe 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.26.0 + 4.27.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 4733957f32..d749cf5283 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index a8a90ad09b..004e0255f9 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.26.0 + 4.27.0 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index aebf085551..63e487aa1a 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index 50a612fe84..389dc51bd1 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.26.0 + 4.27.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 1f5602588c..42b6e4d08c 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index a0b32df388..a7cfe5cf5c 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.26.0 + 4.27.0 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index c6a91b32c9..949f5007c5 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index 8e2c1f918e..390d7edbaa 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.26.0 + 4.27.0 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index c6a4d92f68..bbdd065639 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- * Revert temporary logging changes added for CI timeout investigation (backport `#1741 `_) (`#1747 `_) * Contributors: Julia Jia diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 4206d872aa..65c3d49f15 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.26.0 + 4.27.0 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index b5e866f24d..b26a0504e7 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index 31ad98d692..4a1ffde28f 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.26.0 + 4.27.0 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 33dff9407f..3eb8b35d1a 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index 652429431a..8f2204a28b 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.26.0 + 4.27.0 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 2d3fed45ba..f931945ba1 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index 5d5ce1f1d9..fa55d4674a 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.26.0 + 4.27.0 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 6a253a0b8d..3f35bd8ef4 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index 0e324fa654..e31cdc2833 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.26.0 + 4.27.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index fee7852d99..2dbd18362a 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index 8362df235c..2c7660049c 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.26.0 + 4.27.0 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 25a8ffd07c..b5961ffc2c 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index 4807f1db6d..9da9007930 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.26.0 + 4.27.0 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index d266de91b0..b9ae038b04 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- * Fix atomic variables in JTC (backport `#1749 `_) (`#1766 `_) * Add new AntiWindup parameters to JTC (backport `#1759 `_) (`#1762 `_) * [JTC Doc] Update PID documentation for effort related command interface support (backport `#1748 `_) (`#1752 `_) diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 04a246ef7f..9dfa32fffa 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.26.0 + 4.27.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 50f4b59954..643ae57e13 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index 2e32fec079..69a8f8f94c 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.26.0 + 4.27.0 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 38e3b883d5..3dbf752ff3 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index 69f2bd1e53..008e964f13 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.26.0 + 4.27.0 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 85b10838fd..6e8a028f57 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- * Add new members for PID controller parameters (backport `#1585 `_) (`#1769 `_) * Set enable_feedforward parameter in the respective tests (backport `#1743 `_) (`#1744 `_) * Contributors: Victor Coutinho Vieira Santos, Sai Kishor Kothakota, Christoph Fröhlich diff --git a/pid_controller/package.xml b/pid_controller/package.xml index 0eced4f730..946086e412 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.26.0 + 4.27.0 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index ed0b4da806..f06f3e8eaa 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index 9fe7706263..c328928f87 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.26.0 + 4.27.0 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index d9fd2e966d..09fe3f15ce 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index f9cbe6da03..e45280a234 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.26.0 + 4.27.0 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 6b2200cfe3..991d3a2464 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index ae0abc331e..c01e26c0e4 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.26.0 + 4.27.0 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 85e8108c49..55381579f3 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 33606fdb99..aa36c4a3b7 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.26.0 + 4.27.0 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index ac88aabf14..8afeeec10f 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index ef2c09c2ab..ef280b46c2 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.26.0 + 4.27.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index bd447d311a..397095dcef 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.26.0", + version="4.27.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 306e969f3d..2a2bfa1369 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 5a9cfbdc85..45874f8048 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.26.0 + 4.27.0 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index 34f28f05bc..187d7a54d9 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.26.0", + version="4.27.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index e49750a3e7..ce8d1e56fd 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index fda8ec789e..cb19e42c6f 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.26.0 + 4.27.0 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 1630b54d13..d71a020a6d 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index a48f75ae86..29eda0d7eb 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.26.0 + 4.27.0 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 6b9a2bc038..cfa9a2bed4 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index 65df53929c..b8cb0b335c 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.26.0 + 4.27.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 2036bb6c86..381a29e4df 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.0 (2025-06-23) +------------------- 4.26.0 (2025-06-06) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index 39e6a89d1f..4cc130711c 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.26.0 + 4.27.0 Generic controller for forwarding commands. Bence Magyar From 403b5c4102af0651cab1b9de9897802bbdba9186 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 28 Jun 2025 08:43:04 +0200 Subject: [PATCH 029/108] Fix SteeringOdometry calculation error (backport #1777) (#1779) Co-authored-by: Narukara --- steering_controllers_library/src/steering_odometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/steering_controllers_library/src/steering_odometry.cpp b/steering_controllers_library/src/steering_odometry.cpp index 5f480ca03d..0a5367f4bd 100644 --- a/steering_controllers_library/src/steering_odometry.cpp +++ b/steering_controllers_library/src/steering_odometry.cpp @@ -180,7 +180,7 @@ bool SteeringOdometry::update_from_velocity( double linear_velocity = get_linear_velocity_double_traction_axle( right_traction_wheel_vel, left_traction_wheel_vel, steer_pos_); - const double angular_velocity = steer_pos_ * linear_velocity / wheel_base_; + const double angular_velocity = std::tan(steer_pos_) * linear_velocity / wheel_base_; return update_odometry(linear_velocity, angular_velocity, dt); } From 29a75bb2745d4f64297589e4d9bea47d3f87d4e4 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 21:18:56 +0200 Subject: [PATCH 030/108] Fix cmake deprecation (backport #1780) (#1782) Co-authored-by: mosfet80 <10235105+mosfet80@users.noreply.github.com> --- gpio_controllers/CMakeLists.txt | 2 +- range_sensor_broadcaster/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gpio_controllers/CMakeLists.txt b/gpio_controllers/CMakeLists.txt index 3ceafb990a..a19f7586af 100644 --- a/gpio_controllers/CMakeLists.txt +++ b/gpio_controllers/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.16) project(gpio_controllers) find_package(ros2_control_cmake REQUIRED) diff --git a/range_sensor_broadcaster/CMakeLists.txt b/range_sensor_broadcaster/CMakeLists.txt index 4ef234f812..214e2c6fa9 100644 --- a/range_sensor_broadcaster/CMakeLists.txt +++ b/range_sensor_broadcaster/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.16) project(range_sensor_broadcaster) find_package(ros2_control_cmake REQUIRED) From bcb5a48cd04a2310ec024b3da9e88cf62a30bf27 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 10:26:37 +0200 Subject: [PATCH 031/108] Bump version of pre-commit hooks (backport #1784) (#1785) --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 839de8bf23..6cd97bd075 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -57,14 +57,14 @@ repos: args: ["--line-length=99"] - repo: https://github.com/pycqa/flake8 - rev: 7.2.0 + rev: 7.3.0 hooks: - id: flake8 args: ["--extend-ignore=E501"] # CPP hooks - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v20.1.5 + rev: v20.1.7 hooks: - id: clang-format args: ['-fallback-style=none', '-i'] @@ -110,7 +110,7 @@ repos: # Docs - RestructuredText hooks - repo: https://github.com/PyCQA/doc8 - rev: v1.1.2 + rev: v2.0.0 hooks: - id: doc8 args: ['--max-line-length=100', '--ignore=D001'] @@ -134,7 +134,7 @@ repos: exclude: CHANGELOG\.rst|\.(svg|pyc|drawio)$ - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.33.0 + rev: 0.33.1 hooks: - id: check-github-workflows args: ["--verbose"] From c018516de82a3e3b38ce87f6c7296b7c220b0ca3 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Wed, 2 Jul 2025 08:27:46 +0100 Subject: [PATCH 032/108] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 3 +++ admittance_controller/CHANGELOG.rst | 3 +++ bicycle_steering_controller/CHANGELOG.rst | 3 +++ diff_drive_controller/CHANGELOG.rst | 3 +++ effort_controllers/CHANGELOG.rst | 3 +++ force_torque_sensor_broadcaster/CHANGELOG.rst | 3 +++ forward_command_controller/CHANGELOG.rst | 3 +++ gpio_controllers/CHANGELOG.rst | 5 +++++ gps_sensor_broadcaster/CHANGELOG.rst | 3 +++ gripper_controllers/CHANGELOG.rst | 3 +++ imu_sensor_broadcaster/CHANGELOG.rst | 3 +++ joint_state_broadcaster/CHANGELOG.rst | 3 +++ joint_trajectory_controller/CHANGELOG.rst | 3 +++ mecanum_drive_controller/CHANGELOG.rst | 3 +++ parallel_gripper_controller/CHANGELOG.rst | 3 +++ pid_controller/CHANGELOG.rst | 3 +++ pose_broadcaster/CHANGELOG.rst | 3 +++ position_controllers/CHANGELOG.rst | 3 +++ range_sensor_broadcaster/CHANGELOG.rst | 5 +++++ ros2_controllers/CHANGELOG.rst | 3 +++ ros2_controllers_test_nodes/CHANGELOG.rst | 3 +++ rqt_joint_trajectory_controller/CHANGELOG.rst | 3 +++ steering_controllers_library/CHANGELOG.rst | 5 +++++ tricycle_controller/CHANGELOG.rst | 3 +++ tricycle_steering_controller/CHANGELOG.rst | 3 +++ velocity_controllers/CHANGELOG.rst | 3 +++ 26 files changed, 84 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 1f56fccb6a..58808b095f 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index d749cf5283..8afc533f19 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 63e487aa1a..d1945cfac5 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 42b6e4d08c..8bb77cd6d0 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 949f5007c5..749d197dd3 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index bbdd065639..3c9bb969b2 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- * Revert temporary logging changes added for CI timeout investigation (backport `#1741 `_) (`#1747 `_) diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index b26a0504e7..ca057a4dd3 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 3eb8b35d1a..e5443cdbe6 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix cmake deprecation (backport `#1780 `_) (`#1782 `_) +* Contributors: mergify[bot] + 4.27.0 (2025-06-23) ------------------- diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index f931945ba1..d4a346d4c1 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 3f35bd8ef4..110b08472c 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 2dbd18362a..b11686fbd2 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index b5961ffc2c..4f9d6021f2 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index b9ae038b04..2441fd157e 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- * Fix atomic variables in JTC (backport `#1749 `_) (`#1766 `_) diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 643ae57e13..1e21c7e5a7 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 3dbf752ff3..aea5e148c8 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 6e8a028f57..8a1bd85bf1 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- * Add new members for PID controller parameters (backport `#1585 `_) (`#1769 `_) diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index f06f3e8eaa..7b267e8fe9 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 09fe3f15ce..9c62551e11 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 991d3a2464..240499b729 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix cmake deprecation (backport `#1780 `_) (`#1782 `_) +* Contributors: mergify[bot] + 4.27.0 (2025-06-23) ------------------- diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 55381579f3..57a2edba10 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 8afeeec10f..fd54e2f193 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 2a2bfa1369..5b4b4f0286 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index ce8d1e56fd..c2b1c0ffba 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix SteeringOdometry calculation error (backport `#1777 `_) (`#1779 `_) +* Contributors: mergify[bot] + 4.27.0 (2025-06-23) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index d71a020a6d..6f8009447f 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index cfa9a2bed4..edc89cacb6 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 381a29e4df..b2a73c3cdf 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.0 (2025-06-23) ------------------- From b1b80a6da8c8d03db4a25b01b4b62d3c90219046 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Wed, 2 Jul 2025 08:28:14 +0100 Subject: [PATCH 033/108] 4.27.1 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 54 files changed, 80 insertions(+), 80 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 58808b095f..2b0e6e9af3 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index 2e93da74fe..30556ad411 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.27.0 + 4.27.1 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 8afc533f19..eca281f781 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index 004e0255f9..568ec50dbf 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.27.0 + 4.27.1 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index d1945cfac5..4b457bd445 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index 389dc51bd1..cff7a2ee26 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.27.0 + 4.27.1 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 8bb77cd6d0..bc2ef54956 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index a7cfe5cf5c..6f95d61700 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.27.0 + 4.27.1 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 749d197dd3..13e3e14c02 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index 390d7edbaa..12889bb11b 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.27.0 + 4.27.1 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 3c9bb969b2..b469d69082 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 65c3d49f15..9c54765599 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.27.0 + 4.27.1 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index ca057a4dd3..f24ebdefbc 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index 4a1ffde28f..6fcaf8b2ad 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.27.0 + 4.27.1 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index e5443cdbe6..b1e55b2d52 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- * Fix cmake deprecation (backport `#1780 `_) (`#1782 `_) * Contributors: mergify[bot] diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index 8f2204a28b..3ac6063d91 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.27.0 + 4.27.1 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index d4a346d4c1..9ef044a04b 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index fa55d4674a..d7d1ae8b39 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.27.0 + 4.27.1 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 110b08472c..5f119422f7 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index e31cdc2833..61998df1b4 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.27.0 + 4.27.1 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index b11686fbd2..7a44379ab1 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index 2c7660049c..981a35470c 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.27.0 + 4.27.1 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 4f9d6021f2..d3e4dc4b25 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index 9da9007930..a69f604fd4 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.27.0 + 4.27.1 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 2441fd157e..f6c39f9d79 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 9dfa32fffa..3a8b709208 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.27.0 + 4.27.1 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 1e21c7e5a7..8f531f4fe7 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index 69a8f8f94c..e89992fdf5 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.27.0 + 4.27.1 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index aea5e148c8..d13fff83fe 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index 008e964f13..58a6cacc0e 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.27.0 + 4.27.1 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 8a1bd85bf1..54635d4dda 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/pid_controller/package.xml b/pid_controller/package.xml index 946086e412..10f2bc711b 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.27.0 + 4.27.1 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 7b267e8fe9..7ac167814e 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index c328928f87..ae671afe54 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.27.0 + 4.27.1 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 9c62551e11..68952e0706 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index e45280a234..a862135184 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.27.0 + 4.27.1 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 240499b729..3c21323bcf 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- * Fix cmake deprecation (backport `#1780 `_) (`#1782 `_) * Contributors: mergify[bot] diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index c01e26c0e4..70bc3e314e 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.27.0 + 4.27.1 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 57a2edba10..b1abc57f8a 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index aa36c4a3b7..3503bfb19a 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.27.0 + 4.27.1 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index fd54e2f193..e205e1d89e 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index ef280b46c2..1aa32c421e 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.27.0 + 4.27.1 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index 397095dcef..0d7e0271f6 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.27.0", + version="4.27.1", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 5b4b4f0286..5b059b3370 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 45874f8048..7c1834a5f6 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.27.0 + 4.27.1 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index 187d7a54d9..44694fd455 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.27.0", + version="4.27.1", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index c2b1c0ffba..1c57cc0b56 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- * Fix SteeringOdometry calculation error (backport `#1777 `_) (`#1779 `_) * Contributors: mergify[bot] diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index cb19e42c6f..6e6cac65f5 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.27.0 + 4.27.1 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 6f8009447f..b4ee06926f 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index 29eda0d7eb..1ce2bbf762 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.27.0 + 4.27.1 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index edc89cacb6..dffff4be70 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index b8cb0b335c..5067c70481 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.27.0 + 4.27.1 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index b2a73c3cdf..1d550da7d0 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.27.1 (2025-07-02) +------------------- 4.27.0 (2025-06-23) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index 4cc130711c..be8ef319fe 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.27.0 + 4.27.1 Generic controller for forwarding commands. Bence Magyar From f0f82dfb7250d4fb954a58a1406fd70356118c53 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 22:12:23 +0200 Subject: [PATCH 034/108] Improve paths filtering of docs CI job (backport #1796) (#1798) --- .github/workflows/humble-check-docs.yml | 7 +++++++ .github/workflows/jazzy-check-docs.yml | 7 +++++++ .github/workflows/rolling-check-docs.yml | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/.github/workflows/humble-check-docs.yml b/.github/workflows/humble-check-docs.yml index 448ff4084b..09b7d695e9 100644 --- a/.github/workflows/humble-check-docs.yml +++ b/.github/workflows/humble-check-docs.yml @@ -8,7 +8,14 @@ on: paths: - '**.rst' - '**.md' + - '**.jpg' + - '**.jpeg' + - '**.png' + - '**.svg' + - '**.yml' - '**.yaml' + - '!.github/**' # exclude yaml files in .github directory + - '.github/workflows/humble-check-docs.yml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/jazzy-check-docs.yml b/.github/workflows/jazzy-check-docs.yml index 72a5332d89..02c6f2af50 100644 --- a/.github/workflows/jazzy-check-docs.yml +++ b/.github/workflows/jazzy-check-docs.yml @@ -8,7 +8,14 @@ on: paths: - '**.rst' - '**.md' + - '**.jpg' + - '**.jpeg' + - '**.png' + - '**.svg' + - '**.yml' - '**.yaml' + - '!.github/**' # exclude yaml files in .github directory + - '.github/workflows/jazzy-check-docs.yml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/rolling-check-docs.yml b/.github/workflows/rolling-check-docs.yml index 1144c4e6c0..56a785475d 100644 --- a/.github/workflows/rolling-check-docs.yml +++ b/.github/workflows/rolling-check-docs.yml @@ -8,7 +8,13 @@ on: paths: - '**.rst' - '**.md' + - '**.jpg' + - '**.jpeg' + - '**.png' + - '**.svg' + - '**.yml' - '**.yaml' + - '!.github/**' # exclude yaml files in .github directory - '.github/workflows/rolling-check-docs.yml' concurrency: From 279c54ced70c5c894f46408eb438ccf4f025541a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 3 Jul 2025 22:16:40 +0200 Subject: [PATCH 035/108] Update description of limit() function in speed_limiter (backport #1793) (#1795) --- .../include/diff_drive_controller/speed_limiter.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diff_drive_controller/include/diff_drive_controller/speed_limiter.hpp b/diff_drive_controller/include/diff_drive_controller/speed_limiter.hpp index 937e848460..8e13a35ad1 100644 --- a/diff_drive_controller/include/diff_drive_controller/speed_limiter.hpp +++ b/diff_drive_controller/include/diff_drive_controller/speed_limiter.hpp @@ -96,7 +96,7 @@ class SpeedLimiter } /** - * \brief Limit the velocity and acceleration + * \brief Limit the velocity, acceleration, and jerk * \param [in, out] v Velocity [m/s] * \param [in] v0 Previous velocity to v [m/s] * \param [in] v1 Previous velocity to v0 [m/s] From 99999d716d1790f598e29f85ee05f0677d6ee762 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 08:28:38 +0200 Subject: [PATCH 036/108] fix rqt_joint_trajectory_controller for robots with namespace (backport #1792) (#1803) Co-authored-by: Oscar Lima --- .../joint_trajectory_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/joint_trajectory_controller.py b/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/joint_trajectory_controller.py index 12ac10c64c..38faed8bc6 100644 --- a/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/joint_trajectory_controller.py +++ b/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/joint_trajectory_controller.py @@ -464,7 +464,7 @@ def _jtc_joint_names(jtc_info): joint_names = [] for interface in jtc_info.required_state_interfaces: - name = interface.split("/")[-2] + name = "/".join(interface.split("/")[:-1]) if name not in joint_names: joint_names.append(name) From e88a52a2217f79d974d93202bbe03767a14c123e Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 12:26:01 +0200 Subject: [PATCH 037/108] Add tf_frame_prefix parameters to mecanum_drive_controller (backport #1680) (#1810) Co-authored-by: Dawid Kmak <73443304+KmakD@users.noreply.github.com> --- .../src/mecanum_drive_controller.cpp | 31 +++- .../src/mecanum_drive_controller.yaml | 11 +- .../test/mecanum_drive_controller_params.yaml | 81 ++++----- ...num_drive_controller_preceding_params.yaml | 41 ++--- .../test/test_mecanum_drive_controller.cpp | 160 ++++++++++++++++++ .../test/test_mecanum_drive_controller.hpp | 18 +- 6 files changed, 273 insertions(+), 69 deletions(-) diff --git a/mecanum_drive_controller/src/mecanum_drive_controller.cpp b/mecanum_drive_controller/src/mecanum_drive_controller.cpp index 0d0f1e49f8..9615d3e0c8 100644 --- a/mecanum_drive_controller/src/mecanum_drive_controller.cpp +++ b/mecanum_drive_controller/src/mecanum_drive_controller.cpp @@ -148,10 +148,31 @@ controller_interface::CallbackReturn MecanumDriveController::on_configure( return controller_interface::CallbackReturn::ERROR; } + // Append the tf prefix if there is one + std::string tf_prefix = ""; + if (params_.tf_frame_prefix_enable) + { + tf_prefix = params_.tf_frame_prefix != "" ? params_.tf_frame_prefix + : std::string(get_node()->get_namespace()); + + // Make sure prefix does not start with '/' and always ends with '/' + if (tf_prefix.back() != '/') + { + tf_prefix = tf_prefix + "/"; + } + if (tf_prefix.front() == '/') + { + tf_prefix.erase(0, 1); + } + } + + const auto odom_frame_id = tf_prefix + params_.odom_frame_id; + const auto base_frame_id = tf_prefix + params_.base_frame_id; + rt_odom_state_publisher_->lock(); rt_odom_state_publisher_->msg_.header.stamp = get_node()->now(); - rt_odom_state_publisher_->msg_.header.frame_id = params_.odom_frame_id; - rt_odom_state_publisher_->msg_.child_frame_id = params_.base_frame_id; + rt_odom_state_publisher_->msg_.header.frame_id = odom_frame_id; + rt_odom_state_publisher_->msg_.child_frame_id = base_frame_id; rt_odom_state_publisher_->msg_.pose.pose.position.z = 0; auto & covariance = rt_odom_state_publisher_->msg_.twist.covariance; @@ -182,8 +203,8 @@ controller_interface::CallbackReturn MecanumDriveController::on_configure( rt_tf_odom_state_publisher_->lock(); rt_tf_odom_state_publisher_->msg_.transforms.resize(1); rt_tf_odom_state_publisher_->msg_.transforms[0].header.stamp = get_node()->now(); - rt_tf_odom_state_publisher_->msg_.transforms[0].header.frame_id = params_.odom_frame_id; - rt_tf_odom_state_publisher_->msg_.transforms[0].child_frame_id = params_.base_frame_id; + rt_tf_odom_state_publisher_->msg_.transforms[0].header.frame_id = odom_frame_id; + rt_tf_odom_state_publisher_->msg_.transforms[0].child_frame_id = base_frame_id; rt_tf_odom_state_publisher_->msg_.transforms[0].transform.translation.z = 0.0; rt_tf_odom_state_publisher_->unlock(); @@ -207,7 +228,7 @@ controller_interface::CallbackReturn MecanumDriveController::on_configure( controller_state_publisher_->lock(); controller_state_publisher_->msg_.header.stamp = get_node()->now(); - controller_state_publisher_->msg_.header.frame_id = params_.odom_frame_id; + controller_state_publisher_->msg_.header.frame_id = odom_frame_id; controller_state_publisher_->unlock(); RCLCPP_INFO(get_node()->get_logger(), "MecanumDriveController configured successfully"); diff --git a/mecanum_drive_controller/src/mecanum_drive_controller.yaml b/mecanum_drive_controller/src/mecanum_drive_controller.yaml index 896b731953..058270fd7a 100644 --- a/mecanum_drive_controller/src/mecanum_drive_controller.yaml +++ b/mecanum_drive_controller/src/mecanum_drive_controller.yaml @@ -113,12 +113,21 @@ mecanum_drive_controller: read_only: false, } + tf_frame_prefix_enable: { + type: bool, + default_value: true, + description: "Enables or disables appending ``tf_frame_prefix`` to tf frame id's. See its parameter description for more information.", + } + tf_frame_prefix: { + type: string, + default_value: "", + description: "(optional) Prefix to be appended to the tf frames, will be added to odom_frame_id and base_frame_id before publishing. If the parameter is empty, controller's namespace will be used.", + } base_frame_id: { type: string, default_value: "base_link", description: "Base frame_id set to value of base_frame_id.", read_only: false, - } odom_frame_id: { type: string, diff --git a/mecanum_drive_controller/test/mecanum_drive_controller_params.yaml b/mecanum_drive_controller/test/mecanum_drive_controller_params.yaml index c764c6c063..658cd3b2fa 100644 --- a/mecanum_drive_controller/test/mecanum_drive_controller_params.yaml +++ b/mecanum_drive_controller/test/mecanum_drive_controller_params.yaml @@ -1,40 +1,41 @@ -test_mecanum_drive_controller: - ros__parameters: - reference_timeout: 0.9 - - front_left_wheel_command_joint_name: "front_left_wheel_joint" - front_right_wheel_command_joint_name: "front_right_wheel_joint" - rear_right_wheel_command_joint_name: "back_right_wheel_joint" - rear_left_wheel_command_joint_name: "back_left_wheel_joint" - - kinematics: - base_frame_offset: { x: 0.0, y: 0.0, theta: 0.0 } - wheels_radius: 0.5 - sum_of_robot_center_projection_on_X_Y_axis: 1.0 - - base_frame_id: "base_link" - odom_frame_id: "odom" - enable_odom_tf: true - twist_covariance_diagonal: [0.0, 7.0, 14.0, 21.0, 28.0, 35.0] - pose_covariance_diagonal: [0.0, 7.0, 14.0, 21.0, 28.0, 35.0] - - -test_mecanum_drive_controller_with_rotation: - ros__parameters: - reference_timeout: 5.0 - - front_left_wheel_command_joint_name: "front_left_wheel_joint" - front_right_wheel_command_joint_name: "front_right_wheel_joint" - rear_right_wheel_command_joint_name: "rear_right_wheel_joint" - rear_left_wheel_command_joint_name: "rear_left_wheel_joint" - - kinematics: - base_frame_offset: { x: 1.0, y: 2.0, theta: 3.0 } - wheels_radius: 0.05 - sum_of_robot_center_projection_on_X_Y_axis: 0.2925 - - base_frame_id: "base_link" - odom_frame_id: "odom" - enable_odom_tf: true - pose_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.001] - twist_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.001] +/**: + test_mecanum_drive_controller: + ros__parameters: + reference_timeout: 0.9 + + front_left_wheel_command_joint_name: "front_left_wheel_joint" + front_right_wheel_command_joint_name: "front_right_wheel_joint" + rear_right_wheel_command_joint_name: "back_right_wheel_joint" + rear_left_wheel_command_joint_name: "back_left_wheel_joint" + + kinematics: + base_frame_offset: { x: 0.0, y: 0.0, theta: 0.0 } + wheels_radius: 0.5 + sum_of_robot_center_projection_on_X_Y_axis: 1.0 + + base_frame_id: "base_link" + odom_frame_id: "odom" + enable_odom_tf: true + twist_covariance_diagonal: [0.0, 7.0, 14.0, 21.0, 28.0, 35.0] + pose_covariance_diagonal: [0.0, 7.0, 14.0, 21.0, 28.0, 35.0] + + + test_mecanum_drive_controller_with_rotation: + ros__parameters: + reference_timeout: 5.0 + + front_left_wheel_command_joint_name: "front_left_wheel_joint" + front_right_wheel_command_joint_name: "front_right_wheel_joint" + rear_right_wheel_command_joint_name: "rear_right_wheel_joint" + rear_left_wheel_command_joint_name: "rear_left_wheel_joint" + + kinematics: + base_frame_offset: { x: 1.0, y: 2.0, theta: 3.0 } + wheels_radius: 0.05 + sum_of_robot_center_projection_on_X_Y_axis: 0.2925 + + base_frame_id: "base_link" + odom_frame_id: "odom" + enable_odom_tf: true + pose_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.001] + twist_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.001] diff --git a/mecanum_drive_controller/test/mecanum_drive_controller_preceding_params.yaml b/mecanum_drive_controller/test/mecanum_drive_controller_preceding_params.yaml index c4e5bb391a..72030202b9 100644 --- a/mecanum_drive_controller/test/mecanum_drive_controller_preceding_params.yaml +++ b/mecanum_drive_controller/test/mecanum_drive_controller_preceding_params.yaml @@ -1,24 +1,25 @@ -test_mecanum_drive_controller: - ros__parameters: - reference_timeout: 0.1 +/**: + test_mecanum_drive_controller: + ros__parameters: + reference_timeout: 0.1 - front_left_wheel_command_joint_name: "front_left_wheel_joint" - front_right_wheel_command_joint_name: "front_right_wheel_joint" - rear_right_wheel_command_joint_name: "back_right_wheel_joint" - rear_left_wheel_command_joint_name: "back_left_wheel_joint" + front_left_wheel_command_joint_name: "front_left_wheel_joint" + front_right_wheel_command_joint_name: "front_right_wheel_joint" + rear_right_wheel_command_joint_name: "back_right_wheel_joint" + rear_left_wheel_command_joint_name: "back_left_wheel_joint" - front_left_wheel_state_joint_name: "state_front_left_wheel_joint" - front_right_wheel_state_joint_name: "state_front_right_wheel_joint" - rear_right_wheel_state_joint_name: "state_back_right_wheel_joint" - rear_left_wheel_state_joint_name: "state_back_left_wheel_joint" + front_left_wheel_state_joint_name: "state_front_left_wheel_joint" + front_right_wheel_state_joint_name: "state_front_right_wheel_joint" + rear_right_wheel_state_joint_name: "state_back_right_wheel_joint" + rear_left_wheel_state_joint_name: "state_back_left_wheel_joint" - kinematics: - base_frame_offset: { x: 0.0, y: 0.0, theta: 0.0 } - wheels_radius: 0.5 - sum_of_robot_center_projection_on_X_Y_axis: 1.0 + kinematics: + base_frame_offset: { x: 0.0, y: 0.0, theta: 0.0 } + wheels_radius: 0.5 + sum_of_robot_center_projection_on_X_Y_axis: 1.0 - base_frame_id: "base_link" - odom_frame_id: "odom" - enable_odom_tf: true - twist_covariance_diagonal: [0.0, 7.0, 14.0, 21.0, 28.0, 35.0] - pose_covariance_diagonal: [0.0, 7.0, 14.0, 21.0, 28.0, 35.0] + base_frame_id: "base_link" + odom_frame_id: "odom" + enable_odom_tf: true + twist_covariance_diagonal: [0.0, 7.0, 14.0, 21.0, 28.0, 35.0] + pose_covariance_diagonal: [0.0, 7.0, 14.0, 21.0, 28.0, 35.0] diff --git a/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp b/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp index 00c1f5a74b..31c6c36737 100644 --- a/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp +++ b/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp @@ -118,6 +118,166 @@ TEST_F(MecanumDriveControllerTest, when_controller_configured_expect_properly_ex } } +TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_false_no_namespace) +{ + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = "test_prefix"; + + auto node_options = controller_->define_custom_node_options(); + node_options.append_parameter_override("tf_frame_prefix_enable", rclcpp::ParameterValue(false)); + node_options.append_parameter_override("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)); + node_options.append_parameter_override("odom_frame_id", rclcpp::ParameterValue(odom_id)); + node_options.append_parameter_override("base_frame_id", rclcpp::ParameterValue(base_link_id)); + + SetUpController("test_mecanum_drive_controller", node_options); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + /* tf_frame_prefix_enable is false so no modifications to the frame id's */ + ASSERT_EQ(test_odom_frame_id, odom_id); + ASSERT_EQ(test_base_frame_id, base_link_id); +} + +TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_true_no_namespace) +{ + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = "test_prefix"; + + auto node_options = controller_->define_custom_node_options(); + node_options.append_parameter_override("tf_frame_prefix_enable", rclcpp::ParameterValue(true)); + node_options.append_parameter_override("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)); + node_options.append_parameter_override("odom_frame_id", rclcpp::ParameterValue(odom_id)); + node_options.append_parameter_override("base_frame_id", rclcpp::ParameterValue(base_link_id)); + + SetUpController("test_mecanum_drive_controller", node_options); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + + /* tf_frame_prefix_enable is true and frame_prefix is not blank so should be appended to the + frame + * id's */ + ASSERT_EQ(test_odom_frame_id, frame_prefix + "/" + odom_id); + ASSERT_EQ(test_base_frame_id, frame_prefix + "/" + base_link_id); +} + +TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_blank_prefix_true_no_namespace) +{ + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = ""; + + auto node_options = controller_->define_custom_node_options(); + node_options.append_parameter_override("tf_frame_prefix_enable", rclcpp::ParameterValue(true)); + node_options.append_parameter_override("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)); + node_options.append_parameter_override("odom_frame_id", rclcpp::ParameterValue(odom_id)); + node_options.append_parameter_override("base_frame_id", rclcpp::ParameterValue(base_link_id)); + + SetUpController("test_mecanum_drive_controller", node_options); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + /* tf_frame_prefix_enable is true but frame_prefix is blank so should not be appended to the + frame + * id's */ + ASSERT_EQ(test_odom_frame_id, odom_id); + ASSERT_EQ(test_base_frame_id, base_link_id); +} + +TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_false_set_namespace) +{ + std::string test_namespace = "/test_namespace"; + + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = "test_prefix"; + + auto node_options = controller_->define_custom_node_options(); + node_options.append_parameter_override("tf_frame_prefix_enable", rclcpp::ParameterValue(false)); + node_options.append_parameter_override("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)); + node_options.append_parameter_override("odom_frame_id", rclcpp::ParameterValue(odom_id)); + node_options.append_parameter_override("base_frame_id", rclcpp::ParameterValue(base_link_id)); + + SetUpController("test_mecanum_drive_controller", node_options, test_namespace); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + /* tf_frame_prefix_enable is false so no modifications to the frame id's */ + ASSERT_EQ(test_odom_frame_id, odom_id); + ASSERT_EQ(test_base_frame_id, base_link_id); +} + +TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_true_set_namespace) +{ + std::string test_namespace = "/test_namespace"; + + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = "test_prefix"; + + auto node_options = controller_->define_custom_node_options(); + node_options.append_parameter_override("tf_frame_prefix_enable", rclcpp::ParameterValue(true)); + node_options.append_parameter_override("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)); + node_options.append_parameter_override("odom_frame_id", rclcpp::ParameterValue(odom_id)); + node_options.append_parameter_override("base_frame_id", rclcpp::ParameterValue(base_link_id)); + + SetUpController("test_mecanum_drive_controller", node_options, test_namespace); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + + /* tf_frame_prefix_enable is true and frame_prefix is not blank so should be appended to the + frame + * id's instead of the namespace*/ + ASSERT_EQ(test_odom_frame_id, frame_prefix + "/" + odom_id); + ASSERT_EQ(test_base_frame_id, frame_prefix + "/" + base_link_id); +} + +TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_blank_prefix_true_set_namespace) +{ + std::string test_namespace = "/test_namespace"; + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = ""; + + auto node_options = controller_->define_custom_node_options(); + node_options.append_parameter_override("tf_frame_prefix_enable", rclcpp::ParameterValue(true)); + node_options.append_parameter_override("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)); + node_options.append_parameter_override("odom_frame_id", rclcpp::ParameterValue(odom_id)); + node_options.append_parameter_override("base_frame_id", rclcpp::ParameterValue(base_link_id)); + + SetUpController("test_mecanum_drive_controller", node_options, test_namespace); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + std::string ns_prefix = test_namespace.erase(0, 1) + "/"; + /* tf_frame_prefix_enable is true but frame_prefix is blank so namespace should be appended to + the + * frame id's */ + ASSERT_EQ(test_odom_frame_id, ns_prefix + odom_id); + ASSERT_EQ(test_base_frame_id, ns_prefix + base_link_id); +} + TEST_F(MecanumDriveControllerTest, when_controller_is_activated_expect_reference_reset) { SetUpController(); diff --git a/mecanum_drive_controller/test/test_mecanum_drive_controller.hpp b/mecanum_drive_controller/test/test_mecanum_drive_controller.hpp index 7f87824262..7d42c96c74 100644 --- a/mecanum_drive_controller/test/test_mecanum_drive_controller.hpp +++ b/mecanum_drive_controller/test/test_mecanum_drive_controller.hpp @@ -129,6 +129,16 @@ class TestableMecanumDriveController : public mecanum_drive_controller::MecanumD size_t get_rear_right_wheel_index() { return WheelIndex::REAR_RIGHT; } size_t get_rear_left_wheel_index() { return WheelIndex::REAR_LEFT; } + + /** + * @brief Used to get the odometry message to verify its contents + * + * @return Copy of odometry msg from rt_odom_state_publisher_ object + */ + nav_msgs::msg::Odometry get_rt_odom_state_publisher_msg() + { + return rt_odom_state_publisher_->msg_; + } }; // We are using template class here for easier reuse of Fixture in specializations of controllers @@ -161,12 +171,14 @@ class MecanumDriveControllerFixture : public ::testing::Test void TearDown() { controller_.reset(nullptr); } protected: - void SetUpController(const std::string controller_name = "test_mecanum_drive_controller") + void SetUpController( + const std::string controller_name = "test_mecanum_drive_controller", + const rclcpp::NodeOptions & node_options = rclcpp::NodeOptions(), const std::string ns = "") { const auto urdf = ""; - const auto ns = ""; + ASSERT_EQ( - controller_->init(controller_name, urdf, 0, ns, controller_->define_custom_node_options()), + controller_->init(controller_name, urdf, 0, ns, node_options), controller_interface::return_type::OK); std::vector command_ifs; From 6b5123f07cb639c45de04d8f86544cb86952e4aa Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 13:28:27 +0200 Subject: [PATCH 038/108] Mecanum Drive: Populate the pose covariance matrix (backport #1772) (#1807) Co-authored-by: Hilary Luo <103377417+hilary-luo@users.noreply.github.com> --- .../src/mecanum_drive_controller.cpp | 7 ++++--- .../test/mecanum_drive_controller_params.yaml | 2 +- .../test/test_mecanum_drive_controller.cpp | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/mecanum_drive_controller/src/mecanum_drive_controller.cpp b/mecanum_drive_controller/src/mecanum_drive_controller.cpp index 9615d3e0c8..ead080050f 100644 --- a/mecanum_drive_controller/src/mecanum_drive_controller.cpp +++ b/mecanum_drive_controller/src/mecanum_drive_controller.cpp @@ -175,13 +175,14 @@ controller_interface::CallbackReturn MecanumDriveController::on_configure( rt_odom_state_publisher_->msg_.child_frame_id = base_frame_id; rt_odom_state_publisher_->msg_.pose.pose.position.z = 0; - auto & covariance = rt_odom_state_publisher_->msg_.twist.covariance; + auto & pose_covariance = rt_odom_state_publisher_->msg_.pose.covariance; + auto & twist_covariance = rt_odom_state_publisher_->msg_.twist.covariance; constexpr size_t NUM_DIMENSIONS = 6; for (size_t index = 0; index < 6; ++index) { const size_t diagonal_index = NUM_DIMENSIONS * index + index; - covariance[diagonal_index] = params_.pose_covariance_diagonal[index]; - covariance[diagonal_index] = params_.twist_covariance_diagonal[index]; + pose_covariance[diagonal_index] = params_.pose_covariance_diagonal[index]; + twist_covariance[diagonal_index] = params_.twist_covariance_diagonal[index]; } rt_odom_state_publisher_->unlock(); diff --git a/mecanum_drive_controller/test/mecanum_drive_controller_params.yaml b/mecanum_drive_controller/test/mecanum_drive_controller_params.yaml index 658cd3b2fa..dfa3e5de94 100644 --- a/mecanum_drive_controller/test/mecanum_drive_controller_params.yaml +++ b/mecanum_drive_controller/test/mecanum_drive_controller_params.yaml @@ -17,7 +17,7 @@ odom_frame_id: "odom" enable_odom_tf: true twist_covariance_diagonal: [0.0, 7.0, 14.0, 21.0, 28.0, 35.0] - pose_covariance_diagonal: [0.0, 7.0, 14.0, 21.0, 28.0, 35.0] + pose_covariance_diagonal: [0.0, 6.0, 12.0, 18.0, 24.0, 30.0] test_mecanum_drive_controller_with_rotation: diff --git a/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp b/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp index 31c6c36737..748940b138 100644 --- a/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp +++ b/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp @@ -62,6 +62,13 @@ TEST_F(MecanumDriveControllerTest, when_controller_is_configured_expect_all_para ASSERT_EQ(controller_->params_.kinematics.base_frame_offset.y, 0.0); ASSERT_EQ(controller_->params_.kinematics.base_frame_offset.theta, 0.0); + ASSERT_EQ( + controller_->params_.pose_covariance_diagonal, + std::vector({0.0, 6.0, 12.0, 18.0, 24.0, 30.0})); + ASSERT_EQ( + controller_->params_.twist_covariance_diagonal, + std::vector({0.0, 7.0, 14.0, 21.0, 28.0, 35.0})); + ASSERT_EQ( controller_->params_.front_left_wheel_command_joint_name, TEST_FRONT_LEFT_CMD_JOINT_NAME); ASSERT_EQ( @@ -140,6 +147,17 @@ TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_false_no_na /* tf_frame_prefix_enable is false so no modifications to the frame id's */ ASSERT_EQ(test_odom_frame_id, odom_id); ASSERT_EQ(test_base_frame_id, base_link_id); + + std::array pose_covariance = { + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 12.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 18.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 24.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 30.0}}; + + std::array twist_covariance = { + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 14.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 21.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 28.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 35.0}}; + + ASSERT_EQ(odometry_message.pose.covariance, pose_covariance); + ASSERT_EQ(odometry_message.twist.covariance, twist_covariance); } TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_true_no_namespace) From 26d617b0be2a3e1cf5017faa3cd9cd3aec16bb29 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 09:29:09 +0200 Subject: [PATCH 039/108] Explicit cast rcutils_duration_value_t (backport #1808) (#1812) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christoph Fröhlich --- diff_drive_controller/src/diff_drive_controller.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/diff_drive_controller/src/diff_drive_controller.cpp b/diff_drive_controller/src/diff_drive_controller.cpp index 6ad267ec4e..3295df05a1 100644 --- a/diff_drive_controller/src/diff_drive_controller.cpp +++ b/diff_drive_controller/src/diff_drive_controller.cpp @@ -132,7 +132,8 @@ controller_interface::return_type DiffDriveController::update_reference_from_sub else { RCLCPP_WARN_SKIPFIRST_THROTTLE( - logger, *get_node()->get_clock(), cmd_vel_timeout_.seconds() * 1000, + logger, *get_node()->get_clock(), + static_cast(cmd_vel_timeout_.seconds() * 1000), "Command message contains NaNs. Not updating reference interfaces."); } From 417ae3894b5c97814a26858e053b15f0df98f0f5 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 8 Jul 2025 16:30:03 +0100 Subject: [PATCH 040/108] Run workflow on pushes to save cache (backport #1787) (#1789) --- .github/workflows/humble-pre-commit.yml | 3 +++ .github/workflows/jazzy-pre-commit.yml | 3 +++ .github/workflows/rolling-pre-commit.yml | 3 +++ 3 files changed, 9 insertions(+) diff --git a/.github/workflows/humble-pre-commit.yml b/.github/workflows/humble-pre-commit.yml index 38a76ee025..e6cebafa83 100644 --- a/.github/workflows/humble-pre-commit.yml +++ b/.github/workflows/humble-pre-commit.yml @@ -5,6 +5,9 @@ on: pull_request: branches: - humble + push: + branches: + - humble concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/jazzy-pre-commit.yml b/.github/workflows/jazzy-pre-commit.yml index 44d825a34a..5f94855963 100644 --- a/.github/workflows/jazzy-pre-commit.yml +++ b/.github/workflows/jazzy-pre-commit.yml @@ -5,6 +5,9 @@ on: pull_request: branches: - jazzy + push: + branches: + - jazzy concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/rolling-pre-commit.yml b/.github/workflows/rolling-pre-commit.yml index f323ebfe73..71465d0e56 100644 --- a/.github/workflows/rolling-pre-commit.yml +++ b/.github/workflows/rolling-pre-commit.yml @@ -5,6 +5,9 @@ on: pull_request: branches: - master + push: + branches: + - master concurrency: group: ${{ github.workflow }}-${{ github.ref }} From 8f8b4d45712915816bfc5df7ffbbd2eac230a30d Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Mon, 14 Jul 2025 08:06:22 +0000 Subject: [PATCH 041/108] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 3 +++ admittance_controller/CHANGELOG.rst | 3 +++ bicycle_steering_controller/CHANGELOG.rst | 3 +++ diff_drive_controller/CHANGELOG.rst | 6 ++++++ effort_controllers/CHANGELOG.rst | 3 +++ force_torque_sensor_broadcaster/CHANGELOG.rst | 3 +++ forward_command_controller/CHANGELOG.rst | 3 +++ gpio_controllers/CHANGELOG.rst | 3 +++ gps_sensor_broadcaster/CHANGELOG.rst | 3 +++ gripper_controllers/CHANGELOG.rst | 3 +++ imu_sensor_broadcaster/CHANGELOG.rst | 3 +++ joint_state_broadcaster/CHANGELOG.rst | 3 +++ joint_trajectory_controller/CHANGELOG.rst | 3 +++ mecanum_drive_controller/CHANGELOG.rst | 6 ++++++ parallel_gripper_controller/CHANGELOG.rst | 3 +++ pid_controller/CHANGELOG.rst | 3 +++ pose_broadcaster/CHANGELOG.rst | 3 +++ position_controllers/CHANGELOG.rst | 3 +++ range_sensor_broadcaster/CHANGELOG.rst | 3 +++ ros2_controllers/CHANGELOG.rst | 3 +++ ros2_controllers_test_nodes/CHANGELOG.rst | 3 +++ rqt_joint_trajectory_controller/CHANGELOG.rst | 6 ++++++ steering_controllers_library/CHANGELOG.rst | 3 +++ tricycle_controller/CHANGELOG.rst | 3 +++ tricycle_steering_controller/CHANGELOG.rst | 3 +++ velocity_controllers/CHANGELOG.rst | 3 +++ 26 files changed, 87 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 2b0e6e9af3..e4839a3f03 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index eca281f781..5740e539b4 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 4b457bd445..06707a29d3 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index bc2ef54956..2c1245f28b 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Explicit cast rcutils_duration_value_t (backport `#1808 `_) (`#1812 `_) +* Update description of limit() function in speed_limiter (backport `#1793 `_) (`#1795 `_) +* Contributors: Christoph Fröhlich, mergify[bot] + 4.27.1 (2025-07-02) ------------------- diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 13e3e14c02..2a96747a42 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index b469d69082..6d45226a97 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index f24ebdefbc..127d129d22 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index b1e55b2d52..4d0e00b545 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- * Fix cmake deprecation (backport `#1780 `_) (`#1782 `_) diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 9ef044a04b..6ca55b6f7b 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 5f119422f7..65c71e40a5 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 7a44379ab1..1c7ccba0d3 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index d3e4dc4b25..994605a430 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index f6c39f9d79..aca68d8c65 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 8f531f4fe7..0249763b81 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Mecanum Drive: Populate the pose covariance matrix (backport `#1772 `_) (`#1807 `_) +* Add tf_frame_prefix parameters to mecanum_drive_controller (backport `#1680 `_) (`#1810 `_) +* Contributors: Hilary Luo, Dawid Kmak + 4.27.1 (2025-07-02) ------------------- diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index d13fff83fe..4046866e06 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 54635d4dda..cc427daa80 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 7ac167814e..d0799db826 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 68952e0706..2ff60f49ea 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 3c21323bcf..4b76691dd0 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- * Fix cmake deprecation (backport `#1780 `_) (`#1782 `_) diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index b1abc57f8a..fe40d7ed1f 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index e205e1d89e..ed6da78481 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 5b059b3370..f339c6f56d 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* fix rqt_joint_trajectory_controller for robots with namespace (backport `#1792 `_) (`#1803 `_) + Co-authored-by: Oscar Lima +* Contributors: mergify[bot] + 4.27.1 (2025-07-02) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 1c57cc0b56..5374ad17f4 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- * Fix SteeringOdometry calculation error (backport `#1777 `_) (`#1779 `_) diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index b4ee06926f..ad11b542b6 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index dffff4be70..d54eb050bd 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 1d550da7d0..2e6d1884d1 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.27.1 (2025-07-02) ------------------- From 45ce3c5a857645967bad2bbd340094f4d919d5a7 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Mon, 14 Jul 2025 08:06:33 +0000 Subject: [PATCH 042/108] 4.28.0 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 54 files changed, 80 insertions(+), 80 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index e4839a3f03..6e2e40f67c 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index 30556ad411..32ece8ed42 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.27.1 + 4.28.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 5740e539b4..814c1f5bb8 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index 568ec50dbf..86004a8968 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.27.1 + 4.28.0 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 06707a29d3..4412c3d28f 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index cff7a2ee26..0653e9671d 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.27.1 + 4.28.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 2c1245f28b..21487c6751 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- * Explicit cast rcutils_duration_value_t (backport `#1808 `_) (`#1812 `_) * Update description of limit() function in speed_limiter (backport `#1793 `_) (`#1795 `_) * Contributors: Christoph Fröhlich, mergify[bot] diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 6f95d61700..4bd299366f 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.27.1 + 4.28.0 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 2a96747a42..cd2354ffaa 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index 12889bb11b..e19a9c4707 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.27.1 + 4.28.0 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 6d45226a97..865c7e705a 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 9c54765599..127cac3545 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.27.1 + 4.28.0 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 127d129d22..11e5cb3995 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index 6fcaf8b2ad..90363e5e2b 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.27.1 + 4.28.0 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 4d0e00b545..565e848eca 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index 3ac6063d91..87cfda594e 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.27.1 + 4.28.0 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 6ca55b6f7b..6b95482863 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index d7d1ae8b39..d8fd3be983 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.27.1 + 4.28.0 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 65c71e40a5..a40da4abb9 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index 61998df1b4..6742f65973 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.27.1 + 4.28.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 1c7ccba0d3..6dd111b986 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index 981a35470c..203e686755 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.27.1 + 4.28.0 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 994605a430..c918736cce 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index a69f604fd4..35034379e3 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.27.1 + 4.28.0 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index aca68d8c65..f80af0e948 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 3a8b709208..8deda1f9c9 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.27.1 + 4.28.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 0249763b81..1abf7e9af7 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- * Mecanum Drive: Populate the pose covariance matrix (backport `#1772 `_) (`#1807 `_) * Add tf_frame_prefix parameters to mecanum_drive_controller (backport `#1680 `_) (`#1810 `_) * Contributors: Hilary Luo, Dawid Kmak diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index e89992fdf5..4bf5fcdbb5 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.27.1 + 4.28.0 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 4046866e06..1740d51df8 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index 58a6cacc0e..1ec243a9e7 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.27.1 + 4.28.0 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index cc427daa80..2a60eb453a 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/pid_controller/package.xml b/pid_controller/package.xml index 10f2bc711b..cf237270c2 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.27.1 + 4.28.0 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index d0799db826..1e786ffb49 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index ae671afe54..48a0e32782 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.27.1 + 4.28.0 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 2ff60f49ea..5334e2a4f6 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index a862135184..33fc5793bf 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.27.1 + 4.28.0 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 4b76691dd0..4936b39826 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index 70bc3e314e..7a17de0be6 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.27.1 + 4.28.0 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index fe40d7ed1f..358aeaf026 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 3503bfb19a..3ef0d42282 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.27.1 + 4.28.0 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index ed6da78481..f8aca88e0d 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 1aa32c421e..5e3b4943e1 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.27.1 + 4.28.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index 0d7e0271f6..d28c46765f 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.27.1", + version="4.28.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index f339c6f56d..2417b78f51 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- * fix rqt_joint_trajectory_controller for robots with namespace (backport `#1792 `_) (`#1803 `_) Co-authored-by: Oscar Lima * Contributors: mergify[bot] diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 7c1834a5f6..c2fbac13cd 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.27.1 + 4.28.0 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index 44694fd455..a9fdfc8eaa 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.27.1", + version="4.28.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 5374ad17f4..81b9092168 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index 6e6cac65f5..f21370c4c6 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.27.1 + 4.28.0 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index ad11b542b6..0fa321d10f 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index 1ce2bbf762..2907000b68 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.27.1 + 4.28.0 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index d54eb050bd..66e70e46ba 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index 5067c70481..6c74653edb 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.27.1 + 4.28.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 2e6d1884d1..db4d3ee6e1 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.28.0 (2025-07-14) +------------------- 4.27.1 (2025-07-02) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index be8ef319fe..a6afa512c3 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.27.1 + 4.28.0 Generic controller for forwarding commands. Bence Magyar From 4b66e6a1844403db648b5660ace584caa42acf05 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 16 Jul 2025 03:38:42 +0200 Subject: [PATCH 043/108] =?UTF-8?q?Reject=20non-finite=20values=20in=20for?= =?UTF-8?q?ward=20controller=20subscriber=20callback=20(#=E2=80=A6=20(back?= =?UTF-8?q?port=20#1815)=20(#1817)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: kaizen Co-authored-by: Christoph Fröhlich --- .../src/forward_controllers_base.cpp | 16 ++++++- .../test/test_forward_command_controller.cpp | 46 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/forward_command_controller/src/forward_controllers_base.cpp b/forward_command_controller/src/forward_controllers_base.cpp index 331d3f9eea..ff765e6600 100644 --- a/forward_command_controller/src/forward_controllers_base.cpp +++ b/forward_command_controller/src/forward_controllers_base.cpp @@ -58,7 +58,21 @@ controller_interface::CallbackReturn ForwardControllersBase::on_configure( joints_command_subscriber_ = get_node()->create_subscription( "~/commands", rclcpp::SystemDefaultsQoS(), - [this](const CmdType::SharedPtr msg) { rt_command_ptr_.writeFromNonRT(msg); }); + [this](const CmdType::SharedPtr msg) + { + const auto cmd = *msg; + + if (!std::all_of( + cmd.data.cbegin(), cmd.data.cend(), + [](const auto & value) { return std::isfinite(value); })) + { + RCLCPP_WARN_THROTTLE( + get_node()->get_logger(), *(get_node()->get_clock()), 1000, + "Non-finite value received. Dropping message"); + return; + } + rt_command_ptr_.writeFromNonRT(msg); + }); RCLCPP_INFO(get_node()->get_logger(), "configure successful"); return controller_interface::CallbackReturn::SUCCESS; diff --git a/forward_command_controller/test/test_forward_command_controller.cpp b/forward_command_controller/test/test_forward_command_controller.cpp index bf20aa8eb6..551e09b948 100644 --- a/forward_command_controller/test/test_forward_command_controller.cpp +++ b/forward_command_controller/test/test_forward_command_controller.cpp @@ -328,6 +328,52 @@ TEST_F(ForwardCommandControllerTest, CommandCallbackTest) ASSERT_EQ(joint_3_pos_cmd_.get_value(), 30.0); } +TEST_F(ForwardCommandControllerTest, DropInfiniteCommandCallbackTest) +{ + SetUpController(); + + controller_->get_node()->set_parameter({"joints", joint_names_}); + controller_->get_node()->set_parameter({"interface_name", "position"}); + + // default values + ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + + auto node_state = controller_->configure(); + ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE); + + node_state = controller_->get_node()->activate(); + ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE); + + // send a new command + rclcpp::Node test_node("test_node"); + auto command_pub = test_node.create_publisher( + std::string(controller_->get_node()->get_name()) + "/commands", rclcpp::SystemDefaultsQoS()); + std_msgs::msg::Float64MultiArray command_msg; + command_msg.data = {10.0, std::numeric_limits::infinity(), 30.0}; + command_pub->publish(command_msg); + + // wait for command message to be passed + const auto timeout = std::chrono::milliseconds{10}; + const auto until = controller_->get_node()->get_clock()->now() + timeout; + while (controller_->get_node()->get_clock()->now() < until) + { + executor.spin_some(); + std::this_thread::sleep_for(std::chrono::microseconds(10)); + } + + // update successful + ASSERT_EQ( + controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + + // check message containing infinite command value was rejected + ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); +} + TEST_F(ForwardCommandControllerTest, ActivateDeactivateCommandsResetSuccess) { SetUpController(); From 88ce478aba10ecca75f61b1bc3a79d3a7e34187f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Wed, 16 Jul 2025 19:45:31 +0200 Subject: [PATCH 044/108] Fix precommit (#1818) --- .../test/test_forward_command_controller.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/forward_command_controller/test/test_forward_command_controller.cpp b/forward_command_controller/test/test_forward_command_controller.cpp index 551e09b948..e00a69c468 100644 --- a/forward_command_controller/test/test_forward_command_controller.cpp +++ b/forward_command_controller/test/test_forward_command_controller.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include #include From 0b2703f8e1e2a56f4b95893edf60992a9ca6bb64 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 22 Jul 2025 20:37:15 +0200 Subject: [PATCH 045/108] Change the tests to work without deprecated PID settings (backport #1824) (#1825) --- .../test/pid_controller_params.yaml | 33 ++++++++-- pid_controller/test/test_pid_controller.cpp | 66 +++++++++++-------- pid_controller/test/test_pid_controller.hpp | 5 +- .../test_pid_controller_dual_interface.cpp | 4 +- 4 files changed, 71 insertions(+), 37 deletions(-) diff --git a/pid_controller/test/pid_controller_params.yaml b/pid_controller/test/pid_controller_params.yaml index 15c4eaf049..f8b27f1d49 100644 --- a/pid_controller/test/pid_controller_params.yaml +++ b/pid_controller/test/pid_controller_params.yaml @@ -1,3 +1,10 @@ +/**: + ros__parameters: +# TODO(christohfroehlich): Remove this global parameters once the deprecated antiwindup parameters are removed. + gains: + joint1: {antiwindup_strategy: "none", i_clamp_max: .inf, i_clamp_min: -.inf} + joint2: {antiwindup_strategy: "none", i_clamp_max: .inf, i_clamp_min: -.inf} + test_pid_controller: ros__parameters: dof_names: @@ -8,7 +15,19 @@ test_pid_controller: reference_and_state_interfaces: ["position"] gains: - joint1: {p: 1.0, i: 2.0, d: 3.0, i_clamp_max: 5.0, i_clamp_min: -5.0} + joint1: {p: 1.0, i: 2.0, d: 3.0, u_clamp_max: 5.0, u_clamp_min: -5.0} + +test_pid_controller_unlimited: + ros__parameters: + dof_names: + - joint1 + + command_interface: position + + reference_and_state_interfaces: ["position"] + + gains: + joint1: {p: 1.0, i: 2.0, d: 3.0} test_pid_controller_angle_wraparound_on: ros__parameters: @@ -20,7 +39,7 @@ test_pid_controller_angle_wraparound_on: reference_and_state_interfaces: ["position"] gains: - joint1: {p: 1.0, i: 2.0, d: 3.0, i_clamp_max: 5.0, i_clamp_min: -5.0, angle_wraparound: true} + joint1: {p: 1.0, i: 2.0, d: 3.0, angle_wraparound: true} test_pid_controller_with_feedforward_gain: ros__parameters: @@ -32,7 +51,7 @@ test_pid_controller_with_feedforward_gain: reference_and_state_interfaces: ["position"] gains: - joint1: {p: 0.5, i: 0.0, d: 0.0, i_clamp_max: 5.0, i_clamp_min: -5.0, feedforward_gain: 1.0} + joint1: {p: 0.5, i: 0.0, d: 0.0, feedforward_gain: 1.0} test_pid_controller_with_feedforward_gain_dual_interface: ros__parameters: @@ -45,8 +64,8 @@ test_pid_controller_with_feedforward_gain_dual_interface: reference_and_state_interfaces: ["position", "velocity"] gains: - joint1: {p: 0.5, i: 0.3, d: 0.4, i_clamp_max: 5.0, i_clamp_min: -5.0, feedforward_gain: 1.0} - joint2: {p: 0.5, i: 0.3, d: 0.4, i_clamp_max: 5.0, i_clamp_min: -5.0, feedforward_gain: 1.0} + joint1: {p: 0.5, i: 0.3, d: 0.4, feedforward_gain: 1.0} + joint2: {p: 0.5, i: 0.3, d: 0.4, feedforward_gain: 1.0} test_save_i_term_off: ros__parameters: @@ -58,7 +77,7 @@ test_save_i_term_off: reference_and_state_interfaces: ["position"] gains: - joint1: {p: 1.0, i: 2.0, d: 3.0, i_clamp_max: 5.0, i_clamp_min: -5.0, save_i_term: false} + joint1: {p: 1.0, i: 2.0, d: 3.0, save_i_term: false} test_save_i_term_on: ros__parameters: @@ -70,4 +89,4 @@ test_save_i_term_on: reference_and_state_interfaces: ["position"] gains: - joint1: {p: 1.0, i: 2.0, d: 3.0, i_clamp_max: 5.0, i_clamp_min: -5.0, save_i_term: true} + joint1: {p: 1.0, i: 2.0, d: 3.0, save_i_term: true} diff --git a/pid_controller/test/test_pid_controller.cpp b/pid_controller/test/test_pid_controller.cpp index 3b74e2c094..1900b172ac 100644 --- a/pid_controller/test/test_pid_controller.cpp +++ b/pid_controller/test/test_pid_controller.cpp @@ -46,8 +46,8 @@ TEST_F(PidControllerTest, all_parameters_set_configure_success) ASSERT_EQ(controller_->params_.gains.dof_names_map[dof_name].i, 2.0); ASSERT_EQ(controller_->params_.gains.dof_names_map[dof_name].d, 3.0); ASSERT_FALSE(controller_->params_.gains.dof_names_map[dof_name].antiwindup); - ASSERT_EQ(controller_->params_.gains.dof_names_map[dof_name].i_clamp_max, 5.0); - ASSERT_EQ(controller_->params_.gains.dof_names_map[dof_name].i_clamp_min, -5.0); + ASSERT_EQ(controller_->params_.gains.dof_names_map[dof_name].u_clamp_max, 5.0); + ASSERT_EQ(controller_->params_.gains.dof_names_map[dof_name].u_clamp_min, -5.0); ASSERT_EQ(controller_->params_.gains.dof_names_map[dof_name].feedforward_gain, 0.0); } ASSERT_EQ(controller_->params_.command_interface, command_interface_); @@ -274,7 +274,7 @@ TEST_F(PidControllerTest, test_feedforward_mode_parameter) TEST_F(PidControllerTest, test_update_logic_feedforward_off) { - SetUpController(); + SetUpController("test_pid_controller_unlimited"); rclcpp::executors::MultiThreadedExecutor executor; executor.add_node(controller_->get_node()->get_node_base_interface()); executor.add_node(service_caller_node_->get_node_base_interface()); @@ -312,10 +312,12 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_off) EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->values[i])); } // check the command value + // ref = 101.101, state = 1.1, ds = 0.01 // error = ref - state = 100.001, error_dot = error/ds = 10000.1, - // p_term = 100.001 * 1, i_term = 1.00001 * 2 = 2.00002, d_term = error/ds = 10000.1 * 3 - // feedforward OFF -> cmd = p_term + i_term + d_term = 30102.3 - const double expected_command_value = 30102.30102; + // p_term = 100.001 * 1, i_term = 0.0 at first update call, d_term = error/ds = 10000.1 * 3 + // feedforward ON, feedforward_gain = 0 + // -> cmd = p_term + i_term + d_term + feedforward_gain * ref = 30100.3 + 0 * 101.101 = 30102.3 + const double expected_command_value = 30100.301000; double actual_value = std::round(controller_->command_interfaces_[0].get_value() * 1e5) / 1e5; EXPECT_NEAR(actual_value, expected_command_value, 1e-5); @@ -328,7 +330,7 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_off) TEST_F(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward_gain) { - SetUpController(); + SetUpController("test_pid_controller_unlimited"); rclcpp::executors::MultiThreadedExecutor executor; executor.add_node(controller_->get_node()->get_node_base_interface()); executor.add_node(service_caller_node_->get_node_base_interface()); @@ -372,10 +374,10 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward // check the command value: // ref = 101.101, state = 1.1, ds = 0.01 // error = ref - state = 100.001, error_dot = error/ds = 10000.1, - // p_term = 100.001 * 1, i_term = 1.00001 * 2 = 2.00002, d_term = error/ds = 10000.1 * 3 + // p_term = 100.001 * 1, i_term = 0.0 at first update call, d_term = error/ds = 10000.1 * 3 // feedforward ON, feedforward_gain = 0 - // -> cmd = p_term + i_term + d_term + feedforward_gain * ref = 30102.3 + 0 * 101.101 = 30102.3 - const double expected_command_value = 30102.301020; + // -> cmd = p_term + i_term + d_term + feedforward_gain * ref = 30100.3 + 0 * 101.101 = 30102.3 + const double expected_command_value = 30100.301000; double actual_value = std::round(controller_->command_interfaces_[0].get_value() * 1e5) / 1e5; EXPECT_NEAR(actual_value, expected_command_value, 1e-5); @@ -390,7 +392,7 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward TEST_F(PidControllerTest, test_update_logic_chainable_not_use_subscriber_update) { - SetUpController(); + SetUpController("test_pid_controller_unlimited"); rclcpp::executors::MultiThreadedExecutor executor; executor.add_node(controller_->get_node()->get_node_base_interface()); executor.add_node(service_caller_node_->get_node_base_interface()); @@ -429,12 +431,13 @@ TEST_F(PidControllerTest, test_update_logic_chainable_not_use_subscriber_update) // ref = 5.0, state = 1.1, ds = 0.01, p_gain = 1.0, i_gain = 2.0, d_gain = 3.0 // error = ref - state = 5.0 - 1.1 = 3.9, error_dot = error/ds = 3.9/0.01 = 390.0, // p_term = error * p_gain = 3.9 * 1.0 = 3.9, - // i_term = error * ds * i_gain = 3.9 * 0.01 * 2.0 = 0.078, + // i_term = zero at first update // d_term = error_dot * d_gain = 390.0 * 3.0 = 1170.0 // feedforward OFF -> cmd = p_term + i_term + d_term = 3.9 + 0.078 + 1170.0 = 1173.978 - const double expected_command_value = 1173.978; - - EXPECT_EQ(controller_->command_interfaces_[0].get_value(), expected_command_value); + { + const double expected_command_value = 1173.9; + EXPECT_EQ(controller_->command_interfaces_[0].get_value(), expected_command_value); + } } /** @@ -442,7 +445,7 @@ TEST_F(PidControllerTest, test_update_logic_chainable_not_use_subscriber_update) */ TEST_F(PidControllerTest, test_update_logic_angle_wraparound_off) { - SetUpController(); + SetUpController("test_pid_controller_unlimited"); rclcpp::executors::MultiThreadedExecutor executor; executor.add_node(controller_->get_node()->get_node_base_interface()); executor.add_node(service_caller_node_->get_node_base_interface()); @@ -451,7 +454,7 @@ TEST_F(PidControllerTest, test_update_logic_angle_wraparound_off) ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_FALSE(controller_->params_.gains.dof_names_map[dof_names_[0]].angle_wraparound); - // write reference interface so that the values are would be wrapped + // write reference interface so that the values would be wrapped controller_->reference_interfaces_[0] = 10.0; // run update @@ -460,7 +463,13 @@ TEST_F(PidControllerTest, test_update_logic_angle_wraparound_off) controller_interface::return_type::OK); // check the result of the commands - the values are not wrapped - const double expected_command_value = 2679.078; + // ref = 10.0, state = 1.1, ds = 0.01, p_gain = 1.0, i_gain = 2.0, d_gain = 3.0 + // error = ref - state = 10.0 - 1.1 = 8.9, error_dot = error/ds = 8.9/0.01 = 890.0, + // p_term = error * p_gain = 8.9 * 1.0 = 8.9, + // i_term = zero at first update + // d_term = error_dot * d_gain = 890.0 * 3.0 = 2670.0 + // feedforward OFF -> cmd = p_term + i_term + d_term = 8.9 + 0.0 + 2670.0 = 2678.9 + const double expected_command_value = 2678.9; EXPECT_NEAR(controller_->command_interfaces_[0].get_value(), expected_command_value, 1e-5); } @@ -490,8 +499,13 @@ TEST_F(PidControllerTest, test_update_logic_angle_wraparound_on) controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::OK); - // Check the command value - const double expected_command_value = 787.713559; + // Check the command value with wrapped error + // ref = 10.0, state = 1.1, ds = 0.01, p_gain = 1.0, i_gain = 2.0, d_gain = 3.0 + // error = ref - state = wrap(10.0 - 1.1) = 8.9-2*pi = 2.616814, error_dot = error/ds + // = 2.6168/0.01 = 261.6814, p_term = error * p_gain = 2.6168 * 1.0 = 2.6168, i_term = zero at + // first update d_term = error_dot * d_gain = 261.6814 * 3.0 = 785.0444079 feedforward OFF -> cmd + // = p_term + i_term + d_term = 2.616814, + 0.0 + 785.0444079 = 787.6612219 + const double expected_command_value = 787.6612219; EXPECT_NEAR(controller_->command_interfaces_[0].get_value(), expected_command_value, 1e-5); } @@ -720,9 +734,9 @@ TEST_F(PidControllerTest, test_save_i_term_off) // check the command value // error = ref - state = 100.001, error_dot = error/ds = 10000.1, - // p_term = 100.001 * 1, i_term = 1.00001 * 2 = 2.00002, d_term = error/ds = 10000.1 * 3 - // feedforward OFF -> cmd = p_term + i_term + d_term = 30102.3 - const double expected_command_value = 30102.30102; + // p_term = 100.001 * 1, i_term = zero at first update, d_term = error/ds = 10000.1 * 3 + // feedforward OFF -> cmd = p_term + i_term + d_term = 30100.301 + const double expected_command_value = 30100.3010; double actual_value = std::round(controller_->command_interfaces_[0].get_value() * 1e5) / 1e5; EXPECT_NEAR(actual_value, expected_command_value, 1e-5); @@ -770,9 +784,9 @@ TEST_F(PidControllerTest, test_save_i_term_on) // check the command value // error = ref - state = 100.001, error_dot = error/ds = 10000.1, - // p_term = 100.001 * 1, i_term = 1.00001 * 2 = 2.00002, d_term = error/ds = 10000.1 * 3 - // feedforward OFF -> cmd = p_term + i_term + d_term = 30102.3 - const double expected_command_value = 30102.30102; + // p_term = 100.001 * 1, i_term = zero at first update, d_term = error/ds = 10000.1 * 3 + // feedforward OFF -> cmd = p_term + i_term + d_term = 30102.301 + const double expected_command_value = 30100.3010; double actual_value = std::round(controller_->command_interfaces_[0].get_value() * 1e5) / 1e5; EXPECT_NEAR(actual_value, expected_command_value, 1e-5); diff --git a/pid_controller/test/test_pid_controller.hpp b/pid_controller/test/test_pid_controller.hpp index 1eb55ec878..6bd0af89e9 100644 --- a/pid_controller/test/test_pid_controller.hpp +++ b/pid_controller/test/test_pid_controller.hpp @@ -141,8 +141,6 @@ class PidControllerFixture : public ::testing::Test controller_ = std::make_unique(); command_publisher_node_ = std::make_shared("command_publisher"); - command_publisher_ = command_publisher_node_->create_publisher( - "/test_pid_controller/reference", rclcpp::SystemDefaultsQoS()); service_caller_node_ = std::make_shared("service_caller"); feedforward_service_client_ = service_caller_node_->create_client( @@ -156,6 +154,9 @@ class PidControllerFixture : public ::testing::Test protected: void SetUpController(const std::string controller_name = "test_pid_controller") { + command_publisher_ = command_publisher_node_->create_publisher( + "/" + controller_name + "/reference", rclcpp::SystemDefaultsQoS()); + ASSERT_EQ( controller_->init(controller_name, "", 0, "", controller_->define_custom_node_options()), controller_interface::return_type::OK); diff --git a/pid_controller/test/test_pid_controller_dual_interface.cpp b/pid_controller/test/test_pid_controller_dual_interface.cpp index 2cf6ae8a20..e8847ecd2d 100644 --- a/pid_controller/test/test_pid_controller_dual_interface.cpp +++ b/pid_controller/test/test_pid_controller_dual_interface.cpp @@ -93,8 +93,8 @@ TEST_F(PidControllerDualInterfaceTest, test_chained_feedforward_with_gain_dual_i controller_interface::return_type::OK); // check the commands - const double joint1_expected_cmd = 8.915; - const double joint2_expected_cmd = 9.915; + const double joint1_expected_cmd = 8.90; + const double joint2_expected_cmd = 9.90; ASSERT_EQ(controller_->command_interfaces_[0].get_value(), joint1_expected_cmd); ASSERT_EQ(controller_->command_interfaces_[1].get_value(), joint2_expected_cmd); } From e7aba9156ca43e6501b7d89740a0c11184e91f24 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 22 Jul 2025 21:27:45 +0200 Subject: [PATCH 046/108] Apply API change of PidROS (backport #1823) (#1826) --- doc/migration.rst | 1 + doc/release_notes.rst | 1 + pid_controller/doc/userdoc.rst | 3 +++ pid_controller/src/pid_controller.cpp | 5 ++--- pid_controller/src/pid_controller.yaml | 5 +++++ 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/doc/migration.rst b/doc/migration.rst index 2a7e197711..cef475be0f 100644 --- a/doc/migration.rst +++ b/doc/migration.rst @@ -26,6 +26,7 @@ pid_controller * Parameters ``enable_feedforward`` and service ``set_feedforward_control`` are deprecated. Instead, set the feedforward_gain to zero or a non-zero value. (`#1553 `_). * The legacy ``antiwindup`` boolean and integral clamp parameters ``i_clamp_max``/``i_clamp_min`` have been deprecated in favor of the new ``antiwindup_strategy`` parameter (`#1585 `__). Choose a suitable anti-windup strategy and set the parameters accordingly. +* PID state publisher topic changed to ```` namespace and is initially turned off. It can be turned on by using ``activate_state_publisher`` parameter. (`#1823 `_). steering_controllers_library ******************************** diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 21dddda580..812ed4c85f 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -69,6 +69,7 @@ pid_controller * Output clamping via ``u_clamp_max`` and ``u_clamp_min`` was added, allowing users to bound the controller output. * The legacy ``antiwindup`` boolean and integral clamp parameters ``i_clamp_max``/``i_clamp_min`` have been deprecated in favor of the new ``antiwindup_strategy`` parameter. A ``tracking_time_constant`` parameter has also been introduced to configure the back-calculation strategy. * A new ``error_deadband`` parameter stops integration when the error is within a specified range. +* PID state publisher can be turned off or on by using ``activate_state_publisher`` parameter. (`#1823 `_). steering_controllers_library ******************************** diff --git a/pid_controller/doc/userdoc.rst b/pid_controller/doc/userdoc.rst index 3d476e5eb4..03a760040d 100644 --- a/pid_controller/doc/userdoc.rst +++ b/pid_controller/doc/userdoc.rst @@ -80,6 +80,9 @@ Services Publishers ,,,,,,,,,,, - /controller_state [control_msgs/msg/MultiDOFStateStamped] +- //pid_state [control_msgs/msg/PidState] + +Initially the PidState publisher is turned off. It can be turned on by using ``gains..activate_state_publisher`` parameter. Parameters ,,,,,,,,,,, diff --git a/pid_controller/src/pid_controller.cpp b/pid_controller/src/pid_controller.cpp index b1cb29e7c6..05b534bf3e 100644 --- a/pid_controller/src/pid_controller.cpp +++ b/pid_controller/src/pid_controller.cpp @@ -139,9 +139,8 @@ controller_interface::CallbackReturn PidController::configure_parameters() for (size_t i = 0; i < dof_; ++i) { - // prefix should be interpreted as parameters prefix - pids_[i] = - std::make_shared(get_node(), "gains." + params_.dof_names[i], true); + pids_[i] = std::make_shared( + get_node(), "gains." + params_.dof_names[i], "~/" + params_.dof_names[i], false); if (!pids_[i]->initialize_from_ros_parameters()) { return CallbackReturn::FAILURE; diff --git a/pid_controller/src/pid_controller.yaml b/pid_controller/src/pid_controller.yaml index 459c935d08..0ec150c5ab 100644 --- a/pid_controller/src/pid_controller.yaml +++ b/pid_controller/src/pid_controller.yaml @@ -135,3 +135,8 @@ pid_controller: default_value: true, description: "Indicating if integral term is retained after re-activation" } + activate_state_publisher: { + type: bool, + default_value: false, + description: "Individual state publisher activation for each DOF. If true, the controller will publish the state of each DOF to the topic `///pid_state`." + } From 20a29f9698c91532261f2f65c9cac35ce62f8ad2 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Wed, 23 Jul 2025 06:39:32 +0000 Subject: [PATCH 047/108] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 3 +++ admittance_controller/CHANGELOG.rst | 3 +++ bicycle_steering_controller/CHANGELOG.rst | 3 +++ diff_drive_controller/CHANGELOG.rst | 3 +++ effort_controllers/CHANGELOG.rst | 3 +++ force_torque_sensor_broadcaster/CHANGELOG.rst | 3 +++ forward_command_controller/CHANGELOG.rst | 5 +++++ gpio_controllers/CHANGELOG.rst | 3 +++ gps_sensor_broadcaster/CHANGELOG.rst | 3 +++ gripper_controllers/CHANGELOG.rst | 3 +++ imu_sensor_broadcaster/CHANGELOG.rst | 3 +++ joint_state_broadcaster/CHANGELOG.rst | 3 +++ joint_trajectory_controller/CHANGELOG.rst | 3 +++ mecanum_drive_controller/CHANGELOG.rst | 3 +++ parallel_gripper_controller/CHANGELOG.rst | 3 +++ pid_controller/CHANGELOG.rst | 6 ++++++ pose_broadcaster/CHANGELOG.rst | 3 +++ position_controllers/CHANGELOG.rst | 3 +++ range_sensor_broadcaster/CHANGELOG.rst | 3 +++ ros2_controllers/CHANGELOG.rst | 3 +++ ros2_controllers_test_nodes/CHANGELOG.rst | 3 +++ rqt_joint_trajectory_controller/CHANGELOG.rst | 3 +++ steering_controllers_library/CHANGELOG.rst | 3 +++ tricycle_controller/CHANGELOG.rst | 3 +++ tricycle_steering_controller/CHANGELOG.rst | 3 +++ velocity_controllers/CHANGELOG.rst | 3 +++ 26 files changed, 83 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 6e2e40f67c..cfc33d9699 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 814c1f5bb8..e7f45c212b 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 4412c3d28f..541ff1be46 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 21487c6751..7eaa18d337 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- * Explicit cast rcutils_duration_value_t (backport `#1808 `_) (`#1812 `_) diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index cd2354ffaa..ab52fb37a6 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 865c7e705a..3776507b9e 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 11e5cb3995..33d20548a9 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Reject non-finite values in forward controller subscriber callback (#… (backport `#1815 `_) (`#1817 `_) +* Contributors: Christoph Fröhlich, Kaizen + 4.28.0 (2025-07-14) ------------------- diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 565e848eca..dab19bc25c 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 6b95482863..c548082088 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index a40da4abb9..865b58fa68 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 6dd111b986..ee757e2c03 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index c918736cce..1521e0e99c 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index f80af0e948..601aad1efb 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 1abf7e9af7..1a66a5488d 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- * Mecanum Drive: Populate the pose covariance matrix (backport `#1772 `_) (`#1807 `_) diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 1740d51df8..63b95d1188 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 2a60eb453a..d95d6f075b 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Apply API change of PidROS (backport `#1823 `_) (`#1826 `_) +* Change the tests to work without deprecated PID settings (backport `#1824 `_) (`#1825 `_) +* Contributors: mergify[bot] + 4.28.0 (2025-07-14) ------------------- diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 1e786ffb49..cd17d3ab43 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 5334e2a4f6..3bbbb85efc 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 4936b39826..39abcc2bab 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 358aeaf026..b77f5c13fc 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index f8aca88e0d..acee16a23d 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 2417b78f51..28b7ea616d 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- * fix rqt_joint_trajectory_controller for robots with namespace (backport `#1792 `_) (`#1803 `_) diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 81b9092168..20de7dbefe 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 0fa321d10f..b3cc5cbe2a 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 66e70e46ba..0848f2ad56 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index db4d3ee6e1..61d9443d5f 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.28.0 (2025-07-14) ------------------- From a2601092ab6828a342c12811083265b1f353d6a1 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Wed, 23 Jul 2025 06:39:45 +0000 Subject: [PATCH 048/108] 4.29.0 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 54 files changed, 80 insertions(+), 80 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index cfc33d9699..d8a3f4d71b 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index 32ece8ed42..aa9b468001 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.28.0 + 4.29.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index e7f45c212b..26f17b1256 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index 86004a8968..67bbe133ca 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.28.0 + 4.29.0 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 541ff1be46..3bbac76d07 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index 0653e9671d..af7e5eff5c 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.28.0 + 4.29.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 7eaa18d337..8a986641b3 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 4bd299366f..7a63635b17 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.28.0 + 4.29.0 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index ab52fb37a6..8e914382eb 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index e19a9c4707..a4394c4685 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.28.0 + 4.29.0 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 3776507b9e..c406e3af71 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 127cac3545..fd3bfb2a32 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.28.0 + 4.29.0 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 33d20548a9..ee28c46ad2 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- * Reject non-finite values in forward controller subscriber callback (#… (backport `#1815 `_) (`#1817 `_) * Contributors: Christoph Fröhlich, Kaizen diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index 90363e5e2b..4dc5eecfe5 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.28.0 + 4.29.0 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index dab19bc25c..30fa8ac6b1 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index 87cfda594e..fda492ea46 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.28.0 + 4.29.0 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index c548082088..875c397ea7 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index d8fd3be983..7f8a70ffe0 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.28.0 + 4.29.0 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 865b58fa68..49c4ba7067 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index 6742f65973..8bdf1aa174 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.28.0 + 4.29.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index ee757e2c03..cbae8b752b 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index 203e686755..fb13cc3d52 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.28.0 + 4.29.0 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 1521e0e99c..74f085b153 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index 35034379e3..9e138fe316 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.28.0 + 4.29.0 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 601aad1efb..06519be5d9 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 8deda1f9c9..be1b813350 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.28.0 + 4.29.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 1a66a5488d..836f9dd940 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index 4bf5fcdbb5..75820cf858 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.28.0 + 4.29.0 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 63b95d1188..4b73768508 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index 1ec243a9e7..2ffa2a3422 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.28.0 + 4.29.0 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index d95d6f075b..d5d30fb287 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- * Apply API change of PidROS (backport `#1823 `_) (`#1826 `_) * Change the tests to work without deprecated PID settings (backport `#1824 `_) (`#1825 `_) * Contributors: mergify[bot] diff --git a/pid_controller/package.xml b/pid_controller/package.xml index cf237270c2..9ac2942e27 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.28.0 + 4.29.0 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index cd17d3ab43..08394152a3 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index 48a0e32782..8dad516398 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.28.0 + 4.29.0 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 3bbbb85efc..7e87f3a49a 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index 33fc5793bf..6af00af94f 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.28.0 + 4.29.0 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 39abcc2bab..c61954cabc 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index 7a17de0be6..ad2c10ccc0 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.28.0 + 4.29.0 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index b77f5c13fc..7dac018184 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 3ef0d42282..c54790f664 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.28.0 + 4.29.0 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index acee16a23d..39ec6797e6 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 5e3b4943e1..9be003f2fd 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.28.0 + 4.29.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index d28c46765f..c6a83528cb 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.28.0", + version="4.29.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 28b7ea616d..91923edee5 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index c2fbac13cd..370efe063a 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.28.0 + 4.29.0 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index a9fdfc8eaa..542915ac7b 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.28.0", + version="4.29.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 20de7dbefe..5945f6f820 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index f21370c4c6..5998564837 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.28.0 + 4.29.0 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index b3cc5cbe2a..c21fe0973f 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index 2907000b68..866f4f715e 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.28.0 + 4.29.0 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 0848f2ad56..c944a226a4 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index 6c74653edb..c301d08964 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.28.0 + 4.29.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 61d9443d5f..3419e06f8d 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.29.0 (2025-07-23) +------------------- 4.28.0 (2025-07-14) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index a6afa512c3..e09cb9375e 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.28.0 + 4.29.0 Generic controller for forwarding commands. Bence Magyar From d9b0c8d38bbeca7846d14a3dd6c8c64f0966897e Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 25 Jul 2025 11:14:26 +0200 Subject: [PATCH 049/108] Fix `child_frame_id` in controller_state_msg (backport #1601) (#1835) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Rehan Shah <85085446+rehanshah17@users.noreply.github.com> Co-authored-by: Christoph Fröhlich --- .../admittance_rule_impl.hpp | 8 +++--- .../test/test_admittance_controller.cpp | 25 +++++++++++++++++++ .../test/test_admittance_controller.hpp | 1 + 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/admittance_controller/include/admittance_controller/admittance_rule_impl.hpp b/admittance_controller/include/admittance_controller/admittance_rule_impl.hpp index 859c7e3336..7e3a289e8a 100644 --- a/admittance_controller/include/admittance_controller/admittance_rule_impl.hpp +++ b/admittance_controller/include/admittance_controller/admittance_rule_impl.hpp @@ -102,8 +102,6 @@ controller_interface::return_type AdmittanceRule::reset(const size_t num_joints) state_message_.wrench_base.header.frame_id = parameters_.kinematics.base; state_message_.admittance_velocity.header.frame_id = parameters_.kinematics.base; state_message_.admittance_acceleration.header.frame_id = parameters_.kinematics.base; - state_message_.admittance_position.header.frame_id = parameters_.kinematics.base; - state_message_.admittance_position.child_frame_id = "admittance_offset"; // reset admittance state admittance_state_ = AdmittanceState(num_joints); @@ -392,10 +390,12 @@ const control_msgs::msg::AdmittanceControllerState & AdmittanceRule::get_control admittance_state_.admittance_acceleration[5]; state_message_.admittance_position = tf2::eigenToTransform(admittance_state_.admittance_position); + state_message_.admittance_position.header.frame_id = parameters_.kinematics.base; + state_message_.admittance_position.child_frame_id = "admittance_offset"; - state_message_.ref_trans_base_ft.header.frame_id = parameters_.kinematics.base; - state_message_.ref_trans_base_ft.header.frame_id = "ft_reference"; state_message_.ref_trans_base_ft = tf2::eigenToTransform(admittance_state_.ref_trans_base_ft); + state_message_.ref_trans_base_ft.header.frame_id = parameters_.kinematics.base; + state_message_.ref_trans_base_ft.child_frame_id = parameters_.ft_sensor.frame.id; Eigen::Quaterniond quat(admittance_state_.rot_base_control); state_message_.rot_base_control.w = quat.w(); diff --git a/admittance_controller/test/test_admittance_controller.cpp b/admittance_controller/test/test_admittance_controller.cpp index 80db4be228..711f4edfd6 100644 --- a/admittance_controller/test/test_admittance_controller.cpp +++ b/admittance_controller/test/test_admittance_controller.cpp @@ -358,6 +358,31 @@ TEST_F(AdmittanceControllerTest, receive_message_and_publish_updated_status) subscribe_and_get_messages(msg); } +TEST_F(AdmittanceControllerTest, check_frame_ids_in_controller_state) +{ + SetUpController(); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); + + broadcast_tfs(); // force torque sensor + + ASSERT_EQ( + controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + + const auto & msg = controller_->admittance_->get_controller_state(); + + // Ensure correct frame IDs + ASSERT_EQ( + msg.ref_trans_base_ft.header.frame_id, controller_->admittance_->parameters_.kinematics.base); + ASSERT_EQ( + msg.ref_trans_base_ft.child_frame_id, controller_->admittance_->parameters_.ft_sensor.frame.id); + ASSERT_EQ( + msg.admittance_position.header.frame_id, controller_->admittance_->parameters_.kinematics.base); + ASSERT_EQ(msg.admittance_position.child_frame_id, "admittance_offset"); +} + int main(int argc, char ** argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/admittance_controller/test/test_admittance_controller.hpp b/admittance_controller/test/test_admittance_controller.hpp index c2abdecf65..e38bcc82cf 100644 --- a/admittance_controller/test/test_admittance_controller.hpp +++ b/admittance_controller/test/test_admittance_controller.hpp @@ -67,6 +67,7 @@ class TestableAdmittanceController : public admittance_controller::AdmittanceCon FRIEND_TEST(AdmittanceControllerTest, check_interfaces); FRIEND_TEST(AdmittanceControllerTest, activate_success); FRIEND_TEST(AdmittanceControllerTest, receive_message_and_publish_updated_status); + FRIEND_TEST(AdmittanceControllerTest, check_frame_ids_in_controller_state); public: CallbackReturn on_init() override From 98c719ce914941db86130eaf19193816019b6264 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 26 Jul 2025 11:40:32 +0200 Subject: [PATCH 050/108] Add omni_wheel_drive_controller (backport #1535) (#1836) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Aarav Gupta Co-authored-by: Christoph Fröhlich Co-authored-by: Sai Kishor Kothakota --- doc/controllers_index.rst | 1 + doc/release_notes.rst | 4 + omni_wheel_drive_controller/CMakeLists.txt | 92 ++ omni_wheel_drive_controller/doc/userdoc.rst | 78 ++ .../omni_wheel_drive_controller/odometry.hpp | 76 ++ .../omni_wheel_drive_controller.hpp | 120 +++ .../omni_wheel_drive_plugin.xml | 9 + omni_wheel_drive_controller/package.xml | 43 + omni_wheel_drive_controller/src/odometry.cpp | 160 ++++ .../src/omni_wheel_drive_controller.cpp | 541 +++++++++++ ...mni_wheel_drive_controller_parameters.yaml | 98 ++ .../test_omni_wheel_drive_controller.yaml | 25 + .../test_load_omni_wheel_drive_controller.cpp | 50 + .../test/test_omni_wheel_drive_controller.cpp | 878 ++++++++++++++++++ .../test/test_omni_wheel_drive_controller.hpp | 247 +++++ ros2_controllers/doc/index.rst | 4 + ros2_controllers/package.xml | 1 + 17 files changed, 2427 insertions(+) create mode 100644 omni_wheel_drive_controller/CMakeLists.txt create mode 100644 omni_wheel_drive_controller/doc/userdoc.rst create mode 100644 omni_wheel_drive_controller/include/omni_wheel_drive_controller/odometry.hpp create mode 100644 omni_wheel_drive_controller/include/omni_wheel_drive_controller/omni_wheel_drive_controller.hpp create mode 100644 omni_wheel_drive_controller/omni_wheel_drive_plugin.xml create mode 100644 omni_wheel_drive_controller/package.xml create mode 100644 omni_wheel_drive_controller/src/odometry.cpp create mode 100644 omni_wheel_drive_controller/src/omni_wheel_drive_controller.cpp create mode 100644 omni_wheel_drive_controller/src/omni_wheel_drive_controller_parameters.yaml create mode 100644 omni_wheel_drive_controller/test/config/test_omni_wheel_drive_controller.yaml create mode 100644 omni_wheel_drive_controller/test/test_load_omni_wheel_drive_controller.cpp create mode 100644 omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.cpp create mode 100644 omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.hpp diff --git a/doc/controllers_index.rst b/doc/controllers_index.rst index 6fd3b159b2..1bb61058f8 100644 --- a/doc/controllers_index.rst +++ b/doc/controllers_index.rst @@ -29,6 +29,7 @@ Controllers for Wheeled Mobile Robots Differential Drive Controller <../diff_drive_controller/doc/userdoc.rst> Mecanum Drive Controllers <../mecanum_drive_controller/doc/userdoc.rst> + Omni Wheel Drive Controller <../omni_wheel_drive_controller/doc/userdoc.rst> Steering Controllers Library <../steering_controllers_library/doc/userdoc.rst> Tricycle Controller <../tricycle_controller/doc/userdoc.rst> diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 812ed4c85f..075c1c7e53 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -61,6 +61,10 @@ mecanum_drive_controller ************************ * 🚀 The mecanum_drive_controller was added 🎉 (`#512 `_). +omni_wheel_drive_controller +********************************* +* 🚀 The omni_wheel_drive_controller was added 🎉 (`#1535 `_). + pid_controller ************************ * 🚀 The PID controller was added 🎉 (`#434 `_). diff --git a/omni_wheel_drive_controller/CMakeLists.txt b/omni_wheel_drive_controller/CMakeLists.txt new file mode 100644 index 0000000000..f3da519c2b --- /dev/null +++ b/omni_wheel_drive_controller/CMakeLists.txt @@ -0,0 +1,92 @@ +cmake_minimum_required(VERSION 3.16) +project(omni_wheel_drive_controller) + +find_package(ros2_control_cmake REQUIRED) +set_compiler_options() +export_windows_symbols() + +# Find dependencies +set(THIS_PACKAGE_INCLUDE_DEPENDS + ament_cmake + controller_interface + generate_parameter_library + geometry_msgs + hardware_interface + nav_msgs + pluginlib + rclcpp + rclcpp_lifecycle + realtime_tools + tf2 + tf2_msgs + Eigen3 +) +foreach(Dependency IN ITEMS ${THIS_PACKAGE_INCLUDE_DEPENDS}) + find_package(${Dependency} REQUIRED) +endforeach() + +generate_parameter_library( + ${PROJECT_NAME}_parameters + src/${PROJECT_NAME}_parameters.yaml +) + +add_library(${PROJECT_NAME} SHARED + src/${PROJECT_NAME}.cpp + src/odometry.cpp +) +target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17) +target_include_directories(${PROJECT_NAME} + PUBLIC $ + $ +) +target_link_libraries(${PROJECT_NAME} PUBLIC + ${PROJECT_NAME}_parameters + Eigen3::Eigen + controller_interface::controller_interface + hardware_interface::hardware_interface + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle + realtime_tools::realtime_tools + tf2::tf2 + ${geometry_msgs_TARGETS} + ${nav_msgs_TARGETS} + ${tf2_msgs_TARGETS} +) +pluginlib_export_plugin_description_file(controller_interface omni_wheel_drive_plugin.xml) + +# Install +install( + DIRECTORY include/ + DESTINATION include/${PROJECT_NAME}/ +) +install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_parameters + EXPORT export_${PROJECT_NAME} + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib +) + +if(BUILD_TESTING) + find_package(ament_cmake_gmock REQUIRED) + find_package(controller_manager REQUIRED) + find_package(ros2_control_test_assets REQUIRED) + + ament_add_gmock(test_${PROJECT_NAME} test/test_${PROJECT_NAME}.cpp) + target_link_libraries(test_${PROJECT_NAME} + ${PROJECT_NAME} + ) + + add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") + ament_add_gmock(test_load_${PROJECT_NAME} test/test_load_${PROJECT_NAME}.cpp) + find_package(ament_lint_auto REQUIRED) + ament_lint_auto_find_test_dependencies() + target_link_libraries(test_load_${PROJECT_NAME} + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets + ) +endif() + +ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET) +ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS}) +ament_package() diff --git a/omni_wheel_drive_controller/doc/userdoc.rst b/omni_wheel_drive_controller/doc/userdoc.rst new file mode 100644 index 0000000000..1c88bf840c --- /dev/null +++ b/omni_wheel_drive_controller/doc/userdoc.rst @@ -0,0 +1,78 @@ +:github_url: https://github.com/ros-controls/ros2_controllers/blob/{REPOS_FILE_BRANCH}/omni_wheel_drive_controller/doc/userdoc.rst + +.. _omni_wheel_drive_controller_userdoc: + +omni_wheel_drive_controller +================================= + +Controller for mobile robots with omnidirectional drive. + +Supports using three or more omni wheels spaced at an equal angle from each other in a circular formation. +To better understand this, have a look at :ref:`mobile_robot_kinematics`. + +The controller uses velocity input, i.e., stamped Twist messages where linear ``x``, ``y``, and angular ``z`` components are used. +Values in other components are ignored. + +Odometry is computed from hardware feedback and published. + +Other features +-------------- + + + Realtime-safe implementation. + + Odometry publishing + + Automatic stop after command time-out + +Description of controller's interfaces +-------------------------------------- + +References (from a preceding controller) +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, + +When controller is in chained mode, it exposes the following references which can be commanded by the preceding controller: + +- ``/linear/x/velocity`` double, in m/s +- ``/linear/y/velocity`` double, in m/s +- ``/angular/z/velocity`` double, in rad/s + +Together, these represent the body twist (which in unchained-mode would be obtained from ~/cmd_vel). + +State interfaces +,,,,,,,,,,,,,,,, + +As feedback interface type the joints' position (``hardware_interface::HW_IF_POSITION``) or velocity (``hardware_interface::HW_IF_VELOCITY``, if parameter ``position_feedback=false``) are used. + +Command interfaces +,,,,,,,,,,,,,,,,,,,,,, + +Joints' velocity (``hardware_interface::HW_IF_VELOCITY``) are used. + + +ROS 2 Interfaces +---------------- + +Subscribers +,,,,,,,,,,, + +~/cmd_vel [geometry_msgs/msg/TwistStamped] + Velocity command for the controller. The controller extracts the x and y component of the linear velocity and the z component of the angular velocity. Velocities on other components are ignored. + +Publishers +,,,,,,,,,, +~/odom [nav_msgs::msg::Odometry] + This represents an estimate of the robot's position and velocity in free space. + +/tf [tf2_msgs::msg::TFMessage] + tf tree. Published only if ``enable_odom_tf=true`` + + +Parameters +,,,,,,,,,, + +This controller uses the `generate_parameter_library `_ to handle its parameters. The parameter `definition file located in the src folder `_ contains descriptions for all the parameters used by the controller. + +.. generate_parameter_library_details:: ../src/omni_wheel_drive_controller_parameters.yaml + +An example parameter file for this controller can be found in `the test directory `_: + +.. literalinclude:: ../test/config/test_omni_wheel_drive_controller.yaml + :language: yaml diff --git a/omni_wheel_drive_controller/include/omni_wheel_drive_controller/odometry.hpp b/omni_wheel_drive_controller/include/omni_wheel_drive_controller/odometry.hpp new file mode 100644 index 0000000000..e522662596 --- /dev/null +++ b/omni_wheel_drive_controller/include/omni_wheel_drive_controller/odometry.hpp @@ -0,0 +1,76 @@ +// Copyright 2025 Aarav Gupta +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OMNI_WHEEL_DRIVE_CONTROLLER__ODOMETRY_HPP_ +#define OMNI_WHEEL_DRIVE_CONTROLLER__ODOMETRY_HPP_ + +#include +#include + +#include "rclcpp/time.hpp" + +namespace omni_wheel_drive_controller +{ +class Odometry +{ +public: + Odometry(); + + bool updateFromPos(const std::vector & wheels_pos, const rclcpp::Time & time); + bool updateFromVel(const std::vector & wheels_vel, const rclcpp::Time & time); + bool updateOpenLoop( + const double & linear_x_vel, const double & linear_y_vel, const double & angular_vel, + const rclcpp::Time & time); + void resetOdometry(); + + double getX() const { return x_; } + double getY() const { return y_; } + double getHeading() const { return heading_; } + double getLinearXVel() const { return linear_x_vel_; } + double getLinearYVel() const { return linear_y_vel_; } + double getAngularVel() const { return angular_vel_; } + + void setParams( + const double & robot_radius, const double & wheel_radius, const double & wheel_offset, + const size_t & wheel_count); + +private: + Eigen::Vector3d compute_robot_velocity(const std::vector & wheels_vel) const; + void integrate(const double & dx, const double & dy, const double & dheading); + + // Current timestamp: + rclcpp::Time timestamp_; + + // Current pose: + double x_; // [m] + double y_; // [m] + double heading_; // [rads] + + // Current velocity: + double linear_x_vel_; // [m/s] + double linear_y_vel_; // [m/s] + double angular_vel_; // [rads/s] + + // Robot kinematic parameters: + double robot_radius_; // [m] + double wheel_radius_; // [m] + double wheel_offset_; // [rads] + + // Previous wheel positions/states [rads]: + std::vector wheels_old_pos_; +}; + +} // namespace omni_wheel_drive_controller + +#endif // OMNI_WHEEL_DRIVE_CONTROLLER__ODOMETRY_HPP_ diff --git a/omni_wheel_drive_controller/include/omni_wheel_drive_controller/omni_wheel_drive_controller.hpp b/omni_wheel_drive_controller/include/omni_wheel_drive_controller/omni_wheel_drive_controller.hpp new file mode 100644 index 0000000000..db6f05ec93 --- /dev/null +++ b/omni_wheel_drive_controller/include/omni_wheel_drive_controller/omni_wheel_drive_controller.hpp @@ -0,0 +1,120 @@ +// Copyright 2025 Aarav Gupta +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OMNI_WHEEL_DRIVE_CONTROLLER__OMNI_WHEEL_DRIVE_CONTROLLER_HPP_ +#define OMNI_WHEEL_DRIVE_CONTROLLER__OMNI_WHEEL_DRIVE_CONTROLLER_HPP_ + +#include +#include +#include + +#include "controller_interface/chainable_controller_interface.hpp" +#include "geometry_msgs/msg/twist_stamped.hpp" +#include "nav_msgs/msg/odometry.hpp" +#include "omni_wheel_drive_controller/odometry.hpp" +#include "realtime_tools/realtime_publisher.hpp" +#include "realtime_tools/realtime_thread_safe_box.hpp" +#include "tf2_msgs/msg/tf_message.hpp" + +// auto-generated by generate_parameter_library +#include "omni_wheel_drive_controller/omni_wheel_drive_controller_parameters.hpp" + +namespace omni_wheel_drive_controller +{ +class OmniWheelDriveController : public controller_interface::ChainableControllerInterface +{ + using TwistStamped = geometry_msgs::msg::TwistStamped; + +public: + OmniWheelDriveController(); + + controller_interface::CallbackReturn on_init() override; + + controller_interface::InterfaceConfiguration command_interface_configuration() const override; + + controller_interface::InterfaceConfiguration state_interface_configuration() const override; + + controller_interface::CallbackReturn on_configure( + const rclcpp_lifecycle::State & previous_state) override; + + controller_interface::CallbackReturn on_activate( + const rclcpp_lifecycle::State & previous_state) override; + + controller_interface::CallbackReturn on_deactivate( + const rclcpp_lifecycle::State & previous_state) override; + + controller_interface::return_type update_reference_from_subscribers( + const rclcpp::Time & time, const rclcpp::Duration & period) override; + + controller_interface::return_type update_and_write_commands( + const rclcpp::Time & time, const rclcpp::Duration & period) override; + + controller_interface::CallbackReturn on_cleanup( + const rclcpp_lifecycle::State & previous_state) override; + + controller_interface::CallbackReturn on_error( + const rclcpp_lifecycle::State & previous_state) override; + +protected: + std::vector on_export_reference_interfaces() override; + + // Parameters from ROS for omni_wheel_drive_controller + std::shared_ptr param_listener_; + Params params_; + + struct WheelHandle + { + std::optional> feedback; + std::reference_wrapper velocity; + }; + std::vector registered_wheel_handles_; + + controller_interface::CallbackReturn configure_wheel_handles( + const std::vector & wheel_names, std::vector & registered_handles); + + // Timeout to consider cmd_vel commands old + rclcpp::Duration cmd_vel_timeout_ = rclcpp::Duration::from_seconds(0.5); + + std::atomic_bool subscriber_is_active_ = false; + rclcpp::Subscription::SharedPtr velocity_command_subscriber_ = nullptr; + // Realtime container to exchange the reference from subscriber + realtime_tools::RealtimeThreadSafeBox received_velocity_msg_; + // Save the last reference in case of unable to get value from box + TwistStamped command_msg_; + + std::shared_ptr> odometry_publisher_ = nullptr; + std::shared_ptr> + realtime_odometry_publisher_; + nav_msgs::msg::Odometry odometry_message_; + + Odometry odometry_; + + std::shared_ptr> odometry_transform_publisher_ = + nullptr; + std::shared_ptr> + realtime_odometry_transform_publisher_; + geometry_msgs::msg::TransformStamped transform_; + + void compute_and_set_wheel_velocities(); + const char * feedback_type() const; + void halt(); + bool reset(); + bool on_set_chained_mode(bool chained_mode) override; + +private: + void reset_buffers(); +}; +} // namespace omni_wheel_drive_controller + +#endif // OMNI_WHEEL_DRIVE_CONTROLLER__OMNI_WHEEL_DRIVE_CONTROLLER_HPP_ diff --git a/omni_wheel_drive_controller/omni_wheel_drive_plugin.xml b/omni_wheel_drive_controller/omni_wheel_drive_plugin.xml new file mode 100644 index 0000000000..f801210d55 --- /dev/null +++ b/omni_wheel_drive_controller/omni_wheel_drive_plugin.xml @@ -0,0 +1,9 @@ + + + + A chainable controller for mobile robots with omnidirectional drive with three or more omni wheels. + + + diff --git a/omni_wheel_drive_controller/package.xml b/omni_wheel_drive_controller/package.xml new file mode 100644 index 0000000000..83be9d5773 --- /dev/null +++ b/omni_wheel_drive_controller/package.xml @@ -0,0 +1,43 @@ + + + + omni_wheel_drive_controller + 0.0.0 + A chainable controller for mobile robots with omnidirectional drive with three or + more omni wheels. + Apache License 2.0 + + Aarav Gupta + Bence Magyar + Christoph Froehlich + Denis Štogl + Sai Kishor Kothakota + + Aarav Gupta + + ament_cmake + + generate_parameter_library + ros2_control_cmake + + controller_interface + eigen + geometry_msgs + hardware_interface + nav_msgs + pluginlib + rclcpp + rclcpp_lifecycle + realtime_tools + tf2 + tf2_msgs + + ament_cmake_gmock + controller_manager + hardware_interface + ros2_control_test_assets + + + ament_cmake + + diff --git a/omni_wheel_drive_controller/src/odometry.cpp b/omni_wheel_drive_controller/src/odometry.cpp new file mode 100644 index 0000000000..d78caebbf4 --- /dev/null +++ b/omni_wheel_drive_controller/src/odometry.cpp @@ -0,0 +1,160 @@ +// Copyright 2025 Aarav Gupta +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "omni_wheel_drive_controller/odometry.hpp" + +#include + +namespace omni_wheel_drive_controller +{ +Odometry::Odometry() +: timestamp_(0.0), + x_(0.0), + y_(0.0), + heading_(0.0), + linear_x_vel_(0.0), + linear_y_vel_(0.0), + angular_vel_(0.0), + robot_radius_(0.0), + wheel_radius_(0.0), + wheels_old_pos_(0.0) +{ +} + +bool Odometry::updateFromPos(const std::vector & wheels_pos, const rclcpp::Time & time) +{ + const double dt = time.seconds() - timestamp_.seconds(); + // We cannot estimate angular velocity with very small time intervals + if (std::fabs(dt) < 1e-6) + { + return false; + } + + // Estimate angular velocity of wheels using old and current position [rads/s]: + std::vector wheels_vel(wheels_pos.size()); + for (size_t i = 0; i < static_cast(wheels_pos.size()); ++i) + { + wheels_vel[i] = (wheels_pos[i] - wheels_old_pos_[i]) / dt; + wheels_old_pos_[i] = wheels_pos[i]; + } + + if (updateFromVel(wheels_vel, time)) + { + return true; + } + return false; +} + +bool Odometry::updateFromVel(const std::vector & wheels_vel, const rclcpp::Time & time) +{ + const double dt = time.seconds() - timestamp_.seconds(); + + // Compute linear and angular velocities of the robot: + const Eigen::Vector3d robot_velocity = compute_robot_velocity(wheels_vel); + + // Integrate odometry: + integrate(robot_velocity(0) * dt, robot_velocity(1) * dt, robot_velocity(2) * dt); + + timestamp_ = time; + + linear_x_vel_ = robot_velocity(0); + linear_y_vel_ = robot_velocity(1); + angular_vel_ = robot_velocity(2); + + return true; +} + +Eigen::Vector3d Odometry::compute_robot_velocity(const std::vector & wheels_vel) const +{ + Eigen::MatrixXd A(wheels_vel.size(), 3); // Transformation Matrix + Eigen::VectorXd omega(wheels_vel.size()); // Wheel angular velocities vector + + const double angle_bw_wheels = (2 * M_PI) / static_cast(wheels_vel.size()); + + for (size_t i = 0; i < wheels_vel.size(); ++i) + { + // Define the transformation matrix + const double theta = (angle_bw_wheels * static_cast(i)) + wheel_offset_; + A(static_cast(i), 0) = std::sin(theta); + A(static_cast(i), 1) = -std::cos(theta); + A(static_cast(i), 2) = -robot_radius_; + + // Define the wheel angular velocities vector + omega(static_cast(i)) = wheels_vel[i]; + } + + // Compute the robot velocities using SVD decomposition + const Eigen::Vector3d V = + A.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(omega * wheel_radius_); + + return V; +} + +bool Odometry::updateOpenLoop( + const double & linear_x_vel, const double & linear_y_vel, const double & angular_vel, + const rclcpp::Time & time) +{ + const double dt = time.seconds() - timestamp_.seconds(); + + // Integrate odometry: + integrate(linear_x_vel * dt, linear_y_vel * dt, angular_vel * dt); + + timestamp_ = time; + + // Save last linear and angular velocity: + linear_x_vel_ = linear_x_vel; + linear_y_vel_ = linear_y_vel; + angular_vel_ = angular_vel; + + return true; +} + +void Odometry::resetOdometry() +{ + x_ = 0.0; + y_ = 0.0; + heading_ = 0.0; +} + +void Odometry::setParams( + const double & robot_radius, const double & wheel_radius, const double & wheel_offset, + const size_t & wheel_count) +{ + robot_radius_ = robot_radius; + wheel_radius_ = wheel_radius; + wheel_offset_ = wheel_offset; + wheels_old_pos_.resize(wheel_count, 0.0); +} + +void Odometry::integrate(const double & dx, const double & dy, const double & dheading) +{ + if (std::fabs(dheading) < 1e-6) + { + // For very small dheading, approximate to linear motion + x_ = x_ + ((dx * std::cos(heading_)) - (dy * std::sin(heading_))); + y_ = y_ + ((dx * std::sin(heading_)) + (dy * std::cos(heading_))); + heading_ = heading_ + dheading; + } + else + { + const double heading_old = heading_; + heading_ = heading_ + dheading; + x_ = x_ + ((dx / dheading) * (std::sin(heading_) - std::sin(heading_old))) + + ((dy / dheading) * (std::cos(heading_) - std::cos(heading_old))); + y_ = y_ - (dx / dheading) * (std::cos(heading_) - std::cos(heading_old)) + + (dy / dheading) * (std::sin(heading_) - std::sin(heading_old)); + } +} + +} // namespace omni_wheel_drive_controller diff --git a/omni_wheel_drive_controller/src/omni_wheel_drive_controller.cpp b/omni_wheel_drive_controller/src/omni_wheel_drive_controller.cpp new file mode 100644 index 0000000000..966232898c --- /dev/null +++ b/omni_wheel_drive_controller/src/omni_wheel_drive_controller.cpp @@ -0,0 +1,541 @@ +// Copyright 2025 Aarav Gupta +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "omni_wheel_drive_controller/omni_wheel_drive_controller.hpp" + +#include +#include +#include +#include + +#include "hardware_interface/types/hardware_interface_type_values.hpp" +#include "lifecycle_msgs/msg/state.hpp" +#include "rclcpp/logger.hpp" +#include "rclcpp/logging.hpp" +#include "tf2/LinearMath/Quaternion.hpp" + +namespace +{ +constexpr auto DEFAULT_COMMAND_IN_TOPIC = "~/cmd_vel"; +constexpr auto DEFAULT_ODOMETRY_TOPIC = "~/odom"; +constexpr auto DEFAULT_TRANSFORM_TOPIC = "/tf"; +} // namespace + +namespace omni_wheel_drive_controller +{ +using controller_interface::interface_configuration_type; +using controller_interface::InterfaceConfiguration; +using hardware_interface::HW_IF_POSITION; +using hardware_interface::HW_IF_VELOCITY; +using lifecycle_msgs::msg::State; + +OmniWheelDriveController::OmniWheelDriveController() +: controller_interface::ChainableControllerInterface() +{ +} + +controller_interface::CallbackReturn OmniWheelDriveController::on_init() +{ + try + { + param_listener_ = std::make_shared(get_node()); + } + catch (const std::exception & e) + { + fprintf(stderr, "Exception thrown during init stage with message: %s \n", e.what()); + return controller_interface::CallbackReturn::ERROR; + } + return controller_interface::CallbackReturn::SUCCESS; +} + +controller_interface::CallbackReturn OmniWheelDriveController::on_configure( + const rclcpp_lifecycle::State &) +{ + auto logger = get_node()->get_logger(); + + params_ = param_listener_->get_params(); + + if (params_.wheel_names.size() < 3) + { + RCLCPP_ERROR( + logger, + "The number of wheels is less than 3. If there are more wheels please pass them all to the " + "controller or use a different one for your wheel configuration."); + return controller_interface::CallbackReturn::ERROR; + } + + odometry_.setParams( + params_.robot_radius, params_.wheel_radius, params_.wheel_offset, params_.wheel_names.size()); + + cmd_vel_timeout_ = rclcpp::Duration::from_seconds(params_.cmd_vel_timeout); + + // Allocate reference interfaces if needed + const int nr_ref_itfs = 3; + reference_interfaces_.resize(nr_ref_itfs, std::numeric_limits::quiet_NaN()); + + // Reset the controller + if (!reset()) + { + return controller_interface::CallbackReturn::ERROR; + } + + // Initialize velocity command subscriber and define its callback function + velocity_command_subscriber_ = get_node()->create_subscription( + DEFAULT_COMMAND_IN_TOPIC, rclcpp::SystemDefaultsQoS(), + [this](const std::shared_ptr msg) -> void + { + if (!subscriber_is_active_) + { + RCLCPP_WARN(get_node()->get_logger(), "Can't accept new commands. subscriber is inactive"); + return; + } + if ((msg->header.stamp.sec == 0) && (msg->header.stamp.nanosec == 0)) + { + RCLCPP_WARN_ONCE( + get_node()->get_logger(), + "Received TwistStamped with zero timestamp, setting it to current " + "time, this message will only be shown once"); + msg->header.stamp = get_node()->now(); + } + + const auto current_time_diff = get_node()->now() - msg->header.stamp; + + if ( + cmd_vel_timeout_ == rclcpp::Duration::from_seconds(0.0) || + current_time_diff < cmd_vel_timeout_) + { + received_velocity_msg_.set(*msg); + } + else + { + RCLCPP_WARN( + get_node()->get_logger(), + "Ignoring the received message (timestamp %.10f) because it is older than " + "the current time by %.10f seconds, which exceeds the allowed timeout (%.4f)", + rclcpp::Time(msg->header.stamp).seconds(), current_time_diff.seconds(), + cmd_vel_timeout_.seconds()); + } + }); + + // Initialize odometry publisher and message + odometry_publisher_ = get_node()->create_publisher( + DEFAULT_ODOMETRY_TOPIC, rclcpp::SystemDefaultsQoS()); + realtime_odometry_publisher_ = + std::make_shared>( + odometry_publisher_); + + // Append the tf prefix if there is one + std::string tf_prefix = ""; + if (params_.tf_frame_prefix_enable) + { + if (params_.tf_frame_prefix != "") + { + tf_prefix = params_.tf_frame_prefix; + } + else + { + tf_prefix = std::string(get_node()->get_namespace()); + } + + // Make sure prefix does not start with '/' and always ends with '/' + if (tf_prefix.back() != '/') + { + tf_prefix = tf_prefix + "/"; + } + if (tf_prefix.front() == '/') + { + tf_prefix.erase(0, 1); + } + } + const std::string odom_frame_id = tf_prefix + params_.odom_frame_id; + const std::string base_frame_id = tf_prefix + params_.base_frame_id; + + odometry_message_.header.frame_id = odom_frame_id; + odometry_message_.child_frame_id = base_frame_id; + + // Initialize odom values zeros + odometry_message_.twist = + geometry_msgs::msg::TwistWithCovariance(rosidl_runtime_cpp::MessageInitialization::ALL); + + constexpr size_t NUM_DIMENSIONS = 6; + for (size_t index = 0; index < 6; ++index) + { + // 0, 7, 14, 21, 28, 35 + const size_t diagonal_index = NUM_DIMENSIONS * index + index; + odometry_message_.pose.covariance[diagonal_index] = params_.diagonal_covariance.pose[index]; + odometry_message_.twist.covariance[diagonal_index] = params_.diagonal_covariance.twist[index]; + } + + // Initialize transform publisher and message + odometry_transform_publisher_ = get_node()->create_publisher( + DEFAULT_TRANSFORM_TOPIC, rclcpp::SystemDefaultsQoS()); + realtime_odometry_transform_publisher_ = + std::make_shared>( + odometry_transform_publisher_); + + transform_.header.frame_id = odom_frame_id; + transform_.child_frame_id = base_frame_id; + + return controller_interface::CallbackReturn::SUCCESS; +} + +InterfaceConfiguration OmniWheelDriveController::command_interface_configuration() const +{ + std::vector conf_names; + for (const auto & joint_name : params_.wheel_names) + { + conf_names.push_back(joint_name + "/" + HW_IF_VELOCITY); + } + return {interface_configuration_type::INDIVIDUAL, conf_names}; +} + +InterfaceConfiguration OmniWheelDriveController::state_interface_configuration() const +{ + if (params_.open_loop) + { + return {interface_configuration_type::NONE, {}}; + } + + std::vector conf_names; + for (const auto & joint_name : params_.wheel_names) + { + conf_names.push_back(joint_name + "/" + feedback_type()); + } + return {interface_configuration_type::INDIVIDUAL, conf_names}; +} + +controller_interface::CallbackReturn OmniWheelDriveController::on_activate( + const rclcpp_lifecycle::State &) +{ + // Register wheel handles and check if any errors happen + if ( + configure_wheel_handles(params_.wheel_names, registered_wheel_handles_) == + controller_interface::CallbackReturn::ERROR) + { + return controller_interface::CallbackReturn::ERROR; + } + + subscriber_is_active_ = true; + + RCLCPP_DEBUG(get_node()->get_logger(), "Subscriber and publisher are now active."); + return controller_interface::CallbackReturn::SUCCESS; +} + +controller_interface::CallbackReturn OmniWheelDriveController::on_deactivate( + const rclcpp_lifecycle::State &) +{ + subscriber_is_active_ = false; + halt(); + reset_buffers(); + registered_wheel_handles_.clear(); + return controller_interface::CallbackReturn::SUCCESS; +} + +const char * OmniWheelDriveController::feedback_type() const +{ + return params_.position_feedback ? HW_IF_POSITION : HW_IF_VELOCITY; +} + +controller_interface::return_type OmniWheelDriveController::update_reference_from_subscribers( + const rclcpp::Time & time, const rclcpp::Duration &) +{ + auto logger = get_node()->get_logger(); + + auto current_ref_op = received_velocity_msg_.try_get(); + if (current_ref_op.has_value()) + { + command_msg_ = current_ref_op.value(); + } + + const auto age_of_last_command = time - command_msg_.header.stamp; + // Brake if cmd_vel has timeout, override the stored command + if (age_of_last_command > cmd_vel_timeout_) + { + reference_interfaces_[0] = 0.0; + reference_interfaces_[1] = 0.0; + reference_interfaces_[2] = 0.0; + } + else if ( + std::isfinite(command_msg_.twist.linear.x) && std::isfinite(command_msg_.twist.linear.y) && + std::isfinite(command_msg_.twist.angular.z)) + { + reference_interfaces_[0] = command_msg_.twist.linear.x; + reference_interfaces_[1] = command_msg_.twist.linear.y; + reference_interfaces_[2] = command_msg_.twist.angular.z; + } + else + { + RCLCPP_WARN_SKIPFIRST_THROTTLE( + logger, *get_node()->get_clock(), + static_cast(cmd_vel_timeout_.seconds() * 1000), + "Command message contains NaNs. Not updating reference interfaces."); + } + + return controller_interface::return_type::OK; +} + +controller_interface::return_type OmniWheelDriveController::update_and_write_commands( + const rclcpp::Time & time, const rclcpp::Duration &) +{ + rclcpp::Logger logger = get_node()->get_logger(); + + if ( + !std::isfinite(reference_interfaces_[0]) || !std::isfinite(reference_interfaces_[1]) || + !std::isfinite(reference_interfaces_[2])) + { + // NaNs occur on initialization when the reference interfaces are not yet set + return controller_interface::return_type::OK; + } + + // Update odometry + bool odometry_updated = false; + if (params_.open_loop) + { + odometry_updated = odometry_.updateOpenLoop( + reference_interfaces_[0], reference_interfaces_[1], reference_interfaces_[2], time); + } + else + { + std::vector wheels_feedback(registered_wheel_handles_.size()); // [rads] + for (size_t i = 0; i < static_cast(registered_wheel_handles_.size()); ++i) + { + // Get wheel feedback + const std::optional wheel_feedback_op = + registered_wheel_handles_[i].feedback.value().get().get_optional(); + if (!wheel_feedback_op.has_value()) + { + RCLCPP_DEBUG(logger, "Unable to retrieve data from [%zu] wheel feedback!", i); + return controller_interface::return_type::OK; + } + const double wheel_feedback = wheel_feedback_op.value(); + + if (std::isnan(wheel_feedback)) + { + RCLCPP_ERROR(logger, "The wheel %s is invalid for index [%zu]", feedback_type(), i); + return controller_interface::return_type::ERROR; + } + + wheels_feedback[i] = wheel_feedback; + } + if (params_.position_feedback) + { + odometry_updated = odometry_.updateFromPos(wheels_feedback, time); + } + else + { + odometry_updated = odometry_.updateFromVel(wheels_feedback, time); + } + } + + if (odometry_updated) + { + tf2::Quaternion orientation; + orientation.setRPY(0.0, 0.0, odometry_.getHeading()); + + odometry_message_.header.stamp = get_node()->now(); + odometry_message_.pose.pose.position.x = odometry_.getX(); + odometry_message_.pose.pose.position.y = odometry_.getY(); + odometry_message_.pose.pose.orientation.x = orientation.x(); + odometry_message_.pose.pose.orientation.y = orientation.y(); + odometry_message_.pose.pose.orientation.z = orientation.z(); + odometry_message_.pose.pose.orientation.w = orientation.w(); + odometry_message_.twist.twist.linear.x = odometry_.getLinearXVel(); + odometry_message_.twist.twist.linear.y = odometry_.getLinearYVel(); + odometry_message_.twist.twist.angular.z = odometry_.getAngularVel(); + realtime_odometry_publisher_->try_publish(odometry_message_); + + if (params_.enable_odom_tf) + { + transform_.header.stamp = get_node()->now(); + transform_.transform.translation.x = odometry_.getX(); + transform_.transform.translation.y = odometry_.getY(); + transform_.transform.rotation.x = orientation.x(); + transform_.transform.rotation.y = orientation.y(); + transform_.transform.rotation.z = orientation.z(); + transform_.transform.rotation.w = orientation.w(); + tf2_msgs::msg::TFMessage odometry_transform_message; + odometry_transform_message.transforms.push_back(transform_); + realtime_odometry_transform_publisher_->try_publish(odometry_transform_message); + } + } + + compute_and_set_wheel_velocities(); + + return controller_interface::return_type::OK; +} + +controller_interface::CallbackReturn OmniWheelDriveController::on_cleanup( + const rclcpp_lifecycle::State &) +{ + if (!reset()) + { + return controller_interface::CallbackReturn::ERROR; + } + + return controller_interface::CallbackReturn::SUCCESS; +} + +controller_interface::CallbackReturn OmniWheelDriveController::on_error( + const rclcpp_lifecycle::State &) +{ + if (!reset()) + { + return controller_interface::CallbackReturn::ERROR; + } + return controller_interface::CallbackReturn::SUCCESS; +} + +void OmniWheelDriveController::compute_and_set_wheel_velocities() +{ + bool set_command_result = true; + + double angle_bw_wheels = (2 * M_PI) / static_cast(registered_wheel_handles_.size()); + for (size_t i = 0; i < static_cast(registered_wheel_handles_.size()); ++i) + { + set_command_result &= registered_wheel_handles_[i].velocity.get().set_value( + ((std::sin((angle_bw_wheels * static_cast(i)) + params_.wheel_offset) * + reference_interfaces_[0]) - + (std::cos((angle_bw_wheels * static_cast(i)) + params_.wheel_offset) * + reference_interfaces_[1]) - + (reference_interfaces_[2] * params_.robot_radius)) / + params_.wheel_radius); + } + + rclcpp::Logger logger = get_node()->get_logger(); + RCLCPP_DEBUG_EXPRESSION( + logger, !set_command_result, "Unable to set the command to one of the command handles!"); +} + +bool OmniWheelDriveController::reset() +{ + odometry_.resetOdometry(); + + reset_buffers(); + + registered_wheel_handles_.clear(); + + subscriber_is_active_ = false; + velocity_command_subscriber_.reset(); + + return true; +} + +controller_interface::CallbackReturn OmniWheelDriveController::configure_wheel_handles( + const std::vector & wheel_names, std::vector & registered_handles) +{ + rclcpp::Logger logger = get_node()->get_logger(); + + // Register handles + registered_handles.reserve(wheel_names.size()); + for (const auto & wheel_name : wheel_names) + { + const auto command_handle = std::find_if( + command_interfaces_.begin(), command_interfaces_.end(), + [&wheel_name](const auto & interface) + { + return interface.get_prefix_name() == wheel_name && + interface.get_interface_name() == HW_IF_VELOCITY; + }); + + if (command_handle == command_interfaces_.end()) + { + RCLCPP_ERROR(logger, "Unable to obtain joint command handle for %s", wheel_name.c_str()); + return controller_interface::CallbackReturn::ERROR; + } + + if (params_.open_loop) + { + registered_handles.emplace_back(WheelHandle{std::nullopt, std::ref(*command_handle)}); + } + else + { + const auto interface_name = feedback_type(); + const auto state_handle = std::find_if( + state_interfaces_.cbegin(), state_interfaces_.cend(), + [&wheel_name, &interface_name](const auto & interface) + { + return interface.get_prefix_name() == wheel_name && + interface.get_interface_name() == interface_name; + }); + + if (state_handle == state_interfaces_.cend()) + { + RCLCPP_ERROR(logger, "Unable to obtain joint state handle for %s", wheel_name.c_str()); + return controller_interface::CallbackReturn::ERROR; + } + registered_handles.emplace_back( + WheelHandle{std::ref(*state_handle), std::ref(*command_handle)}); + } + } + + return controller_interface::CallbackReturn::SUCCESS; +} + +void OmniWheelDriveController::halt() +{ + bool set_command_result = true; + for (const WheelHandle & wheel_handle : registered_wheel_handles_) + { + set_command_result &= wheel_handle.velocity.get().set_value(0.0); + } + rclcpp::Logger logger = get_node()->get_logger(); + RCLCPP_DEBUG_EXPRESSION( + logger, !set_command_result, "Unable to set the command to one of the command handles!"); +} + +void OmniWheelDriveController::reset_buffers() +{ + std::fill( + reference_interfaces_.begin(), reference_interfaces_.end(), + std::numeric_limits::quiet_NaN()); + + // Fill RealtimeBox with NaNs so it will contain a known value + // but still indicate that no command has yet been sent. + command_msg_.header.stamp = get_node()->now(); + command_msg_.twist.linear.x = std::numeric_limits::quiet_NaN(); + command_msg_.twist.linear.y = std::numeric_limits::quiet_NaN(); + command_msg_.twist.linear.z = std::numeric_limits::quiet_NaN(); + command_msg_.twist.angular.x = std::numeric_limits::quiet_NaN(); + command_msg_.twist.angular.y = std::numeric_limits::quiet_NaN(); + command_msg_.twist.angular.z = std::numeric_limits::quiet_NaN(); + received_velocity_msg_.set(command_msg_); +} + +bool OmniWheelDriveController::on_set_chained_mode(bool /*chained_mode*/) { return true; } + +std::vector +OmniWheelDriveController::on_export_reference_interfaces() +{ + std::vector reference_interfaces; + reference_interfaces.reserve(reference_interfaces_.size()); + + std::vector reference_interface_names = {"/linear/x", "/linear/y", "/angular/z"}; + + for (size_t i = 0; i < reference_interfaces_.size(); ++i) + { + reference_interfaces.push_back( + hardware_interface::CommandInterface( + get_node()->get_name() + reference_interface_names[i], hardware_interface::HW_IF_VELOCITY, + &reference_interfaces_[i])); + } + + return reference_interfaces; +} +} // namespace omni_wheel_drive_controller + +#include "pluginlib/class_list_macros.hpp" + +PLUGINLIB_EXPORT_CLASS( + omni_wheel_drive_controller::OmniWheelDriveController, + controller_interface::ChainableControllerInterface) diff --git a/omni_wheel_drive_controller/src/omni_wheel_drive_controller_parameters.yaml b/omni_wheel_drive_controller/src/omni_wheel_drive_controller_parameters.yaml new file mode 100644 index 0000000000..3e52baf7b8 --- /dev/null +++ b/omni_wheel_drive_controller/src/omni_wheel_drive_controller_parameters.yaml @@ -0,0 +1,98 @@ +omni_wheel_drive_controller: + wheel_offset: + { + type: double, + description: "Angular offset (radians) of the first wheel from the positive direction of the x-axis of the robot.", + read_only: true, + } + wheel_names: + { + type: string_array, + description: "Names of the wheels' joints, given in an anti-clockwise order starting from the wheel aligned with the positive direction of the x-axis of the robot / offset from it by the value specified in ``wheel_offset``.", + validation: { not_empty<>: [] }, + read_only: true, + } + robot_radius: + { + type: double, + description: "Radius of the robot, distance between the center of the robot and the wheels. If this parameter is wrong, the robot will not behave correctly in curves.", + validation: { gt<>: [0.0] }, + read_only: true, + } + wheel_radius: + { + type: double, + description: "Radius of a wheel, i.e., wheels size, used for transformation of linear velocity into wheel rotations. If this parameter is wrong the robot will move faster or slower than expected.", + validation: { gt<>: [0.0] }, + read_only: true, + } + tf_frame_prefix_enable: + { + type: bool, + default_value: true, + description: "Enables or disables appending tf_prefix to tf frame id's.", + read_only: true, + } + tf_frame_prefix: + { + type: string, + default_value: "", + description: "(optional) Prefix to be appended to the tf frames, will be added to odom_id and base_frame_id before publishing. If the parameter is empty, controller's namespace will be used.", + read_only: true, + } + odom_frame_id: + { + type: string, + default_value: "odom", + description: "Name of the frame for odometry. This frame is parent of ``base_frame_id`` when controller publishes odometry.", + read_only: true, + } + base_frame_id: + { + type: string, + default_value: "base_link", + description: "Name of the robot's base frame that is child of the odometry frame.", + read_only: true, + } + diagonal_covariance: + pose: + { + type: double_array, + default_value: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + description: "Odometry covariance for the encoder output of the robot for the pose. These values should be tuned to your robot's sample odometry data, but these values are a good place to start: ``[0.001, 0.001, 0.001, 0.001, 0.001, 0.01]``.", + read_only: true, + } + twist: + { + type: double_array, + default_value: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + description: "Odometry covariance for the encoder output of the robot for the speed. These values should be tuned to your robot's sample odometry data, but these values are a good place to start: ``[0.001, 0.001, 0.001, 0.001, 0.001, 0.01]``.", + read_only: true, + } + open_loop: + { + type: bool, + default_value: false, + description: "If set to true the odometry of the robot will be calculated from the commanded values and not from feedback.", + read_only: true, + } + position_feedback: + { + type: bool, + default_value: true, + description: "Only valid if ``open_loop`` is set to false. If there is position feedback from the hardware, set the parameter to ``true``, else set it to ``false``.", + read_only: true, + } + enable_odom_tf: + { + type: bool, + default_value: true, + description: "Publish transformation between ``odom_frame_id`` and ``base_frame_id``.", + read_only: true, + } + cmd_vel_timeout: { + type: double, + default_value: 0.5, # seconds + description: "Timeout in seconds, after which input command on ``~/cmd_vel`` topic is considered stale.", + read_only: true, + } diff --git a/omni_wheel_drive_controller/test/config/test_omni_wheel_drive_controller.yaml b/omni_wheel_drive_controller/test/config/test_omni_wheel_drive_controller.yaml new file mode 100644 index 0000000000..bd811cbae0 --- /dev/null +++ b/omni_wheel_drive_controller/test/config/test_omni_wheel_drive_controller.yaml @@ -0,0 +1,25 @@ +test_omni_wheel_drive_controller: + ros__parameters: + wheel_offset: 0.0 + wheel_names: + [ + "front_wheel_joint", + "left_wheel_joint", + "back_wheel_joint", + "right_wheel_joint", + ] + + robot_radius: 0.20 + wheel_radius: 0.02 + + odom_frame_id: odom + base_frame_id: base_link + pose_covariance_diagonal: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] + twist_covariance_diagonal: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] + + open_loop: true + position_feedback: false + enable_odom_tf: true + + cmd_vel_timeout: 0.5 + publish_limited_velocity: true diff --git a/omni_wheel_drive_controller/test/test_load_omni_wheel_drive_controller.cpp b/omni_wheel_drive_controller/test/test_load_omni_wheel_drive_controller.cpp new file mode 100644 index 0000000000..9cdd2bb0b0 --- /dev/null +++ b/omni_wheel_drive_controller/test/test_load_omni_wheel_drive_controller.cpp @@ -0,0 +1,50 @@ +// Copyright 2025 Aarav Gupta +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include + +#include "controller_manager/controller_manager.hpp" +#include "rclcpp/executor.hpp" +#include "rclcpp/executors/single_threaded_executor.hpp" +#include "rclcpp/utilities.hpp" +#include "ros2_control_test_assets/descriptions.hpp" + +TEST(TestLoadOmniWheelDriveController, load_controller) +{ + std::shared_ptr executor = + std::make_shared(); + + controller_manager::ControllerManager cm( + executor, ros2_control_test_assets::minimal_robot_urdf, true, "test_controller_manager"); + const std::string test_file_path = + std::string(TEST_FILES_DIRECTORY) + "/config/test_omni_wheel_drive_controller.yaml"; + + cm.set_parameter({"test_omni_wheel_drive_controller.params_file", test_file_path}); + cm.set_parameter( + {"test_omni_wheel_drive_controller.type", + "omni_wheel_drive_controller/OmniWheelDriveController"}); + + ASSERT_NE(cm.load_controller("test_omni_wheel_drive_controller"), nullptr); +} + +int main(int argc, char ** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + rclcpp::init(argc, argv); + int result = RUN_ALL_TESTS(); + rclcpp::shutdown(); + return result; +} diff --git a/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.cpp b/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.cpp new file mode 100644 index 0000000000..104e37de33 --- /dev/null +++ b/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.cpp @@ -0,0 +1,878 @@ +// Copyright 2025 Aarav Gupta +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "test_omni_wheel_drive_controller.hpp" +#include +#include "controller_interface/controller_interface_base.hpp" +#include "lifecycle_msgs/msg/state.hpp" + +using lifecycle_msgs::msg::State; + +class OmniWheelDriveControllerTest +: public OmniWheelDriveControllerFixture +{ +}; + +TEST_F(OmniWheelDriveControllerTest, init_fails_without_parameters) +{ + const auto ret = + controller_->init(controller_name_, urdf_, 0, "", controller_->define_custom_node_options()); + ASSERT_EQ(ret, controller_interface::return_type::ERROR); +} + +TEST_F(OmniWheelDriveControllerTest, configure_fails_with_less_than_three_wheels) +{ + ASSERT_EQ( + InitController({"first_wheel_joint", "second_wheel_joint"}), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_ERROR); +} + +TEST_F(OmniWheelDriveControllerTest, when_controller_configured_expect_properly_exported_interfaces) +{ + ASSERT_EQ(InitController(), controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + // Check command interfaces configuration + auto command_interfaces = controller_->command_interface_configuration(); + ASSERT_EQ(command_interfaces.names.size(), wheel_names_.size()); + for (size_t i = 0; i < command_interfaces.names.size(); ++i) + { + EXPECT_EQ(command_interfaces.names[i], wheel_names_[i] + "/" + HW_IF_VELOCITY); + } + EXPECT_EQ( + command_interfaces.type, controller_interface::interface_configuration_type::INDIVIDUAL); + + // Check state interfaces configuration + auto state_interfaces = controller_->state_interface_configuration(); + ASSERT_EQ(state_interfaces.names.size(), wheel_names_.size()); + for (size_t i = 0; i < state_interfaces.names.size(); ++i) + { + EXPECT_EQ(state_interfaces.names[i], wheel_names_[i] + "/" + HW_IF_POSITION); + } + EXPECT_EQ(state_interfaces.type, controller_interface::interface_configuration_type::INDIVIDUAL); + + // Check reference interfaces configuration + auto reference_interfaces = controller_->export_reference_interfaces(); + ASSERT_EQ(reference_interfaces.size(), 3); + + for (size_t i = 0; i < reference_interface_names.size(); ++i) + { + const std::string ref_itf_prefix_name = + std::string(controller_->get_node()->get_name()) + "/" + reference_interface_names[i]; + EXPECT_EQ(reference_interfaces[i]->get_prefix_name(), ref_itf_prefix_name); + EXPECT_EQ( + reference_interfaces[i]->get_name(), + ref_itf_prefix_name + "/" + hardware_interface::HW_IF_VELOCITY); + EXPECT_EQ(reference_interfaces[i]->get_interface_name(), hardware_interface::HW_IF_VELOCITY); + } +} + +TEST_F(OmniWheelDriveControllerTest, configure_succeeds_tf_test_prefix_false_no_namespace) +{ + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = "test_prefix"; + + ASSERT_EQ( + InitController( + wheel_names_, 0.0, + {rclcpp::Parameter("tf_frame_prefix_enable", rclcpp::ParameterValue(false)), + rclcpp::Parameter("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)), + rclcpp::Parameter("odom_frame_id", rclcpp::ParameterValue(odom_id)), + rclcpp::Parameter("base_frame_id", rclcpp::ParameterValue(base_link_id))}), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + nav_msgs::msg::Odometry odometry_message = controller_->odometry_message_; + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + /* tf_frame_prefix_enable is false so no modifications to the frame id's */ + ASSERT_EQ(test_odom_frame_id, odom_id); + ASSERT_EQ(test_base_frame_id, base_link_id); +} + +TEST_F(OmniWheelDriveControllerTest, configure_succeeds_tf_test_prefix_true_no_namespace) +{ + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = "test_prefix"; + + ASSERT_EQ( + InitController( + wheel_names_, 0.0, + {rclcpp::Parameter("tf_frame_prefix_enable", rclcpp::ParameterValue(true)), + rclcpp::Parameter("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)), + rclcpp::Parameter("odom_frame_id", rclcpp::ParameterValue(odom_id)), + rclcpp::Parameter("base_frame_id", rclcpp::ParameterValue(base_link_id))}), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + nav_msgs::msg::Odometry odometry_message = controller_->odometry_message_; + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + + /* tf_frame_prefix_enable is true and frame_prefix is not blank so should be appended to the frame + * id's */ + ASSERT_EQ(test_odom_frame_id, frame_prefix + "/" + odom_id); + ASSERT_EQ(test_base_frame_id, frame_prefix + "/" + base_link_id); +} + +TEST_F(OmniWheelDriveControllerTest, configure_succeeds_tf_blank_prefix_true_no_namespace) +{ + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = ""; + + ASSERT_EQ( + InitController( + wheel_names_, 0.0, + {rclcpp::Parameter("tf_frame_prefix_enable", rclcpp::ParameterValue(true)), + rclcpp::Parameter("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)), + rclcpp::Parameter("odom_frame_id", rclcpp::ParameterValue(odom_id)), + rclcpp::Parameter("base_frame_id", rclcpp::ParameterValue(base_link_id))}), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + nav_msgs::msg::Odometry odometry_message = controller_->odometry_message_; + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + /* tf_frame_prefix_enable is true but frame_prefix is blank so should not be appended to the frame + * id's */ + ASSERT_EQ(test_odom_frame_id, odom_id); + ASSERT_EQ(test_base_frame_id, base_link_id); +} + +TEST_F(OmniWheelDriveControllerTest, configure_succeeds_tf_test_prefix_false_set_namespace) +{ + std::string test_namespace = "/test_namespace"; + + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = "test_prefix"; + + ASSERT_EQ( + InitController( + wheel_names_, 0.0, + {rclcpp::Parameter("tf_frame_prefix_enable", rclcpp::ParameterValue(false)), + rclcpp::Parameter("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)), + rclcpp::Parameter("odom_frame_id", rclcpp::ParameterValue(odom_id)), + rclcpp::Parameter("base_frame_id", rclcpp::ParameterValue(base_link_id))}, + test_namespace), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + nav_msgs::msg::Odometry odometry_message = controller_->odometry_message_; + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + /* tf_frame_prefix_enable is false so no modifications to the frame id's */ + ASSERT_EQ(test_odom_frame_id, odom_id); + ASSERT_EQ(test_base_frame_id, base_link_id); +} + +TEST_F(OmniWheelDriveControllerTest, configure_succeeds_tf_test_prefix_true_set_namespace) +{ + std::string test_namespace = "/test_namespace"; + + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = "test_prefix"; + + ASSERT_EQ( + InitController( + wheel_names_, 0.0, + {rclcpp::Parameter("tf_frame_prefix_enable", rclcpp::ParameterValue(true)), + rclcpp::Parameter("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)), + rclcpp::Parameter("odom_frame_id", rclcpp::ParameterValue(odom_id)), + rclcpp::Parameter("base_frame_id", rclcpp::ParameterValue(base_link_id))}, + test_namespace), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + nav_msgs::msg::Odometry odometry_message = controller_->odometry_message_; + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + + /* tf_frame_prefix_enable is true and frame_prefix is not blank so should be appended to the frame + * id's instead of the namespace*/ + ASSERT_EQ(test_odom_frame_id, frame_prefix + "/" + odom_id); + ASSERT_EQ(test_base_frame_id, frame_prefix + "/" + base_link_id); +} + +TEST_F(OmniWheelDriveControllerTest, configure_succeeds_tf_blank_prefix_true_set_namespace) +{ + std::string test_namespace = "/test_namespace"; + std::string odom_id = "odom"; + std::string base_link_id = "base_link"; + std::string frame_prefix = ""; + + ASSERT_EQ( + InitController( + wheel_names_, 0.0, + {rclcpp::Parameter("tf_frame_prefix_enable", rclcpp::ParameterValue(true)), + rclcpp::Parameter("tf_frame_prefix", rclcpp::ParameterValue(frame_prefix)), + rclcpp::Parameter("odom_frame_id", rclcpp::ParameterValue(odom_id)), + rclcpp::Parameter("base_frame_id", rclcpp::ParameterValue(base_link_id))}, + test_namespace), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + + nav_msgs::msg::Odometry odometry_message = controller_->odometry_message_; + std::string test_odom_frame_id = odometry_message.header.frame_id; + std::string test_base_frame_id = odometry_message.child_frame_id; + std::string ns_prefix = test_namespace.erase(0, 1) + "/"; + /* tf_frame_prefix_enable is true but frame_prefix is blank so namespace should be appended to the + * frame id's */ + ASSERT_EQ(test_odom_frame_id, ns_prefix + odom_id); + ASSERT_EQ(test_base_frame_id, ns_prefix + base_link_id); +} + +TEST_F(OmniWheelDriveControllerTest, activate_fails_without_resources_assigned) +{ + ASSERT_EQ(InitController(), controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_ERROR); +} + +TEST_F(OmniWheelDriveControllerTest, activate_succeeds_with_pos_resources_assigned) +{ + ASSERT_EQ(InitController(), controller_interface::return_type::OK); + // We implicitly test that by default position feedback is required + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + assignResourcesPosFeedback(); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); +} + +TEST_F(OmniWheelDriveControllerTest, activate_succeeds_with_vel_resources_assigned) +{ + ASSERT_EQ( + InitController( + wheel_names_, 0.0, {rclcpp::Parameter("position_feedback", rclcpp::ParameterValue(false))}), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + assignResourcesVelFeedback(); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); +} + +TEST_F(OmniWheelDriveControllerTest, activate_fails_with_wrong_resources_assigned_1) +{ + ASSERT_EQ( + InitController( + wheel_names_, 0.0, {rclcpp::Parameter("position_feedback", rclcpp::ParameterValue(false))}), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + assignResourcesPosFeedback(); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_ERROR); +} + +TEST_F(OmniWheelDriveControllerTest, activate_fails_with_wrong_resources_assigned_2) +{ + ASSERT_EQ( + InitController( + wheel_names_, 0.0, {rclcpp::Parameter("position_feedback", rclcpp::ParameterValue(true))}), + controller_interface::return_type::OK); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + assignResourcesVelFeedback(); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_ERROR); +} + +// When not in chained mode, we want to test that +// 1. The controller is configurable and all lifecycle functions work properly +// 2. command_interfaces are set to 0.0 when cmd_vel_timeout_ is exceeded and on deactivation +// 3. command_interfaces are set to correct command values the command messages are not timed-out. +// In particular, make sure that the command_interface is not set to NaN right when it starts up. +TEST_F(OmniWheelDriveControllerTest, chainable_controller_unchained_mode) +{ + ASSERT_EQ(InitController(), controller_interface::return_type::OK); + + rclcpp::executors::SingleThreadedExecutor executor; + executor.add_node(controller_->get_node()->get_node_base_interface()); + + ASSERT_TRUE(controller_->is_chainable()); + ASSERT_TRUE(controller_->set_chained_mode(false)); + ASSERT_FALSE(controller_->is_in_chained_mode()); + + auto state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + assignResourcesPosFeedback(); + + state = controller_->get_node()->activate(); + ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); + + waitForSetup(); + + // Reference interfaces should be NaN on initialization + for (const auto & interface : controller_->reference_interfaces_) + { + EXPECT_TRUE(std::isnan(interface)); + } + // But NaNs should not propagate to command interfaces + for (size_t i = 0; i < command_itfs_.size(); i++) + { + ASSERT_FALSE(std::isnan(command_itfs_[i].get_optional().value())); + } + + // Check that a late command message causes the command interfaces to be set to 0.0 + publish_twist(); + + // delay enough time to trigger the timeout (cmd_vel_timeout_ = 0.5s) + controller_->wait_for_twist(executor); + std::this_thread::sleep_for(std::chrono::milliseconds(501)); + + ASSERT_EQ( + controller_->update( + cmd_vel_publisher_node_->get_clock()->now(), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + // Now check that a timely published command message sets the command interfaces to the correct + // values + publish_twist(); + // wait for msg to be published to the system + controller_->wait_for_twist(executor); + + ASSERT_EQ( + controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + std::vector expected_wheels_vel_cmds = {-15.0, 5.0, 5.0, -15.0}; + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_DOUBLE_EQ(command_itfs_[i].get_optional().value(), expected_wheels_vel_cmds[i]); + } + + // Now check that the command interfaces are set to 0.0 on deactivation + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + state = controller_->get_node()->deactivate(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + // cleanup + state = controller_->get_node()->cleanup(); + ASSERT_EQ(State::PRIMARY_STATE_UNCONFIGURED, state.id()); + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + executor.cancel(); +} + +// When in chained mode, we want to test that +// 1. The controller is configurable and all lifecycle functions work properly +// 2. command_interfaces are set to 0.0 on deactivation +// 3. command_interfaces are set to correct command values (not set to NaN right when it starts up) +TEST_F(OmniWheelDriveControllerTest, chainable_controller_chained_mode) +{ + ASSERT_EQ(InitController(), controller_interface::return_type::OK); + + rclcpp::executors::SingleThreadedExecutor executor; + executor.add_node(controller_->get_node()->get_node_base_interface()); + + ASSERT_TRUE(controller_->is_chainable()); + ASSERT_TRUE(controller_->set_chained_mode(true)); + ASSERT_TRUE(controller_->is_in_chained_mode()); + + auto state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + assignResourcesPosFeedback(); + + state = controller_->get_node()->activate(); + ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); + + waitForSetup(); + + // Reference interfaces should be NaN on initialization + for (const auto & interface : controller_->reference_interfaces_) + { + EXPECT_TRUE(std::isnan(interface)); + } + // But NaNs should not propagate to command interfaces + for (size_t i = 0; i < command_itfs_.size(); i++) + { + ASSERT_FALSE(std::isnan(command_itfs_[i].get_optional().value())); + } + + // Imitate preceding controllers by setting reference_interfaces_ + controller_->reference_interfaces_[0] = 1.0; + controller_->reference_interfaces_[1] = 1.0; + controller_->reference_interfaces_[2] = 1.0; + + ASSERT_EQ( + controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + std::vector expected_wheels_vel_cmds = {-15.0, 5.0, 5.0, -15.0}; + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_DOUBLE_EQ(command_itfs_[i].get_optional().value(), expected_wheels_vel_cmds[i]); + } + + // Now check that the command interfaces are set to 0.0 on deactivation + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + state = controller_->get_node()->deactivate(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + // cleanup + state = controller_->get_node()->cleanup(); + ASSERT_EQ(State::PRIMARY_STATE_UNCONFIGURED, state.id()); + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + executor.cancel(); +} + +// Make sure that the controller is properly reset when deactivated +// and accepts new commands as expected when it is activated again. +TEST_F(OmniWheelDriveControllerTest, deactivate_then_activate) +{ + ASSERT_EQ(InitController(), controller_interface::return_type::OK); + // choose radius = 1 so that the command values (rev/s) are the same as the linear velocity (m/s) + + rclcpp::executors::SingleThreadedExecutor executor; + executor.add_node(controller_->get_node()->get_node_base_interface()); + + ASSERT_TRUE(controller_->set_chained_mode(false)); + + auto state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + assignResourcesPosFeedback(); + + state = controller_->get_node()->activate(); + ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); + + waitForSetup(); + + // Reference interfaces should be NaN on initialization + for (const auto & interface : controller_->reference_interfaces_) + { + EXPECT_TRUE(std::isnan(interface)); + } + // But NaNs should not propagate to command interfaces + for (size_t i = 0; i < command_itfs_.size(); i++) + { + ASSERT_FALSE(std::isnan(command_itfs_[i].get_optional().value())); + } + + // Now check that a timely published command message sets the command interfaces to the correct + // values + publish_twist(); + // wait for msg is be published to the system + controller_->wait_for_twist(executor); + + ASSERT_EQ( + controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + std::vector expected_wheels_vel_cmds = {-15.0, 5.0, 5.0, -15.0}; + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_DOUBLE_EQ(command_itfs_[i].get_optional().value(), expected_wheels_vel_cmds[i]); + } + + // Now check that the command interfaces are set to 0.0 on deactivation + // (despite calls to update()) + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + state = controller_->get_node()->deactivate(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); + ASSERT_EQ( + controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + // Activate again + state = controller_->get_node()->activate(); + ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); + + waitForSetup(); + + for (const auto & interface : controller_->reference_interfaces_) + { + EXPECT_TRUE(std::isnan(interface)) + << "Reference interfaces should initially be NaN on activation"; + } + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + // A new command should work as expected + publish_twist(); + controller_->wait_for_twist(executor); + + ASSERT_EQ( + controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_DOUBLE_EQ(command_itfs_[i].get_optional().value(), expected_wheels_vel_cmds[i]); + } + + // Deactivate again and cleanup + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + state = controller_->get_node()->deactivate(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); + state = controller_->get_node()->cleanup(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_UNCONFIGURED); + executor.cancel(); +} + +TEST_F(OmniWheelDriveControllerTest, command_with_zero_timestamp_is_accepted_with_warning) +{ + ASSERT_EQ(InitController(), controller_interface::return_type::OK); + + rclcpp::executors::SingleThreadedExecutor executor; + executor.add_node(controller_->get_node()->get_node_base_interface()); + + ASSERT_TRUE(controller_->set_chained_mode(false)); + + auto state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + assignResourcesPosFeedback(); + + state = controller_->get_node()->activate(); + ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); + + waitForSetup(); + + // published command message with zero timestamp sets the command interfaces to the correct values + publish_twist_timestamped(rclcpp::Time(0, 0, RCL_ROS_TIME)); + // wait for msg is be published to the system + controller_->wait_for_twist(executor); + + ASSERT_EQ( + controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + std::vector expected_wheels_vel_cmds = {-15.0, 5.0, 5.0, -15.0}; + for (size_t i = 0; i < command_itfs_.size(); i++) + { + EXPECT_DOUBLE_EQ(command_itfs_[i].get_optional().value(), expected_wheels_vel_cmds[i]); + } + + // Deactivate and cleanup + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + state = controller_->get_node()->deactivate(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); + state = controller_->get_node()->cleanup(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_UNCONFIGURED); + executor.cancel(); +} + +TEST_F(OmniWheelDriveControllerTest, 3_wheel_test) +{ + ASSERT_EQ( + InitController({"wheel_1", "wheel_2", "wheel_3"}, 0.0), controller_interface::return_type::OK); + + rclcpp::executors::SingleThreadedExecutor executor; + executor.add_node(controller_->get_node()->get_node_base_interface()); + + auto state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + wheels_pos_states_ = {1, 1, 1}; + wheels_vel_states_ = {1, 1, 1}; + wheels_vel_cmds_ = {0.1, 0.2, 0.3}; + assignResourcesPosFeedback({"wheel_1", "wheel_2", "wheel_3"}); + + state = controller_->get_node()->activate(); + ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); + + waitForSetup(); + + // Reference interfaces should be NaN on initialization + for (const auto & interface : controller_->reference_interfaces_) + { + EXPECT_TRUE(std::isnan(interface)); + } + // But NaNs should not propagate to command interfaces + for (size_t i = 0; i < 3; i++) + { + ASSERT_FALSE(std::isnan(command_itfs_[i].get_optional().value())); + } + + // Check that a published command msg sets the command interfaces to the correct values + publish_twist(); + // wait for msg to be published to the system + controller_->wait_for_twist(executor); + + ASSERT_EQ( + controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + std::vector expected_wheels_vel_cmds = {-15.0, 8.66025, -8.66025}; + for (size_t i = 0; i < 3; i++) + { + EXPECT_NEAR(command_itfs_[i].get_optional().value(), expected_wheels_vel_cmds[i], 0.0001); + } + + // Now check that the command interfaces are set to 0.0 on deactivation + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + state = controller_->get_node()->deactivate(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); + for (size_t i = 0; i < 3; i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + // cleanup + state = controller_->get_node()->cleanup(); + ASSERT_EQ(State::PRIMARY_STATE_UNCONFIGURED, state.id()); + for (size_t i = 0; i < 3; i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + executor.cancel(); +} + +TEST_F(OmniWheelDriveControllerTest, 3_wheel_rot_test) +{ + ASSERT_EQ( + InitController({"wheel_1", "wheel_2", "wheel_3"}, 1.0471975512), + controller_interface::return_type::OK); + + rclcpp::executors::SingleThreadedExecutor executor; + executor.add_node(controller_->get_node()->get_node_base_interface()); + + auto state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + wheels_pos_states_ = {1, 1, 1}; + wheels_vel_states_ = {1, 1, 1}; + wheels_vel_cmds_ = {0.1, 0.2, 0.3}; + assignResourcesPosFeedback({"wheel_1", "wheel_2", "wheel_3"}); + + state = controller_->get_node()->activate(); + ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); + + waitForSetup(); + + // Reference interfaces should be NaN on initialization + for (const auto & interface : controller_->reference_interfaces_) + { + EXPECT_TRUE(std::isnan(interface)); + } + // But NaNs should not propagate to command interfaces + for (size_t i = 0; i < 3; i++) + { + ASSERT_FALSE(std::isnan(command_itfs_[i].get_optional().value())); + } + + // Check that a published command msg sets the command interfaces to the correct values + publish_twist(); + // wait for msg to be published to the system + controller_->wait_for_twist(executor); + + ASSERT_EQ( + controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + std::vector expected_wheels_vel_cmds = {-1.33975, 5.0, -18.6603}; + for (size_t i = 0; i < 3; i++) + { + EXPECT_NEAR(command_itfs_[i].get_optional().value(), expected_wheels_vel_cmds[i], 0.0001); + } + + // Now check that the command interfaces are set to 0.0 on deactivation + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + state = controller_->get_node()->deactivate(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); + for (size_t i = 0; i < 3; i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + // cleanup + state = controller_->get_node()->cleanup(); + ASSERT_EQ(State::PRIMARY_STATE_UNCONFIGURED, state.id()); + for (size_t i = 0; i < 3; i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + executor.cancel(); +} + +TEST_F(OmniWheelDriveControllerTest, 4_wheel_rot_test) +{ + ASSERT_EQ( + InitController({"wheel_1", "wheel_2", "wheel_3", "wheel_4"}, 0.7853981634), + controller_interface::return_type::OK); + + rclcpp::executors::SingleThreadedExecutor executor; + executor.add_node(controller_->get_node()->get_node_base_interface()); + + auto state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + wheels_pos_states_ = {1, 1, 1, 1}; + wheels_vel_states_ = {1, 1, 1, 1}; + wheels_vel_cmds_ = {0.1, 0.2, 0.3, 0.4}; + assignResourcesPosFeedback({"wheel_1", "wheel_2", "wheel_3", "wheel_4"}); + + state = controller_->get_node()->activate(); + ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); + + waitForSetup(); + + // Reference interfaces should be NaN on initialization + for (const auto & interface : controller_->reference_interfaces_) + { + EXPECT_TRUE(std::isnan(interface)); + } + // But NaNs should not propagate to command interfaces + for (size_t i = 0; i < 4; i++) + { + ASSERT_FALSE(std::isnan(command_itfs_[i].get_optional().value())); + } + + // Check that a published command msg sets the command interfaces to the correct values + publish_twist(); + // wait for msg to be published to the system + controller_->wait_for_twist(executor); + + ASSERT_EQ( + controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + std::vector expected_wheels_vel_cmds = {-5.0, 9.14214, -5.0, -19.1421}; + for (size_t i = 0; i < 4; i++) + { + EXPECT_NEAR(command_itfs_[i].get_optional().value(), expected_wheels_vel_cmds[i], 0.0001); + } + + // Now check that the command interfaces are set to 0.0 on deactivation + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + state = controller_->get_node()->deactivate(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); + for (size_t i = 0; i < 4; i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + // cleanup + state = controller_->get_node()->cleanup(); + ASSERT_EQ(State::PRIMARY_STATE_UNCONFIGURED, state.id()); + for (size_t i = 0; i < 4; i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + executor.cancel(); +} + +TEST_F(OmniWheelDriveControllerTest, 5_wheel_test) +{ + ASSERT_EQ( + InitController({"wheel_1", "wheel_2", "wheel_3", "wheel_4", "wheel_5"}, 0.0), + controller_interface::return_type::OK); + + rclcpp::executors::SingleThreadedExecutor executor; + executor.add_node(controller_->get_node()->get_node_base_interface()); + + auto state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + wheels_pos_states_ = {1, 1, 1, 1, 1}; + wheels_vel_states_ = {1, 1, 1, 1, 1}; + wheels_vel_cmds_ = {0.1, 0.2, 0.3, 0.4, 0.5}; + assignResourcesPosFeedback({"wheel_1", "wheel_2", "wheel_3", "wheel_4", "wheel_5"}); + + state = controller_->get_node()->activate(); + ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); + + waitForSetup(); + + // Reference interfaces should be NaN on initialization + for (const auto & interface : controller_->reference_interfaces_) + { + EXPECT_TRUE(std::isnan(interface)); + } + // But NaNs should not propagate to command interfaces + for (size_t i = 0; i < 5; i++) + { + ASSERT_FALSE(std::isnan(command_itfs_[i].get_optional().value())); + } + + // Check that a published command msg sets the command interfaces to the correct values + publish_twist(); + // wait for msg to be published to the system + controller_->wait_for_twist(executor); + + ASSERT_EQ( + controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + std::vector expected_wheels_vel_cmds = {-15.0, 1.42040, 8.96802, -2.78768, -17.6007}; + for (size_t i = 0; i < 5; i++) + { + EXPECT_NEAR(command_itfs_[i].get_optional().value(), expected_wheels_vel_cmds[i], 0.0001); + } + + // Now check that the command interfaces are set to 0.0 on deactivation + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + state = controller_->get_node()->deactivate(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); + for (size_t i = 0; i < 5; i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + // cleanup + state = controller_->get_node()->cleanup(); + ASSERT_EQ(State::PRIMARY_STATE_UNCONFIGURED, state.id()); + for (size_t i = 0; i < 5; i++) + { + EXPECT_EQ(command_itfs_[i].get_optional().value(), 0.0); + } + + state = controller_->get_node()->configure(); + ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + executor.cancel(); +} + +int main(int argc, char ** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + rclcpp::init(argc, argv); + int result = RUN_ALL_TESTS(); + rclcpp::shutdown(); + return result; +} diff --git a/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.hpp b/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.hpp new file mode 100644 index 0000000000..4443af04f3 --- /dev/null +++ b/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.hpp @@ -0,0 +1,247 @@ +// Copyright 2025 Aarav Gupta +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef TEST_OMNI_WHEEL_DRIVE_CONTROLLER_HPP_ +#define TEST_OMNI_WHEEL_DRIVE_CONTROLLER_HPP_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "hardware_interface/handle.hpp" +#include "hardware_interface/loaned_command_interface.hpp" +#include "hardware_interface/loaned_state_interface.hpp" +#include "hardware_interface/types/hardware_interface_type_values.hpp" +#include "omni_wheel_drive_controller/omni_wheel_drive_controller.hpp" +#include "rclcpp/executor.hpp" +#include "rclcpp/executors.hpp" +#include "rclcpp/parameter_value.hpp" +#include "rclcpp/time.hpp" +#include "rclcpp/utilities.hpp" + +using hardware_interface::HW_IF_POSITION; +using hardware_interface::HW_IF_VELOCITY; + +namespace +{ +constexpr auto NODE_SUCCESS = controller_interface::CallbackReturn::SUCCESS; +constexpr auto NODE_ERROR = controller_interface::CallbackReturn::ERROR; +std::vector wheel_names_ = { + "front_wheel_joint", "left_wheel_joint", "back_wheel_joint", "right_wheel_joint"}; +} // namespace + +// subclassing and friending so we can access member variables +class TestableOmniWheelDriveController +: public omni_wheel_drive_controller::OmniWheelDriveController +{ + FRIEND_TEST(OmniWheelDriveControllerTest, configure_succeeds_tf_test_prefix_false_no_namespace); + FRIEND_TEST(OmniWheelDriveControllerTest, configure_succeeds_tf_test_prefix_true_no_namespace); + FRIEND_TEST(OmniWheelDriveControllerTest, configure_succeeds_tf_blank_prefix_true_no_namespace); + FRIEND_TEST(OmniWheelDriveControllerTest, configure_succeeds_tf_test_prefix_false_set_namespace); + FRIEND_TEST(OmniWheelDriveControllerTest, configure_succeeds_tf_test_prefix_true_set_namespace); + FRIEND_TEST(OmniWheelDriveControllerTest, configure_succeeds_tf_blank_prefix_true_set_namespace); + FRIEND_TEST(OmniWheelDriveControllerTest, cleanup); + FRIEND_TEST(OmniWheelDriveControllerTest, chainable_controller_unchained_mode); + FRIEND_TEST(OmniWheelDriveControllerTest, chainable_controller_chained_mode); + FRIEND_TEST(OmniWheelDriveControllerTest, deactivate_then_activate); + FRIEND_TEST(OmniWheelDriveControllerTest, command_with_zero_timestamp_is_accepted_with_warning); + FRIEND_TEST(OmniWheelDriveControllerTest, 3_wheel_test); + FRIEND_TEST(OmniWheelDriveControllerTest, 3_wheel_rot_test); + FRIEND_TEST(OmniWheelDriveControllerTest, 4_wheel_rot_test); + FRIEND_TEST(OmniWheelDriveControllerTest, 5_wheel_test); + + /** + * @brief wait_for_twist block until a new twist is received. + * Requires that the executor is not spinned elsewhere between the + * message publication and the call to this function + */ + void wait_for_twist( + rclcpp::Executor & executor, + const std::chrono::milliseconds & timeout = std::chrono::milliseconds(500)) + { + auto until = get_node()->get_clock()->now() + timeout; + while (get_node()->get_clock()->now() < until) + { + executor.spin_some(); + std::this_thread::sleep_for(std::chrono::microseconds(10)); + } + } +}; + +// We are using template class here for easier reuse of Fixture in specializations of controllers +template +class OmniWheelDriveControllerFixture : public ::testing::Test +{ +public: + void SetUp() + { + // Initialize controller + controller_ = std::make_unique(); + + cmd_vel_publisher_node_ = std::make_shared("cmd_vel_publisher"); + cmd_vel_publisher_ = + cmd_vel_publisher_node_->create_publisher( + "/test_omni_wheel_drive_controller/cmd_vel", rclcpp::SystemDefaultsQoS()); + } + + static void TearDownTestCase() { rclcpp::shutdown(); } + +protected: + void publish_twist(double linear_x = 1.0, double linear_y = 1.0, double angular = 1.0) + { + publish_twist_timestamped( + cmd_vel_publisher_node_->get_clock()->now(), linear_x, linear_y, angular); + } + + void publish_twist_timestamped( + const rclcpp::Time & stamp, const double & twist_linear_x = 1.0, + const double & twist_linear_y = 1.0, const double & twist_angular_z = 1.0) + { + const char * topic_name = cmd_vel_publisher_->get_topic_name(); + size_t wait_count = 0; + while (cmd_vel_publisher_node_->count_subscribers(topic_name) == 0) + { + if (wait_count >= 5) + { + auto error_msg = + std::string("publishing to ") + topic_name + " but no node subscribes to it"; + throw std::runtime_error(error_msg); + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + ++wait_count; + } + + geometry_msgs::msg::TwistStamped msg; + msg.header.stamp = stamp; + msg.twist.linear.x = twist_linear_x; + msg.twist.linear.y = twist_linear_y; + msg.twist.linear.z = std::numeric_limits::quiet_NaN(); + msg.twist.angular.x = std::numeric_limits::quiet_NaN(); + msg.twist.angular.y = std::numeric_limits::quiet_NaN(); + msg.twist.angular.z = twist_angular_z; + + cmd_vel_publisher_->publish(msg); + } + + /// \brief wait for the subscriber and publisher to completely setup + void waitForSetup() + { + constexpr std::chrono::seconds TIMEOUT{2}; + auto clock = cmd_vel_publisher_node_->get_clock(); + auto start = clock->now(); + while (cmd_vel_publisher_->get_subscription_count() <= 0) + { + if ((clock->now() - start) > TIMEOUT) + { + FAIL(); + } + rclcpp::spin_some(cmd_vel_publisher_node_); + } + } + + void assignResourcesPosFeedback(const std::vector wheel_names = wheel_names_) + { + std::vector state_ifs; + state_ifs.reserve(wheels_pos_states_.size()); + state_itfs_.reserve(wheels_pos_states_.size()); + for (size_t i = 0; i < wheels_pos_states_.size(); ++i) + { + state_itfs_.emplace_back( + hardware_interface::StateInterface(wheel_names[i], HW_IF_POSITION, &wheels_pos_states_[i])); + state_ifs.emplace_back(state_itfs_.back()); + } + + std::vector command_ifs; + command_ifs.reserve(wheels_vel_cmds_.size()); + command_itfs_.reserve(wheels_vel_cmds_.size()); + for (size_t i = 0; i < wheels_vel_cmds_.size(); ++i) + { + command_itfs_.emplace_back( + hardware_interface::CommandInterface(wheel_names[i], HW_IF_VELOCITY, &wheels_vel_cmds_[i])); + command_ifs.emplace_back(command_itfs_.back()); + } + + controller_->assign_interfaces(std::move(command_ifs), std::move(state_ifs)); + } + + void assignResourcesVelFeedback() + { + std::vector state_ifs; + state_ifs.reserve(wheels_vel_states_.size()); + state_itfs_.reserve(wheels_vel_states_.size()); + for (size_t i = 0; i < wheels_vel_states_.size(); ++i) + { + state_itfs_.emplace_back( + hardware_interface::StateInterface( + wheel_names_[i], HW_IF_VELOCITY, &wheels_vel_states_[i])); + state_ifs.emplace_back(state_itfs_.back()); + } + + std::vector command_ifs; + command_ifs.reserve(wheels_vel_cmds_.size()); + command_itfs_.reserve(wheels_vel_cmds_.size()); + for (size_t i = 0; i < wheels_vel_cmds_.size(); ++i) + { + command_itfs_.emplace_back( + hardware_interface::CommandInterface( + wheel_names_[i], HW_IF_VELOCITY, &wheels_vel_cmds_[i])); + command_ifs.emplace_back(command_itfs_.back()); + } + + controller_->assign_interfaces(std::move(command_ifs), std::move(state_ifs)); + } + + controller_interface::return_type InitController( + const std::vector wheel_joints_init = wheel_names_, + const double wheel_offset = 0.0, const std::vector & parameters = {}, + const std::string ns = "") + { + auto node_options = rclcpp::NodeOptions(); + std::vector parameter_overrides; + + parameter_overrides.push_back( + rclcpp::Parameter("wheel_names", rclcpp::ParameterValue(wheel_joints_init))); + parameter_overrides.push_back( + rclcpp::Parameter("wheel_offset", rclcpp::ParameterValue(wheel_offset))); + parameter_overrides.push_back(rclcpp::Parameter("robot_radius", rclcpp::ParameterValue(0.5))); + parameter_overrides.push_back(rclcpp::Parameter("wheel_radius", rclcpp::ParameterValue(0.1))); + + parameter_overrides.insert(parameter_overrides.end(), parameters.begin(), parameters.end()); + node_options.parameter_overrides(parameter_overrides); + + return controller_->init(controller_name_, urdf_, 0, ns, node_options); + } + + std::vector wheels_pos_states_ = {1, 1, 1, 1}; + std::vector wheels_vel_states_ = {1, 1, 1, 1}; + std::vector wheels_vel_cmds_ = {0.1, 0.2, 0.3, 0.4}; + + std::vector state_itfs_; + std::vector command_itfs_; + + std::vector reference_interface_names = {"linear/x", "linear/y", "angular/z"}; + + std::unique_ptr controller_; + rclcpp::Node::SharedPtr cmd_vel_publisher_node_; + rclcpp::Publisher::SharedPtr cmd_vel_publisher_; + + const std::string urdf_ = ""; + std::string controller_name_ = "test_omni_wheel_drive_controller"; +}; + +#endif // TEST_OMNI_WHEEL_DRIVE_CONTROLLER_HPP_ diff --git a/ros2_controllers/doc/index.rst b/ros2_controllers/doc/index.rst index f785112944..f92d17702d 100644 --- a/ros2_controllers/doc/index.rst +++ b/ros2_controllers/doc/index.rst @@ -50,6 +50,10 @@ For more information of the ros2_control framework see `control.ros.org `__ - `API `__ - `ROS Index `__ + * - omni_wheel_drive_controller + - `Documentation `__ + - `API `__ + - `ROS Index `__ * - pid_controller - `Documentation `__ - `API `__ diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index c54790f664..160a1578a0 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -31,6 +31,7 @@ joint_state_broadcaster joint_trajectory_controller mecanum_drive_controller + omni_wheel_drive_controller parallel_gripper_controller pid_controller pose_broadcaster From 1cb934c5b475c0436f9f22d5feea6c68585e10cd Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Thu, 31 Jul 2025 08:50:32 +0100 Subject: [PATCH 051/108] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 3 + admittance_controller/CHANGELOG.rst | 5 + bicycle_steering_controller/CHANGELOG.rst | 3 + diff_drive_controller/CHANGELOG.rst | 3 + effort_controllers/CHANGELOG.rst | 3 + force_torque_sensor_broadcaster/CHANGELOG.rst | 3 + forward_command_controller/CHANGELOG.rst | 3 + gpio_controllers/CHANGELOG.rst | 3 + gps_sensor_broadcaster/CHANGELOG.rst | 3 + gripper_controllers/CHANGELOG.rst | 3 + imu_sensor_broadcaster/CHANGELOG.rst | 3 + joint_state_broadcaster/CHANGELOG.rst | 3 + joint_trajectory_controller/CHANGELOG.rst | 3 + mecanum_drive_controller/CHANGELOG.rst | 3 + omni_wheel_drive_controller/CHANGELOG.rst | 254 ++++++++++++++++++ omni_wheel_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 3 + pid_controller/CHANGELOG.rst | 3 + pose_broadcaster/CHANGELOG.rst | 3 + position_controllers/CHANGELOG.rst | 3 + range_sensor_broadcaster/CHANGELOG.rst | 3 + ros2_controllers/CHANGELOG.rst | 5 + ros2_controllers_test_nodes/CHANGELOG.rst | 3 + rqt_joint_trajectory_controller/CHANGELOG.rst | 3 + steering_controllers_library/CHANGELOG.rst | 3 + tricycle_controller/CHANGELOG.rst | 3 + tricycle_steering_controller/CHANGELOG.rst | 3 + velocity_controllers/CHANGELOG.rst | 3 + 28 files changed, 337 insertions(+), 1 deletion(-) create mode 100644 omni_wheel_drive_controller/CHANGELOG.rst diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index d8a3f4d71b..5deabfad9f 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 26f17b1256..19e9a1f471 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix `child_frame_id` in controller_state_msg (backport `#1601 `_) (`#1835 `_) +* Contributors: mergify[bot] + 4.29.0 (2025-07-23) ------------------- diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 3bbac76d07..2815ae2e3a 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 8a986641b3..4e9ce3505c 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 8e914382eb..b77c35ccba 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index c406e3af71..98b4a82e0c 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index ee28c46ad2..d543a511fc 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- * Reject non-finite values in forward controller subscriber callback (#… (backport `#1815 `_) (`#1817 `_) diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 30fa8ac6b1..b38d747adb 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 875c397ea7..bf6e0adbfa 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 49c4ba7067..a3ec0c898e 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index cbae8b752b..160bab1648 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 74f085b153..e9f44414ac 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 06519be5d9..287b731016 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 836f9dd940..6bec1f21dc 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst new file mode 100644 index 0000000000..24fb1a2d49 --- /dev/null +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -0,0 +1,254 @@ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Changelog for package omni_wheel_drive_controller +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Forthcoming +----------- +* Add omni_wheel_drive_controller (backport `#1535 `_) (`#1836 `_) +* Contributors: mergify[bot] + +4.29.0 (2025-07-23) +------------------- + +4.28.0 (2025-07-14) +------------------- + +4.27.1 (2025-07-02) +------------------- + +4.27.0 (2025-06-23) +------------------- + +4.26.0 (2025-06-06) +------------------- + +4.25.0 (2025-05-17) +------------------- + +4.24.0 (2025-04-27) +------------------- + +4.23.0 (2025-04-10) +------------------- + +4.22.0 (2025-03-17) +------------------- + +4.21.0 (2025-03-01) +------------------- + +4.20.0 (2025-01-29) +------------------- + +4.19.0 (2025-01-13) +------------------- + +4.18.0 (2024-12-19) +------------------- + +4.17.0 (2024-12-07) +------------------- + +4.16.0 (2024-11-08) +------------------- + +4.15.0 (2024-10-07) +------------------- + +4.14.0 (2024-09-11) +------------------- + +4.13.0 (2024-08-22) +------------------- + +4.12.1 (2024-08-14) +------------------- + +4.12.0 (2024-07-23) +------------------- + +4.11.0 (2024-07-09) +------------------- + +4.10.0 (2024-07-01) +------------------- + +4.9.0 (2024-06-05) +------------------ + +4.8.0 (2024-05-14) +------------------ + +4.7.0 (2024-03-22) +------------------ + +4.6.0 (2024-02-12) +------------------ + +4.5.0 (2024-01-31) +------------------ + +4.4.0 (2024-01-11) +------------------ + +4.3.0 (2024-01-08) +------------------ + +4.2.0 (2023-12-12) +------------------ + +4.1.0 (2023-12-01) +------------------ + +4.0.0 (2023-11-21) +------------------ + +3.17.0 (2023-10-31) +------------------- + +3.16.0 (2023-09-20) +------------------- + +3.15.0 (2023-09-11) +------------------- + +3.14.0 (2023-08-16) +------------------- + +3.13.0 (2023-08-04) +------------------- + +3.12.0 (2023-07-18) +------------------- + +3.11.0 (2023-06-24) +------------------- + +3.10.1 (2023-06-06) +------------------- + +3.10.0 (2023-06-04) +------------------- + +3.9.0 (2023-05-28) +------------------ + +3.8.0 (2023-05-14) +------------------ + +3.7.0 (2023-05-02) +------------------ + +3.6.0 (2023-04-29) +------------------ + +3.5.0 (2023-04-14) +------------------ + +3.4.0 (2023-04-02) +------------------ + +3.3.0 (2023-03-07) +------------------ + +3.2.0 (2023-02-10) +------------------ + +3.1.0 (2023-01-26) +------------------ + +3.0.0 (2023-01-19) +------------------ + +2.15.0 (2022-12-06) +------------------- + +2.14.0 (2022-11-18) +------------------- + +2.13.0 (2022-10-05) +------------------- + +2.12.0 (2022-09-01) +------------------- + +2.11.0 (2022-08-04) +------------------- + +2.10.0 (2022-08-01) +------------------- + +2.9.0 (2022-07-14) +------------------ + +2.8.0 (2022-07-09) +------------------ + +2.7.0 (2022-07-03) +------------------ + +2.6.0 (2022-06-18) +------------------ + +2.5.0 (2022-05-13) +------------------ + +2.4.0 (2022-04-29) +------------------ + +2.3.0 (2022-04-21) +------------------ + +2.2.0 (2022-03-25) +------------------ + +2.1.0 (2022-02-23) +------------------ + +2.0.1 (2022-02-01) +------------------ + +2.0.0 (2022-01-28) +------------------ + +1.3.0 (2022-01-11) +------------------ + +1.2.0 (2021-12-29) +------------------ + +1.1.0 (2021-10-25) +------------------ + +1.0.0 (2021-09-29) +------------------ + +0.5.0 (2021-08-30) +------------------ + +0.4.1 (2021-07-08) +------------------ + +0.4.0 (2021-06-28) +------------------ + +0.3.1 (2021-05-23) +------------------ + +0.3.0 (2021-05-21) +------------------ + +0.2.1 (2021-05-03) +------------------ + +0.2.0 (2021-02-06) +------------------ + +0.1.2 (2021-01-07) +------------------ + +0.1.1 (2021-01-06) +------------------ + +0.1.0 (2020-12-23) +------------------ diff --git a/omni_wheel_drive_controller/package.xml b/omni_wheel_drive_controller/package.xml index 83be9d5773..8e675dd182 100644 --- a/omni_wheel_drive_controller/package.xml +++ b/omni_wheel_drive_controller/package.xml @@ -2,7 +2,7 @@ omni_wheel_drive_controller - 0.0.0 + 4.29.0 A chainable controller for mobile robots with omnidirectional drive with three or more omni wheels. Apache License 2.0 diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 4b73768508..039929c0c4 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index d5d30fb287..22a1d041cd 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- * Apply API change of PidROS (backport `#1823 `_) (`#1826 `_) diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 08394152a3..8997a59adc 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 7e87f3a49a..6b16ec97dd 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index c61954cabc..bfae5093f2 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 7dac018184..a2712968bd 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Add omni_wheel_drive_controller (backport `#1535 `_) (`#1836 `_) +* Contributors: mergify[bot] + 4.29.0 (2025-07-23) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 39ec6797e6..653cf63674 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 91923edee5..7ffbcd6d6f 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 5945f6f820..3fe24e276d 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index c21fe0973f..009b33ff8a 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index c944a226a4..24aa20aebe 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 3419e06f8d..c1840a954f 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.29.0 (2025-07-23) ------------------- From abb30b616c5775031849ee98ce9116bf31f334b9 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Thu, 31 Jul 2025 08:50:47 +0100 Subject: [PATCH 052/108] 4.30.0 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- omni_wheel_drive_controller/CHANGELOG.rst | 4 ++-- omni_wheel_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 56 files changed, 83 insertions(+), 83 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 5deabfad9f..165e3b87c2 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index aa9b468001..f9eaf63dbb 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.29.0 + 4.30.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 19e9a1f471..1dc43336f9 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- * Fix `child_frame_id` in controller_state_msg (backport `#1601 `_) (`#1835 `_) * Contributors: mergify[bot] diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index 67bbe133ca..f60222e61a 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.29.0 + 4.30.0 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 2815ae2e3a..461c53f32c 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index af7e5eff5c..f3dbb8ab50 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.29.0 + 4.30.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 4e9ce3505c..7835dac301 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 7a63635b17..a028875ffb 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.29.0 + 4.30.0 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index b77c35ccba..0612cdc2b2 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index a4394c4685..b6dd1d3577 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.29.0 + 4.30.0 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 98b4a82e0c..518c73fea6 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index fd3bfb2a32..07e0be5a54 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.29.0 + 4.30.0 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index d543a511fc..4d9a31419d 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index 4dc5eecfe5..ce7c562d0d 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.29.0 + 4.30.0 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index b38d747adb..927588e845 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index fda492ea46..84a1de54e5 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.29.0 + 4.30.0 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index bf6e0adbfa..63ef9d1be0 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index 7f8a70ffe0..65e9c39c1c 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.29.0 + 4.30.0 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index a3ec0c898e..3b01075581 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index 8bdf1aa174..aa5dbf42c9 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.29.0 + 4.30.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 160bab1648..9bb42f1da0 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index fb13cc3d52..be448803fa 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.29.0 + 4.30.0 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index e9f44414ac..266cc648e0 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index 9e138fe316..de4c78dc08 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.29.0 + 4.30.0 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 287b731016..f93a1bc010 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index be1b813350..fbf18d894f 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.29.0 + 4.30.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 6bec1f21dc..5517d54f1d 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index 75820cf858..9ae2503dcf 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.29.0 + 4.30.0 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst index 24fb1a2d49..159ad9e398 100644 --- a/omni_wheel_drive_controller/CHANGELOG.rst +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package omni_wheel_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- * Add omni_wheel_drive_controller (backport `#1535 `_) (`#1836 `_) * Contributors: mergify[bot] diff --git a/omni_wheel_drive_controller/package.xml b/omni_wheel_drive_controller/package.xml index 8e675dd182..867c504eb6 100644 --- a/omni_wheel_drive_controller/package.xml +++ b/omni_wheel_drive_controller/package.xml @@ -2,7 +2,7 @@ omni_wheel_drive_controller - 4.29.0 + 4.30.0 A chainable controller for mobile robots with omnidirectional drive with three or more omni wheels. Apache License 2.0 diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 039929c0c4..8942e3fff3 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index 2ffa2a3422..2c5d5ea155 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.29.0 + 4.30.0 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 22a1d041cd..38184cba98 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/pid_controller/package.xml b/pid_controller/package.xml index 9ac2942e27..7e99c3975f 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.29.0 + 4.30.0 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 8997a59adc..42d8557571 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index 8dad516398..bb3e2b243e 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.29.0 + 4.30.0 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 6b16ec97dd..50f7800727 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index 6af00af94f..8468e406fe 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.29.0 + 4.30.0 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index bfae5093f2..a8f1304420 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index ad2c10ccc0..938ebe5f17 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.29.0 + 4.30.0 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index a2712968bd..14ff7a1039 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- * Add omni_wheel_drive_controller (backport `#1535 `_) (`#1836 `_) * Contributors: mergify[bot] diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 160a1578a0..94d7854a79 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.29.0 + 4.30.0 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 653cf63674..77bfe67674 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 9be003f2fd..04d387de7b 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.29.0 + 4.30.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index c6a83528cb..f98f7827b3 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.29.0", + version="4.30.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 7ffbcd6d6f..5bc7b4cb6a 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 370efe063a..8edf2694fd 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.29.0 + 4.30.0 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index 542915ac7b..a6917ad510 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.29.0", + version="4.30.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 3fe24e276d..0047990a8f 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index 5998564837..fe33900055 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.29.0 + 4.30.0 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 009b33ff8a..c377a93e2c 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index 866f4f715e..661357830f 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.29.0 + 4.30.0 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 24aa20aebe..499ec8f7f4 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index c301d08964..3cd85bdefb 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.29.0 + 4.30.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index c1840a954f..4738f058e5 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.0 (2025-07-31) +------------------- 4.29.0 (2025-07-23) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index e09cb9375e..acd42305c6 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.29.0 + 4.30.0 Generic controller for forwarding commands. Bence Magyar From d53db23aa1ef2c32f6983422c1266a8f8ea5cf59 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 31 Jul 2025 15:22:45 +0200 Subject: [PATCH 053/108] Reset JTC PID's to zero on_activate() (backport #1840) (#1844) Co-authored-by: Marq Rasmussen --- .../src/joint_trajectory_controller.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index dfcbc02d76..a08a16e422 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -1032,6 +1032,11 @@ controller_interface::CallbackReturn JointTrajectoryController::on_activate( read_state_from_state_interfaces(state_current_); read_state_from_state_interfaces(last_commanded_state_); } + // reset/zero out all of the PID's (The integral term is not retained and reset to zero) + for (auto & pid : pids_) + { + pid->reset(); + } last_commanded_time_ = rclcpp::Time(); // The controller should start by holding position at the beginning of active state From bf5e07c9baa2ce9feb0eb66b84825347687a79a3 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 1 Aug 2025 13:02:21 +0200 Subject: [PATCH 054/108] Bump version of pre-commit hooks (backport #1846) (#1848) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6cd97bd075..9e5474800f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -64,7 +64,7 @@ repos: # CPP hooks - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v20.1.7 + rev: v20.1.8 hooks: - id: clang-format args: ['-fallback-style=none', '-i'] @@ -134,7 +134,7 @@ repos: exclude: CHANGELOG\.rst|\.(svg|pyc|drawio)$ - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.33.1 + rev: 0.33.2 hooks: - id: check-github-workflows args: ["--verbose"] From de710f4696d803003654726f95bdb04406d53bec Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Sun, 3 Aug 2025 06:58:44 +0100 Subject: [PATCH 055/108] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 3 +++ admittance_controller/CHANGELOG.rst | 3 +++ bicycle_steering_controller/CHANGELOG.rst | 3 +++ diff_drive_controller/CHANGELOG.rst | 3 +++ effort_controllers/CHANGELOG.rst | 3 +++ force_torque_sensor_broadcaster/CHANGELOG.rst | 3 +++ forward_command_controller/CHANGELOG.rst | 3 +++ gpio_controllers/CHANGELOG.rst | 3 +++ gps_sensor_broadcaster/CHANGELOG.rst | 3 +++ gripper_controllers/CHANGELOG.rst | 3 +++ imu_sensor_broadcaster/CHANGELOG.rst | 3 +++ joint_state_broadcaster/CHANGELOG.rst | 3 +++ joint_trajectory_controller/CHANGELOG.rst | 5 +++++ mecanum_drive_controller/CHANGELOG.rst | 3 +++ omni_wheel_drive_controller/CHANGELOG.rst | 3 +++ parallel_gripper_controller/CHANGELOG.rst | 3 +++ pid_controller/CHANGELOG.rst | 3 +++ pose_broadcaster/CHANGELOG.rst | 3 +++ position_controllers/CHANGELOG.rst | 3 +++ range_sensor_broadcaster/CHANGELOG.rst | 3 +++ ros2_controllers/CHANGELOG.rst | 3 +++ ros2_controllers_test_nodes/CHANGELOG.rst | 3 +++ rqt_joint_trajectory_controller/CHANGELOG.rst | 3 +++ steering_controllers_library/CHANGELOG.rst | 3 +++ tricycle_controller/CHANGELOG.rst | 3 +++ tricycle_steering_controller/CHANGELOG.rst | 3 +++ velocity_controllers/CHANGELOG.rst | 3 +++ 27 files changed, 83 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 165e3b87c2..e000429d00 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 1dc43336f9..7054dc2d92 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- * Fix `child_frame_id` in controller_state_msg (backport `#1601 `_) (`#1835 `_) diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 461c53f32c..38985ab61d 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 7835dac301..14f3e552aa 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 0612cdc2b2..55da30f611 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 518c73fea6..29603ce037 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 4d9a31419d..8fec9aea6e 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 927588e845..c73a9309f3 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 63ef9d1be0..c148dc099e 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 3b01075581..3797f34c31 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 9bb42f1da0..ed8d52273f 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 266cc648e0..cd1f66c7b6 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index f93a1bc010..bde24d02fb 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Reset JTC PID's to zero on_activate() (backport `#1840 `_) (`#1844 `_) +* Contributors: mergify[bot] + 4.30.0 (2025-07-31) ------------------- diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 5517d54f1d..7d449fb51f 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst index 159ad9e398..35404fd73e 100644 --- a/omni_wheel_drive_controller/CHANGELOG.rst +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package omni_wheel_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- * Add omni_wheel_drive_controller (backport `#1535 `_) (`#1836 `_) diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 8942e3fff3..2ae7aa079c 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 38184cba98..f6c68ac60f 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 42d8557571..f17574e1ba 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 50f7800727..b625942b35 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index a8f1304420..41204878c8 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 14ff7a1039..5e362fd974 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- * Add omni_wheel_drive_controller (backport `#1535 `_) (`#1836 `_) diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 77bfe67674..48a1324d76 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 5bc7b4cb6a..13053a37b7 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 0047990a8f..7c16a8f67d 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index c377a93e2c..81424a1f3a 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 499ec8f7f4..31ae003484 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 4738f058e5..1712f7b778 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.0 (2025-07-31) ------------------- From 61f26b126878e98a1fdf5acd263c3f06f13c9ceb Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Sun, 3 Aug 2025 06:59:34 +0100 Subject: [PATCH 056/108] 4.30.1 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- omni_wheel_drive_controller/CHANGELOG.rst | 4 ++-- omni_wheel_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 56 files changed, 83 insertions(+), 83 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index e000429d00..2d722d58d4 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index f9eaf63dbb..dac4f55532 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.30.0 + 4.30.1 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 7054dc2d92..f44bf50af5 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index f60222e61a..a40ab5b28d 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.30.0 + 4.30.1 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 38985ab61d..999cd1fbb3 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index f3dbb8ab50..639a597fd8 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.30.0 + 4.30.1 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 14f3e552aa..52ce1f1e58 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index a028875ffb..9c2f32667c 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.30.0 + 4.30.1 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 55da30f611..77d1204791 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index b6dd1d3577..7e33398a89 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.30.0 + 4.30.1 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 29603ce037..f95ccb6a51 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 07e0be5a54..879cdd6231 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.30.0 + 4.30.1 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 8fec9aea6e..50b41a94c0 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index ce7c562d0d..e6ba255368 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.30.0 + 4.30.1 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index c73a9309f3..65b45a580b 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index 84a1de54e5..c90436832e 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.30.0 + 4.30.1 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index c148dc099e..d3c8fc0131 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index 65e9c39c1c..471517f354 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.30.0 + 4.30.1 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 3797f34c31..b6acda19b2 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index aa5dbf42c9..512c5a96be 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.30.0 + 4.30.1 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index ed8d52273f..26b962ec70 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index be448803fa..cdd63e400f 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.30.0 + 4.30.1 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index cd1f66c7b6..2d727fd1dc 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index de4c78dc08..1481e13f27 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.30.0 + 4.30.1 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index bde24d02fb..ccd56baefe 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- * Reset JTC PID's to zero on_activate() (backport `#1840 `_) (`#1844 `_) * Contributors: mergify[bot] diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index fbf18d894f..0291d13f87 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.30.0 + 4.30.1 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 7d449fb51f..136ed6ecb5 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index 9ae2503dcf..a9b0f67cd4 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.30.0 + 4.30.1 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst index 35404fd73e..04648a8a4a 100644 --- a/omni_wheel_drive_controller/CHANGELOG.rst +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package omni_wheel_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/omni_wheel_drive_controller/package.xml b/omni_wheel_drive_controller/package.xml index 867c504eb6..651ed3955e 100644 --- a/omni_wheel_drive_controller/package.xml +++ b/omni_wheel_drive_controller/package.xml @@ -2,7 +2,7 @@ omni_wheel_drive_controller - 4.30.0 + 4.30.1 A chainable controller for mobile robots with omnidirectional drive with three or more omni wheels. Apache License 2.0 diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 2ae7aa079c..4cf68b6ab7 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index 2c5d5ea155..a68f27e7fc 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.30.0 + 4.30.1 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index f6c68ac60f..9cfde333e4 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/pid_controller/package.xml b/pid_controller/package.xml index 7e99c3975f..c9a1549d93 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.30.0 + 4.30.1 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index f17574e1ba..0de2be084b 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index bb3e2b243e..58d390c0a8 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.30.0 + 4.30.1 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index b625942b35..0cbb0fa82d 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index 8468e406fe..f3e9d3cde1 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.30.0 + 4.30.1 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 41204878c8..f71fdcce11 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index 938ebe5f17..abf54ce207 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.30.0 + 4.30.1 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 5e362fd974..680010b80d 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 94d7854a79..fabfe644f9 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.30.0 + 4.30.1 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 48a1324d76..59abdf1a7f 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 04d387de7b..8000b48e9c 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.30.0 + 4.30.1 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index f98f7827b3..f6ac0ebd42 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.30.0", + version="4.30.1", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 13053a37b7..614b8cddfb 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 8edf2694fd..9dedd838b8 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.30.0 + 4.30.1 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index a6917ad510..c41703fd03 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.30.0", + version="4.30.1", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 7c16a8f67d..4710c13da8 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index fe33900055..314df0f4c5 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.30.0 + 4.30.1 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 81424a1f3a..adf7cecd39 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index 661357830f..693b3b61b4 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.30.0 + 4.30.1 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 31ae003484..48b69b20b4 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index 3cd85bdefb..bd0a7142d8 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.30.0 + 4.30.1 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 1712f7b778..ab9dd54dd4 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.30.1 (2025-08-03) +------------------- 4.30.0 (2025-07-31) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index acd42305c6..23ef4df6a3 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.30.0 + 4.30.1 Generic controller for forwarding commands. Bence Magyar From 28c94fd1ba24e901188714b90451204e8c7644ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Tue, 5 Aug 2025 12:15:12 +0200 Subject: [PATCH 057/108] Add deprecation notice of gripper_action_controller to docs (#1852) --- doc/migration.rst | 3 +++ doc/release_notes.rst | 9 ++++++++- gripper_controllers/doc/userdoc.rst | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/doc/migration.rst b/doc/migration.rst index cef475be0f..349bf110ce 100644 --- a/doc/migration.rst +++ b/doc/migration.rst @@ -4,6 +4,9 @@ Migration Guides: Humble to Jazzy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This list summarizes important changes between Humble (previous) and Jazzy (current) releases, where changes to user code might be necessary. +gripper_action_controller +***************************** +The ``effort_controllers/GripperActionController`` and ``position_controllers/GripperActionController`` will be removed. The ``parallel_gripper_action_controller/GripperActionController`` should be used instead. `(#1652 `__). diff_drive_controller ***************************** diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 075c1c7e53..9f79bbbc49 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -16,6 +16,10 @@ diff_drive_controller * Parameters ``has_velocity_limits``, ``has_acceleration_limits``, and ``has_jerk_limits`` are removed. Instead, set the respective limits to ``.NAN``. (`#1315 `_). * Parameters ``max_acceleration_reverse`` and ``max_deceleration_reverse`` were added to configure asymmetric acceleration/deceleration behavior. (`#1315 `_). +gripper_action_controller +***************************** +The ``effort_controllers/GripperActionController`` and ``position_controllers/GripperActionController`` will be removed. The ``parallel_gripper_action_controller/GripperActionController`` should be used instead. `(#1652 `__). + joint_trajectory_controller ***************************** @@ -56,11 +60,14 @@ joint_trajectory_controller * Parameter ``open_loop_control`` is replaced by ``interpolate_from_desired_state`` and setting the feedback gains to zero (`#1525 `_). * The controller now supports the new anti-windup strategy of the PID class, which allows for more flexible control of the anti-windup behavior. (`#1759 `__). - mecanum_drive_controller ************************ * 🚀 The mecanum_drive_controller was added 🎉 (`#512 `_). +parallel_gripper_action_controller +********************************** +The ``parallel_gripper_action_controller/GripperActionController`` was added. `(#1652 `__). + omni_wheel_drive_controller ********************************* * 🚀 The omni_wheel_drive_controller was added 🎉 (`#1535 `_). diff --git a/gripper_controllers/doc/userdoc.rst b/gripper_controllers/doc/userdoc.rst index 7f51c8f4ac..ffaeefca11 100644 --- a/gripper_controllers/doc/userdoc.rst +++ b/gripper_controllers/doc/userdoc.rst @@ -10,6 +10,10 @@ Controllers for executing a gripper command action for simple single-dof gripper - ``position_controllers/GripperActionController`` - ``effort_controllers/GripperActionController`` +.. note:: + + The ``effort_controllers/GripperActionController`` and ``position_controllers/GripperActionController`` will be removed. The ``parallel_gripper_action_controller/GripperActionController`` should be used instead. `(#1652 `__). + Parameters ^^^^^^^^^^^ These controllers use the `generate_parameter_library `_ to handle its parameters. The parameter `definition file located in the src folder `_ contains descriptions for all the parameters used by the controller. From 848508d53197776a3500424761fb97a06a9531d4 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 13 Aug 2025 13:08:21 +0200 Subject: [PATCH 058/108] Add a generic chained_filter_controller (backport #1634) (#1856) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ankur Bodhe <60222793+ankurbodhe@users.noreply.github.com> Co-authored-by: Christoph Fröhlich --- chained_filter_controller/CMakeLists.txt | 102 +++++++++ chained_filter_controller/doc/userdoc.rst | 27 +++ .../chained_filter.hpp | 63 ++++++ chained_filter_controller/package.xml | 43 ++++ .../plugin_description.xml | 10 + .../src/chained_filter.cpp | 171 +++++++++++++++ .../src/chained_filter_parameters.yaml | 33 +++ .../test/config/test_chained_filter.yaml | 10 + .../config/test_multiple_chained_filter.yaml | 37 ++++ .../test/test_chained_filter.cpp | 168 +++++++++++++++ .../test/test_chained_filter.hpp | 56 +++++ .../test_load_chained_filter_controller.cpp | 48 +++++ .../test/test_multiple_chained_filter.cpp | 202 ++++++++++++++++++ .../test/test_multiple_chained_filter.hpp | 57 +++++ doc/controllers_index.rst | 10 + doc/release_notes.rst | 4 + ros2_controllers/package.xml | 1 + 17 files changed, 1042 insertions(+) create mode 100644 chained_filter_controller/CMakeLists.txt create mode 100644 chained_filter_controller/doc/userdoc.rst create mode 100644 chained_filter_controller/include/chained_filter_controller/chained_filter.hpp create mode 100644 chained_filter_controller/package.xml create mode 100644 chained_filter_controller/plugin_description.xml create mode 100644 chained_filter_controller/src/chained_filter.cpp create mode 100644 chained_filter_controller/src/chained_filter_parameters.yaml create mode 100644 chained_filter_controller/test/config/test_chained_filter.yaml create mode 100644 chained_filter_controller/test/config/test_multiple_chained_filter.yaml create mode 100644 chained_filter_controller/test/test_chained_filter.cpp create mode 100644 chained_filter_controller/test/test_chained_filter.hpp create mode 100644 chained_filter_controller/test/test_load_chained_filter_controller.cpp create mode 100644 chained_filter_controller/test/test_multiple_chained_filter.cpp create mode 100644 chained_filter_controller/test/test_multiple_chained_filter.hpp diff --git a/chained_filter_controller/CMakeLists.txt b/chained_filter_controller/CMakeLists.txt new file mode 100644 index 0000000000..81d4bb7ac0 --- /dev/null +++ b/chained_filter_controller/CMakeLists.txt @@ -0,0 +1,102 @@ +cmake_minimum_required(VERSION 3.10) +project(chained_filter_controller) + +find_package(ros2_control_cmake REQUIRED) +set_compiler_options() +export_windows_symbols() + +# Dependencies +set(THIS_PACKAGE_INCLUDE_DEPENDS + controller_interface + generate_parameter_library + filters + hardware_interface + pluginlib + rclcpp + rclcpp_lifecycle +) +find_package(ament_cmake REQUIRED) +find_package(backward_ros REQUIRED) +foreach(Dependency IN ITEMS ${THIS_PACKAGE_INCLUDE_DEPENDS}) + find_package(${Dependency} REQUIRED) +endforeach() + +# Generate parameters from YAML +generate_parameter_library( + chained_filter_parameters + src/chained_filter_parameters.yaml +) + +# Library definition +add_library(${PROJECT_NAME} SHARED + src/chained_filter.cpp +) +target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17) +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ +) + +# Dependencies +target_link_libraries(${PROJECT_NAME} + PUBLIC + chained_filter_parameters + controller_interface::controller_interface + hardware_interface::hardware_interface + filters::filter_chain + pluginlib::pluginlib + rclcpp::rclcpp + rclcpp_lifecycle::rclcpp_lifecycle +) + +# Export the plugin description +pluginlib_export_plugin_description_file(controller_interface plugin_description.xml) + +if(BUILD_TESTING) + find_package(ament_cmake_gmock REQUIRED) + find_package(controller_manager REQUIRED) + find_package(ros2_control_test_assets REQUIRED) + + add_rostest_with_parameters_gmock(test_chained_filter_controller + test/test_chained_filter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test/config/test_chained_filter.yaml + ) + target_link_libraries(test_chained_filter_controller + ${PROJECT_NAME} + ) + + add_rostest_with_parameters_gmock(test_multiple_chained_filter_controller + test/test_multiple_chained_filter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test/config/test_multiple_chained_filter.yaml + ) + target_link_libraries(test_multiple_chained_filter_controller + ${PROJECT_NAME} + ) + + add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") + ament_add_gmock(test_load_chained_filter_controller test/test_load_chained_filter_controller.cpp) + target_link_libraries(test_load_chained_filter_controller + controller_manager::controller_manager + ros2_control_test_assets::ros2_control_test_assets + ) + +endif() + +install( + DIRECTORY include/ + DESTINATION include/${PROJECT_NAME} +) + +install( + TARGETS ${PROJECT_NAME} + chained_filter_parameters + EXPORT export_${PROJECT_NAME} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin +) + +# Export targets and dependencies +ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET) +ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS}) +ament_package() diff --git a/chained_filter_controller/doc/userdoc.rst b/chained_filter_controller/doc/userdoc.rst new file mode 100644 index 0000000000..68808fe351 --- /dev/null +++ b/chained_filter_controller/doc/userdoc.rst @@ -0,0 +1,27 @@ +:github_url: https://github.com/ros-controls/ros2_controllers/blob/{REPOS_FILE_BRANCH}/chained_filter_controller/doc/userdoc.rst + +.. _chained_filter_controller_userdoc: + +Chained Filter Controller +-------------------------------- +This controller wraps around ``filter_chain`` library from the `filters `__ package. It allows to chain multiple filters together, where the output of one filter is the input of the next one. The controller can be used to apply a sequence of filters to a single interface, the same filter chain to multiple interfaces, or different filter chains to different interfaces. + + +Parameters +^^^^^^^^^^^ +This controller uses the `generate_parameter_library `_ to handle its parameters. The parameter `definition file located in the src folder `_ contains descriptions for all the parameters used by the controller. + + +Full list of parameters: + +.. generate_parameter_library_details:: ../src/chained_filter_parameters.yaml + +An example parameter file for this controller can be found in `the test directory `_ for a single interface: + +.. literalinclude:: ../test/config/test_chained_filter.yaml + :language: yaml + +or for `multiple interfaces `_: + +.. literalinclude:: ../test/config/test_multiple_chained_filter.yaml + :language: yaml diff --git a/chained_filter_controller/include/chained_filter_controller/chained_filter.hpp b/chained_filter_controller/include/chained_filter_controller/chained_filter.hpp new file mode 100644 index 0000000000..66ce8f8f5b --- /dev/null +++ b/chained_filter_controller/include/chained_filter_controller/chained_filter.hpp @@ -0,0 +1,63 @@ +// Copyright 2025 ros2_control PMC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CHAINED_FILTER_CONTROLLER__CHAINED_FILTER_HPP_ +#define CHAINED_FILTER_CONTROLLER__CHAINED_FILTER_HPP_ + +#include +#include +#include + +#include "controller_interface/chainable_controller_interface.hpp" +#include "filters/filter_chain.hpp" +#include "rclcpp/rclcpp.hpp" +#include "rclcpp_lifecycle/state.hpp" + +#include "chained_filter_controller/chained_filter_parameters.hpp" + +namespace chained_filter_controller +{ + +class ChainedFilter : public controller_interface::ChainableControllerInterface +{ +public: + controller_interface::CallbackReturn on_init() override; + + controller_interface::InterfaceConfiguration command_interface_configuration() const override; + + controller_interface::InterfaceConfiguration state_interface_configuration() const override; + + controller_interface::CallbackReturn on_configure( + const rclcpp_lifecycle::State & previous_state) override; + + controller_interface::CallbackReturn on_activate( + const rclcpp_lifecycle::State & previous_state) override; + + controller_interface::return_type update_and_write_commands( + const rclcpp::Time & time, const rclcpp::Duration & period) override; + +protected: + std::vector on_export_state_interfaces() override; + + controller_interface::return_type update_reference_from_subscribers( + const rclcpp::Time & time, const rclcpp::Duration & period) override; + + std::shared_ptr param_listener_; + chained_filter::Params params_; + + std::vector>> filters_; + std::vector output_state_values_; +}; +} // namespace chained_filter_controller +#endif // CHAINED_FILTER_CONTROLLER__CHAINED_FILTER_HPP_ diff --git a/chained_filter_controller/package.xml b/chained_filter_controller/package.xml new file mode 100644 index 0000000000..d90a041621 --- /dev/null +++ b/chained_filter_controller/package.xml @@ -0,0 +1,43 @@ + + + + chained_filter_controller + 0.0.0 + ros2_controller for configuring filter chains + + Bence Magyar + Denis Štogl + Christoph Froehlich + Sai Kishor Kothakota + + Apache License 2.0 + + https://control.ros.org + https://github.com/ros-controls/ros2_controllers/issues + https://github.com/ros-controls/ros2_controllers/ + + Bence Magyar + Christoph Froehlich + ankur-u24 + + ament_cmake + + generate_parameter_library + ros2_control_cmake + + controller_interface + filters + pluginlib + rclcpp + rclcpp_lifecycle + hardware_interface + + ament_cmake_gmock + controller_manager + hardware_interface_testing + ros2_control_test_assets + + + ament_cmake + + diff --git a/chained_filter_controller/plugin_description.xml b/chained_filter_controller/plugin_description.xml new file mode 100644 index 0000000000..5cae753145 --- /dev/null +++ b/chained_filter_controller/plugin_description.xml @@ -0,0 +1,10 @@ + + + + A chainable ROS 2 controller that applies a sequence of filters to a state interface using the filters package, + and exports the filtered output as a new state interface. + + + diff --git a/chained_filter_controller/src/chained_filter.cpp b/chained_filter_controller/src/chained_filter.cpp new file mode 100644 index 0000000000..d30fb4666d --- /dev/null +++ b/chained_filter_controller/src/chained_filter.cpp @@ -0,0 +1,171 @@ +// Copyright 2025 ros2_control PMC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "chained_filter_controller/chained_filter.hpp" + +#include +#include + +#include "pluginlib/class_list_macros.hpp" +#include "rclcpp/version.h" + +namespace chained_filter_controller +{ + +controller_interface::CallbackReturn ChainedFilter::on_init() +{ + try + { + param_listener_ = std::make_shared(get_node()); + } + catch (const std::exception & e) + { + fprintf(stderr, "Exception thrown during init stage with message: %s \n", e.what()); + return controller_interface::CallbackReturn::ERROR; + } + return controller_interface::CallbackReturn::SUCCESS; +} + +controller_interface::InterfaceConfiguration ChainedFilter::command_interface_configuration() const +{ + return {controller_interface::interface_configuration_type::NONE}; +} + +controller_interface::InterfaceConfiguration ChainedFilter::state_interface_configuration() const +{ + return {controller_interface::interface_configuration_type::INDIVIDUAL, params_.input_interfaces}; +} + +controller_interface::CallbackReturn ChainedFilter::on_configure(const rclcpp_lifecycle::State &) +{ + try + { + params_ = param_listener_->get_params(); + + if (params_.input_interfaces.size() != params_.output_interfaces.size()) + { + RCLCPP_ERROR( + get_node()->get_logger(), "Input and output interfaces have to have the same size."); + return controller_interface::CallbackReturn::FAILURE; + } + filters_.resize(params_.input_interfaces.size()); + output_state_values_.resize( + params_.output_interfaces.size(), std::numeric_limits::quiet_NaN()); + + // Check if global filter chain configuration is set, if not we use a per-interface + // configuration + bool has_global_filter_setting = true; + if (params_.input_interfaces.size() > 1) + { + if (!get_node()->has_parameter("filter_chain.filter1.name")) + { + rcl_interfaces::msg::ParameterDescriptor desc; + desc.name = "filter_chain.filter1.name"; + desc.type = rcl_interfaces::msg::ParameterType::PARAMETER_STRING; + desc.read_only = true; + get_node()->declare_parameter( + "filter_chain.filter1.name", rclcpp::ParameterValue{""}, desc); + has_global_filter_setting = + !get_node()->get_parameter("filter_chain.filter1.name").as_string().empty(); + } + RCLCPP_INFO_EXPRESSION( + get_node()->get_logger(), has_global_filter_setting, + "Using global filter setting for all interfaces."); + } + + for (size_t i = 0; i < params_.input_interfaces.size(); ++i) + { + filters_[i] = std::make_unique>("double"); + if (!filters_[i]->configure( + has_global_filter_setting ? "filter_chain" + : params_.input_interfaces[i] + ".filter_chain", + get_node()->get_node_logging_interface(), get_node()->get_node_parameters_interface())) + { + RCLCPP_ERROR( + get_node()->get_logger(), + "Failed to configure filter chain for interfaces %s. Check the parameters for filters " + "setup.", + params_.input_interfaces[i].c_str()); + return controller_interface::CallbackReturn::FAILURE; + } + } + } + catch (const std::exception & e) + { + fprintf(stderr, "Exception thrown during configure stage with message: %s \n", e.what()); + return controller_interface::CallbackReturn::ERROR; + } + return controller_interface::CallbackReturn::SUCCESS; +} + +controller_interface::CallbackReturn ChainedFilter::on_activate(const rclcpp_lifecycle::State &) +{ + std::fill( + output_state_values_.begin(), output_state_values_.end(), + std::numeric_limits::quiet_NaN()); + return controller_interface::CallbackReturn::SUCCESS; +} + +controller_interface::return_type ChainedFilter::update_and_write_commands( + const rclcpp::Time &, const rclcpp::Duration &) +{ + for (size_t i = 0; i < params_.input_interfaces.size(); ++i) + { + const auto sensor_op = state_interfaces_[i].get_optional(); + if (!sensor_op.has_value()) + { + RCLCPP_ERROR( + get_node()->get_logger(), "Failed to read sensor value from state interface '%s'.", + state_interfaces_[0].get_name().c_str()); + continue; + } + if (std::isfinite(sensor_op.value())) + { + filters_[i]->update(sensor_op.value(), output_state_values_[i]); + } + } + + return controller_interface::return_type::OK; +} + +std::vector ChainedFilter::on_export_state_interfaces() +{ + std::vector state_interfaces; + state_interfaces.reserve(params_.output_interfaces.size()); + for (size_t i = 0; i < params_.output_interfaces.size(); ++i) + { + // Split the output interface name by the last "/" if present + const std::string & full_name = params_.output_interfaces.at(i); + auto pos = full_name.rfind('/'); + const std::string iface_name = + (pos != std::string::npos) ? full_name.substr(pos + 1) : full_name; + const std::string iface_prefix = + (pos != std::string::npos) ? "/" + full_name.substr(0, pos) : ""; + + state_interfaces.emplace_back( + get_node()->get_name() + iface_prefix, iface_name, &output_state_values_.at(i)); + } + return state_interfaces; +} + +controller_interface::return_type ChainedFilter::update_reference_from_subscribers( + const rclcpp::Time &, const rclcpp::Duration &) +{ + return controller_interface::return_type::OK; +} + +} // namespace chained_filter_controller + +PLUGINLIB_EXPORT_CLASS( + chained_filter_controller::ChainedFilter, controller_interface::ChainableControllerInterface) diff --git a/chained_filter_controller/src/chained_filter_parameters.yaml b/chained_filter_controller/src/chained_filter_parameters.yaml new file mode 100644 index 0000000000..6aca1fbfcf --- /dev/null +++ b/chained_filter_controller/src/chained_filter_parameters.yaml @@ -0,0 +1,33 @@ +chained_filter: + input_interfaces: + type: string_array + default_value: [] + read_only: true + description: "Name of the input state interface" + validation: { + not_empty<>: [] + } + output_interfaces: + type: string_array + default_value: [] + read_only: true + description: "Name of the output state interface" + validation: { + not_empty<>: [] + } + filter_chain: { + type: none, + description: "Map of parameters that defines a filter chain, containing filterN as key. Valid for all interfaces, overrides .filter_chain if set. + The fields for each filter are: + type: The filter plugin to be loaded + name: Actual name semantically describing the filter, e.g., low_pass_filter + params: And underlying map of parameters needed for a specific filter, refer to the specific filter documentation." + } + __map_input_interfaces: + filter_chain: { + type: none, + description: "Instead of a single configuration, a distinct configuration can be provided for each input interface. The key is the name of the input interface, and the value is a map of parameters that defines a filter chain, containing filterN as key. The fields for each filter are: + type: The filter plugin to be loaded + name: Actual name semantically describing the filter, e.g., low_pass_filter + params: And underlying map of parameters needed for a specific filter, refer to the specific filter documentation." + } diff --git a/chained_filter_controller/test/config/test_chained_filter.yaml b/chained_filter_controller/test/config/test_chained_filter.yaml new file mode 100644 index 0000000000..a2cfe01273 --- /dev/null +++ b/chained_filter_controller/test/config/test_chained_filter.yaml @@ -0,0 +1,10 @@ +test_chained_filter: + ros__parameters: + filter_chain: + filter1: + name: filter1 + type: "filters/MeanFilterDouble" + params: + number_of_observations: 2 + input_interfaces: ["wheel_left/position"] + output_interfaces: ["wheel_left/filtered_position"] diff --git a/chained_filter_controller/test/config/test_multiple_chained_filter.yaml b/chained_filter_controller/test/config/test_multiple_chained_filter.yaml new file mode 100644 index 0000000000..d4fa493b5d --- /dev/null +++ b/chained_filter_controller/test/config/test_multiple_chained_filter.yaml @@ -0,0 +1,37 @@ +test_chained_filter_multiple_interfaces: + ros__parameters: + filter_chain: + filter1: + name: position_filter + type: "filters/MeanFilterDouble" + params: + number_of_observations: 2 + input_interfaces: + - "wheel_left/position" + - "wheel_right/position" + output_interfaces: + - "wheel_left/filtered_position" + - "wheel_right/filtered_position" + +test_chained_filter_multiple_interfaces_config_per_input: + ros__parameters: + input_interfaces: + - "wheel_left/position" + - "wheel_right/position" + output_interfaces: + - "wheel_left/filtered_position" + - "wheel_right/filtered_position" + wheel_left/position: + filter_chain: + filter1: + name: wheel_left_filter + type: "filters/MeanFilterDouble" + params: + number_of_observations: 2 + wheel_right/position: + filter_chain: + filter1: + name: wheel_right_filter + type: "filters/MeanFilterDouble" + params: + number_of_observations: 3 diff --git a/chained_filter_controller/test/test_chained_filter.cpp b/chained_filter_controller/test/test_chained_filter.cpp new file mode 100644 index 0000000000..d1238c00f7 --- /dev/null +++ b/chained_filter_controller/test/test_chained_filter.cpp @@ -0,0 +1,168 @@ +// Copyright 2025 ros2_control PMC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "test_chained_filter.hpp" + +#include + +#include +#include + +#include "controller_interface/controller_interface.hpp" +#include "rclcpp/rclcpp.hpp" + +#include "chained_filter_controller/chained_filter.hpp" + +using chained_filter_controller::ChainedFilter; +using controller_interface::CallbackReturn; +using testing::SizeIs; + +using hardware_interface::LoanedStateInterface; + +void ChainedFilterTest::SetUpTestCase() { /*rclcpp::init(0, nullptr);*/ } + +void ChainedFilterTest::TearDownTestCase() { /*rclcpp::shutdown(); */ } + +void ChainedFilterTest::SetUp() +{ + // initialize controller + controller_ = std::make_unique(); +} + +void ChainedFilterTest::TearDown() { controller_.reset(nullptr); } + +void ChainedFilterTest::SetUpController( + const std::string node_name, const std::vector & parameters) +{ + auto node_options = controller_->define_custom_node_options(); + node_options.parameter_overrides(parameters); + + const auto result = controller_->init(node_name, "", 0, "", node_options); + ASSERT_EQ(result, controller_interface::return_type::OK); + + std::vector state_ifs; + state_ifs.emplace_back(joint_1_pos_); + controller_->assign_interfaces({}, std::move(state_ifs)); + executor.add_node(controller_->get_node()->get_node_base_interface()); +} + +TEST_F(ChainedFilterTest, InitReturnsSuccess) { SetUpController(); } + +TEST_F(ChainedFilterTest, InitFailureWithNoParams) +{ + const auto result = controller_->init( + "test_chained_filter_no_params", "", 0, "", controller_->define_custom_node_options()); + EXPECT_EQ(result, controller_interface::return_type::ERROR); +} + +TEST_F(ChainedFilterTest, ConfigureFailureWithWrongInterfaceSizes) +{ + SetUpController( + "test_chained_filter", + {rclcpp::Parameter("input_interfaces", std::vector{"wheel_left/position"}), + rclcpp::Parameter( + "output_interfaces", + std::vector{"wheel_left/filtered_position", "extra_interface"})}); + auto configure_result = controller_->on_configure(rclcpp_lifecycle::State()); + EXPECT_EQ(configure_result, CallbackReturn::FAILURE); +} + +TEST_F(ChainedFilterTest, ActivateReturnsSuccessWithoutError) +{ + SetUpController(); + + auto configure_result = controller_->on_configure(rclcpp_lifecycle::State()); + EXPECT_EQ(configure_result, CallbackReturn::SUCCESS); + + auto activate_result = controller_->on_activate(rclcpp_lifecycle::State()); + EXPECT_EQ(activate_result, CallbackReturn::SUCCESS); + + ASSERT_FALSE(controller_->is_in_chained_mode()) + << "No controller is claiming the reference interfaces (it has none)."; +} + +TEST_F(ChainedFilterTest, state_interface_configuration_succeeds_when_wheels_are_specified) +{ + SetUpController(); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + + auto state_if_conf = controller_->state_interface_configuration(); + ASSERT_THAT(state_if_conf.names, SizeIs(1u)); + EXPECT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::INDIVIDUAL); + auto cmd_if_conf = controller_->command_interface_configuration(); + ASSERT_THAT(cmd_if_conf.names, SizeIs(0u)); + EXPECT_EQ(cmd_if_conf.type, controller_interface::interface_configuration_type::NONE); + + auto state_if_exported_conf = controller_->export_state_interfaces(); + ASSERT_THAT(state_if_exported_conf, SizeIs(1u)); + EXPECT_EQ( + state_if_exported_conf[0]->get_name(), "test_chained_filter/wheel_left/filtered_position"); + EXPECT_EQ(state_if_exported_conf[0]->get_interface_name(), "filtered_position"); + EXPECT_EQ(state_if_exported_conf[0]->get_prefix_name(), "test_chained_filter/wheel_left"); +} + +TEST_F(ChainedFilterTest, UpdateFilter) +{ + SetUpController(); + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + + ASSERT_EQ( + controller_->update_and_write_commands(rclcpp::Time(), rclcpp::Duration::from_seconds(0.1)), + controller_interface::return_type::OK); + // input state interface should not change + EXPECT_EQ(joint_1_pos_.get_optional().value(), joint_states_[0]); + // output should be the same + auto state_if_exported_conf = controller_->export_state_interfaces(); + ASSERT_THAT(state_if_exported_conf, SizeIs(1u)); + EXPECT_EQ(state_if_exported_conf[0]->get_optional().value(), joint_states_[0]); + + ASSERT_TRUE(joint_1_pos_.set_value(2.0)); + ASSERT_EQ( + controller_->update_and_write_commands(rclcpp::Time(), rclcpp::Duration::from_seconds(0.1)), + controller_interface::return_type::OK); + // input and output should have changed + EXPECT_EQ(joint_1_pos_.get_optional().value(), joint_states_[0]); + EXPECT_EQ(state_if_exported_conf[0]->get_optional().value(), 1.55); + ASSERT_EQ( + controller_->update_and_write_commands(rclcpp::Time(), rclcpp::Duration::from_seconds(0.1)), + controller_interface::return_type::OK); + // output should have reached steady state (mean filter) + EXPECT_EQ(state_if_exported_conf[0]->get_optional().value(), joint_states_[0]); +} + +TEST_F(ChainedFilterTest, DeactivateDoesNotCrash) +{ + EXPECT_NO_THROW({ controller_->on_deactivate(rclcpp_lifecycle::State()); }); +} + +TEST_F(ChainedFilterTest, CleanupDoesNotCrash) +{ + EXPECT_NO_THROW({ controller_->on_cleanup(rclcpp_lifecycle::State()); }); +} + +TEST_F(ChainedFilterTest, ShutdownDoesNotCrash) +{ + EXPECT_NO_THROW({ controller_->on_shutdown(rclcpp_lifecycle::State()); }); +} + +int main(int argc, char ** argv) +{ + ::testing::InitGoogleMock(&argc, argv); + rclcpp::init(argc, argv); + int result = RUN_ALL_TESTS(); + rclcpp::shutdown(); + return result; +} diff --git a/chained_filter_controller/test/test_chained_filter.hpp b/chained_filter_controller/test/test_chained_filter.hpp new file mode 100644 index 0000000000..8ce63433ac --- /dev/null +++ b/chained_filter_controller/test/test_chained_filter.hpp @@ -0,0 +1,56 @@ +// Copyright 2020 PAL Robotics SL. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef TEST_CHAINED_FILTER_HPP_ +#define TEST_CHAINED_FILTER_HPP_ + +#include +#include +#include + +#include "gmock/gmock.h" + +#include "chained_filter_controller/chained_filter.hpp" +#include "hardware_interface/handle.hpp" +#include "hardware_interface/types/hardware_interface_type_values.hpp" +#include "rclcpp/executors/single_threaded_executor.hpp" + +using hardware_interface::HW_IF_POSITION; +using hardware_interface::StateInterface; + +class ChainedFilterTest : public ::testing::Test +{ +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + + void SetUp(); + void TearDown(); + + void SetUpController( + const std::string node_name = "test_chained_filter", + const std::vector & parameters = {}); + +protected: + std::unique_ptr controller_; + + // dummy joint state values used for tests + const std::vector joint_names_ = {"wheel_left"}; + std::vector joint_states_ = {1.1}; + + StateInterface joint_1_pos_{joint_names_[0], HW_IF_POSITION, &joint_states_[0]}; + rclcpp::executors::SingleThreadedExecutor executor; +}; + +#endif // TEST_CHAINED_FILTER_HPP_ diff --git a/chained_filter_controller/test/test_load_chained_filter_controller.cpp b/chained_filter_controller/test/test_load_chained_filter_controller.cpp new file mode 100644 index 0000000000..886015df35 --- /dev/null +++ b/chained_filter_controller/test/test_load_chained_filter_controller.cpp @@ -0,0 +1,48 @@ +// Copyright 2020 PAL Robotics SL. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "controller_manager/controller_manager.hpp" +#include "hardware_interface/resource_manager.hpp" +#include "rclcpp/executor.hpp" +#include "rclcpp/executors/single_threaded_executor.hpp" +#include "rclcpp/utilities.hpp" +#include "ros2_control_test_assets/descriptions.hpp" + +TEST(TestLoadChainedFilter, load_controller) +{ + std::shared_ptr executor = + std::make_shared(); + + controller_manager::ControllerManager cm( + executor, ros2_control_test_assets::diffbot_urdf, true, "test_controller_manager"); + const std::string test_file_path = + std::string(TEST_FILES_DIRECTORY) + "/config/test_chained_filter.yaml"; + + cm.set_parameter({"test_chained_filter.params_file", test_file_path}); + cm.set_parameter({"test_chained_filter.type", "chained_filter_controller/ChainedFilter"}); + + ASSERT_NE(cm.load_controller("test_chained_filter"), nullptr); +} + +int main(int argc, char ** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + rclcpp::init(argc, argv); + int result = RUN_ALL_TESTS(); + rclcpp::shutdown(); + return result; +} diff --git a/chained_filter_controller/test/test_multiple_chained_filter.cpp b/chained_filter_controller/test/test_multiple_chained_filter.cpp new file mode 100644 index 0000000000..0ec774a8c4 --- /dev/null +++ b/chained_filter_controller/test/test_multiple_chained_filter.cpp @@ -0,0 +1,202 @@ +// Copyright 2025 ros2_control PMC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "test_multiple_chained_filter.hpp" + +#include + +#include +#include + +#include "controller_interface/controller_interface.hpp" +#include "rclcpp/rclcpp.hpp" + +#include "chained_filter_controller/chained_filter.hpp" + +using chained_filter_controller::ChainedFilter; +using controller_interface::CallbackReturn; +using testing::SizeIs; + +using hardware_interface::LoanedStateInterface; + +void MultipleChainedFilterTest::SetUpTestCase() { /*rclcpp::init(0, nullptr);*/ } + +void MultipleChainedFilterTest::TearDownTestCase() { /*rclcpp::shutdown(); */ } + +void MultipleChainedFilterTest::SetUp() +{ + // initialize controller + controller_ = std::make_unique(); +} + +void MultipleChainedFilterTest::TearDown() { controller_.reset(nullptr); } + +void MultipleChainedFilterTest::SetUpController( + const std::string node_name, const std::vector & parameters) +{ + auto node_options = controller_->define_custom_node_options(); + node_options.parameter_overrides(parameters); + + const auto result = controller_->init(node_name, "", 0, "", node_options); + ASSERT_EQ(result, controller_interface::return_type::OK); + + std::vector state_ifs; + state_ifs.emplace_back(joint_1_pos_); + state_ifs.emplace_back(joint_2_pos_); + controller_->assign_interfaces({}, std::move(state_ifs)); + executor.add_node(controller_->get_node()->get_node_base_interface()); +} + +TEST_F(MultipleChainedFilterTest, InitReturnsSuccess) { SetUpController(); } + +TEST_F(MultipleChainedFilterTest, ActivateReturnsSuccessWithoutError) +{ + SetUpController(); + + auto configure_result = controller_->on_configure(rclcpp_lifecycle::State()); + EXPECT_EQ(configure_result, CallbackReturn::SUCCESS); + + auto activate_result = controller_->on_activate(rclcpp_lifecycle::State()); + EXPECT_EQ(activate_result, CallbackReturn::SUCCESS); + + ASSERT_FALSE(controller_->is_in_chained_mode()) + << "No controller is claiming the reference interfaces (it has none)."; +} + +TEST_F( + MultipleChainedFilterTest, + state_interface_configuration_succeeds_when_multiple_wheels_are_specified) +{ + SetUpController(); + + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + + auto state_if_conf = controller_->state_interface_configuration(); + ASSERT_THAT(state_if_conf.names, SizeIs(2u)); + EXPECT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::INDIVIDUAL); + auto cmd_if_conf = controller_->command_interface_configuration(); + ASSERT_THAT(cmd_if_conf.names, SizeIs(0u)); + EXPECT_EQ(cmd_if_conf.type, controller_interface::interface_configuration_type::NONE); + + auto state_if_exported_conf = controller_->export_state_interfaces(); + ASSERT_THAT(state_if_exported_conf, SizeIs(2u)); + EXPECT_EQ( + state_if_exported_conf[0]->get_name(), + "test_chained_filter_multiple_interfaces/wheel_left/filtered_position"); + EXPECT_EQ( + state_if_exported_conf[0]->get_prefix_name(), + "test_chained_filter_multiple_interfaces/wheel_left"); + EXPECT_EQ(state_if_exported_conf[0]->get_interface_name(), "filtered_position"); + + EXPECT_EQ( + state_if_exported_conf[1]->get_name(), + "test_chained_filter_multiple_interfaces/wheel_right/filtered_position"); + EXPECT_EQ( + state_if_exported_conf[1]->get_prefix_name(), + "test_chained_filter_multiple_interfaces/wheel_right"); + EXPECT_EQ(state_if_exported_conf[1]->get_interface_name(), "filtered_position"); +} + +TEST_F(MultipleChainedFilterTest, UpdateFilter_multiple_interfaces) +{ + SetUpController(); + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + + ASSERT_EQ( + controller_->update_and_write_commands(rclcpp::Time(), rclcpp::Duration::from_seconds(0.1)), + controller_interface::return_type::OK); + // input state interface should not change + EXPECT_EQ(joint_1_pos_.get_optional().value(), joint_states_[0]); + EXPECT_EQ(joint_2_pos_.get_optional().value(), joint_states_[1]); + // output should be the same + auto state_if_exported_conf = controller_->export_state_interfaces(); + ASSERT_THAT(state_if_exported_conf, SizeIs(2u)); + EXPECT_EQ(state_if_exported_conf[0]->get_optional().value(), joint_states_[0]); + EXPECT_EQ(state_if_exported_conf[1]->get_optional().value(), joint_states_[1]); + + ASSERT_TRUE(joint_1_pos_.set_value(2.0)); + ASSERT_TRUE(joint_2_pos_.set_value(3.0)); + ASSERT_EQ( + controller_->update_and_write_commands(rclcpp::Time(), rclcpp::Duration::from_seconds(0.1)), + controller_interface::return_type::OK); + // input and output should have changed + EXPECT_EQ(joint_1_pos_.get_optional().value(), joint_states_[0]); + EXPECT_EQ(state_if_exported_conf[0]->get_optional().value(), 1.55); + EXPECT_EQ(joint_2_pos_.get_optional().value(), joint_states_[1]); + EXPECT_EQ(state_if_exported_conf[1]->get_optional().value(), 2.6); + + ASSERT_EQ( + controller_->update_and_write_commands(rclcpp::Time(), rclcpp::Duration::from_seconds(0.1)), + controller_interface::return_type::OK); + // output should have reached steady state (mean filter) + EXPECT_EQ(state_if_exported_conf[0]->get_optional().value(), joint_states_[0]); + EXPECT_EQ(state_if_exported_conf[1]->get_optional().value(), joint_states_[1]); +} + +TEST_F(MultipleChainedFilterTest, UpdateFilter_multiple_interfaces_config_per_input) +{ + SetUpController("test_chained_filter_multiple_interfaces_config_per_input"); + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); + + ASSERT_EQ( + controller_->update_and_write_commands(rclcpp::Time(), rclcpp::Duration::from_seconds(0.1)), + controller_interface::return_type::OK); + // input state interface should not change + EXPECT_EQ(joint_1_pos_.get_optional().value(), joint_states_[0]); + EXPECT_EQ(joint_2_pos_.get_optional().value(), joint_states_[1]); + // output should be the same + auto state_if_exported_conf = controller_->export_state_interfaces(); + ASSERT_THAT(state_if_exported_conf, SizeIs(2u)); + EXPECT_EQ(state_if_exported_conf[0]->get_optional().value(), joint_states_[0]); + EXPECT_EQ(state_if_exported_conf[1]->get_optional().value(), joint_states_[1]); + + ASSERT_TRUE(joint_1_pos_.set_value(2.0)); + ASSERT_TRUE(joint_2_pos_.set_value(2.8)); + ASSERT_EQ( + controller_->update_and_write_commands(rclcpp::Time(), rclcpp::Duration::from_seconds(0.1)), + controller_interface::return_type::OK); + // input and output should have changed + EXPECT_EQ(joint_1_pos_.get_optional().value(), joint_states_[0]); + EXPECT_EQ(state_if_exported_conf[0]->get_optional().value(), 1.55); + EXPECT_EQ(joint_2_pos_.get_optional().value(), joint_states_[1]); + // second update call, mean of (2.2, 2.8) + EXPECT_EQ(state_if_exported_conf[1]->get_optional().value(), 2.5); + + ASSERT_EQ( + controller_->update_and_write_commands(rclcpp::Time(), rclcpp::Duration::from_seconds(0.1)), + controller_interface::return_type::OK); + // output should have reached steady state for the first input (mean filter) + EXPECT_EQ(state_if_exported_conf[0]->get_optional().value(), joint_states_[0]); + // third update call, mean of (2.2, 2.8, 2.8) + EXPECT_EQ(state_if_exported_conf[1]->get_optional().value(), 2.6); + + ASSERT_EQ( + controller_->update_and_write_commands(rclcpp::Time(), rclcpp::Duration::from_seconds(0.1)), + controller_interface::return_type::OK); + // no change + EXPECT_EQ(state_if_exported_conf[0]->get_optional().value(), joint_states_[0]); + // output should have reached steady state (mean filter) + EXPECT_NEAR(state_if_exported_conf[1]->get_optional().value(), joint_states_[1], 1e-5); +} + +int main(int argc, char ** argv) +{ + ::testing::InitGoogleMock(&argc, argv); + rclcpp::init(argc, argv); + int result = RUN_ALL_TESTS(); + rclcpp::shutdown(); + return result; +} diff --git a/chained_filter_controller/test/test_multiple_chained_filter.hpp b/chained_filter_controller/test/test_multiple_chained_filter.hpp new file mode 100644 index 0000000000..d2be05a7d9 --- /dev/null +++ b/chained_filter_controller/test/test_multiple_chained_filter.hpp @@ -0,0 +1,57 @@ +// Copyright 2020 PAL Robotics SL. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef TEST_MULTIPLE_CHAINED_FILTER_HPP_ +#define TEST_MULTIPLE_CHAINED_FILTER_HPP_ + +#include +#include +#include + +#include "gmock/gmock.h" + +#include "chained_filter_controller/chained_filter.hpp" +#include "hardware_interface/handle.hpp" +#include "hardware_interface/types/hardware_interface_type_values.hpp" +#include "rclcpp/executors/single_threaded_executor.hpp" + +using hardware_interface::HW_IF_POSITION; +using hardware_interface::StateInterface; + +class MultipleChainedFilterTest : public ::testing::Test +{ +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + + void SetUp(); + void TearDown(); + + void SetUpController( + const std::string node_name = "test_chained_filter_multiple_interfaces", + const std::vector & parameters = {}); + +protected: + std::unique_ptr controller_; + + // dummy joint state values used for tests + const std::vector joint_names_ = {"wheel_left", "wheel_right"}; + std::vector joint_states_ = {1.1, 2.2}; + + StateInterface joint_1_pos_{joint_names_[0], HW_IF_POSITION, &joint_states_[0]}; + StateInterface joint_2_pos_{joint_names_[1], HW_IF_POSITION, &joint_states_[1]}; + rclcpp::executors::SingleThreadedExecutor executor; +}; + +#endif // TEST_MULTIPLE_CHAINED_FILTER_HPP_ diff --git a/doc/controllers_index.rst b/doc/controllers_index.rst index 1bb61058f8..befde85a3a 100644 --- a/doc/controllers_index.rst +++ b/doc/controllers_index.rst @@ -77,6 +77,16 @@ In the sense of ros2_control, broadcasters are still controllers using the same Pose Broadcaster <../pose_broadcaster/doc/userdoc.rst> GPS Sensor Broadcaster <../gps_sensor_broadcaster/doc/userdoc.rst> +Filters +********************** + +Chainable controllers for filtering of state interfaces. They export the filtered values as state interfaces, which can be used by other controllers or broadcasters, and don't publish to ROS topics. + +.. toctree:: + :titlesonly: + + Chained Filter Controller <../chained_filter_controller/doc/userdoc.rst> + Common Controller Parameters **************************** diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 9f79bbbc49..4f02721058 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -20,6 +20,10 @@ gripper_action_controller ***************************** The ``effort_controllers/GripperActionController`` and ``position_controllers/GripperActionController`` will be removed. The ``parallel_gripper_action_controller/GripperActionController`` should be used instead. `(#1652 `__). +chained_filter_controller +******************************* +* The chained_filter_controller was added to use generic filter plugins (`#1634 `__). + joint_trajectory_controller ***************************** diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index fabfe644f9..cc2c48e4cf 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -20,6 +20,7 @@ ackermann_steering_controller admittance_controller bicycle_steering_controller + chained_filter_controller diff_drive_controller effort_controllers force_torque_sensor_broadcaster From 18c68d678f88ff09e97c6837494712045139d704 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 16 Aug 2025 18:50:13 +0200 Subject: [PATCH 059/108] Update jazzy branch for demos (backport #1860) (#1862) --- ros_controls.jazzy.repos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ros_controls.jazzy.repos b/ros_controls.jazzy.repos index e7cfd385f8..4da12a2b37 100644 --- a/ros_controls.jazzy.repos +++ b/ros_controls.jazzy.repos @@ -6,4 +6,4 @@ repositories: ros-controls/ros2_control_demos: type: git url: https://github.com/ros-controls/ros2_control_demos.git - version: master + version: jazzy From c836447d49fa8a487eadcd5c217b92b17680b366 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 16 Aug 2025 18:51:01 +0200 Subject: [PATCH 060/108] Fix latex export (backport #1859) (#1864) --- doc/mobile_robot_kinematics.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/mobile_robot_kinematics.rst b/doc/mobile_robot_kinematics.rst index 4bf285972e..1b2566ed9a 100644 --- a/doc/mobile_robot_kinematics.rst +++ b/doc/mobile_robot_kinematics.rst @@ -46,7 +46,7 @@ It follows the coordinate conventions defined in `ROS REP 103 Date: Tue, 26 Aug 2025 18:49:23 +0100 Subject: [PATCH 061/108] chore: tf2_ros to hpp headers (backport #1866) (#1869) --- admittance_controller/test/test_admittance_controller.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admittance_controller/test/test_admittance_controller.hpp b/admittance_controller/test/test_admittance_controller.hpp index e38bcc82cf..dd854bce7d 100644 --- a/admittance_controller/test/test_admittance_controller.hpp +++ b/admittance_controller/test/test_admittance_controller.hpp @@ -38,7 +38,7 @@ #include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp" #include "semantic_components/force_torque_sensor.hpp" #include "test_asset_6d_robot_description.hpp" -#include "tf2_ros/transform_broadcaster.h" +#include "tf2_ros/transform_broadcaster.hpp" // TODO(anyone): replace the state and command message types using ControllerCommandWrenchMsg = geometry_msgs::msg::WrenchStamped; From aff2f894d86fdc8aae74b6e0ee9d03adcdfd9455 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 26 Aug 2025 20:42:34 +0200 Subject: [PATCH 062/108] docs(joint_state_broadcaster): clarify /dynamic_joint_states contents (backport #1865) (#1871) --- joint_state_broadcaster/doc/userdoc.rst | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/joint_state_broadcaster/doc/userdoc.rst b/joint_state_broadcaster/doc/userdoc.rst index 996284d51a..151b711dc4 100644 --- a/joint_state_broadcaster/doc/userdoc.rst +++ b/joint_state_broadcaster/doc/userdoc.rst @@ -20,6 +20,42 @@ In the latter case, resulting interfaces is defined by a "matrix" of interfaces If some requested interfaces are missing, the controller will print a warning about that, but work for other interfaces. If none of the requested interface are not defined, the controller returns error on activation. +Published topics +---------------- + +* ``/joint_states`` (``sensor_msgs/msg/JointState``): + + Publishes *movement-related* interfaces only — ``position``, ``velocity``, + and ``effort`` — for joints that provide them. If a joint does not expose a given + movement interface, that field is omitted/left empty for that joint in the message. + +* ``/dynamic_joint_states`` (``control_msgs/msg/DynamicJointState``): + + Publishes **all available state interfaces** for each joint. This includes the + movement interfaces (position/velocity/effort) *and* any additional or custom + interfaces provided by the hardware (e.g., temperature, voltage, torque sensor + readings, calibration flags). + + The message maps ``joint_names`` to per-joint interface name lists and values. + Example payload:: + + joint_names: [joint1, joint2] + interface_values: + - interface_names: [position, velocity, effort] + values: [1.5708, 0.0, 0.20] + - interface_names: [position, temperature] + values: [0.7854, 42.1] + + Use this topic if you need *every* reported interface, not just movement. + +.. note:: + + If ``use_local_topics`` is set to ``true``, both topics are published in the + controller’s namespace (e.g., ``/my_state_broadcaster/joint_states`` and + ``/my_state_broadcaster/dynamic_joint_states``). If ``false`` (default), + they are published at the root (e.g., ``/joint_states``). + + Parameters ---------- This controller uses the `generate_parameter_library `_ to handle its parameters. The parameter `definition file located in the src folder `_ contains descriptions for all the parameters used by the controller. From 279136b8b1c881e5a672226092f1b19a09af182c Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Wed, 27 Aug 2025 12:29:31 +0100 Subject: [PATCH 063/108] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 3 + admittance_controller/CHANGELOG.rst | 5 + bicycle_steering_controller/CHANGELOG.rst | 3 + chained_filter_controller/CHANGELOG.rst | 260 ++++++++++++++++++ chained_filter_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 3 + effort_controllers/CHANGELOG.rst | 3 + force_torque_sensor_broadcaster/CHANGELOG.rst | 3 + forward_command_controller/CHANGELOG.rst | 3 + gpio_controllers/CHANGELOG.rst | 3 + gps_sensor_broadcaster/CHANGELOG.rst | 3 + gripper_controllers/CHANGELOG.rst | 5 + imu_sensor_broadcaster/CHANGELOG.rst | 3 + joint_state_broadcaster/CHANGELOG.rst | 5 + joint_trajectory_controller/CHANGELOG.rst | 3 + mecanum_drive_controller/CHANGELOG.rst | 3 + omni_wheel_drive_controller/CHANGELOG.rst | 3 + parallel_gripper_controller/CHANGELOG.rst | 3 + pid_controller/CHANGELOG.rst | 3 + pose_broadcaster/CHANGELOG.rst | 3 + position_controllers/CHANGELOG.rst | 3 + range_sensor_broadcaster/CHANGELOG.rst | 3 + ros2_controllers/CHANGELOG.rst | 5 + ros2_controllers_test_nodes/CHANGELOG.rst | 3 + rqt_joint_trajectory_controller/CHANGELOG.rst | 3 + steering_controllers_library/CHANGELOG.rst | 3 + tricycle_controller/CHANGELOG.rst | 3 + tricycle_steering_controller/CHANGELOG.rst | 3 + velocity_controllers/CHANGELOG.rst | 3 + 29 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 chained_filter_controller/CHANGELOG.rst diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 2d722d58d4..d6d1ccf56b 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index f44bf50af5..85f1ddfe08 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* chore: tf2_ros to hpp headers (backport `#1866 `_) (`#1869 `_) +* Contributors: mergify[bot] + 4.30.1 (2025-08-03) ------------------- diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 999cd1fbb3..c380dd5d78 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/chained_filter_controller/CHANGELOG.rst b/chained_filter_controller/CHANGELOG.rst new file mode 100644 index 0000000000..217b28abd0 --- /dev/null +++ b/chained_filter_controller/CHANGELOG.rst @@ -0,0 +1,260 @@ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Changelog for package chained_filter_controller +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Forthcoming +----------- +* Add a generic chained_filter_controller (backport `#1634 `_) (`#1856 `_) +* Contributors: Ankur Bodhe + +4.30.1 (2025-08-03) +------------------- + +4.30.0 (2025-07-31) +------------------- + +4.29.0 (2025-07-23) +------------------- + +4.28.0 (2025-07-14) +------------------- + +4.27.1 (2025-07-02) +------------------- + +4.27.0 (2025-06-23) +------------------- + +4.26.0 (2025-06-06) +------------------- + +4.25.0 (2025-05-17) +------------------- + +4.24.0 (2025-04-27) +------------------- + +4.23.0 (2025-04-10) +------------------- + +4.22.0 (2025-03-17) +------------------- + +4.21.0 (2025-03-01) +------------------- + +4.20.0 (2025-01-29) +------------------- + +4.19.0 (2025-01-13) +------------------- + +4.18.0 (2024-12-19) +------------------- + +4.17.0 (2024-12-07) +------------------- + +4.16.0 (2024-11-08) +------------------- + +4.15.0 (2024-10-07) +------------------- + +4.14.0 (2024-09-11) +------------------- + +4.13.0 (2024-08-22) +------------------- + +4.12.1 (2024-08-14) +------------------- + +4.12.0 (2024-07-23) +------------------- + +4.11.0 (2024-07-09) +------------------- + +4.10.0 (2024-07-01) +------------------- + +4.9.0 (2024-06-05) +------------------ + +4.8.0 (2024-05-14) +------------------ + +4.7.0 (2024-03-22) +------------------ + +4.6.0 (2024-02-12) +------------------ + +4.5.0 (2024-01-31) +------------------ + +4.4.0 (2024-01-11) +------------------ + +4.3.0 (2024-01-08) +------------------ + +4.2.0 (2023-12-12) +------------------ + +4.1.0 (2023-12-01) +------------------ + +4.0.0 (2023-11-21) +------------------ + +3.17.0 (2023-10-31) +------------------- + +3.16.0 (2023-09-20) +------------------- + +3.15.0 (2023-09-11) +------------------- + +3.14.0 (2023-08-16) +------------------- + +3.13.0 (2023-08-04) +------------------- + +3.12.0 (2023-07-18) +------------------- + +3.11.0 (2023-06-24) +------------------- + +3.10.1 (2023-06-06) +------------------- + +3.10.0 (2023-06-04) +------------------- + +3.9.0 (2023-05-28) +------------------ + +3.8.0 (2023-05-14) +------------------ + +3.7.0 (2023-05-02) +------------------ + +3.6.0 (2023-04-29) +------------------ + +3.5.0 (2023-04-14) +------------------ + +3.4.0 (2023-04-02) +------------------ + +3.3.0 (2023-03-07) +------------------ + +3.2.0 (2023-02-10) +------------------ + +3.1.0 (2023-01-26) +------------------ + +3.0.0 (2023-01-19) +------------------ + +2.15.0 (2022-12-06) +------------------- + +2.14.0 (2022-11-18) +------------------- + +2.13.0 (2022-10-05) +------------------- + +2.12.0 (2022-09-01) +------------------- + +2.11.0 (2022-08-04) +------------------- + +2.10.0 (2022-08-01) +------------------- + +2.9.0 (2022-07-14) +------------------ + +2.8.0 (2022-07-09) +------------------ + +2.7.0 (2022-07-03) +------------------ + +2.6.0 (2022-06-18) +------------------ + +2.5.0 (2022-05-13) +------------------ + +2.4.0 (2022-04-29) +------------------ + +2.3.0 (2022-04-21) +------------------ + +2.2.0 (2022-03-25) +------------------ + +2.1.0 (2022-02-23) +------------------ + +2.0.1 (2022-02-01) +------------------ + +2.0.0 (2022-01-28) +------------------ + +1.3.0 (2022-01-11) +------------------ + +1.2.0 (2021-12-29) +------------------ + +1.1.0 (2021-10-25) +------------------ + +1.0.0 (2021-09-29) +------------------ + +0.5.0 (2021-08-30) +------------------ + +0.4.1 (2021-07-08) +------------------ + +0.4.0 (2021-06-28) +------------------ + +0.3.1 (2021-05-23) +------------------ + +0.3.0 (2021-05-21) +------------------ + +0.2.1 (2021-05-03) +------------------ + +0.2.0 (2021-02-06) +------------------ + +0.1.2 (2021-01-07) +------------------ + +0.1.1 (2021-01-06) +------------------ + +0.1.0 (2020-12-23) +------------------ diff --git a/chained_filter_controller/package.xml b/chained_filter_controller/package.xml index d90a041621..2844f2502e 100644 --- a/chained_filter_controller/package.xml +++ b/chained_filter_controller/package.xml @@ -2,7 +2,7 @@ chained_filter_controller - 0.0.0 + 4.30.1 ros2_controller for configuring filter chains Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 52ce1f1e58..00a96d0ad9 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 77d1204791..71c15fd424 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index f95ccb6a51..f02a1dd95c 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 50b41a94c0..b49075ddf5 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 65b45a580b..baae1d54b6 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index d3c8fc0131..05993f9342 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index b6acda19b2..174ff2e074 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Add deprecation notice of gripper_action_controller to docs (`#1852 `_) +* Contributors: Christoph Fröhlich + 4.30.1 (2025-08-03) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 26b962ec70..4059950ab3 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 2d727fd1dc..b3932eace8 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* docs(joint_state_broadcaster): clarify /dynamic_joint_states contents (backport `#1865 `_) (`#1871 `_) +* Contributors: mergify[bot] + 4.30.1 (2025-08-03) ------------------- diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index ccd56baefe..fbfe75cf52 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- * Reset JTC PID's to zero on_activate() (backport `#1840 `_) (`#1844 `_) diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 136ed6ecb5..14a8cc5ae9 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst index 04648a8a4a..11c83cd43a 100644 --- a/omni_wheel_drive_controller/CHANGELOG.rst +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package omni_wheel_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 4cf68b6ab7..2151cd03e6 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 9cfde333e4..8ebe8eab39 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 0de2be084b..85eac10578 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 0cbb0fa82d..3eacd12b70 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index f71fdcce11..5f1e613332 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 680010b80d..bcefe9cdbd 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Add a generic chained_filter_controller (backport `#1634 `_) (`#1856 `_) +* Contributors: mergify[bot] + 4.30.1 (2025-08-03) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 59abdf1a7f..97cdba6878 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 614b8cddfb..b865b50bfe 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 4710c13da8..18c0730d2c 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index adf7cecd39..8819d8cba6 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 48b69b20b4..5c711e50b7 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index ab9dd54dd4..0580ff5f25 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.30.1 (2025-08-03) ------------------- From d399bc0f594fe4a261b286bb30da20fe27124d47 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Wed, 27 Aug 2025 12:29:54 +0100 Subject: [PATCH 064/108] 4.31.0 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- chained_filter_controller/CHANGELOG.rst | 4 ++-- chained_filter_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- omni_wheel_drive_controller/CHANGELOG.rst | 4 ++-- omni_wheel_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 58 files changed, 86 insertions(+), 86 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index d6d1ccf56b..f784015695 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index dac4f55532..a887f1f391 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.30.1 + 4.31.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 85f1ddfe08..7cd4c15830 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- * chore: tf2_ros to hpp headers (backport `#1866 `_) (`#1869 `_) * Contributors: mergify[bot] diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index a40ab5b28d..b3e7abe78a 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.30.1 + 4.31.0 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index c380dd5d78..77807eeeef 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index 639a597fd8..00800dfa97 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.30.1 + 4.31.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/chained_filter_controller/CHANGELOG.rst b/chained_filter_controller/CHANGELOG.rst index 217b28abd0..6f3a91e5eb 100644 --- a/chained_filter_controller/CHANGELOG.rst +++ b/chained_filter_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package chained_filter_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- * Add a generic chained_filter_controller (backport `#1634 `_) (`#1856 `_) * Contributors: Ankur Bodhe diff --git a/chained_filter_controller/package.xml b/chained_filter_controller/package.xml index 2844f2502e..2c003cc37a 100644 --- a/chained_filter_controller/package.xml +++ b/chained_filter_controller/package.xml @@ -2,7 +2,7 @@ chained_filter_controller - 4.30.1 + 4.31.0 ros2_controller for configuring filter chains Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 00a96d0ad9..7573948f81 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 9c2f32667c..330a993d9e 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.30.1 + 4.31.0 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 71c15fd424..b65dcd1976 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index 7e33398a89..a18e91dc0d 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.30.1 + 4.31.0 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index f02a1dd95c..372b9fcfbc 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 879cdd6231..5ccf51aa9e 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.30.1 + 4.31.0 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index b49075ddf5..505f772c23 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index e6ba255368..bf255fd208 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.30.1 + 4.31.0 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index baae1d54b6..39e8852073 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index c90436832e..02c348e23b 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.30.1 + 4.31.0 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 05993f9342..8e65152bf8 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index 471517f354..7ad521ff1d 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.30.1 + 4.31.0 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 174ff2e074..6fcd579b99 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- * Add deprecation notice of gripper_action_controller to docs (`#1852 `_) * Contributors: Christoph Fröhlich diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index 512c5a96be..8562ddca25 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.30.1 + 4.31.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 4059950ab3..6af4fd326c 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index cdd63e400f..e8d584b68f 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.30.1 + 4.31.0 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index b3932eace8..573d061f4b 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- * docs(joint_state_broadcaster): clarify /dynamic_joint_states contents (backport `#1865 `_) (`#1871 `_) * Contributors: mergify[bot] diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index 1481e13f27..5c7ba04707 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.30.1 + 4.31.0 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index fbfe75cf52..b7513ad3cc 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 0291d13f87..9032b24226 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.30.1 + 4.31.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 14a8cc5ae9..688296c341 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index a9b0f67cd4..c6d0f20d26 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.30.1 + 4.31.0 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst index 11c83cd43a..1b3bf8d675 100644 --- a/omni_wheel_drive_controller/CHANGELOG.rst +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package omni_wheel_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/omni_wheel_drive_controller/package.xml b/omni_wheel_drive_controller/package.xml index 651ed3955e..4083a236d4 100644 --- a/omni_wheel_drive_controller/package.xml +++ b/omni_wheel_drive_controller/package.xml @@ -2,7 +2,7 @@ omni_wheel_drive_controller - 4.30.1 + 4.31.0 A chainable controller for mobile robots with omnidirectional drive with three or more omni wheels. Apache License 2.0 diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 2151cd03e6..1febd3737f 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index a68f27e7fc..b9ae912722 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.30.1 + 4.31.0 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 8ebe8eab39..476a74c9c6 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/pid_controller/package.xml b/pid_controller/package.xml index c9a1549d93..b0f3deb79d 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.30.1 + 4.31.0 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 85eac10578..3ab8fcbed7 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index 58d390c0a8..47fc89564e 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.30.1 + 4.31.0 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 3eacd12b70..25af39ab90 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index f3e9d3cde1..2dca27c39b 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.30.1 + 4.31.0 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 5f1e613332..cbc74e953f 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index abf54ce207..b95b2693ed 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.30.1 + 4.31.0 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index bcefe9cdbd..376c0ac9e3 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- * Add a generic chained_filter_controller (backport `#1634 `_) (`#1856 `_) * Contributors: mergify[bot] diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index cc2c48e4cf..01c5ed0cba 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.30.1 + 4.31.0 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 97cdba6878..ccab3fff72 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 8000b48e9c..35bc64c243 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.30.1 + 4.31.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index f6ac0ebd42..38d1387cb8 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.30.1", + version="4.31.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index b865b50bfe..1875247261 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 9dedd838b8..5e3fa0d966 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.30.1 + 4.31.0 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index c41703fd03..410e2ee3a5 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.30.1", + version="4.31.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 18c0730d2c..c620ac7c0c 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index 314df0f4c5..6506fc5102 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.30.1 + 4.31.0 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 8819d8cba6..d132dafc25 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index 693b3b61b4..12de6ade54 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.30.1 + 4.31.0 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 5c711e50b7..6be565afea 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index bd0a7142d8..629a472a10 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.30.1 + 4.31.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 0580ff5f25..b26597bece 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.31.0 (2025-08-27) +------------------- 4.30.1 (2025-08-03) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index 23ef4df6a3..06fb223b14 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.30.1 + 4.31.0 Generic controller for forwarding commands. Bence Magyar From 71bce6df5cbd99f50bce288df293b49167e9408c Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 27 Aug 2025 20:07:20 +0200 Subject: [PATCH 065/108] Fix `github.ref` check for concurrency settings (backport #1872) (#1874) --- .github/workflows/humble-abi-compatibility.yml | 4 ++-- .github/workflows/humble-binary-build.yml | 4 ++-- .github/workflows/humble-coverage-build.yml | 4 ++-- .github/workflows/humble-debian-build.yml | 4 ++-- .github/workflows/humble-rhel-semi-binary-build.yml | 4 ++-- .github/workflows/humble-semi-binary-build.yml | 4 ++-- .github/workflows/jazzy-abi-compatibility.yml | 4 ++-- .github/workflows/jazzy-binary-build.yml | 4 ++-- .github/workflows/jazzy-coverage-build.yml | 4 ++-- .github/workflows/jazzy-debian-build.yml | 4 ++-- .github/workflows/jazzy-rhel-semi-binary-build.yml | 4 ++-- .github/workflows/jazzy-semi-binary-build.yml | 4 ++-- .github/workflows/rolling-abi-compatibility.yml | 4 ++-- .github/workflows/rolling-binary-build.yml | 4 ++-- .../workflows/rolling-compatibility-humble-binary-build.yml | 4 ++-- .../workflows/rolling-compatibility-jazzy-binary-build.yml | 4 ++-- .../workflows/rolling-compatibility-kilted-binary-build.yml | 4 ++-- .github/workflows/rolling-coverage-build.yml | 4 ++-- .github/workflows/rolling-debian-build.yml | 4 ++-- .github/workflows/rolling-rhel-semi-binary-build.yml | 4 ++-- .github/workflows/rolling-semi-binary-build.yml | 4 ++-- 21 files changed, 42 insertions(+), 42 deletions(-) diff --git a/.github/workflows/humble-abi-compatibility.yml b/.github/workflows/humble-abi-compatibility.yml index 4023b42a7b..03b6511233 100644 --- a/.github/workflows/humble-abi-compatibility.yml +++ b/.github/workflows/humble-abi-compatibility.yml @@ -17,9 +17,9 @@ on: - '**.xml' concurrency: - # cancel previous runs of the same workflow, except for pushes on humble branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: abi_check: diff --git a/.github/workflows/humble-binary-build.yml b/.github/workflows/humble-binary-build.yml index e0fccb05cb..2c202eb4ee 100644 --- a/.github/workflows/humble-binary-build.yml +++ b/.github/workflows/humble-binary-build.yml @@ -37,9 +37,9 @@ on: - cron: '03 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on humble branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: binary: diff --git a/.github/workflows/humble-coverage-build.yml b/.github/workflows/humble-coverage-build.yml index 55d4aa0cfd..9b5490faa9 100644 --- a/.github/workflows/humble-coverage-build.yml +++ b/.github/workflows/humble-coverage-build.yml @@ -33,9 +33,9 @@ on: - '**.xml' concurrency: - # cancel previous runs of the same workflow, except for pushes on humble branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: coverage_humble: diff --git a/.github/workflows/humble-debian-build.yml b/.github/workflows/humble-debian-build.yml index 195f1b084c..f8c457e24f 100644 --- a/.github/workflows/humble-debian-build.yml +++ b/.github/workflows/humble-debian-build.yml @@ -20,9 +20,9 @@ on: - cron: '03 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on humble branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: debian_semi_binary_build: diff --git a/.github/workflows/humble-rhel-semi-binary-build.yml b/.github/workflows/humble-rhel-semi-binary-build.yml index 3e11c5e681..670037fa24 100644 --- a/.github/workflows/humble-rhel-semi-binary-build.yml +++ b/.github/workflows/humble-rhel-semi-binary-build.yml @@ -20,9 +20,9 @@ on: - cron: '03 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on humble branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: rhel_semi_binary_build: diff --git a/.github/workflows/humble-semi-binary-build.yml b/.github/workflows/humble-semi-binary-build.yml index d74dd9ff79..2ed8c6b235 100644 --- a/.github/workflows/humble-semi-binary-build.yml +++ b/.github/workflows/humble-semi-binary-build.yml @@ -36,9 +36,9 @@ on: - cron: '33 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on humble branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: semi_binary: diff --git a/.github/workflows/jazzy-abi-compatibility.yml b/.github/workflows/jazzy-abi-compatibility.yml index f4647b334a..527fd59738 100644 --- a/.github/workflows/jazzy-abi-compatibility.yml +++ b/.github/workflows/jazzy-abi-compatibility.yml @@ -16,9 +16,9 @@ on: - '**.xml' concurrency: - # cancel previous runs of the same workflow, except for pushes on jazzy branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: abi_check: diff --git a/.github/workflows/jazzy-binary-build.yml b/.github/workflows/jazzy-binary-build.yml index b258c54443..b4cf99e8f7 100644 --- a/.github/workflows/jazzy-binary-build.yml +++ b/.github/workflows/jazzy-binary-build.yml @@ -38,9 +38,9 @@ on: - cron: '03 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on jazzy branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: binary: diff --git a/.github/workflows/jazzy-coverage-build.yml b/.github/workflows/jazzy-coverage-build.yml index 3e4d617ced..a519b0263a 100644 --- a/.github/workflows/jazzy-coverage-build.yml +++ b/.github/workflows/jazzy-coverage-build.yml @@ -33,9 +33,9 @@ on: - 'ros2_controllers.jazzy.repos' concurrency: - # cancel previous runs of the same workflow, except for pushes on jazzy branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: coverage_jazzy: diff --git a/.github/workflows/jazzy-debian-build.yml b/.github/workflows/jazzy-debian-build.yml index ed30fc88fc..4fe2bb0dea 100644 --- a/.github/workflows/jazzy-debian-build.yml +++ b/.github/workflows/jazzy-debian-build.yml @@ -20,9 +20,9 @@ on: - cron: '03 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on jazzy branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: debian_semi_binary_build: diff --git a/.github/workflows/jazzy-rhel-semi-binary-build.yml b/.github/workflows/jazzy-rhel-semi-binary-build.yml index c6beef4f63..113dbe636a 100644 --- a/.github/workflows/jazzy-rhel-semi-binary-build.yml +++ b/.github/workflows/jazzy-rhel-semi-binary-build.yml @@ -20,9 +20,9 @@ on: - cron: '03 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on jazzy branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: rhel_semi_binary_build: diff --git a/.github/workflows/jazzy-semi-binary-build.yml b/.github/workflows/jazzy-semi-binary-build.yml index c0666f5009..69f74a56b6 100644 --- a/.github/workflows/jazzy-semi-binary-build.yml +++ b/.github/workflows/jazzy-semi-binary-build.yml @@ -38,9 +38,9 @@ on: - cron: '33 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on jazzy branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: semi_binary: diff --git a/.github/workflows/rolling-abi-compatibility.yml b/.github/workflows/rolling-abi-compatibility.yml index 56b7894308..6ac9220497 100644 --- a/.github/workflows/rolling-abi-compatibility.yml +++ b/.github/workflows/rolling-abi-compatibility.yml @@ -17,9 +17,9 @@ on: - '**.xml' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: abi_check: diff --git a/.github/workflows/rolling-binary-build.yml b/.github/workflows/rolling-binary-build.yml index 4be5a36c05..0bfd29ada5 100644 --- a/.github/workflows/rolling-binary-build.yml +++ b/.github/workflows/rolling-binary-build.yml @@ -41,9 +41,9 @@ on: - cron: '03 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: binary: diff --git a/.github/workflows/rolling-compatibility-humble-binary-build.yml b/.github/workflows/rolling-compatibility-humble-binary-build.yml index 54f85ecf4b..fc37f5baa5 100644 --- a/.github/workflows/rolling-compatibility-humble-binary-build.yml +++ b/.github/workflows/rolling-compatibility-humble-binary-build.yml @@ -36,9 +36,9 @@ on: - '**.xml' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: build-on-humble: diff --git a/.github/workflows/rolling-compatibility-jazzy-binary-build.yml b/.github/workflows/rolling-compatibility-jazzy-binary-build.yml index a3f406fe87..ec4472e745 100644 --- a/.github/workflows/rolling-compatibility-jazzy-binary-build.yml +++ b/.github/workflows/rolling-compatibility-jazzy-binary-build.yml @@ -36,9 +36,9 @@ on: - '**.xml' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: build-on-jazzy: diff --git a/.github/workflows/rolling-compatibility-kilted-binary-build.yml b/.github/workflows/rolling-compatibility-kilted-binary-build.yml index 44ff443346..e45283b4d2 100644 --- a/.github/workflows/rolling-compatibility-kilted-binary-build.yml +++ b/.github/workflows/rolling-compatibility-kilted-binary-build.yml @@ -36,9 +36,9 @@ on: - '**.xml' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: build-on-kilted: diff --git a/.github/workflows/rolling-coverage-build.yml b/.github/workflows/rolling-coverage-build.yml index cd40b1954d..6277ad018c 100644 --- a/.github/workflows/rolling-coverage-build.yml +++ b/.github/workflows/rolling-coverage-build.yml @@ -33,9 +33,9 @@ on: - '**.xml' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: coverage_rolling: diff --git a/.github/workflows/rolling-debian-build.yml b/.github/workflows/rolling-debian-build.yml index 9de2912060..f8f4882b18 100644 --- a/.github/workflows/rolling-debian-build.yml +++ b/.github/workflows/rolling-debian-build.yml @@ -21,9 +21,9 @@ on: - cron: '03 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: debian_semi_binary_build: diff --git a/.github/workflows/rolling-rhel-semi-binary-build.yml b/.github/workflows/rolling-rhel-semi-binary-build.yml index f2f60c6c6d..a00d4603a2 100644 --- a/.github/workflows/rolling-rhel-semi-binary-build.yml +++ b/.github/workflows/rolling-rhel-semi-binary-build.yml @@ -21,9 +21,9 @@ on: - cron: '03 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + 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 987c341a60..82ff2455a7 100644 --- a/.github/workflows/rolling-semi-binary-build.yml +++ b/.github/workflows/rolling-semi-binary-build.yml @@ -40,9 +40,9 @@ on: - cron: '33 1 * * MON-FRI' concurrency: - # cancel previous runs of the same workflow, except for pushes on master branch + # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ !startsWith(github.ref, '/refs/heads') }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} jobs: semi_binary: From f84104490c91237fd74edb850f664d42ca01a52d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 1 Sep 2025 08:22:11 +0200 Subject: [PATCH 066/108] Bump version of pre-commit hooks (backport #1878) (#1880) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9e5474800f..2c4c45f5fd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: # Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: check-added-large-files - id: check-ast @@ -64,7 +64,7 @@ repos: # CPP hooks - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v20.1.8 + rev: v21.1.0 hooks: - id: clang-format args: ['-fallback-style=none', '-i'] @@ -134,7 +134,7 @@ repos: exclude: CHANGELOG\.rst|\.(svg|pyc|drawio)$ - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.33.2 + rev: 0.33.3 hooks: - id: check-github-workflows args: ["--verbose"] From 359f2b23e44aae4cd4342d641ffb498cf87d3597 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 07:47:56 +0200 Subject: [PATCH 067/108] [omni_wheel_drive_controller] Fix the broken links (backport #1882) (#1883) --- omni_wheel_drive_controller/doc/userdoc.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/omni_wheel_drive_controller/doc/userdoc.rst b/omni_wheel_drive_controller/doc/userdoc.rst index 1c88bf840c..3665d808f9 100644 --- a/omni_wheel_drive_controller/doc/userdoc.rst +++ b/omni_wheel_drive_controller/doc/userdoc.rst @@ -68,11 +68,11 @@ Publishers Parameters ,,,,,,,,,, -This controller uses the `generate_parameter_library `_ to handle its parameters. The parameter `definition file located in the src folder `_ contains descriptions for all the parameters used by the controller. +This controller uses the `generate_parameter_library `_ to handle its parameters. The parameter `definition file located in the src folder `_ contains descriptions for all the parameters used by the controller. .. generate_parameter_library_details:: ../src/omni_wheel_drive_controller_parameters.yaml -An example parameter file for this controller can be found in `the test directory `_: +An example parameter file for this controller can be found in `the test directory `_: .. literalinclude:: ../test/config/test_omni_wheel_drive_controller.yaml :language: yaml From 335334a26edfead2374e14ac0597ae9ccc40cf23 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 3 Sep 2025 22:29:08 +0200 Subject: [PATCH 068/108] Add prerelease jobs (backport #1881) (#1885) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christoph Fröhlich --- .github/workflows/humble-pre-release.yml | 27 ++++++++++++++++ .../humble-semi-binary-downstream-build.yml | 12 ------- .github/workflows/jazzy-pre-release.yml | 27 ++++++++++++++++ .../jazzy-semi-binary-downstream-build.yml | 12 ------- .github/workflows/rolling-pre-release.yml | 32 +++++++++++++++++++ .../rolling-semi-binary-downstream-build.yml | 16 ---------- downstream.humble.repos | 5 --- downstream.jazzy.repos | 5 --- downstream.kilted.repos | 5 --- downstream.rolling.repos | 5 --- 10 files changed, 86 insertions(+), 60 deletions(-) create mode 100644 .github/workflows/humble-pre-release.yml create mode 100644 .github/workflows/jazzy-pre-release.yml create mode 100644 .github/workflows/rolling-pre-release.yml delete mode 100644 downstream.humble.repos delete mode 100644 downstream.jazzy.repos delete mode 100644 downstream.kilted.repos delete mode 100644 downstream.rolling.repos diff --git a/.github/workflows/humble-pre-release.yml b/.github/workflows/humble-pre-release.yml new file mode 100644 index 0000000000..a8a4dab1a0 --- /dev/null +++ b/.github/workflows/humble-pre-release.yml @@ -0,0 +1,27 @@ +name: Humble - pre-release +# author: Christoph Froehlich + +on: + workflow_dispatch: + inputs: + downstream_depth: + description: 'The depth of the depends-on tree to be included in the overlay workspace (-1 implies unlimited, default: 0)' + required: false + default: 0 + type: number + pull_request: + branches: + - humble + types: + - opened # default + - reopened # default + - synchronize # default + - labeled # also if a label changes + +jobs: + default: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-prerelease.yml@master + with: + ros_distro: humble + # downstream_depth is not set on pull_request event + prerelease_downstream_depth: ${{ github.event_name == 'pull_request' && '0' || inputs.downstream_depth }} diff --git a/.github/workflows/humble-semi-binary-downstream-build.yml b/.github/workflows/humble-semi-binary-downstream-build.yml index a9ba472ff1..aac43839b5 100644 --- a/.github/workflows/humble-semi-binary-downstream-build.yml +++ b/.github/workflows/humble-semi-binary-downstream-build.yml @@ -36,15 +36,3 @@ jobs: # we test the downstream packages, which are part of our organization downstream_workspace: ros_controls.humble.repos not_test_downstream: false - build-downstream-3rd-party: - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master - with: - ros_distro: humble - ros_repo: testing - ref_for_scheduled_build: humble - upstream_workspace: ros2_controllers.humble.repos - # we don't test this repository, we just build it - not_test_build: true - # we don't test the downstream packages, which are outside of our organization - downstream_workspace: downstream.humble.repos - not_test_downstream: true diff --git a/.github/workflows/jazzy-pre-release.yml b/.github/workflows/jazzy-pre-release.yml new file mode 100644 index 0000000000..0ab61dfcd9 --- /dev/null +++ b/.github/workflows/jazzy-pre-release.yml @@ -0,0 +1,27 @@ +name: Jazzy - pre-release +# author: Christoph Froehlich + +on: + workflow_dispatch: + inputs: + downstream_depth: + description: 'The depth of the depends-on tree to be included in the overlay workspace (-1 implies unlimited, default: 0)' + required: false + default: 0 + type: number + pull_request: + branches: + - jazzy + types: + - opened # default + - reopened # default + - synchronize # default + - labeled # also if a label changes + +jobs: + default: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-prerelease.yml@master + with: + ros_distro: jazzy + # downstream_depth is not set on pull_request event + prerelease_downstream_depth: ${{ github.event_name == 'pull_request' && '0' || inputs.downstream_depth }} diff --git a/.github/workflows/jazzy-semi-binary-downstream-build.yml b/.github/workflows/jazzy-semi-binary-downstream-build.yml index d1627ccc42..62ba27bedd 100644 --- a/.github/workflows/jazzy-semi-binary-downstream-build.yml +++ b/.github/workflows/jazzy-semi-binary-downstream-build.yml @@ -36,15 +36,3 @@ jobs: # we test the downstream packages, which are part of our organization downstream_workspace: ros_controls.jazzy.repos not_test_downstream: false - build-downstream-3rd-party: - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master - with: - ros_distro: jazzy - ros_repo: testing - ref_for_scheduled_build: jazzy - upstream_workspace: ros2_controllers.jazzy.repos - # we don't test this repository, we just build it - not_test_build: true - # we don't test the downstream packages, which are outside of our organization - downstream_workspace: downstream.jazzy.repos - not_test_downstream: true diff --git a/.github/workflows/rolling-pre-release.yml b/.github/workflows/rolling-pre-release.yml new file mode 100644 index 0000000000..95609af1cd --- /dev/null +++ b/.github/workflows/rolling-pre-release.yml @@ -0,0 +1,32 @@ +name: Rolling - pre-release +# author: Christoph Froehlich + +on: + workflow_dispatch: + inputs: + downstream_depth: + description: 'The depth of the depends-on tree to be included in the overlay workspace (-1 implies unlimited, default: 0)' + required: false + default: 0 + type: number + pull_request: + branches: + - master + types: + - opened # default + - reopened # default + - synchronize # default + - labeled # also if a label changes + +jobs: + default: + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [kilted, rolling] + + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-prerelease.yml@master + with: + ros_distro: ${{ matrix.ROS_DISTRO }} + # downstream_depth is not set on pull_request event + prerelease_downstream_depth: ${{ github.event_name == 'pull_request' && '0' || inputs.downstream_depth }} diff --git a/.github/workflows/rolling-semi-binary-downstream-build.yml b/.github/workflows/rolling-semi-binary-downstream-build.yml index a392336c7f..bd3cd1490a 100644 --- a/.github/workflows/rolling-semi-binary-downstream-build.yml +++ b/.github/workflows/rolling-semi-binary-downstream-build.yml @@ -41,19 +41,3 @@ jobs: # we test the downstream packages, which are part of our organization downstream_workspace: ros_controls.${{ matrix.ROS_DISTRO }}.repos not_test_downstream: false - build-downstream-3rd-party: - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master - strategy: - fail-fast: false - matrix: - ROS_DISTRO: [kilted, rolling] - with: - ros_distro: ${{ matrix.ROS_DISTRO }} - ros_repo: testing - ref_for_scheduled_build: master - upstream_workspace: ros2_controllers.${{ matrix.ROS_DISTRO }}.repos - # we don't test this repository, we just build it - not_test_build: true - # we don't test the downstream packages, which are outside of our organization - downstream_workspace: downstream.${{ matrix.ROS_DISTRO }}.repos - not_test_downstream: true diff --git a/downstream.humble.repos b/downstream.humble.repos deleted file mode 100644 index 81feb3723b..0000000000 --- a/downstream.humble.repos +++ /dev/null @@ -1,5 +0,0 @@ -repositories: - UniversalRobots/Universal_Robots_ROS2_Driver: - type: git - url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver.git - version: humble diff --git a/downstream.jazzy.repos b/downstream.jazzy.repos deleted file mode 100644 index e5a26574b7..0000000000 --- a/downstream.jazzy.repos +++ /dev/null @@ -1,5 +0,0 @@ -repositories: - UniversalRobots/Universal_Robots_ROS2_Driver: - type: git - url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver.git - version: main diff --git a/downstream.kilted.repos b/downstream.kilted.repos deleted file mode 100644 index e5a26574b7..0000000000 --- a/downstream.kilted.repos +++ /dev/null @@ -1,5 +0,0 @@ -repositories: - UniversalRobots/Universal_Robots_ROS2_Driver: - type: git - url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver.git - version: main diff --git a/downstream.rolling.repos b/downstream.rolling.repos deleted file mode 100644 index e5a26574b7..0000000000 --- a/downstream.rolling.repos +++ /dev/null @@ -1,5 +0,0 @@ -repositories: - UniversalRobots/Universal_Robots_ROS2_Driver: - type: git - url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver.git - version: main From 1a30add71c4b4e458caaad7c0862554bef635135 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 5 Sep 2025 21:33:45 +0200 Subject: [PATCH 069/108] Fix use of M_PI in omni_wheel_driver_controller on MSVC (backport #1886) (#1887) --- omni_wheel_drive_controller/src/odometry.cpp | 2 ++ omni_wheel_drive_controller/src/omni_wheel_drive_controller.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/omni_wheel_drive_controller/src/odometry.cpp b/omni_wheel_drive_controller/src/odometry.cpp index d78caebbf4..0ec266a6af 100644 --- a/omni_wheel_drive_controller/src/odometry.cpp +++ b/omni_wheel_drive_controller/src/odometry.cpp @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#define _USE_MATH_DEFINES + #include "omni_wheel_drive_controller/odometry.hpp" #include diff --git a/omni_wheel_drive_controller/src/omni_wheel_drive_controller.cpp b/omni_wheel_drive_controller/src/omni_wheel_drive_controller.cpp index 966232898c..0009c4632f 100644 --- a/omni_wheel_drive_controller/src/omni_wheel_drive_controller.cpp +++ b/omni_wheel_drive_controller/src/omni_wheel_drive_controller.cpp @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#define _USE_MATH_DEFINES + #include "omni_wheel_drive_controller/omni_wheel_drive_controller.hpp" #include From f03e50b377cf109491050e42763551ace130a437 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 9 Sep 2025 10:09:47 +0200 Subject: [PATCH 070/108] Bump actions/stale from 9 to 10 (backport #1894) (#1896) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index f30de29b75..75b6b01885 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -12,7 +12,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@v9 + - uses: actions/stale@v10 with: stale-issue-label: 'stale' stale-pr-label: 'stale' From 1ff0951b475e19af6f3f0010d942583f7bd22daf Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 9 Sep 2025 15:45:59 +0200 Subject: [PATCH 071/108] Added frame_id to Joint State Broadcaster (backport #1746) (#1897) Co-authored-by: Jakub "Deli" Delicat --- .../joint_state_broadcaster.hpp | 2 ++ .../src/joint_state_broadcaster.cpp | 8 ++++++ .../joint_state_broadcaster_parameters.yaml | 5 ++++ .../test/test_joint_state_broadcaster.cpp | 27 +++++++++++++++++++ .../test/test_joint_state_broadcaster.hpp | 1 + 5 files changed, 43 insertions(+) diff --git a/joint_state_broadcaster/include/joint_state_broadcaster/joint_state_broadcaster.hpp b/joint_state_broadcaster/include/joint_state_broadcaster/joint_state_broadcaster.hpp index f12c192831..85d2b93765 100644 --- a/joint_state_broadcaster/include/joint_state_broadcaster/joint_state_broadcaster.hpp +++ b/joint_state_broadcaster/include/joint_state_broadcaster/joint_state_broadcaster.hpp @@ -97,6 +97,8 @@ class JointStateBroadcaster : public controller_interface::ControllerInterface Params params_; std::unordered_map map_interface_to_joint_state_; + std::string frame_id_; + // For the JointState message, // we store the name of joints with compatible interfaces std::vector joint_names_; diff --git a/joint_state_broadcaster/src/joint_state_broadcaster.cpp b/joint_state_broadcaster/src/joint_state_broadcaster.cpp index c6857cf245..b88971a3a6 100644 --- a/joint_state_broadcaster/src/joint_state_broadcaster.cpp +++ b/joint_state_broadcaster/src/joint_state_broadcaster.cpp @@ -181,6 +181,12 @@ controller_interface::CallbackReturn JointStateBroadcaster::on_configure( joint_state_msg.velocity.reserve(max_joints_size); joint_state_msg.effort.reserve(max_joints_size); + frame_id_ = params_.frame_id; + if (frame_id_.empty()) + { + RCLCPP_WARN(get_node()->get_logger(), "Frame ID is not set."); + } + return CallbackReturn::SUCCESS; } @@ -313,6 +319,7 @@ void JointStateBroadcaster::init_joint_state_msg() // default initialization for joint state message auto & joint_state_msg = realtime_joint_state_publisher_->msg_; + joint_state_msg.header.frame_id = frame_id_; joint_state_msg.name = joint_names_; joint_state_msg.position.resize(num_joints, kUninitializedValue); joint_state_msg.velocity.resize(num_joints, kUninitializedValue); @@ -346,6 +353,7 @@ void JointStateBroadcaster::init_joint_state_msg() void JointStateBroadcaster::init_dynamic_joint_state_msg() { auto & dynamic_joint_state_msg = realtime_dynamic_joint_state_publisher_->msg_; + dynamic_joint_state_msg.header.frame_id = frame_id_; dynamic_joint_state_msg.joint_names.clear(); dynamic_joint_state_msg.interface_values.clear(); for (const auto & name_ifv : name_if_value_mapping_) diff --git a/joint_state_broadcaster/src/joint_state_broadcaster_parameters.yaml b/joint_state_broadcaster/src/joint_state_broadcaster_parameters.yaml index c8ca928a12..ae525b42a8 100644 --- a/joint_state_broadcaster/src/joint_state_broadcaster_parameters.yaml +++ b/joint_state_broadcaster/src/joint_state_broadcaster_parameters.yaml @@ -46,3 +46,8 @@ joint_state_broadcaster: If true, the broadcaster will publish the data of the joints present in the URDF alone. If false, the broadcaster will publish the data of any interface that has type ``position``, ``velocity``, or ``effort``." } + frame_id: { + type: string, + default_value: "base_link", + description: "The frame_id to be used in the published joint states. This parameter allows rviz2 to visualize the effort of the joints." + } diff --git a/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp b/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp index 277285b05c..fc3d430a02 100644 --- a/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp +++ b/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp @@ -77,6 +77,7 @@ void JointStateBroadcasterTest::init_broadcaster_and_set_parameters( state_broadcaster_->get_node()->set_parameter({"joints", joint_names}); state_broadcaster_->get_node()->set_parameter({"interfaces", interfaces}); + state_broadcaster_->get_node()->set_parameter({"frame_id", frame_id_}); } void JointStateBroadcasterTest::assign_state_interfaces( @@ -177,6 +178,7 @@ TEST_F(JointStateBroadcasterTest, ActivateEmptyTest) // joint state initialized const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_names_)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); @@ -185,6 +187,7 @@ TEST_F(JointStateBroadcasterTest, ActivateEmptyTest) // dynamic joint state initialized const auto & dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(joint_names_)); @@ -227,6 +230,7 @@ TEST_F(JointStateBroadcasterTest, ReactivateTheControllerWithDifferentInterfaces // joint state initialized const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_names_)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); @@ -235,6 +239,7 @@ TEST_F(JointStateBroadcasterTest, ReactivateTheControllerWithDifferentInterfaces // dynamic joint state initialized const auto & dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(joint_names_)); @@ -272,6 +277,7 @@ TEST_F(JointStateBroadcasterTest, ReactivateTheControllerWithDifferentInterfaces // joint state initialized const auto & new_joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + ASSERT_EQ(new_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(new_joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(new_joint_state_msg.position, SizeIs(NUM_JOINTS_WITH_ONE_DEACTIVATED)); ASSERT_THAT(new_joint_state_msg.velocity, SizeIs(NUM_JOINTS_WITH_ONE_DEACTIVATED)); @@ -280,6 +286,7 @@ TEST_F(JointStateBroadcasterTest, ReactivateTheControllerWithDifferentInterfaces // dynamic joint state initialized const auto & new_dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(new_dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(new_dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS_WITH_ONE_DEACTIVATED)); ASSERT_THAT( new_dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS_WITH_ONE_DEACTIVATED)); @@ -322,6 +329,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithoutJointsParameter) // joint state initialized const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_names_)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); @@ -330,6 +338,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithoutJointsParameter) // dynamic joint state initialized const auto & dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(joint_names_)); @@ -577,6 +586,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithoutInterfacesParameter) // joint state initialized const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_names_)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); @@ -585,6 +595,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithoutInterfacesParameter) // dynamic joint state initialized const auto & dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(joint_names_)); @@ -626,6 +637,7 @@ TEST_F(JointStateBroadcasterTest, ActivateDeactivateTestTwoJointsOneInterface) // joint state initialized const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); @@ -642,6 +654,7 @@ TEST_F(JointStateBroadcasterTest, ActivateDeactivateTestTwoJointsOneInterface) // dynamic joint state initialized const auto & dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(JOINT_NAMES)); @@ -690,6 +703,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestOneJointTwoInterfaces) // joint state initialized const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); @@ -702,6 +716,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestOneJointTwoInterfaces) // dynamic joint state initialized const auto & dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(JOINT_NAMES)); @@ -766,6 +781,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestTwoJointTwoInterfacesOneMissing) // joint state initialized const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); @@ -780,6 +796,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestTwoJointTwoInterfacesOneMissing) // dynamic joint state initialized const auto & dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(JOINT_NAMES)); @@ -813,6 +830,7 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceWithoutMapping) // joint state initialized const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, SizeIs(0)); ASSERT_THAT(joint_state_msg.position, SizeIs(0)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(0)); @@ -821,6 +839,7 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceWithoutMapping) // dynamic joint state initialized const auto & dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(JOINT_NAMES)); @@ -858,6 +877,7 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceMapping) // joint state initialized const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); @@ -874,6 +894,7 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceMapping) // dynamic joint state initialized const auto & dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(JOINT_NAMES)); @@ -901,6 +922,7 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceMappingUpdate) const size_t NUM_JOINTS = JOINT_NAMES.size(); // joint state initialized + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_EQ(joint_state_msg.position[0], custom_joint_value_); @@ -918,6 +940,7 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceMappingUpdate) // dynamic joint state initialized const auto & dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(JOINT_NAMES)); @@ -1107,6 +1130,7 @@ void JointStateBroadcasterTest::test_published_joint_state_message(const std::st activate_and_get_joint_state_message(topic, joint_state_msg); const size_t NUM_JOINTS = joint_names_.size(); + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, SizeIs(NUM_JOINTS)); // the order in the message may be different // we only check that all values in this test are present in the message @@ -1177,6 +1201,7 @@ void JointStateBroadcasterTest::test_published_dynamic_joint_state_message( const size_t NUM_JOINTS = 3; const std::vector INTERFACE_NAMES = {HW_IF_POSITION, HW_IF_VELOCITY, HW_IF_EFFORT}; + ASSERT_EQ(dynamic_joint_state_msg->header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg->joint_names, SizeIs(NUM_JOINTS)); // the order in the message may be different // we only check that all values in this test are present in the message @@ -1235,6 +1260,7 @@ TEST_F(JointStateBroadcasterTest, ExtraJointStatePublishTest) // joint state initialized const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(all_joint_names)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); @@ -1243,5 +1269,6 @@ TEST_F(JointStateBroadcasterTest, ExtraJointStatePublishTest) // dynamic joint state initialized const auto & dynamic_joint_state_msg = state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); } diff --git a/joint_state_broadcaster/test/test_joint_state_broadcaster.hpp b/joint_state_broadcaster/test/test_joint_state_broadcaster.hpp index a167d33bf5..158c921ddc 100644 --- a/joint_state_broadcaster/test/test_joint_state_broadcaster.hpp +++ b/joint_state_broadcaster/test/test_joint_state_broadcaster.hpp @@ -112,6 +112,7 @@ class JointStateBroadcasterTest : public ::testing::Test std::vector test_interfaces_; std::unique_ptr state_broadcaster_; + std::string frame_id_ = "base_link"; }; #endif // TEST_JOINT_STATE_BROADCASTER_HPP_ From e7c65beee2cc4e3ea02f6354a6475c49640be2f6 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:20:58 +0200 Subject: [PATCH 072/108] Preallocate `std::vector` variables for interfaces (backport #1893) (#1899) --- .../src/joint_trajectory_controller.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index a08a16e422..9e60899e03 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -769,6 +769,10 @@ controller_interface::CallbackReturn JointTrajectoryController::on_configure( // Check if only allowed interface types are used and initialize storage to avoid memory // allocation during activation joint_command_interface_.resize(allowed_interface_types_.size()); + for (auto & itf : joint_command_interface_) + { + itf.reserve(params_.joints.size()); + } has_position_command_interface_ = contains_interface_type(params_.command_interfaces, hardware_interface::HW_IF_POSITION); @@ -806,6 +810,10 @@ controller_interface::CallbackReturn JointTrajectoryController::on_configure( // allocation during activation // Note: 'effort' storage is also here, but never used. Still, for this is OK. joint_state_interface_.resize(allowed_interface_types_.size()); + for (auto & itf : joint_state_interface_) + { + itf.reserve(params_.joints.size()); + } has_position_state_interface_ = contains_interface_type(params_.state_interfaces, hardware_interface::HW_IF_POSITION); From 3597e2394495b2f9203e900d1dfef7c30ecdf889 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:22:36 +0200 Subject: [PATCH 073/108] Add windows semi-binary build workflow (backport #1892) (#1901) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christoph Fröhlich --- .../rolling-semi-binary-build-win.yml | 48 +++++++++++++++++++ ros2_controllers.windows.rolling.repos | 37 ++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 .github/workflows/rolling-semi-binary-build-win.yml create mode 100644 ros2_controllers.windows.rolling.repos diff --git a/.github/workflows/rolling-semi-binary-build-win.yml b/.github/workflows/rolling-semi-binary-build-win.yml new file mode 100644 index 0000000000..064a65a199 --- /dev/null +++ b/.github/workflows/rolling-semi-binary-build-win.yml @@ -0,0 +1,48 @@ +name: Rolling Windows Semi-Binary Build +# author: Christoph Fröhlich +# description: 'Build & test all dependencies from semi-binary packages.' + +on: + workflow_dispatch: + pull_request: + branches: + - master + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '.github/workflows/rolling-semi-binary-build-win.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.rolling.repos' + - 'ros2_controllers.windows.rolling.repos' + push: + branches: + - master + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '.github/workflows/rolling-semi-binary-build-win.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.rolling.repos' + - 'ros2_controllers.windows.rolling.repos' + +concurrency: + # cancel previous runs of the same workflow, except for pushes on given branches + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} + +jobs: + binary-windows: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-ros-tooling-win-build.yml@master + with: + ros_distro: rolling + pixi_dependencies: typeguard jinja2 boost compilers + windows_dependencies: ros2_controllers.windows.rolling.repos + ninja_packages: rsl + skip_packages: diagnostic_remote_logging generate_parameter_library_example_external generate_parameter_library_example + target_cmake_args: -DBUILD_TESTING=OFF diff --git a/ros2_controllers.windows.rolling.repos b/ros2_controllers.windows.rolling.repos new file mode 100644 index 0000000000..0c7cb73eed --- /dev/null +++ b/ros2_controllers.windows.rolling.repos @@ -0,0 +1,37 @@ +repositories: + filters: + type: git + url: https://github.com/ros/filters.git + version: ros2 + cpp_polyfills: + type: git + url: https://github.com/PickNikRobotics/cpp_polyfills.git + version: main + rsl: + type: git + url: https://github.com/PickNikRobotics/RSL.git + version: main + generate_parameter_library: + type: git + url: https://github.com/PickNikRobotics/generate_parameter_library.git + version: main + pal_statistics: + type: git + url: https://github.com/pal-robotics/pal_statistics.git + version: humble-devel + backward_ros: + type: git + url: https://github.com/pal-robotics//backward_ros.git + version: foxy-devel + diagnostics: + type: git + url: https://github.com/ros/diagnostics + version: ros2 + angles: + type: git + url: https://github.com/ros/angles + version: ros2 + ackermann_msgs: + type: git + url: https://github.com/ros-drivers/ackermann_msgs.git + version: ros2 From cd0ae98b70a97f036a5378385764b5fcf95598c0 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 10 Sep 2025 21:54:35 +0200 Subject: [PATCH 074/108] FTS: Don't make a temporary copy of semantic component (backport #1902) (#1904) --- .../src/force_torque_sensor_broadcaster.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp index 9605cd8c2a..c43d2a6b06 100644 --- a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp @@ -74,17 +74,15 @@ controller_interface::CallbackReturn ForceTorqueSensorBroadcaster::on_configure( if (!params_.sensor_name.empty()) { - force_torque_sensor_ = std::make_unique( - semantic_components::ForceTorqueSensor(params_.sensor_name)); + force_torque_sensor_ = + std::make_unique(params_.sensor_name); } else { auto const & force_names = params_.interface_names.force; auto const & torque_names = params_.interface_names.torque; force_torque_sensor_ = std::make_unique( - semantic_components::ForceTorqueSensor( - force_names.x, force_names.y, force_names.z, torque_names.x, torque_names.y, - torque_names.z)); + force_names.x, force_names.y, force_names.z, torque_names.x, torque_names.y, torque_names.z); } try From 144be31572ac63d730e3baedd660f7ad3168dbb2 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 08:13:33 +0200 Subject: [PATCH 075/108] Fix temporary copies of other semantic components (backport #1905) (#1908) --- .../src/admittance_controller.cpp | 2 +- .../src/gps_sensor_broadcaster.cpp | 16 ++++++++++------ .../src/imu_sensor_broadcaster.cpp | 3 +-- .../src/range_sensor_broadcaster.cpp | 3 +-- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/admittance_controller/src/admittance_controller.cpp b/admittance_controller/src/admittance_controller.cpp index 5c652231fd..77ff09cb01 100644 --- a/admittance_controller/src/admittance_controller.cpp +++ b/admittance_controller/src/admittance_controller.cpp @@ -321,7 +321,7 @@ controller_interface::CallbackReturn AdmittanceController::on_configure( // Initialize FTS semantic semantic_component force_torque_sensor_ = std::make_unique( - semantic_components::ForceTorqueSensor(admittance_->parameters_.ft_sensor.name)); + admittance_->parameters_.ft_sensor.name); // configure admittance rule if ( diff --git a/gps_sensor_broadcaster/src/gps_sensor_broadcaster.cpp b/gps_sensor_broadcaster/src/gps_sensor_broadcaster.cpp index 182eb0e87d..4a97dbcf1a 100644 --- a/gps_sensor_broadcaster/src/gps_sensor_broadcaster.cpp +++ b/gps_sensor_broadcaster/src/gps_sensor_broadcaster.cpp @@ -56,12 +56,16 @@ callback_return_type GPSSensorBroadcaster::on_configure(const rclcpp_lifecycle:: param_listener_->refresh_dynamic_parameters(); params_ = param_listener_->get_params(); - gps_sensor_ = - params_.read_covariance_from_interface - ? GPSSensorVariant{semantic_components::GPSSensor( - params_.sensor_name)} - : GPSSensorVariant{ - semantic_components::GPSSensor(params_.sensor_name)}; + if (params_.read_covariance_from_interface) + { + gps_sensor_.emplace>( + params_.sensor_name); + } + else + { + gps_sensor_.emplace>( + params_.sensor_name); + } std::visit( Visitor{ [this](auto & sensor) { state_names_ = sensor.get_state_interface_names(); }, diff --git a/imu_sensor_broadcaster/src/imu_sensor_broadcaster.cpp b/imu_sensor_broadcaster/src/imu_sensor_broadcaster.cpp index 04a28e5368..9d55e5cde3 100644 --- a/imu_sensor_broadcaster/src/imu_sensor_broadcaster.cpp +++ b/imu_sensor_broadcaster/src/imu_sensor_broadcaster.cpp @@ -45,8 +45,7 @@ controller_interface::CallbackReturn IMUSensorBroadcaster::on_configure( { params_ = param_listener_->get_params(); - imu_sensor_ = std::make_unique( - semantic_components::IMUSensor(params_.sensor_name)); + imu_sensor_ = std::make_unique(params_.sensor_name); try { // register ft sensor data publisher diff --git a/range_sensor_broadcaster/src/range_sensor_broadcaster.cpp b/range_sensor_broadcaster/src/range_sensor_broadcaster.cpp index 4ff817b2d3..e9c916b292 100644 --- a/range_sensor_broadcaster/src/range_sensor_broadcaster.cpp +++ b/range_sensor_broadcaster/src/range_sensor_broadcaster.cpp @@ -56,8 +56,7 @@ controller_interface::CallbackReturn RangeSensorBroadcaster::on_configure( return CallbackReturn::ERROR; } - range_sensor_ = std::make_unique( - semantic_components::RangeSensor(params_.sensor_name)); + range_sensor_ = std::make_unique(params_.sensor_name); try { // register ft sensor data publisher From a31d14cac7409b9ad2257a21d1bfe7751118d06e Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Fri, 12 Sep 2025 12:03:59 +0100 Subject: [PATCH 076/108] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 3 +++ admittance_controller/CHANGELOG.rst | 5 +++++ bicycle_steering_controller/CHANGELOG.rst | 3 +++ chained_filter_controller/CHANGELOG.rst | 3 +++ diff_drive_controller/CHANGELOG.rst | 3 +++ effort_controllers/CHANGELOG.rst | 3 +++ force_torque_sensor_broadcaster/CHANGELOG.rst | 5 +++++ forward_command_controller/CHANGELOG.rst | 3 +++ gpio_controllers/CHANGELOG.rst | 3 +++ gps_sensor_broadcaster/CHANGELOG.rst | 5 +++++ gripper_controllers/CHANGELOG.rst | 3 +++ imu_sensor_broadcaster/CHANGELOG.rst | 5 +++++ joint_state_broadcaster/CHANGELOG.rst | 5 +++++ joint_trajectory_controller/CHANGELOG.rst | 5 +++++ mecanum_drive_controller/CHANGELOG.rst | 3 +++ omni_wheel_drive_controller/CHANGELOG.rst | 6 ++++++ parallel_gripper_controller/CHANGELOG.rst | 3 +++ pid_controller/CHANGELOG.rst | 3 +++ pose_broadcaster/CHANGELOG.rst | 3 +++ position_controllers/CHANGELOG.rst | 3 +++ range_sensor_broadcaster/CHANGELOG.rst | 5 +++++ ros2_controllers/CHANGELOG.rst | 3 +++ ros2_controllers_test_nodes/CHANGELOG.rst | 3 +++ rqt_joint_trajectory_controller/CHANGELOG.rst | 3 +++ steering_controllers_library/CHANGELOG.rst | 3 +++ tricycle_controller/CHANGELOG.rst | 3 +++ tricycle_steering_controller/CHANGELOG.rst | 3 +++ velocity_controllers/CHANGELOG.rst | 3 +++ 28 files changed, 101 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index f784015695..2911800996 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 7cd4c15830..fd110b08f4 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) +* Contributors: mergify[bot] + 4.31.0 (2025-08-27) ------------------- * chore: tf2_ros to hpp headers (backport `#1866 `_) (`#1869 `_) diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 77807eeeef..07b404061c 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/chained_filter_controller/CHANGELOG.rst b/chained_filter_controller/CHANGELOG.rst index 6f3a91e5eb..7c5fda33fd 100644 --- a/chained_filter_controller/CHANGELOG.rst +++ b/chained_filter_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package chained_filter_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- * Add a generic chained_filter_controller (backport `#1634 `_) (`#1856 `_) diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 7573948f81..4198758b57 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index b65dcd1976..2c6da17cd2 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 372b9fcfbc..0a033cea5b 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* FTS: Don't make a temporary copy of semantic component (backport `#1902 `_) (`#1904 `_) +* Contributors: mergify[bot] + 4.31.0 (2025-08-27) ------------------- diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 505f772c23..574a7f7478 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 39e8852073..9da1b1452d 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 8e65152bf8..2be28a9c2e 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) +* Contributors: mergify[bot] + 4.31.0 (2025-08-27) ------------------- diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 6fcd579b99..23d8364fae 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- * Add deprecation notice of gripper_action_controller to docs (`#1852 `_) diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 6af4fd326c..6d3bdae20a 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) +* Contributors: mergify[bot] + 4.31.0 (2025-08-27) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 573d061f4b..acb5a0b48f 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Added frame_id to Joint State Broadcaster (backport `#1746 `_) (`#1897 `_) +* Contributors: mergify[bot] + 4.31.0 (2025-08-27) ------------------- * docs(joint_state_broadcaster): clarify /dynamic_joint_states contents (backport `#1865 `_) (`#1871 `_) diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index b7513ad3cc..98aaff1c06 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Preallocate `std::vector` variables for interfaces (backport `#1893 `_) (`#1899 `_) +* Contributors: mergify[bot] + 4.31.0 (2025-08-27) ------------------- diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 688296c341..b5f3ad1418 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst index 1b3bf8d675..ca74bb1398 100644 --- a/omni_wheel_drive_controller/CHANGELOG.rst +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package omni_wheel_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix use of M_PI in omni_wheel_driver_controller on MSVC (backport `#1886 `_) (`#1887 `_) +* [omni_wheel_drive_controller] Fix the broken links (backport `#1882 `_) (`#1883 `_) +* Contributors: mergify[bot] + 4.31.0 (2025-08-27) ------------------- diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 1febd3737f..367c8dd5d0 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 476a74c9c6..c354941bf1 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 3ab8fcbed7..cf312b246d 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 25af39ab90..1ca1678b3e 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index cbc74e953f..6e9185a700 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) +* Contributors: mergify[bot] + 4.31.0 (2025-08-27) ------------------- diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 376c0ac9e3..b2ea486e9f 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- * Add a generic chained_filter_controller (backport `#1634 `_) (`#1856 `_) diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index ccab3fff72..975a71b792 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 1875247261..21ae0113c1 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index c620ac7c0c..2c3ae54f69 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index d132dafc25..fd39883c24 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 6be565afea..717a1a6a2d 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index b26597bece..1619c8f380 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.31.0 (2025-08-27) ------------------- From 0bc6910e390cb184692dea4b3b4f3a0180fea49a Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Fri, 12 Sep 2025 12:04:17 +0100 Subject: [PATCH 077/108] 4.32.0 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- chained_filter_controller/CHANGELOG.rst | 4 ++-- chained_filter_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- omni_wheel_drive_controller/CHANGELOG.rst | 4 ++-- omni_wheel_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 58 files changed, 86 insertions(+), 86 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 2911800996..49f908082b 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index a887f1f391..db68a6ae01 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.31.0 + 4.32.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index fd110b08f4..005d2c42e2 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- * Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) * Contributors: mergify[bot] diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index b3e7abe78a..42dc1d9ded 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.31.0 + 4.32.0 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 07b404061c..c8968a69ee 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index 00800dfa97..441a2c473c 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.31.0 + 4.32.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/chained_filter_controller/CHANGELOG.rst b/chained_filter_controller/CHANGELOG.rst index 7c5fda33fd..1f6cd33888 100644 --- a/chained_filter_controller/CHANGELOG.rst +++ b/chained_filter_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package chained_filter_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/chained_filter_controller/package.xml b/chained_filter_controller/package.xml index 2c003cc37a..cdc1610ca7 100644 --- a/chained_filter_controller/package.xml +++ b/chained_filter_controller/package.xml @@ -2,7 +2,7 @@ chained_filter_controller - 4.31.0 + 4.32.0 ros2_controller for configuring filter chains Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 4198758b57..cc3c68d529 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 330a993d9e..87d7d747a4 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.31.0 + 4.32.0 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 2c6da17cd2..dfc6305cd5 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index a18e91dc0d..0468f8d586 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.31.0 + 4.32.0 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 0a033cea5b..d1e18139ca 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- * FTS: Don't make a temporary copy of semantic component (backport `#1902 `_) (`#1904 `_) * Contributors: mergify[bot] diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 5ccf51aa9e..94ada12aa3 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.31.0 + 4.32.0 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 574a7f7478..a34ef2bfe5 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index bf255fd208..cd5843a245 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.31.0 + 4.32.0 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 9da1b1452d..a6d20b0025 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index 02c348e23b..009b9b8b0d 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.31.0 + 4.32.0 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 2be28a9c2e..8f7396f8d0 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- * Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) * Contributors: mergify[bot] diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index 7ad521ff1d..29f6de244a 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.31.0 + 4.32.0 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 23d8364fae..2877261306 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index 8562ddca25..c79038fbb8 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.31.0 + 4.32.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 6d3bdae20a..73e8cfc78a 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- * Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) * Contributors: mergify[bot] diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index e8d584b68f..3ed9d42e89 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.31.0 + 4.32.0 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index acb5a0b48f..dc6a056a06 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- * Added frame_id to Joint State Broadcaster (backport `#1746 `_) (`#1897 `_) * Contributors: mergify[bot] diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index 5c7ba04707..4a0972c44e 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.31.0 + 4.32.0 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 98aaff1c06..ad6907acef 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- * Preallocate `std::vector` variables for interfaces (backport `#1893 `_) (`#1899 `_) * Contributors: mergify[bot] diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 9032b24226..965b7b9c5e 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.31.0 + 4.32.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index b5f3ad1418..f4765f24f8 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index c6d0f20d26..782d4c9164 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.31.0 + 4.32.0 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst index ca74bb1398..581437d0f6 100644 --- a/omni_wheel_drive_controller/CHANGELOG.rst +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package omni_wheel_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- * Fix use of M_PI in omni_wheel_driver_controller on MSVC (backport `#1886 `_) (`#1887 `_) * [omni_wheel_drive_controller] Fix the broken links (backport `#1882 `_) (`#1883 `_) * Contributors: mergify[bot] diff --git a/omni_wheel_drive_controller/package.xml b/omni_wheel_drive_controller/package.xml index 4083a236d4..8e91966f7c 100644 --- a/omni_wheel_drive_controller/package.xml +++ b/omni_wheel_drive_controller/package.xml @@ -2,7 +2,7 @@ omni_wheel_drive_controller - 4.31.0 + 4.32.0 A chainable controller for mobile robots with omnidirectional drive with three or more omni wheels. Apache License 2.0 diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 367c8dd5d0..b9b91f1032 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index b9ae912722..8ec2885316 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.31.0 + 4.32.0 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index c354941bf1..4ea2e94412 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/pid_controller/package.xml b/pid_controller/package.xml index b0f3deb79d..a6ad6e348a 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.31.0 + 4.32.0 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index cf312b246d..53198f717e 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index 47fc89564e..cc85169bd3 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.31.0 + 4.32.0 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 1ca1678b3e..de27c672db 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index 2dca27c39b..ba3439a404 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.31.0 + 4.32.0 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 6e9185a700..2407fdb555 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- * Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) * Contributors: mergify[bot] diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index b95b2693ed..059d49c9b8 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.31.0 + 4.32.0 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index b2ea486e9f..2f24eb3023 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 01c5ed0cba..521ee29588 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.31.0 + 4.32.0 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 975a71b792..495250306f 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 35bc64c243..ca0a1aa66c 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.31.0 + 4.32.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index 38d1387cb8..06db8531d1 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.31.0", + version="4.32.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 21ae0113c1..46c28615df 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 5e3fa0d966..34073bf508 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.31.0 + 4.32.0 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index 410e2ee3a5..12ce44883f 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.31.0", + version="4.32.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 2c3ae54f69..42ae8ed720 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index 6506fc5102..b7d52ec8cb 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.31.0 + 4.32.0 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index fd39883c24..c262e219c4 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index 12de6ade54..ecf34b0822 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.31.0 + 4.32.0 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 717a1a6a2d..f4eb504780 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index 629a472a10..0687f1fd5e 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.31.0 + 4.32.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 1619c8f380..0a54dcf240 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.32.0 (2025-09-12) +------------------- 4.31.0 (2025-08-27) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index 06fb223b14..3f9fb46556 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.31.0 + 4.32.0 Generic controller for forwarding commands. Bence Magyar From 89446c8f5b150a9b88b2004ebe01b4a476e59310 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:24:40 +0200 Subject: [PATCH 078/108] Don't call `release_interfaces` from controllers (backport #1910) (#1911) --- .../src/joint_trajectory_controller.cpp | 1 - .../test/test_trajectory_controller.cpp | 8 +++----- .../test/test_trajectory_controller_utils.hpp | 1 + .../parallel_gripper_action_controller_impl.hpp | 1 - .../test/test_parallel_gripper_controller.cpp | 1 + 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index 9e60899e03..117826ff3f 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -1119,7 +1119,6 @@ controller_interface::CallbackReturn JointTrajectoryController::on_deactivate( joint_command_interface_[index].clear(); joint_state_interface_[index].clear(); } - release_interfaces(); subscriber_is_active_ = false; diff --git a/joint_trajectory_controller/test/test_trajectory_controller.cpp b/joint_trajectory_controller/test/test_trajectory_controller.cpp index ec3391a9e1..a5ab3dac25 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller.cpp +++ b/joint_trajectory_controller/test/test_trajectory_controller.cpp @@ -163,10 +163,9 @@ TEST_P(TrajectoryControllerTestParameterized, cleanup) traj_controller_->update( rclcpp::Time(static_cast(0.5 * 1e9)), rclcpp::Duration::from_seconds(0.5)); - auto state = traj_controller_->get_node()->deactivate(); - ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + DeactivateTrajectoryController(); - state = traj_controller_->get_node()->cleanup(); + auto state = traj_controller_->get_node()->cleanup(); ASSERT_EQ(State::PRIMARY_STATE_UNCONFIGURED, state.id()); executor.cancel(); @@ -237,8 +236,7 @@ TEST_P(TrajectoryControllerTestParameterized, correct_initialization_using_param // deactivate std::vector deactivated_positions{joint_pos_[0], joint_pos_[1], joint_pos_[2]}; - state = traj_controller_->get_node()->deactivate(); - ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); + DeactivateTrajectoryController(); // it should be holding the current point expectHoldingPointDeactivated(deactivated_positions); diff --git a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp index f95ef24c8e..a87086e6f7 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp +++ b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp @@ -426,6 +426,7 @@ class TrajectoryControllerTest : public ::testing::Test EXPECT_EQ( traj_controller_->get_node()->deactivate().id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE); + traj_controller_->release_interfaces(); } } } diff --git a/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp b/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp index 50f91678cb..b6be291a8d 100644 --- a/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp +++ b/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp @@ -347,7 +347,6 @@ controller_interface::CallbackReturn GripperActionController::on_deactivate( joint_command_interface_ = std::nullopt; joint_position_state_interface_ = std::nullopt; joint_velocity_state_interface_ = std::nullopt; - release_interfaces(); return controller_interface::CallbackReturn::SUCCESS; } diff --git a/parallel_gripper_controller/test/test_parallel_gripper_controller.cpp b/parallel_gripper_controller/test/test_parallel_gripper_controller.cpp index 23c13b157a..0445a8fd89 100644 --- a/parallel_gripper_controller/test/test_parallel_gripper_controller.cpp +++ b/parallel_gripper_controller/test/test_parallel_gripper_controller.cpp @@ -132,6 +132,7 @@ TEST_F(GripperControllerTest, ActivateDeactivateActivateSuccess) ASSERT_EQ( this->controller_->on_deactivate(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::SUCCESS); + this->controller_->release_interfaces(); // re-assign interfaces std::vector command_ifs; From da0e6ae52983293f52d23e590b1fc9339ec2df99 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 18 Sep 2025 08:37:23 +0200 Subject: [PATCH 079/108] Fix source build workflows (backport #1914) (#1916) --- .github/workflows/humble-source-build.yml | 7 ++++++- .github/workflows/jazzy-source-build.yml | 5 +++++ .github/workflows/rolling-source-build.yml | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/humble-source-build.yml b/.github/workflows/humble-source-build.yml index de3987ce15..e193f04fb0 100644 --- a/.github/workflows/humble-source-build.yml +++ b/.github/workflows/humble-source-build.yml @@ -15,6 +15,11 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers.humble.repos' - '**.xml' + pull_request: + branches: + - humble + paths: + - '.github/workflows/humble-source-build.yml' schedule: # Run every day to detect flakiness and broken dependencies - cron: '03 3 * * MON-FRI' @@ -25,4 +30,4 @@ jobs: with: ros_distro: humble ref: humble - os_name: ubuntu-22.04 + container: ubuntu:22.04 diff --git a/.github/workflows/jazzy-source-build.yml b/.github/workflows/jazzy-source-build.yml index ffff45184f..277407456e 100644 --- a/.github/workflows/jazzy-source-build.yml +++ b/.github/workflows/jazzy-source-build.yml @@ -15,6 +15,11 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers.jazzy.repos' - '**.xml' + pull_request: + branches: + - jazzy + paths: + - '.github/workflows/jazzy-source-build.yml' schedule: # Run every day to detect flakiness and broken dependencies - cron: '03 3 * * MON-FRI' diff --git a/.github/workflows/rolling-source-build.yml b/.github/workflows/rolling-source-build.yml index e62849f22e..98f75def4a 100644 --- a/.github/workflows/rolling-source-build.yml +++ b/.github/workflows/rolling-source-build.yml @@ -16,6 +16,11 @@ on: - 'ros2_controllers.rolling.repos' - 'ros2_controllers.kilted.repos' - '**.xml' + pull_request: + branches: + - master + paths: + - '.github/workflows/rolling-source-build.yml' schedule: # Run every day to detect flakiness and broken dependencies - cron: '03 3 * * MON-FRI' From 39f5ab56347c336b1ab5a7ded9009d2fac380c0b Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:17:27 +0200 Subject: [PATCH 080/108] Remove unused variables and correctly override test class method (backport #1918) (#1920) --- .../test/test_trajectory_controller.cpp | 4 ---- .../test/test_trajectory_controller_utils.hpp | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/joint_trajectory_controller/test/test_trajectory_controller.cpp b/joint_trajectory_controller/test/test_trajectory_controller.cpp index a5ab3dac25..4ba095feee 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller.cpp +++ b/joint_trajectory_controller/test/test_trajectory_controller.cpp @@ -583,8 +583,6 @@ TEST_P(TrajectoryControllerTestParameterized, compute_error_angle_wraparound_tru size_t n_joints = joint_names_.size(); // send msg - constexpr auto FIRST_POINT_TIME = std::chrono::milliseconds(250); - builtin_interfaces::msg::Duration time_from_start{rclcpp::Duration(FIRST_POINT_TIME)}; // *INDENT-OFF* std::vector> points{ {{3.3, 4.4, 6.6}}, {{7.7, 8.8, 9.9}}, {{10.10, 11.11, 12.12}}}; @@ -675,8 +673,6 @@ TEST_P(TrajectoryControllerTestParameterized, compute_error_angle_wraparound_fal size_t n_joints = joint_names_.size(); // send msg - constexpr auto FIRST_POINT_TIME = std::chrono::milliseconds(250); - builtin_interfaces::msg::Duration time_from_start{rclcpp::Duration(FIRST_POINT_TIME)}; // *INDENT-OFF* std::vector> points{ {{3.3, 4.4, 6.6}}, {{7.7, 8.8, 9.9}}, {{10.10, 11.11, 12.12}}}; diff --git a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp index a87086e6f7..c47e9ccd86 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp +++ b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp @@ -236,7 +236,7 @@ class TrajectoryControllerTest : public ::testing::Test public: static void SetUpTestCase() { rclcpp::init(0, nullptr); } - virtual void SetUp() + void SetUp() override { controller_name_ = "test_joint_trajectory_controller"; From 5015d5409db0744859fba8c78ef1d53678667a5e Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sun, 21 Sep 2025 22:15:23 +0200 Subject: [PATCH 081/108] Use auto dependency management for windows workflow (backport #1917) (#1922) --- .../rolling-semi-binary-build-win.yml | 4 -- joint_trajectory_controller/CMakeLists.txt | 20 ++++++---- ros2_controllers.windows.rolling.repos | 37 ------------------- 3 files changed, 13 insertions(+), 48 deletions(-) delete mode 100644 ros2_controllers.windows.rolling.repos diff --git a/.github/workflows/rolling-semi-binary-build-win.yml b/.github/workflows/rolling-semi-binary-build-win.yml index 064a65a199..4fb8302dfb 100644 --- a/.github/workflows/rolling-semi-binary-build-win.yml +++ b/.github/workflows/rolling-semi-binary-build-win.yml @@ -16,7 +16,6 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers.rolling.repos' - - 'ros2_controllers.windows.rolling.repos' push: branches: - master @@ -29,7 +28,6 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers.rolling.repos' - - 'ros2_controllers.windows.rolling.repos' concurrency: # cancel previous runs of the same workflow, except for pushes on given branches @@ -42,7 +40,5 @@ jobs: with: ros_distro: rolling pixi_dependencies: typeguard jinja2 boost compilers - windows_dependencies: ros2_controllers.windows.rolling.repos ninja_packages: rsl - skip_packages: diagnostic_remote_logging generate_parameter_library_example_external generate_parameter_library_example target_cmake_args: -DBUILD_TESTING=OFF diff --git a/joint_trajectory_controller/CMakeLists.txt b/joint_trajectory_controller/CMakeLists.txt index 8b3f109b07..19ac350e10 100644 --- a/joint_trajectory_controller/CMakeLists.txt +++ b/joint_trajectory_controller/CMakeLists.txt @@ -38,6 +38,9 @@ add_library(joint_trajectory_controller SHARED src/trajectory.cpp ) target_compile_features(joint_trajectory_controller PUBLIC cxx_std_17) +if(WIN32) + target_compile_definitions(joint_trajectory_controller PRIVATE _USE_MATH_DEFINES) +endif() target_include_directories(joint_trajectory_controller PUBLIC $ $ @@ -66,23 +69,26 @@ if(BUILD_TESTING) find_package(ros2_control_test_assets REQUIRED) ament_add_gmock(test_trajectory test/test_trajectory.cpp) - target_link_libraries(test_trajectory joint_trajectory_controller) - target_link_libraries(test_trajectory ros2_control_test_assets::ros2_control_test_assets) + target_link_libraries(test_trajectory + joint_trajectory_controller + ros2_control_test_assets::ros2_control_test_assets + ) target_compile_definitions(test_trajectory PRIVATE _USE_MATH_DEFINES) ament_add_gmock(test_tolerances test/test_tolerances.cpp) - target_link_libraries(test_tolerances joint_trajectory_controller) - target_link_libraries(test_tolerances ros2_control_test_assets::ros2_control_test_assets) - target_compile_definitions(test_tolerances PRIVATE _USE_MATH_DEFINES) + target_link_libraries(test_tolerances + joint_trajectory_controller + ros2_control_test_assets::ros2_control_test_assets + ) ament_add_gmock(test_trajectory_controller test/test_trajectory_controller.cpp) set_tests_properties(test_trajectory_controller PROPERTIES TIMEOUT 220) target_link_libraries(test_trajectory_controller joint_trajectory_controller + ros2_control_test_assets::ros2_control_test_assets ) - target_link_libraries(test_trajectory_controller ros2_control_test_assets::ros2_control_test_assets) - target_compile_definitions(joint_trajectory_controller PRIVATE _USE_MATH_DEFINES) + target_compile_definitions(test_trajectory_controller PRIVATE _USE_MATH_DEFINES) add_definitions(-DTEST_FILES_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}/test") ament_add_gmock(test_load_joint_trajectory_controller diff --git a/ros2_controllers.windows.rolling.repos b/ros2_controllers.windows.rolling.repos deleted file mode 100644 index 0c7cb73eed..0000000000 --- a/ros2_controllers.windows.rolling.repos +++ /dev/null @@ -1,37 +0,0 @@ -repositories: - filters: - type: git - url: https://github.com/ros/filters.git - version: ros2 - cpp_polyfills: - type: git - url: https://github.com/PickNikRobotics/cpp_polyfills.git - version: main - rsl: - type: git - url: https://github.com/PickNikRobotics/RSL.git - version: main - generate_parameter_library: - type: git - url: https://github.com/PickNikRobotics/generate_parameter_library.git - version: main - pal_statistics: - type: git - url: https://github.com/pal-robotics/pal_statistics.git - version: humble-devel - backward_ros: - type: git - url: https://github.com/pal-robotics//backward_ros.git - version: foxy-devel - diagnostics: - type: git - url: https://github.com/ros/diagnostics - version: ros2 - angles: - type: git - url: https://github.com/ros/angles - version: ros2 - ackermann_msgs: - type: git - url: https://github.com/ros-drivers/ackermann_msgs.git - version: ros2 From b9f3358d5ef048cb7b1da9201caf169585d0bf7c Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 22 Sep 2025 22:43:23 +0200 Subject: [PATCH 082/108] Remove wrong and unnecessary docstrings (backport #1912) (#1924) --- .../joint_trajectory_controller.hpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp index fecfa3af28..251dacc460 100644 --- a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp +++ b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp @@ -55,14 +55,8 @@ class JointTrajectoryController : public controller_interface::ControllerInterfa public: JointTrajectoryController(); - /** - * @brief command_interface_configuration - */ controller_interface::InterfaceConfiguration command_interface_configuration() const override; - /** - * @brief command_interface_configuration - */ controller_interface::InterfaceConfiguration state_interface_configuration() const override; controller_interface::return_type update( From b5dcb1178db42228d6b0414cb8880c1ba93f0d5f Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 23 Sep 2025 22:15:01 +0200 Subject: [PATCH 083/108] Add filtering capability to ft_broadcaster (backport #1814) (#1927) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Óscar Martínez Martínez Co-authored-by: Christoph Fröhlich --- doc/release_notes.rst | 1 + .../CMakeLists.txt | 27 +++ .../doc/userdoc.rst | 11 +- .../force_torque_sensor_broadcaster.hpp | 25 ++- force_torque_sensor_broadcaster/package.xml | 1 + .../src/force_torque_sensor_broadcaster.cpp | 100 ++++++++--- ..._torque_sensor_broadcaster_parameters.yaml | 7 + .../test/dummy_filter.cpp | 56 ++++++ .../test/dummy_filter_plugin.xml | 9 + ...orce_torque_sensor_broadcaster_params.yaml | 9 +- .../test_force_torque_sensor_broadcaster.cpp | 159 +++++++++++++++--- .../test_force_torque_sensor_broadcaster.hpp | 10 +- 12 files changed, 357 insertions(+), 58 deletions(-) create mode 100644 force_torque_sensor_broadcaster/test/dummy_filter.cpp create mode 100644 force_torque_sensor_broadcaster/test/dummy_filter_plugin.xml diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 4f02721058..325e4f7b35 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -106,3 +106,4 @@ gpio_controllers force_torque_sensor_broadcaster ******************************* * Multiplier support was added. Users can now specify per–axis scaling factors for both force and torque readings, applied after the existing offset logic. (`#1647 `__). +* Added support for filter chains, allowing users to configure a sequence of filter plugins with their parameters. The force/torque sensor readings are filtered sequentially and published on a separate topic. diff --git a/force_torque_sensor_broadcaster/CMakeLists.txt b/force_torque_sensor_broadcaster/CMakeLists.txt index c7d8e3beb8..9224a17001 100644 --- a/force_torque_sensor_broadcaster/CMakeLists.txt +++ b/force_torque_sensor_broadcaster/CMakeLists.txt @@ -7,6 +7,7 @@ export_windows_symbols() set(THIS_PACKAGE_INCLUDE_DEPENDS controller_interface + filters generate_parameter_library geometry_msgs hardware_interface @@ -37,6 +38,7 @@ target_include_directories(force_torque_sensor_broadcaster PUBLIC target_link_libraries(force_torque_sensor_broadcaster PUBLIC force_torque_sensor_broadcaster_parameters controller_interface::controller_interface + filters::filter_chain hardware_interface::hardware_interface pluginlib::pluginlib rclcpp::rclcpp @@ -70,6 +72,31 @@ if(BUILD_TESTING) target_link_libraries(test_force_torque_sensor_broadcaster force_torque_sensor_broadcaster ) + + add_library(dummy_filter SHARED + test/dummy_filter.cpp + ) + target_compile_features(dummy_filter PUBLIC cxx_std_17) + target_include_directories(dummy_filter PUBLIC + $ + $ + ) + target_link_libraries(dummy_filter PUBLIC + filters::increment + ${geometry_msgs_TARGETS} + pluginlib::pluginlib + rclcpp::rclcpp + ) + install( + TARGETS + dummy_filter + EXPORT export_force_torque_sensor_broadcaster + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + ) + + pluginlib_export_plugin_description_file(filters "test/dummy_filter_plugin.xml") endif() install( diff --git a/force_torque_sensor_broadcaster/doc/userdoc.rst b/force_torque_sensor_broadcaster/doc/userdoc.rst index df0430e3bb..bfa82d77f6 100644 --- a/force_torque_sensor_broadcaster/doc/userdoc.rst +++ b/force_torque_sensor_broadcaster/doc/userdoc.rst @@ -7,8 +7,11 @@ Force Torque Sensor Broadcaster Broadcaster of messages from force/torque state interfaces of a robot or sensor. The published message type is ``geometry_msgs/msg/WrenchStamped``. -The controller is a wrapper around ``ForceTorqueSensor`` semantic component (see ``controller_interface`` package). +The broadcaster also supports filtering the force/torque readings using a filter chain, enabling the sequential application of multiple filters. In this case, an additional topic with the +``_filtered`` suffix will be published containing the final result. For more details on filters, refer to the `filters package repository `_. +See the parameter section for instructions on configuring a filter chain with an arbitrary number of filters. +The controller is a wrapper around ``ForceTorqueSensor`` semantic component (see ``controller_interface`` package). Parameters ^^^^^^^^^^^ @@ -17,6 +20,12 @@ This controller uses the `generate_parameter_library `_ library to load each filter at runtime, +passing the specified parameters. + +The chain processes the data sequentially, passing the output of one filter as the input to the next. + Full list of parameters: .. generate_parameter_library_details:: ../src/force_torque_sensor_broadcaster_parameters.yaml diff --git a/force_torque_sensor_broadcaster/include/force_torque_sensor_broadcaster/force_torque_sensor_broadcaster.hpp b/force_torque_sensor_broadcaster/include/force_torque_sensor_broadcaster/force_torque_sensor_broadcaster.hpp index 0c8ce438f1..1f0b4484b7 100644 --- a/force_torque_sensor_broadcaster/include/force_torque_sensor_broadcaster/force_torque_sensor_broadcaster.hpp +++ b/force_torque_sensor_broadcaster/include/force_torque_sensor_broadcaster/force_torque_sensor_broadcaster.hpp @@ -20,18 +20,23 @@ #define FORCE_TORQUE_SENSOR_BROADCASTER__FORCE_TORQUE_SENSOR_BROADCASTER_HPP_ #include +#include #include #include "controller_interface/chainable_controller_interface.hpp" -// auto-generated by generate_parameter_library -#include "force_torque_sensor_broadcaster/force_torque_sensor_broadcaster_parameters.hpp" +#include "filters/filter_chain.hpp" #include "geometry_msgs/msg/wrench_stamped.hpp" #include "rclcpp_lifecycle/state.hpp" #include "realtime_tools/realtime_publisher.hpp" #include "semantic_components/force_torque_sensor.hpp" +// auto-generated by generate_parameter_library +#include "force_torque_sensor_broadcaster/force_torque_sensor_broadcaster_parameters.hpp" + namespace force_torque_sensor_broadcaster { +using WrenchMsgType = geometry_msgs::msg::WrenchStamped; + class ForceTorqueSensorBroadcaster : public controller_interface::ChainableControllerInterface { public: @@ -67,10 +72,18 @@ class ForceTorqueSensorBroadcaster : public controller_interface::ChainableContr Params params_; std::unique_ptr force_torque_sensor_; - - using StatePublisher = realtime_tools::RealtimePublisher; - rclcpp::Publisher::SharedPtr sensor_state_publisher_; - std::unique_ptr realtime_publisher_; + bool has_filter_chain_ = false; + + WrenchMsgType wrench_raw_; + WrenchMsgType wrench_filtered_; + std::unique_ptr> filter_chain_; + + using StatePublisher = rclcpp::Publisher::SharedPtr; + using StateRTPublisher = realtime_tools::RealtimePublisher; + StatePublisher sensor_raw_state_publisher_; + StatePublisher sensor_filtered_state_publisher_; + std::unique_ptr realtime_raw_publisher_; + std::unique_ptr realtime_filtered_publisher_; }; } // namespace force_torque_sensor_broadcaster diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 94ada12aa3..cfbb38cf0c 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -25,6 +25,7 @@ backward_ros controller_interface + filters geometry_msgs hardware_interface pluginlib diff --git a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp index c43d2a6b06..8457a1c09d 100644 --- a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp @@ -18,9 +18,12 @@ #include "force_torque_sensor_broadcaster/force_torque_sensor_broadcaster.hpp" +#include #include #include +#include "rclcpp/logging.hpp" + namespace force_torque_sensor_broadcaster { ForceTorqueSensorBroadcaster::ForceTorqueSensorBroadcaster() @@ -85,12 +88,43 @@ controller_interface::CallbackReturn ForceTorqueSensorBroadcaster::on_configure( force_names.x, force_names.y, force_names.z, torque_names.x, torque_names.y, torque_names.z); } + try + { + filter_chain_ = + std::make_unique>("geometry_msgs::msg::WrenchStamped"); + } + catch (const std::exception & e) + { + fprintf(stderr, "Exception thrown during filter chain creation with message : %s \n", e.what()); + return CallbackReturn::ERROR; + } + + // As the sensor_filter_chain parameter is of type 'none', we cannot directly check if it is + // present. Even if the sensor_filter_chain parameter is not specified, the filter chain will be + // correctly configured with an empty list of filters. + bool filter_chain_configured = filter_chain_->configure( + "sensor_filter_chain", get_node()->get_node_logging_interface(), + get_node()->get_node_parameters_interface()); + + // Even on successful configure, if empty, the chain won't be used + has_filter_chain_ = filter_chain_configured && filter_chain_->get_length() > 0; + + RCLCPP_INFO_EXPRESSION( + get_node()->get_logger(), has_filter_chain_, "Filter active with %zu filters!", + filter_chain_->get_length()); + try { // register ft sensor data publisher - sensor_state_publisher_ = get_node()->create_publisher( + sensor_raw_state_publisher_ = get_node()->create_publisher( "~/wrench", rclcpp::SystemDefaultsQoS()); - realtime_publisher_ = std::make_unique(sensor_state_publisher_); + realtime_raw_publisher_ = std::make_unique(sensor_raw_state_publisher_); + + sensor_filtered_state_publisher_ = + get_node()->create_publisher( + "~/wrench_filtered", rclcpp::SystemDefaultsQoS()); + realtime_filtered_publisher_ = + std::make_unique(sensor_filtered_state_publisher_); } catch (const std::exception & e) { @@ -100,9 +134,19 @@ controller_interface::CallbackReturn ForceTorqueSensorBroadcaster::on_configure( return controller_interface::CallbackReturn::ERROR; } - realtime_publisher_->lock(); - realtime_publisher_->msg_.header.frame_id = params_.frame_id; - realtime_publisher_->unlock(); + wrench_raw_.header.frame_id = params_.frame_id; + wrench_filtered_.header.frame_id = params_.frame_id; + + realtime_raw_publisher_->lock(); + realtime_raw_publisher_->msg_.header.frame_id = params_.frame_id; + realtime_raw_publisher_->unlock(); + + if (has_filter_chain_) + { + realtime_filtered_publisher_->lock(); + realtime_filtered_publisher_->msg_.header.frame_id = params_.frame_id; + realtime_filtered_publisher_->unlock(); + } RCLCPP_INFO(get_node()->get_logger(), "configure successful"); return controller_interface::CallbackReturn::SUCCESS; @@ -146,13 +190,29 @@ controller_interface::return_type ForceTorqueSensorBroadcaster::update_and_write { params_ = param_listener_->get_params(); } - if (realtime_publisher_ && realtime_publisher_->trylock()) + + wrench_raw_.header.stamp = time; + force_torque_sensor_->get_values_as_message(wrench_raw_.wrench); + this->apply_sensor_offset(params_, wrench_raw_); + this->apply_sensor_multiplier(params_, wrench_raw_); + + if (realtime_raw_publisher_ && realtime_raw_publisher_->trylock()) + { + realtime_raw_publisher_->msg_.header.stamp = time; + realtime_raw_publisher_->msg_.wrench = wrench_raw_.wrench; + realtime_raw_publisher_->unlockAndPublish(); + } + + if (has_filter_chain_) { - realtime_publisher_->msg_.header.stamp = time; - force_torque_sensor_->get_values_as_message(realtime_publisher_->msg_.wrench); - this->apply_sensor_offset(params_, realtime_publisher_->msg_); - this->apply_sensor_multiplier(params_, realtime_publisher_->msg_); - realtime_publisher_->unlockAndPublish(); + // Filter sensor data, if no filter chain config was specified, wrench_filtered_ = wrench_raw_ + auto filtered = filter_chain_->update(wrench_raw_, wrench_filtered_); + if (filtered && realtime_filtered_publisher_ && realtime_filtered_publisher_->trylock()) + { + realtime_filtered_publisher_->msg_.header.stamp = time; + realtime_filtered_publisher_->msg_.wrench = wrench_filtered_.wrench; + realtime_filtered_publisher_->unlockAndPublish(); + } } return controller_interface::return_type::OK; @@ -198,38 +258,32 @@ ForceTorqueSensorBroadcaster::on_export_state_interfaces() if (!force_names[0].empty()) { exported_state_interfaces.emplace_back( - hardware_interface::StateInterface( - export_prefix, force_names[0], &realtime_publisher_->msg_.wrench.force.x)); + export_prefix, force_names[0], &realtime_raw_publisher_->msg_.wrench.force.x); } if (!force_names[1].empty()) { exported_state_interfaces.emplace_back( - hardware_interface::StateInterface( - export_prefix, force_names[1], &realtime_publisher_->msg_.wrench.force.y)); + export_prefix, force_names[1], &realtime_raw_publisher_->msg_.wrench.force.y); } if (!force_names[2].empty()) { exported_state_interfaces.emplace_back( - hardware_interface::StateInterface( - export_prefix, force_names[2], &realtime_publisher_->msg_.wrench.force.z)); + export_prefix, force_names[2], &realtime_raw_publisher_->msg_.wrench.force.z); } if (!torque_names[0].empty()) { exported_state_interfaces.emplace_back( - hardware_interface::StateInterface( - export_prefix, torque_names[0], &realtime_publisher_->msg_.wrench.torque.x)); + export_prefix, torque_names[0], &realtime_raw_publisher_->msg_.wrench.torque.x); } if (!torque_names[1].empty()) { exported_state_interfaces.emplace_back( - hardware_interface::StateInterface( - export_prefix, torque_names[1], &realtime_publisher_->msg_.wrench.torque.y)); + export_prefix, torque_names[1], &realtime_raw_publisher_->msg_.wrench.torque.y); } if (!torque_names[2].empty()) { exported_state_interfaces.emplace_back( - hardware_interface::StateInterface( - export_prefix, torque_names[2], &realtime_publisher_->msg_.wrench.torque.z)); + export_prefix, torque_names[2], &realtime_raw_publisher_->msg_.wrench.torque.z); } return exported_state_interfaces; } diff --git a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster_parameters.yaml b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster_parameters.yaml index 47c36b3b14..fe1c7cedbb 100644 --- a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster_parameters.yaml +++ b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster_parameters.yaml @@ -112,3 +112,10 @@ force_torque_sensor_broadcaster: default_value: 1.0, description: "The multiplier of torque value around 'z' axis.", } + sensor_filter_chain: { + type: none, + description: "Map of parameters that defines a filter chain, containing filterN as key. The fields for each filter are: + type: The filter plugin to be loaded + name: Actual name semantically describing the filter, e.g., low_pass_filter + params: And underlying map of parameters needed for a specific filter, refer to the specific filter documentation." + } diff --git a/force_torque_sensor_broadcaster/test/dummy_filter.cpp b/force_torque_sensor_broadcaster/test/dummy_filter.cpp new file mode 100644 index 0000000000..3eef7fb3df --- /dev/null +++ b/force_torque_sensor_broadcaster/test/dummy_filter.cpp @@ -0,0 +1,56 @@ + +// Copyright (c) 2025, PAL Robotics +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* + * Authors: Oscar Martinez + */ + +#include +#include + +#include "geometry_msgs/msg/wrench_stamped.hpp" + +#include "filters/increment.hpp" + +namespace filters +{ + +template <> +bool IncrementFilter::update( + const geometry_msgs::msg::WrenchStamped & data_in, geometry_msgs::msg::WrenchStamped & data_out) +{ + if (!this->configured_) + { + throw std::runtime_error("Filter is not configured"); + } + + // Just increment every value + data_out.wrench.force.x = data_in.wrench.force.x + 1; + data_out.wrench.force.y = data_in.wrench.force.y + 1; + data_out.wrench.force.z = data_in.wrench.force.z + 1; + data_out.wrench.torque.x = data_in.wrench.torque.x + 1; + data_out.wrench.torque.y = data_in.wrench.torque.y + 1; + data_out.wrench.torque.z = data_in.wrench.torque.z + 1; + + return true; +} + +} // namespace filters + +#include "pluginlib/class_list_macros.hpp" + +PLUGINLIB_EXPORT_CLASS( + filters::IncrementFilter, + filters::FilterBase) diff --git a/force_torque_sensor_broadcaster/test/dummy_filter_plugin.xml b/force_torque_sensor_broadcaster/test/dummy_filter_plugin.xml new file mode 100644 index 0000000000..17623c6e44 --- /dev/null +++ b/force_torque_sensor_broadcaster/test/dummy_filter_plugin.xml @@ -0,0 +1,9 @@ + + + + + This is a increment filter which works on a wrench message. + + + + diff --git a/force_torque_sensor_broadcaster/test/force_torque_sensor_broadcaster_params.yaml b/force_torque_sensor_broadcaster/test/force_torque_sensor_broadcaster_params.yaml index 58cc1c6b16..1c09892ccb 100644 --- a/force_torque_sensor_broadcaster/test/force_torque_sensor_broadcaster_params.yaml +++ b/force_torque_sensor_broadcaster/test/force_torque_sensor_broadcaster_params.yaml @@ -1,4 +1,11 @@ test_force_torque_sensor_broadcaster: ros__parameters: - frame_id: "fts_sensor_frame" +test_force_torque_sensor_broadcaster_with_chain: + ros__parameters: + frame_id: "fts_sensor_frame" + sensor_name: "fts_sensor" + sensor_filter_chain: + filter1: + name: dummy + type: filters/IncrementFilterWrench diff --git a/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp b/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp index 053eec35d1..99fa93d845 100644 --- a/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp @@ -19,6 +19,7 @@ #include "test_force_torque_sensor_broadcaster.hpp" #include +#include #include #include @@ -28,6 +29,7 @@ #include "rclcpp/executor.hpp" #include "rclcpp/executors.hpp" #include "rclcpp/utilities.hpp" + using hardware_interface::LoanedStateInterface; using testing::IsEmpty; using testing::SizeIs; @@ -50,11 +52,10 @@ void ForceTorqueSensorBroadcasterTest::SetUp() void ForceTorqueSensorBroadcasterTest::TearDown() { fts_broadcaster_.reset(nullptr); } -void ForceTorqueSensorBroadcasterTest::SetUpFTSBroadcaster() +void ForceTorqueSensorBroadcasterTest::SetUpFTSBroadcaster(std::string node_name) { - const auto result = fts_broadcaster_->init( - "test_force_torque_sensor_broadcaster", "", 0, "", - fts_broadcaster_->define_custom_node_options()); + const auto result = + fts_broadcaster_->init(node_name, "", 0, "", fts_broadcaster_->define_custom_node_options()); ASSERT_EQ(result, controller_interface::return_type::OK); std::vector state_ifs; @@ -69,7 +70,7 @@ void ForceTorqueSensorBroadcasterTest::SetUpFTSBroadcaster() } void ForceTorqueSensorBroadcasterTest::subscribe_and_get_message( - geometry_msgs::msg::WrenchStamped & wrench_msg) + geometry_msgs::msg::WrenchStamped & wrench_msg, std::string & topic_name) { // create a new subscriber geometry_msgs::msg::WrenchStamped::SharedPtr received_msg; @@ -77,7 +78,7 @@ void ForceTorqueSensorBroadcasterTest::subscribe_and_get_message( auto subs_callback = [&](const geometry_msgs::msg::WrenchStamped::SharedPtr msg) { received_msg = msg; }; auto subscription = test_subscription_node.create_subscription( - "/test_force_torque_sensor_broadcaster/wrench", 10, subs_callback); + topic_name, 10, subs_callback); rclcpp::executors::SingleThreadedExecutor executor; executor.add_node(test_subscription_node.get_node_base_interface()); @@ -110,7 +111,7 @@ void ForceTorqueSensorBroadcasterTest::subscribe_and_get_message( TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_InterfaceNames_NotSet) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // configure failed ASSERT_EQ(fts_broadcaster_->on_configure(rclcpp_lifecycle::State()), NODE_ERROR); @@ -118,7 +119,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_InterfaceNames_NotSet) TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_InterfaceNames_Set) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // set the 'sensor_name' fts_broadcaster_->get_node()->set_parameter({"sensor_name", sensor_name_}); @@ -133,7 +134,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_InterfaceNames_Set) TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_IsEmpty_InterfaceNames_NotSet) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // set the 'sensor_name' empty fts_broadcaster_->get_node()->set_parameter({"sensor_name", ""}); @@ -144,7 +145,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_IsEmpty_InterfaceNames_NotSe TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_IsEmpty_SensorName_NotSet) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // set the 'interface_names' empty fts_broadcaster_->get_node()->set_parameter({"interface_names.force.x", ""}); @@ -156,7 +157,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_IsEmpty_SensorName_NotSe TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Configure_Success) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // set the 'sensor_name' fts_broadcaster_->get_node()->set_parameter({"sensor_name", sensor_name_}); @@ -178,7 +179,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Configure_Success) TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_Configure_Success) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // set the 'interface_names' fts_broadcaster_->get_node()->set_parameter({"interface_names.force.x", "fts_sensor/force.x"}); @@ -195,7 +196,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_Configure_Success) TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_ActivateDeactivate_Success) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // set the params 'sensor_name' and 'frame_id' fts_broadcaster_->get_node()->set_parameter({"sensor_name", sensor_name_}); @@ -227,7 +228,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_ActivateDeactivate_Success) TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Update_Success) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // set the params 'sensor_name' and 'frame_id' fts_broadcaster_->get_node()->set_parameter({"sensor_name", sensor_name_}); @@ -243,7 +244,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Update_Success) TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_Success) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // set the params 'interface_names' and 'frame_id' fts_broadcaster_->get_node()->set_parameter({"interface_names.force.x", "fts_sensor/force.x"}); @@ -259,7 +260,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_Success) TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // set the params 'sensor_name' and 'frame_id' fts_broadcaster_->get_node()->set_parameter({"sensor_name", sensor_name_}); @@ -269,7 +270,8 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success) ASSERT_EQ(fts_broadcaster_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); geometry_msgs::msg::WrenchStamped wrench_msg; - subscribe_and_get_message(wrench_msg); + std::string topic_name = "/test_force_torque_sensor_broadcaster/wrench"; + subscribe_and_get_message(wrench_msg, topic_name); ASSERT_EQ(wrench_msg.header.frame_id, frame_id_); ASSERT_EQ(wrench_msg.wrench.force.x, sensor_values_[0]); @@ -282,7 +284,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success) TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success_with_Offsets) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); std::array force_offsets = {{10.0, 30.0, -50.0}}; std::array torque_offsets = {{1.0, -1.2, -5.2}}; @@ -300,7 +302,8 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success_with_Offsets ASSERT_EQ(fts_broadcaster_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); geometry_msgs::msg::WrenchStamped wrench_msg; - subscribe_and_get_message(wrench_msg); + std::string topic_name = "/test_force_torque_sensor_broadcaster/wrench"; + subscribe_and_get_message(wrench_msg, topic_name); ASSERT_EQ(wrench_msg.header.frame_id, frame_id_); ASSERT_EQ(wrench_msg.wrench.force.x, sensor_values_[0] + force_offsets[0]); @@ -344,7 +347,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success_with_Offsets TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success_with_Multipliers) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // some non‐trivial multipliers std::array force_multipliers = {{2.0, 0.5, -1.0}}; @@ -368,7 +371,8 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success_with_Multipl // Publish & grab the message geometry_msgs::msg::WrenchStamped wrench_msg; - subscribe_and_get_message(wrench_msg); + std::string topic_name = "/test_force_torque_sensor_broadcaster/wrench"; + subscribe_and_get_message(wrench_msg, topic_name); // Check header ASSERT_EQ(wrench_msg.header.frame_id, frame_id_); @@ -414,7 +418,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success_with_Multipl TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_Publish_Success) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // set the params 'interface_names' and 'frame_id' fts_broadcaster_->get_node()->set_parameter({"interface_names.force.x", "fts_sensor/force.x"}); @@ -425,7 +429,8 @@ TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_Publish_Success) ASSERT_EQ(fts_broadcaster_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); geometry_msgs::msg::WrenchStamped wrench_msg; - subscribe_and_get_message(wrench_msg); + std::string topic_name = "/test_force_torque_sensor_broadcaster/wrench"; + subscribe_and_get_message(wrench_msg, topic_name); ASSERT_EQ(wrench_msg.header.frame_id, frame_id_); ASSERT_EQ(wrench_msg.wrench.force.x, sensor_values_[0]); @@ -451,7 +456,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_Publish_Success) TEST_F(ForceTorqueSensorBroadcasterTest, All_InterfaceNames_Publish_Success) { - SetUpFTSBroadcaster(); + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster"); // set all the params 'interface_names' and 'frame_id' fts_broadcaster_->get_node()->set_parameter({"interface_names.force.x", "fts_sensor/force.x"}); @@ -466,7 +471,8 @@ TEST_F(ForceTorqueSensorBroadcasterTest, All_InterfaceNames_Publish_Success) ASSERT_EQ(fts_broadcaster_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); geometry_msgs::msg::WrenchStamped wrench_msg; - subscribe_and_get_message(wrench_msg); + std::string topic_name = "/test_force_torque_sensor_broadcaster/wrench"; + subscribe_and_get_message(wrench_msg, topic_name); ASSERT_EQ(wrench_msg.header.frame_id, frame_id_); ASSERT_EQ(wrench_msg.wrench.force.x, sensor_values_[0]); @@ -499,6 +505,109 @@ TEST_F(ForceTorqueSensorBroadcasterTest, All_InterfaceNames_Publish_Success) } } +TEST_F(ForceTorqueSensorBroadcasterTest, SensorFilterChain_Configure_Success) +{ + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster_with_chain"); + + // configure passed + ASSERT_EQ(fts_broadcaster_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_EQ(fts_broadcaster_->has_filter_chain_, true); + + // check interface configuration + auto cmd_if_conf = fts_broadcaster_->command_interface_configuration(); + ASSERT_THAT(cmd_if_conf.names, IsEmpty()); + ASSERT_EQ(cmd_if_conf.type, controller_interface::interface_configuration_type::NONE); + auto state_if_conf = fts_broadcaster_->state_interface_configuration(); + ASSERT_THAT(state_if_conf.names, SizeIs(6lu)); + ASSERT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::INDIVIDUAL); + + std::cout << "Finished" << std::endl; +} + +TEST_F(ForceTorqueSensorBroadcasterTest, SensorFilterChain_ActivateDeactivate_Success) +{ + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster_with_chain"); + + // configure and activate success + ASSERT_EQ(fts_broadcaster_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_EQ(fts_broadcaster_->has_filter_chain_, true); + ASSERT_EQ(fts_broadcaster_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); + + // check interface configuration + auto cmd_if_conf = fts_broadcaster_->command_interface_configuration(); + ASSERT_THAT(cmd_if_conf.names, IsEmpty()); + ASSERT_EQ(cmd_if_conf.type, controller_interface::interface_configuration_type::NONE); + auto state_if_conf = fts_broadcaster_->state_interface_configuration(); + ASSERT_THAT(state_if_conf.names, SizeIs(6lu)); + ASSERT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::INDIVIDUAL); + + // deactivate passed + ASSERT_EQ(fts_broadcaster_->on_deactivate(rclcpp_lifecycle::State()), NODE_SUCCESS); + + // check interface configuration + cmd_if_conf = fts_broadcaster_->command_interface_configuration(); + ASSERT_THAT(cmd_if_conf.names, IsEmpty()); + ASSERT_EQ(cmd_if_conf.type, controller_interface::interface_configuration_type::NONE); + state_if_conf = fts_broadcaster_->state_interface_configuration(); + ASSERT_THAT(state_if_conf.names, SizeIs(6lu)); // did not change + ASSERT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::INDIVIDUAL); +} + +TEST_F(ForceTorqueSensorBroadcasterTest, SensorFilterChain_Update_Success) +{ + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster_with_chain"); + + ASSERT_EQ(fts_broadcaster_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_EQ(fts_broadcaster_->has_filter_chain_, true); + ASSERT_EQ(fts_broadcaster_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); + + ASSERT_EQ( + fts_broadcaster_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); + + // Dummy wrenches + geometry_msgs::msg::WrenchStamped wrench_in; + geometry_msgs::msg::WrenchStamped wrench_out; + + wrench_in.wrench.force.x = 1.0; + wrench_in.wrench.force.y = 2.0; + wrench_in.wrench.force.z = 3.0; + wrench_in.wrench.torque.x = 4.0; + wrench_in.wrench.torque.y = 5.0; + wrench_in.wrench.torque.z = 6.0; + + // Update the filter chain directly (the values from the update are just published) + fts_broadcaster_->filter_chain_->update(wrench_in, wrench_out); + + ASSERT_EQ(wrench_out.wrench.force.x, wrench_in.wrench.force.x + 1.0); + ASSERT_EQ(wrench_out.wrench.force.y, wrench_in.wrench.force.y + 1.0); + ASSERT_EQ(wrench_out.wrench.force.z, wrench_in.wrench.force.z + 1.0); + ASSERT_EQ(wrench_out.wrench.torque.x, wrench_in.wrench.torque.x + 1.0); + ASSERT_EQ(wrench_out.wrench.torque.y, wrench_in.wrench.torque.y + 1.0); + ASSERT_EQ(wrench_out.wrench.torque.z, wrench_in.wrench.torque.z + 1.0); +} + +TEST_F(ForceTorqueSensorBroadcasterTest, SensorFilterChain_Publish_Success) +{ + SetUpFTSBroadcaster("test_force_torque_sensor_broadcaster_with_chain"); + + ASSERT_EQ(fts_broadcaster_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_EQ(fts_broadcaster_->has_filter_chain_, true); + ASSERT_EQ(fts_broadcaster_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); + + geometry_msgs::msg::WrenchStamped wrench_msg_filtered; + std::string topic_name = "/test_force_torque_sensor_broadcaster_with_chain/wrench_filtered"; + subscribe_and_get_message(wrench_msg_filtered, topic_name); + + ASSERT_EQ(wrench_msg_filtered.header.frame_id, frame_id_); + ASSERT_EQ(wrench_msg_filtered.wrench.force.x, sensor_values_[0] + 1.0); + ASSERT_EQ(wrench_msg_filtered.wrench.force.y, sensor_values_[1] + 1.0); + ASSERT_EQ(wrench_msg_filtered.wrench.force.z, sensor_values_[2] + 1.0); + ASSERT_EQ(wrench_msg_filtered.wrench.torque.x, sensor_values_[3] + 1.0); + ASSERT_EQ(wrench_msg_filtered.wrench.torque.y, sensor_values_[4] + 1.0); + ASSERT_EQ(wrench_msg_filtered.wrench.torque.z, sensor_values_[5] + 1.0); +} + int main(int argc, char ** argv) { ::testing::InitGoogleMock(&argc, argv); diff --git a/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.hpp b/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.hpp index 5d485d9d12..5bd6b62452 100644 --- a/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.hpp +++ b/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.hpp @@ -39,6 +39,11 @@ class FriendForceTorqueSensorBroadcaster FRIEND_TEST(ForceTorqueSensorBroadcasterTest, SensorName_ActivateDeactivate_Success); FRIEND_TEST(ForceTorqueSensorBroadcasterTest, UpdateTest); FRIEND_TEST(ForceTorqueSensorBroadcasterTest, SensorStatePublishTest); + + FRIEND_TEST(ForceTorqueSensorBroadcasterTest, SensorFilterChain_Configure_Success); + FRIEND_TEST(ForceTorqueSensorBroadcasterTest, SensorFilterChain_ActivateDeactivate_Success); + FRIEND_TEST(ForceTorqueSensorBroadcasterTest, SensorFilterChain_Update_Success); + FRIEND_TEST(ForceTorqueSensorBroadcasterTest, SensorFilterChain_Publish_Success); }; class ForceTorqueSensorBroadcasterTest : public ::testing::Test @@ -50,7 +55,7 @@ class ForceTorqueSensorBroadcasterTest : public ::testing::Test void SetUp(); void TearDown(); - void SetUpFTSBroadcaster(); + void SetUpFTSBroadcaster(std::string node_name); protected: const std::string sensor_name_ = "fts_sensor"; @@ -66,7 +71,8 @@ class ForceTorqueSensorBroadcasterTest : public ::testing::Test std::unique_ptr fts_broadcaster_; - void subscribe_and_get_message(geometry_msgs::msg::WrenchStamped & wrench_msg); + void subscribe_and_get_message( + geometry_msgs::msg::WrenchStamped & wrench_msg, std::string & topic_name); }; #endif // TEST_FORCE_TORQUE_SENSOR_BROADCASTER_HPP_ From 23c924bda3ade259f8cbdcaff84c693b2ac47892 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 10:25:32 +0200 Subject: [PATCH 084/108] Update writing_new_controller tutorial (backport #1832) (#1931) --- doc/writing_new_controller.rst | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/doc/writing_new_controller.rst b/doc/writing_new_controller.rst index 0874448461..84ebbd2124 100644 --- a/doc/writing_new_controller.rst +++ b/doc/writing_new_controller.rst @@ -12,9 +12,8 @@ The following is a step-by-step guide to create source files, basic tests, and c If the package for the controller does not exist, then create it first. The package should have ``ament_cmake`` as a build type. - The easiest way is to search online for the most recent manual. - A helpful command to support this process is ``ros2 pkg create``. - Use the ``--help`` flag for more information on how to use it. + Generally, you can use ``ros2 pkg create --build-type ament_cmake``. + Use the ``--help`` flag for more information on how to use this command. There is also an option to create library source files and compile rules to help you in the following steps. 2. **Preparing source files** @@ -25,17 +24,32 @@ The following is a step-by-step guide to create source files, basic tests, and c 3. **Adding declarations into header file (.hpp)** - 1. Take care that you use header guards. ROS 2-style is using ``#ifndef`` and ``#define`` preprocessor directives. (For more information on this, a search engine is your friend :) ). + 1. Take care that you use header guards. ROS 2-style is using ``#ifndef`` and ``#define`` preprocessor directives. 2. include ``"controller_interface/controller_interface.hpp"``. 3. Define a unique namespace for your controller. This is usually a package name written in ``snake_case``. - 4. Define the class of the controller, extending ``ControllerInterface``, e.g., + 4. Define the class of the controller, extending ``ControllerInterface``. Now, your code should look similar to this: .. code:: c++ + #ifndef _HPP_ + #define _HPP_ + + #include "controller_interface/controller_interface.hpp" + + namespace + { + class ControllerName : public controller_interface::ControllerInterface + { + // ... + }; + + } // namespace + + #endif // _HPP_ 5. Add a constructor without parameters and the following public methods overriding the ``ControllerInterface`` definition: ``on_init``, ``command_interface_configuration``, ``state_interface_configuration``, ``on_configure``, ``on_activate``, ``on_deactivate``, ``update``. For exact definitions check the ``controller_interface/controller_interface.hpp`` header or one of the controllers from `ros2_controllers `_. @@ -53,7 +67,7 @@ The following is a step-by-step guide to create source files, basic tests, and c This could also be done in the ``on_init`` method. 3. Implement the ``on_init`` method. The first line usually calls the parent ``on_init`` method. - Here is the best place to initialize the variables, reserve memory, and most importantly, declare node parameters used by the controller. If everything works fine return ``controller_interface::return_type::OK`` or ``controller_interface::return_type::ERROR`` otherwise. + Here is the best place to initialize the variables, reserve memory, and most importantly, declare node parameters used by the controller. If everything works fine return ``controller_interface::CallbackReturn::SUCCESS`` or ``controller_interface::CallbackReturn::ERROR`` otherwise. 4. Write the ``on_configure`` method. Parameters are usually read here, and everything is prepared so that the controller can be started. @@ -65,7 +79,6 @@ The following is a step-by-step guide to create source files, basic tests, and c 6. Implement the ``on_activate`` method with checking, and potentially sorting, the interfaces and assigning members' initial values. This method is part of the real-time loop, therefore avoid any reservation of memory and, in general, keep it as short as possible. - 7. Implement the ``on_deactivate`` method, which does the opposite of ``on_activate``. In many cases, this method is empty. This method should also be real-time safe as much as possible. @@ -129,10 +142,10 @@ The following is a step-by-step guide to create source files, basic tests, and c 9. **Compiling and testing the controller** - 1. Now everything is ready to compile the controller using the ``colcon build `` command. + 1. Now everything is ready to compile the controller using the ``colcon build --packages-select `` command. Remember to go into the root of your workspace before executing this command. - 2. If compilation was successful, source the ``setup.bash`` file from the install folder and execute ``colcon test `` to check if the new controller can be found through ``pluginlib`` library and be loaded by the controller manager. + 2. If compilation was successful, source the ``setup.bash`` file from the install folder and execute ``colcon test --packages-select `` to check if the new controller can be found through ``pluginlib`` library and be loaded by the controller manager. That's it! Enjoy writing great controllers! From 825470c3facb558a1370cfdc50cdf9d96c0e5bfc Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 11:30:19 +0200 Subject: [PATCH 085/108] Fix: Remove deprecated `rclcpp::spin_some(node)` (backport #1928) (#1932) --- .../test/test_diff_drive_controller.cpp | 19 ++++++++++--------- .../test/test_omni_wheel_drive_controller.cpp | 18 +++++++++--------- .../test/test_omni_wheel_drive_controller.hpp | 5 +++-- .../test/test_parallel_gripper_controller.cpp | 6 ++++-- .../test/test_tricycle_controller.cpp | 7 ++++--- 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/diff_drive_controller/test/test_diff_drive_controller.cpp b/diff_drive_controller/test/test_diff_drive_controller.cpp index 4cd64bdd6d..860140993a 100644 --- a/diff_drive_controller/test/test_diff_drive_controller.cpp +++ b/diff_drive_controller/test/test_diff_drive_controller.cpp @@ -134,7 +134,7 @@ class TestDiffDriveController : public ::testing::Test } /// \brief wait for the subscriber and publisher to completely setup - void waitForSetup() + void waitForSetup(rclcpp::Executor & executor) { constexpr std::chrono::seconds TIMEOUT{2}; auto clock = pub_node->get_clock(); @@ -145,7 +145,8 @@ class TestDiffDriveController : public ::testing::Test { FAIL(); } - rclcpp::spin_some(pub_node); + executor.spin_some(); + std::this_thread::sleep_for(std::chrono::microseconds(10)); } } @@ -536,7 +537,7 @@ TEST_F(TestDiffDriveController, test_speed_limiter) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // send msg publish(0.0, 0.0); @@ -777,7 +778,7 @@ TEST_F(TestDiffDriveController, cleanup) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // send msg const double linear = 1.0; @@ -898,7 +899,7 @@ TEST_F(TestDiffDriveController, chainable_controller_unchained_mode) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // Reference interfaces should be NaN on initialization // (Note: reference_interfaces_ is protected, but this is @@ -994,7 +995,7 @@ TEST_F(TestDiffDriveController, chainable_controller_chained_mode) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // Reference interfaces should be NaN on initialization for (const auto & interface : controller_->reference_interfaces_) @@ -1098,7 +1099,7 @@ TEST_F(TestDiffDriveController, deactivate_then_activate) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // Reference interfaces should be NaN on initialization // (Note: reference_interfaces_ is protected, but this is @@ -1142,7 +1143,7 @@ TEST_F(TestDiffDriveController, deactivate_then_activate) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // (Note: reference_interfaces_ is protected, but this is // a FRIEND_TEST so we can use it) @@ -1196,7 +1197,7 @@ TEST_F(TestDiffDriveController, command_with_zero_timestamp_is_accepted_with_war state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // published command message with zero timestamp sets the command interfaces to the correct values const double linear = 1.0; diff --git a/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.cpp b/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.cpp index 104e37de33..d0ecb366a2 100644 --- a/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.cpp +++ b/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.cpp @@ -322,7 +322,7 @@ TEST_F(OmniWheelDriveControllerTest, chainable_controller_unchained_mode) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // Reference interfaces should be NaN on initialization for (const auto & interface : controller_->reference_interfaces_) @@ -410,7 +410,7 @@ TEST_F(OmniWheelDriveControllerTest, chainable_controller_chained_mode) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // Reference interfaces should be NaN on initialization for (const auto & interface : controller_->reference_interfaces_) @@ -478,7 +478,7 @@ TEST_F(OmniWheelDriveControllerTest, deactivate_then_activate) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // Reference interfaces should be NaN on initialization for (const auto & interface : controller_->reference_interfaces_) @@ -523,7 +523,7 @@ TEST_F(OmniWheelDriveControllerTest, deactivate_then_activate) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); for (const auto & interface : controller_->reference_interfaces_) { @@ -572,7 +572,7 @@ TEST_F(OmniWheelDriveControllerTest, command_with_zero_timestamp_is_accepted_wit state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // published command message with zero timestamp sets the command interfaces to the correct values publish_twist_timestamped(rclcpp::Time(0, 0, RCL_ROS_TIME)); @@ -615,7 +615,7 @@ TEST_F(OmniWheelDriveControllerTest, 3_wheel_test) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // Reference interfaces should be NaN on initialization for (const auto & interface : controller_->reference_interfaces_) @@ -683,7 +683,7 @@ TEST_F(OmniWheelDriveControllerTest, 3_wheel_rot_test) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // Reference interfaces should be NaN on initialization for (const auto & interface : controller_->reference_interfaces_) @@ -751,7 +751,7 @@ TEST_F(OmniWheelDriveControllerTest, 4_wheel_rot_test) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // Reference interfaces should be NaN on initialization for (const auto & interface : controller_->reference_interfaces_) @@ -819,7 +819,7 @@ TEST_F(OmniWheelDriveControllerTest, 5_wheel_test) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // Reference interfaces should be NaN on initialization for (const auto & interface : controller_->reference_interfaces_) diff --git a/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.hpp b/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.hpp index 4443af04f3..6e0bc45a36 100644 --- a/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.hpp +++ b/omni_wheel_drive_controller/test/test_omni_wheel_drive_controller.hpp @@ -139,7 +139,7 @@ class OmniWheelDriveControllerFixture : public ::testing::Test } /// \brief wait for the subscriber and publisher to completely setup - void waitForSetup() + void waitForSetup(rclcpp::Executor & executor) { constexpr std::chrono::seconds TIMEOUT{2}; auto clock = cmd_vel_publisher_node_->get_clock(); @@ -150,7 +150,8 @@ class OmniWheelDriveControllerFixture : public ::testing::Test { FAIL(); } - rclcpp::spin_some(cmd_vel_publisher_node_); + executor.spin_some(); + std::this_thread::sleep_for(std::chrono::microseconds(10)); } } diff --git a/parallel_gripper_controller/test/test_parallel_gripper_controller.cpp b/parallel_gripper_controller/test/test_parallel_gripper_controller.cpp index 0445a8fd89..1831e8ab92 100644 --- a/parallel_gripper_controller/test/test_parallel_gripper_controller.cpp +++ b/parallel_gripper_controller/test/test_parallel_gripper_controller.cpp @@ -80,9 +80,11 @@ TEST_F(GripperControllerTest, ConfigureParamsSuccess) { this->SetUpController(); - this->controller_->get_node()->set_parameter({"joint", "joint1"}); + rclcpp::executors::SingleThreadedExecutor executor; + executor.add_node(controller_->get_node()->get_node_base_interface()); - rclcpp::spin_some(this->controller_->get_node()->get_node_base_interface()); + this->controller_->get_node()->set_parameter({"joint", "joint1"}); + executor.spin_some(); // configure successful ASSERT_EQ( diff --git a/tricycle_controller/test/test_tricycle_controller.cpp b/tricycle_controller/test/test_tricycle_controller.cpp index 55f41801b5..cdc97b0518 100644 --- a/tricycle_controller/test/test_tricycle_controller.cpp +++ b/tricycle_controller/test/test_tricycle_controller.cpp @@ -120,7 +120,7 @@ class TestTricycleController : public ::testing::Test } /// \brief wait for the subscriber and publisher to completely setup - void waitForSetup() + void waitForSetup(rclcpp::Executor & executor) { constexpr std::chrono::seconds TIMEOUT{2}; auto clock = pub_node->get_clock(); @@ -131,7 +131,8 @@ class TestTricycleController : public ::testing::Test { FAIL(); } - rclcpp::spin_some(pub_node); + executor.spin_some(); + std::this_thread::sleep_for(std::chrono::microseconds(10)); } } @@ -268,7 +269,7 @@ TEST_F(TestTricycleController, cleanup) state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); - waitForSetup(); + waitForSetup(executor); // send msg const double linear = 1.0; From 3602fb46b5d158674fdc9e5cbd40c89313967e5b Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 13:33:34 +0200 Subject: [PATCH 086/108] Bump version of pre-commit hooks (backport #1938) (#1940) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2c4c45f5fd..e68a95c460 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -51,7 +51,7 @@ repos: args: ["--ignore=D100,D101,D102,D103,D104,D105,D106,D107,D203,D212,D404"] - repo: https://github.com/psf/black - rev: 25.1.0 + rev: 25.9.0 hooks: - id: black args: ["--line-length=99"] @@ -64,7 +64,7 @@ repos: # CPP hooks - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v21.1.0 + rev: v21.1.2 hooks: - id: clang-format args: ['-fallback-style=none', '-i'] @@ -134,7 +134,7 @@ repos: exclude: CHANGELOG\.rst|\.(svg|pyc|drawio)$ - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.33.3 + rev: 0.34.0 hooks: - id: check-github-workflows args: ["--verbose"] From 7cc61d3c4abe50da22d0bf3b97edd2d6d3b26574 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 09:08:30 +0200 Subject: [PATCH 087/108] Use new handles API in ros2_controllers to fix deprecation warnings (backport #1566) (#1934) --- .../src/ackermann_steering_controller.cpp | 33 ++++- .../test_ackermann_steering_controller.cpp | 52 +++---- .../src/admittance_controller.cpp | 48 +++++-- .../src/bicycle_steering_controller.cpp | 17 ++- .../test/test_bicycle_steering_controller.cpp | 19 +-- .../src/diff_drive_controller.cpp | 8 +- .../src/joint_group_effort_controller.cpp | 7 +- .../test_joint_group_effort_controller.cpp | 48 +++---- .../test_force_torque_sensor_broadcaster.cpp | 10 +- .../src/forward_controllers_base.cpp | 11 +- .../test/test_forward_command_controller.cpp | 72 +++++----- ...i_interface_forward_command_controller.cpp | 48 +++---- .../src/gpio_command_controller.cpp | 29 +++- .../test/test_gpio_command_controller.cpp | 42 +++--- .../gripper_action_controller_impl.hpp | 8 +- .../hardware_interface_adapter.hpp | 6 +- .../joint_trajectory_controller.hpp | 10 +- .../src/joint_trajectory_controller.cpp | 130 ++++++++++++++---- .../test/test_trajectory_controller_utils.hpp | 19 +-- .../src/mecanum_drive_controller.cpp | 38 +++-- .../test/test_mecanum_drive_controller.cpp | 24 ++-- ...arallel_gripper_action_controller_impl.hpp | 59 ++++++-- pid_controller/src/pid_controller.cpp | 23 +++- pid_controller/test/test_pid_controller.cpp | 39 +++--- .../test_pid_controller_dual_interface.cpp | 4 +- .../test_joint_group_position_controller.cpp | 36 ++--- .../src/steering_controllers_library.cpp | 88 ++++++++++-- .../test_steering_controllers_library.cpp | 16 +-- .../src/tricycle_controller.cpp | 43 +++++- .../test/test_tricycle_controller.cpp | 26 ++-- .../src/tricycle_steering_controller.cpp | 23 +++- .../test_tricycle_steering_controller.cpp | 34 ++--- .../src/joint_group_velocity_controller.cpp | 6 +- .../test_joint_group_velocity_controller.cpp | 48 +++---- 34 files changed, 750 insertions(+), 374 deletions(-) diff --git a/ackermann_steering_controller/src/ackermann_steering_controller.cpp b/ackermann_steering_controller/src/ackermann_steering_controller.cpp index 9452339a81..9300fe1721 100644 --- a/ackermann_steering_controller/src/ackermann_steering_controller.cpp +++ b/ackermann_steering_controller/src/ackermann_steering_controller.cpp @@ -114,18 +114,39 @@ controller_interface::CallbackReturn AckermannSteeringController::configure_odom bool AckermannSteeringController::update_odometry(const rclcpp::Duration & period) { + auto logger = get_node()->get_logger(); + if (params_.open_loop) { odometry_.update_open_loop(last_linear_velocity_, last_angular_velocity_, period.seconds()); } else { - const double traction_right_wheel_value = - state_interfaces_[STATE_TRACTION_RIGHT_WHEEL].get_value(); - const double traction_left_wheel_value = - state_interfaces_[STATE_TRACTION_LEFT_WHEEL].get_value(); - const double steering_right_position = state_interfaces_[STATE_STEER_RIGHT_WHEEL].get_value(); - const double steering_left_position = state_interfaces_[STATE_STEER_LEFT_WHEEL].get_value(); + const auto traction_right_wheel_value_op = + state_interfaces_[STATE_TRACTION_RIGHT_WHEEL].get_optional(); + const auto traction_left_wheel_value_op = + state_interfaces_[STATE_TRACTION_LEFT_WHEEL].get_optional(); + const auto steering_right_position_op = + state_interfaces_[STATE_STEER_RIGHT_WHEEL].get_optional(); + const auto steering_left_position_op = state_interfaces_[STATE_STEER_LEFT_WHEEL].get_optional(); + + if ( + !traction_right_wheel_value_op.has_value() || !traction_left_wheel_value_op.has_value() || + !steering_right_position_op.has_value() || !steering_left_position_op.has_value()) + { + RCLCPP_DEBUG( + logger, + "Unable to retrieve the data from right wheel or left wheel or right steering position or " + "left steering position!"); + + return true; + } + + const double traction_right_wheel_value = traction_right_wheel_value_op.value(); + const double traction_left_wheel_value = traction_left_wheel_value_op.value(); + const double steering_right_position = steering_right_position_op.value(); + const double steering_left_position = steering_left_position_op.value(); + if ( std::isfinite(traction_right_wheel_value) && std::isfinite(traction_left_wheel_value) && std::isfinite(steering_right_position) && std::isfinite(steering_left_position)) diff --git a/ackermann_steering_controller/test/test_ackermann_steering_controller.cpp b/ackermann_steering_controller/test/test_ackermann_steering_controller.cpp index f7cdca092f..da69fbf042 100644 --- a/ackermann_steering_controller/test/test_ackermann_steering_controller.cpp +++ b/ackermann_steering_controller/test/test_ackermann_steering_controller.cpp @@ -140,9 +140,9 @@ TEST_F(AckermannSteeringControllerTest, reactivate_success) ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_deactivate(rclcpp_lifecycle::State()), NODE_SUCCESS); - ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_value())); + ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_optional().value())); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); - ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_value())); + ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_optional().value())); ASSERT_EQ( controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), @@ -173,17 +173,17 @@ TEST_F(AckermannSteeringControllerTest, test_update_logic) // we test with open_loop=false, but steering angle was not updated (is zero) -> same commands EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_RIGHT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_RIGHT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_LEFT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_LEFT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_STEER_RIGHT_WHEEL].get_value(), 1.4179821977774734, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_STEER_RIGHT_WHEEL].get_optional().value(), + 1.4179821977774734, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_STEER_LEFT_WHEEL].get_value(), 1.4179821977774734, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_STEER_LEFT_WHEEL].get_optional().value(), + 1.4179821977774734, COMMON_THRESHOLD); EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size()); @@ -213,17 +213,17 @@ TEST_F(AckermannSteeringControllerTest, test_update_logic_chained) // we test with open_loop=false, but steering angle was not updated (is zero) -> same commands EXPECT_NEAR( - controller_->command_interfaces_[STATE_TRACTION_RIGHT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[STATE_TRACTION_RIGHT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[STATE_TRACTION_LEFT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[STATE_TRACTION_LEFT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[STATE_STEER_RIGHT_WHEEL].get_value(), 1.4179821977774734, - COMMON_THRESHOLD); + controller_->command_interfaces_[STATE_STEER_RIGHT_WHEEL].get_optional().value(), + 1.4179821977774734, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[STATE_STEER_LEFT_WHEEL].get_value(), 1.4179821977774734, - COMMON_THRESHOLD); + controller_->command_interfaces_[STATE_STEER_LEFT_WHEEL].get_optional().value(), + 1.4179821977774734, COMMON_THRESHOLD); EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size()); @@ -263,17 +263,17 @@ TEST_F(AckermannSteeringControllerTest, receive_message_and_publish_updated_stat // we test with open_loop=false, but steering angle was not updated (is zero) -> same commands EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_RIGHT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_RIGHT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_LEFT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_LEFT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_STEER_RIGHT_WHEEL].get_value(), 1.4179821977774734, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_STEER_RIGHT_WHEEL].get_optional().value(), + 1.4179821977774734, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_STEER_LEFT_WHEEL].get_value(), 1.4179821977774734, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_STEER_LEFT_WHEEL].get_optional().value(), + 1.4179821977774734, COMMON_THRESHOLD); subscribe_and_get_messages(msg); diff --git a/admittance_controller/src/admittance_controller.cpp b/admittance_controller/src/admittance_controller.cpp index 77ff09cb01..db6a91700d 100644 --- a/admittance_controller/src/admittance_controller.cpp +++ b/admittance_controller/src/admittance_controller.cpp @@ -528,21 +528,37 @@ void AdmittanceController::read_state_from_hardware( { if (has_position_state_interface_) { - state_current.positions[joint_ind] = - state_interfaces_[pos_ind * num_joints_ + joint_ind].get_value(); - nan_position |= std::isnan(state_current.positions[joint_ind]); + const auto state_current_position_op = + state_interfaces_[pos_ind * num_joints_ + joint_ind].get_optional(); + nan_position |= + !state_current_position_op.has_value() || std::isnan(state_current_position_op.value()); + if (state_current_position_op.has_value()) + { + state_current.positions[joint_ind] = state_current_position_op.value(); + } } if (has_velocity_state_interface_) { - state_current.velocities[joint_ind] = - state_interfaces_[vel_ind * num_joints_ + joint_ind].get_value(); - nan_velocity |= std::isnan(state_current.velocities[joint_ind]); + auto state_current_velocity_op = + state_interfaces_[vel_ind * num_joints_ + joint_ind].get_optional(); + nan_velocity |= + !state_current_velocity_op.has_value() || std::isnan(state_current_velocity_op.value()); + + if (state_current_velocity_op.has_value()) + { + state_current.velocities[joint_ind] = state_current_velocity_op.value(); + } } if (has_acceleration_state_interface_) { - state_current.accelerations[joint_ind] = - state_interfaces_[acc_ind * num_joints_ + joint_ind].get_value(); - nan_acceleration |= std::isnan(state_current.accelerations[joint_ind]); + auto state_current_acceleration_op = + state_interfaces_[acc_ind * num_joints_ + joint_ind].get_optional(); + nan_acceleration |= !state_current_acceleration_op.has_value() || + std::isnan(state_current_acceleration_op.value()); + if (state_current_acceleration_op.has_value()) + { + state_current.accelerations[joint_ind] = state_current_acceleration_op.value(); + } } } @@ -578,23 +594,31 @@ void AdmittanceController::write_state_to_hardware( size_t vel_ind = (has_position_command_interface_) ? pos_ind + has_velocity_command_interface_ : pos_ind; size_t acc_ind = vel_ind + has_acceleration_command_interface_; + + auto logger = get_node()->get_logger(); + for (size_t joint_ind = 0; joint_ind < num_joints_; ++joint_ind) { + bool success = true; if (has_position_command_interface_) { - command_interfaces_[pos_ind * num_joints_ + joint_ind].set_value( + success &= command_interfaces_[pos_ind * num_joints_ + joint_ind].set_value( state_commanded.positions[joint_ind]); } if (has_velocity_command_interface_) { - command_interfaces_[vel_ind * num_joints_ + joint_ind].set_value( + success &= command_interfaces_[vel_ind * num_joints_ + joint_ind].set_value( state_commanded.velocities[joint_ind]); } if (has_acceleration_command_interface_) { - command_interfaces_[acc_ind * num_joints_ + joint_ind].set_value( + success &= command_interfaces_[acc_ind * num_joints_ + joint_ind].set_value( state_commanded.accelerations[joint_ind]); } + if (!success) + { + RCLCPP_WARN(logger, "Error while setting command for joint %zu.", joint_ind); + } } last_commanded_ = state_commanded; } diff --git a/bicycle_steering_controller/src/bicycle_steering_controller.cpp b/bicycle_steering_controller/src/bicycle_steering_controller.cpp index eb10e5ad00..03fbcfa172 100644 --- a/bicycle_steering_controller/src/bicycle_steering_controller.cpp +++ b/bicycle_steering_controller/src/bicycle_steering_controller.cpp @@ -64,14 +64,27 @@ controller_interface::CallbackReturn BicycleSteeringController::configure_odomet bool BicycleSteeringController::update_odometry(const rclcpp::Duration & period) { + auto logger = get_node()->get_logger(); + if (params_.open_loop) { odometry_.update_open_loop(last_linear_velocity_, last_angular_velocity_, period.seconds()); } else { - const double traction_wheel_value = state_interfaces_[STATE_TRACTION_WHEEL].get_value(); - const double steering_position = state_interfaces_[STATE_STEER_AXIS].get_value(); + const auto traction_wheel_value_op = state_interfaces_[STATE_TRACTION_WHEEL].get_optional(); + const auto steering_position_op = state_interfaces_[STATE_STEER_AXIS].get_optional(); + + if (!traction_wheel_value_op.has_value() || !steering_position_op.has_value()) + { + RCLCPP_DEBUG( + logger, "Unable to retrieve the data from the traction wheel or steering position!"); + return true; + } + + const double traction_wheel_value = traction_wheel_value_op.value(); + const double steering_position = steering_position_op.value(); + if (std::isfinite(traction_wheel_value) && std::isfinite(steering_position)) { if (params_.position_feedback) diff --git a/bicycle_steering_controller/test/test_bicycle_steering_controller.cpp b/bicycle_steering_controller/test/test_bicycle_steering_controller.cpp index 23103f7974..7036dd4102 100644 --- a/bicycle_steering_controller/test/test_bicycle_steering_controller.cpp +++ b/bicycle_steering_controller/test/test_bicycle_steering_controller.cpp @@ -126,9 +126,9 @@ TEST_F(BicycleSteeringControllerTest, reactivate_success) ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_deactivate(rclcpp_lifecycle::State()), NODE_SUCCESS); - ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_value())); + ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_optional().value())); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); - ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_value())); + ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_optional().value())); ASSERT_EQ( controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), @@ -158,9 +158,10 @@ TEST_F(BicycleSteeringControllerTest, test_update_logic) controller_interface::return_type::OK); EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_WHEEL].get_value(), 0.1 / 0.45, COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_WHEEL].get_optional().value(), 0.1 / 0.45, + COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_STEER_WHEEL].get_value(), 1.4179821977774734, + controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); @@ -190,9 +191,10 @@ TEST_F(BicycleSteeringControllerTest, test_update_logic_chained) controller_interface::return_type::OK); EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_WHEEL].get_value(), 0.1 / 0.45, COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_WHEEL].get_optional().value(), 0.1 / 0.45, + COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_STEER_WHEEL].get_value(), 1.4179821977774734, + controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); @@ -245,9 +247,10 @@ TEST_F(BicycleSteeringControllerTest, receive_message_and_publish_updated_status controller_interface::return_type::OK); EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_WHEEL].get_value(), 0.1 / 0.45, COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_WHEEL].get_optional().value(), 0.1 / 0.45, + COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_STEER_WHEEL].get_value(), 1.4179821977774734, + controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); subscribe_and_get_messages(msg); diff --git a/diff_drive_controller/src/diff_drive_controller.cpp b/diff_drive_controller/src/diff_drive_controller.cpp index 3295df05a1..3dc5b1d035 100644 --- a/diff_drive_controller/src/diff_drive_controller.cpp +++ b/diff_drive_controller/src/diff_drive_controller.cpp @@ -645,11 +645,15 @@ void DiffDriveController::reset_buffers() void DiffDriveController::halt() { - const auto halt_wheels = [](auto & wheel_handles) + auto logger = get_node()->get_logger(); + const auto halt_wheels = [&](auto & wheel_handles) { for (const auto & wheel_handle : wheel_handles) { - wheel_handle.velocity.get().set_value(0.0); + if (!wheel_handle.velocity.get().set_value(0.0)) + { + RCLCPP_WARN(logger, "Failed to set wheel velocity to value 0.0"); + } } }; diff --git a/effort_controllers/src/joint_group_effort_controller.cpp b/effort_controllers/src/joint_group_effort_controller.cpp index e7d0f274a5..1d053f4c7f 100644 --- a/effort_controllers/src/joint_group_effort_controller.cpp +++ b/effort_controllers/src/joint_group_effort_controller.cpp @@ -55,11 +55,14 @@ controller_interface::CallbackReturn JointGroupEffortController::on_deactivate( const rclcpp_lifecycle::State & previous_state) { auto ret = ForwardCommandController::on_deactivate(previous_state); - // stop all joints for (auto & command_interface : command_interfaces_) { - command_interface.set_value(0.0); + if (!command_interface.set_value(0.0)) + { + RCLCPP_ERROR(get_node()->get_logger(), "Unable to set command interface value to 0.0"); + return controller_interface::CallbackReturn::SUCCESS; + } } return ret; diff --git a/effort_controllers/test/test_joint_group_effort_controller.cpp b/effort_controllers/test/test_joint_group_effort_controller.cpp index 01125ac442..e88dfe63a6 100644 --- a/effort_controllers/test/test_joint_group_effort_controller.cpp +++ b/effort_controllers/test/test_joint_group_effort_controller.cpp @@ -106,9 +106,9 @@ TEST_F(JointGroupEffortControllerTest, CommandSuccessTest) controller_interface::return_type::OK); // check joint commands are still the default ones - ASSERT_EQ(joint_1_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); // send command auto command_ptr = std::make_shared(); @@ -121,9 +121,9 @@ TEST_F(JointGroupEffortControllerTest, CommandSuccessTest) controller_interface::return_type::OK); // check joint commands have been modified - ASSERT_EQ(joint_1_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_2_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_3_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 30.0); } TEST_F(JointGroupEffortControllerTest, WrongCommandCheckTest) @@ -143,9 +143,9 @@ TEST_F(JointGroupEffortControllerTest, WrongCommandCheckTest) controller_interface::return_type::ERROR); // check joint commands are still the default ones - ASSERT_EQ(joint_1_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); } TEST_F(JointGroupEffortControllerTest, NoCommandCheckTest) @@ -160,9 +160,9 @@ TEST_F(JointGroupEffortControllerTest, NoCommandCheckTest) controller_interface::return_type::OK); // check joint commands are still the default ones - ASSERT_EQ(joint_1_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); } TEST_F(JointGroupEffortControllerTest, CommandCallbackTest) @@ -171,9 +171,9 @@ TEST_F(JointGroupEffortControllerTest, CommandCallbackTest) controller_->get_node()->set_parameter({"joints", joint_names_}); // default values - ASSERT_EQ(joint_1_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); auto node_state = controller_->configure(); ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE); @@ -204,9 +204,9 @@ TEST_F(JointGroupEffortControllerTest, CommandCallbackTest) controller_interface::return_type::OK); // check command in handle was set - ASSERT_EQ(joint_1_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_2_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_3_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 30.0); } TEST_F(JointGroupEffortControllerTest, StopJointsOnDeactivateTest) @@ -218,15 +218,15 @@ TEST_F(JointGroupEffortControllerTest, StopJointsOnDeactivateTest) ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); // check joint commands are still the default ones - ASSERT_EQ(joint_1_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); // stop the controller ASSERT_EQ(controller_->on_deactivate(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); // check joint commands are now zero - ASSERT_EQ(joint_1_cmd_.get_value(), 0.0); - ASSERT_EQ(joint_2_cmd_.get_value(), 0.0); - ASSERT_EQ(joint_3_cmd_.get_value(), 0.0); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 0.0); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 0.0); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 0.0); } diff --git a/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp b/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp index 99fa93d845..017928888f 100644 --- a/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/test/test_force_torque_sensor_broadcaster.cpp @@ -340,7 +340,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success_with_Offsets ASSERT_EQ( exported_state_interfaces[i]->get_prefix_name(), controller_name + "/" + sensor_name_); ASSERT_EQ( - exported_state_interfaces[i]->get_value(), + exported_state_interfaces[i]->get_optional().value(), sensor_values_[i] + (i < 3 ? force_offsets[i] : torque_offsets[i - 3])); } } @@ -411,7 +411,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, SensorName_Publish_Success_with_Multipl for (size_t i = 0; i < 6; ++i) { ASSERT_EQ( - exported_state_interfaces[i]->get_value(), + exported_state_interfaces[i]->get_optional().value(), sensor_values_[i] * (i < 3 ? force_multipliers[i] : torque_multipliers[i - 3])); } } @@ -450,8 +450,8 @@ TEST_F(ForceTorqueSensorBroadcasterTest, InterfaceNames_Publish_Success) ASSERT_EQ(exported_state_interfaces[1]->get_prefix_name(), controller_name); ASSERT_EQ(exported_state_interfaces[0]->get_interface_name(), "fts_sensor/force.x"); ASSERT_EQ(exported_state_interfaces[1]->get_interface_name(), "fts_sensor/torque.z"); - ASSERT_EQ(exported_state_interfaces[0]->get_value(), sensor_values_[0]); - ASSERT_EQ(exported_state_interfaces[1]->get_value(), sensor_values_[5]); + ASSERT_EQ(exported_state_interfaces[0]->get_optional().value(), sensor_values_[0]); + ASSERT_EQ(exported_state_interfaces[1]->get_optional().value(), sensor_values_[5]); } TEST_F(ForceTorqueSensorBroadcasterTest, All_InterfaceNames_Publish_Success) @@ -501,7 +501,7 @@ TEST_F(ForceTorqueSensorBroadcasterTest, All_InterfaceNames_Publish_Success) for (size_t i = 0; i < 6; ++i) { ASSERT_EQ(exported_state_interfaces[0]->get_prefix_name(), controller_name); - ASSERT_EQ(exported_state_interfaces[i]->get_value(), sensor_values_[i]); + ASSERT_EQ(exported_state_interfaces[i]->get_optional().value(), sensor_values_[i]); } } diff --git a/forward_command_controller/src/forward_controllers_base.cpp b/forward_command_controller/src/forward_controllers_base.cpp index ff765e6600..e8ccb3c6ca 100644 --- a/forward_command_controller/src/forward_controllers_base.cpp +++ b/forward_command_controller/src/forward_controllers_base.cpp @@ -151,10 +151,17 @@ controller_interface::return_type ForwardControllersBase::update( for (auto index = 0ul; index < command_interfaces_.size(); ++index) { - command_interfaces_[index].set_value((*joint_commands)->data[index]); + const auto & value = (*joint_commands)->data[index]; + + if (!command_interfaces_[index].set_value(value)) + { + RCLCPP_WARN( + get_node()->get_logger(), "Unable to set the command interface value %s: value = %f", + command_interfaces_[index].get_name().c_str(), value); + return controller_interface::return_type::OK; + } } return controller_interface::return_type::OK; } - } // namespace forward_command_controller diff --git a/forward_command_controller/test/test_forward_command_controller.cpp b/forward_command_controller/test/test_forward_command_controller.cpp index e00a69c468..07f4e64e3a 100644 --- a/forward_command_controller/test/test_forward_command_controller.cpp +++ b/forward_command_controller/test/test_forward_command_controller.cpp @@ -213,9 +213,9 @@ TEST_F(ForwardCommandControllerTest, CommandSuccessTest) controller_interface::return_type::OK); // check joint commands are still the default ones - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); // send command auto command_ptr = std::make_shared(); @@ -228,9 +228,9 @@ TEST_F(ForwardCommandControllerTest, CommandSuccessTest) controller_interface::return_type::OK); // check joint commands have been modified - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 30.0); } TEST_F(ForwardCommandControllerTest, WrongCommandCheckTest) @@ -256,9 +256,9 @@ TEST_F(ForwardCommandControllerTest, WrongCommandCheckTest) controller_interface::return_type::ERROR); // check joint commands are still the default ones - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); } TEST_F(ForwardCommandControllerTest, NoCommandCheckTest) @@ -278,9 +278,9 @@ TEST_F(ForwardCommandControllerTest, NoCommandCheckTest) controller_interface::return_type::OK); // check joint commands are still the default ones - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); } TEST_F(ForwardCommandControllerTest, CommandCallbackTest) @@ -291,9 +291,9 @@ TEST_F(ForwardCommandControllerTest, CommandCallbackTest) controller_->get_node()->set_parameter({"interface_name", "position"}); // default values - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); auto node_state = controller_->configure(); ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE); @@ -324,9 +324,9 @@ TEST_F(ForwardCommandControllerTest, CommandCallbackTest) controller_interface::return_type::OK); // check command in handle was set - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 30.0); } TEST_F(ForwardCommandControllerTest, DropInfiniteCommandCallbackTest) @@ -337,9 +337,9 @@ TEST_F(ForwardCommandControllerTest, DropInfiniteCommandCallbackTest) controller_->get_node()->set_parameter({"interface_name", "position"}); // default values - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); auto node_state = controller_->configure(); ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE); @@ -370,9 +370,9 @@ TEST_F(ForwardCommandControllerTest, DropInfiniteCommandCallbackTest) controller_interface::return_type::OK); // check message containing infinite command value was rejected - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); } TEST_F(ForwardCommandControllerTest, ActivateDeactivateCommandsResetSuccess) @@ -383,9 +383,9 @@ TEST_F(ForwardCommandControllerTest, ActivateDeactivateCommandsResetSuccess) controller_->get_node()->set_parameter({"interface_name", "position"}); // default values - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); auto node_state = controller_->configure(); ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE); @@ -420,9 +420,9 @@ TEST_F(ForwardCommandControllerTest, ActivateDeactivateCommandsResetSuccess) controller_interface::return_type::OK); // check command in handle was set - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 10); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 20); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 30); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 10); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 20); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 30); node_state = controller_->get_node()->deactivate(); ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE); @@ -472,9 +472,9 @@ TEST_F(ForwardCommandControllerTest, ActivateDeactivateCommandsResetSuccess) controller_interface::return_type::OK); // values should not change - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 10); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 20); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 30); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 10); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 20); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 30); // set commands again controller_->rt_command_ptr_.writeFromNonRT(command_msg); @@ -485,7 +485,7 @@ TEST_F(ForwardCommandControllerTest, ActivateDeactivateCommandsResetSuccess) controller_interface::return_type::OK); // check command in handle was set - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 5.5); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 6.6); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 7.7); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 5.5); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 6.6); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 7.7); } diff --git a/forward_command_controller/test/test_multi_interface_forward_command_controller.cpp b/forward_command_controller/test/test_multi_interface_forward_command_controller.cpp index 7bd869677c..2be11101a9 100644 --- a/forward_command_controller/test/test_multi_interface_forward_command_controller.cpp +++ b/forward_command_controller/test/test_multi_interface_forward_command_controller.cpp @@ -189,9 +189,9 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, ActivateSuccess) SetUpController(true); // check joint commands are the default ones - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_1_vel_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_1_eff_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_1_vel_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_1_eff_cmd_.get_optional().value(), 3.1); } TEST_F(MultiInterfaceForwardCommandControllerTest, CommandSuccessTest) @@ -209,9 +209,9 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, CommandSuccessTest) controller_interface::return_type::OK); // check command in handle was set - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_1_vel_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_1_eff_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_1_vel_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_1_eff_cmd_.get_optional().value(), 30.0); } TEST_F(MultiInterfaceForwardCommandControllerTest, NoCommandCheckTest) @@ -224,9 +224,9 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, NoCommandCheckTest) controller_interface::return_type::OK); // check joint commands are still the default ones - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_1_vel_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_1_eff_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_1_vel_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_1_eff_cmd_.get_optional().value(), 3.1); } TEST_F(MultiInterfaceForwardCommandControllerTest, WrongCommandCheckTest) @@ -244,9 +244,9 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, WrongCommandCheckTest) controller_interface::return_type::ERROR); // check joint commands are still the default ones - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_1_vel_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_1_eff_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_1_vel_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_1_eff_cmd_.get_optional().value(), 3.1); } TEST_F(MultiInterfaceForwardCommandControllerTest, CommandCallbackTest) @@ -276,9 +276,9 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, CommandCallbackTest) controller_interface::return_type::OK); // check command in handle was set - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_1_vel_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_1_eff_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_1_vel_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_1_eff_cmd_.get_optional().value(), 30.0); } TEST_F(MultiInterfaceForwardCommandControllerTest, ActivateDeactivateCommandsResetSuccess) @@ -304,9 +304,9 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, ActivateDeactivateCommandsRes controller_interface::return_type::OK); // check command in handle was set - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_1_vel_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_1_eff_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_1_vel_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_1_eff_cmd_.get_optional().value(), 30.0); auto node_state = controller_->get_node()->deactivate(); ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE); @@ -355,9 +355,9 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, ActivateDeactivateCommandsRes controller_interface::return_type::OK); // values should not change - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_1_vel_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_1_eff_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_1_vel_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_1_eff_cmd_.get_optional().value(), 30.0); // set commands again controller_->rt_command_ptr_.writeFromNonRT(command_msg); @@ -368,7 +368,7 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, ActivateDeactivateCommandsRes controller_interface::return_type::OK); // check command in handle was set - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 5.5); - ASSERT_EQ(joint_1_vel_cmd_.get_value(), 6.6); - ASSERT_EQ(joint_1_eff_cmd_.get_value(), 7.7); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 5.5); + ASSERT_EQ(joint_1_vel_cmd_.get_optional().value(), 6.6); + ASSERT_EQ(joint_1_eff_cmd_.get_optional().value(), 7.7); } diff --git a/gpio_controllers/src/gpio_command_controller.cpp b/gpio_controllers/src/gpio_command_controller.cpp index fdecf71c30..4250114e1f 100644 --- a/gpio_controllers/src/gpio_command_controller.cpp +++ b/gpio_controllers/src/gpio_command_controller.cpp @@ -350,11 +350,18 @@ void GpioCommandController::apply_command( const auto full_command_interface_name = gpio_commands.interface_groups[gpio_index] + '/' + gpio_commands.interface_values[gpio_index].interface_names[command_interface_index]; + + const auto & command_value = + gpio_commands.interface_values[gpio_index].values[command_interface_index]; + try { - command_interfaces_map_.at(full_command_interface_name) - .get() - .set_value(gpio_commands.interface_values[gpio_index].values[command_interface_index]); + if (!command_interfaces_map_.at(full_command_interface_name).get().set_value(command_value)) + { + RCLCPP_WARN( + get_node()->get_logger(), "Unable to set the command for interface '%s' with value '%f'.", + full_command_interface_name.c_str(), command_value); + } } catch (const std::exception & e) { @@ -394,8 +401,20 @@ void GpioCommandController::apply_state_value( state_msg.interface_values[gpio_index].interface_names[interface_index]; try { - state_msg.interface_values[gpio_index].values[interface_index] = - state_interfaces_map_.at(interface_name).get().get_value(); + auto state_msg_interface_value_op = + state_interfaces_map_.at(interface_name).get().get_optional(); + + if (!state_msg_interface_value_op.has_value()) + { + RCLCPP_DEBUG( + get_node()->get_logger(), "Unable to retrieve the data from state: %s \n", + interface_name.c_str()); + } + else + { + state_msg.interface_values[gpio_index].values[interface_index] = + state_msg_interface_value_op.value(); + } } catch (const std::exception & e) { diff --git a/gpio_controllers/test/test_gpio_command_controller.cpp b/gpio_controllers/test/test_gpio_command_controller.cpp index de085894f2..e8f720de3b 100644 --- a/gpio_controllers/test/test_gpio_command_controller.cpp +++ b/gpio_controllers/test/test_gpio_command_controller.cpp @@ -133,12 +133,12 @@ class GpioCommandControllerTestSuite : public ::testing::Test void assert_default_command_and_state_values() { - ASSERT_EQ(gpio_1_1_dig_cmd.get_value(), gpio_commands.at(0)); - ASSERT_EQ(gpio_1_2_dig_cmd.get_value(), gpio_commands.at(1)); - ASSERT_EQ(gpio_2_ana_cmd.get_value(), gpio_commands.at(2)); - ASSERT_EQ(gpio_1_1_dig_state.get_value(), gpio_states.at(0)); - ASSERT_EQ(gpio_1_2_dig_state.get_value(), gpio_states.at(1)); - ASSERT_EQ(gpio_2_ana_state.get_value(), gpio_states.at(2)); + ASSERT_EQ(gpio_1_1_dig_cmd.get_optional().value(), gpio_commands.at(0)); + ASSERT_EQ(gpio_1_2_dig_cmd.get_optional().value(), gpio_commands.at(1)); + ASSERT_EQ(gpio_2_ana_cmd.get_optional().value(), gpio_commands.at(2)); + ASSERT_EQ(gpio_1_1_dig_state.get_optional().value(), gpio_states.at(0)); + ASSERT_EQ(gpio_1_2_dig_state.get_optional().value(), gpio_states.at(1)); + ASSERT_EQ(gpio_2_ana_state.get_optional().value(), gpio_states.at(2)); } void update_controller_loop() @@ -492,9 +492,9 @@ TEST_F( controller_->rt_command_ptr_.writeFromNonRT(std::make_shared(command)); update_controller_loop(); - ASSERT_EQ(gpio_1_1_dig_cmd.get_value(), 0.0); - ASSERT_EQ(gpio_1_2_dig_cmd.get_value(), 1.0); - ASSERT_EQ(gpio_2_ana_cmd.get_value(), 30.0); + ASSERT_EQ(gpio_1_1_dig_cmd.get_optional().value(), 0.0); + ASSERT_EQ(gpio_1_2_dig_cmd.get_optional().value(), 1.0); + ASSERT_EQ(gpio_2_ana_cmd.get_optional().value(), 30.0); } TEST_F( @@ -516,9 +516,9 @@ TEST_F( controller_->rt_command_ptr_.writeFromNonRT(std::make_shared(command)); update_controller_loop(); - ASSERT_EQ(gpio_1_1_dig_cmd.get_value(), 0.0); - ASSERT_EQ(gpio_1_2_dig_cmd.get_value(), 1.0); - ASSERT_EQ(gpio_2_ana_cmd.get_value(), 30.0); + ASSERT_EQ(gpio_1_1_dig_cmd.get_optional().value(), 0.0); + ASSERT_EQ(gpio_1_2_dig_cmd.get_optional().value(), 1.0); + ASSERT_EQ(gpio_2_ana_cmd.get_optional().value(), 30.0); } TEST_F( @@ -540,9 +540,9 @@ TEST_F( controller_->rt_command_ptr_.writeFromNonRT(std::make_shared(command)); update_controller_loop(); - ASSERT_EQ(gpio_1_1_dig_cmd.get_value(), 0.0); - ASSERT_EQ(gpio_1_2_dig_cmd.get_value(), 1.0); - ASSERT_EQ(gpio_2_ana_cmd.get_value(), gpio_commands[2]); + ASSERT_EQ(gpio_1_1_dig_cmd.get_optional().value(), 0.0); + ASSERT_EQ(gpio_1_2_dig_cmd.get_optional().value(), 1.0); + ASSERT_EQ(gpio_2_ana_cmd.get_optional().value(), gpio_commands[2]); } TEST_F( @@ -565,9 +565,9 @@ TEST_F( controller_->rt_command_ptr_.writeFromNonRT(std::make_shared(command)); update_controller_loop(); - ASSERT_EQ(gpio_1_1_dig_cmd.get_value(), gpio_commands.at(0)); - ASSERT_EQ(gpio_1_2_dig_cmd.get_value(), gpio_commands.at(1)); - ASSERT_EQ(gpio_2_ana_cmd.get_value(), gpio_commands.at(2)); + ASSERT_EQ(gpio_1_1_dig_cmd.get_optional().value(), gpio_commands.at(0)); + ASSERT_EQ(gpio_1_2_dig_cmd.get_optional().value(), gpio_commands.at(1)); + ASSERT_EQ(gpio_2_ana_cmd.get_optional().value(), gpio_commands.at(2)); } TEST_F( @@ -592,9 +592,9 @@ TEST_F( wait_one_miliseconds_for_timeout(); update_controller_loop(); - ASSERT_EQ(gpio_1_1_dig_cmd.get_value(), 0.0); - ASSERT_EQ(gpio_1_2_dig_cmd.get_value(), 1.0); - ASSERT_EQ(gpio_2_ana_cmd.get_value(), 30.0); + ASSERT_EQ(gpio_1_1_dig_cmd.get_optional().value(), 0.0); + ASSERT_EQ(gpio_1_2_dig_cmd.get_optional().value(), 1.0); + ASSERT_EQ(gpio_2_ana_cmd.get_optional().value(), 30.0); } TEST_F(GpioCommandControllerTestSuite, ControllerShouldPublishGpioStatesWithCurrentValues) diff --git a/gripper_controllers/include/gripper_controllers/gripper_action_controller_impl.hpp b/gripper_controllers/include/gripper_controllers/gripper_action_controller_impl.hpp index a94e163d7b..8e60a1add0 100644 --- a/gripper_controllers/include/gripper_controllers/gripper_action_controller_impl.hpp +++ b/gripper_controllers/include/gripper_controllers/gripper_action_controller_impl.hpp @@ -65,8 +65,8 @@ controller_interface::return_type GripperActionController::up { command_struct_rt_ = *(command_.readFromRT()); - const double current_position = joint_position_state_interface_->get().get_value(); - const double current_velocity = joint_velocity_state_interface_->get().get_value(); + const double current_position = joint_position_state_interface_->get().get_optional().value(); + const double current_velocity = joint_velocity_state_interface_->get().get_optional().value(); const double error_position = command_struct_rt_.position_ - current_position; const double error_velocity = -current_velocity; @@ -147,7 +147,7 @@ rclcpp_action::CancelResponse GripperActionController::cancel template void GripperActionController::set_hold_position() { - command_struct_.position_ = joint_position_state_interface_->get().get_value(); + command_struct_.position_ = joint_position_state_interface_->get().get_optional().value(); command_struct_.max_effort_ = params_.max_effort; command_.writeFromNonRT(command_struct_); } @@ -285,7 +285,7 @@ controller_interface::CallbackReturn GripperActionController: hw_iface_adapter_.init(joint_command_interface_, get_node()); // Command - non RT version - command_struct_.position_ = joint_position_state_interface_->get().get_value(); + command_struct_.position_ = joint_position_state_interface_->get().get_optional().value(); command_struct_.max_effort_ = params_.max_effort; command_.initRT(command_struct_); diff --git a/gripper_controllers/include/gripper_controllers/hardware_interface_adapter.hpp b/gripper_controllers/include/gripper_controllers/hardware_interface_adapter.hpp index 66da3d869a..1c7d08baaf 100644 --- a/gripper_controllers/include/gripper_controllers/hardware_interface_adapter.hpp +++ b/gripper_controllers/include/gripper_controllers/hardware_interface_adapter.hpp @@ -83,7 +83,7 @@ class HardwareInterfaceAdapter double /* error_velocity */, double max_allowed_effort) { // Forward desired position to command - joint_handle_->get().set_value(desired_position); + std::ignore = joint_handle_->get().set_value(desired_position); return max_allowed_effort; } @@ -148,7 +148,7 @@ class HardwareInterfaceAdapter } // Reset PIDs, zero effort commands pid_->reset(); - joint_handle_->get().set_value(0.0); + std::ignore = joint_handle_->get().set_value(0.0); } void stopping(const rclcpp::Time & /* time */) {} @@ -168,7 +168,7 @@ class HardwareInterfaceAdapter double command = pid_->compute_command(error_position, error_velocity, period); command = std::min( fabs(max_allowed_effort), std::max(-fabs(max_allowed_effort), command)); - joint_handle_->get().set_value(command); + std::ignore = joint_handle_->get().set_value(command); last_update_time_ = std::chrono::steady_clock::now(); return command; } diff --git a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp index 251dacc460..4c6717d338 100644 --- a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp +++ b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp @@ -282,7 +282,15 @@ class JointTrajectoryController : public controller_interface::ControllerInterfa { for (size_t index = 0; index < num_cmd_joints_; ++index) { - joint_interface[index].get().set_value(trajectory_point_interface[map_cmd_to_joints_[index]]); + if (!joint_interface[index].get().set_value( + trajectory_point_interface[map_cmd_to_joints_[index]])) + { + RCLCPP_ERROR( + get_node()->get_logger(), + "Failed to set value for joint '%s' in command interface '%s'. ", + command_joint_names_[index].c_str(), joint_interface[index].get().get_name().c_str()); + return; + } } } }; diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index 117826ff3f..494ac8b11d 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -430,12 +430,22 @@ controller_interface::return_type JointTrajectoryController::update( void JointTrajectoryController::read_state_from_state_interfaces(JointTrajectoryPoint & state) { + auto logger = get_node()->get_logger(); auto assign_point_from_state_interface = [&](std::vector & trajectory_point_interface, const auto & joint_interface) { for (size_t index = 0; index < dof_; ++index) { - trajectory_point_interface[index] = joint_interface[index].get().get_value(); + const auto joint_state_interface_value_op = joint_interface[index].get().get_optional(); + if (!joint_state_interface_value_op.has_value()) + { + RCLCPP_DEBUG( + logger, "Unable to retrieve joint state interface value for joint at index %zu", index); + } + else + { + trajectory_point_interface[index] = joint_state_interface_value_op.value(); + } } }; auto assign_point_from_command_interface = @@ -446,8 +456,17 @@ void JointTrajectoryController::read_state_from_state_interfaces(JointTrajectory std::numeric_limits::quiet_NaN()); for (size_t index = 0; index < num_cmd_joints_; ++index) { - trajectory_point_interface[map_cmd_to_joints_[index]] = - joint_interface[index].get().get_value(); + const auto joint_command_interface_value_op = joint_interface[index].get().get_optional(); + if (!joint_command_interface_value_op.has_value()) + { + RCLCPP_DEBUG( + logger, "Unable to retrieve joint command interface value for joint at index %zu", index); + } + else + { + trajectory_point_interface[map_cmd_to_joints_[index]] = + joint_command_interface_value_op.value(); + } } }; @@ -491,16 +510,29 @@ bool JointTrajectoryController::read_state_from_command_interfaces(JointTrajecto { for (size_t index = 0; index < num_cmd_joints_; ++index) { - trajectory_point_interface[map_cmd_to_joints_[index]] = - joint_interface[index].get().get_value(); + const auto joint_interface_value_op = joint_interface[index].get().get_optional(); + if (!joint_interface_value_op.has_value()) + { + RCLCPP_DEBUG( + get_node()->get_logger(), + "Unable to retrieve value of joint interface for joint at index %zu", index); + } + else + { + trajectory_point_interface[map_cmd_to_joints_[index]] = joint_interface_value_op.value(); + } } }; auto interface_has_values = [](const auto & joint_interface) { return std::find_if( - joint_interface.begin(), joint_interface.end(), [](const auto & interface) - { return std::isnan(interface.get().get_value()); }) == joint_interface.end(); + joint_interface.begin(), joint_interface.end(), + [](const auto & interface) + { + auto interface_op = interface.get().get_optional(); + return !interface_op.has_value() || std::isnan(interface_op.value()); + }) == joint_interface.end(); }; // Assign values from the command interfaces as state. Therefore needs check for both. @@ -576,16 +608,27 @@ bool JointTrajectoryController::read_commands_from_command_interfaces( { for (size_t index = 0; index < num_cmd_joints_; ++index) { - trajectory_point_interface[map_cmd_to_joints_[index]] = - joint_interface[index].get().get_value(); + auto joint_interface_op = joint_interface[index].get().get_optional(); + if (!joint_interface_op.has_value()) + { + RCLCPP_DEBUG( + get_node()->get_logger(), "Unable to retrieve value of joint interface at index %zu", + index); + continue; + } + trajectory_point_interface[map_cmd_to_joints_[index]] = joint_interface_op.value(); } }; auto interface_has_values = [](const auto & joint_interface) { return std::find_if( - joint_interface.begin(), joint_interface.end(), [](const auto & interface) - { return std::isnan(interface.get().get_value()); }) == joint_interface.end(); + joint_interface.begin(), joint_interface.end(), + [](const auto & interface) + { + auto interface_op = interface.get().get_optional(); + return !interface_op.has_value() || std::isnan(interface_op.value()); + }) == joint_interface.end(); }; // Assign values from the command interfaces as command. @@ -1079,6 +1122,7 @@ controller_interface::CallbackReturn JointTrajectoryController::on_deactivate( const rclcpp_lifecycle::State &) { const auto active_goal = *rt_active_goal_.readFromNonRT(); + auto logger = get_node()->get_logger(); if (active_goal) { rt_has_pending_goal_ = false; @@ -1093,24 +1137,39 @@ controller_interface::CallbackReturn JointTrajectoryController::on_deactivate( { if (has_position_command_interface_) { - joint_command_interface_[0][index].get().set_value( - joint_command_interface_[0][index].get().get_value()); + const auto joint_position_value_op = joint_command_interface_[0][index].get().get_optional(); + if (!joint_position_value_op.has_value()) + { + RCLCPP_WARN(logger, "Unable to retrieve joint position value"); + return controller_interface::CallbackReturn::SUCCESS; + } + if (!joint_command_interface_[0][index].get().set_value(joint_position_value_op.value())) + { + RCLCPP_WARN( + logger, "Unable to set the joint position to value: %f", joint_position_value_op.value()); + return controller_interface::CallbackReturn::SUCCESS; + } } - if (has_velocity_command_interface_) + if (has_velocity_command_interface_ && !joint_command_interface_[1][index].get().set_value(0.0)) { - joint_command_interface_[1][index].get().set_value(0.0); + RCLCPP_WARN(logger, "Error while setting joint velocity to value 0.0"); + return controller_interface::CallbackReturn::SUCCESS; } - if (has_acceleration_command_interface_) + if ( + has_acceleration_command_interface_ && + !joint_command_interface_[2][index].get().set_value(0.0)) { - joint_command_interface_[2][index].get().set_value(0.0); + RCLCPP_WARN(logger, "Error while setting joint acceleration to value 0.0"); + return controller_interface::CallbackReturn::SUCCESS; } // TODO(anyone): How to halt when using effort commands? - if (has_effort_command_interface_) + if (has_effort_command_interface_ && !joint_command_interface_[3][index].get().set_value(0.0)) { - joint_command_interface_[3][index].get().set_value(0.0); + RCLCPP_WARN(logger, "Error while setting joint effort to value 0.0"); + return controller_interface::CallbackReturn::SUCCESS; } } @@ -1342,17 +1401,38 @@ void JointTrajectoryController::fill_partial_goal( // Assume hold position with 0 velocity and acceleration for missing joints if (!it.positions.empty()) { - if ( - has_position_command_interface_ && - !std::isnan(joint_command_interface_[0][index].get().get_value())) + if (has_position_command_interface_) { - // copy last command if cmd interface exists - it.positions.push_back(joint_command_interface_[0][index].get().get_value()); + const auto position_command_value_op = + joint_command_interface_[0][index].get().get_optional(); + + if (!position_command_value_op.has_value()) + { + RCLCPP_DEBUG( + get_node()->get_logger(), + "Unable to retrieve position command value of joint at index %zu", index); + } + else if (!std::isnan(position_command_value_op.value())) + { + it.positions.push_back(position_command_value_op.value()); + } } + else if (has_position_state_interface_) { // copy current state if state interface exists - it.positions.push_back(joint_state_interface_[0][index].get().get_value()); + const auto position_state_value_op = + joint_state_interface_[0][index].get().get_optional(); + if (!position_state_value_op.has_value()) + { + RCLCPP_DEBUG( + get_node()->get_logger(), + "Unable to retrieve position state value of joint at index %zu", index); + } + else if (!std::isnan(position_state_value_op.value())) + { + it.positions.push_back(position_state_value_op.value()); + } } } if (!it.velocities.empty()) diff --git a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp index c47e9ccd86..41a2ab8ece 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp +++ b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp @@ -393,13 +393,13 @@ class TrajectoryControllerTest : public ::testing::Test // Add to export lists and set initial values cmd_interfaces.emplace_back(pos_cmd_interfaces_.back()); - cmd_interfaces.back().set_value(initial_pos_joints[i]); + (void)cmd_interfaces.back().set_value(initial_pos_joints[i]); cmd_interfaces.emplace_back(vel_cmd_interfaces_.back()); - cmd_interfaces.back().set_value(initial_vel_joints[i]); + (void)cmd_interfaces.back().set_value(initial_vel_joints[i]); cmd_interfaces.emplace_back(acc_cmd_interfaces_.back()); - cmd_interfaces.back().set_value(initial_acc_joints[i]); + (void)cmd_interfaces.back().set_value(initial_acc_joints[i]); cmd_interfaces.emplace_back(eff_cmd_interfaces_.back()); - cmd_interfaces.back().set_value(initial_eff_joints[i]); + (void)cmd_interfaces.back().set_value(initial_eff_joints[i]); if (separate_cmd_and_state_values) { joint_state_pos_[i] = INITIAL_POS_JOINTS[i]; @@ -690,9 +690,10 @@ class TrajectoryControllerTest : public ::testing::Test for (size_t i = 0; i < 3; i++) { EXPECT_TRUE(is_same_sign_or_zero( - position.at(i) - pos_state_interfaces_[i].get_value(), joint_vel_[i])) + position.at(i) - pos_state_interfaces_[i].get_optional().value(), joint_vel_[i])) << "test position point " << position.at(i) << ", position state is " - << pos_state_interfaces_[i].get_value() << ", velocity command is " << joint_vel_[i]; + << pos_state_interfaces_[i].get_optional().value() << ", velocity command is " + << joint_vel_[i]; } } if (traj_controller_->has_effort_command_interface()) @@ -700,9 +701,11 @@ class TrajectoryControllerTest : public ::testing::Test for (size_t i = 0; i < 3; i++) { EXPECT_TRUE(is_same_sign_or_zero( - position.at(i) - pos_state_interfaces_[i].get_value() + effort.at(i), joint_eff_[i])) + position.at(i) - pos_state_interfaces_[i].get_optional().value() + effort.at(i), + joint_eff_[i])) << "test position point " << position.at(i) << ", position state is " - << pos_state_interfaces_[i].get_value() << ", effort command is " << joint_eff_[i]; + << pos_state_interfaces_[i].get_optional().value() << ", effort command is " + << joint_eff_[i]; } } } diff --git a/mecanum_drive_controller/src/mecanum_drive_controller.cpp b/mecanum_drive_controller/src/mecanum_drive_controller.cpp index ead080050f..acb3b5a5cf 100644 --- a/mecanum_drive_controller/src/mecanum_drive_controller.cpp +++ b/mecanum_drive_controller/src/mecanum_drive_controller.cpp @@ -400,10 +400,26 @@ controller_interface::return_type MecanumDriveController::update_and_write_comma const rclcpp::Time & time, const rclcpp::Duration & period) { // FORWARD KINEMATICS (odometry). - const double wheel_front_left_state_vel = state_interfaces_[FRONT_LEFT].get_value(); - const double wheel_front_right_state_vel = state_interfaces_[FRONT_RIGHT].get_value(); - const double wheel_rear_right_state_vel = state_interfaces_[REAR_RIGHT].get_value(); - const double wheel_rear_left_state_vel = state_interfaces_[REAR_LEFT].get_value(); + const auto wheel_front_left_state_vel_op = state_interfaces_[FRONT_LEFT].get_optional(); + const auto wheel_front_right_state_vel_op = state_interfaces_[FRONT_RIGHT].get_optional(); + const auto wheel_rear_right_state_vel_op = state_interfaces_[REAR_RIGHT].get_optional(); + const auto wheel_rear_left_state_vel_op = state_interfaces_[REAR_LEFT].get_optional(); + + if ( + !wheel_front_left_state_vel_op.has_value() || !wheel_front_right_state_vel_op.has_value() || + !wheel_rear_right_state_vel_op.has_value() || !wheel_rear_left_state_vel_op.has_value()) + { + RCLCPP_DEBUG( + get_node()->get_logger(), + "Unable to retrieve data from front left wheel or front right wheel or rear left wheel or " + "rear right wheel"); + return controller_interface::return_type::OK; + } + + const double wheel_front_left_state_vel = wheel_front_left_state_vel_op.value(); + const double wheel_front_right_state_vel = wheel_front_right_state_vel_op.value(); + const double wheel_rear_right_state_vel = wheel_rear_right_state_vel_op.value(); + const double wheel_rear_left_state_vel = wheel_rear_left_state_vel_op.value(); if ( !std::isnan(wheel_front_left_state_vel) && !std::isnan(wheel_rear_left_state_vel) && @@ -522,14 +538,12 @@ controller_interface::return_type MecanumDriveController::update_and_write_comma if (controller_state_publisher_->trylock()) { controller_state_publisher_->msg_.header.stamp = get_node()->now(); - controller_state_publisher_->msg_.front_left_wheel_velocity = - state_interfaces_[FRONT_LEFT].get_value(); - controller_state_publisher_->msg_.front_right_wheel_velocity = - state_interfaces_[FRONT_RIGHT].get_value(); - controller_state_publisher_->msg_.back_right_wheel_velocity = - state_interfaces_[REAR_RIGHT].get_value(); - controller_state_publisher_->msg_.back_left_wheel_velocity = - state_interfaces_[REAR_LEFT].get_value(); + + controller_state_publisher_->msg_.front_left_wheel_velocity = wheel_front_left_state_vel; + controller_state_publisher_->msg_.front_right_wheel_velocity = wheel_front_right_state_vel; + controller_state_publisher_->msg_.back_right_wheel_velocity = wheel_rear_right_state_vel; + controller_state_publisher_->msg_.back_left_wheel_velocity = wheel_rear_left_state_vel; + controller_state_publisher_->msg_.reference_velocity.linear.x = reference_interfaces_[0]; controller_state_publisher_->msg_.reference_velocity.linear.y = reference_interfaces_[1]; controller_state_publisher_->msg_.reference_velocity.angular.z = reference_interfaces_[2]; diff --git a/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp b/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp index 748940b138..1278be5453 100644 --- a/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp +++ b/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp @@ -339,11 +339,11 @@ TEST_F( ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); - ASSERT_EQ(controller_->command_interfaces_[NR_CMD_ITFS - 4].get_value(), 101.101); + ASSERT_EQ(controller_->command_interfaces_[NR_CMD_ITFS - 4].get_optional().value(), 101.101); ASSERT_EQ(controller_->on_deactivate(rclcpp_lifecycle::State()), NODE_SUCCESS); - ASSERT_TRUE(std::isnan(controller_->command_interfaces_[NR_CMD_ITFS - 4].get_value())); + ASSERT_TRUE(std::isnan(controller_->command_interfaces_[NR_CMD_ITFS - 4].get_optional().value())); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); - ASSERT_TRUE(std::isnan(controller_->command_interfaces_[NR_CMD_ITFS - 4].get_value())); + ASSERT_TRUE(std::isnan(controller_->command_interfaces_[NR_CMD_ITFS - 4].get_optional().value())); ASSERT_EQ( controller_->update(controller_->get_node()->now(), rclcpp::Duration::from_seconds(0.01)), @@ -561,7 +561,7 @@ TEST_F( } for (size_t i = 0; i < controller_->command_interfaces_.size(); ++i) { - EXPECT_EQ(controller_->command_interfaces_[i].get_value(), 0.0); + EXPECT_EQ(controller_->command_interfaces_[i].get_optional().value(), 0.0); } std::shared_ptr msg_2 = std::make_shared(); @@ -600,7 +600,7 @@ TEST_F( for (size_t i = 0; i < controller_->command_interfaces_.size(); ++i) { - EXPECT_EQ(controller_->command_interfaces_[i].get_value(), 3.0); + EXPECT_EQ(controller_->command_interfaces_[i].get_optional().value(), 3.0); } } @@ -659,7 +659,7 @@ TEST_F( } for (size_t i = 0; i < controller_->command_interfaces_.size(); ++i) { - EXPECT_EQ(controller_->command_interfaces_[i].get_value(), 6.0); + EXPECT_EQ(controller_->command_interfaces_[i].get_optional().value(), 6.0); } } @@ -810,10 +810,14 @@ TEST_F(MecanumDriveControllerTest, SideToSideAndRotationOdometryTest) size_t fr_index = controller_->get_front_right_wheel_index(); size_t rl_index = controller_->get_rear_left_wheel_index(); size_t rr_index = controller_->get_rear_right_wheel_index(); - joint_state_values_[fl_index] = controller_->command_interfaces_[fl_index].get_value(); - joint_state_values_[fr_index] = controller_->command_interfaces_[fr_index].get_value(); - joint_state_values_[rl_index] = controller_->command_interfaces_[rl_index].get_value(); - joint_state_values_[rr_index] = controller_->command_interfaces_[rr_index].get_value(); + joint_state_values_[fl_index] = + controller_->command_interfaces_[fl_index].get_optional().value(); + joint_state_values_[fr_index] = + controller_->command_interfaces_[fr_index].get_optional().value(); + joint_state_values_[rl_index] = + controller_->command_interfaces_[rl_index].get_optional().value(); + joint_state_values_[rr_index] = + controller_->command_interfaces_[rr_index].get_optional().value(); } RCLCPP_INFO( diff --git a/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp b/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp index b6be291a8d..82037ed546 100644 --- a/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp +++ b/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp @@ -57,22 +57,46 @@ controller_interface::CallbackReturn GripperActionController::on_init() controller_interface::return_type GripperActionController::update( const rclcpp::Time & /*time*/, const rclcpp::Duration & /*period*/) { + auto logger = get_node()->get_logger(); command_struct_rt_ = *(command_.readFromRT()); + const auto current_position_op = joint_position_state_interface_->get().get_optional(); + if (!current_position_op.has_value()) + { + RCLCPP_DEBUG(logger, "Unable to retrieve current position value"); + return controller_interface::return_type::OK; + } + const auto current_velocity_op = joint_velocity_state_interface_->get().get_optional(); + if (!current_velocity_op.has_value()) + { + RCLCPP_DEBUG(logger, "Unable to retrieve current velocity value"); + return controller_interface::return_type::OK; + } - const double current_position = joint_position_state_interface_->get().get_value(); - const double current_velocity = joint_velocity_state_interface_->get().get_value(); - const double error_position = command_struct_rt_.position_cmd_ - current_position; + const double error_position = command_struct_rt_.position_cmd_ - current_position_op.value(); - check_for_success(get_node()->now(), error_position, current_position, current_velocity); + check_for_success( + get_node()->now(), error_position, current_position_op.value(), current_velocity_op.value()); - joint_command_interface_->get().set_value(command_struct_rt_.position_cmd_); - if (speed_interface_.has_value()) + if (!joint_command_interface_->get().set_value(command_struct_rt_.position_cmd_)) { - speed_interface_->get().set_value(command_struct_rt_.max_velocity_); + RCLCPP_WARN( + logger, "Unable to set the joint position command to: %f", command_struct_rt_.position_cmd_); + return controller_interface::return_type::OK; + } + if ( + speed_interface_.has_value() && + !speed_interface_->get().set_value(command_struct_rt_.max_velocity_)) + { + RCLCPP_WARN(logger, "Unable to set the speed command to: %f", command_struct_rt_.max_velocity_); + + return controller_interface::return_type::OK; } - if (effort_interface_.has_value()) + if ( + effort_interface_.has_value() && + !effort_interface_->get().set_value(command_struct_rt_.max_effort_)) { - effort_interface_->get().set_value(command_struct_rt_.max_effort_); + RCLCPP_WARN(logger, "Unable to set the effort command to: %f", command_struct_rt_.max_effort_); + return controller_interface::return_type::OK; } return controller_interface::return_type::OK; @@ -168,7 +192,12 @@ rclcpp_action::CancelResponse GripperActionController::cancel_callback( void GripperActionController::set_hold_position() { - command_struct_.position_cmd_ = joint_position_state_interface_->get().get_value(); + const auto position_op = joint_position_state_interface_->get().get_optional(); + if (!position_op.has_value()) + { + RCLCPP_DEBUG(get_node()->get_logger(), "Unable to retrieve data of joint position"); + } + command_struct_.position_cmd_ = position_op.value(); command_struct_.max_effort_ = params_.max_effort; command_struct_.max_velocity_ = params_.max_velocity; command_.writeFromNonRT(command_struct_); @@ -317,7 +346,15 @@ controller_interface::CallbackReturn GripperActionController::on_activate( } // Command - non RT version - command_struct_.position_cmd_ = joint_position_state_interface_->get().get_value(); + const auto position_op = joint_position_state_interface_->get().get_optional(); + if (!position_op.has_value()) + { + RCLCPP_DEBUG(get_node()->get_logger(), "Unable to retrieve data of joint position"); + } + else + { + command_struct_.position_cmd_ = position_op.value(); + } command_struct_.max_effort_ = params_.max_effort; command_struct_.max_velocity_ = params_.max_velocity; command_.initRT(command_struct_); diff --git a/pid_controller/src/pid_controller.cpp b/pid_controller/src/pid_controller.cpp index 05b534bf3e..15b3e77696 100644 --- a/pid_controller/src/pid_controller.cpp +++ b/pid_controller/src/pid_controller.cpp @@ -493,7 +493,15 @@ controller_interface::return_type PidController::update_and_write_commands( { for (size_t i = 0; i < measured_state_values_.size(); ++i) { - measured_state_values_[i] = state_interfaces_[i].get_value(); + const auto state_interface_value_op = state_interfaces_[i].get_optional(); + if (!state_interface_value_op.has_value()) + { + RCLCPP_DEBUG( + get_node()->get_logger(), "Unable to retrieve the state interface value for %s", + state_interfaces_[i].get_name().c_str()); + continue; + } + measured_state_values_[i] = state_interface_value_op.value(); } } @@ -598,7 +606,18 @@ controller_interface::return_type PidController::update_and_write_commands( state_publisher_->msg_.dof_states[i].time_step = period.seconds(); // Command can store the old calculated values. This should be obvious because at least one // another value is NaN. - state_publisher_->msg_.dof_states[i].output = command_interfaces_[i].get_value(); + const auto command_interface_value_op = command_interfaces_[i].get_optional(); + + if (!command_interface_value_op.has_value()) + { + RCLCPP_DEBUG( + get_node()->get_logger(), "Unable to retrieve the command interface value for %s", + command_interfaces_[i].get_name().c_str()); + } + else + { + state_publisher_->msg_.dof_states[i].output = command_interface_value_op.value(); + } } state_publisher_->unlockAndPublish(); } diff --git a/pid_controller/test/test_pid_controller.cpp b/pid_controller/test/test_pid_controller.cpp index 1900b172ac..633a6259ce 100644 --- a/pid_controller/test/test_pid_controller.cpp +++ b/pid_controller/test/test_pid_controller.cpp @@ -179,15 +179,15 @@ TEST_F(PidControllerTest, reactivate_success) ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_TRUE(std::isnan(controller_->reference_interfaces_[0])); ASSERT_TRUE(std::isnan(controller_->measured_state_values_[0])); - ASSERT_EQ(controller_->command_interfaces_[0].get_value(), 101.101); + ASSERT_EQ(controller_->command_interfaces_[0].get_optional().value(), 101.101); ASSERT_EQ(controller_->on_deactivate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_TRUE(std::isnan(controller_->reference_interfaces_[0])); ASSERT_TRUE(std::isnan(controller_->measured_state_values_[0])); - ASSERT_EQ(controller_->command_interfaces_[0].get_value(), 101.101); + ASSERT_EQ(controller_->command_interfaces_[0].get_optional().value(), 101.101); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_TRUE(std::isnan(controller_->reference_interfaces_[0])); ASSERT_TRUE(std::isnan(controller_->measured_state_values_[0])); - ASSERT_EQ(controller_->command_interfaces_[0].get_value(), 101.101); + ASSERT_EQ(controller_->command_interfaces_[0].get_optional().value(), 101.101); ASSERT_EQ( controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), @@ -319,7 +319,8 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_off) // -> cmd = p_term + i_term + d_term + feedforward_gain * ref = 30100.3 + 0 * 101.101 = 30102.3 const double expected_command_value = 30100.301000; - double actual_value = std::round(controller_->command_interfaces_[0].get_value() * 1e5) / 1e5; + double actual_value = + std::round(controller_->command_interfaces_[0].get_optional().value() * 1e5) / 1e5; EXPECT_NEAR(actual_value, expected_command_value, 1e-5); } @@ -379,7 +380,8 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward // -> cmd = p_term + i_term + d_term + feedforward_gain * ref = 30100.3 + 0 * 101.101 = 30102.3 const double expected_command_value = 30100.301000; - double actual_value = std::round(controller_->command_interfaces_[0].get_value() * 1e5) / 1e5; + double actual_value = + std::round(controller_->command_interfaces_[0].get_optional().value() * 1e5) / 1e5; EXPECT_NEAR(actual_value, expected_command_value, 1e-5); } } @@ -434,10 +436,9 @@ TEST_F(PidControllerTest, test_update_logic_chainable_not_use_subscriber_update) // i_term = zero at first update // d_term = error_dot * d_gain = 390.0 * 3.0 = 1170.0 // feedforward OFF -> cmd = p_term + i_term + d_term = 3.9 + 0.078 + 1170.0 = 1173.978 - { - const double expected_command_value = 1173.9; - EXPECT_EQ(controller_->command_interfaces_[0].get_value(), expected_command_value); - } + const double expected_command_value = 1173.9; + + EXPECT_EQ(controller_->command_interfaces_[0].get_optional().value(), expected_command_value); } /** @@ -470,7 +471,8 @@ TEST_F(PidControllerTest, test_update_logic_angle_wraparound_off) // d_term = error_dot * d_gain = 890.0 * 3.0 = 2670.0 // feedforward OFF -> cmd = p_term + i_term + d_term = 8.9 + 0.0 + 2670.0 = 2678.9 const double expected_command_value = 2678.9; - EXPECT_NEAR(controller_->command_interfaces_[0].get_value(), expected_command_value, 1e-5); + EXPECT_NEAR( + controller_->command_interfaces_[0].get_optional().value(), expected_command_value, 1e-5); } /** @@ -506,7 +508,8 @@ TEST_F(PidControllerTest, test_update_logic_angle_wraparound_on) // first update d_term = error_dot * d_gain = 261.6814 * 3.0 = 785.0444079 feedforward OFF -> cmd // = p_term + i_term + d_term = 2.616814, + 0.0 + 785.0444079 = 787.6612219 const double expected_command_value = 787.6612219; - EXPECT_NEAR(controller_->command_interfaces_[0].get_value(), expected_command_value, 1e-5); + EXPECT_NEAR( + controller_->command_interfaces_[0].get_optional().value(), expected_command_value, 1e-5); } TEST_F(PidControllerTest, subscribe_and_get_messages_success) @@ -644,7 +647,7 @@ TEST_F(PidControllerTest, test_update_chained_feedforward_with_gain) controller_interface::return_type::OK); // check on result from update - ASSERT_EQ(controller_->command_interfaces_[0].get_value(), expected_command_value); + ASSERT_EQ(controller_->command_interfaces_[0].get_optional().value(), expected_command_value); } /** @@ -702,7 +705,7 @@ TEST_F(PidControllerTest, test_update_chained_feedforward_off_with_gain) controller_interface::return_type::OK); // check on result from update - ASSERT_EQ(controller_->command_interfaces_[0].get_value(), expected_command_value); + ASSERT_EQ(controller_->command_interfaces_[0].get_optional().value(), expected_command_value); } /** @@ -738,7 +741,8 @@ TEST_F(PidControllerTest, test_save_i_term_off) // feedforward OFF -> cmd = p_term + i_term + d_term = 30100.301 const double expected_command_value = 30100.3010; - double actual_value = std::round(controller_->command_interfaces_[0].get_value() * 1e5) / 1e5; + double actual_value = + std::round(controller_->command_interfaces_[0].get_optional().value() * 1e5) / 1e5; EXPECT_NEAR(actual_value, expected_command_value, 1e-5); // deactivate the controller and set command=state @@ -751,7 +755,7 @@ TEST_F(PidControllerTest, test_save_i_term_off) ASSERT_EQ( controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::OK); - actual_value = std::round(controller_->command_interfaces_[0].get_value() * 1e5) / 1e5; + actual_value = std::round(controller_->command_interfaces_[0].get_optional().value() * 1e5) / 1e5; EXPECT_NEAR(actual_value, 0.0, 1e-5); } @@ -788,7 +792,8 @@ TEST_F(PidControllerTest, test_save_i_term_on) // feedforward OFF -> cmd = p_term + i_term + d_term = 30102.301 const double expected_command_value = 30100.3010; - double actual_value = std::round(controller_->command_interfaces_[0].get_value() * 1e5) / 1e5; + double actual_value = + std::round(controller_->command_interfaces_[0].get_optional().value() * 1e5) / 1e5; EXPECT_NEAR(actual_value, expected_command_value, 1e-5); // deactivate the controller and set command=state @@ -801,7 +806,7 @@ TEST_F(PidControllerTest, test_save_i_term_on) ASSERT_EQ( controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::OK); - actual_value = std::round(controller_->command_interfaces_[0].get_value() * 1e5) / 1e5; + actual_value = std::round(controller_->command_interfaces_[0].get_optional().value() * 1e5) / 1e5; EXPECT_NEAR(actual_value, 2.00002, 1e-5); // i_term from above } diff --git a/pid_controller/test/test_pid_controller_dual_interface.cpp b/pid_controller/test/test_pid_controller_dual_interface.cpp index e8847ecd2d..9099d11a75 100644 --- a/pid_controller/test/test_pid_controller_dual_interface.cpp +++ b/pid_controller/test/test_pid_controller_dual_interface.cpp @@ -95,8 +95,8 @@ TEST_F(PidControllerDualInterfaceTest, test_chained_feedforward_with_gain_dual_i // check the commands const double joint1_expected_cmd = 8.90; const double joint2_expected_cmd = 9.90; - ASSERT_EQ(controller_->command_interfaces_[0].get_value(), joint1_expected_cmd); - ASSERT_EQ(controller_->command_interfaces_[1].get_value(), joint2_expected_cmd); + ASSERT_EQ(controller_->command_interfaces_[0].get_optional().value(), joint1_expected_cmd); + ASSERT_EQ(controller_->command_interfaces_[1].get_optional().value(), joint2_expected_cmd); } int main(int argc, char ** argv) diff --git a/position_controllers/test/test_joint_group_position_controller.cpp b/position_controllers/test/test_joint_group_position_controller.cpp index ea7005c543..380450a6d1 100644 --- a/position_controllers/test/test_joint_group_position_controller.cpp +++ b/position_controllers/test/test_joint_group_position_controller.cpp @@ -106,9 +106,9 @@ TEST_F(JointGroupPositionControllerTest, CommandSuccessTest) controller_interface::return_type::OK); // check joint commands are still the default ones - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); // send command auto command_ptr = std::make_shared(); @@ -121,9 +121,9 @@ TEST_F(JointGroupPositionControllerTest, CommandSuccessTest) controller_interface::return_type::OK); // check joint commands have been modified - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 30.0); } TEST_F(JointGroupPositionControllerTest, WrongCommandCheckTest) @@ -143,9 +143,9 @@ TEST_F(JointGroupPositionControllerTest, WrongCommandCheckTest) controller_interface::return_type::ERROR); // check joint commands are still the default ones - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); } TEST_F(JointGroupPositionControllerTest, NoCommandCheckTest) @@ -160,9 +160,9 @@ TEST_F(JointGroupPositionControllerTest, NoCommandCheckTest) controller_interface::return_type::OK); // check joint commands are still the default ones - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); } TEST_F(JointGroupPositionControllerTest, CommandCallbackTest) @@ -171,9 +171,9 @@ TEST_F(JointGroupPositionControllerTest, CommandCallbackTest) controller_->get_node()->set_parameter({"joints", joint_names_}); // default values - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); auto node_state = controller_->configure(); ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE); @@ -204,7 +204,7 @@ TEST_F(JointGroupPositionControllerTest, CommandCallbackTest) controller_interface::return_type::OK); // check command in handle was set - ASSERT_EQ(joint_1_pos_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_2_pos_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_3_pos_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_pos_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_2_pos_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 30.0); } diff --git a/steering_controllers_library/src/steering_controllers_library.cpp b/steering_controllers_library/src/steering_controllers_library.cpp index f34b3a78e0..bbb779b60a 100644 --- a/steering_controllers_library/src/steering_controllers_library.cpp +++ b/steering_controllers_library/src/steering_controllers_library.cpp @@ -529,7 +529,14 @@ controller_interface::CallbackReturn SteeringControllersLibrary::on_deactivate( { for (size_t i = 0; i < nr_cmd_itfs_; ++i) { - command_interfaces_[i].set_value(std::numeric_limits::quiet_NaN()); + if (!command_interfaces_[i].set_value(std::numeric_limits::quiet_NaN())) + { + RCLCPP_WARN( + get_node()->get_logger(), + "Failed to set NaN value for command interface '%s' (index %zu) during deactivation.", + command_interfaces_[i].get_name().c_str(), i); + return controller_interface::CallbackReturn::SUCCESS; + } } return controller_interface::CallbackReturn::SUCCESS; } @@ -552,6 +559,7 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c const rclcpp::Time & time, const rclcpp::Duration & period) { update_odometry(period); + auto logger = get_node()->get_logger(); // MOVE ROBOT @@ -574,11 +582,23 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c for (size_t i = 0; i < params_.traction_joints_names.size(); i++) { - command_interfaces_[i].set_value(timeout ? 0.0 : traction_commands[i]); + const auto value = timeout ? 0.0 : traction_commands[i]; + + if (!command_interfaces_[i].set_value(value)) + { + RCLCPP_WARN(logger, "Unable to set traction command at index %zu: value = %f", i, value); + return controller_interface::return_type::OK; + } } for (size_t i = 0; i < params_.steering_joints_names.size(); i++) { - command_interfaces_[i + params_.traction_joints_names.size()].set_value(steering_commands[i]); + const auto & value = steering_commands[i]; + + if (!command_interfaces_[i + params_.traction_joints_names.size()].set_value(value)) + { + RCLCPP_WARN(logger, "Unable to set steering command at index %zu: value = %f", i, value); + return controller_interface::return_type::OK; + } } } @@ -628,24 +648,66 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c { if (params_.position_feedback) { - controller_state_publisher_->msg_.traction_wheels_position.push_back( - state_interfaces_[i].get_value()); + auto position_state_interface_op = state_interfaces_[i].get_optional(); + if (!position_state_interface_op.has_value()) + { + RCLCPP_DEBUG( + logger, "Unable to retrieve position feedback data for traction wheel %zu", i); + } + else + { + controller_state_publisher_->msg_.traction_wheels_position.push_back( + position_state_interface_op.value()); + } + } + else + { + auto velocity_state_interface_op = state_interfaces_[i].get_optional(); + if (!velocity_state_interface_op.has_value()) + { + RCLCPP_DEBUG( + logger, "Unable to retrieve velocity feedback data for traction wheel %zu", i); + } + else + { + controller_state_publisher_->msg_.traction_wheels_velocity.push_back( + velocity_state_interface_op.value()); + } + } + + auto velocity_command_interface_op = command_interfaces_[i].get_optional(); + if (!velocity_command_interface_op.has_value()) + { + RCLCPP_DEBUG(logger, "Unable to retrieve velocity command for traction wheel %zu", i); } else { - controller_state_publisher_->msg_.traction_wheels_velocity.push_back( - state_interfaces_[i].get_value()); + controller_state_publisher_->msg_.linear_velocity_command.push_back( + velocity_command_interface_op.value()); } - controller_state_publisher_->msg_.linear_velocity_command.push_back( - command_interfaces_[i].get_value()); } for (size_t i = 0; i < number_of_steering_wheels; ++i) { - controller_state_publisher_->msg_.steer_positions.push_back( - state_interfaces_[number_of_traction_wheels + i].get_value()); - controller_state_publisher_->msg_.steering_angle_command.push_back( - command_interfaces_[number_of_traction_wheels + i].get_value()); + const auto state_interface_value_op = + state_interfaces_[number_of_traction_wheels + i].get_optional(); + const auto command_interface_value_op = + command_interfaces_[number_of_traction_wheels + i].get_optional(); + if (!state_interface_value_op.has_value() || !command_interface_value_op.has_value()) + { + RCLCPP_DEBUG( + logger, "Unable to retrieve %s for steering wheel %zu", + !state_interface_value_op.has_value() ? "state interface value" + : "command interface value", + i); + } + else + { + controller_state_publisher_->msg_.steer_positions.push_back( + state_interface_value_op.value()); + controller_state_publisher_->msg_.steering_angle_command.push_back( + command_interface_value_op.value()); + } } controller_state_publisher_->unlockAndPublish(); diff --git a/steering_controllers_library/test/test_steering_controllers_library.cpp b/steering_controllers_library/test/test_steering_controllers_library.cpp index 26750777c9..b661b85671 100644 --- a/steering_controllers_library/test/test_steering_controllers_library.cpp +++ b/steering_controllers_library/test/test_steering_controllers_library.cpp @@ -146,12 +146,12 @@ TEST_F(SteeringControllersLibraryTest, test_both_update_methods_for_ref_timeout) } // Wheel velocities should reset to 0 - EXPECT_EQ(controller_->command_interfaces_[0].get_value(), 0); - EXPECT_EQ(controller_->command_interfaces_[1].get_value(), 0); + EXPECT_EQ(controller_->command_interfaces_[0].get_optional().value(), 0); + EXPECT_EQ(controller_->command_interfaces_[1].get_optional().value(), 0); // Steer angles should not reset - EXPECT_NEAR(controller_->command_interfaces_[2].get_value(), 0.575875, 1e-6); - EXPECT_NEAR(controller_->command_interfaces_[3].get_value(), 0.575875, 1e-6); + EXPECT_NEAR(controller_->command_interfaces_[2].get_optional().value(), 0.575875, 1e-6); + EXPECT_NEAR(controller_->command_interfaces_[3].get_optional().value(), 0.575875, 1e-6); // case 2 position_feedback = true controller_->params_.position_feedback = true; @@ -190,12 +190,12 @@ TEST_F(SteeringControllersLibraryTest, test_both_update_methods_for_ref_timeout) } // Wheel velocities should reset to 0 - EXPECT_EQ(controller_->command_interfaces_[0].get_value(), 0); - EXPECT_EQ(controller_->command_interfaces_[1].get_value(), 0); + EXPECT_EQ(controller_->command_interfaces_[0].get_optional().value(), 0); + EXPECT_EQ(controller_->command_interfaces_[1].get_optional().value(), 0); // Steer angles should not reset - EXPECT_NEAR(controller_->command_interfaces_[2].get_value(), 0.575875, 1e-6); - EXPECT_NEAR(controller_->command_interfaces_[3].get_value(), 0.575875, 1e-6); + EXPECT_NEAR(controller_->command_interfaces_[2].get_optional().value(), 0.575875, 1e-6); + EXPECT_NEAR(controller_->command_interfaces_[3].get_optional().value(), 0.575875, 1e-6); } int main(int argc, char ** argv) diff --git a/tricycle_controller/src/tricycle_controller.cpp b/tricycle_controller/src/tricycle_controller.cpp index 6d32b8265a..d0a9bd684e 100644 --- a/tricycle_controller/src/tricycle_controller.cpp +++ b/tricycle_controller/src/tricycle_controller.cpp @@ -110,8 +110,19 @@ controller_interface::return_type TricycleController::update( TwistStamped command = *last_command_msg_; double & linear_command = command.twist.linear.x; double & angular_command = command.twist.angular.z; - double Ws_read = traction_joint_[0].velocity_state.get().get_value(); // in radians/s - double alpha_read = steering_joint_[0].position_state.get().get_value(); // in radians + auto Ws_read_op = traction_joint_[0].velocity_state.get().get_optional(); + auto alpha_read_op = steering_joint_[0].position_state.get().get_optional(); + + if (!Ws_read_op.has_value() || !alpha_read_op.has_value()) + { + RCLCPP_WARN( + get_node()->get_logger(), + "Unable to retrieve the data of traction joint velocity or steering joint position"); + return controller_interface::return_type::OK; + } + + double Ws_read = Ws_read_op.value(); // in radians/s + double alpha_read = alpha_read_op.value(); // in radians if (params_.open_loop) { @@ -211,8 +222,18 @@ controller_interface::return_type TricycleController::update( realtime_ackermann_command_publisher_->unlockAndPublish(); } - traction_joint_[0].velocity_command.get().set_value(Ws_write); - steering_joint_[0].position_command.get().set_value(alpha_write); + if (!traction_joint_[0].velocity_command.get().set_value(Ws_write)) + { + RCLCPP_WARN( + get_node()->get_logger(), + "Unable to set the velocity command for traction joint to value: '%f'.", Ws_write); + } + if (!steering_joint_[0].position_command.get().set_value(alpha_write)) + { + RCLCPP_WARN( + get_node()->get_logger(), + "Unable to set the position command for steering joint to value: '%f'.", alpha_write); + } return controller_interface::return_type::OK; } @@ -433,8 +454,18 @@ bool TricycleController::reset() void TricycleController::halt() { - traction_joint_[0].velocity_command.get().set_value(0.0); - steering_joint_[0].position_command.get().set_value(0.0); + if (!traction_joint_[0].velocity_command.get().set_value(0.0)) + { + RCLCPP_WARN( + get_node()->get_logger(), + "Unable to set the velocity command for traction joint to value 0.0"); + } + if (!steering_joint_[0].position_command.get().set_value(0.0)) + { + RCLCPP_WARN( + get_node()->get_logger(), + "Unable to set the position command for steering joint to value 0.0"); + } } CallbackReturn TricycleController::get_traction( diff --git a/tricycle_controller/test/test_tricycle_controller.cpp b/tricycle_controller/test/test_tricycle_controller.cpp index cdc97b0518..a933ef1fa8 100644 --- a/tricycle_controller/test/test_tricycle_controller.cpp +++ b/tricycle_controller/test/test_tricycle_controller.cpp @@ -285,15 +285,15 @@ TEST_F(TestTricycleController, cleanup) ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); // should be stopped - EXPECT_EQ(0.0, steering_joint_pos_cmd_.get_value()); - EXPECT_EQ(0.0, traction_joint_vel_cmd_.get_value()); + EXPECT_EQ(0.0, steering_joint_pos_cmd_.get_optional().value()); + EXPECT_EQ(0.0, traction_joint_vel_cmd_.get_optional().value()); state = controller_->get_node()->cleanup(); ASSERT_EQ(State::PRIMARY_STATE_UNCONFIGURED, state.id()); // should be stopped - EXPECT_EQ(0.0, steering_joint_pos_cmd_.get_value()); - EXPECT_EQ(0.0, traction_joint_vel_cmd_.get_value()); + EXPECT_EQ(0.0, steering_joint_pos_cmd_.get_optional().value()); + EXPECT_EQ(0.0, traction_joint_vel_cmd_.get_optional().value()); executor.cancel(); } @@ -313,8 +313,8 @@ TEST_F(TestTricycleController, correct_initialization_using_parameters) assignResources(); ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); - EXPECT_EQ(position_, steering_joint_pos_cmd_.get_value()); - EXPECT_EQ(velocity_, traction_joint_vel_cmd_.get_value()); + EXPECT_EQ(position_, steering_joint_pos_cmd_.get_optional().value()); + EXPECT_EQ(velocity_, traction_joint_vel_cmd_.get_optional().value()); state = controller_->get_node()->activate(); ASSERT_EQ(State::PRIMARY_STATE_ACTIVE, state.id()); @@ -329,8 +329,8 @@ TEST_F(TestTricycleController, correct_initialization_using_parameters) ASSERT_EQ( controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::OK); - EXPECT_EQ(0.0, steering_joint_pos_cmd_.get_value()); - EXPECT_EQ(1.0, traction_joint_vel_cmd_.get_value()); + EXPECT_EQ(0.0, steering_joint_pos_cmd_.get_optional().value()); + EXPECT_EQ(1.0, traction_joint_vel_cmd_.get_optional().value()); // deactivated // wait so controller process the second point when deactivated @@ -341,14 +341,16 @@ TEST_F(TestTricycleController, correct_initialization_using_parameters) state = controller_->get_node()->deactivate(); ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); - EXPECT_EQ(0.0, steering_joint_pos_cmd_.get_value()) << "Wheels are halted on deactivate()"; - EXPECT_EQ(0.0, traction_joint_vel_cmd_.get_value()) << "Wheels are halted on deactivate()"; + EXPECT_EQ(0.0, steering_joint_pos_cmd_.get_optional().value()) + << "Wheels are halted on deactivate()"; + EXPECT_EQ(0.0, traction_joint_vel_cmd_.get_optional().value()) + << "Wheels are halted on deactivate()"; // cleanup state = controller_->get_node()->cleanup(); ASSERT_EQ(State::PRIMARY_STATE_UNCONFIGURED, state.id()); - EXPECT_EQ(0.0, steering_joint_pos_cmd_.get_value()); - EXPECT_EQ(0.0, traction_joint_vel_cmd_.get_value()); + EXPECT_EQ(0.0, steering_joint_pos_cmd_.get_optional().value()); + EXPECT_EQ(0.0, traction_joint_vel_cmd_.get_optional().value()); state = controller_->configure(); ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); diff --git a/tricycle_steering_controller/src/tricycle_steering_controller.cpp b/tricycle_steering_controller/src/tricycle_steering_controller.cpp index 2c919cbfd8..c626301284 100644 --- a/tricycle_steering_controller/src/tricycle_steering_controller.cpp +++ b/tricycle_steering_controller/src/tricycle_steering_controller.cpp @@ -86,11 +86,24 @@ bool TricycleSteeringController::update_odometry(const rclcpp::Duration & period } else { - const double traction_right_wheel_value = - state_interfaces_[STATE_TRACTION_RIGHT_WHEEL].get_value(); - const double traction_left_wheel_value = - state_interfaces_[STATE_TRACTION_LEFT_WHEEL].get_value(); - const double steering_position = state_interfaces_[STATE_STEER_AXIS].get_value(); + const auto traction_right_wheel_value_op = + state_interfaces_[STATE_TRACTION_RIGHT_WHEEL].get_optional(); + const auto traction_left_wheel_value_op = + state_interfaces_[STATE_TRACTION_LEFT_WHEEL].get_optional(); + const auto steering_position_op = state_interfaces_[STATE_STEER_AXIS].get_optional(); + + if ( + !traction_right_wheel_value_op.has_value() || !traction_left_wheel_value_op.has_value() || + !steering_position_op.has_value()) + { + RCLCPP_WARN( + get_node()->get_logger(), + "Unable to retrieve the data from right wheel or left wheel or steering position"); + return true; + } + const double traction_right_wheel_value = traction_right_wheel_value_op.value(); + const double traction_left_wheel_value = traction_left_wheel_value_op.value(); + const double steering_position = steering_position_op.value(); if ( std::isfinite(traction_right_wheel_value) && std::isfinite(traction_left_wheel_value) && std::isfinite(steering_position)) diff --git a/tricycle_steering_controller/test/test_tricycle_steering_controller.cpp b/tricycle_steering_controller/test/test_tricycle_steering_controller.cpp index 4f9b53e31f..f0d2f6d2db 100644 --- a/tricycle_steering_controller/test/test_tricycle_steering_controller.cpp +++ b/tricycle_steering_controller/test/test_tricycle_steering_controller.cpp @@ -133,9 +133,9 @@ TEST_F(TricycleSteeringControllerTest, reactivate_success) ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_deactivate(rclcpp_lifecycle::State()), NODE_SUCCESS); - ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_value())); + ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_optional().value())); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); - ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_value())); + ASSERT_TRUE(std::isnan(controller_->command_interfaces_[0].get_optional().value())); ASSERT_EQ( controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), @@ -165,13 +165,13 @@ TEST_F(TricycleSteeringControllerTest, test_update_logic) controller_interface::return_type::OK); EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_RIGHT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_RIGHT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_LEFT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_LEFT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_STEER_WHEEL].get_value(), 1.4179821977774734, + controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); @@ -202,13 +202,13 @@ TEST_F(TricycleSteeringControllerTest, test_update_logic_chained) // we test with open_loop=false, but steering angle was not updated (is zero) -> same commands EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_RIGHT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_RIGHT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_LEFT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_LEFT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_STEER_WHEEL].get_value(), 1.4179821977774734, + controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); @@ -248,13 +248,13 @@ TEST_F(TricycleSteeringControllerTest, receive_message_and_publish_updated_statu // we test with open_loop=false, but steering angle was not updated (is zero) -> same commands EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_RIGHT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_RIGHT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_TRACTION_LEFT_WHEEL].get_value(), 0.22222222222222224, - COMMON_THRESHOLD); + controller_->command_interfaces_[CMD_TRACTION_LEFT_WHEEL].get_optional().value(), + 0.22222222222222224, COMMON_THRESHOLD); EXPECT_NEAR( - controller_->command_interfaces_[CMD_STEER_WHEEL].get_value(), 1.4179821977774734, + controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); subscribe_and_get_messages(msg); diff --git a/velocity_controllers/src/joint_group_velocity_controller.cpp b/velocity_controllers/src/joint_group_velocity_controller.cpp index 97f6713d72..b2d0086254 100644 --- a/velocity_controllers/src/joint_group_velocity_controller.cpp +++ b/velocity_controllers/src/joint_group_velocity_controller.cpp @@ -59,7 +59,11 @@ controller_interface::CallbackReturn JointGroupVelocityController::on_deactivate // stop all joints for (auto & command_interface : command_interfaces_) { - command_interface.set_value(0.0); + if (!command_interface.set_value(0.0)) + { + RCLCPP_WARN(get_node()->get_logger(), "Unable to set the command interface to value 0.0"); + return controller_interface::CallbackReturn::SUCCESS; + } } return ret; diff --git a/velocity_controllers/test/test_joint_group_velocity_controller.cpp b/velocity_controllers/test/test_joint_group_velocity_controller.cpp index 9a9af3fb81..880f664141 100644 --- a/velocity_controllers/test/test_joint_group_velocity_controller.cpp +++ b/velocity_controllers/test/test_joint_group_velocity_controller.cpp @@ -106,9 +106,9 @@ TEST_F(JointGroupVelocityControllerTest, CommandSuccessTest) controller_interface::return_type::OK); // check joint commands are still the default ones - ASSERT_EQ(joint_1_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); // send command auto command_ptr = std::make_shared(); @@ -121,9 +121,9 @@ TEST_F(JointGroupVelocityControllerTest, CommandSuccessTest) controller_interface::return_type::OK); // check joint commands have been modified - ASSERT_EQ(joint_1_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_2_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_3_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 30.0); } TEST_F(JointGroupVelocityControllerTest, WrongCommandCheckTest) @@ -143,9 +143,9 @@ TEST_F(JointGroupVelocityControllerTest, WrongCommandCheckTest) controller_interface::return_type::ERROR); // check joint commands are still the default ones - ASSERT_EQ(joint_1_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); } TEST_F(JointGroupVelocityControllerTest, NoCommandCheckTest) @@ -160,9 +160,9 @@ TEST_F(JointGroupVelocityControllerTest, NoCommandCheckTest) controller_interface::return_type::OK); // check joint commands are still the default ones - ASSERT_EQ(joint_1_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); } TEST_F(JointGroupVelocityControllerTest, CommandCallbackTest) @@ -171,9 +171,9 @@ TEST_F(JointGroupVelocityControllerTest, CommandCallbackTest) controller_->get_node()->set_parameter({"joints", joint_names_}); // default values - ASSERT_EQ(joint_1_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); auto node_state = controller_->configure(); ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE); @@ -204,9 +204,9 @@ TEST_F(JointGroupVelocityControllerTest, CommandCallbackTest) controller_interface::return_type::OK); // check command in handle was set - ASSERT_EQ(joint_1_cmd_.get_value(), 10.0); - ASSERT_EQ(joint_2_cmd_.get_value(), 20.0); - ASSERT_EQ(joint_3_cmd_.get_value(), 30.0); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 10.0); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 20.0); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 30.0); } TEST_F(JointGroupVelocityControllerTest, StopJointsOnDeactivateTest) @@ -218,15 +218,15 @@ TEST_F(JointGroupVelocityControllerTest, StopJointsOnDeactivateTest) ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); // check joint commands are still the default ones - ASSERT_EQ(joint_1_cmd_.get_value(), 1.1); - ASSERT_EQ(joint_2_cmd_.get_value(), 2.1); - ASSERT_EQ(joint_3_cmd_.get_value(), 3.1); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 1.1); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 2.1); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); // stop the controller ASSERT_EQ(controller_->on_deactivate(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); // check joint commands are now zero - ASSERT_EQ(joint_1_cmd_.get_value(), 0.0); - ASSERT_EQ(joint_2_cmd_.get_value(), 0.0); - ASSERT_EQ(joint_3_cmd_.get_value(), 0.0); + ASSERT_EQ(joint_1_cmd_.get_optional().value(), 0.0); + ASSERT_EQ(joint_2_cmd_.get_optional().value(), 0.0); + ASSERT_EQ(joint_3_cmd_.get_optional().value(), 0.0); } From d34b72e8b6d6efa6cecdc8eb15b134894b2ee361 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 12:42:40 +0200 Subject: [PATCH 088/108] mecanum_drive_controller: Declare missing backward_ros dependency (backport #1941) (#1943) --- mecanum_drive_controller/package.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index 782d4c9164..eff8d70a60 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -25,6 +25,7 @@ generate_parameter_library ros2_control_cmake + backward_ros control_msgs controller_interface geometry_msgs From ee41ccdc45675def1dd53292ffde67ad6f5f491a Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 17:55:26 +0200 Subject: [PATCH 089/108] Update realtime containers (backport #1721) (#1935) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christoph Fröhlich --- .../test_ackermann_steering_controller.cpp | 33 ++-- .../admittance_controller.hpp | 15 +- .../src/admittance_controller.cpp | 57 ++++-- .../test/test_bicycle_steering_controller.cpp | 31 +-- .../diff_drive_controller.hpp | 7 +- .../src/diff_drive_controller.cpp | 39 ++-- .../test/test_diff_drive_controller.cpp | 4 - .../test_joint_group_effort_controller.cpp | 12 +- .../forward_controllers_base.hpp | 8 +- .../src/forward_controllers_base.cpp | 55 ++++-- .../test/test_forward_command_controller.cpp | 58 +++--- ...i_interface_forward_command_controller.cpp | 58 +++--- .../gpio_command_controller.hpp | 8 +- .../src/gpio_command_controller.cpp | 44 +++-- .../test/test_gpio_command_controller.cpp | 14 +- .../mecanum_drive_controller.hpp | 13 +- .../mecanum_drive_controller/odometry.hpp | 7 +- .../src/mecanum_drive_controller.cpp | 76 ++++---- .../test/test_mecanum_drive_controller.cpp | 173 +++++++++-------- .../parallel_gripper_action_controller.hpp | 20 +- ...arallel_gripper_action_controller_impl.hpp | 35 ++-- .../include/pid_controller/pid_controller.hpp | 9 +- pid_controller/src/pid_controller.cpp | 75 +++++--- pid_controller/test/test_pid_controller.cpp | 26 +-- pid_controller/test/test_pid_controller.hpp | 16 +- .../test_joint_group_position_controller.cpp | 12 +- .../steering_controllers_library.hpp | 11 +- .../src/steering_controllers_library.cpp | 95 ++++++---- .../test_steering_controllers_library.cpp | 177 +++++++++++++----- .../test_steering_controllers_library.hpp | 3 +- .../test_tricycle_steering_controller.cpp | 33 ++-- .../test_joint_group_velocity_controller.cpp | 12 +- 32 files changed, 740 insertions(+), 496 deletions(-) diff --git a/ackermann_steering_controller/test/test_ackermann_steering_controller.cpp b/ackermann_steering_controller/test/test_ackermann_steering_controller.cpp index da69fbf042..c151af1ecc 100644 --- a/ackermann_steering_controller/test/test_ackermann_steering_controller.cpp +++ b/ackermann_steering_controller/test/test_ackermann_steering_controller.cpp @@ -103,13 +103,13 @@ TEST_F(AckermannSteeringControllerTest, activate_success) ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); // check that the message is reset - auto msg = controller_->input_ref_.readFromNonRT(); - EXPECT_TRUE(std::isnan((*msg)->twist.linear.x)); - EXPECT_TRUE(std::isnan((*msg)->twist.linear.y)); - EXPECT_TRUE(std::isnan((*msg)->twist.linear.z)); - EXPECT_TRUE(std::isnan((*msg)->twist.angular.x)); - EXPECT_TRUE(std::isnan((*msg)->twist.angular.y)); - EXPECT_TRUE(std::isnan((*msg)->twist.angular.z)); + auto msg = controller_->input_ref_.get(); + EXPECT_TRUE(std::isnan(msg.twist.linear.x)); + EXPECT_TRUE(std::isnan(msg.twist.linear.y)); + EXPECT_TRUE(std::isnan(msg.twist.linear.z)); + EXPECT_TRUE(std::isnan(msg.twist.angular.x)); + EXPECT_TRUE(std::isnan(msg.twist.angular.y)); + EXPECT_TRUE(std::isnan(msg.twist.angular.z)); } TEST_F(AckermannSteeringControllerTest, update_success) @@ -161,11 +161,11 @@ TEST_F(AckermannSteeringControllerTest, test_update_logic) ASSERT_FALSE(controller_->is_in_chained_mode()); // set command statically - std::shared_ptr msg = std::make_shared(); - msg->header.stamp = controller_->get_node()->now(); - msg->twist.linear.x = 0.1; - msg->twist.angular.z = 0.2; - controller_->input_ref_.writeFromNonRT(msg); + ControllerReferenceMsg msg; + msg.header.stamp = controller_->get_node()->now(); + msg.twist.linear.x = 0.1; + msg.twist.angular.z = 0.2; + controller_->input_ref_.set(msg); ASSERT_EQ( controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), @@ -185,7 +185,7 @@ TEST_F(AckermannSteeringControllerTest, test_update_logic) controller_->command_interfaces_[CMD_STEER_LEFT_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); + EXPECT_FALSE(std::isnan(controller_->input_ref_.get().twist.linear.x)); EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size()); for (const auto & interface : controller_->reference_interfaces_) { @@ -225,7 +225,7 @@ TEST_F(AckermannSteeringControllerTest, test_update_logic_chained) controller_->command_interfaces_[STATE_STEER_LEFT_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); - EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); + EXPECT_TRUE(std::isnan(controller_->input_ref_.get().twist.linear.x)); EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size()); for (const auto & interface : controller_->reference_interfaces_) { @@ -249,8 +249,9 @@ TEST_F(AckermannSteeringControllerTest, receive_message_and_publish_updated_stat ControllerStateMsg msg; subscribe_and_get_messages(msg); - EXPECT_EQ(msg.linear_velocity_command[STATE_TRACTION_RIGHT_WHEEL], 1.1); - EXPECT_EQ(msg.linear_velocity_command[STATE_TRACTION_LEFT_WHEEL], 3.3); + // never received a valid command, linear velocity should have been reset + EXPECT_EQ(msg.linear_velocity_command[STATE_TRACTION_RIGHT_WHEEL], 0.0); + EXPECT_EQ(msg.linear_velocity_command[STATE_TRACTION_LEFT_WHEEL], 0.0); EXPECT_EQ(msg.steering_angle_command[0], 2.2); EXPECT_EQ(msg.steering_angle_command[1], 4.4); diff --git a/admittance_controller/include/admittance_controller/admittance_controller.hpp b/admittance_controller/include/admittance_controller/admittance_controller.hpp index 23aad881c6..47c9fd514a 100644 --- a/admittance_controller/include/admittance_controller/admittance_controller.hpp +++ b/admittance_controller/include/admittance_controller/admittance_controller.hpp @@ -31,8 +31,8 @@ #include "rclcpp/duration.hpp" #include "rclcpp/time.hpp" #include "rclcpp_lifecycle/state.hpp" -#include "realtime_tools/realtime_buffer.hpp" #include "realtime_tools/realtime_publisher.hpp" +#include "realtime_tools/realtime_thread_safe_box.hpp" #include "semantic_components/force_torque_sensor.hpp" namespace admittance_controller @@ -125,15 +125,16 @@ class AdmittanceController : public controller_interface::ChainableControllerInt // admittance parameters std::shared_ptr parameter_handler_; - // ROS messages - std::shared_ptr joint_command_msg_; - - // real-time buffer - realtime_tools::RealtimeBuffer> + // real-time boxes + realtime_tools::RealtimeThreadSafeBox input_joint_command_; - realtime_tools::RealtimeBuffer input_wrench_command_; + realtime_tools::RealtimeThreadSafeBox input_wrench_command_; std::unique_ptr> state_publisher_; + // save the last commands in case of unable to get value from box + trajectory_msgs::msg::JointTrajectoryPoint joint_command_msg_; + geometry_msgs::msg::WrenchStamped wrench_command_msg_; + trajectory_msgs::msg::JointTrajectoryPoint last_commanded_; trajectory_msgs::msg::JointTrajectoryPoint last_reference_; diff --git a/admittance_controller/src/admittance_controller.cpp b/admittance_controller/src/admittance_controller.cpp index db6a91700d..d3e1037d22 100644 --- a/admittance_controller/src/admittance_controller.cpp +++ b/admittance_controller/src/admittance_controller.cpp @@ -25,6 +25,27 @@ #include "geometry_msgs/msg/wrench.hpp" #include "trajectory_msgs/msg/joint_trajectory_point.hpp" +namespace +{ // utility + +// called from RT control loop +void reset_controller_reference_msg(trajectory_msgs::msg::JointTrajectoryPoint & msg) +{ + msg.positions.clear(); + msg.velocities.clear(); +} + +// called from RT control loop +void reset_wrench_msg( + geometry_msgs::msg::WrenchStamped & msg, + const std::shared_ptr & node) +{ + msg.header.stamp = node->now(); + msg.wrench = geometry_msgs::msg::Wrench(); +} + +} // namespace + namespace admittance_controller { @@ -133,7 +154,6 @@ AdmittanceController::on_export_reference_interfaces() reference_interfaces_.resize(num_chainable_interfaces, std::numeric_limits::quiet_NaN()); position_reference_ = {}; velocity_reference_ = {}; - input_wrench_command_.reset(); // assign reference interfaces auto index = 0ul; @@ -286,7 +306,7 @@ controller_interface::CallbackReturn AdmittanceController::on_configure( // setup subscribers and publishers auto joint_command_callback = [this](const std::shared_ptr msg) - { input_joint_command_.writeFromNonRT(msg); }; + { input_joint_command_.set(*msg); }; input_joint_command_subscriber_ = get_node()->create_subscription( "~/joint_references", rclcpp::SystemDefaultsQoS(), joint_command_callback); @@ -307,8 +327,9 @@ controller_interface::CallbackReturn AdmittanceController::on_configure( msg.header.frame_id.c_str(), admittance_->parameters_.ft_sensor.frame.id.c_str()); return; } - input_wrench_command_.writeFromNonRT(msg); + input_wrench_command_.set(msg); }); + s_publisher_ = get_node()->create_publisher( "~/status", rclcpp::SystemDefaultsQoS()); state_publisher_ = @@ -390,6 +411,8 @@ controller_interface::CallbackReturn AdmittanceController::on_activate( return controller_interface::CallbackReturn::ERROR; } } + reset_controller_reference_msg(joint_command_msg_); + reset_wrench_msg(wrench_command_msg_, get_node()); // Use current joint_state as a default reference last_reference_ = joint_state_; @@ -408,26 +431,29 @@ controller_interface::return_type AdmittanceController::update_reference_from_su { return controller_interface::return_type::ERROR; } - - joint_command_msg_ = *input_joint_command_.readFromRT(); + auto joint_command_msg_op = input_joint_command_.try_get(); + if (joint_command_msg_op.has_value()) + { + joint_command_msg_ = joint_command_msg_op.value(); + } // if message exists, load values into references - if (joint_command_msg_.get()) + if (!joint_command_msg_.positions.empty() || !joint_command_msg_.velocities.empty()) { for (const auto & interface : admittance_->parameters_.chainable_command_interfaces) { if (interface == hardware_interface::HW_IF_POSITION) { - for (size_t i = 0; i < joint_command_msg_->positions.size(); ++i) + for (size_t i = 0; i < joint_command_msg_.positions.size(); ++i) { - position_reference_[i].get() = joint_command_msg_->positions[i]; + position_reference_[i].get() = joint_command_msg_.positions[i]; } } else if (interface == hardware_interface::HW_IF_VELOCITY) { - for (size_t i = 0; i < joint_command_msg_->velocities.size(); ++i) + for (size_t i = 0; i < joint_command_msg_.velocities.size(); ++i) { - velocity_reference_[i].get() = joint_command_msg_->velocities[i]; + velocity_reference_[i].get() = joint_command_msg_.velocities[i]; } } } @@ -451,7 +477,13 @@ controller_interface::return_type AdmittanceController::update_and_write_command // get all controller inputs read_state_from_hardware(joint_state_, ft_values_); - auto offsetted_ft_values = add_wrenches(ft_values_, input_wrench_command_.readFromRT()->wrench); + auto wrench_command_op = input_wrench_command_.try_get(); + if (wrench_command_op.has_value()) + { + wrench_command_msg_ = wrench_command_op.value(); + } + + auto offsetted_ft_values = add_wrenches(ft_values_, wrench_command_msg_.wrench); // apply admittance control to reference to determine desired state admittance_->update(joint_state_, offsetted_ft_values, reference_, period, reference_admittance_); @@ -498,6 +530,9 @@ controller_interface::CallbackReturn AdmittanceController::on_deactivate( release_interfaces(); admittance_->reset(num_joints_); + reset_controller_reference_msg(joint_command_msg_); + reset_wrench_msg(wrench_command_msg_, get_node()); + return CallbackReturn::SUCCESS; } diff --git a/bicycle_steering_controller/test/test_bicycle_steering_controller.cpp b/bicycle_steering_controller/test/test_bicycle_steering_controller.cpp index 7036dd4102..9708ac6d7b 100644 --- a/bicycle_steering_controller/test/test_bicycle_steering_controller.cpp +++ b/bicycle_steering_controller/test/test_bicycle_steering_controller.cpp @@ -89,13 +89,13 @@ TEST_F(BicycleSteeringControllerTest, activate_success) ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); // check that the message is reset - auto msg = controller_->input_ref_.readFromNonRT(); - EXPECT_TRUE(std::isnan((*msg)->twist.linear.x)); - EXPECT_TRUE(std::isnan((*msg)->twist.linear.y)); - EXPECT_TRUE(std::isnan((*msg)->twist.linear.z)); - EXPECT_TRUE(std::isnan((*msg)->twist.angular.x)); - EXPECT_TRUE(std::isnan((*msg)->twist.angular.y)); - EXPECT_TRUE(std::isnan((*msg)->twist.angular.z)); + auto msg = controller_->input_ref_.get(); + EXPECT_TRUE(std::isnan(msg.twist.linear.x)); + EXPECT_TRUE(std::isnan(msg.twist.linear.y)); + EXPECT_TRUE(std::isnan(msg.twist.linear.z)); + EXPECT_TRUE(std::isnan(msg.twist.angular.x)); + EXPECT_TRUE(std::isnan(msg.twist.angular.y)); + EXPECT_TRUE(std::isnan(msg.twist.angular.z)); } TEST_F(BicycleSteeringControllerTest, update_success) @@ -147,11 +147,11 @@ TEST_F(BicycleSteeringControllerTest, test_update_logic) ASSERT_FALSE(controller_->is_in_chained_mode()); // set command statically - std::shared_ptr msg = std::make_shared(); - msg->header.stamp = controller_->get_node()->now(); - msg->twist.linear.x = 0.1; - msg->twist.angular.z = 0.2; - controller_->input_ref_.writeFromNonRT(msg); + ControllerReferenceMsg msg; + msg.header.stamp = controller_->get_node()->now(); + msg.twist.linear.x = 0.1; + msg.twist.angular.z = 0.2; + controller_->input_ref_.set(msg); ASSERT_EQ( controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), @@ -164,7 +164,7 @@ TEST_F(BicycleSteeringControllerTest, test_update_logic) controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); + EXPECT_FALSE(std::isnan(controller_->input_ref_.get().twist.linear.x)); EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size()); for (const auto & interface : controller_->reference_interfaces_) { @@ -197,7 +197,7 @@ TEST_F(BicycleSteeringControllerTest, test_update_logic_chained) controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); - EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); + EXPECT_TRUE(std::isnan(controller_->input_ref_.get().twist.linear.x)); EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size()); for (const auto & interface : controller_->reference_interfaces_) { @@ -236,7 +236,8 @@ TEST_F(BicycleSteeringControllerTest, receive_message_and_publish_updated_status ControllerStateMsg msg; subscribe_and_get_messages(msg); - EXPECT_EQ(msg.linear_velocity_command[0], 1.1); + // never received a valid command, linear velocity should have been reset + EXPECT_EQ(msg.linear_velocity_command[0], 0.0); EXPECT_EQ(msg.steering_angle_command[0], 2.2); publish_commands(0.1, 0.2); diff --git a/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp b/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp index c736c0032a..0ca1d023ec 100644 --- a/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp +++ b/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp @@ -32,8 +32,8 @@ #include "nav_msgs/msg/odometry.hpp" #include "odometry.hpp" #include "rclcpp_lifecycle/state.hpp" -#include "realtime_tools/realtime_buffer.hpp" #include "realtime_tools/realtime_publisher.hpp" +#include "realtime_tools/realtime_thread_safe_box.hpp" #include "tf2_msgs/msg/tf_message.hpp" // auto-generated by generate_parameter_library @@ -122,7 +122,10 @@ class DiffDriveController : public controller_interface::ChainableControllerInte bool subscriber_is_active_ = false; rclcpp::Subscription::SharedPtr velocity_command_subscriber_ = nullptr; - realtime_tools::RealtimeBuffer> received_velocity_msg_ptr_{nullptr}; + // the realtime container to exchange the reference from subscriber + realtime_tools::RealtimeThreadSafeBox received_velocity_msg_; + // save the last reference in case of unable to get value from box + TwistStamped command_msg_; std::queue> previous_two_commands_; // speed limiters diff --git a/diff_drive_controller/src/diff_drive_controller.cpp b/diff_drive_controller/src/diff_drive_controller.cpp index 3dc5b1d035..1c808a7be2 100644 --- a/diff_drive_controller/src/diff_drive_controller.cpp +++ b/diff_drive_controller/src/diff_drive_controller.cpp @@ -107,15 +107,13 @@ controller_interface::return_type DiffDriveController::update_reference_from_sub { auto logger = get_node()->get_logger(); - const std::shared_ptr command_msg_ptr = *(received_velocity_msg_ptr_.readFromRT()); - - if (command_msg_ptr == nullptr) + auto current_ref_op = received_velocity_msg_.try_get(); + if (current_ref_op.has_value()) { - RCLCPP_WARN(logger, "Velocity message received was a nullptr."); - return controller_interface::return_type::ERROR; + command_msg_ = current_ref_op.value(); } - const auto age_of_last_command = time - command_msg_ptr->header.stamp; + const auto age_of_last_command = time - command_msg_.header.stamp; // Brake if cmd_vel has timeout, override the stored command if (age_of_last_command > cmd_vel_timeout_) { @@ -123,11 +121,10 @@ controller_interface::return_type DiffDriveController::update_reference_from_sub reference_interfaces_[1] = 0.0; } else if ( - std::isfinite(command_msg_ptr->twist.linear.x) && - std::isfinite(command_msg_ptr->twist.angular.z)) + std::isfinite(command_msg_.twist.linear.x) && std::isfinite(command_msg_.twist.angular.z)) { - reference_interfaces_[0] = command_msg_ptr->twist.linear.x; - reference_interfaces_[1] = command_msg_ptr->twist.angular.z; + reference_interfaces_[0] = command_msg_.twist.linear.x; + reference_interfaces_[1] = command_msg_.twist.angular.z; } else { @@ -458,7 +455,7 @@ controller_interface::CallbackReturn DiffDriveController::on_configure( cmd_vel_timeout_ == rclcpp::Duration::from_seconds(0.0) || current_time_diff < cmd_vel_timeout_) { - received_velocity_msg_ptr_.writeFromNonRT(msg); + received_velocity_msg_.set(*msg); } else { @@ -629,18 +626,16 @@ void DiffDriveController::reset_buffers() previous_two_commands_.push({{0.0, 0.0}}); previous_two_commands_.push({{0.0, 0.0}}); - // Fill RealtimeBuffer with NaNs so it will contain a known value + // Fill RealtimeBox with NaNs so it will contain a known value // but still indicate that no command has yet been sent. - received_velocity_msg_ptr_.reset(); - std::shared_ptr empty_msg_ptr = std::make_shared(); - empty_msg_ptr->header.stamp = get_node()->now(); - empty_msg_ptr->twist.linear.x = std::numeric_limits::quiet_NaN(); - empty_msg_ptr->twist.linear.y = std::numeric_limits::quiet_NaN(); - empty_msg_ptr->twist.linear.z = std::numeric_limits::quiet_NaN(); - empty_msg_ptr->twist.angular.x = std::numeric_limits::quiet_NaN(); - empty_msg_ptr->twist.angular.y = std::numeric_limits::quiet_NaN(); - empty_msg_ptr->twist.angular.z = std::numeric_limits::quiet_NaN(); - received_velocity_msg_ptr_.writeFromNonRT(empty_msg_ptr); + command_msg_.header.stamp = get_node()->now(); + command_msg_.twist.linear.x = std::numeric_limits::quiet_NaN(); + command_msg_.twist.linear.y = std::numeric_limits::quiet_NaN(); + command_msg_.twist.linear.z = std::numeric_limits::quiet_NaN(); + command_msg_.twist.angular.x = std::numeric_limits::quiet_NaN(); + command_msg_.twist.angular.y = std::numeric_limits::quiet_NaN(); + command_msg_.twist.angular.z = std::numeric_limits::quiet_NaN(); + received_velocity_msg_.set(command_msg_); } void DiffDriveController::halt() diff --git a/diff_drive_controller/test/test_diff_drive_controller.cpp b/diff_drive_controller/test/test_diff_drive_controller.cpp index 860140993a..8b442875c7 100644 --- a/diff_drive_controller/test/test_diff_drive_controller.cpp +++ b/diff_drive_controller/test/test_diff_drive_controller.cpp @@ -45,10 +45,6 @@ class TestableDiffDriveController : public diff_drive_controller::DiffDriveContr { public: using DiffDriveController::DiffDriveController; - std::shared_ptr getLastReceivedTwist() - { - return *(received_velocity_msg_ptr_.readFromNonRT()); - } /** * @brief wait_for_twist block until a new twist is received. diff --git a/effort_controllers/test/test_joint_group_effort_controller.cpp b/effort_controllers/test/test_joint_group_effort_controller.cpp index e88dfe63a6..5fa4394250 100644 --- a/effort_controllers/test/test_joint_group_effort_controller.cpp +++ b/effort_controllers/test/test_joint_group_effort_controller.cpp @@ -111,9 +111,9 @@ TEST_F(JointGroupEffortControllerTest, CommandSuccessTest) ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); // send command - auto command_ptr = std::make_shared(); - command_ptr->data = {10.0, 20.0, 30.0}; - controller_->rt_command_ptr_.writeFromNonRT(command_ptr); + forward_command_controller::CmdType command; + command.data = {10.0, 20.0, 30.0}; + controller_->rt_command_.set(command); // update successful, command received ASSERT_EQ( @@ -133,9 +133,9 @@ TEST_F(JointGroupEffortControllerTest, WrongCommandCheckTest) ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); // send command with wrong number of joints - auto command_ptr = std::make_shared(); - command_ptr->data = {10.0, 20.0}; - controller_->rt_command_ptr_.writeFromNonRT(command_ptr); + forward_command_controller::CmdType command; + command.data = {10.0, 20.0}; + controller_->rt_command_.set(command); // update failed, command size does not match number of joints ASSERT_EQ( diff --git a/forward_command_controller/include/forward_command_controller/forward_controllers_base.hpp b/forward_command_controller/include/forward_command_controller/forward_controllers_base.hpp index c8b620d593..9f03042cdf 100644 --- a/forward_command_controller/include/forward_command_controller/forward_controllers_base.hpp +++ b/forward_command_controller/include/forward_command_controller/forward_controllers_base.hpp @@ -22,7 +22,7 @@ #include "controller_interface/controller_interface.hpp" #include "rclcpp/subscription.hpp" #include "rclcpp_lifecycle/state.hpp" -#include "realtime_tools/realtime_buffer.hpp" +#include "realtime_tools/realtime_thread_safe_box.hpp" #include "std_msgs/msg/float64_multi_array.hpp" namespace forward_command_controller @@ -86,7 +86,11 @@ class ForwardControllersBase : public controller_interface::ControllerInterface std::vector command_interface_types_; - realtime_tools::RealtimeBuffer> rt_command_ptr_; + // the realtime container to exchange the reference from subscriber + realtime_tools::RealtimeThreadSafeBox rt_command_; + // save the last reference in case of unable to get value from box + CmdType joint_commands_; + rclcpp::Subscription::SharedPtr joints_command_subscriber_; }; diff --git a/forward_command_controller/src/forward_controllers_base.cpp b/forward_command_controller/src/forward_controllers_base.cpp index e8ccb3c6ca..b83e22a298 100644 --- a/forward_command_controller/src/forward_controllers_base.cpp +++ b/forward_command_controller/src/forward_controllers_base.cpp @@ -14,6 +14,8 @@ #include "forward_command_controller/forward_controllers_base.hpp" +#include +#include #include #include #include @@ -23,12 +25,24 @@ #include "rclcpp/logging.hpp" #include "rclcpp/qos.hpp" +namespace +{ // utility + +// called from RT control loop +void reset_controller_reference_msg(forward_command_controller::CmdType & msg) +{ + for (auto & data : msg.data) + { + data = std::numeric_limits::quiet_NaN(); + } +} + +} // namespace + namespace forward_command_controller { ForwardControllersBase::ForwardControllersBase() -: controller_interface::ControllerInterface(), - rt_command_ptr_(nullptr), - joints_command_subscriber_(nullptr) +: controller_interface::ControllerInterface(), joints_command_subscriber_(nullptr) { } @@ -71,7 +85,7 @@ controller_interface::CallbackReturn ForwardControllersBase::on_configure( "Non-finite value received. Dropping message"); return; } - rt_command_ptr_.writeFromNonRT(msg); + rt_command_.set(*msg); }); RCLCPP_INFO(get_node()->get_logger(), "configure successful"); @@ -115,7 +129,10 @@ controller_interface::CallbackReturn ForwardControllersBase::on_activate( } // reset command buffer if a command came through callback when controller was inactive - rt_command_ptr_ = realtime_tools::RealtimeBuffer>(nullptr); + // Try to set default value in command. + // If this fails, then another command will be received soon anyways. + reset_controller_reference_msg(joint_commands_); + rt_command_.try_set(joint_commands_); RCLCPP_INFO(get_node()->get_logger(), "activate successful"); return controller_interface::CallbackReturn::SUCCESS; @@ -124,40 +141,46 @@ controller_interface::CallbackReturn ForwardControllersBase::on_activate( controller_interface::CallbackReturn ForwardControllersBase::on_deactivate( const rclcpp_lifecycle::State & /*previous_state*/) { - // reset command buffer - rt_command_ptr_ = realtime_tools::RealtimeBuffer>(nullptr); + // Try to set default value in command. + reset_controller_reference_msg(joint_commands_); + rt_command_.try_set(joint_commands_); + return controller_interface::CallbackReturn::SUCCESS; } controller_interface::return_type ForwardControllersBase::update( const rclcpp::Time & /*time*/, const rclcpp::Duration & /*period*/) { - auto joint_commands = rt_command_ptr_.readFromRT(); + auto joint_commands_op = rt_command_.try_get(); + if (joint_commands_op.has_value()) + { + joint_commands_ = joint_commands_op.value(); + } // no command received yet - if (!joint_commands || !(*joint_commands)) + if (std::all_of( + joint_commands_.data.cbegin(), joint_commands_.data.cend(), + [](const auto & value) { return std::isnan(value); })) { return controller_interface::return_type::OK; } - if ((*joint_commands)->data.size() != command_interfaces_.size()) + if (joint_commands_.data.size() != command_interfaces_.size()) { RCLCPP_ERROR_THROTTLE( get_node()->get_logger(), *(get_node()->get_clock()), 1000, - "command size (%zu) does not match number of interfaces (%zu)", - (*joint_commands)->data.size(), command_interfaces_.size()); + "command size (%zu) does not match number of interfaces (%zu)", joint_commands_.data.size(), + command_interfaces_.size()); return controller_interface::return_type::ERROR; } for (auto index = 0ul; index < command_interfaces_.size(); ++index) { - const auto & value = (*joint_commands)->data[index]; - - if (!command_interfaces_[index].set_value(value)) + if (!command_interfaces_[index].set_value(joint_commands_.data[index])) { RCLCPP_WARN( get_node()->get_logger(), "Unable to set the command interface value %s: value = %f", - command_interfaces_[index].get_name().c_str(), value); + command_interfaces_[index].get_name().c_str(), joint_commands_.data[index]); return controller_interface::return_type::OK; } } diff --git a/forward_command_controller/test/test_forward_command_controller.cpp b/forward_command_controller/test/test_forward_command_controller.cpp index 07f4e64e3a..50f2f7cf20 100644 --- a/forward_command_controller/test/test_forward_command_controller.cpp +++ b/forward_command_controller/test/test_forward_command_controller.cpp @@ -218,9 +218,9 @@ TEST_F(ForwardCommandControllerTest, CommandSuccessTest) ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); // send command - auto command_ptr = std::make_shared(); - command_ptr->data = {10.0, 20.0, 30.0}; - controller_->rt_command_ptr_.writeFromNonRT(command_ptr); + forward_command_controller::CmdType command_msg; + command_msg.data = {10.0, 20.0, 30.0}; + controller_->rt_command_.set(command_msg); // update successful, command received ASSERT_EQ( @@ -246,9 +246,9 @@ TEST_F(ForwardCommandControllerTest, WrongCommandCheckTest) controller_interface::CallbackReturn::SUCCESS); // send command with wrong number of joints - auto command_ptr = std::make_shared(); - command_ptr->data = {10.0, 20.0}; - controller_->rt_command_ptr_.writeFromNonRT(command_ptr); + forward_command_controller::CmdType command_msg; + command_msg.data = {10.0, 20.0}; + controller_->rt_command_.set(command_msg); // update failed, command size does not match number of joints ASSERT_EQ( @@ -409,10 +409,10 @@ TEST_F(ForwardCommandControllerTest, ActivateDeactivateCommandsResetSuccess) ASSERT_THAT(state_if_conf.names, IsEmpty()); EXPECT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::NONE); - auto command_msg = std::make_shared(); - command_msg->data = {10.0, 20.0, 30.0}; - - controller_->rt_command_ptr_.writeFromNonRT(command_msg); + // send command + forward_command_controller::CmdType command; + command.data = {10.0, 20.0, 30.0}; + controller_->rt_command_.set(command); // update successful ASSERT_EQ( @@ -436,35 +436,31 @@ TEST_F(ForwardCommandControllerTest, ActivateDeactivateCommandsResetSuccess) EXPECT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::NONE); // command ptr should be reset (nullptr) after deactivation - same check as in `update` - ASSERT_FALSE( - controller_->rt_command_ptr_.readFromNonRT() && - *(controller_->rt_command_ptr_.readFromNonRT())); - ASSERT_FALSE( - controller_->rt_command_ptr_.readFromRT() && *(controller_->rt_command_ptr_.readFromRT())); + auto cmd = controller_->rt_command_.get(); + ASSERT_THAT( + cmd.data, + ::testing::Each(::testing::NanSensitiveDoubleEq(std::numeric_limits::quiet_NaN()))); // Controller is inactive but let's put some data into buffer (simulate callback when inactive) - command_msg = std::make_shared(); - command_msg->data = {5.5, 6.6, 7.7}; - - controller_->rt_command_ptr_.writeFromNonRT(command_msg); + command.data = {5.5, 6.6, 7.7}; + controller_->rt_command_.set(command); // command ptr should be available and message should be there - same check as in `update` - ASSERT_TRUE( - controller_->rt_command_ptr_.readFromNonRT() && - *(controller_->rt_command_ptr_.readFromNonRT())); - ASSERT_TRUE( - controller_->rt_command_ptr_.readFromRT() && *(controller_->rt_command_ptr_.readFromRT())); + cmd = controller_->rt_command_.get(); + ASSERT_THAT( + cmd.data, + ::testing::Each( + ::testing::Not(::testing::NanSensitiveDoubleEq(std::numeric_limits::quiet_NaN())))); // Now activate again node_state = controller_->get_node()->activate(); ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE); - // command ptr should be reset (nullptr) after activation - same check as in `update` - ASSERT_FALSE( - controller_->rt_command_ptr_.readFromNonRT() && - *(controller_->rt_command_ptr_.readFromNonRT())); - ASSERT_FALSE( - controller_->rt_command_ptr_.readFromRT() && *(controller_->rt_command_ptr_.readFromRT())); + // command ptr should be reset after activation - same check as in `update` + cmd = controller_->rt_command_.get(); + ASSERT_THAT( + cmd.data, + ::testing::Each(::testing::NanSensitiveDoubleEq(std::numeric_limits::quiet_NaN()))); // update successful ASSERT_EQ( @@ -477,7 +473,7 @@ TEST_F(ForwardCommandControllerTest, ActivateDeactivateCommandsResetSuccess) ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 30); // set commands again - controller_->rt_command_ptr_.writeFromNonRT(command_msg); + controller_->rt_command_.set(command); // update successful ASSERT_EQ( diff --git a/forward_command_controller/test/test_multi_interface_forward_command_controller.cpp b/forward_command_controller/test/test_multi_interface_forward_command_controller.cpp index 2be11101a9..814d7b6218 100644 --- a/forward_command_controller/test/test_multi_interface_forward_command_controller.cpp +++ b/forward_command_controller/test/test_multi_interface_forward_command_controller.cpp @@ -15,6 +15,7 @@ /// \authors: Jack Center, Denis Stogl #include +#include #include #include #include @@ -199,9 +200,9 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, CommandSuccessTest) SetUpController(true); // send command - auto command_ptr = std::make_shared(); - command_ptr->data = {10.0, 20.0, 30.0}; - controller_->rt_command_ptr_.writeFromNonRT(command_ptr); + forward_command_controller::CmdType command; + command.data = {10.0, 20.0, 30.0}; + controller_->rt_command_.set(command); // update successful, command received ASSERT_EQ( @@ -234,9 +235,9 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, WrongCommandCheckTest) SetUpController(true); // send command with wrong number of joints - auto command_ptr = std::make_shared(); - command_ptr->data = {10.0, 20.0}; - controller_->rt_command_ptr_.writeFromNonRT(command_ptr); + forward_command_controller::CmdType command; + command.data = {10.0, 20.0}; + controller_->rt_command_.set(command); // update failed, command size does not match number of joints ASSERT_EQ( @@ -294,9 +295,9 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, ActivateDeactivateCommandsRes EXPECT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::NONE); // send command - auto command_ptr = std::make_shared(); - command_ptr->data = {10.0, 20.0, 30.0}; - controller_->rt_command_ptr_.writeFromNonRT(command_ptr); + forward_command_controller::CmdType command; + command.data = {10.0, 20.0, 30.0}; + controller_->rt_command_.set(command); // update successful, command received ASSERT_EQ( @@ -319,35 +320,32 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, ActivateDeactivateCommandsRes ASSERT_THAT(state_if_conf.names, IsEmpty()); EXPECT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::NONE); - // command ptr should be reset (nullptr) after deactivation - same check as in `update` - ASSERT_FALSE( - controller_->rt_command_ptr_.readFromNonRT() && - *(controller_->rt_command_ptr_.readFromNonRT())); - ASSERT_FALSE( - controller_->rt_command_ptr_.readFromRT() && *(controller_->rt_command_ptr_.readFromRT())); + // command ptr should be reset after deactivation - same check as in `update` + auto cmd = controller_->rt_command_.get(); + ASSERT_THAT( + cmd.data, + ::testing::Each(::testing::NanSensitiveDoubleEq(std::numeric_limits::quiet_NaN()))); // Controller is inactive but let's put some data into buffer (simulate callback when inactive) - auto command_msg = std::make_shared(); - command_msg->data = {5.5, 6.6, 7.7}; - controller_->rt_command_ptr_.writeFromNonRT(command_msg); + command.data = {5.5, 6.6, 7.7}; + controller_->rt_command_.set(command); // command ptr should be available and message should be there - same check as in `update` - ASSERT_TRUE( - controller_->rt_command_ptr_.readFromNonRT() && - *(controller_->rt_command_ptr_.readFromNonRT())); - ASSERT_TRUE( - controller_->rt_command_ptr_.readFromRT() && *(controller_->rt_command_ptr_.readFromRT())); + cmd = controller_->rt_command_.get(); + ASSERT_THAT( + cmd.data, + ::testing::Each( + ::testing::Not(::testing::NanSensitiveDoubleEq(std::numeric_limits::quiet_NaN())))); // Now activate again node_state = controller_->get_node()->activate(); ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE); - // command ptr should be reset (nullptr) after activation - same check as in `update` - ASSERT_FALSE( - controller_->rt_command_ptr_.readFromNonRT() && - *(controller_->rt_command_ptr_.readFromNonRT())); - ASSERT_FALSE( - controller_->rt_command_ptr_.readFromRT() && *(controller_->rt_command_ptr_.readFromRT())); + // command ptr should be reset after activation - same check as in `update` + cmd = controller_->rt_command_.get(); + ASSERT_THAT( + cmd.data, + ::testing::Each(::testing::NanSensitiveDoubleEq(std::numeric_limits::quiet_NaN()))); // update successful ASSERT_EQ( @@ -360,7 +358,7 @@ TEST_F(MultiInterfaceForwardCommandControllerTest, ActivateDeactivateCommandsRes ASSERT_EQ(joint_1_eff_cmd_.get_optional().value(), 30.0); // set commands again - controller_->rt_command_ptr_.writeFromNonRT(command_msg); + controller_->rt_command_.set(command); // update successful ASSERT_EQ( diff --git a/gpio_controllers/include/gpio_controllers/gpio_command_controller.hpp b/gpio_controllers/include/gpio_controllers/gpio_command_controller.hpp index 35cf7c283d..f7d75e1c20 100644 --- a/gpio_controllers/include/gpio_controllers/gpio_command_controller.hpp +++ b/gpio_controllers/include/gpio_controllers/gpio_command_controller.hpp @@ -24,8 +24,8 @@ #include "controller_interface/controller_interface.hpp" #include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp" #include "rclcpp_lifecycle/state.hpp" -#include "realtime_tools/realtime_buffer.hpp" #include "realtime_tools/realtime_publisher.hpp" +#include "realtime_tools/realtime_thread_safe_box.hpp" #include "gpio_controllers/gpio_command_controller_parameters.hpp" @@ -91,9 +91,13 @@ class GpioCommandController : public controller_interface::ControllerInterface MapOfReferencesToCommandInterfaces command_interfaces_map_; MapOfReferencesToStateInterfaces state_interfaces_map_; - realtime_tools::RealtimeBuffer> rt_command_ptr_{}; rclcpp::Subscription::SharedPtr gpios_command_subscriber_{}; + // the realtime container to exchange the reference from subscriber + realtime_tools::RealtimeThreadSafeBox rt_command_; + // save the last reference in case of unable to get value from box + CmdType gpio_commands_; + std::shared_ptr> gpio_state_publisher_{}; std::shared_ptr> realtime_gpio_state_publisher_{}; diff --git a/gpio_controllers/src/gpio_command_controller.cpp b/gpio_controllers/src/gpio_command_controller.cpp index 4250114e1f..34222928c3 100644 --- a/gpio_controllers/src/gpio_command_controller.cpp +++ b/gpio_controllers/src/gpio_command_controller.cpp @@ -23,7 +23,7 @@ #include "rclcpp/subscription.hpp" namespace -{ +{ // utility template void print_interface(const rclcpp::Logger & logger, const T & command_interfaces) { @@ -33,6 +33,15 @@ void print_interface(const rclcpp::Logger & logger, const T & command_interfaces } } +// called from RT control loop +void reset_controller_reference_msg( + gpio_controllers::CmdType & msg, const std::shared_ptr & node) +{ + msg.header.stamp = node->now(); + msg.interface_groups.clear(); + msg.interface_values.clear(); +} + std::vector extract_gpios_from_hardware_info( const std::vector & hardware_infos) { @@ -85,7 +94,7 @@ try { gpios_command_subscriber_ = get_node()->create_subscription( "~/commands", rclcpp::SystemDefaultsQoS(), - [this](const CmdType::SharedPtr msg) { rt_command_ptr_.writeFromNonRT(msg); }); + [this](const CmdType::SharedPtr msg) { rt_command_.set(*msg); }); } gpio_state_publisher_ = @@ -137,14 +146,18 @@ CallbackReturn GpioCommandController::on_activate(const rclcpp_lifecycle::State } initialize_gpio_state_msg(); - rt_command_ptr_.reset(); + // Set default value in command + reset_controller_reference_msg(gpio_commands_, get_node()); + rt_command_.try_set(gpio_commands_); RCLCPP_INFO(get_node()->get_logger(), "activate successful"); return CallbackReturn::SUCCESS; } CallbackReturn GpioCommandController::on_deactivate(const rclcpp_lifecycle::State &) { - rt_command_ptr_.reset(); + // Set default value in command + reset_controller_reference_msg(gpio_commands_, get_node()); + rt_command_.try_set(gpio_commands_); return CallbackReturn::SUCCESS; } @@ -315,19 +328,24 @@ bool GpioCommandController::check_if_configured_interfaces_matches_received( controller_interface::return_type GpioCommandController::update_gpios_commands() { - auto gpio_commands_ptr = rt_command_ptr_.readFromRT(); - if (!gpio_commands_ptr || !(*gpio_commands_ptr)) + auto gpio_commands_op = rt_command_.try_get(); + if (gpio_commands_op.has_value()) { + gpio_commands_ = gpio_commands_op.value(); + } + if (gpio_commands_.interface_groups.empty() || gpio_commands_.interface_values.empty()) + { + // no command received yet return controller_interface::return_type::OK; } - const auto gpio_commands = *(*gpio_commands_ptr); - for (std::size_t gpio_index = 0; gpio_index < gpio_commands.interface_groups.size(); ++gpio_index) + for (std::size_t gpio_index = 0; gpio_index < gpio_commands_.interface_groups.size(); + ++gpio_index) { - const auto & gpio_name = gpio_commands.interface_groups[gpio_index]; + const auto & gpio_name = gpio_commands_.interface_groups[gpio_index]; if ( - gpio_commands.interface_values[gpio_index].values.size() != - gpio_commands.interface_values[gpio_index].interface_names.size()) + gpio_commands_.interface_values[gpio_index].values.size() != + gpio_commands_.interface_values[gpio_index].interface_names.size()) { RCLCPP_ERROR( get_node()->get_logger(), "For gpio %s interfaces_names do not match values", @@ -335,10 +353,10 @@ controller_interface::return_type GpioCommandController::update_gpios_commands() return controller_interface::return_type::ERROR; } for (std::size_t command_interface_index = 0; - command_interface_index < gpio_commands.interface_values[gpio_index].values.size(); + command_interface_index < gpio_commands_.interface_values[gpio_index].values.size(); ++command_interface_index) { - apply_command(gpio_commands, gpio_index, command_interface_index); + apply_command(gpio_commands_, gpio_index, command_interface_index); } } return controller_interface::return_type::OK; diff --git a/gpio_controllers/test/test_gpio_command_controller.cpp b/gpio_controllers/test/test_gpio_command_controller.cpp index e8f720de3b..9bf26e91d9 100644 --- a/gpio_controllers/test/test_gpio_command_controller.cpp +++ b/gpio_controllers/test/test_gpio_command_controller.cpp @@ -445,7 +445,7 @@ TEST_F( const auto command = createGpioCommand( {"gpio1", "gpio2"}, {createInterfaceValue({"dig.1", "dig.2"}, {0.0, 1.0, 1.0}), createInterfaceValue({"ana.1"}, {30.0})}); - controller_->rt_command_ptr_.writeFromNonRT(std::make_shared(command)); + controller_->rt_command_.set(command); ASSERT_EQ( controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::ERROR); @@ -467,7 +467,7 @@ TEST_F( const auto command = createGpioCommand( {"gpio1", "gpio2"}, {createInterfaceValue({"dig.1", "dig.2"}, {0.0}), createInterfaceValue({"ana.1"}, {30.0})}); - controller_->rt_command_ptr_.writeFromNonRT(std::make_shared(command)); + controller_->rt_command_.set(command); ASSERT_EQ( controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::ERROR); @@ -489,7 +489,7 @@ TEST_F( const auto command = createGpioCommand( {"gpio1", "gpio2"}, {createInterfaceValue({"dig.1", "dig.2"}, {0.0, 1.0}), createInterfaceValue({"ana.1"}, {30.0})}); - controller_->rt_command_ptr_.writeFromNonRT(std::make_shared(command)); + controller_->rt_command_.set(command); update_controller_loop(); ASSERT_EQ(gpio_1_1_dig_cmd.get_optional().value(), 0.0); @@ -513,7 +513,7 @@ TEST_F( const auto command = createGpioCommand( {"gpio2", "gpio1"}, {createInterfaceValue({"ana.1"}, {30.0}), createInterfaceValue({"dig.2", "dig.1"}, {1.0, 0.0})}); - controller_->rt_command_ptr_.writeFromNonRT(std::make_shared(command)); + controller_->rt_command_.set(command); update_controller_loop(); ASSERT_EQ(gpio_1_1_dig_cmd.get_optional().value(), 0.0); @@ -536,8 +536,7 @@ TEST_F( const auto command = createGpioCommand({"gpio1"}, {createInterfaceValue({"dig.1", "dig.2"}, {0.0, 1.0})}); - - controller_->rt_command_ptr_.writeFromNonRT(std::make_shared(command)); + controller_->rt_command_.set(command); update_controller_loop(); ASSERT_EQ(gpio_1_1_dig_cmd.get_optional().value(), 0.0); @@ -561,8 +560,7 @@ TEST_F( const auto command = createGpioCommand( {"gpio1", "gpio3"}, {createInterfaceValue({"dig.3", "dig.4"}, {20.0, 25.0}), createInterfaceValue({"ana.1"}, {21.0})}); - - controller_->rt_command_ptr_.writeFromNonRT(std::make_shared(command)); + controller_->rt_command_.set(command); update_controller_loop(); ASSERT_EQ(gpio_1_1_dig_cmd.get_optional().value(), gpio_commands.at(0)); diff --git a/mecanum_drive_controller/include/mecanum_drive_controller/mecanum_drive_controller.hpp b/mecanum_drive_controller/include/mecanum_drive_controller/mecanum_drive_controller.hpp index 189805c17c..c0edc8c5a2 100644 --- a/mecanum_drive_controller/include/mecanum_drive_controller/mecanum_drive_controller.hpp +++ b/mecanum_drive_controller/include/mecanum_drive_controller/mecanum_drive_controller.hpp @@ -29,8 +29,8 @@ #include "nav_msgs/msg/odometry.hpp" #include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp" #include "rclcpp_lifecycle/state.hpp" -#include "realtime_tools/realtime_buffer.hpp" #include "realtime_tools/realtime_publisher.hpp" +#include "realtime_tools/realtime_thread_safe_box.hpp" #include "std_srvs/srv/set_bool.hpp" #include "tf2_msgs/msg/tf_message.hpp" @@ -109,14 +109,15 @@ class MecanumDriveController : public controller_interface::ChainableControllerI */ std::vector state_joint_names_; - // Names of the references, ex: high level vel commands from MoveIt, Nav2, etc. - // used for preceding controller - std::vector reference_names_; + // the RT Box containing the command message + realtime_tools::RealtimeThreadSafeBox input_ref_; + // save the last reference in case of unable to get value from box + ControllerReferenceMsg current_ref_; + // the reference timeout value from parameters + rclcpp::Duration ref_timeout_ = rclcpp::Duration::from_seconds(0.0); // Command subscribers and Controller State, odom state, tf state publishers rclcpp::Subscription::SharedPtr ref_subscriber_ = nullptr; - realtime_tools::RealtimeBuffer> input_ref_; - rclcpp::Duration ref_timeout_ = rclcpp::Duration::from_seconds(0.0); using OdomStatePublisher = realtime_tools::RealtimePublisher; rclcpp::Publisher::SharedPtr odom_s_publisher_; diff --git a/mecanum_drive_controller/include/mecanum_drive_controller/odometry.hpp b/mecanum_drive_controller/include/mecanum_drive_controller/odometry.hpp index 79a1b54846..823764ccfe 100644 --- a/mecanum_drive_controller/include/mecanum_drive_controller/odometry.hpp +++ b/mecanum_drive_controller/include/mecanum_drive_controller/odometry.hpp @@ -15,9 +15,10 @@ #ifndef MECANUM_DRIVE_CONTROLLER__ODOMETRY_HPP_ #define MECANUM_DRIVE_CONTROLLER__ODOMETRY_HPP_ -#include "geometry_msgs/msg/twist.hpp" -#include "realtime_tools/realtime_buffer.hpp" -#include "realtime_tools/realtime_publisher.hpp" +#include +#include + +#include "rclcpp/time.hpp" #define PLANAR_POINT_DIM 3 diff --git a/mecanum_drive_controller/src/mecanum_drive_controller.cpp b/mecanum_drive_controller/src/mecanum_drive_controller.cpp index acb3b5a5cf..c320b258be 100644 --- a/mecanum_drive_controller/src/mecanum_drive_controller.cpp +++ b/mecanum_drive_controller/src/mecanum_drive_controller.cpp @@ -33,16 +33,15 @@ using ControllerReferenceMsg = // called from RT control loop void reset_controller_reference_msg( - const std::shared_ptr & msg, - const std::shared_ptr & node) + ControllerReferenceMsg & msg, const std::shared_ptr & node) { - msg->header.stamp = node->now(); - msg->twist.linear.x = std::numeric_limits::quiet_NaN(); - msg->twist.linear.y = std::numeric_limits::quiet_NaN(); - msg->twist.linear.z = std::numeric_limits::quiet_NaN(); - msg->twist.angular.x = std::numeric_limits::quiet_NaN(); - msg->twist.angular.y = std::numeric_limits::quiet_NaN(); - msg->twist.angular.z = std::numeric_limits::quiet_NaN(); + msg.header.stamp = node->now(); + msg.twist.linear.x = std::numeric_limits::quiet_NaN(); + msg.twist.linear.y = std::numeric_limits::quiet_NaN(); + msg.twist.linear.z = std::numeric_limits::quiet_NaN(); + msg.twist.angular.x = std::numeric_limits::quiet_NaN(); + msg.twist.angular.y = std::numeric_limits::quiet_NaN(); + msg.twist.angular.z = std::numeric_limits::quiet_NaN(); } } // namespace @@ -129,9 +128,8 @@ controller_interface::CallbackReturn MecanumDriveController::on_configure( "~/reference", subscribers_qos, std::bind(&MecanumDriveController::reference_callback, this, std::placeholders::_1)); - std::shared_ptr msg = std::make_shared(); - reset_controller_reference_msg(msg, get_node()); - input_ref_.writeFromNonRT(msg); + reset_controller_reference_msg(current_ref_, get_node()); + input_ref_.set(current_ref_); try { @@ -253,7 +251,7 @@ void MecanumDriveController::reference_callback(const std::shared_ptrheader.stamp).seconds(), age_of_last_command.seconds(), ref_timeout_.seconds()); - reset_controller_reference_msg(msg, get_node()); + ControllerReferenceMsg emtpy_msg; + reset_controller_reference_msg(emtpy_msg, get_node()); + input_ref_.set(emtpy_msg); } } @@ -325,8 +325,11 @@ bool MecanumDriveController::on_set_chained_mode(bool /*chained_mode*/) { return controller_interface::CallbackReturn MecanumDriveController::on_activate( const rclcpp_lifecycle::State & /*previous_state*/) { - // Set default value in command - reset_controller_reference_msg(*(input_ref_.readFromRT()), get_node()); + // Try to set default value in command. + // If this fails, then another command will be received soon anyways. + ControllerReferenceMsg emtpy_msg; + reset_controller_reference_msg(emtpy_msg, get_node()); + input_ref_.try_set(emtpy_msg); return controller_interface::CallbackReturn::SUCCESS; } @@ -355,41 +358,50 @@ controller_interface::CallbackReturn MecanumDriveController::on_deactivate( controller_interface::return_type MecanumDriveController::update_reference_from_subscribers( const rclcpp::Time & time, const rclcpp::Duration & /*period*/) { - auto current_ref = *(input_ref_.readFromRT()); - const auto age_of_last_command = time - (current_ref)->header.stamp; + auto current_ref_op = input_ref_.try_get(); + if (current_ref_op.has_value()) + { + current_ref_ = current_ref_op.value(); + } + + const auto age_of_last_command = time - current_ref_.header.stamp; - // send message only if there is no timeout + // accept message only if there is no timeout if (age_of_last_command <= ref_timeout_ || ref_timeout_ == rclcpp::Duration::from_seconds(0)) { if ( - !std::isnan(current_ref->twist.linear.x) && !std::isnan(current_ref->twist.linear.y) && - !std::isnan(current_ref->twist.angular.z)) + !std::isnan(current_ref_.twist.linear.x) && !std::isnan(current_ref_.twist.linear.y) && + !std::isnan(current_ref_.twist.angular.z)) { - reference_interfaces_[0] = current_ref->twist.linear.x; - reference_interfaces_[1] = current_ref->twist.linear.y; - reference_interfaces_[2] = current_ref->twist.angular.z; + reference_interfaces_[0] = current_ref_.twist.linear.x; + reference_interfaces_[1] = current_ref_.twist.linear.y; + reference_interfaces_[2] = current_ref_.twist.angular.z; if (ref_timeout_ == rclcpp::Duration::from_seconds(0)) { - current_ref->twist.linear.x = std::numeric_limits::quiet_NaN(); - current_ref->twist.linear.y = std::numeric_limits::quiet_NaN(); - current_ref->twist.angular.z = std::numeric_limits::quiet_NaN(); + current_ref_.twist.linear.x = std::numeric_limits::quiet_NaN(); + current_ref_.twist.linear.y = std::numeric_limits::quiet_NaN(); + current_ref_.twist.angular.z = std::numeric_limits::quiet_NaN(); + + input_ref_.try_set(current_ref_); } } } else { if ( - !std::isnan(current_ref->twist.linear.x) && !std::isnan(current_ref->twist.linear.y) && - !std::isnan(current_ref->twist.angular.z)) + !std::isnan(current_ref_.twist.linear.x) && !std::isnan(current_ref_.twist.linear.y) && + !std::isnan(current_ref_.twist.angular.z)) { reference_interfaces_[0] = 0.0; reference_interfaces_[1] = 0.0; reference_interfaces_[2] = 0.0; - current_ref->twist.linear.x = std::numeric_limits::quiet_NaN(); - current_ref->twist.linear.y = std::numeric_limits::quiet_NaN(); - current_ref->twist.angular.z = std::numeric_limits::quiet_NaN(); + current_ref_.twist.linear.x = std::numeric_limits::quiet_NaN(); + current_ref_.twist.linear.y = std::numeric_limits::quiet_NaN(); + current_ref_.twist.angular.z = std::numeric_limits::quiet_NaN(); + + input_ref_.try_set(current_ref_); } } diff --git a/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp b/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp index 1278be5453..c1466bf6f3 100644 --- a/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp +++ b/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp @@ -304,10 +304,9 @@ TEST_F(MecanumDriveControllerTest, when_controller_is_activated_expect_reference ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); // check that the message is reset - auto msg = controller_->input_ref_.readFromNonRT(); - EXPECT_TRUE(std::isnan((*msg)->twist.linear.x)); - - ASSERT_TRUE(std::isnan((*msg)->twist.angular.z)); + auto msg = controller_->input_ref_.get(); + EXPECT_TRUE(std::isnan(msg.twist.linear.x)); + ASSERT_TRUE(std::isnan(msg.twist.angular.z)); } TEST_F(MecanumDriveControllerTest, when_controller_active_and_update_called_expect_success) @@ -425,11 +424,11 @@ TEST_F(MecanumDriveControllerTest, when_reference_msg_is_too_old_expect_unset_re ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); - auto reference = *(controller_->input_ref_.readFromNonRT()); - auto old_timestamp = reference->header.stamp; - EXPECT_TRUE(std::isnan(reference->twist.linear.x)); - EXPECT_TRUE(std::isnan(reference->twist.linear.y)); - EXPECT_TRUE(std::isnan(reference->twist.angular.z)); + auto reference = controller_->input_ref_.get(); + auto old_timestamp = reference.header.stamp; + EXPECT_TRUE(std::isnan(reference.twist.linear.x)); + EXPECT_TRUE(std::isnan(reference.twist.linear.y)); + EXPECT_TRUE(std::isnan(reference.twist.angular.z)); // reference_callback() is implicitly called when publish_commands() is called // reference_msg is published with provided time stamp when publish_commands( time_stamp) @@ -438,10 +437,10 @@ TEST_F(MecanumDriveControllerTest, when_reference_msg_is_too_old_expect_unset_re controller_->get_node()->now() - controller_->ref_timeout_ - rclcpp::Duration::from_seconds(0.1)); controller_->wait_for_commands(executor); - ASSERT_EQ(old_timestamp, (*(controller_->input_ref_.readFromNonRT()))->header.stamp); - EXPECT_TRUE(std::isnan((reference)->twist.linear.x)); - EXPECT_TRUE(std::isnan((reference)->twist.linear.y)); - EXPECT_TRUE(std::isnan((reference)->twist.angular.z)); + ASSERT_EQ(old_timestamp, reference.header.stamp); + EXPECT_TRUE(std::isnan(reference.twist.linear.x)); + EXPECT_TRUE(std::isnan(reference.twist.linear.y)); + EXPECT_TRUE(std::isnan(reference.twist.angular.z)); } // when time stamp is zero expect that time stamp is set to current time stamp @@ -456,11 +455,11 @@ TEST_F( ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); - auto reference = controller_->input_ref_.readFromNonRT(); - auto old_timestamp = (*reference)->header.stamp; - EXPECT_TRUE(std::isnan((*reference)->twist.linear.x)); - EXPECT_TRUE(std::isnan((*reference)->twist.linear.y)); - EXPECT_TRUE(std::isnan((*reference)->twist.angular.z)); + auto reference = controller_->input_ref_.get(); + auto old_timestamp = reference.header.stamp; + EXPECT_TRUE(std::isnan(reference.twist.linear.x)); + EXPECT_TRUE(std::isnan(reference.twist.linear.y)); + EXPECT_TRUE(std::isnan(reference.twist.angular.z)); // reference_callback() is implicitly called when publish_commands() is called // reference_msg is published with provided time stamp when publish_commands( time_stamp) @@ -468,13 +467,15 @@ TEST_F( publish_commands(rclcpp::Time(0)); controller_->wait_for_commands(executor); - ASSERT_EQ(old_timestamp.sec, (*(controller_->input_ref_.readFromNonRT()))->header.stamp.sec); - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromNonRT()))->twist.linear.x)); - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromNonRT()))->twist.angular.z)); - EXPECT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.linear.x, 1.5); - EXPECT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.linear.y, 0.0); - EXPECT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.angular.z, 0.0); - EXPECT_NE((*(controller_->input_ref_.readFromNonRT()))->header.stamp.sec, 0.0); + reference = controller_->input_ref_.get(); + + ASSERT_EQ(old_timestamp.sec, reference.header.stamp.sec); + EXPECT_FALSE(std::isnan(reference.twist.linear.x)); + EXPECT_FALSE(std::isnan(reference.twist.angular.z)); + EXPECT_EQ(reference.twist.linear.x, 1.5); + EXPECT_EQ(reference.twist.linear.y, 0.0); + EXPECT_EQ(reference.twist.angular.z, 0.0); + EXPECT_NE(reference.header.stamp.sec, 0.0); } // when the reference_msg has valid timestamp then the timeout check in reference_callback() @@ -489,9 +490,9 @@ TEST_F(MecanumDriveControllerTest, when_message_has_valid_timestamp_expect_refer ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); - auto reference = controller_->input_ref_.readFromNonRT(); - EXPECT_TRUE(std::isnan((*reference)->twist.linear.x)); - EXPECT_TRUE(std::isnan((*reference)->twist.angular.z)); + auto reference = controller_->input_ref_.get(); + EXPECT_TRUE(std::isnan(reference.twist.linear.x)); + EXPECT_TRUE(std::isnan(reference.twist.angular.z)); // reference_callback() is implicitly called when publish_commands() is called // reference_msg is published with provided time stamp when publish_commands( time_stamp) @@ -499,11 +500,12 @@ TEST_F(MecanumDriveControllerTest, when_message_has_valid_timestamp_expect_refer publish_commands(controller_->get_node()->now()); controller_->wait_for_commands(executor); - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromNonRT()))->twist.linear.x)); - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromNonRT()))->twist.angular.z)); - EXPECT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.linear.x, 1.5); - EXPECT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.linear.y, 0.0); - EXPECT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.angular.z, 0.0); + reference = controller_->input_ref_.get(); + EXPECT_FALSE(std::isnan(reference.twist.linear.x)); + EXPECT_FALSE(std::isnan(reference.twist.angular.z)); + EXPECT_EQ(reference.twist.linear.x, 1.5); + EXPECT_EQ(reference.twist.linear.y, 0.0); + EXPECT_EQ(reference.twist.angular.z, 0.0); } // when not in chainable mode and ref_msg_timedout expect @@ -532,23 +534,24 @@ TEST_F( // set command statically joint_command_values_[controller_->get_rear_left_wheel_index()] = command_lin_x; - std::shared_ptr msg = std::make_shared(); + ControllerReferenceMsg msg, msg_2; + + msg.header.stamp = controller_->get_node()->now() - controller_->ref_timeout_ - + rclcpp::Duration::from_seconds(0.1); + msg.twist.linear.x = TEST_LINEAR_VELOCITY_X; + msg.twist.linear.y = TEST_LINEAR_VELOCITY_y; + msg.twist.linear.z = std::numeric_limits::quiet_NaN(); + msg.twist.angular.x = std::numeric_limits::quiet_NaN(); + msg.twist.angular.y = std::numeric_limits::quiet_NaN(); + msg.twist.angular.z = TEST_ANGULAR_VELOCITY_Z; + controller_->input_ref_.set(msg); - msg->header.stamp = controller_->get_node()->now() - controller_->ref_timeout_ - - rclcpp::Duration::from_seconds(0.1); - msg->twist.linear.x = TEST_LINEAR_VELOCITY_X; - msg->twist.linear.y = TEST_LINEAR_VELOCITY_y; - msg->twist.linear.z = std::numeric_limits::quiet_NaN(); - msg->twist.angular.x = std::numeric_limits::quiet_NaN(); - msg->twist.angular.y = std::numeric_limits::quiet_NaN(); - msg->twist.angular.z = TEST_ANGULAR_VELOCITY_Z; - controller_->input_ref_.writeFromNonRT(msg); - const auto age_of_last_command = - controller_->get_node()->now() - (*(controller_->input_ref_.readFromNonRT()))->header.stamp; + auto reference = controller_->input_ref_.get(); + const auto age_of_last_command = controller_->get_node()->now() - reference.header.stamp; // age_of_last_command > ref_timeout_ ASSERT_FALSE(age_of_last_command <= controller_->ref_timeout_); - ASSERT_EQ((*(controller_->input_ref_.readFromRT()))->twist.linear.x, TEST_LINEAR_VELOCITY_X); + ASSERT_EQ(reference.twist.linear.x, TEST_LINEAR_VELOCITY_X); ASSERT_EQ( controller_->update(controller_->get_node()->now(), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::OK); @@ -564,21 +567,21 @@ TEST_F( EXPECT_EQ(controller_->command_interfaces_[i].get_optional().value(), 0.0); } - std::shared_ptr msg_2 = std::make_shared(); - msg_2->header.stamp = controller_->get_node()->now() - rclcpp::Duration::from_seconds(0.01); - msg_2->twist.linear.x = TEST_LINEAR_VELOCITY_X; - msg_2->twist.linear.y = TEST_LINEAR_VELOCITY_y; - msg_2->twist.linear.z = std::numeric_limits::quiet_NaN(); - msg_2->twist.angular.x = std::numeric_limits::quiet_NaN(); - msg_2->twist.angular.y = std::numeric_limits::quiet_NaN(); - msg_2->twist.angular.z = TEST_ANGULAR_VELOCITY_Z; - controller_->input_ref_.writeFromNonRT(msg_2); - const auto age_of_last_command_2 = - controller_->get_node()->now() - (*(controller_->input_ref_.readFromNonRT()))->header.stamp; + msg_2.header.stamp = controller_->get_node()->now() - rclcpp::Duration::from_seconds(0.01); + msg_2.twist.linear.x = TEST_LINEAR_VELOCITY_X; + msg_2.twist.linear.y = TEST_LINEAR_VELOCITY_y; + msg_2.twist.linear.z = std::numeric_limits::quiet_NaN(); + msg_2.twist.angular.x = std::numeric_limits::quiet_NaN(); + msg_2.twist.angular.y = std::numeric_limits::quiet_NaN(); + msg_2.twist.angular.z = TEST_ANGULAR_VELOCITY_Z; + controller_->input_ref_.set(msg_2); + + reference = controller_->input_ref_.get(); + const auto age_of_last_command_2 = controller_->get_node()->now() - reference.header.stamp; // age_of_last_command_2 < ref_timeout_ ASSERT_TRUE(age_of_last_command_2 <= controller_->ref_timeout_); - ASSERT_EQ((*(controller_->input_ref_.readFromRT()))->twist.linear.x, TEST_LINEAR_VELOCITY_X); + ASSERT_EQ(reference.twist.linear.x, TEST_LINEAR_VELOCITY_X); ASSERT_EQ( controller_->update(controller_->get_node()->now(), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::OK); @@ -592,7 +595,7 @@ TEST_F( // joint_command_values_[controller_->get_rear_left_wheel_index()] = 1.0 / 0.5 * (1.5 - 0.0 - 1 * // 0.0) EXPECT_EQ(joint_command_values_[controller_->get_rear_left_wheel_index()], 3.0); - ASSERT_EQ((*(controller_->input_ref_.readFromRT()))->twist.linear.x, TEST_LINEAR_VELOCITY_X); + ASSERT_EQ(reference.twist.linear.x, TEST_LINEAR_VELOCITY_X); for (const auto & interface : controller_->reference_interfaces_) { EXPECT_TRUE(std::isnan(interface)); @@ -679,21 +682,22 @@ TEST_F( joint_command_values_[controller_->get_rear_left_wheel_index()] = command_lin_x; controller_->ref_timeout_ = rclcpp::Duration::from_seconds(0.0); - std::shared_ptr msg = std::make_shared(); - - msg->header.stamp = controller_->get_node()->now() - rclcpp::Duration::from_seconds(0.0); - msg->twist.linear.x = TEST_LINEAR_VELOCITY_X; - msg->twist.linear.y = TEST_LINEAR_VELOCITY_y; - msg->twist.linear.z = std::numeric_limits::quiet_NaN(); - msg->twist.angular.x = std::numeric_limits::quiet_NaN(); - msg->twist.angular.y = std::numeric_limits::quiet_NaN(); - msg->twist.angular.z = TEST_ANGULAR_VELOCITY_Z; - controller_->input_ref_.writeFromNonRT(msg); - const auto age_of_last_command = - controller_->get_node()->now() - (*(controller_->input_ref_.readFromNonRT()))->header.stamp; + ControllerReferenceMsg msg; + + msg.header.stamp = controller_->get_node()->now() - rclcpp::Duration::from_seconds(0.0); + msg.twist.linear.x = TEST_LINEAR_VELOCITY_X; + msg.twist.linear.y = TEST_LINEAR_VELOCITY_y; + msg.twist.linear.z = std::numeric_limits::quiet_NaN(); + msg.twist.angular.x = std::numeric_limits::quiet_NaN(); + msg.twist.angular.y = std::numeric_limits::quiet_NaN(); + msg.twist.angular.z = TEST_ANGULAR_VELOCITY_Z; + controller_->input_ref_.set(msg); + auto reference = controller_->input_ref_.get(); + + const auto age_of_last_command = controller_->get_node()->now() - reference.header.stamp; ASSERT_FALSE(age_of_last_command <= controller_->ref_timeout_); - ASSERT_EQ((*(controller_->input_ref_.readFromRT()))->twist.linear.x, TEST_LINEAR_VELOCITY_X); + ASSERT_EQ(reference.twist.linear.x, TEST_LINEAR_VELOCITY_X); ASSERT_EQ( controller_->update(controller_->get_node()->now(), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::OK); @@ -707,7 +711,8 @@ TEST_F( // velocity_in_center_frame_angular_z_); // joint_command_values_[REAR_LEFT] = 1.0 / 0.5 * (1.5 - 0.0 - 1 * 0.0) EXPECT_EQ(joint_command_values_[controller_->get_rear_left_wheel_index()], 3.0); - ASSERT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); + reference = controller_->input_ref_.get(); + ASSERT_TRUE(std::isnan(reference.twist.linear.x)); } TEST_F( @@ -720,9 +725,10 @@ TEST_F( ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); - EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromNonRT()))->twist.linear.x)); - EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromNonRT()))->twist.linear.y)); - EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromNonRT()))->twist.angular.z)); + auto reference = controller_->input_ref_.get(); + EXPECT_TRUE(std::isnan(reference.twist.linear.x)); + EXPECT_TRUE(std::isnan(reference.twist.linear.y)); + EXPECT_TRUE(std::isnan(reference.twist.angular.z)); controller_->ref_timeout_ = rclcpp::Duration::from_seconds(0.0); // reference_callback() is called implicitly when publish_commands() is called. @@ -731,13 +737,14 @@ TEST_F( publish_commands(controller_->get_node()->now()); controller_->wait_for_commands(executor); - - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromNonRT()))->twist.linear.x)); - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromNonRT()))->twist.linear.y)); - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromNonRT()))->twist.angular.z)); - EXPECT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.linear.x, 1.5); - EXPECT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.linear.y, 0.0); - EXPECT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.angular.z, 0.0); + reference = controller_->input_ref_.get(); + + EXPECT_FALSE(std::isnan(reference.twist.linear.x)); + EXPECT_FALSE(std::isnan(reference.twist.linear.y)); + EXPECT_FALSE(std::isnan(reference.twist.angular.z)); + EXPECT_EQ(reference.twist.linear.x, 1.5); + EXPECT_EQ(reference.twist.linear.y, 0.0); + EXPECT_EQ(reference.twist.angular.z, 0.0); } TEST_F(MecanumDriveControllerTest, SideToSideAndRotationOdometryTest) diff --git a/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller.hpp b/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller.hpp index 0bd48b65f5..93a6f6ec65 100644 --- a/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller.hpp +++ b/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller.hpp @@ -36,8 +36,8 @@ #include "controller_interface/controller_interface.hpp" #include "hardware_interface/loaned_command_interface.hpp" #include "hardware_interface/loaned_state_interface.hpp" -#include "realtime_tools/realtime_buffer.hpp" #include "realtime_tools/realtime_server_goal_handle.hpp" +#include "realtime_tools/realtime_thread_safe_box.hpp" // Project #include "parallel_gripper_controller/parallel_gripper_action_controller_parameters.hpp" @@ -93,10 +93,6 @@ class GripperActionController : public controller_interface::ControllerInterface controller_interface::CallbackReturn on_deactivate( const rclcpp_lifecycle::State & previous_state) override; - realtime_tools::RealtimeBuffer command_; - // pre-allocated memory that is reused to set the realtime buffer - Commands command_struct_, command_struct_rt_; - protected: using GripperCommandAction = control_msgs::action::ParallelGripperCommand; using ActionServer = rclcpp_action::Server; @@ -105,12 +101,16 @@ class GripperActionController : public controller_interface::ControllerInterface using RealtimeGoalHandle = realtime_tools::RealtimeServerGoalHandle; using RealtimeGoalHandlePtr = std::shared_ptr; - using RealtimeGoalHandleBuffer = realtime_tools::RealtimeBuffer; + using RealtimeGoalHandleBox = realtime_tools::RealtimeThreadSafeBox; - bool update_hold_position_; + // the realtime container to exchange the reference from subscriber + realtime_tools::RealtimeThreadSafeBox command_; + // pre-allocated memory that is reused + Commands command_struct_; + // save the last reference in case of unable to get value from box + Commands command_struct_rt_; - bool verbose_ = false; ///< Hard coded verbose flag to help in debugging - std::string name_; ///< Controller name. + std::string name_; ///< Controller name. std::optional> joint_command_interface_; std::optional> @@ -125,7 +125,7 @@ class GripperActionController : public controller_interface::ControllerInterface std::shared_ptr param_listener_; Params params_; - RealtimeGoalHandleBuffer + RealtimeGoalHandleBox rt_active_goal_; ///< Container for the currently active action goal, if any. control_msgs::action::ParallelGripperCommand::Result::SharedPtr pre_alloc_result_; diff --git a/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp b/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp index 82037ed546..479c255a25 100644 --- a/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp +++ b/parallel_gripper_controller/include/parallel_gripper_controller/parallel_gripper_action_controller_impl.hpp @@ -30,12 +30,14 @@ namespace parallel_gripper_action_controller void GripperActionController::preempt_active_goal() { // Cancels the currently active goal - const auto active_goal = *rt_active_goal_.readFromNonRT(); + RealtimeGoalHandlePtr active_goal; + rt_active_goal_.get([&](const RealtimeGoalHandlePtr & goal) { active_goal = goal; }); if (active_goal) { // Marks the current goal as canceled active_goal->setCanceled(std::make_shared()); - rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr()); + rt_active_goal_.set([](RealtimeGoalHandlePtr & stored_value) + { stored_value = RealtimeGoalHandlePtr(); }); } } @@ -58,7 +60,11 @@ controller_interface::return_type GripperActionController::update( const rclcpp::Time & /*time*/, const rclcpp::Duration & /*period*/) { auto logger = get_node()->get_logger(); - command_struct_rt_ = *(command_.readFromRT()); + auto command_struct_rt_op = command_.try_get(); + if (command_struct_rt_op.has_value()) + { + command_struct_rt_ = command_struct_rt_op.value(); + } const auto current_position_op = joint_position_state_interface_->get().get_optional(); if (!current_position_op.has_value()) { @@ -148,14 +154,14 @@ void GripperActionController::accepted_callback( { command_struct_.max_effort_ = params_.max_effort; } - command_.writeFromNonRT(command_struct_); + command_.set(command_struct_); pre_alloc_result_->reached_goal = false; pre_alloc_result_->stalled = false; last_movement_time_ = get_node()->now(); rt_goal->execute(); - rt_active_goal_.writeFromNonRT(rt_goal); + rt_active_goal_.set([rt_goal](RealtimeGoalHandlePtr & stored_value) { stored_value = rt_goal; }); // Set smartpointer to expire for create_wall_timer to delete previous entry from timer list goal_handle_timer_.reset(); @@ -172,7 +178,8 @@ rclcpp_action::CancelResponse GripperActionController::cancel_callback( RCLCPP_INFO(get_node()->get_logger(), "Got request to cancel goal"); // Check that cancel request refers to currently active goal (if any) - const auto active_goal = *rt_active_goal_.readFromNonRT(); + RealtimeGoalHandlePtr active_goal; + rt_active_goal_.get([&](const RealtimeGoalHandlePtr & goal) { active_goal = goal; }); if (active_goal && active_goal->gh_ == goal_handle) { // Enter hold current position mode @@ -185,7 +192,8 @@ rclcpp_action::CancelResponse GripperActionController::cancel_callback( auto action_res = std::make_shared(); active_goal->setCanceled(action_res); // Reset current goal - rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr()); + rt_active_goal_.set([](RealtimeGoalHandlePtr & stored_value) + { stored_value = RealtimeGoalHandlePtr(); }); } return rclcpp_action::CancelResponse::ACCEPT; } @@ -200,14 +208,15 @@ void GripperActionController::set_hold_position() command_struct_.position_cmd_ = position_op.value(); command_struct_.max_effort_ = params_.max_effort; command_struct_.max_velocity_ = params_.max_velocity; - command_.writeFromNonRT(command_struct_); + command_.set(command_struct_); } void GripperActionController::check_for_success( const rclcpp::Time & time, double error_position, double current_position, double current_velocity) { - const auto active_goal = *rt_active_goal_.readFromNonRT(); + RealtimeGoalHandlePtr active_goal; + rt_active_goal_.get([&](const RealtimeGoalHandlePtr & goal) { active_goal = goal; }); if (!active_goal) { return; @@ -221,7 +230,8 @@ void GripperActionController::check_for_success( pre_alloc_result_->stalled = false; RCLCPP_DEBUG(get_node()->get_logger(), "Successfully moved to goal."); active_goal->setSucceeded(pre_alloc_result_); - rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr()); + rt_active_goal_.set([](RealtimeGoalHandlePtr & stored_value) + { stored_value = RealtimeGoalHandlePtr(); }); } else { @@ -246,7 +256,8 @@ void GripperActionController::check_for_success( RCLCPP_DEBUG(get_node()->get_logger(), "Stall detected moving to goal. Aborting action!"); active_goal->setAborted(pre_alloc_result_); } - rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr()); + rt_active_goal_.set([](RealtimeGoalHandlePtr & stored_value) + { stored_value = RealtimeGoalHandlePtr(); }); } } } @@ -357,7 +368,7 @@ controller_interface::CallbackReturn GripperActionController::on_activate( } command_struct_.max_effort_ = params_.max_effort; command_struct_.max_velocity_ = params_.max_velocity; - command_.initRT(command_struct_); + command_.try_set(command_struct_); // Result pre_alloc_result_ = std::make_shared(); diff --git a/pid_controller/include/pid_controller/pid_controller.hpp b/pid_controller/include/pid_controller/pid_controller.hpp index 34a50a3687..c8e651ed30 100644 --- a/pid_controller/include/pid_controller/pid_controller.hpp +++ b/pid_controller/include/pid_controller/pid_controller.hpp @@ -18,6 +18,7 @@ #ifndef PID_CONTROLLER__PID_CONTROLLER_HPP_ #define PID_CONTROLLER__PID_CONTROLLER_HPP_ +#include #include #include #include @@ -27,8 +28,8 @@ #include "control_toolbox/pid_ros.hpp" #include "controller_interface/chainable_controller_interface.hpp" #include "rclcpp_lifecycle/state.hpp" -#include "realtime_tools/realtime_buffer.hpp" #include "realtime_tools/realtime_publisher.hpp" +#include "realtime_tools/realtime_thread_safe_box.hpp" #include "std_srvs/srv/set_bool.hpp" #include "pid_controller/pid_controller_parameters.hpp" @@ -82,10 +83,12 @@ class PidController : public controller_interface::ChainableControllerInterface // Command subscribers and Controller State publisher rclcpp::Subscription::SharedPtr ref_subscriber_ = nullptr; - realtime_tools::RealtimeBuffer> input_ref_; + realtime_tools::RealtimeThreadSafeBox input_ref_; + ControllerReferenceMsg current_ref_; rclcpp::Subscription::SharedPtr measured_state_subscriber_ = nullptr; - realtime_tools::RealtimeBuffer> measured_state_; + realtime_tools::RealtimeThreadSafeBox measured_state_; + ControllerMeasuredStateMsg current_state_; rclcpp::Service::SharedPtr set_feedforward_control_service_; realtime_tools::RealtimeBuffer feedforward_mode_enabled_; diff --git a/pid_controller/src/pid_controller.cpp b/pid_controller/src/pid_controller.cpp index 15b3e77696..25cecddbb7 100644 --- a/pid_controller/src/pid_controller.cpp +++ b/pid_controller/src/pid_controller.cpp @@ -53,15 +53,15 @@ using ControllerCommandMsg = pid_controller::PidController::ControllerReferenceM // called from RT control loop void reset_controller_reference_msg( - const std::shared_ptr & msg, const std::vector & dof_names) + ControllerCommandMsg & msg, const std::vector & dof_names) { - msg->dof_names = dof_names; - msg->values.resize(dof_names.size(), std::numeric_limits::quiet_NaN()); - msg->values_dot.resize(dof_names.size(), std::numeric_limits::quiet_NaN()); + msg.dof_names = dof_names; + msg.values.resize(dof_names.size(), std::numeric_limits::quiet_NaN()); + msg.values_dot.resize(dof_names.size(), std::numeric_limits::quiet_NaN()); } void reset_controller_measured_state_msg( - const std::shared_ptr & msg, const std::vector & dof_names) + ControllerCommandMsg & msg, const std::vector & dof_names) { reset_controller_reference_msg(msg, dof_names); } @@ -178,9 +178,8 @@ controller_interface::CallbackReturn PidController::on_configure( "~/reference", subscribers_qos, std::bind(&PidController::reference_callback, this, std::placeholders::_1)); - std::shared_ptr msg = std::make_shared(); - reset_controller_reference_msg(msg, reference_and_state_dof_names_); - input_ref_.writeFromNonRT(msg); + reset_controller_reference_msg(current_ref_, reference_and_state_dof_names_); + input_ref_.set(current_ref_); // input state Subscriber and callback if (params_.use_external_measured_states) @@ -226,16 +225,15 @@ controller_interface::CallbackReturn PidController::on_configure( } } // TODO(destogl): Sort the input values based on joint and interface names - measured_state_.writeFromNonRT(state_msg); + measured_state_.set(*state_msg); }; measured_state_subscriber_ = get_node()->create_subscription( "~/measured_state", subscribers_qos, measured_state_callback); } - std::shared_ptr measured_state_msg = - std::make_shared(); + ControllerMeasuredStateMsg measured_state_msg; reset_controller_measured_state_msg(measured_state_msg, reference_and_state_dof_names_); - measured_state_.writeFromNonRT(measured_state_msg); + measured_state_.set(measured_state_msg); measured_state_values_.resize( dof_ * params_.reference_and_state_interfaces.size(), std::numeric_limits::quiet_NaN()); @@ -296,7 +294,7 @@ void PidController::reference_callback(const std::shared_ptrdof_names = reference_and_state_dof_names_; - input_ref_.writeFromNonRT(ref_msg); + input_ref_.set(*ref_msg); } else if ( msg->dof_names.size() == reference_and_state_dof_names_.size() && @@ -305,7 +303,7 @@ void PidController::reference_callback(const std::shared_ptrdof_names.size(); ++i) @@ -328,7 +326,7 @@ void PidController::reference_callback(const std::shared_ptr::quiet_NaN()); @@ -452,21 +460,26 @@ controller_interface::CallbackReturn PidController::on_activate( controller_interface::return_type PidController::update_reference_from_subscribers( const rclcpp::Time & /*time*/, const rclcpp::Duration & /*period*/) { - auto current_ref = input_ref_.readFromRT(); + auto current_ref_op = input_ref_.try_get(); + if (current_ref_op.has_value()) + { + current_ref_ = current_ref_op.value(); + } for (size_t i = 0; i < dof_; ++i) { - if (!std::isnan((*current_ref)->values[i])) + if (!std::isnan(current_ref_.values[i])) { - reference_interfaces_[i] = (*current_ref)->values[i]; - if (reference_interfaces_.size() == 2 * dof_ && !std::isnan((*current_ref)->values_dot[i])) + reference_interfaces_[i] = current_ref_.values[i]; + if (reference_interfaces_.size() == 2 * dof_ && !std::isnan(current_ref_.values_dot[i])) { - reference_interfaces_[dof_ + i] = (*current_ref)->values_dot[i]; + reference_interfaces_[dof_ + i] = current_ref_.values_dot[i]; } - - (*current_ref)->values[i] = std::numeric_limits::quiet_NaN(); + current_ref_.values[i] = std::numeric_limits::quiet_NaN(); } } + // save cleared input_ref_ + input_ref_.try_set(current_ref_); return controller_interface::return_type::OK; } @@ -479,13 +492,17 @@ controller_interface::return_type PidController::update_and_write_commands( // Update feedback either from external measured state or from state interfaces if (params_.use_external_measured_states) { - const auto measured_state = *(measured_state_.readFromRT()); + auto measured_state_op = measured_state_.try_get(); + if (measured_state_op.has_value()) + { + current_state_ = measured_state_op.value(); + } for (size_t i = 0; i < dof_; ++i) { - measured_state_values_[i] = measured_state->values[i]; + measured_state_values_[i] = current_state_.values[i]; if (measured_state_values_.size() == 2 * dof_) { - measured_state_values_[dof_ + i] = measured_state->values_dot[i]; + measured_state_values_[dof_ + i] = current_state_.values_dot[i]; } } } @@ -521,9 +538,9 @@ controller_interface::return_type PidController::update_and_write_commands( // calculate feed-forward if (*(feedforward_mode_enabled_.readFromRT())) { - // two interfaces if (reference_interfaces_.size() == 2 * dof_) { + // two interfaces if (std::isfinite(reference_interfaces_[dof_ + i])) { tmp_command = reference_interfaces_[dof_ + i] * diff --git a/pid_controller/test/test_pid_controller.cpp b/pid_controller/test/test_pid_controller.cpp index 633a6259ce..bd3fefcb60 100644 --- a/pid_controller/test/test_pid_controller.cpp +++ b/pid_controller/test/test_pid_controller.cpp @@ -131,14 +131,14 @@ TEST_F(PidControllerTest, activate_success) ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); // check that the message is reset - auto msg = controller_->input_ref_.readFromNonRT(); - EXPECT_EQ((*msg)->values.size(), dof_names_.size()); - for (const auto & cmd : (*msg)->values) + auto msg = controller_->input_ref_.get(); + EXPECT_EQ(msg.values.size(), dof_names_.size()); + for (const auto & cmd : msg.values) { EXPECT_TRUE(std::isnan(cmd)); } - EXPECT_EQ((*msg)->values_dot.size(), dof_names_.size()); - for (const auto & cmd : (*msg)->values_dot) + EXPECT_EQ(msg.values_dot.size(), dof_names_.size()); + for (const auto & cmd : msg.values_dot) { EXPECT_TRUE(std::isnan(cmd)); } @@ -283,7 +283,7 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_off) controller_->set_chained_mode(false); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_FALSE(controller_->is_in_chained_mode()); - EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->values[0])); + EXPECT_TRUE(std::isnan(controller_->input_ref_.get().values[0])); EXPECT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); for (const auto & interface : controller_->reference_interfaces_) { @@ -294,8 +294,8 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_off) for (size_t i = 0; i < dof_command_values_.size(); ++i) { - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromRT()))->values[i])); - EXPECT_EQ((*(controller_->input_ref_.readFromRT()))->values[i], dof_command_values_[i]); + EXPECT_FALSE(std::isnan(controller_->input_ref_.get().values[i])); + EXPECT_EQ(controller_->input_ref_.get().values[i], dof_command_values_[i]); EXPECT_TRUE(std::isnan(controller_->reference_interfaces_[i])); } @@ -309,7 +309,7 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_off) EXPECT_EQ(controller_->reference_interfaces_.size(), dof_state_values_.size()); for (size_t i = 0; i < dof_command_values_.size(); ++i) { - EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->values[i])); + EXPECT_TRUE(std::isnan(controller_->input_ref_.get().values[i])); } // check the command value // ref = 101.101, state = 1.1, ds = 0.01 @@ -340,7 +340,7 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward controller_->set_chained_mode(false); ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); ASSERT_FALSE(controller_->is_in_chained_mode()); - EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->values[0])); + EXPECT_TRUE(std::isnan(controller_->input_ref_.get().values[0])); EXPECT_EQ(*(controller_->feedforward_mode_enabled_.readFromRT()), false); for (const auto & interface : controller_->reference_interfaces_) { @@ -355,8 +355,8 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward for (size_t i = 0; i < dof_command_values_.size(); ++i) { - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromRT()))->values[i])); - EXPECT_EQ((*(controller_->input_ref_.readFromRT()))->values[i], dof_command_values_[i]); + EXPECT_FALSE(std::isnan(controller_->input_ref_.get().values[i])); + EXPECT_EQ(controller_->input_ref_.get().values[i], dof_command_values_[i]); EXPECT_TRUE(std::isnan(controller_->reference_interfaces_[i])); } @@ -370,7 +370,7 @@ TEST_F(PidControllerTest, test_update_logic_feedforward_on_with_zero_feedforward EXPECT_EQ(controller_->reference_interfaces_.size(), dof_state_values_.size()); for (size_t i = 0; i < dof_command_values_.size(); ++i) { - EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->values[i])); + EXPECT_TRUE(std::isnan(controller_->input_ref_.get().values[i])); // check the command value: // ref = 101.101, state = 1.1, ds = 0.01 diff --git a/pid_controller/test/test_pid_controller.hpp b/pid_controller/test/test_pid_controller.hpp index 6bd0af89e9..d63fb5a322 100644 --- a/pid_controller/test/test_pid_controller.hpp +++ b/pid_controller/test/test_pid_controller.hpp @@ -109,15 +109,15 @@ class TestablePidController : public pid_controller::PidController void set_reference(const std::vector & target_value) { - std::shared_ptr msg = std::make_shared(); - msg->dof_names = params_.dof_names; - msg->values.resize(msg->dof_names.size(), 0.0); - for (size_t i = 0; i < msg->dof_names.size(); ++i) + ControllerCommandMsg msg; + msg.dof_names = params_.dof_names; + msg.values.resize(msg.dof_names.size(), 0.0); + for (size_t i = 0; i < msg.dof_names.size(); ++i) { - msg->values[i] = target_value[i]; + msg.values[i] = target_value[i]; } - msg->values_dot.resize(msg->dof_names.size(), std::numeric_limits::quiet_NaN()); - input_ref_.writeFromNonRT(msg); + msg.values_dot.resize(msg.dof_names.size(), std::numeric_limits::quiet_NaN()); + input_ref_.set(msg); } }; @@ -145,6 +145,8 @@ class PidControllerFixture : public ::testing::Test service_caller_node_ = std::make_shared("service_caller"); feedforward_service_client_ = service_caller_node_->create_client( "/test_pid_controller/set_feedforward_control"); + command_publisher_ = command_publisher_node_->create_publisher( + "/test_pid_controller/reference", rclcpp::SystemDefaultsQoS()); } static void TearDownTestCase() { rclcpp::shutdown(); } diff --git a/position_controllers/test/test_joint_group_position_controller.cpp b/position_controllers/test/test_joint_group_position_controller.cpp index 380450a6d1..3d38671cba 100644 --- a/position_controllers/test/test_joint_group_position_controller.cpp +++ b/position_controllers/test/test_joint_group_position_controller.cpp @@ -111,9 +111,9 @@ TEST_F(JointGroupPositionControllerTest, CommandSuccessTest) ASSERT_EQ(joint_3_pos_cmd_.get_optional().value(), 3.1); // send command - auto command_ptr = std::make_shared(); - command_ptr->data = {10.0, 20.0, 30.0}; - controller_->rt_command_ptr_.writeFromNonRT(command_ptr); + forward_command_controller::CmdType command; + command.data = {10.0, 20.0, 30.0}; + controller_->rt_command_.set(command); // update successful, command received ASSERT_EQ( @@ -133,9 +133,9 @@ TEST_F(JointGroupPositionControllerTest, WrongCommandCheckTest) ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); // send command with wrong number of joints - auto command_ptr = std::make_shared(); - command_ptr->data = {10.0, 20.0}; - controller_->rt_command_ptr_.writeFromNonRT(command_ptr); + forward_command_controller::CmdType command; + command.data = {10.0, 20.0}; + controller_->rt_command_.set(command); // update failed, command size does not match number of joints ASSERT_EQ( diff --git a/steering_controllers_library/include/steering_controllers_library/steering_controllers_library.hpp b/steering_controllers_library/include/steering_controllers_library/steering_controllers_library.hpp index e700767e4c..83057652a5 100644 --- a/steering_controllers_library/include/steering_controllers_library/steering_controllers_library.hpp +++ b/steering_controllers_library/include/steering_controllers_library/steering_controllers_library.hpp @@ -23,8 +23,8 @@ #include "controller_interface/chainable_controller_interface.hpp" #include "hardware_interface/handle.hpp" #include "rclcpp_lifecycle/state.hpp" -#include "realtime_tools/realtime_buffer.hpp" #include "realtime_tools/realtime_publisher.hpp" +#include "realtime_tools/realtime_thread_safe_box.hpp" // TODO(anyone): Replace with controller specific messages #include "control_msgs/msg/steering_controller_status.hpp" @@ -81,11 +81,14 @@ class SteeringControllersLibrary : public controller_interface::ChainableControl std::shared_ptr param_listener_; steering_controllers_library::Params params_; - // Command subscribers and Controller State publisher - rclcpp::Subscription::SharedPtr ref_subscriber_twist_ = nullptr; - realtime_tools::RealtimeBuffer> input_ref_; + // the RT Box containing the command message + realtime_tools::RealtimeThreadSafeBox input_ref_; + // save the last reference in case of unable to get value from box + ControllerTwistReferenceMsg current_ref_; rclcpp::Duration ref_timeout_ = rclcpp::Duration::from_seconds(0.0); // 0ms + // Command subscribers and Controller State publisher + rclcpp::Subscription::SharedPtr ref_subscriber_twist_ = nullptr; using ControllerStatePublisherOdom = realtime_tools::RealtimePublisher; using ControllerStatePublisherTf = realtime_tools::RealtimePublisher; diff --git a/steering_controllers_library/src/steering_controllers_library.cpp b/steering_controllers_library/src/steering_controllers_library.cpp index bbb779b60a..69322f4403 100644 --- a/steering_controllers_library/src/steering_controllers_library.cpp +++ b/steering_controllers_library/src/steering_controllers_library.cpp @@ -31,16 +31,15 @@ using ControllerTwistReferenceMsg = // called from RT control loop void reset_controller_reference_msg( - const std::shared_ptr & msg, - const std::shared_ptr & node) + ControllerTwistReferenceMsg & msg, const std::shared_ptr & node) { - msg->header.stamp = node->now(); - msg->twist.linear.x = std::numeric_limits::quiet_NaN(); - msg->twist.linear.y = std::numeric_limits::quiet_NaN(); - msg->twist.linear.z = std::numeric_limits::quiet_NaN(); - msg->twist.angular.x = std::numeric_limits::quiet_NaN(); - msg->twist.angular.y = std::numeric_limits::quiet_NaN(); - msg->twist.angular.z = std::numeric_limits::quiet_NaN(); + msg.header.stamp = node->now(); + msg.twist.linear.x = std::numeric_limits::quiet_NaN(); + msg.twist.linear.y = std::numeric_limits::quiet_NaN(); + msg.twist.linear.z = std::numeric_limits::quiet_NaN(); + msg.twist.angular.x = std::numeric_limits::quiet_NaN(); + msg.twist.angular.y = std::numeric_limits::quiet_NaN(); + msg.twist.angular.z = std::numeric_limits::quiet_NaN(); } } // namespace @@ -333,10 +332,8 @@ controller_interface::CallbackReturn SteeringControllersLibrary::on_configure( "~/reference", subscribers_qos, std::bind(&SteeringControllersLibrary::reference_callback, this, std::placeholders::_1)); - std::shared_ptr msg = - std::make_shared(); - reset_controller_reference_msg(msg, get_node()); - input_ref_.writeFromNonRT(msg); + reset_controller_reference_msg(current_ref_, get_node()); + input_ref_.set(current_ref_); try { @@ -433,7 +430,7 @@ void SteeringControllersLibrary::reference_callback( if (ref_timeout_ == rclcpp::Duration::from_seconds(0) || age_of_last_command <= ref_timeout_) { - input_ref_.writeFromNonRT(msg); + input_ref_.set(*msg); } else { @@ -518,8 +515,10 @@ bool SteeringControllersLibrary::on_set_chained_mode(bool /*chained_mode*/) { re controller_interface::CallbackReturn SteeringControllersLibrary::on_activate( const rclcpp_lifecycle::State & /*previous_state*/) { - // Set default value in command - reset_controller_reference_msg(*(input_ref_.readFromRT()), get_node()); + // Try to set default value in command. + // If this fails, then another command will be received soon anyways. + reset_controller_reference_msg(current_ref_, get_node()); + input_ref_.try_set(current_ref_); return controller_interface::CallbackReturn::SUCCESS; } @@ -542,14 +541,45 @@ controller_interface::CallbackReturn SteeringControllersLibrary::on_deactivate( } controller_interface::return_type SteeringControllersLibrary::update_reference_from_subscribers( - const rclcpp::Time & /*time*/, const rclcpp::Duration & /*period*/) + const rclcpp::Time & time, const rclcpp::Duration & /*period*/) { - auto current_ref = *(input_ref_.readFromRT()); + auto current_ref_op = input_ref_.try_get(); + if (current_ref_op.has_value()) + { + current_ref_ = current_ref_op.value(); + } - if (!std::isnan(current_ref->twist.linear.x) && !std::isnan(current_ref->twist.angular.z)) + const auto age_of_last_command = time - current_ref_.header.stamp; + + // accept message only if there is no timeout + if (age_of_last_command <= ref_timeout_ || ref_timeout_ == rclcpp::Duration::from_seconds(0)) { - reference_interfaces_[0] = current_ref->twist.linear.x; - reference_interfaces_[1] = current_ref->twist.angular.z; + if (!std::isnan(current_ref_.twist.linear.x) && !std::isnan(current_ref_.twist.linear.y)) + { + reference_interfaces_[0] = current_ref_.twist.linear.x; + reference_interfaces_[1] = current_ref_.twist.angular.z; + + if (ref_timeout_ == rclcpp::Duration::from_seconds(0)) + { + current_ref_.twist.linear.x = std::numeric_limits::quiet_NaN(); + current_ref_.twist.angular.z = std::numeric_limits::quiet_NaN(); + + input_ref_.try_set(current_ref_); + } + } + } + else + { + if (!std::isnan(current_ref_.twist.linear.x) && !std::isnan(current_ref_.twist.angular.z)) + { + reference_interfaces_[0] = std::numeric_limits::quiet_NaN(); + reference_interfaces_[1] = std::numeric_limits::quiet_NaN(); + + current_ref_.twist.linear.x = std::numeric_limits::quiet_NaN(); + current_ref_.twist.angular.z = std::numeric_limits::quiet_NaN(); + + input_ref_.try_set(current_ref_); + } } return controller_interface::return_type::OK; @@ -568,25 +598,17 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c if (!std::isnan(reference_interfaces_[0]) && !std::isnan(reference_interfaces_[1])) { - const auto age_of_last_command = time - (*(input_ref_.readFromRT()))->header.stamp; - const auto timeout = - age_of_last_command > ref_timeout_ && ref_timeout_ != rclcpp::Duration::from_seconds(0); - - // store (for open loop odometry) and set commands - last_linear_velocity_ = timeout ? 0.0 : reference_interfaces_[0]; - last_angular_velocity_ = timeout ? 0.0 : reference_interfaces_[1]; - auto [traction_commands, steering_commands] = odometry_.get_commands( reference_interfaces_[0], reference_interfaces_[1], params_.open_loop, params_.reduce_wheel_speed_until_steering_reached); for (size_t i = 0; i < params_.traction_joints_names.size(); i++) { - const auto value = timeout ? 0.0 : traction_commands[i]; - - if (!command_interfaces_[i].set_value(value)) + if (!command_interfaces_[i].set_value(traction_commands[i])) { - RCLCPP_WARN(logger, "Unable to set traction command at index %zu: value = %f", i, value); + RCLCPP_WARN( + logger, "Unable to set traction command at index %zu: value = %f", i, + traction_commands[i]); return controller_interface::return_type::OK; } } @@ -601,6 +623,13 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c } } } + else + { + for (size_t i = 0; i < params_.traction_joints_names.size(); i++) + { + command_interfaces_[i].set_value(0.0); + } + } // Publish odometry message // Compute and store orientation info diff --git a/steering_controllers_library/test/test_steering_controllers_library.cpp b/steering_controllers_library/test/test_steering_controllers_library.cpp index b661b85671..79740f3693 100644 --- a/steering_controllers_library/test/test_steering_controllers_library.cpp +++ b/steering_controllers_library/test/test_steering_controllers_library.cpp @@ -80,11 +80,12 @@ TEST_F(SteeringControllersLibraryTest, check_exported_interfaces) } // Tests controller update_reference_from_subscribers and -// its two cases for position_feedback true/false behavior +// for position_feedback behavior // when too old msg is sent i.e age_of_last_command > ref_timeout case -TEST_F(SteeringControllersLibraryTest, test_both_update_methods_for_ref_timeout) +TEST_F(SteeringControllersLibraryTest, test_position_feedback_ref_timeout) { SetUpController(); + controller_->params_.position_feedback = true; rclcpp::executors::MultiThreadedExecutor executor; executor.add_node(controller_->get_node()->get_node_base_interface()); @@ -104,46 +105,76 @@ TEST_F(SteeringControllersLibraryTest, test_both_update_methods_for_ref_timeout) const double TEST_LINEAR_VELOCITY_Y = 0.0; const double TEST_ANGULAR_VELOCITY_Z = 0.3; - std::shared_ptr msg = std::make_shared(); + ControllerReferenceMsg msg; - // adjusting to achieve age_of_last_command > ref_timeout - msg->header.stamp = controller_->get_node()->now() - controller_->ref_timeout_ - - rclcpp::Duration::from_seconds(0.1); - msg->twist.linear.x = TEST_LINEAR_VELOCITY_X; - msg->twist.linear.y = TEST_LINEAR_VELOCITY_Y; - msg->twist.linear.z = std::numeric_limits::quiet_NaN(); - msg->twist.angular.x = std::numeric_limits::quiet_NaN(); - msg->twist.angular.y = std::numeric_limits::quiet_NaN(); - msg->twist.angular.z = TEST_ANGULAR_VELOCITY_Z; - controller_->input_ref_.writeFromNonRT(msg); - - const auto age_of_last_command = - controller_->get_node()->now() - (*(controller_->input_ref_.readFromNonRT()))->header.stamp; - - // case 1 position_feedback = false - controller_->params_.position_feedback = false; + msg.header.stamp = controller_->get_node()->now(); + msg.twist.linear.x = TEST_LINEAR_VELOCITY_X; + msg.twist.linear.y = TEST_LINEAR_VELOCITY_Y; + msg.twist.linear.z = std::numeric_limits::quiet_NaN(); + msg.twist.angular.x = std::numeric_limits::quiet_NaN(); + msg.twist.angular.y = std::numeric_limits::quiet_NaN(); + msg.twist.angular.z = TEST_ANGULAR_VELOCITY_Z; + controller_->input_ref_.set(msg); - // age_of_last_command > ref_timeout_ - ASSERT_FALSE(age_of_last_command <= controller_->ref_timeout_); - ASSERT_EQ((*(controller_->input_ref_.readFromRT()))->twist.linear.x, TEST_LINEAR_VELOCITY_X); + // age_of_last_command < ref_timeout_ + auto age_of_last_command = + controller_->get_node()->now() - controller_->input_ref_.get().header.stamp; + ASSERT_TRUE(age_of_last_command <= controller_->ref_timeout_); + ASSERT_EQ(controller_->input_ref_.get().twist.linear.x, TEST_LINEAR_VELOCITY_X); ASSERT_EQ( controller_->update(controller_->get_node()->now(), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::OK); - EXPECT_TRUE(std::isnan(controller_->reference_interfaces_[0])); - EXPECT_TRUE(std::isnan(controller_->reference_interfaces_[1])); for (const auto & interface : controller_->reference_interfaces_) { EXPECT_TRUE(std::isnan(interface)); } - ASSERT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.linear.x, TEST_LINEAR_VELOCITY_X); - ASSERT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.angular.z, TEST_ANGULAR_VELOCITY_Z); + ASSERT_FALSE(std::isnan(controller_->input_ref_.get().twist.linear.x)); + ASSERT_FALSE(std::isnan(controller_->input_ref_.get().twist.angular.z)); + + // are the command_itfs updated? + EXPECT_NEAR(controller_->command_interfaces_[0].get_optional().value(), 3.333333, 1e-6); + EXPECT_NEAR(controller_->command_interfaces_[1].get_optional().value(), 3.333333, 1e-6); + EXPECT_NEAR(controller_->command_interfaces_[2].get_optional().value(), 0.575875, 1e-6); + EXPECT_NEAR(controller_->command_interfaces_[3].get_optional().value(), 0.575875, 1e-6); + + // adjusting to achieve age_of_last_command > ref_timeout + msg.header.stamp = controller_->get_node()->now() - controller_->ref_timeout_ - + rclcpp::Duration::from_seconds(0.1); + msg.twist.linear.x = TEST_LINEAR_VELOCITY_X; + msg.twist.linear.y = TEST_LINEAR_VELOCITY_Y; + msg.twist.linear.z = std::numeric_limits::quiet_NaN(); + msg.twist.angular.x = std::numeric_limits::quiet_NaN(); + msg.twist.angular.y = std::numeric_limits::quiet_NaN(); + msg.twist.angular.z = TEST_ANGULAR_VELOCITY_Z; + controller_->input_ref_.set(msg); + + age_of_last_command = controller_->get_node()->now() - controller_->input_ref_.get().header.stamp; + + // adjusting to achieve age_of_last_command > ref_timeout + msg.header.stamp = controller_->get_node()->now() - controller_->ref_timeout_ - + rclcpp::Duration::from_seconds(0.1); + msg.twist.linear.x = TEST_LINEAR_VELOCITY_X; + msg.twist.linear.y = TEST_LINEAR_VELOCITY_Y; + msg.twist.linear.z = std::numeric_limits::quiet_NaN(); + msg.twist.angular.x = std::numeric_limits::quiet_NaN(); + msg.twist.angular.y = std::numeric_limits::quiet_NaN(); + msg.twist.angular.z = TEST_ANGULAR_VELOCITY_Z; + controller_->input_ref_.set(msg); + + // age_of_last_command > ref_timeout_ + ASSERT_FALSE(age_of_last_command <= controller_->ref_timeout_); + ASSERT_EQ(controller_->input_ref_.get().twist.linear.x, TEST_LINEAR_VELOCITY_X); + ASSERT_EQ( + controller_->update(controller_->get_node()->now(), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); - EXPECT_TRUE(std::isnan(controller_->reference_interfaces_[0])); for (const auto & interface : controller_->reference_interfaces_) { EXPECT_TRUE(std::isnan(interface)); } + ASSERT_TRUE(std::isnan(controller_->input_ref_.get().twist.linear.x)); + ASSERT_TRUE(std::isnan(controller_->input_ref_.get().twist.angular.z)); // Wheel velocities should reset to 0 EXPECT_EQ(controller_->command_interfaces_[0].get_optional().value(), 0); @@ -152,42 +183,94 @@ TEST_F(SteeringControllersLibraryTest, test_both_update_methods_for_ref_timeout) // Steer angles should not reset EXPECT_NEAR(controller_->command_interfaces_[2].get_optional().value(), 0.575875, 1e-6); EXPECT_NEAR(controller_->command_interfaces_[3].get_optional().value(), 0.575875, 1e-6); +} - // case 2 position_feedback = true - controller_->params_.position_feedback = true; +// Tests controller update_reference_from_subscribers and +// for position_feedback=false behavior +// when too old msg is sent i.e age_of_last_command > ref_timeout case +TEST_F(SteeringControllersLibraryTest, test_velocity_feedback_ref_timeout) +{ + SetUpController(); + controller_->params_.position_feedback = false; - // adjusting to achieve age_of_last_command > ref_timeout - msg->header.stamp = controller_->get_node()->now() - controller_->ref_timeout_ - - rclcpp::Duration::from_seconds(0.1); - msg->twist.linear.x = TEST_LINEAR_VELOCITY_X; - msg->twist.linear.y = TEST_LINEAR_VELOCITY_Y; - msg->twist.linear.z = std::numeric_limits::quiet_NaN(); - msg->twist.angular.x = std::numeric_limits::quiet_NaN(); - msg->twist.angular.y = std::numeric_limits::quiet_NaN(); - msg->twist.angular.z = TEST_ANGULAR_VELOCITY_Z; - controller_->input_ref_.writeFromNonRT(msg); + rclcpp::executors::MultiThreadedExecutor executor; + executor.add_node(controller_->get_node()->get_node_base_interface()); - // age_of_last_command > ref_timeout_ - ASSERT_FALSE(age_of_last_command <= controller_->ref_timeout_); - ASSERT_EQ((*(controller_->input_ref_.readFromRT()))->twist.linear.x, TEST_LINEAR_VELOCITY_X); + ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); + controller_->set_chained_mode(false); + ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); + ASSERT_FALSE(controller_->is_in_chained_mode()); + + for (const auto & interface : controller_->reference_interfaces_) + { + EXPECT_TRUE(std::isnan(interface)); + } + + // set command statically + const double TEST_LINEAR_VELOCITY_X = 1.5; + const double TEST_LINEAR_VELOCITY_Y = 0.0; + const double TEST_ANGULAR_VELOCITY_Z = 0.3; + + ControllerReferenceMsg msg; + + msg.header.stamp = controller_->get_node()->now(); + msg.twist.linear.x = TEST_LINEAR_VELOCITY_X; + msg.twist.linear.y = TEST_LINEAR_VELOCITY_Y; + msg.twist.linear.z = std::numeric_limits::quiet_NaN(); + msg.twist.angular.x = std::numeric_limits::quiet_NaN(); + msg.twist.angular.y = std::numeric_limits::quiet_NaN(); + msg.twist.angular.z = TEST_ANGULAR_VELOCITY_Z; + controller_->input_ref_.set(msg); + + auto age_of_last_command = + controller_->get_node()->now() - controller_->input_ref_.get().header.stamp; + + // age_of_last_command < ref_timeout_ + ASSERT_TRUE(age_of_last_command <= controller_->ref_timeout_); + ASSERT_EQ(controller_->input_ref_.get().twist.linear.x, TEST_LINEAR_VELOCITY_X); ASSERT_EQ( controller_->update(controller_->get_node()->now(), rclcpp::Duration::from_seconds(0.01)), controller_interface::return_type::OK); - EXPECT_TRUE(std::isnan(controller_->reference_interfaces_[0])); - EXPECT_TRUE(std::isnan(controller_->reference_interfaces_[1])); for (const auto & interface : controller_->reference_interfaces_) { EXPECT_TRUE(std::isnan(interface)); } - ASSERT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.linear.x, TEST_LINEAR_VELOCITY_X); - ASSERT_EQ((*(controller_->input_ref_.readFromNonRT()))->twist.angular.z, TEST_ANGULAR_VELOCITY_Z); + ASSERT_FALSE(std::isnan(controller_->input_ref_.get().twist.linear.x)); + ASSERT_FALSE(std::isnan(controller_->input_ref_.get().twist.angular.z)); + + // are the command_itfs updated? + EXPECT_NEAR(controller_->command_interfaces_[0].get_optional().value(), 3.333333, 1e-6); + EXPECT_NEAR(controller_->command_interfaces_[1].get_optional().value(), 3.333333, 1e-6); + EXPECT_NEAR(controller_->command_interfaces_[2].get_optional().value(), 0.575875, 1e-6); + EXPECT_NEAR(controller_->command_interfaces_[3].get_optional().value(), 0.575875, 1e-6); + + // adjusting to achieve age_of_last_command > ref_timeout + msg.header.stamp = controller_->get_node()->now() - controller_->ref_timeout_ - + rclcpp::Duration::from_seconds(0.1); + msg.twist.linear.x = TEST_LINEAR_VELOCITY_X; + msg.twist.linear.y = TEST_LINEAR_VELOCITY_Y; + msg.twist.linear.z = std::numeric_limits::quiet_NaN(); + msg.twist.angular.x = std::numeric_limits::quiet_NaN(); + msg.twist.angular.y = std::numeric_limits::quiet_NaN(); + msg.twist.angular.z = TEST_ANGULAR_VELOCITY_Z; + controller_->input_ref_.set(msg); + + age_of_last_command = controller_->get_node()->now() - controller_->input_ref_.get().header.stamp; + + // age_of_last_command > ref_timeout_ + ASSERT_FALSE(age_of_last_command <= controller_->ref_timeout_); + ASSERT_EQ(controller_->input_ref_.get().twist.linear.x, TEST_LINEAR_VELOCITY_X); + ASSERT_EQ( + controller_->update(controller_->get_node()->now(), rclcpp::Duration::from_seconds(0.01)), + controller_interface::return_type::OK); - EXPECT_TRUE(std::isnan(controller_->reference_interfaces_[0])); for (const auto & interface : controller_->reference_interfaces_) { EXPECT_TRUE(std::isnan(interface)); } + ASSERT_TRUE(std::isnan(controller_->input_ref_.get().twist.linear.x)); + ASSERT_TRUE(std::isnan(controller_->input_ref_.get().twist.angular.z)); // Wheel velocities should reset to 0 EXPECT_EQ(controller_->command_interfaces_[0].get_optional().value(), 0); diff --git a/steering_controllers_library/test/test_steering_controllers_library.hpp b/steering_controllers_library/test/test_steering_controllers_library.hpp index 22d70fd7a5..5aac580b33 100644 --- a/steering_controllers_library/test/test_steering_controllers_library.hpp +++ b/steering_controllers_library/test/test_steering_controllers_library.hpp @@ -70,7 +70,8 @@ class TestableSteeringControllersLibrary : public steering_controllers_library::SteeringControllersLibrary { FRIEND_TEST(SteeringControllersLibraryTest, check_exported_interfaces); - FRIEND_TEST(SteeringControllersLibraryTest, test_both_update_methods_for_ref_timeout); + FRIEND_TEST(SteeringControllersLibraryTest, test_position_feedback_ref_timeout); + FRIEND_TEST(SteeringControllersLibraryTest, test_velocity_feedback_ref_timeout); public: controller_interface::CallbackReturn on_configure( diff --git a/tricycle_steering_controller/test/test_tricycle_steering_controller.cpp b/tricycle_steering_controller/test/test_tricycle_steering_controller.cpp index f0d2f6d2db..8096fd980a 100644 --- a/tricycle_steering_controller/test/test_tricycle_steering_controller.cpp +++ b/tricycle_steering_controller/test/test_tricycle_steering_controller.cpp @@ -96,13 +96,13 @@ TEST_F(TricycleSteeringControllerTest, activate_success) ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); // check that the message is reset - auto msg = controller_->input_ref_.readFromNonRT(); - EXPECT_TRUE(std::isnan((*msg)->twist.linear.x)); - EXPECT_TRUE(std::isnan((*msg)->twist.linear.y)); - EXPECT_TRUE(std::isnan((*msg)->twist.linear.z)); - EXPECT_TRUE(std::isnan((*msg)->twist.angular.x)); - EXPECT_TRUE(std::isnan((*msg)->twist.angular.y)); - EXPECT_TRUE(std::isnan((*msg)->twist.angular.z)); + auto msg = controller_->input_ref_.get(); + EXPECT_TRUE(std::isnan(msg.twist.linear.x)); + EXPECT_TRUE(std::isnan(msg.twist.linear.y)); + EXPECT_TRUE(std::isnan(msg.twist.linear.z)); + EXPECT_TRUE(std::isnan(msg.twist.angular.x)); + EXPECT_TRUE(std::isnan(msg.twist.angular.y)); + EXPECT_TRUE(std::isnan(msg.twist.angular.z)); } TEST_F(TricycleSteeringControllerTest, update_success) @@ -154,11 +154,11 @@ TEST_F(TricycleSteeringControllerTest, test_update_logic) ASSERT_FALSE(controller_->is_in_chained_mode()); // set command statically - std::shared_ptr msg = std::make_shared(); - msg->header.stamp = controller_->get_node()->now(); - msg->twist.linear.x = 0.1; - msg->twist.angular.z = 0.2; - controller_->input_ref_.writeFromNonRT(msg); + ControllerReferenceMsg msg; + msg.header.stamp = controller_->get_node()->now(); + msg.twist.linear.x = 0.1; + msg.twist.angular.z = 0.2; + controller_->input_ref_.set(msg); ASSERT_EQ( controller_->update(rclcpp::Time(0, 0, RCL_ROS_TIME), rclcpp::Duration::from_seconds(0.01)), @@ -174,7 +174,7 @@ TEST_F(TricycleSteeringControllerTest, test_update_logic) controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); - EXPECT_FALSE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); + EXPECT_FALSE(std::isnan(controller_->input_ref_.get().twist.linear.x)); EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size()); for (const auto & interface : controller_->reference_interfaces_) { @@ -211,7 +211,7 @@ TEST_F(TricycleSteeringControllerTest, test_update_logic_chained) controller_->command_interfaces_[CMD_STEER_WHEEL].get_optional().value(), 1.4179821977774734, COMMON_THRESHOLD); - EXPECT_TRUE(std::isnan((*(controller_->input_ref_.readFromRT()))->twist.linear.x)); + EXPECT_TRUE(std::isnan(controller_->input_ref_.get().twist.linear.x)); EXPECT_EQ(controller_->reference_interfaces_.size(), joint_reference_interfaces_.size()); for (const auto & interface : controller_->reference_interfaces_) { @@ -235,8 +235,9 @@ TEST_F(TricycleSteeringControllerTest, receive_message_and_publish_updated_statu ControllerStateMsg msg; subscribe_and_get_messages(msg); - EXPECT_EQ(msg.linear_velocity_command[STATE_TRACTION_RIGHT_WHEEL], 1.1); - EXPECT_EQ(msg.linear_velocity_command[STATE_TRACTION_LEFT_WHEEL], 3.3); + // never received a valid command, linear velocity should have been reset + EXPECT_EQ(msg.linear_velocity_command[STATE_TRACTION_RIGHT_WHEEL], 0.0); + EXPECT_EQ(msg.linear_velocity_command[STATE_TRACTION_LEFT_WHEEL], 0.0); EXPECT_EQ(msg.steering_angle_command[0], 2.2); publish_commands(); diff --git a/velocity_controllers/test/test_joint_group_velocity_controller.cpp b/velocity_controllers/test/test_joint_group_velocity_controller.cpp index 880f664141..9d7a5f2b19 100644 --- a/velocity_controllers/test/test_joint_group_velocity_controller.cpp +++ b/velocity_controllers/test/test_joint_group_velocity_controller.cpp @@ -111,9 +111,9 @@ TEST_F(JointGroupVelocityControllerTest, CommandSuccessTest) ASSERT_EQ(joint_3_cmd_.get_optional().value(), 3.1); // send command - auto command_ptr = std::make_shared(); - command_ptr->data = {10.0, 20.0, 30.0}; - controller_->rt_command_ptr_.writeFromNonRT(command_ptr); + forward_command_controller::CmdType command; + command.data = {10.0, 20.0, 30.0}; + controller_->rt_command_.set(command); // update successful, command received ASSERT_EQ( @@ -133,9 +133,9 @@ TEST_F(JointGroupVelocityControllerTest, WrongCommandCheckTest) ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); // send command with wrong number of joints - auto command_ptr = std::make_shared(); - command_ptr->data = {10.0, 20.0}; - controller_->rt_command_ptr_.writeFromNonRT(command_ptr); + forward_command_controller::CmdType command; + command.data = {10.0, 20.0}; + controller_->rt_command_.set(command); // update failed, command size does not match number of joints ASSERT_EQ( From e7124c382da53a5fa9e860404b4b242c0973762c Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 19:29:44 +0200 Subject: [PATCH 090/108] Update API for realtime publisher (backport #1830) (#1944) --- README.md | 2 +- .../admittance_controller.hpp | 1 + .../src/admittance_controller.cpp | 12 +-- .../diff_drive_controller.hpp | 3 + .../src/diff_drive_controller.cpp | 55 ++++++------ .../src/force_torque_sensor_broadcaster.cpp | 24 ++--- .../gpio_command_controller.hpp | 1 + .../src/gpio_command_controller.cpp | 28 +++--- .../gps_sensor_broadcaster.hpp | 3 + .../src/gps_sensor_broadcaster.cpp | 18 ++-- .../test/test_imu_sensor_broadcaster.cpp | 1 - .../joint_state_broadcaster.hpp | 2 + .../src/joint_state_broadcaster.cpp | 73 ++++++++------- .../test/test_joint_state_broadcaster.cpp | 78 +++++++--------- .../joint_trajectory_controller.hpp | 1 + .../src/joint_trajectory_controller.cpp | 59 ++++++------ .../mecanum_drive_controller.hpp | 3 + .../src/mecanum_drive_controller.cpp | 85 ++++++++---------- .../test/test_mecanum_drive_controller.cpp | 12 +-- .../test/test_mecanum_drive_controller.hpp | 17 ++-- .../include/pid_controller/pid_controller.hpp | 1 + pid_controller/src/pid_controller.cpp | 29 +++--- .../pose_broadcaster/pose_broadcaster.hpp | 2 + pose_broadcaster/src/pose_broadcaster.cpp | 30 +++---- .../range_sensor_broadcaster.hpp | 1 + .../src/range_sensor_broadcaster.cpp | 22 +++-- .../steering_controllers_library.hpp | 3 + .../src/steering_controllers_library.cpp | 89 ++++++++----------- .../tricycle_controller.hpp | 3 + .../src/tricycle_controller.cpp | 56 ++++++------ 30 files changed, 327 insertions(+), 387 deletions(-) diff --git a/README.md b/README.md index fe82c65629..4a0c7916b1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # ros2_controllers [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -[![codecov](https://codecov.io/gh/ros-controls/ros2_controllers/graph/badge.svg?token=KSdY0tsHm6)](https://codecov.io/gh/ros-controls/ros2_controllers) +[![codecov](https://codecov.io/gh/ros-controls/ros2_controllers/branch/jazzy/graph/badge.svg?token=KSdY0tsHm6)](https://codecov.io/gh/ros-controls/ros2_controllers) Commonly used and generalized controllers for ros2-control framework that are ready to use with many robots, MoveIt2 and Nav2. diff --git a/admittance_controller/include/admittance_controller/admittance_controller.hpp b/admittance_controller/include/admittance_controller/admittance_controller.hpp index 47c9fd514a..51da1fc848 100644 --- a/admittance_controller/include/admittance_controller/admittance_controller.hpp +++ b/admittance_controller/include/admittance_controller/admittance_controller.hpp @@ -130,6 +130,7 @@ class AdmittanceController : public controller_interface::ChainableControllerInt input_joint_command_; realtime_tools::RealtimeThreadSafeBox input_wrench_command_; std::unique_ptr> state_publisher_; + ControllerStateMsg state_msg_; // save the last commands in case of unable to get value from box trajectory_msgs::msg::JointTrajectoryPoint joint_command_msg_; diff --git a/admittance_controller/src/admittance_controller.cpp b/admittance_controller/src/admittance_controller.cpp index d3e1037d22..e9bc609f48 100644 --- a/admittance_controller/src/admittance_controller.cpp +++ b/admittance_controller/src/admittance_controller.cpp @@ -336,9 +336,7 @@ controller_interface::CallbackReturn AdmittanceController::on_configure( std::make_unique>(s_publisher_); // Initialize state message - state_publisher_->lock(); - state_publisher_->msg_ = admittance_->get_controller_state(); - state_publisher_->unlock(); + state_msg_ = admittance_->get_controller_state(); // Initialize FTS semantic semantic_component force_torque_sensor_ = std::make_unique( @@ -492,9 +490,11 @@ controller_interface::return_type AdmittanceController::update_and_write_command write_state_to_hardware(reference_admittance_); // Publish controller state - state_publisher_->lock(); - state_publisher_->msg_ = admittance_->get_controller_state(); - state_publisher_->unlockAndPublish(); + if (state_publisher_) + { + state_msg_ = admittance_->get_controller_state(); + state_publisher_->try_publish(state_msg_); + } return controller_interface::return_type::OK; } diff --git a/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp b/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp index 0ca1d023ec..fca6e30039 100644 --- a/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp +++ b/diff_drive_controller/include/diff_drive_controller/diff_drive_controller.hpp @@ -113,11 +113,13 @@ class DiffDriveController : public controller_interface::ChainableControllerInte std::shared_ptr> odometry_publisher_ = nullptr; std::shared_ptr> realtime_odometry_publisher_ = nullptr; + nav_msgs::msg::Odometry odometry_message_; std::shared_ptr> odometry_transform_publisher_ = nullptr; std::shared_ptr> realtime_odometry_transform_publisher_ = nullptr; + tf2_msgs::msg::TFMessage odometry_transform_message_; bool subscriber_is_active_ = false; rclcpp::Subscription::SharedPtr velocity_command_subscriber_ = nullptr; @@ -136,6 +138,7 @@ class DiffDriveController : public controller_interface::ChainableControllerInte std::shared_ptr> limited_velocity_publisher_ = nullptr; std::shared_ptr> realtime_limited_velocity_publisher_ = nullptr; + TwistStamped limited_velocity_message_; rclcpp::Time previous_update_timestamp_{0}; diff --git a/diff_drive_controller/src/diff_drive_controller.cpp b/diff_drive_controller/src/diff_drive_controller.cpp index 1c808a7be2..f63f7126d9 100644 --- a/diff_drive_controller/src/diff_drive_controller.cpp +++ b/diff_drive_controller/src/diff_drive_controller.cpp @@ -231,24 +231,23 @@ controller_interface::return_type DiffDriveController::update_and_write_commands if (should_publish) { - if (realtime_odometry_publisher_->trylock()) + if (realtime_odometry_publisher_) { - auto & odometry_message = realtime_odometry_publisher_->msg_; - odometry_message.header.stamp = time; - odometry_message.pose.pose.position.x = odometry_.getX(); - odometry_message.pose.pose.position.y = odometry_.getY(); - odometry_message.pose.pose.orientation.x = orientation.x(); - odometry_message.pose.pose.orientation.y = orientation.y(); - odometry_message.pose.pose.orientation.z = orientation.z(); - odometry_message.pose.pose.orientation.w = orientation.w(); - odometry_message.twist.twist.linear.x = odometry_.getLinear(); - odometry_message.twist.twist.angular.z = odometry_.getAngular(); - realtime_odometry_publisher_->unlockAndPublish(); + odometry_message_.header.stamp = time; + odometry_message_.pose.pose.position.x = odometry_.getX(); + odometry_message_.pose.pose.position.y = odometry_.getY(); + odometry_message_.pose.pose.orientation.x = orientation.x(); + odometry_message_.pose.pose.orientation.y = orientation.y(); + odometry_message_.pose.pose.orientation.z = orientation.z(); + odometry_message_.pose.pose.orientation.w = orientation.w(); + odometry_message_.twist.twist.linear.x = odometry_.getLinear(); + odometry_message_.twist.twist.angular.z = odometry_.getAngular(); + realtime_odometry_publisher_->try_publish(odometry_message_); } - if (params_.enable_odom_tf && realtime_odometry_transform_publisher_->trylock()) + if (params_.enable_odom_tf && realtime_odometry_transform_publisher_) { - auto & transform = realtime_odometry_transform_publisher_->msg_.transforms.front(); + auto & transform = odometry_transform_message_.transforms.front(); transform.header.stamp = time; transform.transform.translation.x = odometry_.getX(); transform.transform.translation.y = odometry_.getY(); @@ -256,7 +255,7 @@ controller_interface::return_type DiffDriveController::update_and_write_commands transform.transform.rotation.y = orientation.y(); transform.transform.rotation.z = orientation.z(); transform.transform.rotation.w = orientation.w(); - realtime_odometry_transform_publisher_->unlockAndPublish(); + realtime_odometry_transform_publisher_->try_publish(odometry_transform_message_); } } @@ -271,17 +270,16 @@ controller_interface::return_type DiffDriveController::update_and_write_commands previous_two_commands_.push({{linear_command, angular_command}}); // Publish limited velocity - if (publish_limited_velocity_ && realtime_limited_velocity_publisher_->trylock()) + if (publish_limited_velocity_ && realtime_limited_velocity_publisher_) { - auto & limited_velocity_command = realtime_limited_velocity_publisher_->msg_; - limited_velocity_command.header.stamp = time; - limited_velocity_command.twist.linear.x = linear_command; - limited_velocity_command.twist.linear.y = 0.0; - limited_velocity_command.twist.linear.z = 0.0; - limited_velocity_command.twist.angular.x = 0.0; - limited_velocity_command.twist.angular.y = 0.0; - limited_velocity_command.twist.angular.z = angular_command; - realtime_limited_velocity_publisher_->unlockAndPublish(); + limited_velocity_message_.header.stamp = time; + limited_velocity_message_.twist.linear.x = linear_command; + limited_velocity_message_.twist.linear.y = 0.0; + limited_velocity_message_.twist.linear.z = 0.0; + limited_velocity_message_.twist.angular.x = 0.0; + limited_velocity_message_.twist.angular.y = 0.0; + limited_velocity_message_.twist.angular.z = angular_command; + realtime_limited_velocity_publisher_->try_publish(limited_velocity_message_); } // Compute wheels velocities: @@ -531,10 +529,9 @@ controller_interface::CallbackReturn DiffDriveController::on_configure( odometry_transform_publisher_); // keeping track of odom and base_link transforms only - auto & odometry_transform_message = realtime_odometry_transform_publisher_->msg_; - odometry_transform_message.transforms.resize(1); - odometry_transform_message.transforms.front().header.frame_id = odom_frame_id; - odometry_transform_message.transforms.front().child_frame_id = base_frame_id; + odometry_transform_message_.transforms.resize(1); + odometry_transform_message_.transforms.front().header.frame_id = odom_frame_id; + odometry_transform_message_.transforms.front().child_frame_id = base_frame_id; previous_update_timestamp_ = get_node()->get_clock()->now(); return controller_interface::CallbackReturn::SUCCESS; diff --git a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp index 8457a1c09d..114c4466fa 100644 --- a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp @@ -137,17 +137,6 @@ controller_interface::CallbackReturn ForceTorqueSensorBroadcaster::on_configure( wrench_raw_.header.frame_id = params_.frame_id; wrench_filtered_.header.frame_id = params_.frame_id; - realtime_raw_publisher_->lock(); - realtime_raw_publisher_->msg_.header.frame_id = params_.frame_id; - realtime_raw_publisher_->unlock(); - - if (has_filter_chain_) - { - realtime_filtered_publisher_->lock(); - realtime_filtered_publisher_->msg_.header.frame_id = params_.frame_id; - realtime_filtered_publisher_->unlock(); - } - RCLCPP_INFO(get_node()->get_logger(), "configure successful"); return controller_interface::CallbackReturn::SUCCESS; } @@ -196,22 +185,19 @@ controller_interface::return_type ForceTorqueSensorBroadcaster::update_and_write this->apply_sensor_offset(params_, wrench_raw_); this->apply_sensor_multiplier(params_, wrench_raw_); - if (realtime_raw_publisher_ && realtime_raw_publisher_->trylock()) + if (realtime_raw_publisher_) { - realtime_raw_publisher_->msg_.header.stamp = time; - realtime_raw_publisher_->msg_.wrench = wrench_raw_.wrench; - realtime_raw_publisher_->unlockAndPublish(); + realtime_raw_publisher_->try_publish(wrench_raw_); } if (has_filter_chain_) { // Filter sensor data, if no filter chain config was specified, wrench_filtered_ = wrench_raw_ auto filtered = filter_chain_->update(wrench_raw_, wrench_filtered_); - if (filtered && realtime_filtered_publisher_ && realtime_filtered_publisher_->trylock()) + if (filtered && realtime_filtered_publisher_) { - realtime_filtered_publisher_->msg_.header.stamp = time; - realtime_filtered_publisher_->msg_.wrench = wrench_filtered_.wrench; - realtime_filtered_publisher_->unlockAndPublish(); + wrench_filtered_.header.stamp = time; + realtime_filtered_publisher_->try_publish(wrench_filtered_); } } diff --git a/gpio_controllers/include/gpio_controllers/gpio_command_controller.hpp b/gpio_controllers/include/gpio_controllers/gpio_command_controller.hpp index f7d75e1c20..561abcce91 100644 --- a/gpio_controllers/include/gpio_controllers/gpio_command_controller.hpp +++ b/gpio_controllers/include/gpio_controllers/gpio_command_controller.hpp @@ -100,6 +100,7 @@ class GpioCommandController : public controller_interface::ControllerInterface std::shared_ptr> gpio_state_publisher_{}; std::shared_ptr> realtime_gpio_state_publisher_{}; + StateType gpio_state_msg_; std::shared_ptr param_listener_{}; gpio_command_controller_parameters::Params params_; diff --git a/gpio_controllers/src/gpio_command_controller.cpp b/gpio_controllers/src/gpio_command_controller.cpp index 34222928c3..f2768f07cf 100644 --- a/gpio_controllers/src/gpio_command_controller.cpp +++ b/gpio_controllers/src/gpio_command_controller.cpp @@ -252,19 +252,18 @@ void GpioCommandController::store_state_interface_types() void GpioCommandController::initialize_gpio_state_msg() { - auto & gpio_state_msg = realtime_gpio_state_publisher_->msg_; - gpio_state_msg.header.stamp = get_node()->now(); - gpio_state_msg.interface_groups.resize(params_.gpios.size()); - gpio_state_msg.interface_values.resize(params_.gpios.size()); + gpio_state_msg_.header.stamp = get_node()->now(); + gpio_state_msg_.interface_groups.resize(params_.gpios.size()); + gpio_state_msg_.interface_values.resize(params_.gpios.size()); for (std::size_t gpio_index = 0; gpio_index < params_.gpios.size(); ++gpio_index) { const auto gpio_name = params_.gpios[gpio_index]; - gpio_state_msg.interface_groups[gpio_index] = gpio_name; - gpio_state_msg.interface_values[gpio_index].interface_names = + gpio_state_msg_.interface_groups[gpio_index] = gpio_name; + gpio_state_msg_.interface_values[gpio_index].interface_names = get_gpios_state_interfaces_names(gpio_name); - gpio_state_msg.interface_values[gpio_index].values = std::vector( - gpio_state_msg.interface_values[gpio_index].interface_names.size(), + gpio_state_msg_.interface_values[gpio_index].values = std::vector( + gpio_state_msg_.interface_values[gpio_index].interface_names.size(), std::numeric_limits::quiet_NaN()); } } @@ -391,24 +390,23 @@ void GpioCommandController::apply_command( void GpioCommandController::update_gpios_states() { - if (!realtime_gpio_state_publisher_ || !realtime_gpio_state_publisher_->trylock()) + if (!realtime_gpio_state_publisher_) { return; } - auto & gpio_state_msg = realtime_gpio_state_publisher_->msg_; - gpio_state_msg.header.stamp = get_node()->now(); - for (std::size_t gpio_index = 0; gpio_index < gpio_state_msg.interface_groups.size(); + gpio_state_msg_.header.stamp = get_node()->now(); + for (std::size_t gpio_index = 0; gpio_index < gpio_state_msg_.interface_groups.size(); ++gpio_index) { for (std::size_t interface_index = 0; - interface_index < gpio_state_msg.interface_values[gpio_index].interface_names.size(); + interface_index < gpio_state_msg_.interface_values[gpio_index].interface_names.size(); ++interface_index) { - apply_state_value(gpio_state_msg, gpio_index, interface_index); + apply_state_value(gpio_state_msg_, gpio_index, interface_index); } } - realtime_gpio_state_publisher_->unlockAndPublish(); + realtime_gpio_state_publisher_->try_publish(gpio_state_msg_); } void GpioCommandController::apply_state_value( diff --git a/gps_sensor_broadcaster/include/gps_sensor_broadcaster/gps_sensor_broadcaster.hpp b/gps_sensor_broadcaster/include/gps_sensor_broadcaster/gps_sensor_broadcaster.hpp index 35c88073aa..2ef100af25 100644 --- a/gps_sensor_broadcaster/include/gps_sensor_broadcaster/gps_sensor_broadcaster.hpp +++ b/gps_sensor_broadcaster/include/gps_sensor_broadcaster/gps_sensor_broadcaster.hpp @@ -57,8 +57,11 @@ class GPSSensorBroadcaster : public controller_interface::ControllerInterface callback_return_type setup_publisher(); GPSSensorVariant gps_sensor_; + rclcpp::Publisher::SharedPtr sensor_state_publisher_; std::unique_ptr realtime_publisher_; + sensor_msgs::msg::NavSatFix state_message_; + std::shared_ptr param_listener_{}; gps_sensor_broadcaster::Params params_; std::vector state_names_; diff --git a/gps_sensor_broadcaster/src/gps_sensor_broadcaster.cpp b/gps_sensor_broadcaster/src/gps_sensor_broadcaster.cpp index 4a97dbcf1a..0856987f72 100644 --- a/gps_sensor_broadcaster/src/gps_sensor_broadcaster.cpp +++ b/gps_sensor_broadcaster/src/gps_sensor_broadcaster.cpp @@ -82,10 +82,8 @@ callback_return_type GPSSensorBroadcaster::setup_publisher() sensor_state_publisher_ = get_node()->create_publisher( "~/gps/fix", rclcpp::SystemDefaultsQoS()); realtime_publisher_ = std::make_unique(sensor_state_publisher_); - realtime_publisher_->lock(); - realtime_publisher_->msg_.header.frame_id = params_.frame_id; + state_message_.header.frame_id = params_.frame_id; setup_covariance(); - realtime_publisher_->unlock(); return callback_return_type::SUCCESS; } @@ -102,14 +100,14 @@ void GPSSensorBroadcaster::setup_covariance() { if (params_.read_covariance_from_interface) { - realtime_publisher_->msg_.position_covariance_type = COVARIANCE_TYPE_DIAGONAL_KNOWN; + state_message_.position_covariance_type = COVARIANCE_TYPE_DIAGONAL_KNOWN; return; } for (size_t i = 0; i < COVARIANCE_3x3_SIZE; ++i) { - realtime_publisher_->msg_.position_covariance[i] = params_.static_position_covariance[i]; - realtime_publisher_->msg_.position_covariance_type = COVARIANCE_TYPE_KNOWN; + state_message_.position_covariance[i] = params_.static_position_covariance[i]; + state_message_.position_covariance_type = COVARIANCE_TYPE_KNOWN; } } @@ -152,19 +150,19 @@ callback_return_type GPSSensorBroadcaster::on_deactivate(const rclcpp_lifecycle: controller_interface::return_type GPSSensorBroadcaster::update( const rclcpp::Time &, const rclcpp::Duration &) { - if (realtime_publisher_ && realtime_publisher_->trylock()) + if (realtime_publisher_) { - realtime_publisher_->msg_.header.stamp = get_node()->now(); + state_message_.header.stamp = get_node()->now(); std::visit( Visitor{ [this](auto & sensor) { sensor_msgs::msg::NavSatFix message; - sensor.get_values_as_message(realtime_publisher_->msg_); + sensor.get_values_as_message(state_message_); }, [](std::monostate &) {}}, gps_sensor_); - realtime_publisher_->unlockAndPublish(); + realtime_publisher_->try_publish(state_message_); } return controller_interface::return_type::OK; } diff --git a/imu_sensor_broadcaster/test/test_imu_sensor_broadcaster.cpp b/imu_sensor_broadcaster/test/test_imu_sensor_broadcaster.cpp index 67cf31f8a5..9cd3219495 100644 --- a/imu_sensor_broadcaster/test/test_imu_sensor_broadcaster.cpp +++ b/imu_sensor_broadcaster/test/test_imu_sensor_broadcaster.cpp @@ -35,7 +35,6 @@ using testing::SizeIs; namespace { constexpr auto NODE_SUCCESS = controller_interface::CallbackReturn::SUCCESS; -constexpr auto NODE_ERROR = controller_interface::CallbackReturn::ERROR; } // namespace void IMUSensorBroadcasterTest::SetUpTestCase() {} diff --git a/joint_state_broadcaster/include/joint_state_broadcaster/joint_state_broadcaster.hpp b/joint_state_broadcaster/include/joint_state_broadcaster/joint_state_broadcaster.hpp index 85d2b93765..05d2334d0b 100644 --- a/joint_state_broadcaster/include/joint_state_broadcaster/joint_state_broadcaster.hpp +++ b/joint_state_broadcaster/include/joint_state_broadcaster/joint_state_broadcaster.hpp @@ -105,6 +105,7 @@ class JointStateBroadcaster : public controller_interface::ControllerInterface std::shared_ptr> joint_state_publisher_; std::shared_ptr> realtime_joint_state_publisher_; + sensor_msgs::msg::JointState joint_state_msg_; // For the DynamicJointState format, we use a map to buffer values in for easier lookup // This allows to preserve whatever order or names/interfaces were initialized. @@ -113,6 +114,7 @@ class JointStateBroadcaster : public controller_interface::ControllerInterface dynamic_joint_state_publisher_; std::shared_ptr> realtime_dynamic_joint_state_publisher_; + control_msgs::msg::DynamicJointState dynamic_joint_state_msg_; urdf::Model model_; bool is_model_loaded_ = false; diff --git a/joint_state_broadcaster/src/joint_state_broadcaster.cpp b/joint_state_broadcaster/src/joint_state_broadcaster.cpp index b88971a3a6..bdcc1d1c82 100644 --- a/joint_state_broadcaster/src/joint_state_broadcaster.cpp +++ b/joint_state_broadcaster/src/joint_state_broadcaster.cpp @@ -175,11 +175,10 @@ controller_interface::CallbackReturn JointStateBroadcaster::on_configure( (params_.joints.empty() ? model_.joints_.size() : params_.joints.size()) + params_.extra_joints.size(); joint_names_.reserve(max_joints_size); - auto & joint_state_msg = realtime_joint_state_publisher_->msg_; - joint_state_msg.name.reserve(max_joints_size); - joint_state_msg.position.reserve(max_joints_size); - joint_state_msg.velocity.reserve(max_joints_size); - joint_state_msg.effort.reserve(max_joints_size); + joint_state_msg_.name.reserve(max_joints_size); + joint_state_msg_.position.reserve(max_joints_size); + joint_state_msg_.velocity.reserve(max_joints_size); + joint_state_msg_.effort.reserve(max_joints_size); frame_id_ = params_.frame_id; if (frame_id_.empty()) @@ -314,16 +313,15 @@ void JointStateBroadcaster::init_joint_state_msg() { const size_t num_joints = joint_names_.size(); - /// @note joint_state_msg publishes position, velocity and effort for all joints, + /// @note joint_state_msg_ publishes position, velocity and effort for all joints, /// with at least one of these interfaces, the rest are omitted from this message // default initialization for joint state message - auto & joint_state_msg = realtime_joint_state_publisher_->msg_; - joint_state_msg.header.frame_id = frame_id_; - joint_state_msg.name = joint_names_; - joint_state_msg.position.resize(num_joints, kUninitializedValue); - joint_state_msg.velocity.resize(num_joints, kUninitializedValue); - joint_state_msg.effort.resize(num_joints, kUninitializedValue); + joint_state_msg_.header.frame_id = frame_id_; + joint_state_msg_.name = joint_names_; + joint_state_msg_.position.resize(num_joints, kUninitializedValue); + joint_state_msg_.velocity.resize(num_joints, kUninitializedValue); + joint_state_msg_.effort.resize(num_joints, kUninitializedValue); // save joint state data auto get_address = @@ -352,36 +350,36 @@ void JointStateBroadcaster::init_joint_state_msg() void JointStateBroadcaster::init_dynamic_joint_state_msg() { - auto & dynamic_joint_state_msg = realtime_dynamic_joint_state_publisher_->msg_; - dynamic_joint_state_msg.header.frame_id = frame_id_; - dynamic_joint_state_msg.joint_names.clear(); - dynamic_joint_state_msg.interface_values.clear(); + dynamic_joint_state_msg_.header.frame_id = frame_id_; + dynamic_joint_state_msg_.joint_names.clear(); + dynamic_joint_state_msg_.interface_values.clear(); for (const auto & name_ifv : name_if_value_mapping_) { const auto & name = name_ifv.first; const auto & interfaces_and_values = name_ifv.second; - dynamic_joint_state_msg.joint_names.push_back(name); + dynamic_joint_state_msg_.joint_names.push_back(name); control_msgs::msg::InterfaceValue if_value; for (const auto & interface_and_value : interfaces_and_values) { if_value.interface_names.emplace_back(interface_and_value.first); if_value.values.emplace_back(kUninitializedValue); } - dynamic_joint_state_msg.interface_values.emplace_back(if_value); + dynamic_joint_state_msg_.interface_values.emplace_back(if_value); } // save dynamic joint state data dynamic_joint_states_data_.clear(); - const auto & msg = realtime_dynamic_joint_state_publisher_->msg_; - for (auto ji = 0u; ji < msg.joint_names.size(); ++ji) + for (auto ji = 0u; ji < dynamic_joint_state_msg_.joint_names.size(); ++ji) { dynamic_joint_states_data_.push_back(std::vector()); - const auto & name = msg.joint_names[ji]; + const auto & name = dynamic_joint_state_msg_.joint_names[ji]; - for (auto ii = 0u; ii < msg.interface_values[ji].interface_names.size(); ++ii) + for (auto ii = 0u; ii < dynamic_joint_state_msg_.interface_values[ji].interface_names.size(); + ++ii) { - const auto & interface_name = msg.interface_values[ji].interface_names[ii]; + const auto & interface_name = + dynamic_joint_state_msg_.interface_values[ji].interface_names[ii]; dynamic_joint_states_data_[ji].push_back(&name_if_value_mapping_[name][interface_name]); } } @@ -421,34 +419,33 @@ controller_interface::return_type JointStateBroadcaster::update( } } - if (realtime_joint_state_publisher_ && realtime_joint_state_publisher_->trylock()) + if (realtime_joint_state_publisher_) { - auto & joint_state_msg = realtime_joint_state_publisher_->msg_; - - joint_state_msg.header.stamp = time; + joint_state_msg_.header.stamp = time; // update joint state message and dynamic joint state message for (size_t i = 0; i < joint_names_.size(); ++i) { - joint_state_msg.position[i] = joint_states_data_[i].position_; - joint_state_msg.velocity[i] = joint_states_data_[i].velocity_; - joint_state_msg.effort[i] = joint_states_data_[i].effort_; + joint_state_msg_.position[i] = joint_states_data_[i].position_; + joint_state_msg_.velocity[i] = joint_states_data_[i].velocity_; + joint_state_msg_.effort[i] = joint_states_data_[i].effort_; } - realtime_joint_state_publisher_->unlockAndPublish(); + realtime_joint_state_publisher_->try_publish(joint_state_msg_); } - if (realtime_dynamic_joint_state_publisher_ && realtime_dynamic_joint_state_publisher_->trylock()) + if (realtime_dynamic_joint_state_publisher_) { - auto & msg = realtime_dynamic_joint_state_publisher_->msg_; - msg.header.stamp = time; - for (auto ji = 0u; ji < msg.joint_names.size(); ++ji) + dynamic_joint_state_msg_.header.stamp = time; + for (auto ji = 0u; ji < dynamic_joint_state_msg_.joint_names.size(); ++ji) { - for (auto ii = 0u; ii < msg.interface_values[ji].interface_names.size(); ++ii) + for (auto ii = 0u; ii < dynamic_joint_state_msg_.interface_values[ji].interface_names.size(); + ++ii) { - msg.interface_values[ji].values[ii] = *dynamic_joint_states_data_[ji][ii]; + dynamic_joint_state_msg_.interface_values[ji].values[ii] = + *dynamic_joint_states_data_[ji][ii]; } } - realtime_dynamic_joint_state_publisher_->unlockAndPublish(); + realtime_dynamic_joint_state_publisher_->try_publish(dynamic_joint_state_msg_); } return controller_interface::return_type::OK; diff --git a/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp b/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp index fc3d430a02..8946f4ea55 100644 --- a/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp +++ b/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp @@ -177,7 +177,7 @@ TEST_F(JointStateBroadcasterTest, ActivateEmptyTest) ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_names_)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); @@ -185,8 +185,7 @@ TEST_F(JointStateBroadcasterTest, ActivateEmptyTest) ASSERT_THAT(joint_state_msg.effort, SizeIs(NUM_JOINTS)); // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); @@ -229,7 +228,7 @@ TEST_F(JointStateBroadcasterTest, ReactivateTheControllerWithDifferentInterfaces ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_names_)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); @@ -237,8 +236,7 @@ TEST_F(JointStateBroadcasterTest, ReactivateTheControllerWithDifferentInterfaces ASSERT_THAT(joint_state_msg.effort, SizeIs(NUM_JOINTS)); // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); @@ -276,7 +274,7 @@ TEST_F(JointStateBroadcasterTest, ReactivateTheControllerWithDifferentInterfaces ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & new_joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & new_joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_EQ(new_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(new_joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(new_joint_state_msg.position, SizeIs(NUM_JOINTS_WITH_ONE_DEACTIVATED)); @@ -284,8 +282,7 @@ TEST_F(JointStateBroadcasterTest, ReactivateTheControllerWithDifferentInterfaces ASSERT_THAT(new_joint_state_msg.effort, SizeIs(NUM_JOINTS_WITH_ONE_DEACTIVATED)); // dynamic joint state initialized - const auto & new_dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & new_dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(new_dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(new_dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS_WITH_ONE_DEACTIVATED)); ASSERT_THAT( @@ -328,7 +325,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithoutJointsParameter) ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_names_)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); @@ -336,8 +333,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithoutJointsParameter) ASSERT_THAT(joint_state_msg.effort, SizeIs(NUM_JOINTS)); // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); @@ -380,15 +376,14 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithoutJointsParameterInvalidURDF) ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_names_)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.effort, SizeIs(NUM_JOINTS)); // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(joint_names_)); @@ -435,15 +430,14 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithoutJointsParameterWithRobotDes ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_in_urdf)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.effort, SizeIs(NUM_JOINTS)); // dynamic joint state initialized and it will have the data of all the interfaces - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(joint_names_.size())); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(joint_names_.size())); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(joint_names_)); @@ -489,15 +483,14 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithJointsAndNoInterfaces) ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_in_urdf)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.effort, SizeIs(NUM_JOINTS)); // dynamic joint state initialized and it will have the data of all the interfaces - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(joint_names_.size())); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(joint_names_.size())); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(joint_names_)); @@ -542,15 +535,14 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithJointsAndInterfaces) ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_THAT(joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.velocity, SizeIs(NUM_JOINTS)); ASSERT_THAT(joint_state_msg.effort, SizeIs(NUM_JOINTS)); // dynamic joint state initialized and it will have the data of all the interfaces - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.joint_names, ElementsAreArray(JOINT_NAMES)); @@ -585,7 +577,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithoutInterfacesParameter) ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(joint_names_)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); @@ -593,8 +585,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestWithoutInterfacesParameter) ASSERT_THAT(joint_state_msg.effort, SizeIs(NUM_JOINTS)); // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); @@ -636,7 +627,7 @@ TEST_F(JointStateBroadcasterTest, ActivateDeactivateTestTwoJointsOneInterface) ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); @@ -652,8 +643,7 @@ TEST_F(JointStateBroadcasterTest, ActivateDeactivateTestTwoJointsOneInterface) } // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); @@ -702,7 +692,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestOneJointTwoInterfaces) ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); @@ -714,8 +704,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestOneJointTwoInterfaces) } // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); @@ -780,7 +769,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestTwoJointTwoInterfacesOneMissing) ASSERT_TRUE(state_broadcaster_->realtime_dynamic_joint_state_publisher_); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); @@ -794,8 +783,7 @@ TEST_F(JointStateBroadcasterTest, ActivateTestTwoJointTwoInterfacesOneMissing) } // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); @@ -829,7 +817,7 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceWithoutMapping) EXPECT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::INDIVIDUAL); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, SizeIs(0)); ASSERT_THAT(joint_state_msg.position, SizeIs(0)); @@ -837,8 +825,7 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceWithoutMapping) ASSERT_THAT(joint_state_msg.effort, SizeIs(0)); // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); @@ -876,7 +863,7 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceMapping) EXPECT_EQ(state_if_conf.type, controller_interface::interface_configuration_type::INDIVIDUAL); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(JOINT_NAMES)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); @@ -892,8 +879,7 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceMapping) } // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); @@ -938,8 +924,7 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceMappingUpdate) } // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); ASSERT_THAT(dynamic_joint_state_msg.interface_values, SizeIs(NUM_JOINTS)); @@ -1259,7 +1244,7 @@ TEST_F(JointStateBroadcasterTest, ExtraJointStatePublishTest) const size_t NUM_JOINTS = all_joint_names.size(); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; + const auto & joint_state_msg = state_broadcaster_->joint_state_msg_; ASSERT_EQ(joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(joint_state_msg.name, ElementsAreArray(all_joint_names)); ASSERT_THAT(joint_state_msg.position, SizeIs(NUM_JOINTS)); @@ -1267,8 +1252,7 @@ TEST_F(JointStateBroadcasterTest, ExtraJointStatePublishTest) ASSERT_THAT(joint_state_msg.effort, SizeIs(NUM_JOINTS)); // dynamic joint state initialized - const auto & dynamic_joint_state_msg = - state_broadcaster_->realtime_dynamic_joint_state_publisher_->msg_; + const auto & dynamic_joint_state_msg = state_broadcaster_->dynamic_joint_state_msg_; ASSERT_EQ(dynamic_joint_state_msg.header.frame_id, frame_id_); ASSERT_THAT(dynamic_joint_state_msg.joint_names, SizeIs(NUM_JOINTS)); } diff --git a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp index 4c6717d338..560a726e7d 100644 --- a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp +++ b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp @@ -166,6 +166,7 @@ class JointTrajectoryController : public controller_interface::ControllerInterfa using StatePublisherPtr = std::unique_ptr; rclcpp::Publisher::SharedPtr publisher_; StatePublisherPtr state_publisher_; + ControllerStateMsg state_msg_; using FollowJTrajAction = control_msgs::action::FollowJointTrajectory; using RealtimeGoalHandle = realtime_tools::RealtimeServerGoalHandle; diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index 494ac8b11d..f5630c302e 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -936,42 +936,39 @@ controller_interface::CallbackReturn JointTrajectoryController::on_configure( "~/controller_state", rclcpp::SystemDefaultsQoS()); state_publisher_ = std::make_unique(publisher_); - state_publisher_->lock(); - state_publisher_->msg_.joint_names = params_.joints; - state_publisher_->msg_.reference.positions.resize(dof_); - state_publisher_->msg_.reference.velocities.resize(dof_); - state_publisher_->msg_.reference.accelerations.resize(dof_); - state_publisher_->msg_.feedback.positions.resize(dof_); - state_publisher_->msg_.error.positions.resize(dof_); + state_msg_.joint_names = params_.joints; + state_msg_.reference.positions.resize(dof_); + state_msg_.reference.velocities.resize(dof_); + state_msg_.reference.accelerations.resize(dof_); + state_msg_.feedback.positions.resize(dof_); + state_msg_.error.positions.resize(dof_); if (has_velocity_state_interface_) { - state_publisher_->msg_.feedback.velocities.resize(dof_); - state_publisher_->msg_.error.velocities.resize(dof_); + state_msg_.feedback.velocities.resize(dof_); + state_msg_.error.velocities.resize(dof_); } if (has_acceleration_state_interface_) { - state_publisher_->msg_.feedback.accelerations.resize(dof_); - state_publisher_->msg_.error.accelerations.resize(dof_); + state_msg_.feedback.accelerations.resize(dof_); + state_msg_.error.accelerations.resize(dof_); } if (has_position_command_interface_) { - state_publisher_->msg_.output.positions.resize(dof_); + state_msg_.output.positions.resize(dof_); } if (has_velocity_command_interface_) { - state_publisher_->msg_.output.velocities.resize(dof_); + state_msg_.output.velocities.resize(dof_); } if (has_acceleration_command_interface_) { - state_publisher_->msg_.output.accelerations.resize(dof_); + state_msg_.output.accelerations.resize(dof_); } if (has_effort_command_interface_) { - state_publisher_->msg_.output.effort.resize(dof_); + state_msg_.output.effort.resize(dof_); } - state_publisher_->unlock(); - // action server configuration if (params_.allow_partial_joints_goal) { @@ -1218,30 +1215,30 @@ void JointTrajectoryController::publish_state( const rclcpp::Time & time, const JointTrajectoryPoint & desired_state, const JointTrajectoryPoint & current_state, const JointTrajectoryPoint & state_error) { - if (state_publisher_->trylock()) - { - state_publisher_->msg_.header.stamp = time; - state_publisher_->msg_.reference.positions = desired_state.positions; - state_publisher_->msg_.reference.velocities = desired_state.velocities; - state_publisher_->msg_.reference.accelerations = desired_state.accelerations; - state_publisher_->msg_.feedback.positions = current_state.positions; - state_publisher_->msg_.error.positions = state_error.positions; + if (state_publisher_) + { + state_msg_.header.stamp = time; + state_msg_.reference.positions = desired_state.positions; + state_msg_.reference.velocities = desired_state.velocities; + state_msg_.reference.accelerations = desired_state.accelerations; + state_msg_.feedback.positions = current_state.positions; + state_msg_.error.positions = state_error.positions; if (has_velocity_state_interface_) { - state_publisher_->msg_.feedback.velocities = current_state.velocities; - state_publisher_->msg_.error.velocities = state_error.velocities; + state_msg_.feedback.velocities = current_state.velocities; + state_msg_.error.velocities = state_error.velocities; } if (has_acceleration_state_interface_) { - state_publisher_->msg_.feedback.accelerations = current_state.accelerations; - state_publisher_->msg_.error.accelerations = state_error.accelerations; + state_msg_.feedback.accelerations = current_state.accelerations; + state_msg_.error.accelerations = state_error.accelerations; } if (read_commands_from_command_interfaces(command_current_)) { - state_publisher_->msg_.output = command_current_; + state_msg_.output = command_current_; } - state_publisher_->unlockAndPublish(); + state_publisher_->try_publish(state_msg_); } } diff --git a/mecanum_drive_controller/include/mecanum_drive_controller/mecanum_drive_controller.hpp b/mecanum_drive_controller/include/mecanum_drive_controller/mecanum_drive_controller.hpp index c0edc8c5a2..58b6de04b7 100644 --- a/mecanum_drive_controller/include/mecanum_drive_controller/mecanum_drive_controller.hpp +++ b/mecanum_drive_controller/include/mecanum_drive_controller/mecanum_drive_controller.hpp @@ -122,14 +122,17 @@ class MecanumDriveController : public controller_interface::ChainableControllerI using OdomStatePublisher = realtime_tools::RealtimePublisher; rclcpp::Publisher::SharedPtr odom_s_publisher_; std::unique_ptr rt_odom_state_publisher_; + OdomStateMsg odom_state_msg_; using TfStatePublisher = realtime_tools::RealtimePublisher; rclcpp::Publisher::SharedPtr tf_odom_s_publisher_; std::unique_ptr rt_tf_odom_state_publisher_; + TfStateMsg tf_odom_state_msg_; using ControllerStatePublisher = realtime_tools::RealtimePublisher; rclcpp::Publisher::SharedPtr controller_s_publisher_; std::unique_ptr controller_state_publisher_; + ControllerStateMsg controller_state_msg_; // override methods from ChainableControllerInterface std::vector on_export_reference_interfaces() override; diff --git a/mecanum_drive_controller/src/mecanum_drive_controller.cpp b/mecanum_drive_controller/src/mecanum_drive_controller.cpp index c320b258be..e468c8577b 100644 --- a/mecanum_drive_controller/src/mecanum_drive_controller.cpp +++ b/mecanum_drive_controller/src/mecanum_drive_controller.cpp @@ -167,14 +167,13 @@ controller_interface::CallbackReturn MecanumDriveController::on_configure( const auto odom_frame_id = tf_prefix + params_.odom_frame_id; const auto base_frame_id = tf_prefix + params_.base_frame_id; - rt_odom_state_publisher_->lock(); - rt_odom_state_publisher_->msg_.header.stamp = get_node()->now(); - rt_odom_state_publisher_->msg_.header.frame_id = odom_frame_id; - rt_odom_state_publisher_->msg_.child_frame_id = base_frame_id; - rt_odom_state_publisher_->msg_.pose.pose.position.z = 0; - - auto & pose_covariance = rt_odom_state_publisher_->msg_.pose.covariance; - auto & twist_covariance = rt_odom_state_publisher_->msg_.twist.covariance; + odom_state_msg_.header.stamp = get_node()->now(); + odom_state_msg_.header.frame_id = odom_frame_id; + odom_state_msg_.child_frame_id = base_frame_id; + odom_state_msg_.pose.pose.position.z = 0; + + auto & pose_covariance = odom_state_msg_.pose.covariance; + auto & twist_covariance = odom_state_msg_.twist.covariance; constexpr size_t NUM_DIMENSIONS = 6; for (size_t index = 0; index < 6; ++index) { @@ -182,7 +181,6 @@ controller_interface::CallbackReturn MecanumDriveController::on_configure( pose_covariance[diagonal_index] = params_.pose_covariance_diagonal[index]; twist_covariance[diagonal_index] = params_.twist_covariance_diagonal[index]; } - rt_odom_state_publisher_->unlock(); try { @@ -199,13 +197,11 @@ controller_interface::CallbackReturn MecanumDriveController::on_configure( return controller_interface::CallbackReturn::ERROR; } - rt_tf_odom_state_publisher_->lock(); - rt_tf_odom_state_publisher_->msg_.transforms.resize(1); - rt_tf_odom_state_publisher_->msg_.transforms[0].header.stamp = get_node()->now(); - rt_tf_odom_state_publisher_->msg_.transforms[0].header.frame_id = odom_frame_id; - rt_tf_odom_state_publisher_->msg_.transforms[0].child_frame_id = base_frame_id; - rt_tf_odom_state_publisher_->msg_.transforms[0].transform.translation.z = 0.0; - rt_tf_odom_state_publisher_->unlock(); + tf_odom_state_msg_.transforms.resize(1); + tf_odom_state_msg_.transforms[0].header.stamp = get_node()->now(); + tf_odom_state_msg_.transforms[0].header.frame_id = odom_frame_id; + tf_odom_state_msg_.transforms[0].child_frame_id = base_frame_id; + tf_odom_state_msg_.transforms[0].transform.translation.z = 0.0; try { @@ -225,10 +221,8 @@ controller_interface::CallbackReturn MecanumDriveController::on_configure( return controller_interface::CallbackReturn::ERROR; } - controller_state_publisher_->lock(); - controller_state_publisher_->msg_.header.stamp = get_node()->now(); - controller_state_publisher_->msg_.header.frame_id = odom_frame_id; - controller_state_publisher_->unlock(); + controller_state_msg_.header.stamp = get_node()->now(); + controller_state_msg_.header.frame_id = odom_frame_id; RCLCPP_INFO(get_node()->get_logger(), "MecanumDriveController configured successfully"); @@ -524,42 +518,41 @@ controller_interface::return_type MecanumDriveController::update_and_write_comma orientation.setRPY(0.0, 0.0, odometry_.getRz()); // Populate odom message and publish - if (rt_odom_state_publisher_->trylock()) + if (rt_odom_state_publisher_) { - rt_odom_state_publisher_->msg_.header.stamp = time; - rt_odom_state_publisher_->msg_.pose.pose.position.x = odometry_.getX(); - rt_odom_state_publisher_->msg_.pose.pose.position.y = odometry_.getY(); - rt_odom_state_publisher_->msg_.pose.pose.orientation = tf2::toMsg(orientation); - rt_odom_state_publisher_->msg_.twist.twist.linear.x = odometry_.getVx(); - rt_odom_state_publisher_->msg_.twist.twist.linear.y = odometry_.getVy(); - rt_odom_state_publisher_->msg_.twist.twist.angular.z = odometry_.getWz(); - rt_odom_state_publisher_->unlockAndPublish(); + odom_state_msg_.header.stamp = time; + odom_state_msg_.pose.pose.position.x = odometry_.getX(); + odom_state_msg_.pose.pose.position.y = odometry_.getY(); + odom_state_msg_.pose.pose.orientation = tf2::toMsg(orientation); + odom_state_msg_.twist.twist.linear.x = odometry_.getVx(); + odom_state_msg_.twist.twist.linear.y = odometry_.getVy(); + odom_state_msg_.twist.twist.angular.z = odometry_.getWz(); + rt_odom_state_publisher_->try_publish(odom_state_msg_); } // Publish tf /odom frame - if (params_.enable_odom_tf && rt_tf_odom_state_publisher_->trylock()) + if (params_.enable_odom_tf && rt_tf_odom_state_publisher_) { - rt_tf_odom_state_publisher_->msg_.transforms.front().header.stamp = time; - rt_tf_odom_state_publisher_->msg_.transforms.front().transform.translation.x = odometry_.getX(); - rt_tf_odom_state_publisher_->msg_.transforms.front().transform.translation.y = odometry_.getY(); - rt_tf_odom_state_publisher_->msg_.transforms.front().transform.rotation = - tf2::toMsg(orientation); - rt_tf_odom_state_publisher_->unlockAndPublish(); + tf_odom_state_msg_.transforms.front().header.stamp = time; + tf_odom_state_msg_.transforms.front().transform.translation.x = odometry_.getX(); + tf_odom_state_msg_.transforms.front().transform.translation.y = odometry_.getY(); + tf_odom_state_msg_.transforms.front().transform.rotation = tf2::toMsg(orientation); + rt_tf_odom_state_publisher_->try_publish(tf_odom_state_msg_); } - if (controller_state_publisher_->trylock()) + if (controller_state_publisher_) { - controller_state_publisher_->msg_.header.stamp = get_node()->now(); + controller_state_msg_.header.stamp = get_node()->now(); - controller_state_publisher_->msg_.front_left_wheel_velocity = wheel_front_left_state_vel; - controller_state_publisher_->msg_.front_right_wheel_velocity = wheel_front_right_state_vel; - controller_state_publisher_->msg_.back_right_wheel_velocity = wheel_rear_right_state_vel; - controller_state_publisher_->msg_.back_left_wheel_velocity = wheel_rear_left_state_vel; + controller_state_msg_.front_left_wheel_velocity = wheel_front_left_state_vel; + controller_state_msg_.front_right_wheel_velocity = wheel_front_right_state_vel; + controller_state_msg_.back_right_wheel_velocity = wheel_rear_right_state_vel; + controller_state_msg_.back_left_wheel_velocity = wheel_rear_left_state_vel; - controller_state_publisher_->msg_.reference_velocity.linear.x = reference_interfaces_[0]; - controller_state_publisher_->msg_.reference_velocity.linear.y = reference_interfaces_[1]; - controller_state_publisher_->msg_.reference_velocity.angular.z = reference_interfaces_[2]; - controller_state_publisher_->unlockAndPublish(); + controller_state_msg_.reference_velocity.linear.x = reference_interfaces_[0]; + controller_state_msg_.reference_velocity.linear.y = reference_interfaces_[1]; + controller_state_msg_.reference_velocity.angular.z = reference_interfaces_[2]; + controller_state_publisher_->try_publish(controller_state_msg_); } reference_interfaces_[0] = std::numeric_limits::quiet_NaN(); diff --git a/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp b/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp index c1466bf6f3..a1ec5fdba9 100644 --- a/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp +++ b/mecanum_drive_controller/test/test_mecanum_drive_controller.cpp @@ -141,7 +141,7 @@ TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_false_no_na ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); - auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + auto odometry_message = controller_->odom_state_msg_; std::string test_odom_frame_id = odometry_message.header.frame_id; std::string test_base_frame_id = odometry_message.child_frame_id; /* tf_frame_prefix_enable is false so no modifications to the frame id's */ @@ -176,7 +176,7 @@ TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_true_no_nam ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); - auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + auto odometry_message = controller_->odom_state_msg_; std::string test_odom_frame_id = odometry_message.header.frame_id; std::string test_base_frame_id = odometry_message.child_frame_id; @@ -203,7 +203,7 @@ TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_blank_prefix_true_no_na ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); - auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + auto odometry_message = controller_->odom_state_msg_; std::string test_odom_frame_id = odometry_message.header.frame_id; std::string test_base_frame_id = odometry_message.child_frame_id; /* tf_frame_prefix_enable is true but frame_prefix is blank so should not be appended to the @@ -231,7 +231,7 @@ TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_false_set_n ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); - auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + auto odometry_message = controller_->odom_state_msg_; std::string test_odom_frame_id = odometry_message.header.frame_id; std::string test_base_frame_id = odometry_message.child_frame_id; /* tf_frame_prefix_enable is false so no modifications to the frame id's */ @@ -257,7 +257,7 @@ TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_true_set_na ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); - auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + auto odometry_message = controller_->odom_state_msg_; std::string test_odom_frame_id = odometry_message.header.frame_id; std::string test_base_frame_id = odometry_message.child_frame_id; @@ -285,7 +285,7 @@ TEST_F(MecanumDriveControllerTest, configure_succeeds_tf_blank_prefix_true_set_n ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); - auto odometry_message = controller_->get_rt_odom_state_publisher_msg(); + auto odometry_message = controller_->odom_state_msg_; std::string test_odom_frame_id = odometry_message.header.frame_id; std::string test_base_frame_id = odometry_message.child_frame_id; std::string ns_prefix = test_namespace.erase(0, 1) + "/"; diff --git a/mecanum_drive_controller/test/test_mecanum_drive_controller.hpp b/mecanum_drive_controller/test/test_mecanum_drive_controller.hpp index 7d42c96c74..4d07dee7b2 100644 --- a/mecanum_drive_controller/test/test_mecanum_drive_controller.hpp +++ b/mecanum_drive_controller/test/test_mecanum_drive_controller.hpp @@ -84,6 +84,13 @@ class TestableMecanumDriveController : public mecanum_drive_controller::MecanumD when_ref_timeout_zero_for_reference_callback_expect_reference_msg_being_used_only_once); FRIEND_TEST(MecanumDriveControllerTest, SideToSideAndRotationOdometryTest); + FRIEND_TEST(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_false_no_namespace); + FRIEND_TEST(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_true_no_namespace); + FRIEND_TEST(MecanumDriveControllerTest, configure_succeeds_tf_blank_prefix_true_no_namespace); + FRIEND_TEST(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_false_set_namespace); + FRIEND_TEST(MecanumDriveControllerTest, configure_succeeds_tf_test_prefix_true_set_namespace); + FRIEND_TEST(MecanumDriveControllerTest, configure_succeeds_tf_blank_prefix_true_set_namespace); + public: controller_interface::CallbackReturn on_configure( const rclcpp_lifecycle::State & previous_state) override @@ -129,16 +136,6 @@ class TestableMecanumDriveController : public mecanum_drive_controller::MecanumD size_t get_rear_right_wheel_index() { return WheelIndex::REAR_RIGHT; } size_t get_rear_left_wheel_index() { return WheelIndex::REAR_LEFT; } - - /** - * @brief Used to get the odometry message to verify its contents - * - * @return Copy of odometry msg from rt_odom_state_publisher_ object - */ - nav_msgs::msg::Odometry get_rt_odom_state_publisher_msg() - { - return rt_odom_state_publisher_->msg_; - } }; // We are using template class here for easier reuse of Fixture in specializations of controllers diff --git a/pid_controller/include/pid_controller/pid_controller.hpp b/pid_controller/include/pid_controller/pid_controller.hpp index c8e651ed30..ffb4d36ae5 100644 --- a/pid_controller/include/pid_controller/pid_controller.hpp +++ b/pid_controller/include/pid_controller/pid_controller.hpp @@ -97,6 +97,7 @@ class PidController : public controller_interface::ChainableControllerInterface rclcpp::Publisher::SharedPtr s_publisher_; std::unique_ptr state_publisher_; + ControllerStateMsg state_msg_; // override methods from ChainableControllerInterface std::vector on_export_reference_interfaces() override; diff --git a/pid_controller/src/pid_controller.cpp b/pid_controller/src/pid_controller.cpp index 25cecddbb7..38601c26d6 100644 --- a/pid_controller/src/pid_controller.cpp +++ b/pid_controller/src/pid_controller.cpp @@ -272,13 +272,11 @@ controller_interface::CallbackReturn PidController::on_configure( } // Reserve memory in state publisher - state_publisher_->lock(); - state_publisher_->msg_.dof_states.resize(reference_and_state_dof_names_.size()); + state_msg_.dof_states.resize(reference_and_state_dof_names_.size()); for (size_t i = 0; i < reference_and_state_dof_names_.size(); ++i) { - state_publisher_->msg_.dof_states[i].name = reference_and_state_dof_names_[i]; + state_msg_.dof_states[i].name = reference_and_state_dof_names_[i]; } - state_publisher_->unlock(); RCLCPP_INFO(get_node()->get_logger(), "configure successful"); return controller_interface::CallbackReturn::SUCCESS; @@ -596,31 +594,30 @@ controller_interface::return_type PidController::update_and_write_commands( } } - if (state_publisher_ && state_publisher_->trylock()) + if (state_publisher_) { - state_publisher_->msg_.header.stamp = time; + state_msg_.header.stamp = time; for (size_t i = 0; i < dof_; ++i) { - state_publisher_->msg_.dof_states[i].reference = reference_interfaces_[i]; - state_publisher_->msg_.dof_states[i].feedback = measured_state_values_[i]; + state_msg_.dof_states[i].reference = reference_interfaces_[i]; + state_msg_.dof_states[i].feedback = measured_state_values_[i]; if (reference_interfaces_.size() == 2 * dof_ && measured_state_values_.size() == 2 * dof_) { - state_publisher_->msg_.dof_states[i].feedback_dot = measured_state_values_[dof_ + i]; + state_msg_.dof_states[i].feedback_dot = measured_state_values_[dof_ + i]; } - state_publisher_->msg_.dof_states[i].error = - reference_interfaces_[i] - measured_state_values_[i]; + state_msg_.dof_states[i].error = reference_interfaces_[i] - measured_state_values_[i]; if (params_.gains.dof_names_map[params_.dof_names[i]].angle_wraparound) { // for continuous angles the error is normalized between -pimsg_.dof_states[i].error = + state_msg_.dof_states[i].error = angles::shortest_angular_distance(measured_state_values_[i], reference_interfaces_[i]); } if (reference_interfaces_.size() == 2 * dof_ && measured_state_values_.size() == 2 * dof_) { - state_publisher_->msg_.dof_states[i].error_dot = + state_msg_.dof_states[i].error_dot = reference_interfaces_[dof_ + i] - measured_state_values_[dof_ + i]; } - state_publisher_->msg_.dof_states[i].time_step = period.seconds(); + state_msg_.dof_states[i].time_step = period.seconds(); // Command can store the old calculated values. This should be obvious because at least one // another value is NaN. const auto command_interface_value_op = command_interfaces_[i].get_optional(); @@ -633,10 +630,10 @@ controller_interface::return_type PidController::update_and_write_commands( } else { - state_publisher_->msg_.dof_states[i].output = command_interface_value_op.value(); + state_msg_.dof_states[i].output = command_interface_value_op.value(); } } - state_publisher_->unlockAndPublish(); + state_publisher_->try_publish(state_msg_); } return controller_interface::return_type::OK; diff --git a/pose_broadcaster/include/pose_broadcaster/pose_broadcaster.hpp b/pose_broadcaster/include/pose_broadcaster/pose_broadcaster.hpp index 45aaa7a1ff..b9bf273518 100644 --- a/pose_broadcaster/include/pose_broadcaster/pose_broadcaster.hpp +++ b/pose_broadcaster/include/pose_broadcaster/pose_broadcaster.hpp @@ -62,6 +62,7 @@ class PoseBroadcaster : public controller_interface::ControllerInterface rclcpp::Publisher::SharedPtr pose_publisher_; std::unique_ptr> realtime_publisher_; + geometry_msgs::msg::PoseStamped pose_msg_; // TODO(amronos): Remove these two member variables std::optional tf_publish_period_; @@ -70,6 +71,7 @@ class PoseBroadcaster : public controller_interface::ControllerInterface rclcpp::Publisher::SharedPtr tf_publisher_; std::unique_ptr> realtime_tf_publisher_; + tf2_msgs::msg::TFMessage tf_msg_; }; } // namespace pose_broadcaster diff --git a/pose_broadcaster/src/pose_broadcaster.cpp b/pose_broadcaster/src/pose_broadcaster.cpp index ef371c1d44..6d5f773d63 100644 --- a/pose_broadcaster/src/pose_broadcaster.cpp +++ b/pose_broadcaster/src/pose_broadcaster.cpp @@ -120,17 +120,13 @@ controller_interface::CallbackReturn PoseBroadcaster::on_configure( } // Initialize pose message - realtime_publisher_->lock(); - realtime_publisher_->msg_.header.frame_id = params_.frame_id; - realtime_publisher_->unlock(); + pose_msg_.header.frame_id = params_.frame_id; // Initialize tf message if tf publishing is enabled if (realtime_tf_publisher_) { - realtime_tf_publisher_->lock(); - - realtime_tf_publisher_->msg_.transforms.resize(1); - auto & tf_transform = realtime_tf_publisher_->msg_.transforms.front(); + tf_msg_.transforms.resize(1); + auto & tf_transform = tf_msg_.transforms.front(); tf_transform.header.frame_id = params_.frame_id; if (params_.tf.child_frame_id.empty()) { @@ -140,8 +136,6 @@ controller_interface::CallbackReturn PoseBroadcaster::on_configure( { tf_transform.child_frame_id = params_.tf.child_frame_id; } - - realtime_tf_publisher_->unlock(); } return controller_interface::CallbackReturn::SUCCESS; @@ -167,11 +161,11 @@ controller_interface::return_type PoseBroadcaster::update( geometry_msgs::msg::Pose pose; pose_sensor_->get_values_as_message(pose); - if (realtime_publisher_ && realtime_publisher_->trylock()) + if (realtime_publisher_) { - realtime_publisher_->msg_.header.stamp = time; - realtime_publisher_->msg_.pose = pose; - realtime_publisher_->unlockAndPublish(); + pose_msg_.header.stamp = time; + pose_msg_.pose = pose; + realtime_publisher_->try_publish(pose_msg_); } if (!is_pose_valid(pose)) { @@ -182,7 +176,7 @@ controller_interface::return_type PoseBroadcaster::update( pose.orientation.w); } // TODO(amronos): Remove publish rate functionality - else if (realtime_tf_publisher_ && realtime_tf_publisher_->trylock()) + else if (realtime_tf_publisher_) { bool do_publish = false; // rlcpp::Time comparisons throw if clock types are not the same @@ -197,7 +191,7 @@ controller_interface::return_type PoseBroadcaster::update( if (do_publish) { - auto & tf_transform = realtime_tf_publisher_->msg_.transforms[0]; + auto & tf_transform = tf_msg_.transforms[0]; tf_transform.header.stamp = time; tf_transform.transform.translation.x = pose.position.x; @@ -209,14 +203,10 @@ controller_interface::return_type PoseBroadcaster::update( tf_transform.transform.rotation.z = pose.orientation.z; tf_transform.transform.rotation.w = pose.orientation.w; - realtime_tf_publisher_->unlockAndPublish(); + realtime_tf_publisher_->try_publish(tf_msg_); tf_last_publish_time_ = time; } - else - { - realtime_tf_publisher_->unlock(); - } } return controller_interface::return_type::OK; diff --git a/range_sensor_broadcaster/include/range_sensor_broadcaster/range_sensor_broadcaster.hpp b/range_sensor_broadcaster/include/range_sensor_broadcaster/range_sensor_broadcaster.hpp index 65a1d3092f..75862d0815 100644 --- a/range_sensor_broadcaster/include/range_sensor_broadcaster/range_sensor_broadcaster.hpp +++ b/range_sensor_broadcaster/include/range_sensor_broadcaster/range_sensor_broadcaster.hpp @@ -60,6 +60,7 @@ class RangeSensorBroadcaster : public controller_interface::ControllerInterface using StatePublisher = realtime_tools::RealtimePublisher; rclcpp::Publisher::SharedPtr sensor_state_publisher_; std::unique_ptr realtime_publisher_; + sensor_msgs::msg::Range range_msg_; }; } // namespace range_sensor_broadcaster diff --git a/range_sensor_broadcaster/src/range_sensor_broadcaster.cpp b/range_sensor_broadcaster/src/range_sensor_broadcaster.cpp index e9c916b292..bd9018e9d0 100644 --- a/range_sensor_broadcaster/src/range_sensor_broadcaster.cpp +++ b/range_sensor_broadcaster/src/range_sensor_broadcaster.cpp @@ -72,17 +72,15 @@ controller_interface::CallbackReturn RangeSensorBroadcaster::on_configure( return CallbackReturn::ERROR; } - realtime_publisher_->lock(); - realtime_publisher_->msg_.header.frame_id = params_.frame_id; - realtime_publisher_->msg_.radiation_type = static_cast(params_.radiation_type); - realtime_publisher_->msg_.field_of_view = static_cast(params_.field_of_view); - realtime_publisher_->msg_.min_range = static_cast(params_.min_range); - realtime_publisher_->msg_.max_range = static_cast(params_.max_range); + range_msg_.header.frame_id = params_.frame_id; + range_msg_.radiation_type = static_cast(params_.radiation_type); + range_msg_.field_of_view = static_cast(params_.field_of_view); + range_msg_.min_range = static_cast(params_.min_range); + range_msg_.max_range = static_cast(params_.max_range); // \note The versions conditioning is added here to support the source-compatibility with Humble #if SENSOR_MSGS_VERSION_MAJOR >= 5 - realtime_publisher_->msg_.variance = params_.variance; + range_msg_.variance = params_.variance; #endif - realtime_publisher_->unlock(); RCLCPP_DEBUG(get_node()->get_logger(), "configure successful"); return CallbackReturn::SUCCESS; @@ -122,11 +120,11 @@ controller_interface::CallbackReturn RangeSensorBroadcaster::on_deactivate( controller_interface::return_type RangeSensorBroadcaster::update( const rclcpp::Time & time, const rclcpp::Duration & /*period*/) { - if (realtime_publisher_ && realtime_publisher_->trylock()) + if (realtime_publisher_) { - realtime_publisher_->msg_.header.stamp = time; - range_sensor_->get_values_as_message(realtime_publisher_->msg_); - realtime_publisher_->unlockAndPublish(); + range_msg_.header.stamp = time; + range_sensor_->get_values_as_message(range_msg_); + realtime_publisher_->try_publish(range_msg_); } return controller_interface::return_type::OK; diff --git a/steering_controllers_library/include/steering_controllers_library/steering_controllers_library.hpp b/steering_controllers_library/include/steering_controllers_library/steering_controllers_library.hpp index 83057652a5..6deabe8237 100644 --- a/steering_controllers_library/include/steering_controllers_library/steering_controllers_library.hpp +++ b/steering_controllers_library/include/steering_controllers_library/steering_controllers_library.hpp @@ -96,7 +96,9 @@ class SteeringControllersLibrary : public controller_interface::ChainableControl rclcpp::Publisher::SharedPtr tf_odom_s_publisher_; std::unique_ptr rt_odom_state_publisher_; + ControllerStateMsgOdom odom_state_msg_; std::unique_ptr rt_tf_odom_state_publisher_; + ControllerStateMsgTf tf_odom_state_msg_; // override methods from ChainableControllerInterface std::vector on_export_reference_interfaces() override; @@ -111,6 +113,7 @@ class SteeringControllersLibrary : public controller_interface::ChainableControl using ControllerStatePublisher = realtime_tools::RealtimePublisher; rclcpp::Publisher::SharedPtr controller_s_publisher_; std::unique_ptr controller_state_publisher_; + SteeringControllerStateMsg controller_state_msg_; // name constants for state interfaces size_t nr_state_itfs_; diff --git a/steering_controllers_library/src/steering_controllers_library.cpp b/steering_controllers_library/src/steering_controllers_library.cpp index 69322f4403..ace7bc2611 100644 --- a/steering_controllers_library/src/steering_controllers_library.cpp +++ b/steering_controllers_library/src/steering_controllers_library.cpp @@ -350,13 +350,12 @@ controller_interface::CallbackReturn SteeringControllersLibrary::on_configure( return controller_interface::CallbackReturn::ERROR; } - rt_odom_state_publisher_->lock(); - rt_odom_state_publisher_->msg_.header.stamp = get_node()->now(); - rt_odom_state_publisher_->msg_.header.frame_id = params_.odom_frame_id; - rt_odom_state_publisher_->msg_.child_frame_id = params_.base_frame_id; - rt_odom_state_publisher_->msg_.pose.pose.position.z = 0; + odom_state_msg_.header.stamp = get_node()->now(); + odom_state_msg_.header.frame_id = params_.odom_frame_id; + odom_state_msg_.child_frame_id = params_.base_frame_id; + odom_state_msg_.pose.pose.position.z = 0; - auto & covariance = rt_odom_state_publisher_->msg_.twist.covariance; + auto & covariance = odom_state_msg_.twist.covariance; constexpr size_t NUM_DIMENSIONS = 6; for (size_t index = 0; index < 6; ++index) { @@ -365,7 +364,6 @@ controller_interface::CallbackReturn SteeringControllersLibrary::on_configure( covariance[diagonal_index] = params_.pose_covariance_diagonal[index]; covariance[diagonal_index] = params_.twist_covariance_diagonal[index]; } - rt_odom_state_publisher_->unlock(); try { @@ -383,13 +381,11 @@ controller_interface::CallbackReturn SteeringControllersLibrary::on_configure( return controller_interface::CallbackReturn::ERROR; } - rt_tf_odom_state_publisher_->lock(); - rt_tf_odom_state_publisher_->msg_.transforms.resize(1); - rt_tf_odom_state_publisher_->msg_.transforms[0].header.stamp = get_node()->now(); - rt_tf_odom_state_publisher_->msg_.transforms[0].header.frame_id = params_.odom_frame_id; - rt_tf_odom_state_publisher_->msg_.transforms[0].child_frame_id = params_.base_frame_id; - rt_tf_odom_state_publisher_->msg_.transforms[0].transform.translation.z = 0.0; - rt_tf_odom_state_publisher_->unlock(); + tf_odom_state_msg_.transforms.resize(1); + tf_odom_state_msg_.transforms[0].header.stamp = get_node()->now(); + tf_odom_state_msg_.transforms[0].header.frame_id = params_.odom_frame_id; + tf_odom_state_msg_.transforms[0].child_frame_id = params_.base_frame_id; + tf_odom_state_msg_.transforms[0].transform.translation.z = 0.0; try { @@ -407,10 +403,8 @@ controller_interface::CallbackReturn SteeringControllersLibrary::on_configure( return controller_interface::CallbackReturn::ERROR; } - controller_state_publisher_->lock(); - controller_state_publisher_->msg_.header.stamp = get_node()->now(); - controller_state_publisher_->msg_.header.frame_id = params_.odom_frame_id; - controller_state_publisher_->unlock(); + controller_state_msg_.header.stamp = get_node()->now(); + controller_state_msg_.header.frame_id = params_.odom_frame_id; RCLCPP_INFO(get_node()->get_logger(), "configure successful"); return controller_interface::CallbackReturn::SUCCESS; } @@ -637,38 +631,35 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c orientation.setRPY(0.0, 0.0, odometry_.get_heading()); // Populate odom message and publish - if (rt_odom_state_publisher_->trylock()) + if (rt_odom_state_publisher_) { - rt_odom_state_publisher_->msg_.header.stamp = time; - rt_odom_state_publisher_->msg_.pose.pose.position.x = odometry_.get_x(); - rt_odom_state_publisher_->msg_.pose.pose.position.y = odometry_.get_y(); - rt_odom_state_publisher_->msg_.pose.pose.orientation = tf2::toMsg(orientation); - rt_odom_state_publisher_->msg_.twist.twist.linear.x = odometry_.get_linear(); - rt_odom_state_publisher_->msg_.twist.twist.angular.z = odometry_.get_angular(); - rt_odom_state_publisher_->unlockAndPublish(); + odom_state_msg_.header.stamp = time; + odom_state_msg_.pose.pose.position.x = odometry_.get_x(); + odom_state_msg_.pose.pose.position.y = odometry_.get_y(); + odom_state_msg_.pose.pose.orientation = tf2::toMsg(orientation); + odom_state_msg_.twist.twist.linear.x = odometry_.get_linear(); + odom_state_msg_.twist.twist.angular.z = odometry_.get_angular(); + rt_odom_state_publisher_->try_publish(odom_state_msg_); } // Publish tf /odom frame - if (params_.enable_odom_tf && rt_tf_odom_state_publisher_->trylock()) + if (params_.enable_odom_tf && rt_tf_odom_state_publisher_) { - rt_tf_odom_state_publisher_->msg_.transforms.front().header.stamp = time; - rt_tf_odom_state_publisher_->msg_.transforms.front().transform.translation.x = - odometry_.get_x(); - rt_tf_odom_state_publisher_->msg_.transforms.front().transform.translation.y = - odometry_.get_y(); - rt_tf_odom_state_publisher_->msg_.transforms.front().transform.rotation = - tf2::toMsg(orientation); - rt_tf_odom_state_publisher_->unlockAndPublish(); + tf_odom_state_msg_.transforms.front().header.stamp = time; + tf_odom_state_msg_.transforms.front().transform.translation.x = odometry_.get_x(); + tf_odom_state_msg_.transforms.front().transform.translation.y = odometry_.get_y(); + tf_odom_state_msg_.transforms.front().transform.rotation = tf2::toMsg(orientation); + rt_tf_odom_state_publisher_->try_publish(tf_odom_state_msg_); } - if (controller_state_publisher_->trylock()) + if (controller_state_publisher_) { - controller_state_publisher_->msg_.header.stamp = time; - controller_state_publisher_->msg_.traction_wheels_position.clear(); - controller_state_publisher_->msg_.traction_wheels_velocity.clear(); - controller_state_publisher_->msg_.linear_velocity_command.clear(); - controller_state_publisher_->msg_.steer_positions.clear(); - controller_state_publisher_->msg_.steering_angle_command.clear(); + controller_state_msg_.header.stamp = time; + controller_state_msg_.traction_wheels_position.clear(); + controller_state_msg_.traction_wheels_velocity.clear(); + controller_state_msg_.linear_velocity_command.clear(); + controller_state_msg_.steer_positions.clear(); + controller_state_msg_.steering_angle_command.clear(); auto number_of_traction_wheels = params_.traction_joints_names.size(); auto number_of_steering_wheels = params_.steering_joints_names.size(); @@ -685,7 +676,7 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c } else { - controller_state_publisher_->msg_.traction_wheels_position.push_back( + controller_state_msg_.traction_wheels_position.push_back( position_state_interface_op.value()); } } @@ -699,7 +690,7 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c } else { - controller_state_publisher_->msg_.traction_wheels_velocity.push_back( + controller_state_msg_.traction_wheels_velocity.push_back( velocity_state_interface_op.value()); } } @@ -711,7 +702,7 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c } else { - controller_state_publisher_->msg_.linear_velocity_command.push_back( + controller_state_msg_.linear_velocity_command.push_back( velocity_command_interface_op.value()); } } @@ -732,14 +723,12 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c } else { - controller_state_publisher_->msg_.steer_positions.push_back( - state_interface_value_op.value()); - controller_state_publisher_->msg_.steering_angle_command.push_back( - command_interface_value_op.value()); + controller_state_msg_.steer_positions.push_back(state_interface_value_op.value()); + controller_state_msg_.steering_angle_command.push_back(command_interface_value_op.value()); } } - controller_state_publisher_->unlockAndPublish(); + controller_state_publisher_->try_publish(controller_state_msg_); } reference_interfaces_[0] = std::numeric_limits::quiet_NaN(); diff --git a/tricycle_controller/include/tricycle_controller/tricycle_controller.hpp b/tricycle_controller/include/tricycle_controller/tricycle_controller.hpp index 60590012b9..004f7d867b 100644 --- a/tricycle_controller/include/tricycle_controller/tricycle_controller.hpp +++ b/tricycle_controller/include/tricycle_controller/tricycle_controller.hpp @@ -106,17 +106,20 @@ class TricycleController : public controller_interface::ControllerInterface std::shared_ptr> ackermann_command_publisher_ = nullptr; std::shared_ptr> realtime_ackermann_command_publisher_ = nullptr; + AckermannDrive ackermann_command_msg_; Odometry odometry_; std::shared_ptr> odometry_publisher_ = nullptr; std::shared_ptr> realtime_odometry_publisher_ = nullptr; + nav_msgs::msg::Odometry odometry_msg_; std::shared_ptr> odometry_transform_publisher_ = nullptr; std::shared_ptr> realtime_odometry_transform_publisher_ = nullptr; + tf2_msgs::msg::TFMessage tf_msg_; // Timeout to consider cmd_vel commands old std::chrono::milliseconds cmd_vel_timeout_{500}; diff --git a/tricycle_controller/src/tricycle_controller.cpp b/tricycle_controller/src/tricycle_controller.cpp index d0a9bd684e..3037a7e92c 100644 --- a/tricycle_controller/src/tricycle_controller.cpp +++ b/tricycle_controller/src/tricycle_controller.cpp @@ -141,27 +141,26 @@ controller_interface::return_type TricycleController::update( tf2::Quaternion orientation; orientation.setRPY(0.0, 0.0, odometry_.getHeading()); - if (realtime_odometry_publisher_->trylock()) + if (realtime_odometry_publisher_) { - auto & odometry_message = realtime_odometry_publisher_->msg_; - odometry_message.header.stamp = time; + odometry_msg_.header.stamp = time; if (!params_.odom_only_twist) { - odometry_message.pose.pose.position.x = odometry_.getX(); - odometry_message.pose.pose.position.y = odometry_.getY(); - odometry_message.pose.pose.orientation.x = orientation.x(); - odometry_message.pose.pose.orientation.y = orientation.y(); - odometry_message.pose.pose.orientation.z = orientation.z(); - odometry_message.pose.pose.orientation.w = orientation.w(); + odometry_msg_.pose.pose.position.x = odometry_.getX(); + odometry_msg_.pose.pose.position.y = odometry_.getY(); + odometry_msg_.pose.pose.orientation.x = orientation.x(); + odometry_msg_.pose.pose.orientation.y = orientation.y(); + odometry_msg_.pose.pose.orientation.z = orientation.z(); + odometry_msg_.pose.pose.orientation.w = orientation.w(); } - odometry_message.twist.twist.linear.x = odometry_.getLinear(); - odometry_message.twist.twist.angular.z = odometry_.getAngular(); - realtime_odometry_publisher_->unlockAndPublish(); + odometry_msg_.twist.twist.linear.x = odometry_.getLinear(); + odometry_msg_.twist.twist.angular.z = odometry_.getAngular(); + realtime_odometry_publisher_->try_publish(odometry_msg_); } - if (params_.enable_odom_tf && realtime_odometry_transform_publisher_->trylock()) + if (params_.enable_odom_tf && realtime_odometry_transform_publisher_) { - auto & transform = realtime_odometry_transform_publisher_->msg_.transforms.front(); + auto & transform = tf_msg_.transforms.front(); transform.header.stamp = time; transform.transform.translation.x = odometry_.getX(); transform.transform.translation.y = odometry_.getY(); @@ -169,7 +168,7 @@ controller_interface::return_type TricycleController::update( transform.transform.rotation.y = orientation.y(); transform.transform.rotation.z = orientation.z(); transform.transform.rotation.w = orientation.w(); - realtime_odometry_transform_publisher_->unlockAndPublish(); + realtime_odometry_transform_publisher_->try_publish(tf_msg_); } // Compute wheel velocity and angle @@ -212,14 +211,13 @@ controller_interface::return_type TricycleController::update( previous_commands_.emplace(ackermann_command); // Publish ackermann command - if (params_.publish_ackermann_command && realtime_ackermann_command_publisher_->trylock()) + if (params_.publish_ackermann_command && realtime_ackermann_command_publisher_) { - auto & realtime_ackermann_command = realtime_ackermann_command_publisher_->msg_; // speed in AckermannDrive is defined desired forward speed (m/s) but we use it here as wheel // speed (rad/s) - realtime_ackermann_command.speed = static_cast(Ws_write); - realtime_ackermann_command.steering_angle = static_cast(alpha_write); - realtime_ackermann_command_publisher_->unlockAndPublish(); + ackermann_command_msg_.speed = static_cast(Ws_write); + ackermann_command_msg_.steering_angle = static_cast(alpha_write); + realtime_ackermann_command_publisher_->try_publish(ackermann_command_msg_); } if (!traction_joint_[0].velocity_command.get().set_value(Ws_write)) @@ -333,12 +331,11 @@ CallbackReturn TricycleController::on_configure(const rclcpp_lifecycle::State & std::make_shared>( odometry_publisher_); - auto & odometry_message = realtime_odometry_publisher_->msg_; - odometry_message.header.frame_id = params_.odom_frame_id; - odometry_message.child_frame_id = params_.base_frame_id; + odometry_msg_.header.frame_id = params_.odom_frame_id; + odometry_msg_.child_frame_id = params_.base_frame_id; // initialize odom values zeros - odometry_message.twist = + odometry_msg_.twist = geometry_msgs::msg::TwistWithCovariance(rosidl_runtime_cpp::MessageInitialization::ALL); constexpr size_t NUM_DIMENSIONS = 6; @@ -346,8 +343,8 @@ CallbackReturn TricycleController::on_configure(const rclcpp_lifecycle::State & { // 0, 7, 14, 21, 28, 35 const size_t diagonal_index = NUM_DIMENSIONS * index + index; - odometry_message.pose.covariance[diagonal_index] = params_.pose_covariance_diagonal[index]; - odometry_message.twist.covariance[diagonal_index] = params_.twist_covariance_diagonal[index]; + odometry_msg_.pose.covariance[diagonal_index] = params_.pose_covariance_diagonal[index]; + odometry_msg_.twist.covariance[diagonal_index] = params_.twist_covariance_diagonal[index]; } // initialize transform publisher and message @@ -360,10 +357,9 @@ CallbackReturn TricycleController::on_configure(const rclcpp_lifecycle::State & odometry_transform_publisher_); // keeping track of odom and base_link transforms only - auto & odometry_transform_message = realtime_odometry_transform_publisher_->msg_; - odometry_transform_message.transforms.resize(1); - odometry_transform_message.transforms.front().header.frame_id = params_.odom_frame_id; - odometry_transform_message.transforms.front().child_frame_id = params_.base_frame_id; + tf_msg_.transforms.resize(1); + tf_msg_.transforms.front().header.frame_id = params_.odom_frame_id; + tf_msg_.transforms.front().child_frame_id = params_.base_frame_id; } // Create odom reset service From cc99e597da7df317434b59d1d96e42a8fa9cccfe Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Fri, 3 Oct 2025 17:33:35 +0000 Subject: [PATCH 091/108] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 6 ++++++ admittance_controller/CHANGELOG.rst | 7 +++++++ bicycle_steering_controller/CHANGELOG.rst | 6 ++++++ chained_filter_controller/CHANGELOG.rst | 3 +++ diff_drive_controller/CHANGELOG.rst | 8 ++++++++ effort_controllers/CHANGELOG.rst | 6 ++++++ force_torque_sensor_broadcaster/CHANGELOG.rst | 7 +++++++ forward_command_controller/CHANGELOG.rst | 6 ++++++ gpio_controllers/CHANGELOG.rst | 7 +++++++ gps_sensor_broadcaster/CHANGELOG.rst | 5 +++++ gripper_controllers/CHANGELOG.rst | 5 +++++ imu_sensor_broadcaster/CHANGELOG.rst | 5 +++++ joint_state_broadcaster/CHANGELOG.rst | 5 +++++ joint_trajectory_controller/CHANGELOG.rst | 10 ++++++++++ mecanum_drive_controller/CHANGELOG.rst | 8 ++++++++ omni_wheel_drive_controller/CHANGELOG.rst | 5 +++++ parallel_gripper_controller/CHANGELOG.rst | 8 ++++++++ pid_controller/CHANGELOG.rst | 7 +++++++ pose_broadcaster/CHANGELOG.rst | 5 +++++ position_controllers/CHANGELOG.rst | 6 ++++++ range_sensor_broadcaster/CHANGELOG.rst | 5 +++++ ros2_controllers/CHANGELOG.rst | 3 +++ ros2_controllers_test_nodes/CHANGELOG.rst | 3 +++ rqt_joint_trajectory_controller/CHANGELOG.rst | 3 +++ steering_controllers_library/CHANGELOG.rst | 7 +++++++ tricycle_controller/CHANGELOG.rst | 7 +++++++ tricycle_steering_controller/CHANGELOG.rst | 6 ++++++ velocity_controllers/CHANGELOG.rst | 6 ++++++ 28 files changed, 165 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 49f908082b..0e8b256eaf 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 005d2c42e2..fb04206523 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- * Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index c8968a69ee..5f8ea706da 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/chained_filter_controller/CHANGELOG.rst b/chained_filter_controller/CHANGELOG.rst index 1f6cd33888..6867319896 100644 --- a/chained_filter_controller/CHANGELOG.rst +++ b/chained_filter_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package chained_filter_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.32.0 (2025-09-12) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index cc3c68d529..f76f8c1006 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,14 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Fix: Remove deprecated `rclcpp::spin_some(node)` (backport `#1928 `_) (`#1932 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index dfc6305cd5..ca5b1b994d 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index d1e18139ca..bb84a0d91e 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Add filtering capability to ft_broadcaster (backport `#1814 `_) (`#1927 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- * FTS: Don't make a temporary copy of semantic component (backport `#1902 `_) (`#1904 `_) diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index a34ef2bfe5..818dbd6de2 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index a6d20b0025..30f94bb494 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 8f7396f8d0..018910b4c4 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- * Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 2877261306..15d4cf9e8d 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 73e8cfc78a..d796c2ff36 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- * Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index dc6a056a06..01cb84aea7 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- * Added frame_id to Joint State Broadcaster (backport `#1746 `_) (`#1897 `_) diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index ad6907acef..5d4e67f52e 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,16 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Remove wrong and unnecessary docstrings (backport `#1912 `_) (`#1924 `_) +* Use auto dependency management for windows workflow (backport `#1917 `_) (`#1922 `_) +* Remove unused variables and correctly override test class method (backport `#1918 `_) (`#1920 `_) +* Don't call `release_interfaces` from controllers (backport `#1910 `_) (`#1911 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- * Preallocate `std::vector` variables for interfaces (backport `#1893 `_) (`#1899 `_) diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index f4765f24f8..40abbf8540 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,14 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* mecanum_drive_controller: Declare missing backward_ros dependency (backport `#1941 `_) (`#1943 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst index 581437d0f6..4d901bea8b 100644 --- a/omni_wheel_drive_controller/CHANGELOG.rst +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package omni_wheel_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix: Remove deprecated `rclcpp::spin_some(node)` (backport `#1928 `_) (`#1932 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- * Fix use of M_PI in omni_wheel_driver_controller on MSVC (backport `#1886 `_) (`#1887 `_) diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index b9b91f1032..648dc18776 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,14 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Fix: Remove deprecated `rclcpp::spin_some(node)` (backport `#1928 `_) (`#1932 `_) +* Don't call `release_interfaces` from controllers (backport `#1910 `_) (`#1911 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 4ea2e94412..4474bdc728 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 53198f717e..bc14caf122 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index de27c672db..697c287068 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 2407fdb555..8b3164c3e1 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- * Fix temporary copies of other semantic components (backport `#1905 `_) (`#1908 `_) diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 2f24eb3023..3dcd031d18 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.32.0 (2025-09-12) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 495250306f..50b66b13ce 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.32.0 (2025-09-12) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 46c28615df..7810c7d4bd 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.32.0 (2025-09-12) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 42ae8ed720..aa76f607af 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index c262e219c4..c52a312045 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Fix: Remove deprecated `rclcpp::spin_some(node)` (backport `#1928 `_) (`#1932 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index f4eb504780..83471e59a5 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 0a54dcf240..1abe90b5e2 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update realtime containers (backport `#1721 `_) (`#1935 `_) +* Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) +* Contributors: mergify[bot] + 4.32.0 (2025-09-12) ------------------- From b1f7bbe68de9e1dc21a714c9fb66f9750462212d Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Fri, 3 Oct 2025 17:33:58 +0000 Subject: [PATCH 092/108] 4.33.0 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- chained_filter_controller/CHANGELOG.rst | 4 ++-- chained_filter_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- omni_wheel_drive_controller/CHANGELOG.rst | 4 ++-- omni_wheel_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 58 files changed, 86 insertions(+), 86 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 0e8b256eaf..7d68848cb5 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Contributors: mergify[bot] diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index db68a6ae01..e622a61a5d 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.32.0 + 4.33.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index fb04206523..b5d7380651 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index 42dc1d9ded..921f2a0361 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.32.0 + 4.33.0 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 5f8ea706da..e3ae9e8d0d 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Contributors: mergify[bot] diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index 441a2c473c..de2ca044e6 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.32.0 + 4.33.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/chained_filter_controller/CHANGELOG.rst b/chained_filter_controller/CHANGELOG.rst index 6867319896..34522b6115 100644 --- a/chained_filter_controller/CHANGELOG.rst +++ b/chained_filter_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package chained_filter_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- 4.32.0 (2025-09-12) ------------------- diff --git a/chained_filter_controller/package.xml b/chained_filter_controller/package.xml index cdc1610ca7..f2e69a067b 100644 --- a/chained_filter_controller/package.xml +++ b/chained_filter_controller/package.xml @@ -2,7 +2,7 @@ chained_filter_controller - 4.32.0 + 4.33.0 ros2_controller for configuring filter chains Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index f76f8c1006..45773e929e 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 87d7d747a4..5260677e9f 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.32.0 + 4.33.0 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index ca5b1b994d..42abea348e 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Contributors: mergify[bot] diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index 0468f8d586..09ef1ccfe5 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.32.0 + 4.33.0 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index bb84a0d91e..bdce62d40e 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Add filtering capability to ft_broadcaster (backport `#1814 `_) (`#1927 `_) diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index cfbb38cf0c..e66a149d3c 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.32.0 + 4.33.0 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 818dbd6de2..0516fcb96e 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Contributors: mergify[bot] diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index cd5843a245..a830f8550c 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.32.0 + 4.33.0 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 30f94bb494..2ccd28e2c9 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index 009b9b8b0d..508a1b939c 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.32.0 + 4.33.0 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 018910b4c4..66dc3637df 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Contributors: mergify[bot] diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index 29f6de244a..afaa3478d6 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.32.0 + 4.33.0 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 15d4cf9e8d..f2f80d83bf 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Contributors: mergify[bot] diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index c79038fbb8..97c1a82137 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.32.0 + 4.33.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index d796c2ff36..296c177ae5 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Contributors: mergify[bot] diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index 3ed9d42e89..d98f78dd29 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.32.0 + 4.33.0 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 01cb84aea7..19dea1e1a3 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Contributors: mergify[bot] diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index 4a0972c44e..d02a7eacd8 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.32.0 + 4.33.0 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 5d4e67f52e..6d46c5a746 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Remove wrong and unnecessary docstrings (backport `#1912 `_) (`#1924 `_) diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 965b7b9c5e..5a8df8b32e 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.32.0 + 4.33.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 40abbf8540..3e5b66681e 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Update realtime containers (backport `#1721 `_) (`#1935 `_) * mecanum_drive_controller: Declare missing backward_ros dependency (backport `#1941 `_) (`#1943 `_) diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index eff8d70a60..8d4afead3f 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.32.0 + 4.33.0 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst index 4d901bea8b..9566c7bc5b 100644 --- a/omni_wheel_drive_controller/CHANGELOG.rst +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package omni_wheel_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Fix: Remove deprecated `rclcpp::spin_some(node)` (backport `#1928 `_) (`#1932 `_) * Contributors: mergify[bot] diff --git a/omni_wheel_drive_controller/package.xml b/omni_wheel_drive_controller/package.xml index 8e91966f7c..09a0e8ecaa 100644 --- a/omni_wheel_drive_controller/package.xml +++ b/omni_wheel_drive_controller/package.xml @@ -2,7 +2,7 @@ omni_wheel_drive_controller - 4.32.0 + 4.33.0 A chainable controller for mobile robots with omnidirectional drive with three or more omni wheels. Apache License 2.0 diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 648dc18776..2ae9a94ae8 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Fix: Remove deprecated `rclcpp::spin_some(node)` (backport `#1928 `_) (`#1932 `_) diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index 8ec2885316..91df8c44a2 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.32.0 + 4.33.0 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 4474bdc728..8deb2ae51c 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) diff --git a/pid_controller/package.xml b/pid_controller/package.xml index a6ad6e348a..1dacbfff81 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.32.0 + 4.33.0 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index bc14caf122..9df61c01ea 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Contributors: mergify[bot] diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index cc85169bd3..ab8af0286c 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.32.0 + 4.33.0 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 697c287068..924f652fe4 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Contributors: mergify[bot] diff --git a/position_controllers/package.xml b/position_controllers/package.xml index ba3439a404..ae0a6440c3 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.32.0 + 4.33.0 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 8b3164c3e1..a98a2250ec 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Contributors: mergify[bot] diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index 059d49c9b8..03b7aa8bee 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.32.0 + 4.33.0 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 3dcd031d18..9077b0a583 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- 4.32.0 (2025-09-12) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 521ee29588..2cb9f3d99a 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.32.0 + 4.33.0 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 50b66b13ce..0ce28b397b 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- 4.32.0 (2025-09-12) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index ca0a1aa66c..d4714a73d2 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.32.0 + 4.33.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index 06db8531d1..b5e4fb0ab1 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.32.0", + version="4.33.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 7810c7d4bd..4e3493e9b1 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- 4.32.0 (2025-09-12) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 34073bf508..a96c652248 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.32.0 + 4.33.0 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index 12ce44883f..7713da940b 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.32.0", + version="4.33.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index aa76f607af..1cc7688545 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index b7d52ec8cb..c7453b58f2 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.32.0 + 4.33.0 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index c52a312045..ecc198d2ff 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Fix: Remove deprecated `rclcpp::spin_some(node)` (backport `#1928 `_) (`#1932 `_) diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index ecf34b0822..e959f0ea77 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.32.0 + 4.33.0 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 83471e59a5..392f1b5f28 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Contributors: mergify[bot] diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index 0687f1fd5e..f13989b0b9 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.32.0 + 4.33.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 1abe90b5e2..d97ec79e43 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.0 (2025-10-03) +------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) * Contributors: mergify[bot] diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index 3f9fb46556..0cd89d1641 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.32.0 + 4.33.0 Generic controller for forwarding commands. Bence Magyar From f44771680e1a7a1950ab3ea7b2566fcaa7b7920f Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sun, 5 Oct 2025 10:25:51 +0200 Subject: [PATCH 093/108] Don't use `msg_` field of realtime publisher (backport #1947) (#1948) --- .../src/diff_drive_controller.cpp | 11 ++-- .../test/test_diff_drive_controller.cpp | 52 +++++++------------ .../src/force_torque_sensor_broadcaster.cpp | 12 ++--- .../test/test_trajectory_controller_utils.hpp | 2 +- .../tricycle_controller.hpp | 5 +- 5 files changed, 34 insertions(+), 48 deletions(-) diff --git a/diff_drive_controller/src/diff_drive_controller.cpp b/diff_drive_controller/src/diff_drive_controller.cpp index f63f7126d9..f119774984 100644 --- a/diff_drive_controller/src/diff_drive_controller.cpp +++ b/diff_drive_controller/src/diff_drive_controller.cpp @@ -500,16 +500,15 @@ controller_interface::CallbackReturn DiffDriveController::on_configure( const auto odom_frame_id = tf_prefix + params_.odom_frame_id; const auto base_frame_id = tf_prefix + params_.base_frame_id; - auto & odometry_message = realtime_odometry_publisher_->msg_; - odometry_message.header.frame_id = odom_frame_id; - odometry_message.child_frame_id = base_frame_id; + odometry_message_.header.frame_id = odom_frame_id; + odometry_message_.child_frame_id = base_frame_id; // limit the publication on the topics /odom and /tf publish_rate_ = params_.publish_rate; publish_period_ = rclcpp::Duration::from_seconds(1.0 / publish_rate_); // initialize odom values zeros - odometry_message.twist = + odometry_message_.twist = geometry_msgs::msg::TwistWithCovariance(rosidl_runtime_cpp::MessageInitialization::ALL); constexpr size_t NUM_DIMENSIONS = 6; @@ -517,8 +516,8 @@ controller_interface::CallbackReturn DiffDriveController::on_configure( { // 0, 7, 14, 21, 28, 35 const size_t diagonal_index = NUM_DIMENSIONS * index + index; - odometry_message.pose.covariance[diagonal_index] = params_.pose_covariance_diagonal[index]; - odometry_message.twist.covariance[diagonal_index] = params_.twist_covariance_diagonal[index]; + odometry_message_.pose.covariance[diagonal_index] = params_.pose_covariance_diagonal[index]; + odometry_message_.twist.covariance[diagonal_index] = params_.twist_covariance_diagonal[index]; } // initialize transform publisher and message diff --git a/diff_drive_controller/test/test_diff_drive_controller.cpp b/diff_drive_controller/test/test_diff_drive_controller.cpp index 8b442875c7..17cea9e7a7 100644 --- a/diff_drive_controller/test/test_diff_drive_controller.cpp +++ b/diff_drive_controller/test/test_diff_drive_controller.cpp @@ -73,7 +73,13 @@ class TestableDiffDriveController : public diff_drive_controller::DiffDriveContr { return realtime_odometry_publisher_; } - + // Declare these tests as friends so we can access odometry_message_ + FRIEND_TEST(TestDiffDriveController, configure_succeeds_tf_test_prefix_false_no_namespace); + FRIEND_TEST(TestDiffDriveController, configure_succeeds_tf_test_prefix_true_no_namespace); + FRIEND_TEST(TestDiffDriveController, configure_succeeds_tf_blank_prefix_true_no_namespace); + FRIEND_TEST(TestDiffDriveController, configure_succeeds_tf_test_prefix_false_set_namespace); + FRIEND_TEST(TestDiffDriveController, configure_succeeds_tf_test_prefix_true_set_namespace); + FRIEND_TEST(TestDiffDriveController, configure_succeeds_tf_blank_prefix_true_set_namespace); // Declare these tests as friends so we can access controller_->reference_interfaces_ FRIEND_TEST(TestDiffDriveController, chainable_controller_unchained_mode); FRIEND_TEST(TestDiffDriveController, chainable_controller_chained_mode); @@ -305,12 +311,9 @@ TEST_F(TestDiffDriveController, configure_succeeds_tf_test_prefix_false_no_names ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); - auto odometry_message = controller_->get_rt_odom_publisher()->msg_; - std::string test_odom_frame_id = odometry_message.header.frame_id; - std::string test_base_frame_id = odometry_message.child_frame_id; /* tf_frame_prefix_enable is false so no modifications to the frame id's */ - ASSERT_EQ(test_odom_frame_id, odom_id); - ASSERT_EQ(test_base_frame_id, base_link_id); + ASSERT_EQ(controller_->odometry_message_.header.frame_id, odom_id); + ASSERT_EQ(controller_->odometry_message_.child_frame_id, base_link_id); } TEST_F(TestDiffDriveController, configure_succeeds_tf_test_prefix_true_no_namespace) @@ -330,14 +333,10 @@ TEST_F(TestDiffDriveController, configure_succeeds_tf_test_prefix_true_no_namesp ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); - auto odometry_message = controller_->get_rt_odom_publisher()->msg_; - std::string test_odom_frame_id = odometry_message.header.frame_id; - std::string test_base_frame_id = odometry_message.child_frame_id; - /* tf_frame_prefix_enable is true and frame_prefix is not blank so should be appended to the frame * id's */ - ASSERT_EQ(test_odom_frame_id, frame_prefix + "/" + odom_id); - ASSERT_EQ(test_base_frame_id, frame_prefix + "/" + base_link_id); + ASSERT_EQ(controller_->odometry_message_.header.frame_id, frame_prefix + "/" + odom_id); + ASSERT_EQ(controller_->odometry_message_.child_frame_id, frame_prefix + "/" + base_link_id); } TEST_F(TestDiffDriveController, configure_succeeds_tf_blank_prefix_true_no_namespace) @@ -357,13 +356,10 @@ TEST_F(TestDiffDriveController, configure_succeeds_tf_blank_prefix_true_no_names ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); - auto odometry_message = controller_->get_rt_odom_publisher()->msg_; - std::string test_odom_frame_id = odometry_message.header.frame_id; - std::string test_base_frame_id = odometry_message.child_frame_id; /* tf_frame_prefix_enable is true but frame_prefix is blank so should not be appended to the frame * id's */ - ASSERT_EQ(test_odom_frame_id, odom_id); - ASSERT_EQ(test_base_frame_id, base_link_id); + ASSERT_EQ(controller_->odometry_message_.header.frame_id, odom_id); + ASSERT_EQ(controller_->odometry_message_.child_frame_id, base_link_id); } TEST_F(TestDiffDriveController, configure_succeeds_tf_test_prefix_false_set_namespace) @@ -386,12 +382,9 @@ TEST_F(TestDiffDriveController, configure_succeeds_tf_test_prefix_false_set_name ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); - auto odometry_message = controller_->get_rt_odom_publisher()->msg_; - std::string test_odom_frame_id = odometry_message.header.frame_id; - std::string test_base_frame_id = odometry_message.child_frame_id; /* tf_frame_prefix_enable is false so no modifications to the frame id's */ - ASSERT_EQ(test_odom_frame_id, odom_id); - ASSERT_EQ(test_base_frame_id, base_link_id); + ASSERT_EQ(controller_->odometry_message_.header.frame_id, odom_id); + ASSERT_EQ(controller_->odometry_message_.child_frame_id, base_link_id); } TEST_F(TestDiffDriveController, configure_succeeds_tf_test_prefix_true_set_namespace) @@ -414,14 +407,10 @@ TEST_F(TestDiffDriveController, configure_succeeds_tf_test_prefix_true_set_names ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); - auto odometry_message = controller_->get_rt_odom_publisher()->msg_; - std::string test_odom_frame_id = odometry_message.header.frame_id; - std::string test_base_frame_id = odometry_message.child_frame_id; - /* tf_frame_prefix_enable is true and frame_prefix is not blank so should be appended to the frame * id's instead of the namespace*/ - ASSERT_EQ(test_odom_frame_id, frame_prefix + "/" + odom_id); - ASSERT_EQ(test_base_frame_id, frame_prefix + "/" + base_link_id); + ASSERT_EQ(controller_->odometry_message_.header.frame_id, frame_prefix + "/" + odom_id); + ASSERT_EQ(controller_->odometry_message_.child_frame_id, frame_prefix + "/" + base_link_id); } TEST_F(TestDiffDriveController, configure_succeeds_tf_blank_prefix_true_set_namespace) @@ -443,14 +432,11 @@ TEST_F(TestDiffDriveController, configure_succeeds_tf_blank_prefix_true_set_name ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), CallbackReturn::SUCCESS); - auto odometry_message = controller_->get_rt_odom_publisher()->msg_; - std::string test_odom_frame_id = odometry_message.header.frame_id; - std::string test_base_frame_id = odometry_message.child_frame_id; std::string ns_prefix = test_namespace.erase(0, 1) + "/"; /* tf_frame_prefix_enable is true but frame_prefix is blank so namespace should be appended to the * frame id's */ - ASSERT_EQ(test_odom_frame_id, ns_prefix + odom_id); - ASSERT_EQ(test_base_frame_id, ns_prefix + base_link_id); + ASSERT_EQ(controller_->odometry_message_.header.frame_id, ns_prefix + odom_id); + ASSERT_EQ(controller_->odometry_message_.child_frame_id, ns_prefix + base_link_id); } TEST_F(TestDiffDriveController, activate_fails_without_resources_assigned) diff --git a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp index 114c4466fa..2b85929ae9 100644 --- a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp @@ -244,32 +244,32 @@ ForceTorqueSensorBroadcaster::on_export_state_interfaces() if (!force_names[0].empty()) { exported_state_interfaces.emplace_back( - export_prefix, force_names[0], &realtime_raw_publisher_->msg_.wrench.force.x); + export_prefix, force_names[0], &wrench_raw_.wrench.force.x); } if (!force_names[1].empty()) { exported_state_interfaces.emplace_back( - export_prefix, force_names[1], &realtime_raw_publisher_->msg_.wrench.force.y); + export_prefix, force_names[1], &wrench_raw_.wrench.force.y); } if (!force_names[2].empty()) { exported_state_interfaces.emplace_back( - export_prefix, force_names[2], &realtime_raw_publisher_->msg_.wrench.force.z); + export_prefix, force_names[2], &wrench_raw_.wrench.force.z); } if (!torque_names[0].empty()) { exported_state_interfaces.emplace_back( - export_prefix, torque_names[0], &realtime_raw_publisher_->msg_.wrench.torque.x); + export_prefix, torque_names[0], &wrench_raw_.wrench.torque.x); } if (!torque_names[1].empty()) { exported_state_interfaces.emplace_back( - export_prefix, torque_names[1], &realtime_raw_publisher_->msg_.wrench.torque.y); + export_prefix, torque_names[1], &wrench_raw_.wrench.torque.y); } if (!torque_names[2].empty()) { exported_state_interfaces.emplace_back( - export_prefix, torque_names[2], &realtime_raw_publisher_->msg_.wrench.torque.z); + export_prefix, torque_names[2], &wrench_raw_.wrench.torque.z); } return exported_state_interfaces; } diff --git a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp index 41a2ab8ece..bd1c0b494c 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp +++ b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp @@ -208,7 +208,7 @@ class TestableJointTrajectoryController control_msgs::msg::JointTrajectoryControllerState get_state_msg() { - return state_publisher_->msg_; + return state_publisher_->get_msg(); } /** diff --git a/tricycle_controller/include/tricycle_controller/tricycle_controller.hpp b/tricycle_controller/include/tricycle_controller/tricycle_controller.hpp index 004f7d867b..81a62b989c 100644 --- a/tricycle_controller/include/tricycle_controller/tricycle_controller.hpp +++ b/tricycle_controller/include/tricycle_controller/tricycle_controller.hpp @@ -33,8 +33,8 @@ #include "geometry_msgs/msg/twist_stamped.hpp" #include "nav_msgs/msg/odometry.hpp" #include "rclcpp_lifecycle/state.hpp" -#include "realtime_tools/realtime_box.hpp" #include "realtime_tools/realtime_publisher.hpp" +#include "realtime_tools/realtime_thread_safe_box.hpp" #include "std_srvs/srv/empty.hpp" #include "tf2_msgs/msg/tf_message.hpp" @@ -127,7 +127,8 @@ class TricycleController : public controller_interface::ControllerInterface bool subscriber_is_active_ = false; rclcpp::Subscription::SharedPtr velocity_command_subscriber_ = nullptr; - realtime_tools::RealtimeBox> received_velocity_msg_ptr_{nullptr}; + realtime_tools::RealtimeThreadSafeBox> received_velocity_msg_ptr_{ + nullptr}; std::shared_ptr last_command_msg_; rclcpp::Service::SharedPtr reset_odom_service_; From de70f72cf6761bd8ef7a3d5571b90ef06285765c Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sun, 5 Oct 2025 22:32:29 +0200 Subject: [PATCH 094/108] =?UTF-8?q?Branch=20off=20kilted=20=F0=9F=8C=BF=20?= =?UTF-8?q?(backport=20#1945)=20(#1952)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/dependabot.yml | 14 +++++ .github/mergify.yml | 9 +++ .../workflows/kilted-abi-compatibility.yml | 27 ++++++++ .github/workflows/kilted-binary-build.yml | 56 +++++++++++++++++ .github/workflows/kilted-check-docs.yml | 29 +++++++++ .github/workflows/kilted-coverage-build.yml | 45 +++++++++++++ .github/workflows/kilted-debian-build.yml | 35 +++++++++++ .github/workflows/kilted-pre-commit.yml | 20 ++++++ .github/workflows/kilted-pre-release.yml | 27 ++++++++ .../kilted-rhel-semi-binary-build.yml | 34 ++++++++++ .../workflows/kilted-semi-binary-build.yml | 63 +++++++++++++++++++ .../kilted-semi-binary-downstream-build.yml | 38 +++++++++++ .github/workflows/kilted-source-build.yml | 33 ++++++++++ .../workflows/rolling-abi-compatibility.yml | 2 +- .github/workflows/rolling-binary-build.yml | 2 +- .github/workflows/rolling-debian-build.yml | 2 +- .github/workflows/rolling-pre-commit.yml | 2 +- .github/workflows/rolling-pre-release.yml | 2 +- .../rolling-rhel-semi-binary-build.yml | 2 +- .../workflows/rolling-semi-binary-build.yml | 4 +- .../rolling-semi-binary-downstream-build.yml | 2 +- .github/workflows/rolling-source-build.yml | 2 +- README.md | 2 +- ros2_controllers.kilted.repos | 4 +- 24 files changed, 443 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/kilted-abi-compatibility.yml create mode 100644 .github/workflows/kilted-binary-build.yml create mode 100644 .github/workflows/kilted-check-docs.yml create mode 100644 .github/workflows/kilted-coverage-build.yml create mode 100644 .github/workflows/kilted-debian-build.yml create mode 100644 .github/workflows/kilted-pre-commit.yml create mode 100644 .github/workflows/kilted-pre-release.yml create mode 100644 .github/workflows/kilted-rhel-semi-binary-build.yml create mode 100644 .github/workflows/kilted-semi-binary-build.yml create mode 100644 .github/workflows/kilted-semi-binary-downstream-build.yml create mode 100644 .github/workflows/kilted-source-build.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f5e9921f23..f89baba15b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -18,3 +18,17 @@ updates: schedule: interval: "weekly" target-branch: "humble" + - package-ecosystem: "github-actions" + # Workflow files stored in the + # default location of `.github/workflows` + directory: "/" + schedule: + interval: "weekly" + target-branch: "jazzy" + - package-ecosystem: "github-actions" + # Workflow files stored in the + # default location of `.github/workflows` + directory: "/" + schedule: + interval: "weekly" + target-branch: "kilted" diff --git a/.github/mergify.yml b/.github/mergify.yml index 44f51cf58f..8293ec1b06 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -17,6 +17,15 @@ pull_request_rules: branches: - jazzy + - name: Backport to kilted at reviewers discretion + conditions: + - base=master + - "label=backport-kilted" + actions: + backport: + branches: + - kilted + - name: Ask to resolve conflict conditions: - conflict diff --git a/.github/workflows/kilted-abi-compatibility.yml b/.github/workflows/kilted-abi-compatibility.yml new file mode 100644 index 0000000000..155013c64d --- /dev/null +++ b/.github/workflows/kilted-abi-compatibility.yml @@ -0,0 +1,27 @@ +name: Kilted - ABI Compatibility Check +on: + workflow_dispatch: + pull_request: + branches: + - kilted + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.yaml' + - '.github/workflows/kilted-abi-compatibility.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers-not-released.kilted.repos' + - '**.xml' + +concurrency: + # cancel previous runs of the same workflow, except for pushes on given branches + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} + +jobs: + abi_check: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-abi-check.yml@master + with: + ros_distro: kilted diff --git a/.github/workflows/kilted-binary-build.yml b/.github/workflows/kilted-binary-build.yml new file mode 100644 index 0000000000..e0a9bce77b --- /dev/null +++ b/.github/workflows/kilted-binary-build.yml @@ -0,0 +1,56 @@ +name: Kilted Binary Build +# author: Denis Ĺ togl +# description: 'Build & test all dependencies from released (binary) packages.' + +on: + workflow_dispatch: + pull_request: + branches: + - kilted + - '*feature*' + - '*feature/**' + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '**.yaml' + - '.github/workflows/kilted-binary-build.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers-not-released.kilted.repos' + - '**.xml' + push: + branches: + - kilted + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.yaml' + - '.github/workflows/kilted-binary-build.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers-not-released.kilted.repos' + - '**.xml' + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '03 1 * * MON-FRI' + +concurrency: + # cancel previous runs of the same workflow, except for pushes on given branches + 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 + strategy: + fail-fast: false + matrix: + ROS_REPO: [main, testing] + with: + ros_distro: kilted + ros_repo: ${{ matrix.ROS_REPO }} + upstream_workspace: ros2_controllers-not-released.kilted.repos + ref_for_scheduled_build: kilted diff --git a/.github/workflows/kilted-check-docs.yml b/.github/workflows/kilted-check-docs.yml new file mode 100644 index 0000000000..189b6df699 --- /dev/null +++ b/.github/workflows/kilted-check-docs.yml @@ -0,0 +1,29 @@ +name: Kilted Check Docs + +on: + workflow_dispatch: + pull_request: + branches: + - kilted + paths: + - '**.rst' + - '**.md' + - '**.jpg' + - '**.jpeg' + - '**.png' + - '**.svg' + - '**.yml' + - '**.yaml' + - '!.github/**' # exclude yaml files in .github directory + - '.github/workflows/kilted-check-docs.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + check-docs: + name: Check Docs + uses: ros-controls/control.ros.org/.github/workflows/reusable-sphinx-check-single-version.yml@kilted + with: + ROS2_CONTROLLERS_PR: ${{ github.ref }} diff --git a/.github/workflows/kilted-coverage-build.yml b/.github/workflows/kilted-coverage-build.yml new file mode 100644 index 0000000000..2862c74d57 --- /dev/null +++ b/.github/workflows/kilted-coverage-build.yml @@ -0,0 +1,45 @@ +name: Coverage Build - Kilted +on: + workflow_dispatch: + push: + branches: + - kilted + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '.github/workflows/kilted-coverage-build.yml' + - '**.yaml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'codecov.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.kilted.repos' + pull_request: + branches: + - kilted + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '.github/workflows/kilted-coverage-build.yml' + - '**.yaml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'codecov.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.kilted.repos' + +concurrency: + # cancel previous runs of the same workflow, except for pushes on given branches + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} + +jobs: + coverage_kilted: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-build-coverage.yml@master + secrets: inherit + with: + ros_distro: kilted diff --git a/.github/workflows/kilted-debian-build.yml b/.github/workflows/kilted-debian-build.yml new file mode 100644 index 0000000000..35fb0d0110 --- /dev/null +++ b/.github/workflows/kilted-debian-build.yml @@ -0,0 +1,35 @@ +name: Kilted - Debian Semi-Binary Build +on: + workflow_dispatch: + pull_request: + branches: + - kilted + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '**.yaml' + - '.github/workflows/kilted-debian-build.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.kilted.repos' + - '**.xml' + schedule: + # Run every day to detect flakiness and broken dependencies + - cron: '03 1 * * MON-FRI' + +concurrency: + # cancel previous runs of the same workflow, except for pushes on given branches + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} + +jobs: + debian_semi_binary_build: + name: Rolling debian build + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-debian-build.yml@master + with: + ros_distro: kilted + upstream_workspace: ros2_controllers.kilted.repos + ref_for_scheduled_build: kilted + skip_packages: rqt_joint_trajectory_controller diff --git a/.github/workflows/kilted-pre-commit.yml b/.github/workflows/kilted-pre-commit.yml new file mode 100644 index 0000000000..fc2d6d0858 --- /dev/null +++ b/.github/workflows/kilted-pre-commit.yml @@ -0,0 +1,20 @@ +name: Pre-Commit - Kilted + +on: + workflow_dispatch: + pull_request: + branches: + - kilted + push: + branches: + - kilted + +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 + with: + ros_distro: kilted diff --git a/.github/workflows/kilted-pre-release.yml b/.github/workflows/kilted-pre-release.yml new file mode 100644 index 0000000000..c2c6b4042b --- /dev/null +++ b/.github/workflows/kilted-pre-release.yml @@ -0,0 +1,27 @@ +name: Kilted - pre-release +# author: Christoph Froehlich + +on: + workflow_dispatch: + inputs: + downstream_depth: + description: 'The depth of the depends-on tree to be included in the overlay workspace (-1 implies unlimited, default: 0)' + required: false + default: 0 + type: number + pull_request: + branches: + - kilted + types: + - opened # default + - reopened # default + - synchronize # default + - labeled # also if a label changes + +jobs: + default: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-prerelease.yml@master + with: + ros_distro: kilted + # downstream_depth is not set on pull_request event + prerelease_downstream_depth: ${{ github.event_name == 'pull_request' && '0' || inputs.downstream_depth }} diff --git a/.github/workflows/kilted-rhel-semi-binary-build.yml b/.github/workflows/kilted-rhel-semi-binary-build.yml new file mode 100644 index 0000000000..79b48aa2cd --- /dev/null +++ b/.github/workflows/kilted-rhel-semi-binary-build.yml @@ -0,0 +1,34 @@ +name: Kilted - RHEL Semi-Binary Build +on: + workflow_dispatch: + pull_request: + branches: + - kilted + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '**.yaml' + - '.github/workflows/kilted-rhel-semi-binary-build.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.kilted.repos' + - '**.xml' + schedule: + # Run every day to detect flakiness and broken dependencies + - cron: '03 1 * * MON-FRI' + +concurrency: + # cancel previous runs of the same workflow, except for pushes on given branches + 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 + with: + ros_distro: kilted + upstream_workspace: ros2_controllers.kilted.repos + ref_for_scheduled_build: kilted + skip_packages: rqt_joint_trajectory_controller diff --git a/.github/workflows/kilted-semi-binary-build.yml b/.github/workflows/kilted-semi-binary-build.yml new file mode 100644 index 0000000000..4ccbc9d87e --- /dev/null +++ b/.github/workflows/kilted-semi-binary-build.yml @@ -0,0 +1,63 @@ +name: Kilted Semi-Binary Build +# description: 'Build & test that compiles the main dependencies from source.' + +on: + workflow_dispatch: + pull_request: + branches: + - kilted + - '*feature*' + - '*feature/**' + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '**.yaml' + - '.github/workflows/kilted-semi-binary-build.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.kilted.repos' + - '**.xml' + push: + branches: + - kilted + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '**.yaml' + - '.github/workflows/kilted-semi-binary-build.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.kilted.repos' + - '**.xml' + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '33 1 * * MON-FRI' + +concurrency: + # cancel previous runs of the same workflow, except for pushes on given branches + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ !startsWith(github.ref, 'refs/heads') }} + +jobs: + semi_binary: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + with: + ros_distro: kilted + ros_repo: testing + upstream_workspace: ros2_controllers.kilted.repos + ref_for_scheduled_build: kilted + semi_binary_clang: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + with: + ros_distro: kilted + ros_repo: testing + upstream_workspace: ros2_controllers.kilted.repos + ref_for_scheduled_build: kilted + additional_debs: clang + c_compiler: clang + cxx_compiler: clang++ + not_test_build: true diff --git a/.github/workflows/kilted-semi-binary-downstream-build.yml b/.github/workflows/kilted-semi-binary-downstream-build.yml new file mode 100644 index 0000000000..9ad1f6cb94 --- /dev/null +++ b/.github/workflows/kilted-semi-binary-downstream-build.yml @@ -0,0 +1,38 @@ +name: Kilted Downstream Build +# description: 'Build & test downstream packages from source.' +# author: Christoph Froehlich + +on: + workflow_dispatch: + pull_request: + branches: + - kilted + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '**.yaml' + - '.github/workflows/kilted-semi-binary-downstream-build.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros_controls.kilted.repos' + - '**.xml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-downstream: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + with: + ros_distro: kilted + ros_repo: testing + ref_for_scheduled_build: kilted + upstream_workspace: ros2_controllers.kilted.repos + # we don't test this repository, we just build it + not_test_build: true + # we test the downstream packages, which are part of our organization + downstream_workspace: ros_controls.kilted.repos + not_test_downstream: false diff --git a/.github/workflows/kilted-source-build.yml b/.github/workflows/kilted-source-build.yml new file mode 100644 index 0000000000..76a2dab12d --- /dev/null +++ b/.github/workflows/kilted-source-build.yml @@ -0,0 +1,33 @@ +name: Kilted Source Build +on: + workflow_dispatch: + push: + branches: + - kilted + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '**.yaml' + - '.github/workflows/kilted-source-build.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_controllers.kilted.repos' + - '**.xml' + pull_request: + branches: + - kilted + paths: + - '.github/workflows/kilted-source-build.yml' + schedule: + # Run every day to detect flakiness and broken dependencies + - cron: '03 3 * * MON-FRI' + +jobs: + source: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-ros-tooling-source-build.yml@master + with: + ros_distro: kilted + ref: kilted + container: ubuntu:24.04 diff --git a/.github/workflows/rolling-abi-compatibility.yml b/.github/workflows/rolling-abi-compatibility.yml index 6ac9220497..20afed10b2 100644 --- a/.github/workflows/rolling-abi-compatibility.yml +++ b/.github/workflows/rolling-abi-compatibility.yml @@ -27,6 +27,6 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [kilted, rolling] + ROS_DISTRO: [rolling] with: ros_distro: ${{ matrix.ROS_DISTRO }} diff --git a/.github/workflows/rolling-binary-build.yml b/.github/workflows/rolling-binary-build.yml index 0bfd29ada5..c3d5762d28 100644 --- a/.github/workflows/rolling-binary-build.yml +++ b/.github/workflows/rolling-binary-build.yml @@ -51,7 +51,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [kilted, rolling] + ROS_DISTRO: [rolling] ROS_REPO: [main, testing] with: ros_distro: ${{ matrix.ROS_DISTRO }} diff --git a/.github/workflows/rolling-debian-build.yml b/.github/workflows/rolling-debian-build.yml index f8f4882b18..7ffcc0093f 100644 --- a/.github/workflows/rolling-debian-build.yml +++ b/.github/workflows/rolling-debian-build.yml @@ -32,7 +32,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [kilted, rolling] + ROS_DISTRO: [rolling] with: ros_distro: ${{ matrix.ROS_DISTRO }} upstream_workspace: ros2_controllers.${{ matrix.ROS_DISTRO }}.repos diff --git a/.github/workflows/rolling-pre-commit.yml b/.github/workflows/rolling-pre-commit.yml index 71465d0e56..54d7e90adf 100644 --- a/.github/workflows/rolling-pre-commit.yml +++ b/.github/workflows/rolling-pre-commit.yml @@ -19,6 +19,6 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [kilted, rolling] + ROS_DISTRO: [rolling] with: ros_distro: ${{ matrix.ROS_DISTRO }} diff --git a/.github/workflows/rolling-pre-release.yml b/.github/workflows/rolling-pre-release.yml index 95609af1cd..3550e647f1 100644 --- a/.github/workflows/rolling-pre-release.yml +++ b/.github/workflows/rolling-pre-release.yml @@ -23,7 +23,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [kilted, rolling] + ROS_DISTRO: [rolling] uses: ros-controls/ros2_control_ci/.github/workflows/reusable-prerelease.yml@master with: diff --git a/.github/workflows/rolling-rhel-semi-binary-build.yml b/.github/workflows/rolling-rhel-semi-binary-build.yml index a00d4603a2..208f2407ba 100644 --- a/.github/workflows/rolling-rhel-semi-binary-build.yml +++ b/.github/workflows/rolling-rhel-semi-binary-build.yml @@ -31,7 +31,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [kilted, rolling] + ROS_DISTRO: [rolling] with: ros_distro: ${{ matrix.ROS_DISTRO }} upstream_workspace: ros2_controllers.${{ matrix.ROS_DISTRO }}.repos diff --git a/.github/workflows/rolling-semi-binary-build.yml b/.github/workflows/rolling-semi-binary-build.yml index 82ff2455a7..59a6f87193 100644 --- a/.github/workflows/rolling-semi-binary-build.yml +++ b/.github/workflows/rolling-semi-binary-build.yml @@ -50,7 +50,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [kilted, rolling] + ROS_DISTRO: [rolling] with: ros_distro: ${{ matrix.ROS_DISTRO }} ros_repo: testing @@ -61,7 +61,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [kilted, rolling] + ROS_DISTRO: [rolling] with: ros_distro: ${{ matrix.ROS_DISTRO }} ros_repo: testing diff --git a/.github/workflows/rolling-semi-binary-downstream-build.yml b/.github/workflows/rolling-semi-binary-downstream-build.yml index bd3cd1490a..317164c4ed 100644 --- a/.github/workflows/rolling-semi-binary-downstream-build.yml +++ b/.github/workflows/rolling-semi-binary-downstream-build.yml @@ -30,7 +30,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [kilted, rolling] + ROS_DISTRO: [rolling] with: ros_distro: ${{ matrix.ROS_DISTRO }} ros_repo: testing diff --git a/.github/workflows/rolling-source-build.yml b/.github/workflows/rolling-source-build.yml index 98f75def4a..34478d1ff7 100644 --- a/.github/workflows/rolling-source-build.yml +++ b/.github/workflows/rolling-source-build.yml @@ -31,7 +31,7 @@ jobs: strategy: fail-fast: false matrix: - ROS_DISTRO: [kilted, rolling] + ROS_DISTRO: [rolling] with: ros_distro: ${{ matrix.ROS_DISTRO }} ref: master diff --git a/README.md b/README.md index 4a0c7916b1..7eaed18d41 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ If you are new to the project, please read the [contributing guide](https://cont ROS2 Distro | Branch | Build status | Documentation | Released packages :---------: | :----: | :----------: | :-----------: | :---------------: **Rolling** | [`master`](https://github.com/ros-controls/ros2_controllers/tree/master) | [![Rolling Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-binary-build.yml?branch=master)
[![Rolling Semi-Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-semi-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/rolling-semi-binary-build.yml?branch=master)
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Rdev__ros2_controllers__ubuntu_noble_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Rdev__ros2_controllers__ubuntu_noble_amd64/) | [control.ros.org](https://control.ros.org/master/doc/ros2_controllers/doc/controllers_index.html) | [![Build Status](https://build.ros2.org/buildStatus/icon?job=Rbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary)](https://build.ros2.org/job/Rbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary/) -**Kilted** | [`master`](https://github.com/ros-controls/ros2_controllers/tree/master) | see above
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Kdev__ros2_controllers__ubuntu_noble_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Kdev__ros2_controllers__ubuntu_noble_amd64/) | [control.ros.org](https://control.ros.org/master/doc/ros2_controllers/doc/controllers_index.html) | [![Build Status](https://build.ros2.org/buildStatus/icon?job=Kbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary)](https://build.ros2.org/job/Kbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary/) +**Kilted** | [`kilted`](https://github.com/ros-controls/ros2_controllers/tree/kilted) | [![Kilted Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/kilted-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/kilted-binary-build.yml?branch=master)
[![Kilted Semi-Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/kilted-semi-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/kilted-semi-binary-build.yml?branch=master)
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Kdev__ros2_controllers__ubuntu_noble_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Kdev__ros2_controllers__ubuntu_noble_amd64/) | [control.ros.org](https://control.ros.org/kilted/doc/ros2_controllers/doc/controllers_index.html) | [![Build Status](https://build.ros2.org/buildStatus/icon?job=Kbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary)](https://build.ros2.org/job/Kbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary/) **Jazzy** | [`jazzy`](https://github.com/ros-controls/ros2_controllers/tree/jazzy) | [![Jazzy Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-binary-build.yml?branch=master)
[![Jazzy Semi-Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-semi-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/jazzy-semi-binary-build.yml?branch=master)
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Jdev__ros2_controllers__ubuntu_noble_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Jdev__ros2_controllers__ubuntu_noble_amd64/) | [control.ros.org](https://control.ros.org/jazzy/doc/ros2_controllers/doc/controllers_index.html) | [![Build Status](https://build.ros2.org/buildStatus/icon?job=Jbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary)](https://build.ros2.org/job/Jbin_uN64__ros2_controllers__ubuntu_noble_amd64__binary/) **Humble** | [`humble`](https://github.com/ros-controls/ros2_controllers/tree/humble) | [![Humble Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-binary-build.yml?branch=master)
[![Humble Semi-Binary Build](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-semi-binary-build.yml/badge.svg?branch=master)](https://github.com/ros-controls/ros2_controllers/actions/workflows/humble-semi-binary-build.yml?branch=master)
[![build.ros2.org](https://build.ros2.org/buildStatus/icon?job=Hdev__ros2_controllers__ubuntu_jammy_amd64&subject=build.ros2.org)](https://build.ros2.org/job/Hdev__ros2_controllers__ubuntu_jammy_amd64/) | [control.ros.org](https://control.ros.org/humble/doc/ros2_controllers/doc/controllers_index.html) | [![Build Status](https://build.ros2.org/buildStatus/icon?job=Hbin_uJ64__ros2_controllers__ubuntu_jammy_amd64__binary)](https://build.ros2.org/job/Hbin_uJ64__ros2_controllers__ubuntu_jammy_amd64__binary/) diff --git a/ros2_controllers.kilted.repos b/ros2_controllers.kilted.repos index f6462c4b4f..5c05b397ed 100644 --- a/ros2_controllers.kilted.repos +++ b/ros2_controllers.kilted.repos @@ -2,11 +2,11 @@ repositories: ros2_control: type: git url: https://github.com/ros-controls/ros2_control.git - version: master + version: kilted realtime_tools: type: git url: https://github.com/ros-controls/realtime_tools.git - version: master + version: kilted control_msgs: type: git url: https://github.com/ros-controls/control_msgs.git From 05d7249beb96d3be9202ea40fa06208e269e8b4b Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 09:57:50 +0200 Subject: [PATCH 095/108] [CI] Use YAML anchors (backport #1953) (#1955) --- .github/workflows/humble-binary-build.yml | 17 ++--------------- .github/workflows/humble-coverage-build.yml | 18 ++---------------- .github/workflows/humble-semi-binary-build.yml | 17 ++--------------- .github/workflows/jazzy-binary-build.yml | 16 ++-------------- .github/workflows/jazzy-coverage-build.yml | 18 ++---------------- .github/workflows/jazzy-semi-binary-build.yml | 17 ++--------------- .github/workflows/kilted-binary-build.yml | 16 ++-------------- .github/workflows/kilted-coverage-build.yml | 18 ++---------------- .github/workflows/kilted-semi-binary-build.yml | 17 ++--------------- .github/workflows/rolling-binary-build.yml | 18 ++---------------- ...lling-compatibility-humble-binary-build.yml | 17 ++--------------- ...olling-compatibility-jazzy-binary-build.yml | 17 ++--------------- ...lling-compatibility-kilted-binary-build.yml | 17 ++--------------- .github/workflows/rolling-coverage-build.yml | 18 ++---------------- .../rolling-semi-binary-build-win.yml | 16 ++-------------- .../workflows/rolling-semi-binary-build.yml | 18 ++---------------- 16 files changed, 32 insertions(+), 243 deletions(-) diff --git a/.github/workflows/humble-binary-build.yml b/.github/workflows/humble-binary-build.yml index 2c202eb4ee..c7e5aebf73 100644 --- a/.github/workflows/humble-binary-build.yml +++ b/.github/workflows/humble-binary-build.yml @@ -4,21 +4,7 @@ name: Humble Binary Build on: workflow_dispatch: - pull_request: - branches: - - humble - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/humble-binary-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers-not-released.humble.repos' - - '**.xml' - push: + pull_request: &event branches: - humble paths: @@ -32,6 +18,7 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers-not-released.humble.repos' - '**.xml' + push: *event schedule: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * MON-FRI' diff --git a/.github/workflows/humble-coverage-build.yml b/.github/workflows/humble-coverage-build.yml index 9b5490faa9..c826935710 100644 --- a/.github/workflows/humble-coverage-build.yml +++ b/.github/workflows/humble-coverage-build.yml @@ -1,22 +1,7 @@ name: Coverage Build - Humble on: workflow_dispatch: - push: - branches: - - humble - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/humble-coverage-build.yml' - - 'codecov.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.humble.repos' - - '**.xml' - pull_request: + pull_request: &event branches: - humble paths: @@ -31,6 +16,7 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers.humble.repos' - '**.xml' + push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/humble-semi-binary-build.yml b/.github/workflows/humble-semi-binary-build.yml index 2ed8c6b235..76af7b33eb 100644 --- a/.github/workflows/humble-semi-binary-build.yml +++ b/.github/workflows/humble-semi-binary-build.yml @@ -3,21 +3,7 @@ name: Humble Semi-Binary Build on: workflow_dispatch: - pull_request: - branches: - - humble - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/humble-semi-binary-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.humble.repos' - - '**.xml' - push: + pull_request: &event branches: - humble paths: @@ -31,6 +17,7 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers.humble.repos' - '**.xml' + push: *event schedule: # Run every morning to detect flakiness and broken dependencies - cron: '33 1 * * MON-FRI' diff --git a/.github/workflows/jazzy-binary-build.yml b/.github/workflows/jazzy-binary-build.yml index b4cf99e8f7..70b0f364f9 100644 --- a/.github/workflows/jazzy-binary-build.yml +++ b/.github/workflows/jazzy-binary-build.yml @@ -4,7 +4,7 @@ name: Jazzy Binary Build on: workflow_dispatch: - pull_request: + pull_request: &event branches: - jazzy - '*feature*' @@ -20,19 +20,7 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers-not-released.jazzy.repos' - '**.xml' - push: - branches: - - jazzy - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.yaml' - - '.github/workflows/jazzy-binary-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers-not-released.jazzy.repos' - - '**.xml' + push: *event schedule: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * MON-FRI' diff --git a/.github/workflows/jazzy-coverage-build.yml b/.github/workflows/jazzy-coverage-build.yml index a519b0263a..29ff6aba44 100644 --- a/.github/workflows/jazzy-coverage-build.yml +++ b/.github/workflows/jazzy-coverage-build.yml @@ -1,22 +1,7 @@ name: Coverage Build - Jazzy on: workflow_dispatch: - push: - branches: - - jazzy - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '.github/workflows/jazzy-coverage-build.yml' - - '**.yaml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'codecov.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.jazzy.repos' - pull_request: + pull_request: &event branches: - jazzy paths: @@ -31,6 +16,7 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers.jazzy.repos' + push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/jazzy-semi-binary-build.yml b/.github/workflows/jazzy-semi-binary-build.yml index 69f74a56b6..5adf2f413d 100644 --- a/.github/workflows/jazzy-semi-binary-build.yml +++ b/.github/workflows/jazzy-semi-binary-build.yml @@ -3,7 +3,7 @@ name: Jazzy Semi-Binary Build on: workflow_dispatch: - pull_request: + pull_request: &event branches: - jazzy - '*feature*' @@ -19,20 +19,7 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers.jazzy.repos' - '**.xml' - push: - branches: - - jazzy - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/jazzy-semi-binary-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.jazzy.repos' - - '**.xml' + push: *event schedule: # Run every morning to detect flakiness and broken dependencies - cron: '33 1 * * MON-FRI' diff --git a/.github/workflows/kilted-binary-build.yml b/.github/workflows/kilted-binary-build.yml index e0a9bce77b..816b0fa065 100644 --- a/.github/workflows/kilted-binary-build.yml +++ b/.github/workflows/kilted-binary-build.yml @@ -4,7 +4,7 @@ name: Kilted Binary Build on: workflow_dispatch: - pull_request: + pull_request: &event branches: - kilted - '*feature*' @@ -20,19 +20,7 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers-not-released.kilted.repos' - '**.xml' - push: - branches: - - kilted - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.yaml' - - '.github/workflows/kilted-binary-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers-not-released.kilted.repos' - - '**.xml' + push: *event schedule: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * MON-FRI' diff --git a/.github/workflows/kilted-coverage-build.yml b/.github/workflows/kilted-coverage-build.yml index 2862c74d57..2cb96a1be7 100644 --- a/.github/workflows/kilted-coverage-build.yml +++ b/.github/workflows/kilted-coverage-build.yml @@ -1,22 +1,7 @@ name: Coverage Build - Kilted on: workflow_dispatch: - push: - branches: - - kilted - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '.github/workflows/kilted-coverage-build.yml' - - '**.yaml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'codecov.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.kilted.repos' - pull_request: + pull_request: &event branches: - kilted paths: @@ -31,6 +16,7 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_controllers.kilted.repos' + push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/kilted-semi-binary-build.yml b/.github/workflows/kilted-semi-binary-build.yml index 4ccbc9d87e..cffc6eab28 100644 --- a/.github/workflows/kilted-semi-binary-build.yml +++ b/.github/workflows/kilted-semi-binary-build.yml @@ -3,7 +3,7 @@ name: Kilted Semi-Binary Build on: workflow_dispatch: - pull_request: + pull_request: &event branches: - kilted - '*feature*' @@ -19,20 +19,7 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers.kilted.repos' - '**.xml' - push: - branches: - - kilted - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/kilted-semi-binary-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.kilted.repos' - - '**.xml' + push: *event schedule: # Run every morning to detect flakiness and broken dependencies - cron: '33 1 * * MON-FRI' diff --git a/.github/workflows/rolling-binary-build.yml b/.github/workflows/rolling-binary-build.yml index c3d5762d28..61a201d097 100644 --- a/.github/workflows/rolling-binary-build.yml +++ b/.github/workflows/rolling-binary-build.yml @@ -4,7 +4,7 @@ name: Rolling Binary Build on: workflow_dispatch: - pull_request: + pull_request: &event branches: - master - '*feature*' @@ -21,21 +21,7 @@ on: - 'ros2_controllers-not-released.rolling.repos' - 'ros2_controllers-not-released.kilted.repos' - '**.xml' - push: - branches: - - master - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/rolling-binary-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers-not-released.rolling.repos' - - 'ros2_controllers-not-released.kilted.repos' - - '**.xml' + push: *event schedule: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * MON-FRI' diff --git a/.github/workflows/rolling-compatibility-humble-binary-build.yml b/.github/workflows/rolling-compatibility-humble-binary-build.yml index fc37f5baa5..f7884cf804 100644 --- a/.github/workflows/rolling-compatibility-humble-binary-build.yml +++ b/.github/workflows/rolling-compatibility-humble-binary-build.yml @@ -4,7 +4,7 @@ name: Check Rolling Compatibility on Humble on: workflow_dispatch: - pull_request: + pull_request: &event branches: - master - '*feature*' @@ -20,20 +20,7 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers.rolling.repos' - '**.xml' - push: - branches: - - master - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/rolling-compatibility-humble-binary-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.rolling.repos' - - '**.xml' + push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-compatibility-jazzy-binary-build.yml b/.github/workflows/rolling-compatibility-jazzy-binary-build.yml index ec4472e745..9bd04e2ad0 100644 --- a/.github/workflows/rolling-compatibility-jazzy-binary-build.yml +++ b/.github/workflows/rolling-compatibility-jazzy-binary-build.yml @@ -4,7 +4,7 @@ name: Check Rolling Compatibility on Jazzy on: workflow_dispatch: - pull_request: + pull_request: &event branches: - master - '*feature*' @@ -20,20 +20,7 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers.rolling.repos' - '**.xml' - push: - branches: - - master - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/rolling-compatibility-jazzy-binary-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.rolling.repos' - - '**.xml' + push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-compatibility-kilted-binary-build.yml b/.github/workflows/rolling-compatibility-kilted-binary-build.yml index e45283b4d2..1d8c3b3bb2 100644 --- a/.github/workflows/rolling-compatibility-kilted-binary-build.yml +++ b/.github/workflows/rolling-compatibility-kilted-binary-build.yml @@ -4,7 +4,7 @@ name: Check Rolling Compatibility on Kilted on: workflow_dispatch: - pull_request: + pull_request: &event branches: - master - '*feature*' @@ -20,20 +20,7 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers.rolling.repos' - '**.xml' - push: - branches: - - master - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/rolling-compatibility-kilted-binary-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.rolling.repos' - - '**.xml' + push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-coverage-build.yml b/.github/workflows/rolling-coverage-build.yml index 6277ad018c..906f710d7d 100644 --- a/.github/workflows/rolling-coverage-build.yml +++ b/.github/workflows/rolling-coverage-build.yml @@ -1,22 +1,7 @@ name: Coverage Build - Rolling on: workflow_dispatch: - push: - branches: - - master - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/rolling-coverage-build.yml' - - 'codecov.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.rolling.repos' - - '**.xml' - pull_request: + pull_request: &event branches: - master paths: @@ -31,6 +16,7 @@ on: - '**/CMakeLists.txt' - 'ros2_controllers.rolling.repos' - '**.xml' + push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-semi-binary-build-win.yml b/.github/workflows/rolling-semi-binary-build-win.yml index 4fb8302dfb..88fa295207 100644 --- a/.github/workflows/rolling-semi-binary-build-win.yml +++ b/.github/workflows/rolling-semi-binary-build-win.yml @@ -4,7 +4,7 @@ name: Rolling Windows Semi-Binary Build on: workflow_dispatch: - pull_request: + pull_request: &event branches: - master paths: @@ -15,19 +15,7 @@ on: - '.github/workflows/rolling-semi-binary-build-win.yml' - '**/package.xml' - '**/CMakeLists.txt' - - 'ros2_controllers.rolling.repos' - push: - branches: - - master - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '.github/workflows/rolling-semi-binary-build-win.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.rolling.repos' + push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-semi-binary-build.yml b/.github/workflows/rolling-semi-binary-build.yml index 59a6f87193..4be9be1678 100644 --- a/.github/workflows/rolling-semi-binary-build.yml +++ b/.github/workflows/rolling-semi-binary-build.yml @@ -3,7 +3,7 @@ name: Rolling Semi-Binary Build on: workflow_dispatch: - pull_request: + pull_request: &event branches: - master - '*feature*' @@ -20,21 +20,7 @@ on: - 'ros2_controllers.rolling.repos' - 'ros2_controllers.kilted.repos' - '**.xml' - push: - branches: - - master - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/rolling-semi-binary-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_controllers.rolling.repos' - - 'ros2_controllers.kilted.repos' - - '**.xml' + push: *event schedule: # Run every morning to detect flakiness and broken dependencies - cron: '33 1 * * MON-FRI' From 1aad51b550f1a7723aea317bdbac217e603a31e5 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 10:08:42 +0200 Subject: [PATCH 096/108] Remove unused `get_state_msg` method (backport #1949) (#1950) --- .../test/test_trajectory_controller_utils.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp index bd1c0b494c..b4c7cdf5f6 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp +++ b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp @@ -206,11 +206,6 @@ class TestableJointTrajectoryController trajectory_msgs::msg::JointTrajectoryPoint get_state_error() { return state_error_; } trajectory_msgs::msg::JointTrajectoryPoint get_current_command() { return command_current_; } - control_msgs::msg::JointTrajectoryControllerState get_state_msg() - { - return state_publisher_->get_msg(); - } - /** * a copy of the private member function */ From 8287413c7b5819fcd2bfbdc9cb6b36596da55b04 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 11 Oct 2025 11:56:00 +0200 Subject: [PATCH 097/108] Fix JTC crashing when shutdown while executing (backport #1960) (#1962) --- .../joint_trajectory_controller/joint_trajectory_controller.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp index 560a726e7d..05d5fe992c 100644 --- a/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp +++ b/joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp @@ -173,8 +173,8 @@ class JointTrajectoryController : public controller_interface::ControllerInterfa using RealtimeGoalHandlePtr = std::shared_ptr; using RealtimeGoalHandleBuffer = realtime_tools::RealtimeBuffer; + RealtimeGoalHandleBuffer rt_active_goal_; ///< Currently active action goal, if any. rclcpp_action::Server::SharedPtr action_server_; - RealtimeGoalHandleBuffer rt_active_goal_; ///< Currently active action goal, if any. std::atomic rt_has_pending_goal_{false}; ///< Is there a pending action goal? rclcpp::TimerBase::SharedPtr goal_handle_timer_; rclcpp::Duration action_monitor_period_ = rclcpp::Duration(50ms); From 8b9a22300970a0d6dacf1f43d6344b0501bc0dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Mon, 13 Oct 2025 10:32:19 +0200 Subject: [PATCH 098/108] Fix upstream Pid class deprecation warnings (#1959) --- .../src/joint_trajectory_controller.cpp | 5 ++-- ...oint_trajectory_controller_parameters.yaml | 24 +++++++++---------- .../test/test_trajectory_controller.cpp | 1 + .../test/test_trajectory_controller_utils.hpp | 9 ++++++- pid_controller/src/pid_controller.yaml | 4 ++-- .../test/pid_controller_params.yaml | 4 ++-- .../test/pid_controller_preceding_params.yaml | 3 +++ 7 files changed, 31 insertions(+), 19 deletions(-) diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index f5630c302e..e9d498edcc 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -1764,8 +1764,9 @@ void JointTrajectoryController::update_pids() const auto & gains = params_.gains.joints_map.at(params_.joints.at(map_cmd_to_joints_[i])); control_toolbox::AntiWindupStrategy antiwindup_strat; antiwindup_strat.set_type(gains.antiwindup_strategy); - antiwindup_strat.i_max = gains.i_clamp; - antiwindup_strat.i_min = -gains.i_clamp; + // deprecated parameter i_clamp: i_clamp_max and i_clamp_min have precedence over i_clamp + antiwindup_strat.i_max = std::isfinite(gains.i_clamp_max) ? gains.i_clamp_max : gains.i_clamp; + antiwindup_strat.i_min = std::isfinite(gains.i_clamp_min) ? gains.i_clamp_min : -gains.i_clamp; antiwindup_strat.error_deadband = gains.error_deadband; antiwindup_strat.tracking_time_constant = gains.tracking_time_constant; if (pids_[i]) diff --git a/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml b/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml index 44748368ef..b06c8c2e26 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml +++ b/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml @@ -132,8 +132,18 @@ joint_trajectory_controller: } i_clamp: { type: double, - default_value: 0.0, - description: "Integral clamp. Symmetrical in both positive and negative direction." + default_value: .inf, + description: "[Deprecated, use i_clamp_max/i_clamp_min] Integral clamp. Symmetrical in both positive and negative direction." + } + i_clamp_max: { + type: double, + default_value: .inf, + description: "Upper integral clamp." + } + i_clamp_min: { + type: double, + default_value: -.inf, + description: "Lower integral clamp." } ff_velocity_scale: { type: double, @@ -150,16 +160,6 @@ joint_trajectory_controller: default_value: -.inf, description: "Lower output clamp." } - i_clamp_max: { - type: double, - default_value: 0.0, - description: "[Deprecated, see antiwindup_strategy] Upper integral clamp." - } - i_clamp_min: { - type: double, - default_value: 0.0, - description: "[Deprecated, see antiwindup_strategy] Lower integral clamp." - } antiwindup_strategy: { type: string, default_value: "legacy", diff --git a/joint_trajectory_controller/test/test_trajectory_controller.cpp b/joint_trajectory_controller/test/test_trajectory_controller.cpp index 4ba095feee..eecceeee70 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller.cpp +++ b/joint_trajectory_controller/test/test_trajectory_controller.cpp @@ -191,6 +191,7 @@ TEST_P(TrajectoryControllerTestParameterized, correct_initialization_using_param { rclcpp::executors::MultiThreadedExecutor executor; SetUpTrajectoryController(executor); + SetPidParameters(0.0, 1.0); traj_controller_->get_node()->set_parameter( rclcpp::Parameter("allow_nonzero_velocity_at_trajectory_end", true)); traj_controller_->get_node()->set_parameter(rclcpp::Parameter("update_rate", 10)); diff --git a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp index b4c7cdf5f6..b05c7a8116 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp +++ b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp @@ -279,11 +279,18 @@ class TrajectoryControllerTest : public ::testing::Test traj_controller_ = std::make_shared(); auto node_options = rclcpp::NodeOptions(); + // read-only parameters have to be set before init std::vector parameter_overrides; parameter_overrides.push_back(rclcpp::Parameter("joints", joint_names_)); parameter_overrides.push_back( rclcpp::Parameter("command_interfaces", command_interface_types_)); parameter_overrides.push_back(rclcpp::Parameter("state_interfaces", state_interface_types_)); + // avoid deprecation warning for legacy (default) antiwindup strategy + for (const auto & joint : joint_names_) + { + parameter_overrides.push_back( + rclcpp::Parameter("gains." + joint + ".antiwindup_strategy", "none")); + } parameter_overrides.insert(parameter_overrides.end(), parameters.begin(), parameters.end()); node_options.parameter_overrides(parameter_overrides); traj_controller_->set_node_options(node_options); @@ -303,7 +310,7 @@ class TrajectoryControllerTest : public ::testing::Test const rclcpp::Parameter k_p(prefix + ".p", p_value); const rclcpp::Parameter k_i(prefix + ".i", 0.0); const rclcpp::Parameter k_d(prefix + ".d", 0.0); - const rclcpp::Parameter i_clamp(prefix + ".i_clamp", 0.0); + const rclcpp::Parameter i_clamp(prefix + ".i_clamp", 1000.0); const rclcpp::Parameter ff_velocity_scale(prefix + ".ff_velocity_scale", ff_value); node->set_parameters({k_p, k_i, k_d, i_clamp, ff_velocity_scale}); } diff --git a/pid_controller/src/pid_controller.yaml b/pid_controller/src/pid_controller.yaml index 0ec150c5ab..46d7d3748a 100644 --- a/pid_controller/src/pid_controller.yaml +++ b/pid_controller/src/pid_controller.yaml @@ -85,12 +85,12 @@ pid_controller: } i_clamp_max: { type: double, - default_value: 0.0, + default_value: .inf, description: "[Deprecated, see antiwindup_strategy] Upper integral clamp." } i_clamp_min: { type: double, - default_value: 0.0, + default_value: -.inf, description: "[Deprecated, see antiwindup_strategy] Lower integral clamp." } antiwindup_strategy: { diff --git a/pid_controller/test/pid_controller_params.yaml b/pid_controller/test/pid_controller_params.yaml index f8b27f1d49..87b0cb3176 100644 --- a/pid_controller/test/pid_controller_params.yaml +++ b/pid_controller/test/pid_controller_params.yaml @@ -2,8 +2,8 @@ ros__parameters: # TODO(christohfroehlich): Remove this global parameters once the deprecated antiwindup parameters are removed. gains: - joint1: {antiwindup_strategy: "none", i_clamp_max: .inf, i_clamp_min: -.inf} - joint2: {antiwindup_strategy: "none", i_clamp_max: .inf, i_clamp_min: -.inf} + joint1: {antiwindup_strategy: "none",} + joint2: {antiwindup_strategy: "none",} test_pid_controller: ros__parameters: diff --git a/pid_controller/test/pid_controller_preceding_params.yaml b/pid_controller/test/pid_controller_preceding_params.yaml index 673abfe08e..b5ec89c2f5 100644 --- a/pid_controller/test/pid_controller_preceding_params.yaml +++ b/pid_controller/test/pid_controller_preceding_params.yaml @@ -9,3 +9,6 @@ test_pid_controller: reference_and_state_dof_names: - joint1state + + gains: + joint1: {antiwindup_strategy: "none"} From 6c8129376b6e0f697d729b735a147af5aaa44632 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 15 Oct 2025 13:40:39 +0200 Subject: [PATCH 099/108] [CI] Use kilted branch of control_toolbox (backport #1963) (#1965) --- ros2_controllers.kilted.repos | 2 +- ros2_controllers.rolling.repos | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ros2_controllers.kilted.repos b/ros2_controllers.kilted.repos index 5c05b397ed..4953c9faab 100644 --- a/ros2_controllers.kilted.repos +++ b/ros2_controllers.kilted.repos @@ -14,7 +14,7 @@ repositories: control_toolbox: type: git url: https://github.com/ros-controls/control_toolbox.git - version: ros2-master + version: kilted kinematics_interface: type: git url: https://github.com/ros-controls/kinematics_interface.git diff --git a/ros2_controllers.rolling.repos b/ros2_controllers.rolling.repos index f6462c4b4f..067271620f 100644 --- a/ros2_controllers.rolling.repos +++ b/ros2_controllers.rolling.repos @@ -14,7 +14,7 @@ repositories: control_toolbox: type: git url: https://github.com/ros-controls/control_toolbox.git - version: ros2-master + version: master kinematics_interface: type: git url: https://github.com/ros-controls/kinematics_interface.git From 708f8317ca42c06db76f49b7c92b232348da787e Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 17 Oct 2025 10:11:55 +0200 Subject: [PATCH 100/108] fix issue of not listing new JTCs (backport #1891) (#1969) --- .../joint_limits_urdf.py | 90 +++++++++---------- .../rqt_joint_trajectory_controller/utils.py | 2 + 2 files changed, 47 insertions(+), 45 deletions(-) diff --git a/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/joint_limits_urdf.py b/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/joint_limits_urdf.py index e77c4410dd..1e5e80b7a9 100644 --- a/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/joint_limits_urdf.py +++ b/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/joint_limits_urdf.py @@ -71,55 +71,55 @@ def get_joint_limits(node, joints_names, use_smallest_joint_limits=True): continue name = child.getAttribute("name") - if name in joints_names: + try: + limit = child.getElementsByTagName("limit")[0] try: - limit = child.getElementsByTagName("limit")[0] - try: - minval = float(limit.getAttribute("lower")) - maxval = float(limit.getAttribute("upper")) - except ValueError: - if jtype == "continuous": - minval = -pi - maxval = pi - else: - raise Exception( - f"Missing lower/upper position limits for the joint : {name} of type : {jtype} in the robot_description!" - ) - try: - maxvel = float(limit.getAttribute("velocity")) - except ValueError: + minval = float(limit.getAttribute("lower")) + maxval = float(limit.getAttribute("upper")) + except ValueError: + if jtype == "continuous": + minval = -pi + maxval = pi + else: raise Exception( - f"Missing velocity limits for the joint : {name} of type : {jtype} in the robot_description!" + f"Missing lower/upper position limits for the joint : {name} of type : {jtype} in the robot_description!" ) - except IndexError: + try: + maxvel = float(limit.getAttribute("velocity")) + except ValueError: + raise Exception( + f"Missing velocity limits for the joint : {name} of type : {jtype} in the robot_description!" + ) + except IndexError: + if name in joints_names: raise Exception( f"Missing limits tag for the joint : {name} in the robot_description!" ) - safety_tags = child.getElementsByTagName("safety_controller") - if use_small and len(safety_tags) == 1: - tag = safety_tags[0] - if tag.hasAttribute("soft_lower_limit"): - minval = max(minval, float(tag.getAttribute("soft_lower_limit"))) - if tag.hasAttribute("soft_upper_limit"): - maxval = min(maxval, float(tag.getAttribute("soft_upper_limit"))) - - mimic_tags = child.getElementsByTagName("mimic") - if use_mimic and len(mimic_tags) == 1: - tag = mimic_tags[0] - entry = {"parent": tag.getAttribute("joint")} - if tag.hasAttribute("multiplier"): - entry["factor"] = float(tag.getAttribute("multiplier")) - if tag.hasAttribute("offset"): - entry["offset"] = float(tag.getAttribute("offset")) - - dependent_joints[name] = entry - continue - - if name in dependent_joints: - continue - - joint = {"min_position": minval, "max_position": maxval} - joint["has_position_limits"] = jtype != "continuous" - joint["max_velocity"] = maxvel - free_joints[name] = joint + safety_tags = child.getElementsByTagName("safety_controller") + if use_small and len(safety_tags) == 1: + tag = safety_tags[0] + if tag.hasAttribute("soft_lower_limit"): + minval = max(minval, float(tag.getAttribute("soft_lower_limit"))) + if tag.hasAttribute("soft_upper_limit"): + maxval = min(maxval, float(tag.getAttribute("soft_upper_limit"))) + + mimic_tags = child.getElementsByTagName("mimic") + if use_mimic and len(mimic_tags) == 1: + tag = mimic_tags[0] + entry = {"parent": tag.getAttribute("joint")} + if tag.hasAttribute("multiplier"): + entry["factor"] = float(tag.getAttribute("multiplier")) + if tag.hasAttribute("offset"): + entry["offset"] = float(tag.getAttribute("offset")) + + dependent_joints[name] = entry + continue + + if name in dependent_joints: + continue + + joint = {"min_position": minval, "max_position": maxval} + joint["has_position_limits"] = jtype != "continuous" + joint["max_velocity"] = maxvel + free_joints[name] = joint return free_joints diff --git a/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/utils.py b/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/utils.py index 577cc1ab07..ec857b623d 100644 --- a/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/utils.py +++ b/rqt_joint_trajectory_controller/rqt_joint_trajectory_controller/utils.py @@ -152,6 +152,8 @@ def _srv_exists(node, srv_name, srv_type): srv_list = node.get_service_names_and_types() srv_info = [item for item in srv_list if item[0] == srv_name] + if len(srv_info) == 0: + return False srv_obtained_type = srv_info[0][1][0] return srv_type == srv_obtained_type From 8fbc30ac0a6f343e22666137a2e5d1a395e382ac Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Fri, 17 Oct 2025 08:12:58 +0000 Subject: [PATCH 101/108] Update changelog --- ackermann_steering_controller/CHANGELOG.rst | 3 +++ admittance_controller/CHANGELOG.rst | 3 +++ bicycle_steering_controller/CHANGELOG.rst | 3 +++ chained_filter_controller/CHANGELOG.rst | 3 +++ diff_drive_controller/CHANGELOG.rst | 5 +++++ effort_controllers/CHANGELOG.rst | 3 +++ force_torque_sensor_broadcaster/CHANGELOG.rst | 5 +++++ forward_command_controller/CHANGELOG.rst | 3 +++ gpio_controllers/CHANGELOG.rst | 3 +++ gps_sensor_broadcaster/CHANGELOG.rst | 3 +++ gripper_controllers/CHANGELOG.rst | 3 +++ imu_sensor_broadcaster/CHANGELOG.rst | 3 +++ joint_state_broadcaster/CHANGELOG.rst | 3 +++ joint_trajectory_controller/CHANGELOG.rst | 8 ++++++++ mecanum_drive_controller/CHANGELOG.rst | 3 +++ omni_wheel_drive_controller/CHANGELOG.rst | 3 +++ parallel_gripper_controller/CHANGELOG.rst | 3 +++ pid_controller/CHANGELOG.rst | 5 +++++ pose_broadcaster/CHANGELOG.rst | 3 +++ position_controllers/CHANGELOG.rst | 3 +++ range_sensor_broadcaster/CHANGELOG.rst | 3 +++ ros2_controllers/CHANGELOG.rst | 3 +++ ros2_controllers_test_nodes/CHANGELOG.rst | 3 +++ rqt_joint_trajectory_controller/CHANGELOG.rst | 5 +++++ steering_controllers_library/CHANGELOG.rst | 3 +++ tricycle_controller/CHANGELOG.rst | 5 +++++ tricycle_steering_controller/CHANGELOG.rst | 3 +++ velocity_controllers/CHANGELOG.rst | 3 +++ 28 files changed, 99 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 7d68848cb5..fab01e0f25 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index b5d7380651..5567e43f25 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index e3ae9e8d0d..b75776bf00 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) diff --git a/chained_filter_controller/CHANGELOG.rst b/chained_filter_controller/CHANGELOG.rst index 34522b6115..01e756e0df 100644 --- a/chained_filter_controller/CHANGELOG.rst +++ b/chained_filter_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package chained_filter_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 45773e929e..cfaea8ef5a 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Don't use `msg\_` field of realtime publisher (backport `#1947 `_) (`#1948 `_) +* Contributors: mergify[bot] + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 42abea348e..8a46782f3e 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index bdce62d40e..ea654d5a2c 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Don't use `msg\_` field of realtime publisher (backport `#1947 `_) (`#1948 `_) +* Contributors: mergify[bot] + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 0516fcb96e..cb5a4b9446 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 2ccd28e2c9..20b2a0ff30 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 66dc3637df..52644d31c3 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index f2f80d83bf..d2881aa1f1 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Use new handles API in ros2_controllers to fix deprecation warnings (backport `#1566 `_) (`#1934 `_) diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 296c177ae5..e6d84e3d17 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 19dea1e1a3..85fc5732ab 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 6d46c5a746..a5a41a3b14 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,14 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix upstream Pid class deprecation warnings (`#1959 `_) +* Fix JTC crashing when shutdown while executing (backport `#1960 `_) (`#1962 `_) +* Remove unused `get_state_msg` method (backport `#1949 `_) (`#1950 `_) +* Don't use `msg\_` field of realtime publisher (backport `#1947 `_) (`#1948 `_) +* Contributors: Christoph FrĂśhlich, mergify[bot] + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index 3e5b66681e..cf4180191b 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst index 9566c7bc5b..8e72d442b8 100644 --- a/omni_wheel_drive_controller/CHANGELOG.rst +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package omni_wheel_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Fix: Remove deprecated `rclcpp::spin_some(node)` (backport `#1928 `_) (`#1932 `_) diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 2ae9a94ae8..701f2382fc 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index 8deb2ae51c..a09ac6997d 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fix upstream Pid class deprecation warnings (`#1959 `_) +* Contributors: Christoph FrĂśhlich + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 9df61c01ea..85a0553334 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 924f652fe4..7c81828a93 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index a98a2250ec..e85f8aed78 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 9077b0a583..34179b2a80 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 0ce28b397b..10200bca87 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 4e3493e9b1..e8db0328e7 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* fix issue of not listing new JTCs (backport `#1891 `_) (`#1969 `_) +* Contributors: mergify[bot] + 4.33.0 (2025-10-03) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 1cc7688545..40ab87ae10 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index ecc198d2ff..1b894b257d 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Don't use `msg\_` field of realtime publisher (backport `#1947 `_) (`#1948 `_) +* Contributors: mergify[bot] + 4.33.0 (2025-10-03) ------------------- * Update API for realtime publisher (backport `#1830 `_) (`#1944 `_) diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 392f1b5f28..4f8cdfd72a 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index d97ec79e43..89cf8edaf0 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 4.33.0 (2025-10-03) ------------------- * Update realtime containers (backport `#1721 `_) (`#1935 `_) From 5b1b0f9bef8ca31ba4e0883d9be48164a9f03251 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Fri, 17 Oct 2025 08:13:30 +0000 Subject: [PATCH 102/108] 4.33.1 --- ackermann_steering_controller/CHANGELOG.rst | 4 ++-- ackermann_steering_controller/package.xml | 2 +- admittance_controller/CHANGELOG.rst | 4 ++-- admittance_controller/package.xml | 2 +- bicycle_steering_controller/CHANGELOG.rst | 4 ++-- bicycle_steering_controller/package.xml | 2 +- chained_filter_controller/CHANGELOG.rst | 4 ++-- chained_filter_controller/package.xml | 2 +- diff_drive_controller/CHANGELOG.rst | 4 ++-- diff_drive_controller/package.xml | 2 +- effort_controllers/CHANGELOG.rst | 4 ++-- effort_controllers/package.xml | 2 +- force_torque_sensor_broadcaster/CHANGELOG.rst | 4 ++-- force_torque_sensor_broadcaster/package.xml | 2 +- forward_command_controller/CHANGELOG.rst | 4 ++-- forward_command_controller/package.xml | 2 +- gpio_controllers/CHANGELOG.rst | 4 ++-- gpio_controllers/package.xml | 2 +- gps_sensor_broadcaster/CHANGELOG.rst | 4 ++-- gps_sensor_broadcaster/package.xml | 2 +- gripper_controllers/CHANGELOG.rst | 4 ++-- gripper_controllers/package.xml | 2 +- imu_sensor_broadcaster/CHANGELOG.rst | 4 ++-- imu_sensor_broadcaster/package.xml | 2 +- joint_state_broadcaster/CHANGELOG.rst | 4 ++-- joint_state_broadcaster/package.xml | 2 +- joint_trajectory_controller/CHANGELOG.rst | 4 ++-- joint_trajectory_controller/package.xml | 2 +- mecanum_drive_controller/CHANGELOG.rst | 4 ++-- mecanum_drive_controller/package.xml | 2 +- omni_wheel_drive_controller/CHANGELOG.rst | 4 ++-- omni_wheel_drive_controller/package.xml | 2 +- parallel_gripper_controller/CHANGELOG.rst | 4 ++-- parallel_gripper_controller/package.xml | 2 +- pid_controller/CHANGELOG.rst | 4 ++-- pid_controller/package.xml | 2 +- pose_broadcaster/CHANGELOG.rst | 4 ++-- pose_broadcaster/package.xml | 2 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/package.xml | 2 +- range_sensor_broadcaster/CHANGELOG.rst | 4 ++-- range_sensor_broadcaster/package.xml | 2 +- ros2_controllers/CHANGELOG.rst | 4 ++-- ros2_controllers/package.xml | 2 +- ros2_controllers_test_nodes/CHANGELOG.rst | 4 ++-- ros2_controllers_test_nodes/package.xml | 2 +- ros2_controllers_test_nodes/setup.py | 2 +- rqt_joint_trajectory_controller/CHANGELOG.rst | 4 ++-- rqt_joint_trajectory_controller/package.xml | 2 +- rqt_joint_trajectory_controller/setup.py | 2 +- steering_controllers_library/CHANGELOG.rst | 4 ++-- steering_controllers_library/package.xml | 2 +- tricycle_controller/CHANGELOG.rst | 4 ++-- tricycle_controller/package.xml | 2 +- tricycle_steering_controller/CHANGELOG.rst | 4 ++-- tricycle_steering_controller/package.xml | 2 +- velocity_controllers/CHANGELOG.rst | 4 ++-- velocity_controllers/package.xml | 2 +- 58 files changed, 86 insertions(+), 86 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index fab01e0f25..e4c20d1bd4 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index e622a61a5d..5fcb373f58 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 4.33.0 + 4.33.1 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 5567e43f25..8bb4a55a1b 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index 921f2a0361..9f0780cada 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 4.33.0 + 4.33.1 Implementation of admittance controllers for different input and output interface. Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index b75776bf00..af510bfcc6 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index de2ca044e6..fea1f1e6ea 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 4.33.0 + 4.33.1 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Bence Magyar diff --git a/chained_filter_controller/CHANGELOG.rst b/chained_filter_controller/CHANGELOG.rst index 01e756e0df..f12ca18ea3 100644 --- a/chained_filter_controller/CHANGELOG.rst +++ b/chained_filter_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package chained_filter_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/chained_filter_controller/package.xml b/chained_filter_controller/package.xml index f2e69a067b..3cc28a7373 100644 --- a/chained_filter_controller/package.xml +++ b/chained_filter_controller/package.xml @@ -2,7 +2,7 @@ chained_filter_controller - 4.33.0 + 4.33.1 ros2_controller for configuring filter chains Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index cfaea8ef5a..6af36a154e 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- * Don't use `msg\_` field of realtime publisher (backport `#1947 `_) (`#1948 `_) * Contributors: mergify[bot] diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 5260677e9f..f6f74d0f2b 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 4.33.0 + 4.33.1 Controller for a differential-drive mobile base. Bence Magyar diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 8a46782f3e..5f1cc053ec 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index 09ef1ccfe5..259215234e 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 4.33.0 + 4.33.1 Generic controller for forwarding commands. Bence Magyar diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index ea654d5a2c..bccc723531 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- * Don't use `msg\_` field of realtime publisher (backport `#1947 `_) (`#1948 `_) * Contributors: mergify[bot] diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index e66a149d3c..96c6c84c3c 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 4.33.0 + 4.33.1 Controller to publish state of force-torque sensors. Bence Magyar diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index cb5a4b9446..57e7cb7a3d 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index a830f8550c..336efa774c 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 4.33.0 + 4.33.1 Generic controller for forwarding commands. Bence Magyar diff --git a/gpio_controllers/CHANGELOG.rst b/gpio_controllers/CHANGELOG.rst index 20b2a0ff30..8eb09683d2 100644 --- a/gpio_controllers/CHANGELOG.rst +++ b/gpio_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gpio_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/gpio_controllers/package.xml b/gpio_controllers/package.xml index 508a1b939c..7b3e36db1b 100644 --- a/gpio_controllers/package.xml +++ b/gpio_controllers/package.xml @@ -2,7 +2,7 @@ gpio_controllers - 4.33.0 + 4.33.1 Controllers to interact with gpios. Bence Magyar diff --git a/gps_sensor_broadcaster/CHANGELOG.rst b/gps_sensor_broadcaster/CHANGELOG.rst index 52644d31c3..4e90b9d1ff 100644 --- a/gps_sensor_broadcaster/CHANGELOG.rst +++ b/gps_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gps_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/gps_sensor_broadcaster/package.xml b/gps_sensor_broadcaster/package.xml index afaa3478d6..9557247210 100644 --- a/gps_sensor_broadcaster/package.xml +++ b/gps_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ gps_sensor_broadcaster - 4.33.0 + 4.33.1 Controller to publish readings of GPS sensors. Apache License 2.0 diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index d2881aa1f1..844b615bb6 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index 97c1a82137..c8f726044c 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 4.33.0 + 4.33.1 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index e6d84e3d17..290ced66c4 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index d98f78dd29..103c001c27 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 4.33.0 + 4.33.1 Controller to publish readings of IMU sensors. Bence Magyar diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 85fc5732ab..eada361763 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index d02a7eacd8..a0136fe284 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 4.33.0 + 4.33.1 Broadcaster to publish joint state Bence Magyar diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index a5a41a3b14..edaa2d700c 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- * Fix upstream Pid class deprecation warnings (`#1959 `_) * Fix JTC crashing when shutdown while executing (backport `#1960 `_) (`#1962 `_) * Remove unused `get_state_msg` method (backport `#1949 `_) (`#1950 `_) diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 5a8df8b32e..3db25f9f7b 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 4.33.0 + 4.33.1 Controller for executing joint-space trajectories on a group of joints Bence Magyar diff --git a/mecanum_drive_controller/CHANGELOG.rst b/mecanum_drive_controller/CHANGELOG.rst index cf4180191b..b88285e046 100644 --- a/mecanum_drive_controller/CHANGELOG.rst +++ b/mecanum_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package mecanum_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/mecanum_drive_controller/package.xml b/mecanum_drive_controller/package.xml index 8d4afead3f..8f828d9476 100644 --- a/mecanum_drive_controller/package.xml +++ b/mecanum_drive_controller/package.xml @@ -2,7 +2,7 @@ mecanum_drive_controller - 4.33.0 + 4.33.1 Implementation of mecanum drive controller for 4 wheel drive. diff --git a/omni_wheel_drive_controller/CHANGELOG.rst b/omni_wheel_drive_controller/CHANGELOG.rst index 8e72d442b8..4aaec0deb5 100644 --- a/omni_wheel_drive_controller/CHANGELOG.rst +++ b/omni_wheel_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package omni_wheel_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/omni_wheel_drive_controller/package.xml b/omni_wheel_drive_controller/package.xml index 09a0e8ecaa..1724f044b6 100644 --- a/omni_wheel_drive_controller/package.xml +++ b/omni_wheel_drive_controller/package.xml @@ -2,7 +2,7 @@ omni_wheel_drive_controller - 4.33.0 + 4.33.1 A chainable controller for mobile robots with omnidirectional drive with three or more omni wheels. Apache License 2.0 diff --git a/parallel_gripper_controller/CHANGELOG.rst b/parallel_gripper_controller/CHANGELOG.rst index 701f2382fc..05b8e37db9 100644 --- a/parallel_gripper_controller/CHANGELOG.rst +++ b/parallel_gripper_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package parallel_gripper_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/parallel_gripper_controller/package.xml b/parallel_gripper_controller/package.xml index 91df8c44a2..82a2012b1f 100644 --- a/parallel_gripper_controller/package.xml +++ b/parallel_gripper_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> parallel_gripper_controller - 4.33.0 + 4.33.1 The parallel_gripper_controller package Bence Magyar diff --git a/pid_controller/CHANGELOG.rst b/pid_controller/CHANGELOG.rst index a09ac6997d..f734073420 100644 --- a/pid_controller/CHANGELOG.rst +++ b/pid_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pid_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- * Fix upstream Pid class deprecation warnings (`#1959 `_) * Contributors: Christoph FrĂśhlich diff --git a/pid_controller/package.xml b/pid_controller/package.xml index 1dacbfff81..07f7ca31f7 100644 --- a/pid_controller/package.xml +++ b/pid_controller/package.xml @@ -2,7 +2,7 @@ pid_controller - 4.33.0 + 4.33.1 Controller based on PID implememenation from control_toolbox package. Bence Magyar diff --git a/pose_broadcaster/CHANGELOG.rst b/pose_broadcaster/CHANGELOG.rst index 85a0553334..1284166204 100644 --- a/pose_broadcaster/CHANGELOG.rst +++ b/pose_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package pose_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/pose_broadcaster/package.xml b/pose_broadcaster/package.xml index ab8af0286c..9065ffb923 100644 --- a/pose_broadcaster/package.xml +++ b/pose_broadcaster/package.xml @@ -2,7 +2,7 @@ pose_broadcaster - 4.33.0 + 4.33.1 Broadcaster to publish cartesian states. Bence Magyar diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 7c81828a93..283f50f665 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index ae0a6440c3..a15e07057d 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 4.33.0 + 4.33.1 Generic position controller for forwarding position commands. Bence Magyar diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index e85f8aed78..84af9bfbf0 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index 03b7aa8bee..66f0837546 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 4.33.0 + 4.33.1 Controller to publish readings of range sensors. Bence Magyar diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 34179b2a80..51187d639b 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 2cb9f3d99a..21e2e21123 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 4.33.0 + 4.33.1 Metapackage for ros2_controllers related packages Bence Magyar diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 10200bca87..43b2688966 100644 --- a/ros2_controllers_test_nodes/CHANGELOG.rst +++ b/ros2_controllers_test_nodes/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers_test_nodes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index d4714a73d2..49f4ca6817 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 4.33.0 + 4.33.1 Demo nodes for showing and testing functionalities of the ros2_control framework. Bence Magyar diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index b5e4fb0ab1..6316963a17 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="4.33.0", + version="4.33.1", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index e8db0328e7..1d30144827 100644 --- a/rqt_joint_trajectory_controller/CHANGELOG.rst +++ b/rqt_joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- * fix issue of not listing new JTCs (backport `#1891 `_) (`#1969 `_) * Contributors: mergify[bot] diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index a96c652248..f4589dceca 100644 --- a/rqt_joint_trajectory_controller/package.xml +++ b/rqt_joint_trajectory_controller/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> rqt_joint_trajectory_controller - 4.33.0 + 4.33.1 Graphical frontend for interacting with joint_trajectory_controller instances. Bence Magyar diff --git a/rqt_joint_trajectory_controller/setup.py b/rqt_joint_trajectory_controller/setup.py index 7713da940b..7e5d5f36e8 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -21,7 +21,7 @@ setup( name=package_name, - version="4.33.0", + version="4.33.1", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 40ab87ae10..47713ca4e6 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index c7453b58f2..5ec5cb8566 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 4.33.0 + 4.33.1 Package for steering robot configurations including odometry and interfaces. Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 1b894b257d..a3c4de3e97 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- * Don't use `msg\_` field of realtime publisher (backport `#1947 `_) (`#1948 `_) * Contributors: mergify[bot] diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index e959f0ea77..4256d8acdb 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 4.33.0 + 4.33.1 Controller for a tricycle drive mobile base Bence Magyar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 4f8cdfd72a..1aea621a1d 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index f13989b0b9..28bab30d9e 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 4.33.0 + 4.33.1 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 89cf8edaf0..2e29ecf7ce 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +4.33.1 (2025-10-17) +------------------- 4.33.0 (2025-10-03) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index 0cd89d1641..60a3cf3308 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 4.33.0 + 4.33.1 Generic controller for forwarding commands. Bence Magyar From 1a4e19a50e54032fc071e995687e4f2ebfd1d833 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 1 Nov 2025 13:09:04 +0100 Subject: [PATCH 103/108] Bump version of pre-commit hooks (backport #1974) (#1976) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e68a95c460..fb11912667 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -38,7 +38,7 @@ repos: # Python hooks - repo: https://github.com/asottile/pyupgrade - rev: v3.20.0 + rev: v3.21.0 hooks: - id: pyupgrade args: [--py36-plus] @@ -134,7 +134,7 @@ repos: exclude: CHANGELOG\.rst|\.(svg|pyc|drawio)$ - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.34.0 + rev: 0.34.1 hooks: - id: check-github-workflows args: ["--verbose"] From cdcacb58abdb5e3dda95adac5fe112363191f3fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Sun, 2 Nov 2025 14:16:48 +0100 Subject: [PATCH 104/108] :memo: Remove wrong information about trajectory replacement (#1979) --- .../doc/trajectory.rst | 57 +----------------- .../doc/trajectory_replacement_future.png | Bin 71754 -> 0 bytes .../doc/trajectory_replacement_now.png | Bin 64005 -> 0 bytes .../doc/trajectory_replacement_past.png | Bin 74230 -> 0 bytes 4 files changed, 2 insertions(+), 55 deletions(-) delete mode 100644 joint_trajectory_controller/doc/trajectory_replacement_future.png delete mode 100644 joint_trajectory_controller/doc/trajectory_replacement_now.png delete mode 100644 joint_trajectory_controller/doc/trajectory_replacement_past.png diff --git a/joint_trajectory_controller/doc/trajectory.rst b/joint_trajectory_controller/doc/trajectory.rst index d570d59fab..71e7cf831e 100644 --- a/joint_trajectory_controller/doc/trajectory.rst +++ b/joint_trajectory_controller/doc/trajectory.rst @@ -111,60 +111,7 @@ To visualize the difference of the different interpolation methods and their inp Trajectory Replacement --------------------------------- -*Parts of this documentation were originally published in the ROS 1 wiki under the* `CC BY 3.0 license `_. [#f1]_ - Joint trajectory messages allow to specify the time at which a new trajectory should start executing by means of the header timestamp, where zero time (the default) means "start now". -The arrival of a new trajectory command does not necessarily mean that the controller will completely discard the currently running trajectory and substitute it with the new one. -Rather, the controller will take the useful parts of both and combine them appropriately, yielding a smarter trajectory replacement strategy. - -The steps followed by the controller for trajectory replacement are as follows: - - + Get useful parts of the new trajectory: Preserve all waypoints whose time to be reached is in the future, and discard those with times in the past. - If there are no useful parts (ie. all waypoints are in the past) the new trajectory is rejected and the current one continues execution without changes. - - + Get useful parts of the current trajectory: Preserve the current trajectory up to the start time of the new trajectory, discard the later parts. - - + Combine the useful parts of the current and new trajectories. - -The following examples describe this behavior in detail. - -The first example shows a joint which is in hold position mode (flat grey line labeled *pos hold* in the figure below). -A new trajectory (shown in red) arrives at the current time (now), which contains three waypoints and a start time in the future (*traj start*). -The time at which waypoints should be reached (``time_from_start`` member of ``trajectory_msgs/JointTrajectoryPoint``) is relative to the trajectory start time. - -The controller splices the current hold trajectory at time *traj start* and appends the three waypoints. -Notice that between now and *traj start* the previous position hold is still maintained, as the new trajectory is not supposed to start yet. -After the last waypoint is reached, its position is held until new commands arrive. - -.. image:: new_trajectory.png - :alt: Receiving a new trajectory. - -| - -The controller guarantees that the transition between the current and new trajectories will be smooth. Longer times to reach the first waypoint mean slower transitions. - -The next examples discuss the effect of sending the same trajectory to the controller with different start times. -The scenario is that of a controller executing the trajectory from the previous example (shown in red), -and receiving a new command (shown in green) with a trajectory start time set to either zero (start now), -a future time, or a time in the past. - -.. image:: trajectory_replacement_future.png - :alt: Trajectory start time in the future. - -| - -.. image:: trajectory_replacement_now.png - :alt: Zero trajectory start time (start now). - -| - -Of special interest is the last example, where the new trajectory start time and first waypoint are in the past (before now). -In this case, the first waypoint is discarded and only the second one is realized. - -.. image:: trajectory_replacement_past.png - :alt: Trajectory start time in the past. - -| - -.. [#f1] Adolfo Rodriguez: `Understanding trajectory replacement `_ +The current implementation just forgets the old trajectory. +Follow this `issue `__ for more information. diff --git a/joint_trajectory_controller/doc/trajectory_replacement_future.png b/joint_trajectory_controller/doc/trajectory_replacement_future.png deleted file mode 100644 index 582a6acce85995fae84013dbc0ad0569d3c15ab7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71754 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
h 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 diff --git a/joint_trajectory_controller/doc/trajectory_replacement_past.png b/joint_trajectory_controller/doc/trajectory_replacement_past.png deleted file mode 100644 index a719f6fc66bd9c9dddc0a8dbfb5801df45413b23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74230 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 SC`6C|0000 Date: Sun, 2 Nov 2025 22:22:17 +0100 Subject: [PATCH 105/108] Fix integer literal for size_t (backport #1986) (#1987) --- gpio_controllers/src/gpio_command_controller.cpp | 2 +- joint_state_broadcaster/test/test_joint_state_broadcaster.cpp | 2 +- .../include/joint_trajectory_controller/tolerances.hpp | 2 +- joint_trajectory_controller/src/joint_trajectory_controller.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gpio_controllers/src/gpio_command_controller.cpp b/gpio_controllers/src/gpio_command_controller.cpp index f2768f07cf..8ee414d7a0 100644 --- a/gpio_controllers/src/gpio_command_controller.cpp +++ b/gpio_controllers/src/gpio_command_controller.cpp @@ -313,7 +313,7 @@ bool GpioCommandController::check_if_configured_interfaces_matches_received( if (!(configured_interfaces.size() == interfaces_from_params.size())) { RCLCPP_ERROR( - get_node()->get_logger(), "Expected %ld interfaces, got %ld", interfaces_from_params.size(), + get_node()->get_logger(), "Expected %zu interfaces, got %zu", interfaces_from_params.size(), configured_interfaces.size()); for (const auto & interface : interfaces_from_params) { diff --git a/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp b/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp index 8946f4ea55..b963b520c3 100644 --- a/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp +++ b/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp @@ -1012,7 +1012,7 @@ TEST_F(JointStateBroadcasterTest, UpdatePerformanceTest) } RCLCPP_INFO( - state_broadcaster_->get_node()->get_logger(), "Number of test interfaces: %lu", + state_broadcaster_->get_node()->get_logger(), "Number of test interfaces: %zu", test_interfaces_.size()); std::vector state_interfaces; diff --git a/joint_trajectory_controller/include/joint_trajectory_controller/tolerances.hpp b/joint_trajectory_controller/include/joint_trajectory_controller/tolerances.hpp index a89991bd55..7daf6abad6 100644 --- a/joint_trajectory_controller/include/joint_trajectory_controller/tolerances.hpp +++ b/joint_trajectory_controller/include/joint_trajectory_controller/tolerances.hpp @@ -316,7 +316,7 @@ inline bool check_state_tolerance_per_joint( if (show_errors) { const auto logger = rclcpp::get_logger("tolerances"); - RCLCPP_ERROR(logger, "State tolerances failed for joint %lu:", joint_idx); + RCLCPP_ERROR(logger, "State tolerances failed for joint %zu:", joint_idx); if (state_tolerance.position > 0.0 && abs(error_position) > state_tolerance.position) { diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index e9d498edcc..7dd5581148 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -791,7 +791,7 @@ controller_interface::CallbackReturn JointTrajectoryController::on_configure( for (size_t i = 0; i < command_joint_names_.size(); i++) { RCLCPP_DEBUG( - logger, "Command joint %lu: '%s' maps to joint %lu: '%s'.", i, + logger, "Command joint %zu: '%s' maps to joint %zu: '%s'.", i, command_joint_names_[i].c_str(), map_cmd_to_joints_[i], params_.joints.at(map_cmd_to_joints_[i]).c_str()); } From e78e1eeccad6163917ad1a17c4e1760b113f3ddb Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 3 Nov 2025 10:33:43 +0100 Subject: [PATCH 106/108] Add time_from_start to action feedback and state message (cherry-pick #1755) (backport #1820) (#1988) --- .../src/joint_trajectory_controller.cpp | 5 ++++ .../src/trajectory.cpp | 1 + .../test/test_trajectory_controller.cpp | 27 +++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index 7dd5581148..6661bc802b 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -203,12 +203,15 @@ controller_interface::return_type JointTrajectoryController::update( // Sample expected state from the trajectory current_trajectory_->sample( traj_time_, interpolation_method_, state_desired_, start_segment_itr, end_segment_itr); + state_desired_.time_from_start = traj_time_ - current_trajectory_->time_from_start(); // Sample setpoint for next control cycle const bool valid_point = current_trajectory_->sample( traj_time_ + update_period_, interpolation_method_, command_next_, start_segment_itr, end_segment_itr, false); + state_current_.time_from_start = time - current_trajectory_->time_from_start(); + if (valid_point) { const rclcpp::Time traj_start = current_trajectory_->time_from_start(); @@ -1218,9 +1221,11 @@ void JointTrajectoryController::publish_state( if (state_publisher_) { state_msg_.header.stamp = time; + state_msg_.reference.time_from_start = desired_state.time_from_start; state_msg_.reference.positions = desired_state.positions; state_msg_.reference.velocities = desired_state.velocities; state_msg_.reference.accelerations = desired_state.accelerations; + state_msg_.feedback.time_from_start = current_state.time_from_start; state_msg_.feedback.positions = current_state.positions; state_msg_.error.positions = state_error.positions; if (has_velocity_state_interface_) diff --git a/joint_trajectory_controller/src/trajectory.cpp b/joint_trajectory_controller/src/trajectory.cpp index 3ced840c02..86282e875e 100644 --- a/joint_trajectory_controller/src/trajectory.cpp +++ b/joint_trajectory_controller/src/trajectory.cpp @@ -177,6 +177,7 @@ bool Trajectory::sample( } start_segment_itr = begin() + static_cast(i); end_segment_itr = begin() + static_cast(i + 1); + output_state.time_from_start = next_point.time_from_start; if (search_monotonically_increasing) { last_sample_idx_ = i; diff --git a/joint_trajectory_controller/test/test_trajectory_controller.cpp b/joint_trajectory_controller/test/test_trajectory_controller.cpp index eecceeee70..56ec6aecd2 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller.cpp +++ b/joint_trajectory_controller/test/test_trajectory_controller.cpp @@ -461,6 +461,33 @@ TEST_P(TrajectoryControllerTestParameterized, state_topic_consistency_command_jo } } +TEST_F(TrajectoryControllerTest, time_from_start_populated) +{ + rclcpp::executors::SingleThreadedExecutor executor; + SetUpAndActivateTrajectoryController(executor, {}); + subscribeToState(executor); + + // schedule a single waypoint at 100ms: + builtin_interfaces::msg::Duration tfs; + tfs.sec = 0; + tfs.nanosec = 100000000u; + publish(tfs, {INITIAL_POS_JOINTS}, rclcpp::Time(0)); + traj_controller_->wait_for_trajectory(executor); + + // update for 0.2s + updateController(rclcpp::Duration::from_seconds(0.2)); + // give the publish timer one more spin + executor.spin_some(); + + auto state = getState(); + ASSERT_TRUE(state); + // should be around 0.2s + EXPECT_EQ(state->feedback.time_from_start.sec, 0u); + EXPECT_NEAR(state->feedback.time_from_start.nanosec, 200000000u, 10000000u); + EXPECT_EQ(state->reference.time_from_start.sec, 0u); + EXPECT_NEAR(state->reference.time_from_start.nanosec, 200000000u, 10000000u); +} + /** * @brief check if dynamic parameters are updated */ From a775763a44b831b4aeedff955f622ec7a43eb71f Mon Sep 17 00:00:00 2001 From: Abed Al Rahman Al Mrad Date: Tue, 4 Nov 2025 17:36:26 -0500 Subject: [PATCH 107/108] removed referene to filter_chain length --- .../src/force_torque_sensor_broadcaster.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp index 2b85929ae9..bb99606bdd 100644 --- a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp @@ -107,11 +107,10 @@ controller_interface::CallbackReturn ForceTorqueSensorBroadcaster::on_configure( get_node()->get_node_parameters_interface()); // Even on successful configure, if empty, the chain won't be used - has_filter_chain_ = filter_chain_configured && filter_chain_->get_length() > 0; + has_filter_chain_ = filter_chain_configured; RCLCPP_INFO_EXPRESSION( - get_node()->get_logger(), has_filter_chain_, "Filter active with %zu filters!", - filter_chain_->get_length()); + get_node()->get_logger(), has_filter_chain_, "Filter chain configured successfully!"); try { From f9166eb51fb3f66257dc45160238ccf581480838 Mon Sep 17 00:00:00 2001 From: Abed Al Rahman Al Mrad Date: Tue, 4 Nov 2025 17:41:28 -0500 Subject: [PATCH 108/108] adjusted reference to tf2_ros/transform_broadcaster header file --- admittance_controller/test/test_admittance_controller.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admittance_controller/test/test_admittance_controller.hpp b/admittance_controller/test/test_admittance_controller.hpp index dd854bce7d..e38bcc82cf 100644 --- a/admittance_controller/test/test_admittance_controller.hpp +++ b/admittance_controller/test/test_admittance_controller.hpp @@ -38,7 +38,7 @@ #include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp" #include "semantic_components/force_torque_sensor.hpp" #include "test_asset_6d_robot_description.hpp" -#include "tf2_ros/transform_broadcaster.hpp" +#include "tf2_ros/transform_broadcaster.h" // TODO(anyone): replace the state and command message types using ControllerCommandWrenchMsg = geometry_msgs::msg::WrenchStamped;