From 87c91990c870e55e8956f7811fb6d7c237373dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Sat, 1 Jul 2023 18:57:57 +0200 Subject: [PATCH 1/7] Add CI workflow to check docs (#1069) --- .github/workflows/ci-check-docs.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/workflows/ci-check-docs.yml diff --git a/.github/workflows/ci-check-docs.yml b/.github/workflows/ci-check-docs.yml new file mode 100644 index 0000000000..90a822aa72 --- /dev/null +++ b/.github/workflows/ci-check-docs.yml @@ -0,0 +1,12 @@ +name: Check Docs + +on: + workflow_dispatch: + pull_request: + +jobs: + check-docs: + name: Check Docs + uses: ros-controls/control.ros.org/.github/workflows/reusable-sphinx-check-single-version.yml@master + with: + ROS2_CONTROL_PR: ${{ github.ref }} From 185fbeafc97334eb9b09fde74e70b9eed30616d2 Mon Sep 17 00:00:00 2001 From: "Dr. Denis" Date: Sun, 2 Jul 2023 19:00:03 +0200 Subject: [PATCH 2/7] Create doc file for chained controllers (#985) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bence Magyar Co-authored-by: Christoph Fröhlich --- .../doc/controller_chaining.rst | 119 ++++++++++++++++++ .../doc/images/chaining_example2.png | Bin 0 -> 37092 bytes doc/index.rst | 6 +- 3 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 controller_manager/doc/controller_chaining.rst create mode 100644 controller_manager/doc/images/chaining_example2.png diff --git a/controller_manager/doc/controller_chaining.rst b/controller_manager/doc/controller_chaining.rst new file mode 100644 index 0000000000..437cb70509 --- /dev/null +++ b/controller_manager/doc/controller_chaining.rst @@ -0,0 +1,119 @@ +:github_url: https://github.com/ros-controls/ros2_control/blob/{REPOS_FILE_BRANCH}/controller_manager/doc/controller_chaining.rst + +.. _controller_chaining: + +Controller Chaining / Cascade Control +====================================== + +This document proposes a minimal-viable-implementation of serial controller chaining as described in `Chaining Controllers design document `__. +Cascade control is a specific type of controller chaining. + + +Scope of the Document and Background Knowledge +------------------------------------------------------- + +This approach focuses only on serial chaining of controllers and tries to reuse existing mechanisms for it. +It focuses on `inputs and outputs of a controller `__ and their management in the controller manager. +The concept of `controller groups `__ will be introduced only for clarity reasons, and its only meaning is that controllers in that group can be updated in arbitrary order. +This doesn't mean that the controller groups as described `in the controller chaining document `__ will not be introduced and used in the future. +Nevertheless, the author is convinced that this would add only unnecessary complexity at this stage, although in the long term they *could* provide clearer structure and interfaces. + +Motivation, Purpose and Use +--------------------------------- + +To describe the intent of this document, lets focus on the simple yet sufficient example `Example 2 from 'controllers_chaining' design docs `__: + +.. image:: images/chaining_example2.png + :alt: Example2 + + +In this example, we want to chain 'position_tracking' controller with 'diff_drive_controller' and two PID controllers. +Let's now imagine a use-case where we don't only want to run all those controllers as a group, but also flexibly add preceding steps. +This means the following: + + 1. When a robot is started, we want to check if motor velocity control is working properly and therefore only PID controllers are activated. + At this stage we can control the input of PID controller also externally using topics. + However, these controllers also provide virtual interfaces, so we can chain them. + 2. Then "diff_drive_controller" is activated and attaches itself to the virtual input interfaces of PID controllers. + PID controllers also get informed that they are working in chained mode and therefore disable their external interface through subscriber. + Now we check if kinematics of differential robot is running properly. + 3. After that, "position_tracking" can be activated and attached to "diff_drive_controller" that disables its external interfaces. + 4. If any of the controllers is deactivated, also all preceding controllers are deactivated. + + +Implementation +-------------- + +A Controller Base-Class: ChainableController +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A ``ChainableController`` extends ``ControllerInterface`` class with ``virtual InterfaceConfiguration input_interface_configuration() const = 0`` method. +This method should implement for each controller that **can be preceded** by another controller exporting all the input interfaces. +For simplicity reasons, it is assumed for now that controller's all input interfaces are used. +Therefore, do not try to implement any exclusive combinations of input interfaces, but rather write multiple controllers if you need exclusivity. + +The ``ChainableController`` base class implements ``void set_chained_mode(bool activate)`` that sets an internal flag that a controller is used by another controller (in chained mode) and calls ``virtual void on_set_chained_mode(bool activate) = 0`` that implements controller's specific actions when chained modes is activated or deactivated, e.g., deactivating subscribers. + +As an example, PID controllers export one virtual interface ``pid_reference`` and stop their subscriber ``/pid_reference`` when used in chained mode. 'diff_drive_controller' controller exports list of virtual interfaces ``/v_x``, ``/v_y``, and ``/w_z``, and stops subscribers from topics ``/cmd_vel`` and ``/cmd_vel_unstamped``. Its publishers can continue running. + +Inner Resource Management +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +After configuring a chainable controller, controller manager calls ``input_interface_configuration`` method and takes ownership over controller's input interfaces. +This is the same process as done by ``ResourceManager`` and hardware interfaces. +Controller manager maintains "claimed" status of interface in a vector (the same as done in ``ResourceManager``). + +Activation and Deactivation Chained Controllers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Controller Manager has an additional parameter that describes how controllers are chained. +In the first version, the parameter-structure would have some semantic meaning embedded into it, as follows: + + +.. code-block:: yaml + + controller_manager: + ros__parameters: + chained_controllers: + + - parallel_group_1: + - controller1_1 + - controller1_2 + + - parallel_group_2: + - controller2_1 + + - parallel_group_3: + - controller3_1 + - controller3_2 + - controller3_3 + + ... + + - parallel_group_N: + - controllerN_1 + - ... + - controllerN_M + + + +This structure is motivated by ``filter_chain`` structure from `ros/filters repository `__, see `this file for implementation `__. + +This structure is stored internally by controller manager into an ordered map (``std::map>``) with group name as key. +When a controller should be deactivated, the controller manager deactivates all the controllers in the preceding groups first. +All other controllers from the group stay active, as well as all controllers in the following groups. +NOTE: In the future this could be done more intelligently, i.e., deactivate only controllers in the preceding groups that actually precede the controller that should be deactivated. + +On the other hand, the controller should be manually activated in the reverse order, i.e., from the those closer to the hardware toward those preceding them. + + +Debugging outputs +---------------------------- + +Flag ``unavailable`` on reference interface does not provide much information about anything at the moment. So don't get confused by it. The reason we have it are internal implementation reasons irelevant for the usage. + + +Closing remarks +---------------------------- + +- Maybe addition of the new controller's type ``ChainableController`` is not necessary. It would also be feasible to add implementation of ``input_interface_configuration()`` method into ``ControllerInterface`` class with default result ``interface_configuration_type::NONE``. diff --git a/controller_manager/doc/images/chaining_example2.png b/controller_manager/doc/images/chaining_example2.png new file mode 100644 index 0000000000000000000000000000000000000000..1ba49a116edcba1f365d76d4b52b3464f316a118 GIT binary patch literal 37092 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 literal 0 HcmV?d00001 diff --git a/doc/index.rst b/doc/index.rst index 196ea93285..91f965d601 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -6,6 +6,8 @@ ros2_control ################# +This is the documentation of the ros2_control framework core. + `GitHub Repository `_ ================= @@ -14,15 +16,12 @@ API Documentation API documentation is parsed by doxygen and can be found `here <../../api/index.html>`_ - - ========= Features ========= * :ref:`Command Line Interface (CLI) ` - ======== Concepts ======== @@ -31,5 +30,6 @@ Concepts :titlesonly: Controller Manager <../controller_manager/doc/userdoc.rst> + Controller Chaining / Cascade Control <../controller_manager/doc/controller_chaining.rst> Hardware Components <../hardware_interface/doc/hardware_components_userdoc.rst> Mock Components <../hardware_interface/doc/mock_components_userdoc.rst> From d39ddcdb2a6cf423530f93587646f2ce502b85d4 Mon Sep 17 00:00:00 2001 From: Sai Kishor Kothakota Date: Tue, 4 Jul 2023 21:32:56 +0200 Subject: [PATCH 3/7] Fix equal and higher controller update rate (#1070) --- controller_manager/src/controller_manager.cpp | 17 ++- .../test/test_controller/test_controller.hpp | 2 +- .../test/test_controller_manager.cpp | 121 +++++++++++++++++- 3 files changed, 131 insertions(+), 9 deletions(-) diff --git a/controller_manager/src/controller_manager.cpp b/controller_manager/src/controller_manager.cpp index 58f91a786d..cb875f25de 100644 --- a/controller_manager/src/controller_manager.cpp +++ b/controller_manager/src/controller_manager.cpp @@ -610,6 +610,18 @@ controller_interface::return_type ControllerManager::configure_controller( controller_name, std::make_unique(controller, update_rate_)); } + const auto controller_update_rate = controller->get_update_rate(); + const auto cm_update_rate = get_update_rate(); + if (controller_update_rate > cm_update_rate) + { + RCLCPP_WARN( + get_logger(), + "The controller : %s update rate : %d Hz should be less than or equal to controller " + "manager's update rate : %d Hz!. The controller will be updated at controller_manager's " + "update rate.", + controller_name.c_str(), controller_update_rate, cm_update_rate); + } + // CHAINABLE CONTROLLERS: get reference interfaces from chainable controllers if (controller->is_chainable()) { @@ -1873,8 +1885,9 @@ controller_interface::return_type ControllerManager::update( { const auto controller_update_rate = loaded_controller.c->get_update_rate(); - bool controller_go = - controller_update_rate == 0 || ((update_loop_counter_ % controller_update_rate) == 0); + bool controller_go = controller_update_rate == 0 || + ((update_loop_counter_ % controller_update_rate) == 0) || + (controller_update_rate >= update_rate_); RCLCPP_DEBUG( get_logger(), "update_loop_counter: '%d ' controller_go: '%s ' controller_name: '%s '", update_loop_counter_, controller_go ? "True" : "False", diff --git a/controller_manager/test/test_controller/test_controller.hpp b/controller_manager/test/test_controller/test_controller.hpp index 1b070ab302..f73f592037 100644 --- a/controller_manager/test/test_controller/test_controller.hpp +++ b/controller_manager/test/test_controller/test_controller.hpp @@ -65,7 +65,7 @@ class TestController : public controller_interface::ControllerInterface CONTROLLER_MANAGER_PUBLIC void set_state_interface_configuration(const controller_interface::InterfaceConfiguration & cfg); - size_t internal_counter = 0; + unsigned int internal_counter = 0; bool simulate_cleanup_failure = false; // Variable where we store when cleanup was called, pointer because the controller // is usually destroyed after cleanup diff --git a/controller_manager/test/test_controller_manager.cpp b/controller_manager/test/test_controller_manager.cpp index 22221b6e21..5a452bb0b1 100644 --- a/controller_manager/test/test_controller_manager.cpp +++ b/controller_manager/test/test_controller_manager.cpp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include #include #include #include @@ -27,13 +27,13 @@ using ::testing::_; using ::testing::Return; -class TestControllerManager +class TestControllerManagerWithStrictness : public ControllerManagerFixture, public testing::WithParamInterface { }; -TEST_P(TestControllerManager, controller_lifecycle) +TEST_P(TestControllerManagerWithStrictness, controller_lifecycle) { const auto test_param = GetParam(); auto test_controller = std::make_shared(); @@ -159,7 +159,7 @@ TEST_P(TestControllerManager, controller_lifecycle) controller_interface::return_type::OK, cm_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01))); EXPECT_GE(test_controller->internal_counter, 1u); - auto last_internal_counter = test_controller->internal_counter; + size_t last_internal_counter = test_controller->internal_counter; // Stop controller, will take effect at the end of the update function start_controllers = {}; @@ -196,7 +196,7 @@ TEST_P(TestControllerManager, controller_lifecycle) EXPECT_EQ(1, test_controller.use_count()); } -TEST_P(TestControllerManager, per_controller_update_rate) +TEST_P(TestControllerManagerWithStrictness, per_controller_update_rate) { auto strictness = GetParam().strictness; auto test_controller = std::make_shared(); @@ -254,4 +254,113 @@ TEST_P(TestControllerManager, per_controller_update_rate) } INSTANTIATE_TEST_SUITE_P( - test_strict_best_effort, TestControllerManager, testing::Values(strict, best_effort)); + test_strict_best_effort, TestControllerManagerWithStrictness, + testing::Values(strict, best_effort)); + +class TestControllerManagerWithUpdateRates +: public ControllerManagerFixture, + public testing::WithParamInterface +{ +}; + +TEST_P(TestControllerManagerWithUpdateRates, per_controller_equal_and_higher_update_rate) +{ + const auto strictness = controller_manager_msgs::srv::SwitchController::Request::STRICT; + const unsigned int ctrl_update_rate = GetParam(); + auto test_controller = std::make_shared(); + + auto last_internal_counter = 0u; + RCLCPP_INFO( + rclcpp::get_logger("test_controller_manager"), "Testing update rate : %u Hz", ctrl_update_rate); + { + ControllerManagerRunner cm_runner(this); + cm_->add_controller( + test_controller, test_controller::TEST_CONTROLLER_NAME, + test_controller::TEST_CONTROLLER_CLASS_NAME); + } + EXPECT_EQ(1u, cm_->get_loaded_controllers().size()); + EXPECT_EQ(2, test_controller.use_count()); + EXPECT_EQ( + controller_interface::return_type::OK, + cm_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01))); + EXPECT_EQ(last_internal_counter, test_controller->internal_counter) + << "Update should not reach an unconfigured controller"; + + EXPECT_EQ( + lifecycle_msgs::msg::State::PRIMARY_STATE_UNCONFIGURED, test_controller->get_state().id()); + + rclcpp::Parameter update_rate_parameter("update_rate", static_cast(ctrl_update_rate)); + test_controller->get_node()->set_parameter(update_rate_parameter); + // configure controller + cm_->configure_controller(test_controller::TEST_CONTROLLER_NAME); + EXPECT_EQ( + controller_interface::return_type::OK, + cm_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01))); + EXPECT_EQ(last_internal_counter, test_controller->internal_counter) + << "Controller is not started"; + EXPECT_EQ(lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE, test_controller->get_state().id()); + + // Start controller, will take effect at the end of the update function + std::vector start_controllers = {test_controller::TEST_CONTROLLER_NAME}; + std::vector stop_controllers = {}; + auto switch_future = std::async( + std::launch::async, &controller_manager::ControllerManager::switch_controller, cm_, + start_controllers, stop_controllers, strictness, true, rclcpp::Duration(0, 0)); + + ASSERT_EQ(std::future_status::timeout, switch_future.wait_for(std::chrono::milliseconds(100))) + << "switch_controller should be blocking until next update cycle"; + + EXPECT_EQ( + controller_interface::return_type::OK, + cm_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01))); + EXPECT_EQ(last_internal_counter, test_controller->internal_counter) + << "Controller is started at the end of update"; + { + ControllerManagerRunner cm_runner(this); + EXPECT_EQ(controller_interface::return_type::OK, switch_future.get()); + } + + EXPECT_EQ(lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE, test_controller->get_state().id()); + + const auto pre_internal_counter = test_controller->internal_counter; + rclcpp::Rate loop_rate(cm_->get_update_rate()); + for (size_t i = 0; i < 2 * cm_->get_update_rate(); i++) + { + EXPECT_EQ( + controller_interface::return_type::OK, + cm_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01))); + loop_rate.sleep(); + } + // if we do 2 times of the controller_manager update rate, the internal counter should be + // similarly incremented + EXPECT_EQ(test_controller->internal_counter, pre_internal_counter + (2 * cm_->get_update_rate())); + EXPECT_EQ(test_controller->get_update_rate(), ctrl_update_rate); + + auto deactivate_future = std::async( + std::launch::async, &controller_manager::ControllerManager::switch_controller, cm_, + stop_controllers, start_controllers, strictness, true, rclcpp::Duration(0, 0)); + + ASSERT_EQ(std::future_status::timeout, deactivate_future.wait_for(std::chrono::milliseconds(100))) + << "switch_controller should be blocking until next update cycle"; + + EXPECT_EQ( + controller_interface::return_type::OK, + cm_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01))) + << "Controller is stopped at the end of update, so it should have done one more update"; + { + ControllerManagerRunner cm_runner(this); + EXPECT_EQ(controller_interface::return_type::OK, deactivate_future.get()); + } + auto unload_future = std::async( + std::launch::async, &controller_manager::ControllerManager::unload_controller, cm_, + test_controller::TEST_CONTROLLER_NAME); + ASSERT_EQ(std::future_status::timeout, unload_future.wait_for(std::chrono::milliseconds(100))) + << "unload_controller should be blocking until next update cycle"; + ControllerManagerRunner cm_runner(this); + EXPECT_EQ(controller_interface::return_type::OK, unload_future.get()); + last_internal_counter = test_controller->internal_counter; +} + +INSTANTIATE_TEST_SUITE_P( + per_controller_equal_and_higher_update_rate, TestControllerManagerWithUpdateRates, + testing::Values(100, 232, 400)); From ca33bcc57d3f7138f7263011315c826da30c8a49 Mon Sep 17 00:00:00 2001 From: "Dr. Denis" Date: Wed, 5 Jul 2023 17:46:13 +0200 Subject: [PATCH 4/7] [CM] Make error message after trying to active controller more informative. (#1066) --- controller_manager/src/controller_manager.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/controller_manager/src/controller_manager.cpp b/controller_manager/src/controller_manager.cpp index cb875f25de..c4887db15a 100644 --- a/controller_manager/src/controller_manager.cpp +++ b/controller_manager/src/controller_manager.cpp @@ -1399,8 +1399,11 @@ void ControllerManager::activate_controllers( if (new_state.id() != lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE) { RCLCPP_ERROR( - get_logger(), "After activating, controller '%s' is in state '%s', expected Active", - controller->get_node()->get_name(), new_state.label().c_str()); + get_logger(), + "After activation, controller '%s' is in state '%s' (%d), expected '%s' (%d).", + controller->get_node()->get_name(), new_state.label().c_str(), new_state.id(), + hardware_interface::lifecycle_state_names::ACTIVE, + lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE); } if (controller->is_async()) From 09c6da4a170f56c39f57e22cf59d2d0927eeb6f3 Mon Sep 17 00:00:00 2001 From: Sai Kishor Kothakota Date: Fri, 7 Jul 2023 07:42:46 +0200 Subject: [PATCH 5/7] added controller manager runner to have update cycles (#1075) --- controller_manager/test/test_spawner_unspawner.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/controller_manager/test/test_spawner_unspawner.cpp b/controller_manager/test/test_spawner_unspawner.cpp index c9ba0e6355..d67ae8a7d1 100644 --- a/controller_manager/test/test_spawner_unspawner.cpp +++ b/controller_manager/test/test_spawner_unspawner.cpp @@ -96,6 +96,7 @@ TEST_F(TestLoadController, spawner_test_type_in_param) { cm_->set_parameter(rclcpp::Parameter("ctrl_1.type", test_controller::TEST_CONTROLLER_CLASS_NAME)); + ControllerManagerRunner cm_runner(this); EXPECT_EQ(call_spawner("ctrl_1 -c test_controller_manager"), 0); ASSERT_EQ(cm_->get_loaded_controllers().size(), 1ul); From c7df155882494e382852c1468f0c13b26a3748fa Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Sun, 9 Jul 2023 21:27:54 +0100 Subject: [PATCH 6/7] Update changelogs --- controller_interface/CHANGELOG.rst | 3 +++ controller_manager/CHANGELOG.rst | 8 ++++++++ controller_manager_msgs/CHANGELOG.rst | 3 +++ hardware_interface/CHANGELOG.rst | 3 +++ joint_limits/CHANGELOG.rst | 3 +++ ros2_control/CHANGELOG.rst | 3 +++ ros2_control_test_assets/CHANGELOG.rst | 3 +++ ros2controlcli/CHANGELOG.rst | 3 +++ rqt_controller_manager/CHANGELOG.rst | 3 +++ transmission_interface/CHANGELOG.rst | 3 +++ 10 files changed, 35 insertions(+) diff --git a/controller_interface/CHANGELOG.rst b/controller_interface/CHANGELOG.rst index 475ecc1b32..cd33e9924d 100644 --- a/controller_interface/CHANGELOG.rst +++ b/controller_interface/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package controller_interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 3.15.0 (2023-06-23) ------------------- diff --git a/controller_manager/CHANGELOG.rst b/controller_manager/CHANGELOG.rst index 31bec20a0c..ad4ecd285f 100644 --- a/controller_manager/CHANGELOG.rst +++ b/controller_manager/CHANGELOG.rst @@ -2,6 +2,14 @@ Changelog for package controller_manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* added controller manager runner to have update cycles (`#1075 `_) +* [CM] Make error message after trying to active controller more informative. (`#1066 `_) +* Fix equal and higher controller update rate (`#1070 `_) +* Create doc file for chained controllers (`#985 `_) +* Contributors: Dr. Denis, Sai Kishor Kothakota + 3.15.0 (2023-06-23) ------------------- * Enable setting of initial state in HW compoments (`#1046 `_) diff --git a/controller_manager_msgs/CHANGELOG.rst b/controller_manager_msgs/CHANGELOG.rst index 7299338c57..7d59153f73 100644 --- a/controller_manager_msgs/CHANGELOG.rst +++ b/controller_manager_msgs/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package controller_manager_msgs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 3.15.0 (2023-06-23) ------------------- diff --git a/hardware_interface/CHANGELOG.rst b/hardware_interface/CHANGELOG.rst index 1a2d480216..210bf8ec43 100644 --- a/hardware_interface/CHANGELOG.rst +++ b/hardware_interface/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package hardware_interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 3.15.0 (2023-06-23) ------------------- * Enable setting of initial state in HW compoments (`#1046 `_) diff --git a/joint_limits/CHANGELOG.rst b/joint_limits/CHANGELOG.rst index 00f6f6f868..e63dff0077 100644 --- a/joint_limits/CHANGELOG.rst +++ b/joint_limits/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_limits ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 3.15.0 (2023-06-23) ------------------- diff --git a/ros2_control/CHANGELOG.rst b/ros2_control/CHANGELOG.rst index e31c44e4eb..5d8a6ee37e 100644 --- a/ros2_control/CHANGELOG.rst +++ b/ros2_control/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_control ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 3.15.0 (2023-06-23) ------------------- diff --git a/ros2_control_test_assets/CHANGELOG.rst b/ros2_control_test_assets/CHANGELOG.rst index d5ae3c2304..5a136fe913 100644 --- a/ros2_control_test_assets/CHANGELOG.rst +++ b/ros2_control_test_assets/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_control_test_assets ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 3.15.0 (2023-06-23) ------------------- diff --git a/ros2controlcli/CHANGELOG.rst b/ros2controlcli/CHANGELOG.rst index 06dd3441d7..563176978e 100644 --- a/ros2controlcli/CHANGELOG.rst +++ b/ros2controlcli/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2controlcli ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 3.15.0 (2023-06-23) ------------------- * Improve list hardware components output and code for better readability. (`#1060 `_) diff --git a/rqt_controller_manager/CHANGELOG.rst b/rqt_controller_manager/CHANGELOG.rst index cdf03f67f7..1feeb20dec 100644 --- a/rqt_controller_manager/CHANGELOG.rst +++ b/rqt_controller_manager/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package rqt_controller_manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 3.15.0 (2023-06-23) ------------------- diff --git a/transmission_interface/CHANGELOG.rst b/transmission_interface/CHANGELOG.rst index ec7e028687..87710f8070 100644 --- a/transmission_interface/CHANGELOG.rst +++ b/transmission_interface/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package transmission_interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 3.15.0 (2023-06-23) ------------------- From e4aa23842e42f57f5a186a335095c3ba8d2b6972 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Sun, 9 Jul 2023 21:29:00 +0100 Subject: [PATCH 7/7] 3.16.0 --- controller_interface/CHANGELOG.rst | 4 ++-- controller_interface/package.xml | 2 +- controller_manager/CHANGELOG.rst | 4 ++-- controller_manager/package.xml | 2 +- controller_manager_msgs/CHANGELOG.rst | 4 ++-- controller_manager_msgs/package.xml | 2 +- hardware_interface/CHANGELOG.rst | 4 ++-- hardware_interface/package.xml | 2 +- joint_limits/CHANGELOG.rst | 4 ++-- joint_limits/package.xml | 2 +- ros2_control/CHANGELOG.rst | 4 ++-- ros2_control/package.xml | 2 +- ros2_control_test_assets/CHANGELOG.rst | 4 ++-- ros2_control_test_assets/package.xml | 2 +- ros2controlcli/CHANGELOG.rst | 4 ++-- ros2controlcli/package.xml | 2 +- ros2controlcli/setup.py | 2 +- rqt_controller_manager/CHANGELOG.rst | 4 ++-- rqt_controller_manager/package.xml | 2 +- rqt_controller_manager/setup.py | 2 +- transmission_interface/CHANGELOG.rst | 4 ++-- transmission_interface/package.xml | 2 +- 22 files changed, 32 insertions(+), 32 deletions(-) diff --git a/controller_interface/CHANGELOG.rst b/controller_interface/CHANGELOG.rst index cd33e9924d..c0325027a4 100644 --- a/controller_interface/CHANGELOG.rst +++ b/controller_interface/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package controller_interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +3.16.0 (2023-07-09) +------------------- 3.15.0 (2023-06-23) ------------------- diff --git a/controller_interface/package.xml b/controller_interface/package.xml index 9f6d3c5cb6..a060a01054 100644 --- a/controller_interface/package.xml +++ b/controller_interface/package.xml @@ -2,7 +2,7 @@ controller_interface - 3.15.0 + 3.16.0 Description of controller_interface Bence Magyar Denis Štogl diff --git a/controller_manager/CHANGELOG.rst b/controller_manager/CHANGELOG.rst index ad4ecd285f..d78eaec6a7 100644 --- a/controller_manager/CHANGELOG.rst +++ b/controller_manager/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package controller_manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +3.16.0 (2023-07-09) +------------------- * added controller manager runner to have update cycles (`#1075 `_) * [CM] Make error message after trying to active controller more informative. (`#1066 `_) * Fix equal and higher controller update rate (`#1070 `_) diff --git a/controller_manager/package.xml b/controller_manager/package.xml index 4e885f59cf..33255fc700 100644 --- a/controller_manager/package.xml +++ b/controller_manager/package.xml @@ -2,7 +2,7 @@ controller_manager - 3.15.0 + 3.16.0 Description of controller_manager Bence Magyar Denis Štogl diff --git a/controller_manager_msgs/CHANGELOG.rst b/controller_manager_msgs/CHANGELOG.rst index 7d59153f73..3c481827d2 100644 --- a/controller_manager_msgs/CHANGELOG.rst +++ b/controller_manager_msgs/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package controller_manager_msgs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +3.16.0 (2023-07-09) +------------------- 3.15.0 (2023-06-23) ------------------- diff --git a/controller_manager_msgs/package.xml b/controller_manager_msgs/package.xml index 2de7f5ee2f..93af7dc706 100644 --- a/controller_manager_msgs/package.xml +++ b/controller_manager_msgs/package.xml @@ -2,7 +2,7 @@ controller_manager_msgs - 3.15.0 + 3.16.0 Messages and services for the controller manager. Bence Magyar Denis Štogl diff --git a/hardware_interface/CHANGELOG.rst b/hardware_interface/CHANGELOG.rst index 210bf8ec43..14dc8b8744 100644 --- a/hardware_interface/CHANGELOG.rst +++ b/hardware_interface/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package hardware_interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +3.16.0 (2023-07-09) +------------------- 3.15.0 (2023-06-23) ------------------- diff --git a/hardware_interface/package.xml b/hardware_interface/package.xml index 16d86dc985..a329215218 100644 --- a/hardware_interface/package.xml +++ b/hardware_interface/package.xml @@ -1,7 +1,7 @@ hardware_interface - 3.15.0 + 3.16.0 ros2_control hardware interface Bence Magyar Denis Štogl diff --git a/joint_limits/CHANGELOG.rst b/joint_limits/CHANGELOG.rst index e63dff0077..d89b2981e9 100644 --- a/joint_limits/CHANGELOG.rst +++ b/joint_limits/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_limits ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +3.16.0 (2023-07-09) +------------------- 3.15.0 (2023-06-23) ------------------- diff --git a/joint_limits/package.xml b/joint_limits/package.xml index a532d59fb4..d72273844a 100644 --- a/joint_limits/package.xml +++ b/joint_limits/package.xml @@ -1,6 +1,6 @@ joint_limits - 3.15.0 + 3.16.0 Interfaces for handling of joint limits for controllers or hardware. Bence Magyar diff --git a/ros2_control/CHANGELOG.rst b/ros2_control/CHANGELOG.rst index 5d8a6ee37e..7befead368 100644 --- a/ros2_control/CHANGELOG.rst +++ b/ros2_control/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_control ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +3.16.0 (2023-07-09) +------------------- 3.15.0 (2023-06-23) ------------------- diff --git a/ros2_control/package.xml b/ros2_control/package.xml index 9f7b7f8e4e..a445ed27ff 100644 --- a/ros2_control/package.xml +++ b/ros2_control/package.xml @@ -1,7 +1,7 @@ ros2_control - 3.15.0 + 3.16.0 Metapackage for ROS2 control related packages Bence Magyar Denis Štogl diff --git a/ros2_control_test_assets/CHANGELOG.rst b/ros2_control_test_assets/CHANGELOG.rst index 5a136fe913..bcd91a1b55 100644 --- a/ros2_control_test_assets/CHANGELOG.rst +++ b/ros2_control_test_assets/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_control_test_assets ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +3.16.0 (2023-07-09) +------------------- 3.15.0 (2023-06-23) ------------------- diff --git a/ros2_control_test_assets/package.xml b/ros2_control_test_assets/package.xml index 67e7be2e53..8c8edff772 100644 --- a/ros2_control_test_assets/package.xml +++ b/ros2_control_test_assets/package.xml @@ -2,7 +2,7 @@ ros2_control_test_assets - 3.15.0 + 3.16.0 The package provides shared test resources for ros2_control stack Bence Magyar diff --git a/ros2controlcli/CHANGELOG.rst b/ros2controlcli/CHANGELOG.rst index 563176978e..bbb52f9821 100644 --- a/ros2controlcli/CHANGELOG.rst +++ b/ros2controlcli/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2controlcli ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +3.16.0 (2023-07-09) +------------------- 3.15.0 (2023-06-23) ------------------- diff --git a/ros2controlcli/package.xml b/ros2controlcli/package.xml index 8fe8ddfa90..c72388c597 100644 --- a/ros2controlcli/package.xml +++ b/ros2controlcli/package.xml @@ -2,7 +2,7 @@ ros2controlcli - 3.15.0 + 3.16.0 The ROS 2 command line tools for ROS2 Control. diff --git a/ros2controlcli/setup.py b/ros2controlcli/setup.py index d003a71365..5eb29039cc 100644 --- a/ros2controlcli/setup.py +++ b/ros2controlcli/setup.py @@ -19,7 +19,7 @@ setup( name=package_name, - version="3.15.0", + version="3.16.0", packages=find_packages(exclude=["test"]), data_files=[ ("share/" + package_name, ["package.xml"]), diff --git a/rqt_controller_manager/CHANGELOG.rst b/rqt_controller_manager/CHANGELOG.rst index 1feeb20dec..660dedfeb0 100644 --- a/rqt_controller_manager/CHANGELOG.rst +++ b/rqt_controller_manager/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package rqt_controller_manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +3.16.0 (2023-07-09) +------------------- 3.15.0 (2023-06-23) ------------------- diff --git a/rqt_controller_manager/package.xml b/rqt_controller_manager/package.xml index b5e82f3a99..3dac59a834 100644 --- a/rqt_controller_manager/package.xml +++ b/rqt_controller_manager/package.xml @@ -2,7 +2,7 @@ rqt_controller_manager - 3.15.0 + 3.16.0 Graphical frontend for interacting with the controller manager. Bence Magyar Denis Štogl diff --git a/rqt_controller_manager/setup.py b/rqt_controller_manager/setup.py index 7096280cd0..30117e7fe2 100644 --- a/rqt_controller_manager/setup.py +++ b/rqt_controller_manager/setup.py @@ -6,7 +6,7 @@ setup( name=package_name, - version="3.15.0", + version="3.16.0", packages=[package_name], data_files=[ ("share/ament_index/resource_index/packages", ["resource/" + package_name]), diff --git a/transmission_interface/CHANGELOG.rst b/transmission_interface/CHANGELOG.rst index 87710f8070..a124333b85 100644 --- a/transmission_interface/CHANGELOG.rst +++ b/transmission_interface/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package transmission_interface ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +3.16.0 (2023-07-09) +------------------- 3.15.0 (2023-06-23) ------------------- diff --git a/transmission_interface/package.xml b/transmission_interface/package.xml index ac00e7afd5..9d2839198c 100644 --- a/transmission_interface/package.xml +++ b/transmission_interface/package.xml @@ -2,7 +2,7 @@ transmission_interface - 3.15.0 + 3.16.0 transmission_interface contains data structures for representing mechanical transmissions, methods for propagating values between actuator and joint spaces and tooling to support this. Bence Magyar Denis Štogl