From e5b99ab1023eb084e46b17eaceec57d2b630d409 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 1 Aug 2023 16:25:21 +0100 Subject: [PATCH 01/39] Small improvement in remapping (#393) (#724) --- .../src/joint_trajectory_controller.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index 602b5528ff..ba299dd736 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -1312,8 +1312,12 @@ void JointTrajectoryController::sort_to_local_joint_order( get_node()->get_logger(), "Invalid input size (%zu) for sorting", to_remap.size()); return to_remap; } - std::vector output; - output.resize(mapping.size(), 0.0); + static std::vector output(dof_, 0.0); + // Only resize if necessary since it's an expensive operation + if (output.size() != mapping.size()) + { + output.resize(mapping.size(), 0.0); + } for (size_t index = 0; index < mapping.size(); ++index) { auto map_index = mapping[index]; From d0dda064efb7c89fb14bd1928199a7d093ab044c Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 3 Aug 2023 15:37:32 +0100 Subject: [PATCH 02/39] Fix file name for include guard (backport #681) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit c619aac5f67cd323129eec6889d814ab1c160c87) Co-authored-by: Christoph Fröhlich --- admittance_controller/test/test_admittance_controller.hpp | 2 +- ..._description.hpp => test_asset_6d_robot_description.hpp} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename admittance_controller/test/{6d_robot_description.hpp => test_asset_6d_robot_description.hpp} (98%) diff --git a/admittance_controller/test/test_admittance_controller.hpp b/admittance_controller/test/test_admittance_controller.hpp index be78f05bb9..143e5c2846 100644 --- a/admittance_controller/test/test_admittance_controller.hpp +++ b/admittance_controller/test/test_admittance_controller.hpp @@ -27,7 +27,6 @@ #include "gmock/gmock.h" -#include "6d_robot_description.hpp" #include "admittance_controller/admittance_controller.hpp" #include "control_msgs/msg/admittance_controller_state.hpp" #include "geometry_msgs/msg/transform_stamped.hpp" @@ -38,6 +37,7 @@ #include "rclcpp/utilities.hpp" #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 "trajectory_msgs/msg/joint_trajectory.hpp" diff --git a/admittance_controller/test/6d_robot_description.hpp b/admittance_controller/test/test_asset_6d_robot_description.hpp similarity index 98% rename from admittance_controller/test/6d_robot_description.hpp rename to admittance_controller/test/test_asset_6d_robot_description.hpp index f67b5bd054..4d38df7c30 100644 --- a/admittance_controller/test/6d_robot_description.hpp +++ b/admittance_controller/test/test_asset_6d_robot_description.hpp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef ROS2_CONTROL_TEST_ASSETS__6D_ROBOT_DESCRIPTION_HPP_ -#define ROS2_CONTROL_TEST_ASSETS__6D_ROBOT_DESCRIPTION_HPP_ +#ifndef TEST_ASSET_6D_ROBOT_DESCRIPTION_HPP_ +#define TEST_ASSET_6D_ROBOT_DESCRIPTION_HPP_ #include @@ -310,4 +310,4 @@ const auto valid_6d_robot_srdf = } // namespace ros2_control_test_assets -#endif // ROS2_CONTROL_TEST_ASSETS__6D_ROBOT_DESCRIPTION_HPP_ +#endif // TEST_ASSET_6D_ROBOT_DESCRIPTION_HPP_ From e38ca433411ea4b9040f5dc2a29ec3d525695a90 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 3 Aug 2023 17:00:07 +0100 Subject: [PATCH 03/39] Activate AdmittanceControllerTestParameterizedInvalidParameters (#711) (#733) --- .../test/test_admittance_controller.cpp | 16 ++++++++++++---- .../test/test_admittance_controller.hpp | 10 ++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/admittance_controller/test/test_admittance_controller.cpp b/admittance_controller/test/test_admittance_controller.cpp index d056e0406c..7aa099db5a 100644 --- a/admittance_controller/test/test_admittance_controller.cpp +++ b/admittance_controller/test/test_admittance_controller.cpp @@ -67,10 +67,18 @@ INSTANTIATE_TEST_SUITE_P( // wrong length selected axes std::make_tuple( std::string("admittance.selected_axes"), - rclcpp::ParameterValue(std::vector() = {1, 2, 3})), - // invalid robot description - std::make_tuple( - std::string("robot_description"), rclcpp::ParameterValue(std::string() = "bad_robot")))); + rclcpp::ParameterValue(std::vector() = {1, 2, 3})) + // invalid robot description. + // TODO(anyone): deactivated, because SetUpController returns SUCCESS here? + // ,std::make_tuple( + // std::string("robot_description"), rclcpp::ParameterValue(std::string() = "bad_robot"))) + )); + +// Test on_init returns ERROR when a parameter is invalid +TEST_P(AdmittanceControllerTestParameterizedInvalidParameters, invalid_parameters) +{ + ASSERT_EQ(SetUpController(), controller_interface::return_type::ERROR); +} TEST_F(AdmittanceControllerTest, all_parameters_set_configure_success) { diff --git a/admittance_controller/test/test_admittance_controller.hpp b/admittance_controller/test/test_admittance_controller.hpp index 143e5c2846..04c629a21b 100644 --- a/admittance_controller/test/test_admittance_controller.hpp +++ b/admittance_controller/test/test_admittance_controller.hpp @@ -454,9 +454,15 @@ class AdmittanceControllerTestParameterizedInvalidParameters static void TearDownTestCase() { AdmittanceControllerTest::TearDownTestCase(); } protected: - void SetUpController() + controller_interface::return_type SetUpController() { - AdmittanceControllerTest::SetUpController("test_admittance_controller"); + auto param_name = std::get<0>(GetParam()); + auto param_value = std::get<1>(GetParam()); + std::vector parameter_overrides; + rclcpp::Parameter param(param_name, param_value); + parameter_overrides.push_back(param); + return AdmittanceControllerTest::SetUpController( + "test_admittance_controller", parameter_overrides); } }; From 862928c72ba147228d8bf63fa2b61148a179b152 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 5 Aug 2023 10:32:40 +0100 Subject: [PATCH 04/39] [JTC] Re-enabling test, bugfixing and hardening. Adding a parameter to define when trajectories with non-zero velocity at the end are used. (backport #705) (#706) --- .../workflows/rolling-binary-build-main.yml | 4 + .../rolling-binary-build-testing.yml | 4 + .../rolling-semi-binary-build-main.yml | 4 + .../rolling-semi-binary-build-testing.yml | 4 + joint_trajectory_controller/CMakeLists.txt | 14 +- joint_trajectory_controller/doc/userdoc.rst | 5 + .../validate_jtc_parameters.hpp | 5 +- .../src/joint_trajectory_controller.cpp | 29 +- ...oint_trajectory_controller_parameters.yaml | 9 +- .../test/test_trajectory_actions.cpp | 316 ++- .../test/test_trajectory_controller.cpp | 1884 ++++++++--------- .../test/test_trajectory_controller_utils.hpp | 38 +- 12 files changed, 1294 insertions(+), 1022 deletions(-) diff --git a/.github/workflows/rolling-binary-build-main.yml b/.github/workflows/rolling-binary-build-main.yml index b51bbabe29..793db5d7e5 100644 --- a/.github/workflows/rolling-binary-build-main.yml +++ b/.github/workflows/rolling-binary-build-main.yml @@ -6,9 +6,13 @@ on: workflow_dispatch: branches: - master + - '*feature*' + - '*feature/**' pull_request: branches: - master + - '*feature*' + - '*feature/**' push: branches: - master diff --git a/.github/workflows/rolling-binary-build-testing.yml b/.github/workflows/rolling-binary-build-testing.yml index a1db89b8d9..9b480d99c3 100644 --- a/.github/workflows/rolling-binary-build-testing.yml +++ b/.github/workflows/rolling-binary-build-testing.yml @@ -6,9 +6,13 @@ on: workflow_dispatch: branches: - master + - '*feature*' + - '*feature/**' pull_request: branches: - master + - '*feature*' + - '*feature/**' push: branches: - master diff --git a/.github/workflows/rolling-semi-binary-build-main.yml b/.github/workflows/rolling-semi-binary-build-main.yml index eca9483438..8b395e5163 100644 --- a/.github/workflows/rolling-semi-binary-build-main.yml +++ b/.github/workflows/rolling-semi-binary-build-main.yml @@ -5,9 +5,13 @@ on: workflow_dispatch: branches: - master + - '*feature*' + - '*feature/**' pull_request: branches: - master + - '*feature*' + - '*feature/**' push: branches: - master diff --git a/.github/workflows/rolling-semi-binary-build-testing.yml b/.github/workflows/rolling-semi-binary-build-testing.yml index 62214adae9..630881dc0a 100644 --- a/.github/workflows/rolling-semi-binary-build-testing.yml +++ b/.github/workflows/rolling-semi-binary-build-testing.yml @@ -5,9 +5,13 @@ on: workflow_dispatch: branches: - master + - '*feature*' + - '*feature/**' pull_request: branches: - master + - '*feature*' + - '*feature/**' push: branches: - master diff --git a/joint_trajectory_controller/CMakeLists.txt b/joint_trajectory_controller/CMakeLists.txt index cf64269e65..73d01ef132 100644 --- a/joint_trajectory_controller/CMakeLists.txt +++ b/joint_trajectory_controller/CMakeLists.txt @@ -78,13 +78,13 @@ if(BUILD_TESTING) ros2_control_test_assets ) - # TODO(andyz): Disabled due to flakiness - # ament_add_gmock(test_trajectory_actions - # test/test_trajectory_actions.cpp - # ) - # target_link_libraries(test_trajectory_actions - # joint_trajectory_controller - # ) + ament_add_gmock(test_trajectory_actions + test/test_trajectory_actions.cpp + ) + set_tests_properties(test_trajectory_actions PROPERTIES TIMEOUT 300) + target_link_libraries(test_trajectory_actions + joint_trajectory_controller + ) endif() diff --git a/joint_trajectory_controller/doc/userdoc.rst b/joint_trajectory_controller/doc/userdoc.rst index 798cc161e5..54341721d5 100644 --- a/joint_trajectory_controller/doc/userdoc.rst +++ b/joint_trajectory_controller/doc/userdoc.rst @@ -159,6 +159,11 @@ open_loop_control (boolean) If this flag is set, the controller tries to read the values from the command interfaces on starting. If they have real numeric values, those will be used instead of state interfaces. Therefore it is important set command interfaces to NaN (std::numeric_limits::quiet_NaN()) or state values when the hardware is started. +allow_nonzero_velocity_at_trajectory_end (boolean) + If false, the last velocity point has to be zero or the goal will be rejected. + + Default: true + constraints (structure) Default values for tolerances if no explicit values are states in JointTrajectory message. diff --git a/joint_trajectory_controller/include/joint_trajectory_controller/validate_jtc_parameters.hpp b/joint_trajectory_controller/include/joint_trajectory_controller/validate_jtc_parameters.hpp index 91c652013e..6c909e3278 100644 --- a/joint_trajectory_controller/include/joint_trajectory_controller/validate_jtc_parameters.hpp +++ b/joint_trajectory_controller/include/joint_trajectory_controller/validate_jtc_parameters.hpp @@ -19,10 +19,11 @@ #include #include "parameter_traits/parameter_traits.hpp" +#include "rclcpp/parameter.hpp" #include "rsl/algorithm.hpp" #include "tl_expected/expected.hpp" -namespace parameter_traits +namespace joint_trajectory_controller { tl::expected command_interface_type_combinations( rclcpp::Parameter const & parameter) @@ -94,6 +95,6 @@ tl::expected state_interface_type_combinations( return {}; } -} // namespace parameter_traits +} // namespace joint_trajectory_controller #endif // JOINT_TRAJECTORY_CONTROLLER__VALIDATE_JTC_PARAMETERS_HPP_ diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index ba299dd736..cc033b76cf 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -67,6 +67,15 @@ controller_interface::CallbackReturn JointTrajectoryController::on_init() return CallbackReturn::ERROR; } + // TODO(christophfroehlich): remove deprecation warning + if (params_.allow_nonzero_velocity_at_trajectory_end) + { + RCLCPP_WARN( + get_node()->get_logger(), + "[Deprecated]: \"allow_nonzero_velocity_at_trajectory_end\" is set to " + "true. The default behavior will change to false."); + } + return CallbackReturn::SUCCESS; } @@ -136,7 +145,9 @@ controller_interface::return_type JointTrajectoryController::update( { error.positions[index] = desired.positions[index] - current.positions[index]; } - if (has_velocity_state_interface_ && has_velocity_command_interface_) + if ( + has_velocity_state_interface_ && + (has_velocity_command_interface_ || has_effort_command_interface_)) { error.velocities[index] = desired.velocities[index] - current.velocities[index]; } @@ -234,7 +245,7 @@ controller_interface::return_type JointTrajectoryController::update( const rclcpp::Time traj_start = (*traj_point_active_ptr_)->get_trajectory_start_time(); const rclcpp::Time traj_end = traj_start + start_segment_itr->time_from_start; - time_difference = get_node()->now().seconds() - traj_end.seconds(); + time_difference = time.seconds() - traj_end.seconds(); if (time_difference > default_tolerances_.goal_time_tolerance) { @@ -1416,6 +1427,20 @@ bool JointTrajectoryController::validate_trajectory_msg( } } + if (!params_.allow_nonzero_velocity_at_trajectory_end) + { + for (size_t i = 0; i < trajectory.points.back().velocities.size(); ++i) + { + if (trajectory.points.back().velocities.at(i) != 0.) + { + RCLCPP_ERROR( + get_node()->get_logger(), "Velocity of last trajectory point of joint %s is not zero: %f", + trajectory.joint_names.at(i).c_str(), trajectory.points.back().velocities.at(i)); + return false; + } + } + } + rclcpp::Duration previous_traj_time(0ms); for (size_t i = 0; i < trajectory.points.size(); ++i) { diff --git a/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml b/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml index e710b33d07..a754929ef7 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml +++ b/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml @@ -22,7 +22,7 @@ joint_trajectory_controller: validation: { unique<>: null, subset_of<>: [["position", "velocity", "acceleration", "effort",]], - command_interface_type_combinations: null, + "joint_trajectory_controller::command_interface_type_combinations": null, } } state_interfaces: { @@ -32,7 +32,7 @@ joint_trajectory_controller: validation: { unique<>: null, subset_of<>: [["position", "velocity", "acceleration",]], - state_interface_type_combinations: null, + "joint_trajectory_controller::state_interface_type_combinations": null, } } allow_partial_joints_goal: { @@ -74,6 +74,11 @@ joint_trajectory_controller: one_of<>: [["splines", "none"]], } } + allow_nonzero_velocity_at_trajectory_end: { + type: bool, + default_value: true, + description: "If false, the last velocity point has to be zero or the goal will be rejected", + } gains: __map_joints: p: { diff --git a/joint_trajectory_controller/test/test_trajectory_actions.cpp b/joint_trajectory_controller/test/test_trajectory_actions.cpp index 10dd3a6b90..fdea551c30 100644 --- a/joint_trajectory_controller/test/test_trajectory_actions.cpp +++ b/joint_trajectory_controller/test/test_trajectory_actions.cpp @@ -66,21 +66,20 @@ class TestTrajectoryActions : public TrajectoryControllerTest goal_options_.feedback_callback = nullptr; } - void SetUpExecutor(const std::vector & parameters = {}) + void SetUpExecutor( + const std::vector & parameters = {}, + bool separate_cmd_and_state_values = false) { setup_executor_ = true; - executor_ = std::make_unique(); - - SetUpAndActivateTrajectoryController(true, parameters); - - executor_->add_node(traj_controller_->get_node()->get_node_base_interface()); + SetUpAndActivateTrajectoryController( + executor_, true, parameters, separate_cmd_and_state_values); SetUpActionClient(); - executor_->add_node(node_->get_node_base_interface()); + executor_.add_node(node_->get_node_base_interface()); - executor_future_handle_ = std::async(std::launch::async, [&]() -> void { executor_->spin(); }); + executor_future_handle_ = std::async(std::launch::async, [&]() -> void { executor_.spin(); }); } void SetUpControllerHardware() @@ -132,7 +131,7 @@ class TestTrajectoryActions : public TrajectoryControllerTest if (setup_executor_) { setup_executor_ = false; - executor_->cancel(); + executor_.cancel(); executor_future_handle_.wait(); } } @@ -169,7 +168,7 @@ class TestTrajectoryActions : public TrajectoryControllerTest int common_action_result_code_ = control_msgs::action::FollowJointTrajectory_Result::SUCCESSFUL; bool setup_executor_ = false; - rclcpp::executors::MultiThreadedExecutor::UniquePtr executor_; + rclcpp::executors::MultiThreadedExecutor executor_; std::future executor_future_handle_; bool setup_controller_hw_ = false; @@ -201,7 +200,24 @@ class TestTrajectoryActions : public TrajectoryControllerTest } }; -TEST_F(TestTrajectoryActions, test_success_single_point_sendgoal) +// From the tutorial: https://www.sandordargo.com/blog/2019/04/24/parameterized-testing-with-gtest +class TestTrajectoryActionsTestParameterized +: public TestTrajectoryActions, + public ::testing::WithParamInterface< + std::tuple, std::vector>> +{ +public: + virtual void SetUp() + { + TestTrajectoryActions::SetUp(); + command_interface_types_ = std::get<0>(GetParam()); + state_interface_types_ = std::get<1>(GetParam()); + } + + static void TearDownTestCase() { TrajectoryControllerTest::TearDownTestCase(); } +}; + +TEST_P(TestTrajectoryActionsTestParameterized, test_success_single_point_sendgoal) { SetUpExecutor(); SetUpControllerHardware(); @@ -227,12 +243,15 @@ TEST_F(TestTrajectoryActions, test_success_single_point_sendgoal) EXPECT_TRUE(gh_future.get()); EXPECT_EQ(rclcpp_action::ResultCode::SUCCEEDED, common_resultcode_); - EXPECT_EQ(1.0, joint_pos_[0]); - EXPECT_EQ(2.0, joint_pos_[1]); - EXPECT_EQ(3.0, joint_pos_[2]); + if (traj_controller_->has_position_command_interface()) + { + EXPECT_EQ(1.0, joint_pos_[0]); + EXPECT_EQ(2.0, joint_pos_[1]); + EXPECT_EQ(3.0, joint_pos_[2]); + } } -TEST_F(TestTrajectoryActions, test_success_multi_point_sendgoal) +TEST_P(TestTrajectoryActionsTestParameterized, test_success_multi_point_sendgoal) { SetUpExecutor(); SetUpControllerHardware(); @@ -274,11 +293,18 @@ TEST_F(TestTrajectoryActions, test_success_multi_point_sendgoal) EXPECT_TRUE(gh_future.get()); EXPECT_EQ(rclcpp_action::ResultCode::SUCCEEDED, common_resultcode_); - EXPECT_NEAR(7.0, joint_pos_[0], COMMON_THRESHOLD); - EXPECT_NEAR(8.0, joint_pos_[1], COMMON_THRESHOLD); - EXPECT_NEAR(9.0, joint_pos_[2], COMMON_THRESHOLD); + if (traj_controller_->has_position_command_interface()) + { + EXPECT_NEAR(7.0, joint_pos_[0], COMMON_THRESHOLD); + EXPECT_NEAR(8.0, joint_pos_[1], COMMON_THRESHOLD); + EXPECT_NEAR(9.0, joint_pos_[2], COMMON_THRESHOLD); + } } +/** + * Makes sense with position command interface only, + * because no integration to position state interface is implemented + */ TEST_F(TestTrajectoryActions, test_goal_tolerances_single_point_success) { // set tolerance parameters @@ -312,11 +338,18 @@ TEST_F(TestTrajectoryActions, test_goal_tolerances_single_point_success) EXPECT_EQ( control_msgs::action::FollowJointTrajectory_Result::SUCCESSFUL, common_action_result_code_); - EXPECT_NEAR(1.0, joint_pos_[0], COMMON_THRESHOLD); - EXPECT_NEAR(2.0, joint_pos_[1], COMMON_THRESHOLD); - EXPECT_NEAR(3.0, joint_pos_[2], COMMON_THRESHOLD); + if (traj_controller_->has_position_command_interface()) + { + EXPECT_NEAR(1.0, joint_pos_[0], COMMON_THRESHOLD); + EXPECT_NEAR(2.0, joint_pos_[1], COMMON_THRESHOLD); + EXPECT_NEAR(3.0, joint_pos_[2], COMMON_THRESHOLD); + } } +/** + * Makes sense with position command interface only, + * because no integration to position state interface is implemented + */ TEST_F(TestTrajectoryActions, test_goal_tolerances_multi_point_success) { // set tolerance parameters @@ -367,12 +400,15 @@ TEST_F(TestTrajectoryActions, test_goal_tolerances_multi_point_success) EXPECT_EQ( control_msgs::action::FollowJointTrajectory_Result::SUCCESSFUL, common_action_result_code_); - EXPECT_NEAR(7.0, joint_pos_[0], COMMON_THRESHOLD); - EXPECT_NEAR(8.0, joint_pos_[1], COMMON_THRESHOLD); - EXPECT_NEAR(9.0, joint_pos_[2], COMMON_THRESHOLD); + if (traj_controller_->has_position_command_interface()) + { + EXPECT_NEAR(7.0, joint_pos_[0], COMMON_THRESHOLD); + EXPECT_NEAR(8.0, joint_pos_[1], COMMON_THRESHOLD); + EXPECT_NEAR(9.0, joint_pos_[2], COMMON_THRESHOLD); + } } -TEST_F(TestTrajectoryActions, test_state_tolerances_fail) +TEST_P(TestTrajectoryActionsTestParameterized, test_state_tolerances_fail) { // set joint tolerance parameters const double state_tol = 0.0001; @@ -417,14 +453,17 @@ TEST_F(TestTrajectoryActions, test_state_tolerances_fail) common_action_result_code_); // run an update, it should be holding - traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); + updateController(rclcpp::Duration::from_seconds(0.01)); - EXPECT_NEAR(INITIAL_POS_JOINT1, joint_pos_[0], COMMON_THRESHOLD); - EXPECT_NEAR(INITIAL_POS_JOINT2, joint_pos_[1], COMMON_THRESHOLD); - EXPECT_NEAR(INITIAL_POS_JOINT3, joint_pos_[2], COMMON_THRESHOLD); + if (traj_controller_->has_position_command_interface()) + { + EXPECT_NEAR(INITIAL_POS_JOINT1, joint_pos_[0], COMMON_THRESHOLD); + EXPECT_NEAR(INITIAL_POS_JOINT2, joint_pos_[1], COMMON_THRESHOLD); + EXPECT_NEAR(INITIAL_POS_JOINT3, joint_pos_[2], COMMON_THRESHOLD); + } } -TEST_F(TestTrajectoryActions, test_goal_tolerances_fail) +TEST_P(TestTrajectoryActionsTestParameterized, test_goal_tolerances_fail) { // set joint tolerance parameters const double goal_tol = 0.1; @@ -436,15 +475,13 @@ TEST_F(TestTrajectoryActions, test_goal_tolerances_fail) rclcpp::Parameter("constraints.joint3.goal", goal_tol), rclcpp::Parameter("constraints.goal_time", goal_time)}; - SetUpExecutor(params); + // separate command from states -> goal won't never be reached + bool separate_cmd_and_state_values = true; + SetUpExecutor(params, separate_cmd_and_state_values); SetUpControllerHardware(); - const double init_pos1 = joint_pos_[0]; - const double init_pos2 = joint_pos_[1]; - const double init_pos3 = joint_pos_[2]; - std::shared_future gh_future; - // send goal + // send goal; one point only -> command is directly set to reach this goal (no interpolation) { std::vector points; JointTrajectoryPoint point; @@ -466,15 +503,18 @@ TEST_F(TestTrajectoryActions, test_goal_tolerances_fail) control_msgs::action::FollowJointTrajectory_Result::GOAL_TOLERANCE_VIOLATED, common_action_result_code_); - // run an update, it should be holding - traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); + // run an update, it should be holding the last received goal + updateController(rclcpp::Duration::from_seconds(0.01)); - EXPECT_NEAR(init_pos1, joint_pos_[0], COMMON_THRESHOLD); - EXPECT_NEAR(init_pos2, joint_pos_[1], COMMON_THRESHOLD); - EXPECT_NEAR(init_pos3, joint_pos_[2], COMMON_THRESHOLD); + if (traj_controller_->has_position_command_interface()) + { + EXPECT_NEAR(4.0, joint_pos_[0], COMMON_THRESHOLD); + EXPECT_NEAR(5.0, joint_pos_[1], COMMON_THRESHOLD); + EXPECT_NEAR(6.0, joint_pos_[2], COMMON_THRESHOLD); + } } -TEST_F(TestTrajectoryActions, test_no_time_from_start_state_tolerance_fail) +TEST_P(TestTrajectoryActionsTestParameterized, test_no_time_from_start_state_tolerance_fail) { // set joint tolerance parameters const double state_tol = 0.0001; @@ -514,14 +554,17 @@ TEST_F(TestTrajectoryActions, test_no_time_from_start_state_tolerance_fail) common_action_result_code_); // run an update, it should be holding - traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); + updateController(rclcpp::Duration::from_seconds(0.01)); - EXPECT_NEAR(init_pos1, joint_pos_[0], COMMON_THRESHOLD); - EXPECT_NEAR(init_pos2, joint_pos_[1], COMMON_THRESHOLD); - EXPECT_NEAR(init_pos3, joint_pos_[2], COMMON_THRESHOLD); + if (traj_controller_->has_position_command_interface()) + { + EXPECT_NEAR(init_pos1, joint_pos_[0], COMMON_THRESHOLD); + EXPECT_NEAR(init_pos2, joint_pos_[1], COMMON_THRESHOLD); + EXPECT_NEAR(init_pos3, joint_pos_[2], COMMON_THRESHOLD); + } } -TEST_F(TestTrajectoryActions, test_cancel_hold_position) +TEST_P(TestTrajectoryActionsTestParameterized, test_cancel_hold_position) { SetUpExecutor(); SetUpControllerHardware(); @@ -563,9 +606,180 @@ TEST_F(TestTrajectoryActions, test_cancel_hold_position) const double prev_pos3 = joint_pos_[2]; // run an update, it should be holding - traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); + updateController(rclcpp::Duration::from_seconds(0.01)); + + if (traj_controller_->has_position_command_interface()) + { + EXPECT_EQ(prev_pos1, joint_pos_[0]); + EXPECT_EQ(prev_pos2, joint_pos_[1]); + EXPECT_EQ(prev_pos3, joint_pos_[2]); + } +} + +TEST_P(TestTrajectoryActionsTestParameterized, test_allow_nonzero_velocity_at_trajectory_end_true) +{ + std::vector params = { + rclcpp::Parameter("allow_nonzero_velocity_at_trajectory_end", true)}; + SetUpExecutor(params); + SetUpControllerHardware(); + + std::shared_future gh_future; + // send goal with nonzero last velocities + { + std::vector points; + JointTrajectoryPoint point1; + point1.time_from_start = rclcpp::Duration::from_seconds(0.0); + point1.positions.resize(joint_names_.size()); + point1.velocities.resize(joint_names_.size()); + + point1.positions[0] = 4.0; + point1.positions[1] = 5.0; + point1.positions[2] = 6.0; + point1.velocities[0] = 4.0; + point1.velocities[1] = 5.0; + point1.velocities[2] = 6.0; + points.push_back(point1); + + JointTrajectoryPoint point2; + point2.time_from_start = rclcpp::Duration::from_seconds(0.1); + point2.positions.resize(joint_names_.size()); + point2.velocities.resize(joint_names_.size()); + + point2.positions[0] = 7.0; + point2.positions[1] = 8.0; + point2.positions[2] = 9.0; + point2.velocities[0] = 4.0; + point2.velocities[1] = 5.0; + point2.velocities[2] = 6.0; + points.push_back(point2); + + gh_future = sendActionGoal(points, 1.0, goal_options_); + } + controller_hw_thread_.join(); + + // will be accepted despite nonzero last point + EXPECT_TRUE(gh_future.get()); + EXPECT_EQ(rclcpp_action::ResultCode::SUCCEEDED, common_resultcode_); +} + +TEST_P(TestTrajectoryActionsTestParameterized, test_allow_nonzero_velocity_at_trajectory_end_false) +{ + std::vector params = { + rclcpp::Parameter("allow_nonzero_velocity_at_trajectory_end", false)}; + SetUpExecutor(params); + SetUpControllerHardware(); + + std::shared_future gh_future; + // send goal with nonzero last velocities + { + std::vector points; + JointTrajectoryPoint point1; + point1.time_from_start = rclcpp::Duration::from_seconds(0.0); + point1.positions.resize(joint_names_.size()); + point1.velocities.resize(joint_names_.size()); + + point1.positions[0] = 4.0; + point1.positions[1] = 5.0; + point1.positions[2] = 6.0; + point1.velocities[0] = 4.0; + point1.velocities[1] = 5.0; + point1.velocities[2] = 6.0; + points.push_back(point1); + + JointTrajectoryPoint point2; + point2.time_from_start = rclcpp::Duration::from_seconds(0.1); + point2.positions.resize(joint_names_.size()); + point2.velocities.resize(joint_names_.size()); + + point2.positions[0] = 7.0; + point2.positions[1] = 8.0; + point2.positions[2] = 9.0; + point2.velocities[0] = 4.0; + point2.velocities[1] = 5.0; + point2.velocities[2] = 6.0; + points.push_back(point2); + + gh_future = sendActionGoal(points, 1.0, goal_options_); + } + controller_hw_thread_.join(); + + EXPECT_FALSE(gh_future.get()); + + // send goal with last velocity being zero + { + std::vector points; + JointTrajectoryPoint point1; + point1.time_from_start = rclcpp::Duration::from_seconds(0.0); + point1.positions.resize(joint_names_.size()); + point1.velocities.resize(joint_names_.size()); - EXPECT_EQ(prev_pos1, joint_pos_[0]); - EXPECT_EQ(prev_pos2, joint_pos_[1]); - EXPECT_EQ(prev_pos3, joint_pos_[2]); + point1.positions[0] = 4.0; + point1.positions[1] = 5.0; + point1.positions[2] = 6.0; + point1.velocities[0] = 4.0; + point1.velocities[1] = 5.0; + point1.velocities[2] = 6.0; + points.push_back(point1); + + JointTrajectoryPoint point2; + point2.time_from_start = rclcpp::Duration::from_seconds(0.1); + point2.positions.resize(joint_names_.size()); + point2.velocities.resize(joint_names_.size()); + + point2.positions[0] = 7.0; + point2.positions[1] = 8.0; + point2.positions[2] = 9.0; + point2.velocities[0] = 0.0; + point2.velocities[1] = 0.0; + point2.velocities[2] = 0.0; + points.push_back(point2); + + gh_future = sendActionGoal(points, 1.0, goal_options_); + } + + EXPECT_TRUE(gh_future.get()); } + +// position controllers +INSTANTIATE_TEST_SUITE_P( + PositionTrajectoryControllersActions, TestTrajectoryActionsTestParameterized, + ::testing::Values( + std::make_tuple(std::vector({"position"}), std::vector({"position"})), + std::make_tuple( + std::vector({"position"}), std::vector({"position", "velocity"})), + std::make_tuple( + std::vector({"position"}), + std::vector({"position", "velocity", "acceleration"})))); + +// position_velocity controllers +INSTANTIATE_TEST_SUITE_P( + PositionVelocityTrajectoryControllersActions, TestTrajectoryActionsTestParameterized, + ::testing::Values( + std::make_tuple( + std::vector({"position", "velocity"}), std::vector({"position"})), + std::make_tuple( + std::vector({"position", "velocity"}), + std::vector({"position", "velocity"})), + std::make_tuple( + std::vector({"position", "velocity"}), + std::vector({"position", "velocity", "acceleration"})))); + +// only velocity controller +INSTANTIATE_TEST_SUITE_P( + OnlyVelocityTrajectoryControllersAction, TestTrajectoryActionsTestParameterized, + ::testing::Values( + std::make_tuple( + std::vector({"velocity"}), std::vector({"position", "velocity"})), + std::make_tuple( + std::vector({"velocity"}), + std::vector({"position", "velocity", "acceleration"})))); + +// only effort controller +INSTANTIATE_TEST_SUITE_P( + OnlyEffortTrajectoryControllers, TestTrajectoryActionsTestParameterized, + ::testing::Values( + std::make_tuple( + std::vector({"effort"}), std::vector({"position", "velocity"})), + std::make_tuple( + std::vector({"effort"}), + std::vector({"position", "velocity", "acceleration"})))); diff --git a/joint_trajectory_controller/test/test_trajectory_controller.cpp b/joint_trajectory_controller/test/test_trajectory_controller.cpp index e3512d4d94..55d0ee0dfe 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller.cpp +++ b/joint_trajectory_controller/test/test_trajectory_controller.cpp @@ -29,7 +29,6 @@ #include "builtin_interfaces/msg/duration.hpp" #include "builtin_interfaces/msg/time.hpp" -#include "control_msgs/msg/detail/joint_trajectory_controller_state__struct.hpp" #include "controller_interface/controller_interface.hpp" #include "hardware_interface/resource_manager.hpp" #include "joint_trajectory_controller/joint_trajectory_controller.hpp" @@ -49,10 +48,11 @@ #include "rclcpp_lifecycle/lifecycle_node.hpp" #include "rclcpp_lifecycle/state.hpp" #include "std_msgs/msg/header.hpp" -#include "test_trajectory_controller_utils.hpp" #include "trajectory_msgs/msg/joint_trajectory.hpp" #include "trajectory_msgs/msg/joint_trajectory_point.hpp" +#include "test_trajectory_controller_utils.hpp" + using lifecycle_msgs::msg::State; using test_trajectory_controllers::TrajectoryControllerTest; using test_trajectory_controllers::TrajectoryControllerTestParameterized; @@ -65,6 +65,8 @@ TEST_P(TrajectoryControllerTestParameterized, configure_state_ignores_commands) { rclcpp::executors::MultiThreadedExecutor executor; SetUpTrajectoryController(executor); + traj_controller_->get_node()->set_parameter( + rclcpp::Parameter("allow_nonzero_velocity_at_trajectory_end", true)); // const auto future_handle_ = std::async(std::launch::async, spin, &executor); @@ -199,123 +201,12 @@ TEST_P(TrajectoryControllerTestParameterized, activate) executor.cancel(); } -// TEST_F(TestTrajectoryController, activation) { -// auto traj_controller = std::make_shared( -// joint_names_, op_mode_); -// auto ret = traj_controller->init(test_robot_, controller_name_); -// if (ret != controller_interface::return_type::OK) { -// FAIL(); -// } -// -// auto traj_node = traj_controller->get_node(); -// rclcpp::executors::MultiThreadedExecutor executor; -// executor.add_node(traj_node->get_node_base_interface()); -// -// auto state = traj_controller_->configure(); -// ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); -// -// state = traj_node->activate(); -// ASSERT_EQ(state.id(), State::PRIMARY_STATE_ACTIVE); -// -// // wait for the subscriber and publisher to completely setup -// std::this_thread::sleep_for(std::chrono::seconds(2)); -// -// // send msg -// builtin_interfaces::msg::Duration time_from_start; -// time_from_start.sec = 1; -// time_from_start.nanosec = 0; -// std::vector> points {{{3.3, 4.4, 5.5}}}; -// publish(time_from_start, points, rclcpp::Time()); -// // wait for msg is be published to the system -// std::this_thread::sleep_for(std::chrono::milliseconds(1000)); -// executor.spin_once(); -// -// traj_controller->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// resource_manager_->write(); -// -// // change in hw position -// EXPECT_EQ(3.3, joint_pos_[0]); -// EXPECT_EQ(4.4, joint_pos_[1]); -// EXPECT_EQ(5.5, joint_pos_[2]); -// -// executor.cancel(); -// } - -// TEST_F(TestTrajectoryController, reactivation) { -// auto traj_controller = std::make_shared( -// joint_names_, op_mode_); -// auto ret = traj_controller->init(test_robot_, controller_name_); -// if (ret != controller_interface::return_type::OK) { -// FAIL(); -// } -// -// auto traj_node = traj_controller->get_node(); -// rclcpp::executors::MultiThreadedExecutor executor; -// executor.add_node(traj_node->get_node_base_interface()); -// -// auto state = traj_controller_->configure(); -// ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); -// -// state = traj_node->activate(); -// ASSERT_EQ(state.id(), State::PRIMARY_STATE_ACTIVE); -// -// // wait for the subscriber and publisher to completely setup -// std::this_thread::sleep_for(std::chrono::seconds(2)); -// -// // send msg -// builtin_interfaces::msg::Duration time_from_start; -// time_from_start.sec = 1; -// time_from_start.nanosec = 0; -// // *INDENT-OFF* -// std::vector> points { -// {{3.3, 4.4, 5.5}}, -// {{7.7, 8.8, 9.9}}, -// {{10.10, 11.11, 12.12}} -// }; -// // *INDENT-ON* -// publish(time_from_start, points, rclcpp::Time()); -// // wait for msg is be published to the system -// std::this_thread::sleep_for(std::chrono::milliseconds(500)); -// executor.spin_once(); -// -// traj_controller->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// resource_manager_->write(); -// -// // deactivated -// // wait so controller process the second point when deactivated -// std::this_thread::sleep_for(std::chrono::milliseconds(500)); -// state = traj_controller_->deactivate(); -// ASSERT_EQ(state.id(), State::PRIMARY_STATE_INACTIVE); -// resource_manager_->read(); -// traj_controller->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// resource_manager_->write(); -// -// // no change in hw position -// EXPECT_EQ(3.3, joint_pos_[0]); -// EXPECT_EQ(4.4, joint_pos_[1]); -// EXPECT_EQ(5.5, joint_pos_[2]); -// -// // reactivated -// // wait so controller process the third point when reactivated -// std::this_thread::sleep_for(std::chrono::milliseconds(3000)); -// state = traj_node->activate(); -// ASSERT_EQ(state.id(), State::PRIMARY_STATE_ACTIVE); -// resource_manager_->read(); -// traj_controller->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// resource_manager_->write(); -// -// // change in hw position to 3rd point -// EXPECT_EQ(10.10, joint_pos_[0]); -// EXPECT_EQ(11.11, joint_pos_[1]); -// EXPECT_EQ(12.12, joint_pos_[2]); -// -// executor.cancel(); -// } - TEST_P(TrajectoryControllerTestParameterized, cleanup) { rclcpp::executors::MultiThreadedExecutor executor; - SetUpAndActivateTrajectoryController(executor); + std::vector params = { + rclcpp::Parameter("allow_nonzero_velocity_at_trajectory_end", true)}; + SetUpAndActivateTrajectoryController(executor, true, params); // send msg constexpr auto FIRST_POINT_TIME = std::chrono::milliseconds(250); @@ -338,13 +229,6 @@ TEST_P(TrajectoryControllerTestParameterized, cleanup) state = traj_controller_->get_node()->cleanup(); ASSERT_EQ(State::PRIMARY_STATE_UNCONFIGURED, state.id()); - // update for 0.25 seconds - updateController(rclcpp::Duration::from_seconds(0.25)); - - // should be home pose again - EXPECT_NEAR(INITIAL_POS_JOINT1, joint_pos_[0], COMMON_THRESHOLD); - EXPECT_NEAR(INITIAL_POS_JOINT2, joint_pos_[1], COMMON_THRESHOLD); - EXPECT_NEAR(INITIAL_POS_JOINT3, joint_pos_[2], COMMON_THRESHOLD); executor.cancel(); } @@ -369,6 +253,8 @@ TEST_P(TrajectoryControllerTestParameterized, correct_initialization_using_param { rclcpp::executors::MultiThreadedExecutor executor; SetUpTrajectoryController(executor, false); + traj_controller_->get_node()->set_parameter( + rclcpp::Parameter("allow_nonzero_velocity_at_trajectory_end", true)); // This call is replacing the way parameters are set via launch SetParameters(); @@ -428,21 +314,15 @@ TEST_P(TrajectoryControllerTestParameterized, correct_initialization_using_param EXPECT_LE(0.0, joint_eff_[2]); } - // cleanup - state = traj_controller_->get_node()->cleanup(); - ASSERT_EQ(State::PRIMARY_STATE_UNCONFIGURED, state.id()); - - // TODO(anyone): should the controller even allow calling update() when it is not active? - // update loop receives a new msg and updates accordingly - traj_controller_->update( - rclcpp::Time(static_cast(0.35 * 1e9)), rclcpp::Duration::from_seconds(0.1)); - - EXPECT_NEAR(3.3, joint_pos_[0], allowed_delta); - EXPECT_NEAR(4.4, joint_pos_[1], allowed_delta); - EXPECT_NEAR(5.5, joint_pos_[2], allowed_delta); + // reactivated + // wait so controller process the third point when reactivated + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + ActivateTrajectoryController(); + state = traj_controller_->get_state(); + ASSERT_EQ(state.id(), State::PRIMARY_STATE_ACTIVE); - // state = traj_controller_->get_node()->configure(); - // ASSERT_EQ(State::PRIMARY_STATE_INACTIVE, state.id()); + // TODO(christophfroehlich) add test if there is no active trajectory after + // reactivation once #558 or #609 got merged (needs methods for TestableJointTrajectoryController) executor.cancel(); } @@ -605,7 +485,9 @@ TEST_P(TrajectoryControllerTestParameterized, position_error_not_normalized) { rclcpp::executors::MultiThreadedExecutor executor; constexpr double k_p = 10.0; - SetUpAndActivateTrajectoryController(executor, true, {}, true, k_p, 0.0, false); + std::vector params = { + rclcpp::Parameter("allow_nonzero_velocity_at_trajectory_end", true)}; + SetUpAndActivateTrajectoryController(executor, true, params, true, k_p, 0.0, false); subscribeToState(); size_t n_joints = joint_names_.size(); @@ -659,14 +541,20 @@ TEST_P(TrajectoryControllerTestParameterized, position_error_not_normalized) EXPECT_NEAR(points[0][0], joint_pos_[0], allowed_delta); EXPECT_NEAR(points[0][1], joint_pos_[1], allowed_delta); EXPECT_NEAR(points[0][2], joint_pos_[2], allowed_delta); + EXPECT_NEAR(points[0][0], state_msg->output.positions[0], allowed_delta); + EXPECT_NEAR(points[0][1], state_msg->output.positions[1], allowed_delta); + EXPECT_NEAR(points[0][2], state_msg->output.positions[2], 3 * allowed_delta); } if (traj_controller_->has_velocity_command_interface()) { // check command interface - EXPECT_LE(0.0, joint_vel_[0]); - EXPECT_LE(0.0, joint_vel_[1]); - EXPECT_LE(0.0, joint_vel_[2]); + EXPECT_LT(0.0, joint_vel_[0]); + EXPECT_LT(0.0, joint_vel_[1]); + EXPECT_LT(0.0, joint_vel_[2]); + EXPECT_LT(0.0, state_msg->output.velocities[0]); + EXPECT_LT(0.0, state_msg->output.velocities[1]); + EXPECT_LT(0.0, state_msg->output.velocities[2]); // use_closed_loop_pid_adapter_ if (traj_controller_->use_closed_loop_pid_adapter()) @@ -688,9 +576,12 @@ TEST_P(TrajectoryControllerTestParameterized, position_error_not_normalized) if (traj_controller_->has_effort_command_interface()) { // check command interface - EXPECT_LE(0.0, joint_eff_[0]); - EXPECT_LE(0.0, joint_eff_[1]); - EXPECT_LE(0.0, joint_eff_[2]); + EXPECT_LT(0.0, joint_eff_[0]); + EXPECT_LT(0.0, joint_eff_[1]); + EXPECT_LT(0.0, joint_eff_[2]); + EXPECT_LT(0.0, state_msg->output.effort[0]); + EXPECT_LT(0.0, state_msg->output.effort[1]); + EXPECT_LT(0.0, state_msg->output.effort[2]); } executor.cancel(); @@ -703,7 +594,9 @@ TEST_P(TrajectoryControllerTestParameterized, position_error_normalized) { rclcpp::executors::MultiThreadedExecutor executor; constexpr double k_p = 10.0; - SetUpAndActivateTrajectoryController(executor, true, {}, true, k_p, 0.0, true); + std::vector params = { + rclcpp::Parameter("allow_nonzero_velocity_at_trajectory_end", true)}; + SetUpAndActivateTrajectoryController(executor, true, params, true, k_p, 0.0, true); subscribeToState(); size_t n_joints = joint_names_.size(); @@ -762,14 +655,9 @@ TEST_P(TrajectoryControllerTestParameterized, position_error_normalized) if (traj_controller_->has_velocity_command_interface()) { - // check command interface - EXPECT_LE(0.0, joint_vel_[0]); - EXPECT_LE(0.0, joint_vel_[1]); - // use_closed_loop_pid_adapter_ if (traj_controller_->use_closed_loop_pid_adapter()) { - EXPECT_GE(0.0, joint_vel_[2]); // we expect u = k_p * (s_d-s) for positions[0] and positions[1] EXPECT_NEAR( k_p * (state_msg->reference.positions[0] - INITIAL_POS_JOINTS[0]), joint_vel_[0], @@ -778,6 +666,7 @@ TEST_P(TrajectoryControllerTestParameterized, position_error_normalized) k_p * (state_msg->reference.positions[1] - INITIAL_POS_JOINTS[1]), joint_vel_[1], k_p * allowed_delta); // is error of positions[2] normalized? + EXPECT_GT(0.0, joint_vel_[2]); EXPECT_NEAR( k_p * (state_msg->reference.positions[2] - INITIAL_POS_JOINTS[2] - 2 * M_PI), joint_vel_[2], k_p * allowed_delta); @@ -785,16 +674,39 @@ TEST_P(TrajectoryControllerTestParameterized, position_error_normalized) else { // interpolated points_velocities only - EXPECT_LE(0.0, joint_vel_[2]); + // check command interface + EXPECT_LT(0.0, joint_vel_[0]); + EXPECT_LT(0.0, joint_vel_[1]); + EXPECT_LT(0.0, joint_vel_[2]); } } if (traj_controller_->has_effort_command_interface()) { - // check command interface - EXPECT_LE(0.0, joint_eff_[0]); - EXPECT_LE(0.0, joint_eff_[1]); - EXPECT_LE(0.0, joint_eff_[2]); + // use_closed_loop_pid_adapter_ + if (traj_controller_->use_closed_loop_pid_adapter()) + { + // we expect u = k_p * (s_d-s) for positions[0] and positions[1] + EXPECT_NEAR( + k_p * (state_msg->reference.positions[0] - INITIAL_POS_JOINTS[0]), joint_eff_[0], + k_p * allowed_delta); + EXPECT_NEAR( + k_p * (state_msg->reference.positions[1] - INITIAL_POS_JOINTS[1]), joint_eff_[1], + k_p * allowed_delta); + // is error of positions[2] normalized? + EXPECT_GT(0.0, joint_eff_[2]); + EXPECT_NEAR( + k_p * (state_msg->reference.positions[2] - INITIAL_POS_JOINTS[2] - 2 * M_PI), joint_eff_[2], + k_p * allowed_delta); + } + else + { + // interpolated points_velocities only + // check command interface + EXPECT_LT(0.0, joint_eff_[0]); + EXPECT_LT(0.0, joint_eff_[1]); + EXPECT_LT(0.0, joint_eff_[2]); + } } executor.cancel(); @@ -847,804 +759,883 @@ TEST_P(TrajectoryControllerTestParameterized, test_state_publish_rate) // test_state_publish_rate_target(0); // } -// /** -// * @brief test_jumbled_joint_order Test sending trajectories with a joint order different from -// * internal controller order -// */ -// TEST_P(TrajectoryControllerTestParameterized, test_jumbled_joint_order) -// { -// rclcpp::executors::SingleThreadedExecutor executor; -// SetUpAndActivateTrajectoryController(true, {}, &executor); -// { -// trajectory_msgs::msg::JointTrajectory traj_msg; -// const std::vector jumbled_joint_names{ -// joint_names_[1], joint_names_[2], joint_names_[0]}; -// traj_msg.joint_names = jumbled_joint_names; -// traj_msg.header.stamp = rclcpp::Time(0); -// traj_msg.points.resize(1); - -// traj_msg.points[0].time_from_start = rclcpp::Duration::from_seconds(0.25); -// traj_msg.points[0].positions.resize(3); -// traj_msg.points[0].positions[0] = 2.0; -// traj_msg.points[0].positions[1] = 3.0; -// traj_msg.points[0].positions[2] = 1.0; - -// if (traj_controller_->has_velocity_command_interface()) -// { -// traj_msg.points[0].velocities.resize(3); -// traj_msg.points[0].velocities[0] = -0.1; -// traj_msg.points[0].velocities[1] = -0.1; -// traj_msg.points[0].velocities[2] = -0.1; -// } - -// if (traj_controller_->has_effort_command_interface()) -// { -// traj_msg.points[0].effort.resize(3); -// traj_msg.points[0].effort[0] = -0.1; -// traj_msg.points[0].effort[1] = -0.1; -// traj_msg.points[0].effort[2] = -0.1; -// } - -// trajectory_publisher_->publish(traj_msg); -// } - -// traj_controller_->wait_for_trajectory(executor); -// // update for 0.25 seconds -// // TODO(destogl): Make this time a bit shorter to increase stability on the CI? -// // Currently COMMON_THRESHOLD is adjusted. -// updateController(rclcpp::Duration::from_seconds(0.25)); - -// if (traj_controller_->has_position_command_interface()) -// { -// EXPECT_NEAR(1.0, joint_pos_[0], COMMON_THRESHOLD); -// EXPECT_NEAR(2.0, joint_pos_[1], COMMON_THRESHOLD); -// EXPECT_NEAR(3.0, joint_pos_[2], COMMON_THRESHOLD); -// } +/** + * @brief check if use_closed_loop_pid is active + */ +TEST_P(TrajectoryControllerTestParameterized, use_closed_loop_pid) +{ + rclcpp::executors::MultiThreadedExecutor executor; -// if (traj_controller_->has_velocity_command_interface()) -// { -// EXPECT_GT(0.0, joint_vel_[0]); -// EXPECT_GT(0.0, joint_vel_[1]); -// EXPECT_GT(0.0, joint_vel_[2]); -// } + SetUpAndActivateTrajectoryController(executor); -// if (traj_controller_->has_effort_command_interface()) -// { -// EXPECT_GT(0.0, joint_eff_[0]); -// EXPECT_GT(0.0, joint_eff_[1]); -// EXPECT_GT(0.0, joint_eff_[2]); -// } -// } + if ( + (traj_controller_->has_velocity_command_interface() && + !traj_controller_->has_position_command_interface() && + !traj_controller_->has_effort_command_interface() && + !traj_controller_->has_acceleration_command_interface() && + !traj_controller_->is_open_loop()) || + traj_controller_->has_effort_command_interface()) + { + EXPECT_TRUE(traj_controller_->use_closed_loop_pid_adapter()); + } +} -// /** -// * @brief test_partial_joint_list Test sending trajectories with a subset of the controlled -// * joints -// */ -// TEST_P(TrajectoryControllerTestParameterized, test_partial_joint_list) -// { -// rclcpp::Parameter partial_joints_parameters("allow_partial_joints_goal", true); +/** + * @brief check if velocity error is calculated correctly + */ +TEST_P(TrajectoryControllerTestParameterized, velocity_error) +{ + rclcpp::executors::MultiThreadedExecutor executor; + SetUpAndActivateTrajectoryController(executor, true, {}, true); + subscribeToState(); -// rclcpp::executors::SingleThreadedExecutor executor; -// SetUpAndActivateTrajectoryController(true, {partial_joints_parameters}, &executor); + size_t n_joints = joint_names_.size(); -// const double initial_joint1_cmd = joint_pos_[0]; -// const double initial_joint2_cmd = joint_pos_[1]; -// const double initial_joint3_cmd = joint_pos_[2]; -// trajectory_msgs::msg::JointTrajectory traj_msg; + // 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_positions{ + {{3.3, 4.4, 6.6}}, {{7.7, 8.8, 9.9}}, {{10.10, 11.11, 12.12}}}; + std::vector> points_velocities{ + {{0.1, 0.1, 0.1}}, {{0.2, 0.2, 0.2}}, {{0.3, 0.3, 0.3}}}; + // *INDENT-ON* + publish(time_from_start, points_positions, rclcpp::Time(), {}, points_velocities); + traj_controller_->wait_for_trajectory(executor); -// { -// std::vector partial_joint_names{joint_names_[1], joint_names_[0]}; -// traj_msg.joint_names = partial_joint_names; -// traj_msg.header.stamp = rclcpp::Time(0); -// traj_msg.points.resize(1); - -// traj_msg.points[0].time_from_start = rclcpp::Duration::from_seconds(0.25); -// traj_msg.points[0].positions.resize(2); -// traj_msg.points[0].positions[0] = 2.0; -// traj_msg.points[0].positions[1] = 1.0; -// traj_msg.points[0].velocities.resize(2); -// traj_msg.points[0].velocities[0] = -// copysign(2.0, traj_msg.points[0].positions[0] - initial_joint2_cmd); -// traj_msg.points[0].velocities[1] = -// copysign(1.0, traj_msg.points[0].positions[1] - initial_joint1_cmd); - -// trajectory_publisher_->publish(traj_msg); -// } - -// traj_controller_->wait_for_trajectory(executor); -// // update for 0.5 seconds -// updateController(rclcpp::Duration::from_seconds(0.25)); - -// double threshold = 0.001; - -// if (traj_controller_->has_position_command_interface()) -// { -// EXPECT_NEAR(traj_msg.points[0].positions[1], joint_pos_[0], threshold); -// EXPECT_NEAR(traj_msg.points[0].positions[0], joint_pos_[1], threshold); -// EXPECT_NEAR(initial_joint3_cmd, joint_pos_[2], threshold) -// << "Joint 3 command should be current position"; -// } - -// if ( -// std::find(command_interface_types_.begin(), command_interface_types_.end(), "velocity") != -// command_interface_types_.end()) -// { -// // estimate the sign of the velocity -// // joint rotates forward -// EXPECT_TRUE( -// is_same_sign(traj_msg.points[0].positions[0] - initial_joint2_cmd, joint_vel_[0])); -// EXPECT_TRUE( -// is_same_sign(traj_msg.points[0].positions[1] - initial_joint1_cmd, joint_vel_[1])); -// EXPECT_NEAR(0.0, joint_vel_[2], threshold) -// << "Joint 3 velocity should be 0.0 since it's not in the goal"; -// } - -// if ( -// std::find(command_interface_types_.begin(), command_interface_types_.end(), "effort") != -// command_interface_types_.end()) -// { -// // estimate the sign of the velocity -// // joint rotates forward -// EXPECT_TRUE( -// is_same_sign(traj_msg.points[0].positions[0] - initial_joint2_cmd, joint_eff_[0])); -// EXPECT_TRUE( -// is_same_sign(traj_msg.points[0].positions[1] - initial_joint1_cmd, joint_eff_[1])); -// EXPECT_NEAR(0.0, joint_eff_[2], threshold) -// << "Joint 3 effort should be 0.0 since it's not in the goal"; -// } -// // TODO(anyone): add here ckecks for acceleration commands - -// executor.cancel(); -// } + // first update + updateController(rclcpp::Duration(FIRST_POINT_TIME)); -// /** -// * @brief test_partial_joint_list Test sending trajectories with a subset of the controlled -// * joints without allow_partial_joints_goal -// */ -// TEST_P(TrajectoryControllerTestParameterized, test_partial_joint_list_not_allowed) -// { -// rclcpp::Parameter partial_joints_parameters("allow_partial_joints_goal", false); + // Spin to receive latest state + executor.spin_some(); + auto state_msg = getState(); + ASSERT_TRUE(state_msg); -// rclcpp::executors::SingleThreadedExecutor executor; -// SetUpAndActivateTrajectoryController(true, {partial_joints_parameters}, &executor); + // has the msg the correct vector sizes? + EXPECT_EQ(n_joints, state_msg->reference.positions.size()); + EXPECT_EQ(n_joints, state_msg->feedback.positions.size()); + EXPECT_EQ(n_joints, state_msg->error.positions.size()); + if (traj_controller_->has_velocity_state_interface()) + { + EXPECT_EQ(n_joints, state_msg->reference.velocities.size()); + EXPECT_EQ(n_joints, state_msg->feedback.velocities.size()); + EXPECT_EQ(n_joints, state_msg->error.velocities.size()); + } + if (traj_controller_->has_acceleration_state_interface()) + { + EXPECT_EQ(n_joints, state_msg->reference.accelerations.size()); + EXPECT_EQ(n_joints, state_msg->feedback.accelerations.size()); + EXPECT_EQ(n_joints, state_msg->error.accelerations.size()); + } -// const double initial_joint1_cmd = joint_pos_[0]; -// const double initial_joint2_cmd = joint_pos_[1]; -// const double initial_joint3_cmd = joint_pos_[2]; -// const double initial_joint_vel = 0.0; -// const double initial_joint_acc = 0.0; -// trajectory_msgs::msg::JointTrajectory traj_msg; + // no change in state interface should happen + if (traj_controller_->has_velocity_state_interface()) + { + EXPECT_EQ(state_msg->feedback.velocities, INITIAL_VEL_JOINTS); + } + // is the velocity error correct? + if ( + traj_controller_->use_closed_loop_pid_adapter() // always needed for PID controller + || (traj_controller_->has_velocity_state_interface() && + traj_controller_->has_velocity_command_interface())) + { + // don't check against a value, because spline intepolation might overshoot depending on + // interface combinations + EXPECT_GE(state_msg->error.velocities[0], points_velocities[0][0]); + EXPECT_GE(state_msg->error.velocities[1], points_velocities[0][1]); + EXPECT_GE(state_msg->error.velocities[2], points_velocities[0][2]); + } -// { -// std::vector partial_joint_names{joint_names_[1], joint_names_[0]}; -// traj_msg.joint_names = partial_joint_names; -// traj_msg.header.stamp = rclcpp::Time(0); -// traj_msg.points.resize(1); - -// traj_msg.points[0].time_from_start = rclcpp::Duration::from_seconds(0.25); -// traj_msg.points[0].positions.resize(2); -// traj_msg.points[0].positions[0] = 2.0; -// traj_msg.points[0].positions[1] = 1.0; -// traj_msg.points[0].velocities.resize(2); -// traj_msg.points[0].velocities[0] = 2.0; -// traj_msg.points[0].velocities[1] = 1.0; - -// trajectory_publisher_->publish(traj_msg); -// } - -// traj_controller_->wait_for_trajectory(executor); -// // update for 0.5 seconds -// updateController(rclcpp::Duration::from_seconds(0.25)); - -// double threshold = 0.001; -// EXPECT_NEAR(initial_joint1_cmd, joint_pos_[0], threshold) -// << "All joints command should be current position because goal was rejected"; -// EXPECT_NEAR(initial_joint2_cmd, joint_pos_[1], threshold) -// << "All joints command should be current position because goal was rejected"; -// EXPECT_NEAR(initial_joint3_cmd, joint_pos_[2], threshold) -// << "All joints command should be current position because goal was rejected"; - -// if ( -// std::find(command_interface_types_.begin(), command_interface_types_.end(), "velocity") != -// command_interface_types_.end()) -// { -// EXPECT_NEAR(initial_joint_vel, joint_vel_[0], threshold) -// << "All joints velocities should be 0.0 because goal was rejected"; -// EXPECT_NEAR(initial_joint_vel, joint_vel_[1], threshold) -// << "All joints velocities should be 0.0 because goal was rejected"; -// EXPECT_NEAR(initial_joint_vel, joint_vel_[2], threshold) -// << "All joints velocities should be 0.0 because goal was rejected"; -// } - -// if ( -// std::find( -// command_interface_types_.begin(), command_interface_types_.end(), "acceleration") != -// command_interface_types_.end()) -// { -// EXPECT_NEAR(initial_joint_acc, joint_acc_[0], threshold) -// << "All joints accelerations should be 0.0 because goal was rejected"; -// EXPECT_NEAR(initial_joint_acc, joint_acc_[1], threshold) -// << "All joints accelerations should be 0.0 because goal was rejected"; -// EXPECT_NEAR(initial_joint_acc, joint_acc_[2], threshold) -// << "All joints accelerations should be 0.0 because goal was rejected"; -// } - -// executor.cancel(); -// } + executor.cancel(); +} -// /** -// * @brief invalid_message Test mismatched joint and reference vector sizes -// */ -// TEST_P(TrajectoryControllerTestParameterized, invalid_message) -// { -// rclcpp::Parameter partial_joints_parameters("allow_partial_joints_goal", false); -// rclcpp::Parameter allow_integration_parameters( -// "allow_integration_in_goal_trajectories", false); -// rclcpp::executors::SingleThreadedExecutor executor; -// SetUpAndActivateTrajectoryController( -// true, {partial_joints_parameters, allow_integration_parameters}, &executor); - -// trajectory_msgs::msg::JointTrajectory traj_msg, good_traj_msg; - -// good_traj_msg.joint_names = joint_names_; -// good_traj_msg.header.stamp = rclcpp::Time(0); -// good_traj_msg.points.resize(1); -// good_traj_msg.points[0].time_from_start = rclcpp::Duration::from_seconds(0.25); -// good_traj_msg.points[0].positions.resize(1); -// good_traj_msg.points[0].positions = {1.0, 2.0, 3.0}; -// good_traj_msg.points[0].velocities.resize(1); -// good_traj_msg.points[0].velocities = {-1.0, -2.0, -3.0}; -// EXPECT_TRUE(traj_controller_->validate_trajectory_msg(good_traj_msg)); - -// // Incompatible joint names -// traj_msg = good_traj_msg; -// traj_msg.joint_names = {"bad_name"}; -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // No position data -// traj_msg = good_traj_msg; -// traj_msg.points[0].positions.clear(); -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // Incompatible data sizes, too few positions -// traj_msg = good_traj_msg; -// traj_msg.points[0].positions = {1.0, 2.0}; -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // Incompatible data sizes, too many positions -// traj_msg = good_traj_msg; -// traj_msg.points[0].positions = {1.0, 2.0, 3.0, 4.0}; -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // Incompatible data sizes, too few velocities -// traj_msg = good_traj_msg; -// traj_msg.points[0].velocities = {1.0, 2.0}; -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // Incompatible data sizes, too few accelerations -// traj_msg = good_traj_msg; -// traj_msg.points[0].accelerations = {1.0, 2.0}; -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // Incompatible data sizes, too few efforts -// traj_msg = good_traj_msg; -// traj_msg.points[0].positions.clear(); -// traj_msg.points[0].effort = {1.0, 2.0}; -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // Non-strictly increasing waypoint times -// traj_msg = good_traj_msg; -// traj_msg.points.push_back(traj_msg.points.front()); -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); -// } +/** + * @brief test_jumbled_joint_order Test sending trajectories with a joint order different from + * internal controller order + */ +TEST_P(TrajectoryControllerTestParameterized, test_jumbled_joint_order) +{ + rclcpp::executors::SingleThreadedExecutor executor; + SetUpAndActivateTrajectoryController(executor); + { + trajectory_msgs::msg::JointTrajectory traj_msg; + const std::vector jumbled_joint_names{ + joint_names_[1], joint_names_[2], joint_names_[0]}; + traj_msg.joint_names = jumbled_joint_names; + traj_msg.header.stamp = rclcpp::Time(0); + traj_msg.points.resize(1); + + traj_msg.points[0].time_from_start = rclcpp::Duration::from_seconds(0.25); + traj_msg.points[0].positions.resize(3); + traj_msg.points[0].positions[0] = 2.0; + traj_msg.points[0].positions[1] = 3.0; + traj_msg.points[0].positions[2] = 1.0; + + if (traj_controller_->has_velocity_command_interface()) + { + traj_msg.points[0].velocities.resize(3); + traj_msg.points[0].velocities[0] = -0.1; + traj_msg.points[0].velocities[1] = -0.1; + traj_msg.points[0].velocities[2] = -0.1; + } + trajectory_publisher_->publish(traj_msg); + } -// /// With allow_integration_in_goal_trajectories parameter trajectory missing position or -// /// velocities are accepted -// TEST_P(TrajectoryControllerTestParameterized, missing_positions_message_accepted) -// { -// rclcpp::Parameter allow_integration_parameters("allow_integration_in_goal_trajectories", true); -// rclcpp::executors::SingleThreadedExecutor executor; -// SetUpAndActivateTrajectoryController(true, {allow_integration_parameters}, &executor); - -// trajectory_msgs::msg::JointTrajectory traj_msg, good_traj_msg; - -// good_traj_msg.joint_names = joint_names_; -// good_traj_msg.header.stamp = rclcpp::Time(0); -// good_traj_msg.points.resize(1); -// good_traj_msg.points[0].time_from_start = rclcpp::Duration::from_seconds(0.25); -// good_traj_msg.points[0].positions.resize(1); -// good_traj_msg.points[0].positions = {1.0, 2.0, 3.0}; -// good_traj_msg.points[0].velocities.resize(1); -// good_traj_msg.points[0].velocities = {-1.0, -2.0, -3.0}; -// good_traj_msg.points[0].accelerations.resize(1); -// good_traj_msg.points[0].accelerations = {1.0, 2.0, 3.0}; -// EXPECT_TRUE(traj_controller_->validate_trajectory_msg(good_traj_msg)); - -// // No position data -// traj_msg = good_traj_msg; -// traj_msg.points[0].positions.clear(); -// EXPECT_TRUE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // No position and velocity data -// traj_msg = good_traj_msg; -// traj_msg.points[0].positions.clear(); -// traj_msg.points[0].velocities.clear(); -// EXPECT_TRUE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // All empty -// traj_msg = good_traj_msg; -// traj_msg.points[0].positions.clear(); -// traj_msg.points[0].velocities.clear(); -// traj_msg.points[0].accelerations.clear(); -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // Incompatible data sizes, too few positions -// traj_msg = good_traj_msg; -// traj_msg.points[0].positions = {1.0, 2.0}; -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // Incompatible data sizes, too many positions -// traj_msg = good_traj_msg; -// traj_msg.points[0].positions = {1.0, 2.0, 3.0, 4.0}; -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // Incompatible data sizes, too few velocities -// traj_msg = good_traj_msg; -// traj_msg.points[0].velocities = {1.0}; -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); - -// // Incompatible data sizes, too few accelerations -// traj_msg = good_traj_msg; -// traj_msg.points[0].accelerations = {2.0}; -// EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); -// } + traj_controller_->wait_for_trajectory(executor); + // update for 0.25 seconds + // TODO(destogl): Make this time a bit shorter to increase stability on the CI? + // Currently COMMON_THRESHOLD is adjusted. + updateController(rclcpp::Duration::from_seconds(0.25)); -// /** -// * @brief test_trajectory_replace Test replacing an existing trajectory -// */ -// TEST_P(TrajectoryControllerTestParameterized, test_trajectory_replace) -// { -// rclcpp::executors::SingleThreadedExecutor executor; -// rclcpp::Parameter partial_joints_parameters("allow_partial_joints_goal", true); -// SetUpAndActivateTrajectoryController(true, {partial_joints_parameters}, &executor); - -// subscribeToState(); - -// std::vector> points_old{{{2., 3., 4.}}}; -// std::vector> points_old_velocities{{{0.2, 0.3, 0.4}}}; -// std::vector> points_partial_new{{1.5}}; -// std::vector> points_partial_new_velocities{{0.15}}; - -// const auto delay = std::chrono::milliseconds(500); -// builtin_interfaces::msg::Duration time_from_start{rclcpp::Duration(delay)}; -// publish(time_from_start, points_old, rclcpp::Time(), {}, points_old_velocities); -// trajectory_msgs::msg::JointTrajectoryPoint expected_actual, expected_desired; -// expected_actual.positions = {points_old[0].begin(), points_old[0].end()}; -// expected_desired.positions = {points_old[0].begin(), points_old[0].end()}; -// expected_actual.velocities = { -// points_old_velocities[0].begin(), points_old_velocities[0].end()}; -// expected_desired.velocities = { -// points_old_velocities[0].begin(), points_old_velocities[0].end()}; -// // Check that we reached end of points_old trajectory -// // Denis: delta was 0.1 with 0.2 works for me -// waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.2); - -// RCLCPP_INFO(traj_controller_->get_node()->get_logger(), "Sending new trajectory"); -// points_partial_new_velocities[0][0] = -// copysign(0.15, points_partial_new[0][0] - joint_state_pos_[0]); -// publish( -// time_from_start, points_partial_new, rclcpp::Time(), {}, points_partial_new_velocities); - -// // Replaced trajectory is a mix of previous and current goal -// expected_desired.positions[0] = points_partial_new[0][0]; -// expected_desired.positions[1] = points_old[0][1]; -// expected_desired.positions[2] = points_old[0][2]; -// expected_desired.velocities[0] = points_partial_new_velocities[0][0]; -// expected_desired.velocities[1] = 0.0; -// expected_desired.velocities[2] = 0.0; -// expected_actual = expected_desired; -// waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); -// } + if (traj_controller_->has_position_command_interface()) + { + EXPECT_NEAR(1.0, joint_pos_[0], COMMON_THRESHOLD); + EXPECT_NEAR(2.0, joint_pos_[1], COMMON_THRESHOLD); + EXPECT_NEAR(3.0, joint_pos_[2], COMMON_THRESHOLD); + } -// /** -// * @brief test_ignore_old_trajectory Sending an old trajectory replacing an existing trajectory -// */ -// TEST_P(TrajectoryControllerTestParameterized, test_ignore_old_trajectory) -// { -// rclcpp::executors::SingleThreadedExecutor executor; -// SetUpAndActivateTrajectoryController(true, {}, &executor); -// subscribeToState(); - -// // TODO(anyone): add expectations for velocities and accelerations -// std::vector> points_old{{{2., 3., 4.}, {4., 5., 6.}}}; -// std::vector> points_new{{{-1., -2., -3.}}}; - -// RCLCPP_INFO( -// traj_controller_->get_node()->get_logger(), "Sending new trajectory in the future"); -// const auto delay = std::chrono::milliseconds(500); -// builtin_interfaces::msg::Duration time_from_start{rclcpp::Duration(delay)}; -// publish(time_from_start, points_old, rclcpp::Time()); -// trajectory_msgs::msg::JointTrajectoryPoint expected_actual, expected_desired; -// expected_actual.positions = {points_old[0].begin(), points_old[0].end()}; -// expected_desired = expected_actual; -// // Check that we reached end of points_old[0] trajectory -// waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); - -// RCLCPP_INFO(traj_controller_->get_node()->get_logger(), "Sending new trajectory in the past"); -// // New trajectory will end before current time -// rclcpp::Time new_traj_start = rclcpp::Clock().now() - delay - std::chrono::milliseconds(100); -// expected_actual.positions = {points_old[1].begin(), points_old[1].end()}; -// expected_desired = expected_actual; -// std::cout << "Sending old trajectory" << std::endl; -// publish(time_from_start, points_new, new_traj_start); -// waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); -// } + if (traj_controller_->has_velocity_command_interface()) + { + EXPECT_GT(0.0, joint_vel_[0]); + EXPECT_GT(0.0, joint_vel_[1]); + EXPECT_GT(0.0, joint_vel_[2]); + } + // TODO(anyone): add here checks for acceleration commands +} -// TEST_P(TrajectoryControllerTestParameterized, test_ignore_partial_old_trajectory) -// { -// rclcpp::executors::SingleThreadedExecutor executor; -// SetUpAndActivateTrajectoryController(true, {}, &executor); -// subscribeToState(); - -// std::vector> points_old{{{2., 3., 4.}, {4., 5., 6.}}}; -// std::vector> points_new{{{-1., -2., -3.}, {-2., -4., -6.}}}; - -// const auto delay = std::chrono::milliseconds(500); -// builtin_interfaces::msg::Duration time_from_start{rclcpp::Duration(delay)}; -// publish(time_from_start, points_old, rclcpp::Time()); -// trajectory_msgs::msg::JointTrajectoryPoint expected_actual, expected_desired; -// expected_actual.positions = {points_old[0].begin(), points_old[0].end()}; -// expected_desired = expected_actual; -// // Check that we reached end of points_old[0]trajectory -// waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); - -// RCLCPP_INFO( -// traj_controller_->get_node()->get_logger(), "Sending new trajectory partially in the past"); -// // New trajectory first point is in the past, second is in the future -// rclcpp::Time new_traj_start = rclcpp::Clock().now() - delay - std::chrono::milliseconds(100); -// expected_actual.positions = {points_new[1].begin(), points_new[1].end()}; -// expected_desired = expected_actual; -// publish(time_from_start, points_new, new_traj_start); -// waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); -// } +/** + * @brief test_partial_joint_list Test sending trajectories with a subset of the controlled + * joints + */ +TEST_P(TrajectoryControllerTestParameterized, test_partial_joint_list) +{ + rclcpp::Parameter partial_joints_parameters("allow_partial_joints_goal", true); -// TEST_P(TrajectoryControllerTestParameterized, test_execute_partial_traj_in_future) -// { -// SetUpTrajectoryController(); -// auto traj_node = traj_controller_->get_node(); -// RCLCPP_WARN( -// traj_node->get_logger(), -// "Test disabled until current_trajectory is taken into account when adding a new trajectory."); -// // https://github.com/ros-controls/ros_controllers/blob/melodic-devel/ -// // joint_trajectory_controller/include/joint_trajectory_controller/init_joint_trajectory.h#L149 -// return; - -// // TODO(anyone): use SetUpAndActivateTrajectoryController method instead of the next line -// rclcpp::executors::SingleThreadedExecutor executor; -// executor.add_node(traj_node->get_node_base_interface()); -// subscribeToState(); -// rclcpp::Parameter partial_joints_parameters("allow_partial_joints_goal", true); -// traj_node->set_parameter(partial_joints_parameters); -// traj_controller_->get_node()->configure(); -// traj_controller_->get_node()->activate(); - -// std::vector> full_traj{{{2., 3., 4.}, {4., 6., 8.}}}; -// std::vector> full_traj_velocities{{{0.2, 0.3, 0.4}, {0.4, 0.6, 0.8}}}; -// std::vector> partial_traj{ -// {{-1., -2.}, -// { -// -2., -// -4, -// }}}; -// std::vector> partial_traj_velocities{ -// {{-0.1, -0.2}, -// { -// -0.2, -// -0.4, -// }}}; -// const auto delay = std::chrono::milliseconds(500); -// builtin_interfaces::msg::Duration points_delay{rclcpp::Duration(delay)}; -// // Send full trajectory -// publish(points_delay, full_traj, rclcpp::Time(), {}, full_traj_velocities); -// // Sleep until first waypoint of full trajectory - -// trajectory_msgs::msg::JointTrajectoryPoint expected_actual, expected_desired; -// expected_actual.positions = {full_traj[0].begin(), full_traj[0].end()}; -// expected_desired = expected_actual; -// // Check that we reached end of points_old[0]trajectory and are starting points_old[1] -// waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); - -// // Send partial trajectory starting after full trajecotry is complete -// RCLCPP_INFO(traj_node->get_logger(), "Sending new trajectory in the future"); -// publish( -// points_delay, partial_traj, rclcpp::Clock().now() + delay * 2, {}, partial_traj_velocities); -// // Wait until the end start and end of partial traj - -// expected_actual.positions = { -// partial_traj.back()[0], partial_traj.back()[1], full_traj.back()[2]}; -// expected_desired = expected_actual; - -// waitAndCompareState( -// expected_actual, expected_desired, executor, rclcpp::Duration(delay * (2 + 2)), 0.1); -// } + rclcpp::executors::SingleThreadedExecutor executor; + SetUpAndActivateTrajectoryController(executor, true, {partial_joints_parameters}); -// TEST_P(TrajectoryControllerTestParameterized, test_jump_when_state_tracking_error_updated) -// { -// rclcpp::executors::SingleThreadedExecutor executor; -// // default if false so it will not be actually set parameter -// rclcpp::Parameter is_open_loop_parameters("open_loop_control", false); -// SetUpAndActivateTrajectoryController(true, {is_open_loop_parameters}, &executor, true); - -// // goal setup -// std::vector first_goal = {3.3, 4.4, 5.5}; -// std::vector> first_goal_velocities = {{0.33, 0.44, 0.55}}; -// std::vector second_goal = {6.6, 8.8, 11.0}; -// std::vector> second_goal_velocities = {{0.66, 0.88, 1.1}}; -// double state_from_command_offset = 0.3; - -// // send msg -// builtin_interfaces::msg::Duration time_from_start; -// time_from_start.sec = 1; -// time_from_start.nanosec = 0; -// std::vector> points{{first_goal}}; -// publish(time_from_start, points, rclcpp::Time(), {}, first_goal_velocities); -// traj_controller_->wait_for_trajectory(executor); -// updateController(rclcpp::Duration::from_seconds(1.1)); - -// if (traj_controller_->has_position_command_interface()) -// { -// // JTC is executing trajectory in open-loop therefore: -// // - internal state does not have to be updated (in this test-case it shouldn't) -// // - internal command is updated -// EXPECT_NEAR(INITIAL_POS_JOINT1, joint_state_pos_[0], COMMON_THRESHOLD); -// EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); - -// // State interface should have offset from the command before starting a new trajectory -// joint_state_pos_[0] = first_goal[0] - state_from_command_offset; - -// // Move joint further in the same direction as before (to the second goal) -// points = {{second_goal}}; -// publish(time_from_start, points, rclcpp::Time(1.0), {}, second_goal_velocities); -// traj_controller_->wait_for_trajectory(executor); - -// // One the first update(s) there should be a "jump" in opposite direction from command -// // (towards the state value) -// EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// // Expect backward commands at first -// EXPECT_NEAR(joint_state_pos_[0], joint_pos_[0], COMMON_THRESHOLD); -// EXPECT_GT(joint_pos_[0], joint_state_pos_[0]); -// EXPECT_LT(joint_pos_[0], first_goal[0]); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// EXPECT_GT(joint_pos_[0], joint_state_pos_[0]); -// EXPECT_LT(joint_pos_[0], first_goal[0]); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// EXPECT_GT(joint_pos_[0], joint_state_pos_[0]); -// EXPECT_LT(joint_pos_[0], first_goal[0]); - -// // Finally the second goal will be commanded/reached -// updateController(rclcpp::Duration::from_seconds(1.1)); -// EXPECT_NEAR(second_goal[0], joint_pos_[0], COMMON_THRESHOLD); - -// // State interface should have offset from the command before starting a new trajectory -// joint_state_pos_[0] = second_goal[0] - state_from_command_offset; - -// // Move joint back to the first goal -// points = {{first_goal}}; -// publish(time_from_start, points, rclcpp::Time()); -// traj_controller_->wait_for_trajectory(executor); - -// // One the first update(s) there should be a "jump" in the goal direction from command -// // (towards the state value) -// EXPECT_NEAR(second_goal[0], joint_pos_[0], COMMON_THRESHOLD); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// // Expect backward commands at first -// EXPECT_NEAR(joint_state_pos_[0], joint_pos_[0], COMMON_THRESHOLD); -// EXPECT_LT(joint_pos_[0], joint_state_pos_[0]); -// EXPECT_GT(joint_pos_[0], first_goal[0]); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// EXPECT_LT(joint_pos_[0], joint_state_pos_[0]); -// EXPECT_GT(joint_pos_[0], first_goal[0]); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// EXPECT_LT(joint_pos_[0], joint_state_pos_[0]); -// EXPECT_GT(joint_pos_[0], first_goal[0]); - -// // Finally the first goal will be commanded/reached -// updateController(rclcpp::Duration::from_seconds(1.1)); -// EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); -// } - -// executor.cancel(); -// } + const double initial_joint1_cmd = joint_pos_[0]; + const double initial_joint2_cmd = joint_pos_[1]; + const double initial_joint3_cmd = joint_pos_[2]; + trajectory_msgs::msg::JointTrajectory traj_msg; -// TEST_P(TrajectoryControllerTestParameterized, test_no_jump_when_state_tracking_error_not_updated) -// { -// rclcpp::executors::SingleThreadedExecutor executor; -// // default if false so it will not be actually set parameter -// rclcpp::Parameter is_open_loop_parameters("open_loop_control", true); -// SetUpAndActivateTrajectoryController(true, {is_open_loop_parameters}, &executor, true); - -// // goal setup -// std::vector first_goal = {3.3, 4.4, 5.5}; -// std::vector second_goal = {6.6, 8.8, 11.0}; -// double state_from_command_offset = 0.3; - -// // send msg -// builtin_interfaces::msg::Duration time_from_start; -// time_from_start.sec = 1; -// time_from_start.nanosec = 0; -// std::vector> points{{first_goal}}; -// publish(time_from_start, points, rclcpp::Time()); -// traj_controller_->wait_for_trajectory(executor); -// updateController(rclcpp::Duration::from_seconds(1.1)); - -// if (traj_controller_->has_position_command_interface()) -// { -// // JTC is executing trajectory in open-loop therefore: -// // - internal state does not have to be updated (in this test-case it shouldn't) -// // - internal command is updated -// EXPECT_NEAR(INITIAL_POS_JOINT1, joint_state_pos_[0], COMMON_THRESHOLD); -// EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); - -// // State interface should have offset from the command before starting a new trajectory -// joint_state_pos_[0] = first_goal[0] - state_from_command_offset; - -// // Move joint further in the same direction as before (to the second goal) -// points = {{second_goal}}; -// publish(time_from_start, points, rclcpp::Time()); -// traj_controller_->wait_for_trajectory(executor); - -// // One the first update(s) there **should not** be a "jump" in opposite direction from -// // command (towards the state value) -// EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// // There should not be backward commands -// EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); -// EXPECT_GT(joint_pos_[0], first_goal[0]); -// EXPECT_LT(joint_pos_[0], second_goal[0]); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// EXPECT_GT(joint_pos_[0], first_goal[0]); -// EXPECT_LT(joint_pos_[0], second_goal[0]); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// EXPECT_GT(joint_pos_[0], first_goal[0]); -// EXPECT_LT(joint_pos_[0], second_goal[0]); - -// // Finally the second goal will be commanded/reached -// updateController(rclcpp::Duration::from_seconds(1.1)); -// EXPECT_NEAR(second_goal[0], joint_pos_[0], COMMON_THRESHOLD); - -// // State interface should have offset from the command before starting a new trajectory -// joint_state_pos_[0] = second_goal[0] - state_from_command_offset; - -// // Move joint back to the first goal -// points = {{first_goal}}; -// publish(time_from_start, points, rclcpp::Time()); -// traj_controller_->wait_for_trajectory(executor); - -// // One the first update(s) there **should not** be a "jump" in the goal direction from -// // command (towards the state value) -// EXPECT_NEAR(second_goal[0], joint_pos_[0], COMMON_THRESHOLD); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// // There should not be a jump toward commands -// EXPECT_NEAR(second_goal[0], joint_pos_[0], COMMON_THRESHOLD); -// EXPECT_LT(joint_pos_[0], second_goal[0]); -// EXPECT_GT(joint_pos_[0], first_goal[0]); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// EXPECT_GT(joint_pos_[0], first_goal[0]); -// EXPECT_LT(joint_pos_[0], second_goal[0]); -// traj_controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); -// EXPECT_GT(joint_pos_[0], first_goal[0]); -// EXPECT_LT(joint_pos_[0], second_goal[0]); - -// // Finally the first goal will be commanded/reached -// updateController(rclcpp::Duration::from_seconds(1.1)); -// EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); -// } - -// executor.cancel(); -// } + { + std::vector partial_joint_names{joint_names_[1], joint_names_[0]}; + traj_msg.joint_names = partial_joint_names; + traj_msg.header.stamp = rclcpp::Time(0); + traj_msg.points.resize(1); + + traj_msg.points[0].time_from_start = rclcpp::Duration::from_seconds(0.25); + traj_msg.points[0].positions.resize(2); + traj_msg.points[0].positions[0] = 2.0; + traj_msg.points[0].positions[1] = 1.0; + traj_msg.points[0].velocities.resize(2); + traj_msg.points[0].velocities[0] = + copysign(2.0, traj_msg.points[0].positions[0] - initial_joint2_cmd); + traj_msg.points[0].velocities[1] = + copysign(1.0, traj_msg.points[0].positions[1] - initial_joint1_cmd); + + trajectory_publisher_->publish(traj_msg); + } -// // Testing that values are read from state interfaces when hardware is started for the first -// // time and hardware state has offset --> this is indicated by NaN values in state interfaces -// TEST_P(TrajectoryControllerTestParameterized, test_hw_states_has_offset_first_controller_start) -// { -// rclcpp::executors::SingleThreadedExecutor executor; -// // default if false so it will not be actually set parameter -// rclcpp::Parameter is_open_loop_parameters("open_loop_control", true); + traj_controller_->wait_for_trajectory(executor); + updateController(rclcpp::Duration::from_seconds(0.25)); -// // set command values to NaN -// for (size_t i = 0; i < 3; ++i) -// { -// joint_pos_[i] = std::numeric_limits::quiet_NaN(); -// joint_vel_[i] = std::numeric_limits::quiet_NaN(); -// joint_acc_[i] = std::numeric_limits::quiet_NaN(); -// } -// SetUpAndActivateTrajectoryController(true, {is_open_loop_parameters}, &executor, true); + double threshold = 0.001; -// auto current_state_when_offset = traj_controller_->get_current_state_when_offset(); + if (traj_controller_->has_position_command_interface()) + { + EXPECT_NEAR(traj_msg.points[0].positions[1], joint_pos_[0], threshold); + EXPECT_NEAR(traj_msg.points[0].positions[0], joint_pos_[1], threshold); + EXPECT_NEAR(initial_joint3_cmd, joint_pos_[2], threshold) + << "Joint 3 command should be current position"; + } -// for (size_t i = 0; i < 3; ++i) -// { -// EXPECT_EQ(current_state_when_offset.positions[i], joint_state_pos_[i]); - -// // check velocity -// if ( -// std::find( -// state_interface_types_.begin(), state_interface_types_.end(), -// hardware_interface::HW_IF_VELOCITY) != state_interface_types_.end() && -// std::find( -// command_interface_types_.begin(), command_interface_types_.end(), -// hardware_interface::HW_IF_VELOCITY) != command_interface_types_.end()) -// { -// EXPECT_EQ(current_state_when_offset.positions[i], joint_state_pos_[i]); -// } - -// // check acceleration -// if ( -// std::find( -// state_interface_types_.begin(), state_interface_types_.end(), -// hardware_interface::HW_IF_ACCELERATION) != state_interface_types_.end() && -// std::find( -// command_interface_types_.begin(), command_interface_types_.end(), -// hardware_interface::HW_IF_ACCELERATION) != command_interface_types_.end()) -// { -// EXPECT_EQ(current_state_when_offset.positions[i], joint_state_pos_[i]); -// } -// } - -// executor.cancel(); -// } + if (traj_controller_->has_velocity_command_interface()) + { + // estimate the sign of the velocity + // joint rotates forward + EXPECT_TRUE(is_same_sign(traj_msg.points[0].positions[0] - initial_joint2_cmd, joint_vel_[0])); + EXPECT_TRUE(is_same_sign(traj_msg.points[0].positions[1] - initial_joint1_cmd, joint_vel_[1])); + EXPECT_NEAR(0.0, joint_vel_[2], threshold) + << "Joint 3 velocity should be 0.0 since it's not in the goal"; + } -// // Testing that values are read from state interfaces when hardware is started after some values -// // are set on the hardware commands -// TEST_P(TrajectoryControllerTestParameterized, test_hw_states_has_offset_later_controller_start) -// { -// rclcpp::executors::SingleThreadedExecutor executor; -// // default if false so it will not be actually set parameter -// rclcpp::Parameter is_open_loop_parameters("open_loop_control", true); + if (traj_controller_->has_effort_command_interface()) + { + // estimate the sign of the effort + // joint rotates forward + EXPECT_TRUE(is_same_sign(traj_msg.points[0].positions[0] - initial_joint2_cmd, joint_eff_[0])); + EXPECT_TRUE(is_same_sign(traj_msg.points[0].positions[1] - initial_joint1_cmd, joint_eff_[1])); + EXPECT_NEAR(0.0, joint_eff_[2], threshold) + << "Joint 3 effort should be 0.0 since it's not in the goal"; + } + // TODO(anyone): add here checks for acceleration commands -// // set command values to NaN -// for (size_t i = 0; i < 3; ++i) -// { -// joint_pos_[i] = 3.1 + i; -// joint_vel_[i] = 0.25 + i; -// joint_acc_[i] = 0.02 + i / 10.0; -// } -// SetUpAndActivateTrajectoryController(true, {is_open_loop_parameters}, &executor, true); + executor.cancel(); +} -// auto current_state_when_offset = traj_controller_->get_current_state_when_offset(); +/** + * @brief test_partial_joint_list Test sending trajectories with a subset of the controlled + * joints without allow_partial_joints_goal + */ +TEST_P(TrajectoryControllerTestParameterized, test_partial_joint_list_not_allowed) +{ + rclcpp::Parameter partial_joints_parameters("allow_partial_joints_goal", false); -// for (size_t i = 0; i < 3; ++i) -// { -// EXPECT_EQ(current_state_when_offset.positions[i], joint_pos_[i]); - -// // check velocity -// if ( -// std::find( -// state_interface_types_.begin(), state_interface_types_.end(), -// hardware_interface::HW_IF_VELOCITY) != state_interface_types_.end() && -// std::find( -// command_interface_types_.begin(), command_interface_types_.end(), -// hardware_interface::HW_IF_VELOCITY) != command_interface_types_.end()) -// { -// EXPECT_EQ(current_state_when_offset.positions[i], joint_pos_[i]); -// } - -// // check acceleration -// if ( -// std::find( -// state_interface_types_.begin(), state_interface_types_.end(), -// hardware_interface::HW_IF_ACCELERATION) != state_interface_types_.end() && -// std::find( -// command_interface_types_.begin(), command_interface_types_.end(), -// hardware_interface::HW_IF_ACCELERATION) != command_interface_types_.end()) -// { -// EXPECT_EQ(current_state_when_offset.positions[i], joint_pos_[i]); -// } -// } - -// executor.cancel(); -// } + rclcpp::executors::SingleThreadedExecutor executor; + SetUpAndActivateTrajectoryController(executor, true, {partial_joints_parameters}); + + const double initial_joint1_cmd = joint_pos_[0]; + const double initial_joint2_cmd = joint_pos_[1]; + const double initial_joint3_cmd = joint_pos_[2]; + trajectory_msgs::msg::JointTrajectory traj_msg; + + { + std::vector partial_joint_names{joint_names_[1], joint_names_[0]}; + traj_msg.joint_names = partial_joint_names; + traj_msg.header.stamp = rclcpp::Time(0); + traj_msg.points.resize(1); + + traj_msg.points[0].time_from_start = rclcpp::Duration::from_seconds(0.25); + traj_msg.points[0].positions.resize(2); + traj_msg.points[0].positions[0] = 2.0; + traj_msg.points[0].positions[1] = 1.0; + traj_msg.points[0].velocities.resize(2); + traj_msg.points[0].velocities[0] = 2.0; + traj_msg.points[0].velocities[1] = 1.0; + + trajectory_publisher_->publish(traj_msg); + } + + traj_controller_->wait_for_trajectory(executor); + // update for 0.5 seconds + updateController(rclcpp::Duration::from_seconds(0.25)); + + double threshold = 0.001; + + if (traj_controller_->has_position_command_interface()) + { + EXPECT_NEAR(initial_joint1_cmd, joint_pos_[0], threshold) + << "All joints command should be current position because goal was rejected"; + EXPECT_NEAR(initial_joint2_cmd, joint_pos_[1], threshold) + << "All joints command should be current position because goal was rejected"; + EXPECT_NEAR(initial_joint3_cmd, joint_pos_[2], threshold) + << "All joints command should be current position because goal was rejected"; + } + + if (traj_controller_->has_velocity_command_interface()) + { + EXPECT_NEAR(INITIAL_VEL_JOINTS[0], joint_vel_[0], threshold) + << "All joints velocities should be 0.0 because goal was rejected"; + EXPECT_NEAR(INITIAL_VEL_JOINTS[1], joint_vel_[1], threshold) + << "All joints velocities should be 0.0 because goal was rejected"; + EXPECT_NEAR(INITIAL_VEL_JOINTS[2], joint_vel_[2], threshold) + << "All joints velocities should be 0.0 because goal was rejected"; + } + + if (traj_controller_->has_acceleration_command_interface()) + { + EXPECT_NEAR(INITIAL_ACC_JOINTS[0], joint_acc_[0], threshold) + << "All joints accelerations should be 0.0 because goal was rejected"; + EXPECT_NEAR(INITIAL_ACC_JOINTS[1], joint_acc_[1], threshold) + << "All joints accelerations should be 0.0 because goal was rejected"; + EXPECT_NEAR(INITIAL_ACC_JOINTS[2], joint_acc_[2], threshold) + << "All joints accelerations should be 0.0 because goal was rejected"; + } + + if (traj_controller_->has_effort_command_interface()) + { + EXPECT_NEAR(INITIAL_EFF_JOINTS[0], joint_eff_[0], threshold) + << "All joints efforts should be 0.0 because goal was rejected"; + EXPECT_NEAR(INITIAL_EFF_JOINTS[1], joint_eff_[1], threshold) + << "All joints efforts should be 0.0 because goal was rejected"; + EXPECT_NEAR(INITIAL_EFF_JOINTS[2], joint_eff_[2], threshold) + << "All joints efforts should be 0.0 because goal was rejected"; + } + + executor.cancel(); +} + +/** + * @brief invalid_message Test mismatched joint and reference vector sizes + */ +TEST_P(TrajectoryControllerTestParameterized, invalid_message) +{ + rclcpp::Parameter partial_joints_parameters("allow_partial_joints_goal", false); + rclcpp::Parameter allow_integration_parameters("allow_integration_in_goal_trajectories", false); + rclcpp::executors::SingleThreadedExecutor executor; + SetUpAndActivateTrajectoryController( + executor, true, {partial_joints_parameters, allow_integration_parameters}); + + trajectory_msgs::msg::JointTrajectory traj_msg, good_traj_msg; + + good_traj_msg.joint_names = joint_names_; + good_traj_msg.header.stamp = rclcpp::Time(0); + good_traj_msg.points.resize(1); + good_traj_msg.points[0].time_from_start = rclcpp::Duration::from_seconds(0.25); + good_traj_msg.points[0].positions.resize(1); + good_traj_msg.points[0].positions = {1.0, 2.0, 3.0}; + good_traj_msg.points[0].velocities.resize(1); + good_traj_msg.points[0].velocities = {-1.0, -2.0, -3.0}; + EXPECT_TRUE(traj_controller_->validate_trajectory_msg(good_traj_msg)); + + // Incompatible joint names + traj_msg = good_traj_msg; + traj_msg.joint_names = {"bad_name"}; + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); + + // No position data + traj_msg = good_traj_msg; + traj_msg.points[0].positions.clear(); + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); + + // Incompatible data sizes, too few positions + traj_msg = good_traj_msg; + traj_msg.points[0].positions = {1.0, 2.0}; + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); + + // Incompatible data sizes, too many positions + traj_msg = good_traj_msg; + traj_msg.points[0].positions = {1.0, 2.0, 3.0, 4.0}; + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); + + // Incompatible data sizes, too few velocities + traj_msg = good_traj_msg; + traj_msg.points[0].velocities = {1.0, 2.0}; + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); + + // Incompatible data sizes, too few accelerations + traj_msg = good_traj_msg; + traj_msg.points[0].accelerations = {1.0, 2.0}; + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); + +// Effort is not supported in trajectory message +#if 0 + // TODO(christophfroehlich) activate with #730 + traj_msg = good_traj_msg; + traj_msg.points[0].effort = {1.0, 2.0, 3.0}; + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); +#endif + + // Non-strictly increasing waypoint times + traj_msg = good_traj_msg; + traj_msg.points.push_back(traj_msg.points.front()); + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); +} + +/// With allow_integration_in_goal_trajectories parameter trajectory missing position or +/// velocities are accepted +TEST_P(TrajectoryControllerTestParameterized, missing_positions_message_accepted) +{ + rclcpp::Parameter allow_integration_parameters("allow_integration_in_goal_trajectories", true); + rclcpp::executors::SingleThreadedExecutor executor; + SetUpAndActivateTrajectoryController(executor, true, {allow_integration_parameters}); + + trajectory_msgs::msg::JointTrajectory traj_msg, good_traj_msg; + + good_traj_msg.joint_names = joint_names_; + good_traj_msg.header.stamp = rclcpp::Time(0); + good_traj_msg.points.resize(1); + good_traj_msg.points[0].time_from_start = rclcpp::Duration::from_seconds(0.25); + good_traj_msg.points[0].positions.resize(1); + good_traj_msg.points[0].positions = {1.0, 2.0, 3.0}; + good_traj_msg.points[0].velocities.resize(1); + good_traj_msg.points[0].velocities = {-1.0, -2.0, -3.0}; + good_traj_msg.points[0].accelerations.resize(1); + good_traj_msg.points[0].accelerations = {1.0, 2.0, 3.0}; + EXPECT_TRUE(traj_controller_->validate_trajectory_msg(good_traj_msg)); + + // No position data + traj_msg = good_traj_msg; + traj_msg.points[0].positions.clear(); + EXPECT_TRUE(traj_controller_->validate_trajectory_msg(traj_msg)); + + // No position and velocity data + traj_msg = good_traj_msg; + traj_msg.points[0].positions.clear(); + traj_msg.points[0].velocities.clear(); + EXPECT_TRUE(traj_controller_->validate_trajectory_msg(traj_msg)); + + // All empty + traj_msg = good_traj_msg; + traj_msg.points[0].positions.clear(); + traj_msg.points[0].velocities.clear(); + traj_msg.points[0].accelerations.clear(); + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); + + // Incompatible data sizes, too few positions + traj_msg = good_traj_msg; + traj_msg.points[0].positions = {1.0, 2.0}; + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); + + // Incompatible data sizes, too many positions + traj_msg = good_traj_msg; + traj_msg.points[0].positions = {1.0, 2.0, 3.0, 4.0}; + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); + + // Incompatible data sizes, too few velocities + traj_msg = good_traj_msg; + traj_msg.points[0].velocities = {1.0}; + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); + + // Incompatible data sizes, too few accelerations + traj_msg = good_traj_msg; + traj_msg.points[0].accelerations = {2.0}; + EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); +} + +/** + * @brief test_trajectory_replace Test replacing an existing trajectory + */ +TEST_P(TrajectoryControllerTestParameterized, test_trajectory_replace) +{ + rclcpp::executors::SingleThreadedExecutor executor; + rclcpp::Parameter partial_joints_parameters("allow_partial_joints_goal", true); + SetUpAndActivateTrajectoryController(executor, true, {partial_joints_parameters}); + + subscribeToState(); + + std::vector> points_old{{{2., 3., 4.}}}; + std::vector> points_old_velocities{{{0.2, 0.3, 0.4}}}; + std::vector> points_partial_new{{1.5}}; + std::vector> points_partial_new_velocities{{0.15}}; + + const auto delay = std::chrono::milliseconds(500); + builtin_interfaces::msg::Duration time_from_start{rclcpp::Duration(delay)}; + publish(time_from_start, points_old, rclcpp::Time(), {}, points_old_velocities); + trajectory_msgs::msg::JointTrajectoryPoint expected_actual, expected_desired; + expected_actual.positions = {points_old[0].begin(), points_old[0].end()}; + expected_desired.positions = {points_old[0].begin(), points_old[0].end()}; + expected_actual.velocities = {points_old_velocities[0].begin(), points_old_velocities[0].end()}; + expected_desired.velocities = {points_old_velocities[0].begin(), points_old_velocities[0].end()}; + // Check that we reached end of points_old trajectory + // Denis: delta was 0.1 with 0.2 works for me + waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.2); + + RCLCPP_INFO(traj_controller_->get_node()->get_logger(), "Sending new trajectory"); + points_partial_new_velocities[0][0] = + copysign(0.15, points_partial_new[0][0] - joint_state_pos_[0]); + publish(time_from_start, points_partial_new, rclcpp::Time(), {}, points_partial_new_velocities); + + // Replaced trajectory is a mix of previous and current goal + expected_desired.positions[0] = points_partial_new[0][0]; + expected_desired.positions[1] = points_old[0][1]; + expected_desired.positions[2] = points_old[0][2]; + expected_desired.velocities[0] = points_partial_new_velocities[0][0]; + expected_desired.velocities[1] = 0.0; + expected_desired.velocities[2] = 0.0; + expected_actual = expected_desired; + waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); +} + +/** + * @brief test_ignore_old_trajectory Sending an old trajectory replacing an existing trajectory + */ +TEST_P(TrajectoryControllerTestParameterized, test_ignore_old_trajectory) +{ + rclcpp::executors::SingleThreadedExecutor executor; + SetUpAndActivateTrajectoryController(executor, true, {}); + subscribeToState(); + + // TODO(anyone): add expectations for velocities and accelerations + std::vector> points_old{{{2., 3., 4.}, {4., 5., 6.}}}; + std::vector> points_new{{{-1., -2., -3.}}}; + + RCLCPP_INFO(traj_controller_->get_node()->get_logger(), "Sending new trajectory in the future"); + const auto delay = std::chrono::milliseconds(500); + builtin_interfaces::msg::Duration time_from_start{rclcpp::Duration(delay)}; + publish(time_from_start, points_old, rclcpp::Time()); + trajectory_msgs::msg::JointTrajectoryPoint expected_actual, expected_desired; + expected_actual.positions = {points_old[0].begin(), points_old[0].end()}; + expected_desired = expected_actual; + // Check that we reached end of points_old[0] trajectory + waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); + + RCLCPP_INFO(traj_controller_->get_node()->get_logger(), "Sending new trajectory in the past"); + // New trajectory will end before current time + rclcpp::Time new_traj_start = + rclcpp::Clock(RCL_STEADY_TIME).now() - delay - std::chrono::milliseconds(100); + expected_actual.positions = {points_old[1].begin(), points_old[1].end()}; + expected_desired = expected_actual; + std::cout << "Sending old trajectory" << std::endl; + publish(time_from_start, points_new, new_traj_start); + waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); +} + +TEST_P(TrajectoryControllerTestParameterized, test_ignore_partial_old_trajectory) +{ + rclcpp::executors::SingleThreadedExecutor executor; + SetUpAndActivateTrajectoryController(executor, true, {}); + subscribeToState(); + + std::vector> points_old{{{2., 3., 4.}, {4., 5., 6.}}}; + std::vector> points_new{{{-1., -2., -3.}, {-2., -4., -6.}}}; + trajectory_msgs::msg::JointTrajectoryPoint expected_actual, expected_desired; + const auto delay = std::chrono::milliseconds(500); + builtin_interfaces::msg::Duration time_from_start{rclcpp::Duration(delay)}; + + // send points_old and wait to reach first point + publish(time_from_start, points_old, rclcpp::Time()); + expected_actual.positions = {points_old[0].begin(), points_old[0].end()}; + expected_desired = expected_actual; + // Check that we reached end of points_old[0]trajectory + waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); + + // send points_new before the old trajectory is finished + RCLCPP_INFO( + traj_controller_->get_node()->get_logger(), "Sending new trajectory partially in the past"); + // New trajectory first point is in the past, second is in the future + rclcpp::Time new_traj_start = + rclcpp::Clock(RCL_STEADY_TIME).now() - delay - std::chrono::milliseconds(100); + publish(time_from_start, points_new, new_traj_start); + // it should not have accepted the new goal but finish the old one + expected_actual.positions = {points_old[1].begin(), points_old[1].end()}; + expected_desired.positions = {points_old[1].begin(), points_old[1].end()}; + waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); +} + +TEST_P(TrajectoryControllerTestParameterized, test_execute_partial_traj_in_future) +{ + rclcpp::Parameter partial_joints_parameters("allow_partial_joints_goal", true); + rclcpp::executors::SingleThreadedExecutor executor; + SetUpAndActivateTrajectoryController(executor, true, {partial_joints_parameters}); + subscribeToState(); + + RCLCPP_WARN( + traj_controller_->get_node()->get_logger(), + "Test disabled until current_trajectory is taken into account when adding a new trajectory."); + // https://github.com/ros-controls/ros_controllers/blob/melodic-devel/ + // joint_trajectory_controller/include/joint_trajectory_controller/init_joint_trajectory.h#L149 + return; + + // *INDENT-OFF* + std::vector> full_traj{{{2., 3., 4.}, {4., 6., 8.}}}; + std::vector> full_traj_velocities{{{0.2, 0.3, 0.4}, {0.4, 0.6, 0.8}}}; + std::vector> partial_traj{{{-1., -2.}, {-2., -4}}}; + std::vector> partial_traj_velocities{{{-0.1, -0.2}, {-0.2, -0.4}}}; + // *INDENT-ON* + const auto delay = std::chrono::milliseconds(500); + builtin_interfaces::msg::Duration points_delay{rclcpp::Duration(delay)}; + // Send full trajectory + publish(points_delay, full_traj, rclcpp::Time(), {}, full_traj_velocities); + // Sleep until first waypoint of full trajectory + + trajectory_msgs::msg::JointTrajectoryPoint expected_actual, expected_desired; + expected_actual.positions = {full_traj[0].begin(), full_traj[0].end()}; + expected_desired = expected_actual; + // Check that we reached end of points_old[0]trajectory and are starting points_old[1] + waitAndCompareState(expected_actual, expected_desired, executor, rclcpp::Duration(delay), 0.1); + + // Send partial trajectory starting after full trajecotry is complete + RCLCPP_INFO(traj_controller_->get_node()->get_logger(), "Sending new trajectory in the future"); + publish( + points_delay, partial_traj, rclcpp::Clock(RCL_STEADY_TIME).now() + delay * 2, {}, + partial_traj_velocities); + // Wait until the end start and end of partial traj + + expected_actual.positions = {partial_traj.back()[0], partial_traj.back()[1], full_traj.back()[2]}; + expected_desired = expected_actual; + + waitAndCompareState( + expected_actual, expected_desired, executor, rclcpp::Duration(delay * (2 + 2)), 0.1); +} + +// TODO(destogl) this test fails with errors +// second publish() gives an error, because end time is before current time +// as well as +// 2: The difference between joint_state_pos_[0] and joint_pos_[0] is 0.02999799000000003, +// which exceeds COMMON_THRESHOLD, where +// 2: joint_state_pos_[0] evaluates to 6.2999999999999998, +// 2: joint_pos_[0] evaluates to 6.2700020099999998, and +// 2: COMMON_THRESHOLD evaluates to 0.0011000000000000001. +// 2: [ FAILED ] PositionTrajectoryControllers/TrajectoryControllerTestParameterized. +// test_jump_when_state_tracking_error_updated/0, where GetParam() = +// ({ "position" }, { "position" }) (3372 ms) + +#if 0 +TEST_P(TrajectoryControllerTestParameterized, test_jump_when_state_tracking_error_updated) +{ + rclcpp::executors::SingleThreadedExecutor executor; + // default if false so it will not be actually set parameter + rclcpp::Parameter is_open_loop_parameters("open_loop_control", false); + SetUpAndActivateTrajectoryController(executor, true, {is_open_loop_parameters}, true); + + // goal setup + std::vector first_goal = {3.3, 4.4, 5.5}; + std::vector> first_goal_velocities = {{0.33, 0.44, 0.55}}; + std::vector second_goal = {6.6, 8.8, 11.0}; + std::vector> second_goal_velocities = {{0.66, 0.88, 1.1}}; + double state_from_command_offset = 0.3; + + // send msg + builtin_interfaces::msg::Duration time_from_start; + time_from_start.sec = 1; + time_from_start.nanosec = 0; + std::vector> points{{first_goal}}; + publish(time_from_start, points, + rclcpp::Time(0.0, 0.0, RCL_STEADY_TIME), {}, first_goal_velocities); + traj_controller_->wait_for_trajectory(executor); + updateController(rclcpp::Duration::from_seconds(1.1)); + + if (traj_controller_->has_position_command_interface()) + { + // JTC is executing trajectory in open-loop therefore: + // - internal state does not have to be updated (in this test-case it shouldn't) + // - internal command is updated + EXPECT_NEAR(INITIAL_POS_JOINT1, joint_state_pos_[0], COMMON_THRESHOLD); + EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); + + // State interface should have offset from the command before starting a new trajectory + joint_state_pos_[0] = first_goal[0] - state_from_command_offset; + + // Move joint further in the same direction as before (to the second goal) + points = {{second_goal}}; + publish(time_from_start, points, + rclcpp::Time(1.0, 0.0, RCL_STEADY_TIME), {}, second_goal_velocities); + traj_controller_->wait_for_trajectory(executor); + + // One the first update(s) there should be a "jump" in opposite direction from command + // (towards the state value) + EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); + updateController(rclcpp::Duration::from_seconds(0.01)); + // Expect backward commands at first + EXPECT_NEAR(joint_state_pos_[0], joint_pos_[0], state_from_command_offset + COMMON_THRESHOLD); + EXPECT_GT(joint_pos_[0], joint_state_pos_[0]); + EXPECT_LT(joint_pos_[0], first_goal[0]); + updateController(rclcpp::Duration::from_seconds(0.01)); + EXPECT_GT(joint_pos_[0], joint_state_pos_[0]); + EXPECT_LT(joint_pos_[0], first_goal[0]); + updateController(rclcpp::Duration::from_seconds(0.01)); + EXPECT_GT(joint_pos_[0], joint_state_pos_[0]); + EXPECT_LT(joint_pos_[0], first_goal[0]); + + // Finally the second goal will be commanded/reached + updateController(rclcpp::Duration::from_seconds(1.1)); + EXPECT_NEAR(second_goal[0], joint_pos_[0], COMMON_THRESHOLD); + + // State interface should have offset from the command before starting a new trajectory + joint_state_pos_[0] = second_goal[0] - state_from_command_offset; + + // Move joint back to the first goal + points = {{first_goal}}; + publish(time_from_start, points, rclcpp::Time(0.0, 0.0, RCL_STEADY_TIME)); + traj_controller_->wait_for_trajectory(executor); + + // One the first update(s) there should be a "jump" in the goal direction from command + // (towards the state value) + EXPECT_NEAR(second_goal[0], joint_pos_[0], COMMON_THRESHOLD); + updateController(rclcpp::Duration::from_seconds(0.01)); + // Expect backward commands at first + EXPECT_NEAR(joint_state_pos_[0], joint_pos_[0], COMMON_THRESHOLD); + EXPECT_LT(joint_pos_[0], joint_state_pos_[0]); + EXPECT_GT(joint_pos_[0], first_goal[0]); + updateController(rclcpp::Duration::from_seconds(0.01)); + EXPECT_LT(joint_pos_[0], joint_state_pos_[0]); + EXPECT_GT(joint_pos_[0], first_goal[0]); + updateController(rclcpp::Duration::from_seconds(0.01)); + EXPECT_LT(joint_pos_[0], joint_state_pos_[0]); + EXPECT_GT(joint_pos_[0], first_goal[0]); + + // Finally the first goal will be commanded/reached + updateController(rclcpp::Duration::from_seconds(1.1)); + EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); + } + + executor.cancel(); +} +#endif + +// TODO(destogl) this test fails +// 2: The difference between second_goal[0] and joint_pos_[0] is 0.032986635000000319, +// which exceeds COMMON_THRESHOLD, where +// 2: second_goal[0] evaluates to 6.5999999999999996, +// 2: joint_pos_[0] evaluates to 6.5670133649999993, and +// 2: COMMON_THRESHOLD evaluates to 0.0011000000000000001. +// 2: [ FAILED ] PositionTrajectoryControllers/TrajectoryControllerTestParameterized. +// test_no_jump_when_state_tracking_error_not_updated/1, where GetParam() = +// ({ "position" }, { "position", "velocity" }) (3374 ms) +#if 0 +TEST_P(TrajectoryControllerTestParameterized, test_no_jump_when_state_tracking_error_not_updated) +{ + rclcpp::executors::SingleThreadedExecutor executor; + rclcpp::Parameter is_open_loop_parameters("open_loop_control", true); + SetUpAndActivateTrajectoryController(executor, true, {is_open_loop_parameters}, true); + + // goal setup + std::vector first_goal = {3.3, 4.4, 5.5}; + std::vector second_goal = {6.6, 8.8, 11.0}; + double state_from_command_offset = 0.3; + + // send msg + builtin_interfaces::msg::Duration time_from_start; + time_from_start.sec = 1; + time_from_start.nanosec = 0; + std::vector> points{{first_goal}}; + publish(time_from_start, points, rclcpp::Time(0.0, 0.0, RCL_STEADY_TIME)); + traj_controller_->wait_for_trajectory(executor); + updateController(rclcpp::Duration::from_seconds(1.1)); + + if (traj_controller_->has_position_command_interface()) + { + // JTC is executing trajectory in open-loop therefore: + // - internal state does not have to be updated (in this test-case it shouldn't) + // - internal command is updated + EXPECT_NEAR(INITIAL_POS_JOINT1, joint_state_pos_[0], COMMON_THRESHOLD); + EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); + + // State interface should have offset from the command before starting a new trajectory + joint_state_pos_[0] = first_goal[0] - state_from_command_offset; + + // Move joint further in the same direction as before (to the second goal) + points = {{second_goal}}; + publish(time_from_start, points, rclcpp::Time(0.0, 0.0, RCL_STEADY_TIME)); + traj_controller_->wait_for_trajectory(executor); + + // One the first update(s) there **should not** be a "jump" in opposite direction from + // command (towards the state value) + EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); + updateController(rclcpp::Duration::from_seconds(0.01)); + // There should not be backward commands + EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); + EXPECT_GT(joint_pos_[0], first_goal[0]); + EXPECT_LT(joint_pos_[0], second_goal[0]); + updateController(rclcpp::Duration::from_seconds(0.01)); + EXPECT_GT(joint_pos_[0], first_goal[0]); + EXPECT_LT(joint_pos_[0], second_goal[0]); + updateController(rclcpp::Duration::from_seconds(0.01)); + EXPECT_GT(joint_pos_[0], first_goal[0]); + EXPECT_LT(joint_pos_[0], second_goal[0]); + + // Finally the second goal will be commanded/reached + updateController(rclcpp::Duration::from_seconds(1.1)); + EXPECT_NEAR(second_goal[0], joint_pos_[0], COMMON_THRESHOLD); + + // State interface should have offset from the command before starting a new trajectory + joint_state_pos_[0] = second_goal[0] - state_from_command_offset; + + // Move joint back to the first goal + points = {{first_goal}}; + publish(time_from_start, points, rclcpp::Time(0.0, 0.0, RCL_STEADY_TIME)); + traj_controller_->wait_for_trajectory(executor); + + // One the first update(s) there **should not** be a "jump" in the goal direction from + // command (towards the state value) + EXPECT_NEAR(second_goal[0], joint_pos_[0], COMMON_THRESHOLD); + updateController(rclcpp::Duration::from_seconds(0.01)); + // There should not be a jump toward commands + EXPECT_NEAR(second_goal[0], joint_pos_[0], COMMON_THRESHOLD); + EXPECT_LT(joint_pos_[0], second_goal[0]); + EXPECT_GT(joint_pos_[0], first_goal[0]); + updateController(rclcpp::Duration::from_seconds(0.01)); + EXPECT_GT(joint_pos_[0], first_goal[0]); + EXPECT_LT(joint_pos_[0], second_goal[0]); + updateController(rclcpp::Duration::from_seconds(0.01)); + EXPECT_GT(joint_pos_[0], first_goal[0]); + EXPECT_LT(joint_pos_[0], second_goal[0]); + + // Finally the first goal will be commanded/reached + updateController(rclcpp::Duration::from_seconds(1.1)); + EXPECT_NEAR(first_goal[0], joint_pos_[0], COMMON_THRESHOLD); + } + + executor.cancel(); +} +#endif + +// Testing that values are read from state interfaces when hardware is started for the first +// time and hardware state has offset --> this is indicated by NaN values in state interfaces +TEST_P(TrajectoryControllerTestParameterized, test_hw_states_has_offset_first_controller_start) +{ + rclcpp::executors::SingleThreadedExecutor executor; + // default if false so it will not be actually set parameter + rclcpp::Parameter is_open_loop_parameters("open_loop_control", true); + + // set command values to NaN + for (size_t i = 0; i < 3; ++i) + { + joint_pos_[i] = std::numeric_limits::quiet_NaN(); + joint_vel_[i] = std::numeric_limits::quiet_NaN(); + joint_acc_[i] = std::numeric_limits::quiet_NaN(); + } + SetUpAndActivateTrajectoryController(executor, true, {is_open_loop_parameters}, true); + + auto current_state_when_offset = traj_controller_->get_current_state_when_offset(); + + for (size_t i = 0; i < 3; ++i) + { + EXPECT_EQ(current_state_when_offset.positions[i], joint_state_pos_[i]); + + // check velocity + if ( + std::find( + state_interface_types_.begin(), state_interface_types_.end(), + hardware_interface::HW_IF_VELOCITY) != state_interface_types_.end() && + traj_controller_->has_velocity_command_interface()) + { + EXPECT_EQ(current_state_when_offset.positions[i], joint_state_pos_[i]); + } + + // check acceleration + if ( + std::find( + state_interface_types_.begin(), state_interface_types_.end(), + hardware_interface::HW_IF_ACCELERATION) != state_interface_types_.end() && + traj_controller_->has_acceleration_command_interface()) + { + EXPECT_EQ(current_state_when_offset.positions[i], joint_state_pos_[i]); + } + } + + executor.cancel(); +} + +// Testing that values are read from state interfaces when hardware is started after some values +// are set on the hardware commands +TEST_P(TrajectoryControllerTestParameterized, test_hw_states_has_offset_later_controller_start) +{ + rclcpp::executors::SingleThreadedExecutor executor; + // default if false so it will not be actually set parameter + rclcpp::Parameter is_open_loop_parameters("open_loop_control", true); + + // set command values to NaN + for (size_t i = 0; i < 3; ++i) + { + joint_pos_[i] = 3.1 + i; + joint_vel_[i] = 0.25 + i; + joint_acc_[i] = 0.02 + i / 10.0; + } + SetUpAndActivateTrajectoryController(executor, true, {is_open_loop_parameters}, true); + + auto current_state_when_offset = traj_controller_->get_current_state_when_offset(); + + for (size_t i = 0; i < 3; ++i) + { + EXPECT_EQ(current_state_when_offset.positions[i], joint_pos_[i]); + + // check velocity + if ( + std::find( + state_interface_types_.begin(), state_interface_types_.end(), + hardware_interface::HW_IF_VELOCITY) != state_interface_types_.end() && + traj_controller_->has_velocity_command_interface()) + { + EXPECT_EQ(current_state_when_offset.positions[i], joint_pos_[i]); + } + + // check acceleration + if ( + std::find( + state_interface_types_.begin(), state_interface_types_.end(), + hardware_interface::HW_IF_ACCELERATION) != state_interface_types_.end() && + traj_controller_->has_acceleration_command_interface()) + { + EXPECT_EQ(current_state_when_offset.positions[i], joint_pos_[i]); + } + } + + executor.cancel(); +} // position controllers INSTANTIATE_TEST_SUITE_P( @@ -1684,26 +1675,25 @@ INSTANTIATE_TEST_SUITE_P( std::vector({"position", "velocity", "acceleration"}), std::vector({"position", "velocity", "acceleration"})))); -// // only velocity controller -// INSTANTIATE_TEST_SUITE_P( -// OnlyVelocityTrajectoryControllers, TrajectoryControllerTestParameterized, -// ::testing::Values( -// std::make_tuple( -// std::vector({"velocity"}), -// std::vector({"position", "velocity"})), -// std::make_tuple( -// std::vector({"velocity"}), -// std::vector({"position", "velocity", "acceleration"})))); - -// // only effort controller -// INSTANTIATE_TEST_SUITE_P( -// OnlyEffortTrajectoryControllers, TrajectoryControllerTestParameterized, -// ::testing::Values( -// std::make_tuple( -// std::vector({"effort"}), std::vector({"position", "velocity"})), -// std::make_tuple( -// std::vector({"effort"}), -// std::vector({"position", "velocity", "acceleration"})))); +// only velocity controller +INSTANTIATE_TEST_SUITE_P( + OnlyVelocityTrajectoryControllers, TrajectoryControllerTestParameterized, + ::testing::Values( + std::make_tuple( + std::vector({"velocity"}), std::vector({"position", "velocity"})), + std::make_tuple( + std::vector({"velocity"}), + std::vector({"position", "velocity", "acceleration"})))); + +// only effort controller +INSTANTIATE_TEST_SUITE_P( + OnlyEffortTrajectoryControllers, TrajectoryControllerTestParameterized, + ::testing::Values( + std::make_tuple( + std::vector({"effort"}), std::vector({"position", "velocity"})), + std::make_tuple( + std::vector({"effort"}), + std::vector({"position", "velocity", "acceleration"})))); // TODO(destogl): this tests should be changed because we are using `generate_parameters_library` // TEST_F(TrajectoryControllerTest, incorrect_initialization_using_interface_parameters) diff --git a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp index 0c01eb1357..874a814a5d 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp +++ b/joint_trajectory_controller/test/test_trajectory_controller_utils.hpp @@ -105,15 +105,24 @@ class TestableJointTrajectoryController { return last_commanded_state_; } + bool has_position_state_interface() { return has_position_state_interface_; } + + bool has_velocity_state_interface() { return has_velocity_state_interface_; } + + bool has_acceleration_state_interface() { return has_acceleration_state_interface_; } bool has_position_command_interface() { return has_position_command_interface_; } bool has_velocity_command_interface() { return has_velocity_command_interface_; } + bool has_acceleration_command_interface() { return has_acceleration_command_interface_; } + bool has_effort_command_interface() { return has_effort_command_interface_; } bool use_closed_loop_pid_adapter() { return use_closed_loop_pid_adapter_; } + bool is_open_loop() { return params_.open_loop_control; } + rclcpp::WaitSet joint_cmd_sub_wait_set_; }; @@ -316,13 +325,14 @@ class TrajectoryControllerTest : public ::testing::Test /// Publish trajectory msgs with multiple points /** * delay_btwn_points - delay between each points - * points - vector of trajectories. One point per controlled joint + * points_positions - vector of trajectory-positions. One point per controlled joint * joint_names - names of joints, if empty, will use joint_names_ up to the number of provided * points + * points - vector of trajectory-velocities. One point per controlled joint */ void publish( const builtin_interfaces::msg::Duration & delay_btwn_points, - const std::vector> & points, rclcpp::Time start_time, + const std::vector> & points_positions, rclcpp::Time start_time, const std::vector & joint_names = {}, const std::vector> & points_velocities = {}) { @@ -342,14 +352,15 @@ class TrajectoryControllerTest : public ::testing::Test trajectory_msgs::msg::JointTrajectory traj_msg; if (joint_names.empty()) { - traj_msg.joint_names = {joint_names_.begin(), joint_names_.begin() + points[0].size()}; + traj_msg.joint_names = { + joint_names_.begin(), joint_names_.begin() + points_positions[0].size()}; } else { traj_msg.joint_names = joint_names; } traj_msg.header.stamp = start_time; - traj_msg.points.resize(points.size()); + traj_msg.points.resize(points_positions.size()); builtin_interfaces::msg::Duration duration_msg; duration_msg.sec = delay_btwn_points.sec; @@ -357,14 +368,14 @@ class TrajectoryControllerTest : public ::testing::Test rclcpp::Duration duration(duration_msg); rclcpp::Duration duration_total(duration_msg); - for (size_t index = 0; index < points.size(); ++index) + for (size_t index = 0; index < points_positions.size(); ++index) { traj_msg.points[index].time_from_start = duration_total; - traj_msg.points[index].positions.resize(points[index].size()); - for (size_t j = 0; j < points[index].size(); ++j) + traj_msg.points[index].positions.resize(points_positions[index].size()); + for (size_t j = 0; j < points_positions[index].size(); ++j) { - traj_msg.points[index].positions[j] = points[index][j]; + traj_msg.points[index].positions[j] = points_positions[index][j]; } duration_total = duration_total + duration; } @@ -386,9 +397,13 @@ class TrajectoryControllerTest : public ::testing::Test auto clock = rclcpp::Clock(RCL_STEADY_TIME); const auto start_time = clock.now(); const auto end_time = start_time + wait_time; + auto previous_time = start_time; + while (clock.now() < end_time) { - traj_controller_->update(clock.now(), clock.now() - start_time); + auto now = clock.now(); + traj_controller_->update(now, now - previous_time); + previous_time = now; } } @@ -413,7 +428,7 @@ class TrajectoryControllerTest : public ::testing::Test // TODO(anyone): add checking for velocties and accelerations if (traj_controller_->has_position_command_interface()) { - EXPECT_NEAR(expected_actual.positions[i], state_msg->actual.positions[i], allowed_delta); + EXPECT_NEAR(expected_actual.positions[i], state_msg->feedback.positions[i], allowed_delta); } } @@ -423,7 +438,8 @@ class TrajectoryControllerTest : public ::testing::Test // TODO(anyone): add checking for velocties and accelerations if (traj_controller_->has_position_command_interface()) { - EXPECT_NEAR(expected_desired.positions[i], state_msg->desired.positions[i], allowed_delta); + EXPECT_NEAR( + expected_desired.positions[i], state_msg->reference.positions[i], allowed_delta); } } } From 6a4e7a6e00d687184efb723c9cd0b0e133669fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Mon, 7 Aug 2023 12:56:51 +0200 Subject: [PATCH 05/39] [JTC] Reject messages with effort fields (#699) (#719) (#738) --- .../src/joint_trajectory_controller.cpp | 24 +++++++++---------- .../test/test_trajectory_controller.cpp | 5 +--- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index cc033b76cf..0a0e6cf9d1 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -292,14 +292,7 @@ controller_interface::return_type JointTrajectoryController::update( } if (has_effort_command_interface_) { - if (use_closed_loop_pid_adapter_) - { - assign_interface_from_point(joint_command_interface_[3], tmp_command_); - } - else - { - assign_interface_from_point(joint_command_interface_[3], state_desired_.effort); - } + assign_interface_from_point(joint_command_interface_[3], tmp_command_); } // store the previous command. Used in open-loop control mode @@ -1364,8 +1357,9 @@ bool JointTrajectoryController::validate_trajectory_point_field( if (joint_names_size != vector_field.size()) { RCLCPP_ERROR( - get_node()->get_logger(), "Mismatch between joint_names (%zu) and %s (%zu) at point #%zu.", - joint_names_size, string_for_vector_field.c_str(), vector_field.size(), i); + get_node()->get_logger(), + "Mismatch between joint_names size (%zu) and %s (%zu) at point #%zu.", joint_names_size, + string_for_vector_field.c_str(), vector_field.size(), i); return false; } return true; @@ -1481,11 +1475,17 @@ bool JointTrajectoryController::validate_trajectory_msg( !validate_trajectory_point_field(joint_count, points[i].positions, "positions", i, false) || !validate_trajectory_point_field(joint_count, points[i].velocities, "velocities", i, true) || !validate_trajectory_point_field( - joint_count, points[i].accelerations, "accelerations", i, true) || - !validate_trajectory_point_field(joint_count, points[i].effort, "effort", i, true)) + joint_count, points[i].accelerations, "accelerations", i, true)) { return false; } + // reject effort entries + if (!points[i].effort.empty()) + { + RCLCPP_ERROR( + get_node()->get_logger(), "Trajectories with effort fields are currently not supported."); + return false; + } } return true; } diff --git a/joint_trajectory_controller/test/test_trajectory_controller.cpp b/joint_trajectory_controller/test/test_trajectory_controller.cpp index 55d0ee0dfe..72cd2e8ca9 100644 --- a/joint_trajectory_controller/test/test_trajectory_controller.cpp +++ b/joint_trajectory_controller/test/test_trajectory_controller.cpp @@ -1110,13 +1110,10 @@ TEST_P(TrajectoryControllerTestParameterized, invalid_message) traj_msg.points[0].accelerations = {1.0, 2.0}; EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); -// Effort is not supported in trajectory message -#if 0 - // TODO(christophfroehlich) activate with #730 + // Effort is not supported in trajectory message traj_msg = good_traj_msg; traj_msg.points[0].effort = {1.0, 2.0, 3.0}; EXPECT_FALSE(traj_controller_->validate_trajectory_msg(traj_msg)); -#endif // Non-strictly increasing waypoint times traj_msg = good_traj_msg; From 2889038c0edeb4ebe1e0454e098b03bb13477da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Mon, 7 Aug 2023 15:50:13 +0200 Subject: [PATCH 06/39] [JTC] Disable use of closed-loop PID adapter if controller is used in open-loop mode. (#551) (#740) (cherry picked from commit 8029a2f11aca838cabdd7a8bbe028dd75c334316) Co-authored-by: Dr. Denis Co-authored-by: Bence Magyar --- joint_trajectory_controller/doc/userdoc.rst | 18 +++++++++++++++--- .../src/joint_trajectory_controller.cpp | 3 ++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/joint_trajectory_controller/doc/userdoc.rst b/joint_trajectory_controller/doc/userdoc.rst index 54341721d5..6125b9e385 100644 --- a/joint_trajectory_controller/doc/userdoc.rst +++ b/joint_trajectory_controller/doc/userdoc.rst @@ -155,9 +155,18 @@ allow_partial_joints_goal (boolean) Allow joint goals defining trajectory for only some joints. open_loop_control (boolean) - Use controller in open-loop control mode using ignoring the states provided by hardware interface and using last commands as states in the next control step. This is useful if hardware states are not following commands, i.e., an offset between those (typical for hydraulic manipulators). + Use controller in open-loop control mode: + + The controller ignores the states provided by hardware interface but using last commands as states for starting the trajectory interpolation. + + It deactivates the feedback control, see the ``gains`` structure. - If this flag is set, the controller tries to read the values from the command interfaces on starting. If they have real numeric values, those will be used instead of state interfaces. Therefore it is important set command interfaces to NaN (std::numeric_limits::quiet_NaN()) or state values when the hardware is started. + This is useful if hardware states are not following commands, i.e., an offset between those (typical for hydraulic manipulators). + + .. Note:: + If this flag is set, the controller tries to read the values from the command interfaces on activation. + If they have real numeric values, those will be used instead of state interfaces. + Therefore it is important set command interfaces to NaN (i.e., ``std::numeric_limits::quiet_NaN()``) or state values when the hardware is started. + + Default: false allow_nonzero_velocity_at_trajectory_end (boolean) If false, the last velocity point has to be zero or the goal will be rejected. @@ -188,7 +197,10 @@ constraints..goal (double) Default: 0.0 (tolerance is not enforced) gains (structure) - 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 + Only relevant, if ``open_loop_control`` is not set. + + 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 .. math:: diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index 0a0e6cf9d1..d85d23b37b 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -687,7 +687,8 @@ controller_interface::CallbackReturn JointTrajectoryController::on_configure( // if there is only velocity or if there is effort command interface // then use also PID adapter use_closed_loop_pid_adapter_ = - (has_velocity_command_interface_ && params_.command_interfaces.size() == 1) || + (has_velocity_command_interface_ && params_.command_interfaces.size() == 1 && + !params_.open_loop_control) || has_effort_command_interface_; if (use_closed_loop_pid_adapter_) From 061aa748886ed3414f49438b00bc980555979b04 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Mon, 7 Aug 2023 18:58:27 +0100 Subject: [PATCH 07/39] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 3 +++ admittance_controller/CHANGELOG.rst | 7 +++++++ 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 +++ gripper_controllers/CHANGELOG.rst | 3 +++ imu_sensor_broadcaster/CHANGELOG.rst | 3 +++ joint_state_broadcaster/CHANGELOG.rst | 3 +++ joint_trajectory_controller/CHANGELOG.rst | 8 ++++++++ position_controllers/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 +++ 19 files changed, 66 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 27bf6cdc8f..c6b4642c17 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 6e8b5ae9ca..2e23179f43 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Activate AdmittanceControllerTestParameterizedInvalidParameters (`#711 `_) (`#733 `_) +* Fix file name for include guard (backport `#681 `_) +* Fix out of bound access in admittance controller (`#721 `_) (`#722 `_) +* Contributors: Christoph Fröhlich + 2.23.0 (2023-06-23) ------------------- * Renovate load controller tests (`#569 `_) (`#677 `_) diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 70632904ae..9e645fc2e8 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 7525d4998d..00a59772ca 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- * Renovate load controller tests (`#569 `_) (`#677 `_) diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 8cfcd76934..057b8209c0 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- * Renovate load controller tests (`#569 `_) (`#677 `_) diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index e92b4cd215..ac3a096d80 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 +----------- + 2.23.0 (2023-06-23) ------------------- * Broadcaster parameters (`#650 `_) (`#678 `_) diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index dc9c2db8be..feeec33051 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- * Renovate load controller tests (`#569 `_) (`#677 `_) diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index da64f0583a..db3c84d340 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- * Renovate load controller tests (`#569 `_) (`#677 `_) diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index fd9449ea0e..37c6820e70 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- * Broadcaster parameters (`#650 `_) (`#678 `_) diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 145b4a50da..99e7e915ed 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- * Renovate load controller tests (`#569 `_) (`#677 `_) diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 3163f94965..70d937a53e 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,14 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* [JTC] Disable use of closed-loop PID adapter if controller is used in open-loop mode. (`#551 `_) (`#740 `_) +* [JTC] Reject messages with effort fields (`#699 `_) (`#719 `_) (`#738 `_) +* [JTC] Re-enabling test, bugfixing and hardening. Adding a parameter to define when trajectories with non-zero velocity at the end are used. (backport `#705 `_) (`#706 `_) +* Small improvement in remapping (`#393 `_) (`#724 `_) +* Contributors: Christoph Fröhlich, Dr. Denis, Bence Magyar + 2.23.0 (2023-06-23) ------------------- * Renovate load controller tests (`#569 `_) (`#677 `_) diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 37d356d773..ddae1f6cd4 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- * Renovate load controller tests (`#569 `_) (`#677 `_) diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index f702291963..6d16c2d08e 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 68e9e923de..ff12265a86 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 +----------- + 2.23.0 (2023-06-23) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index d92f3beab5..44834b3d93 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 +----------- + 2.23.0 (2023-06-23) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 6e5ab30bfb..c11bcfa722 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 4221af6f47..33b165d01d 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- * Renovate load controller tests (`#569 `_) (`#677 `_) diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 50f00fdf4f..6f529f0b5f 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index e916e8d151..8afd3b473f 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.23.0 (2023-06-23) ------------------- * Renovate load controller tests (`#569 `_) (`#677 `_) From 78e5f051ad76098d0a94b5d69fe4f30b976e4c6d Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Mon, 7 Aug 2023 18:58:59 +0100 Subject: [PATCH 08/39] 2.24.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 +- 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 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/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 +- 40 files changed, 59 insertions(+), 59 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index c6b4642c17..2e03ed85cd 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index a015873b99..14020f408b 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 2.23.0 + 2.24.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Apache License 2.0 Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 2e23179f43..06c9fe96b4 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- * Activate AdmittanceControllerTestParameterizedInvalidParameters (`#711 `_) (`#733 `_) * Fix file name for include guard (backport `#681 `_) * Fix out of bound access in admittance controller (`#721 `_) (`#722 `_) diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index 6d51b0e75c..5a7ac89ce9 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 2.23.0 + 2.24.0 Implementation of admittance controllers for different input and output interface. Denis Štogl Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 9e645fc2e8..fc43ad7788 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index 59b24b248a..e351384728 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 2.23.0 + 2.24.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 00a59772ca..b5f99dea81 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 8e0ec4c9d2..5b369a9a3b 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 2.23.0 + 2.24.0 Controller for a differential drive mobile base. Bence Magyar Jordan Palacios diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 057b8209c0..887c841b04 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index 0a32f9cc7c..961830a1c7 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 2.23.0 + 2.24.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index ac3a096d80..67279aa991 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 ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 297a7d2812..6e7568f7a2 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 2.23.0 + 2.24.0 Controller to publish state of force-torque sensors. Bence Magyar Denis Štogl diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index feeec33051..c809ee1be4 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index 821103dfda..17674e1a52 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 2.23.0 + 2.24.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index db3c84d340..880217f563 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index a63e5097f2..988fcf0e12 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 2.23.0 + 2.24.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 37c6820e70..a479b97330 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index df16e434cb..1add6dd6b5 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 2.23.0 + 2.24.0 Controller to publish readings of IMU sensors. Bence Magyar Denis Štogl diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 99e7e915ed..fbb89a363f 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index 1fd7c889e9..a46c3e9404 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 2.23.0 + 2.24.0 Broadcaster to publish joint state Bence Magyar Denis Stogl diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 70d937a53e..04dad95c49 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- * [JTC] Disable use of closed-loop PID adapter if controller is used in open-loop mode. (`#551 `_) (`#740 `_) * [JTC] Reject messages with effort fields (`#699 `_) (`#719 `_) (`#738 `_) * [JTC] Re-enabling test, bugfixing and hardening. Adding a parameter to define when trajectories with non-zero velocity at the end are used. (backport `#705 `_) (`#706 `_) diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 17a97945b8..77b4cf108c 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 2.23.0 + 2.24.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar Jordan Palacios diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index ddae1f6cd4..82fe42a2a3 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index cd120bb7ba..96e43ec041 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 2.23.0 + 2.24.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 6d16c2d08e..22910f088c 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index f114c05264..96e5e75de2 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 2.23.0 + 2.24.0 Metapackage for ROS2 controllers related packages Bence Magyar Jordan Palacios diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index ff12265a86..d49958b127 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 ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index f02d0b5a17..8704e0af60 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 2.23.0 + 2.24.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Denis Štogl diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index 154a4ca266..31d7bd704a 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="2.23.0", + version="2.24.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 44834b3d93..0ed4429d54 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 ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 033a32aa68..0f02c95bf7 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 - 2.23.0 + 2.24.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 7276cd2cd6..11138b8aed 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -7,7 +7,7 @@ setup( name=package_name, - version="2.23.0", + version="2.24.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 c11bcfa722..11eac10521 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index 22a22be78c..243e96b4c2 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 2.23.0 + 2.24.0 Package for steering robot configurations including odometry and interfaces. Apache License 2.0 Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 33b165d01d..602e965be3 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index b9d5eeea10..801706eb90 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 2.23.0 + 2.24.0 Controller for a tricycle drive mobile base Bence Magyar Tony Najjar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 6f529f0b5f..86b21fd93c 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index 5aa18c46fc..24adc6bb94 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 2.23.0 + 2.24.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 8afd3b473f..dc3f7ecc8c 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.24.0 (2023-08-07) +------------------- 2.23.0 (2023-06-23) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index c5d16ffbcc..53fd6221ef 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 2.23.0 + 2.24.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios From 65904ec300ca37096a497480eea1ba8f126152f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Tue, 8 Aug 2023 13:31:25 +0200 Subject: [PATCH 09/39] [JTC] Update trajectory documentation (#714) (#741) --- .../doc/new_trajectory.png | Bin 0 -> 73149 bytes .../doc/parameters.rst | 137 ++++++++++++++ .../doc/spline_acceleration.png | Bin 0 -> 34639 bytes .../doc/spline_position.png | Bin 0 -> 28511 bytes .../doc/spline_position_velocity.png | Bin 0 -> 37882 bytes .../spline_position_velocity_acceleration.png | Bin 0 -> 39812 bytes ...ion_velocity_acceleration_initialpoint.png | Bin 0 -> 39086 bytes ...ocity_acceleration_initialpoint_notime.png | Bin 0 -> 36267 bytes .../doc/spline_velocity.png | Bin 0 -> 32183 bytes .../doc/spline_wrong_points.png | Bin 0 -> 41712 bytes .../doc/trajectory.rst | 168 ++++++++++++++++++ .../doc/trajectory_replacement_future.png | Bin 0 -> 71754 bytes .../doc/trajectory_replacement_now.png | Bin 0 -> 64005 bytes .../doc/trajectory_replacement_past.png | Bin 0 -> 74230 bytes joint_trajectory_controller/doc/userdoc.rst | 160 ++--------------- 15 files changed, 321 insertions(+), 144 deletions(-) create mode 100644 joint_trajectory_controller/doc/new_trajectory.png create mode 100644 joint_trajectory_controller/doc/parameters.rst create mode 100644 joint_trajectory_controller/doc/spline_acceleration.png create mode 100644 joint_trajectory_controller/doc/spline_position.png create mode 100644 joint_trajectory_controller/doc/spline_position_velocity.png create mode 100644 joint_trajectory_controller/doc/spline_position_velocity_acceleration.png create mode 100644 joint_trajectory_controller/doc/spline_position_velocity_acceleration_initialpoint.png create mode 100644 joint_trajectory_controller/doc/spline_position_velocity_acceleration_initialpoint_notime.png create mode 100644 joint_trajectory_controller/doc/spline_velocity.png create mode 100644 joint_trajectory_controller/doc/spline_wrong_points.png create mode 100644 joint_trajectory_controller/doc/trajectory.rst create mode 100644 joint_trajectory_controller/doc/trajectory_replacement_future.png create mode 100644 joint_trajectory_controller/doc/trajectory_replacement_now.png create mode 100644 joint_trajectory_controller/doc/trajectory_replacement_past.png diff --git a/joint_trajectory_controller/doc/new_trajectory.png b/joint_trajectory_controller/doc/new_trajectory.png new file mode 100644 index 0000000000000000000000000000000000000000..b7c07eeffee46b4602ef8f2a9333afdcab666a14 GIT binary patch literal 73149 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 literal 0 HcmV?d00001 diff --git a/joint_trajectory_controller/doc/parameters.rst b/joint_trajectory_controller/doc/parameters.rst new file mode 100644 index 0000000000..8be135ff4b --- /dev/null +++ b/joint_trajectory_controller/doc/parameters.rst @@ -0,0 +1,137 @@ +:github_url: https://github.com/ros-controls/ros2_controllers/blob/{REPOS_FILE_BRANCH}/joint_trajectory_controller/doc/parameters.rst + +.. _parameters: + +Details about parameters +^^^^^^^^^^^^^^^^^^^^^^^^ + +joints (list(string)) + Joint names to control and listen to. + +command_joints (list(string)) + Joint names to control. This parameters is used if JTC is used in a controller chain where command and state interfaces don't have same names. + +command_interface (list(string)) + Command interfaces provided by the hardware interface for all joints. + + Values: [position | velocity | acceleration] (multiple allowed) + +state_interfaces (list(string)) + State interfaces provided by the hardware for all joints. + + Values: position (mandatory) [velocity, [acceleration]]. + Acceleration interface can only be used in combination with position and velocity. + +state_publish_rate (double) + Publish-rate of the controller's "state" topic. + + Default: 50.0 + +action_monitor_rate (double) + Rate to monitor status changes when the controller is executing action (control_msgs::action::FollowJointTrajectory). + + Default: 20.0 + +allow_partial_joints_goal (boolean) + Allow joint goals defining trajectory for only some joints. + + Default: false + +allow_integration_in_goal_trajectories (boolean) + Allow integration in goal trajectories to accept goals without position or velocity specified + + Default: false + +interpolation_method (string) + The type of interpolation to use, if any. Can be "splines" or "none". + + Default: splines + +open_loop_control (boolean) + Use controller in open-loop control mode: + + * The controller ignores the states provided by hardware interface but using last commands as states for starting the trajectory interpolation. + * It deactivates the feedback control, see the ``gains`` structure. + + This is useful if hardware states are not following commands, i.e., an offset between those (typical for hydraulic manipulators). + + .. Note:: + If this flag is set, the controller tries to read the values from the command interfaces on activation. + If they have real numeric values, those will be used instead of state interfaces. + Therefore it is important set command interfaces to NaN (i.e., ``std::numeric_limits::quiet_NaN()``) or state values when the hardware is started. + + Default: false + +allow_nonzero_velocity_at_trajectory_end (boolean) + If false, the last velocity point has to be zero or the goal will be rejected. + + Default: true + +constraints (structure) + Default values for tolerances if no explicit values are states in JointTrajectory message. + +constraints.stopped_velocity_tolerance (double) + Default value for end velocity deviation. + + Default: 0.01 + +constraints.goal_time (double) + Maximally allowed tolerance for not reaching the end of the trajectory in a predefined time. + + Default: 0.0 (not checked) + +constraints..trajectory (double) + Maximally allowed deviation from the target trajectory for a given joint. + + Default: 0.0 (tolerance is not enforced) + +constraints..goal (double) + Maximally allowed deviation from the goal (end of the trajectory) for a given joint. + + Default: 0.0 (tolerance is not enforced) + +gains (structure) + Only relevant, if ``open_loop_control`` is not set. + + 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 + + .. 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`` or ``effort`` manipulated variable (control variable) :math:`u`, respectively. + +gains..p (double) + Proportional gain :math:`k_p` for PID + + Default: 0.0 + +gains..i (double) + Integral gain :math:`k_i` for PID + + Default: 0.0 + +gains..d (double) + Derivative gain :math:`k_d` for PID + + Default: 0.0 + +gains..i_clamp (double) + Integral clamp. Symmetrical in both positive and negative direction. + + Default: 0.0 + +gains..ff_velocity_scale (double) + Feed-forward scaling :math:`k_{ff}` of velocity + + Default: 0.0 + +gains..normalize_error (bool) + If true, the position error :math:`e = normalize(s_d - s)` is normalized between :math:`-\pi, \pi`. + 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. Use this for revolute joints without end stop, + where the shortest rotation to the target position is the desired motion. + + Default: false diff --git a/joint_trajectory_controller/doc/spline_acceleration.png b/joint_trajectory_controller/doc/spline_acceleration.png new file mode 100644 index 0000000000000000000000000000000000000000..98672beedd184285cf0bf4b311b9efa93e916e0f GIT binary patch literal 34639 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 literal 0 HcmV?d00001 diff --git a/joint_trajectory_controller/doc/spline_position_velocity_acceleration.png b/joint_trajectory_controller/doc/spline_position_velocity_acceleration.png new file mode 100644 index 0000000000000000000000000000000000000000..70152eec4e097d26ed93c3986d4e97d217bc7967 GIT binary patch literal 39812 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 literal 0 HcmV?d00001 diff --git a/joint_trajectory_controller/doc/spline_velocity.png b/joint_trajectory_controller/doc/spline_velocity.png new file mode 100644 index 0000000000000000000000000000000000000000..d427f4da8819e2ec818bac73e13398f9404006a8 GIT binary patch literal 32183 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 literal 0 HcmV?d00001 diff --git a/joint_trajectory_controller/doc/spline_wrong_points.png b/joint_trajectory_controller/doc/spline_wrong_points.png new file mode 100644 index 0000000000000000000000000000000000000000..f73310c031dccb9a038d3d4a67d781e38ac1cefc GIT binary patch literal 41712 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. [#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 `_ diff --git a/joint_trajectory_controller/doc/trajectory_replacement_future.png b/joint_trajectory_controller/doc/trajectory_replacement_future.png new file mode 100644 index 0000000000000000000000000000000000000000..582a6acce85995fae84013dbc0ad0569d3c15ab7 GIT binary patch literal 71754 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
h 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 literal 0 HcmV?d00001 diff --git a/joint_trajectory_controller/doc/trajectory_replacement_past.png b/joint_trajectory_controller/doc/trajectory_replacement_past.png new file mode 100644 index 0000000000000000000000000000000000000000..a719f6fc66bd9c9dddc0a8dbfb5801df45413b23 GIT binary patch literal 74230 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 SC`6C|0000`_. *Citations are given in the respective section, but were adapted for the ROS 2 implementation.* [#f1]_ [#f2]_ - -Trajectory representation [#f1]_ ---------------------------------- - -Trajectories are represented internally with ``trajectory_msgs/msg/JointTrajectory`` data structure. -By default, a spline interpolator is provided, but it's possible to support other representations. -The spline interpolator uses the following interpolation strategies depending on the waypoint specification: - -* Linear: Only position is specified. Guarantees continuity at the position level. Discouraged because it yields trajectories with discontinuous velocities at the waypoints. - -* Cubic: Position and velocity are specified. Guarantees continuity at the velocity level. - -* Quintic: Position, velocity and acceleration are specified: Guarantees continuity at the acceleration level. +*Parts of this documentation were originally published in the ROS 1 wiki under the* `CC BY 3.0 license `_. *Citations are given in the respective section, but were adapted for the ROS 2 implementation.* [#f1]_ Hardware interface type [#f1]_ ------------------------------- @@ -115,133 +101,10 @@ Preemption policy [#f1]_ Only one action goal can be active at any moment, or none if the topic interface is used. Path and goal tolerances are checked only for the trajectory segments of the active goal. -When an active action goal is preempted by another command coming from the action interface, the goal is canceled and the client is notified. +When an active action goal is preempted by another command coming from the action interface, the goal is canceled and the client is notified. The trajectory is replaced in a defined way, see :ref:`trajectory replacement `. Sending an empty trajectory message from the topic interface (not the action interface) will override the current action goal and not abort the action. -.. _parameters: - -Details about parameters -^^^^^^^^^^^^^^^^^^^^^^^^ - -joints (list(string)) - Joint names to control and listen to. - -command_joints (list(string)) - Joint names to control. This parameters is used if JTC is used in a controller chain where command and state interfaces don't have same names. - -command_interface (list(string)) - Command interfaces provided by the hardware interface for all joints. - - Values: [position | velocity | acceleration] (multiple allowed) - -state_interfaces (list(string)) - State interfaces provided by the hardware for all joints. - - Values: position (mandatory) [velocity, [acceleration]]. - Acceleration interface can only be used in combination with position and velocity. - -state_publish_rate (double) - Publish-rate of the controller's "state" topic. - - Default: 50.0 - -action_monitor_rate (double) - Rate to monitor status changes when the controller is executing action (control_msgs::action::FollowJointTrajectory). - - Default: 20.0 - -allow_partial_joints_goal (boolean) - Allow joint goals defining trajectory for only some joints. - -open_loop_control (boolean) - Use controller in open-loop control mode: - + The controller ignores the states provided by hardware interface but using last commands as states for starting the trajectory interpolation. - + It deactivates the feedback control, see the ``gains`` structure. - - This is useful if hardware states are not following commands, i.e., an offset between those (typical for hydraulic manipulators). - - .. Note:: - If this flag is set, the controller tries to read the values from the command interfaces on activation. - If they have real numeric values, those will be used instead of state interfaces. - Therefore it is important set command interfaces to NaN (i.e., ``std::numeric_limits::quiet_NaN()``) or state values when the hardware is started. - - Default: false - -allow_nonzero_velocity_at_trajectory_end (boolean) - If false, the last velocity point has to be zero or the goal will be rejected. - - Default: true - -constraints (structure) - Default values for tolerances if no explicit values are states in JointTrajectory message. - -constraints.stopped_velocity_tolerance (double) - Default value for end velocity deviation. - - Default: 0.01 - -constraints.goal_time (double) - Maximally allowed tolerance for not reaching the end of the trajectory in a predefined time. - - Default: 0.0 (not checked) - -constraints..trajectory (double) - Maximally allowed deviation from the target trajectory for a given joint. - - Default: 0.0 (tolerance is not enforced) - -constraints..goal (double) - Maximally allowed deviation from the goal (end of the trajectory) for a given joint. - - Default: 0.0 (tolerance is not enforced) - -gains (structure) - Only relevant, if ``open_loop_control`` is not set. - - 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 - - .. math:: - - u = k_ff v_d + k_p (s_d - s) + k_i \sum(s_d - s) dt + k_d (v_d - v) - - with the desired velocity :math:`v_d` and position :math:`s_d`, - the measured velocity :math:`v` and position :math:`s`, the controller period :math:`dt`, - and the ``velocity`` or ``effort`` setpoint :math:`u`, respectively. - -gains..p (double) - Proportional gain :math:`k_p` for PID - - Default: 0.0 - -gains..i (double) - Integral gain :math:`k_i` for PID - - Default: 0.0 - -gains..d (double) - Derivative gain :math:`k_d` for PID - - Default: 0.0 - -gains..i_clamp (double) - Integral clamp. Symmetrical in both positive and negative direction. - - Default: 0.0 - -gains..ff_velocity_scale (double) - Feed-forward scaling :math:`k_ff` of velocity - - Default: 0.0 - -gains..normalize_error (bool) - If true, the position error :math:`e = normalize(s_d - s)` is normalized between :math:`-\pi, \pi`. - 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. Use this for revolute joints without end stop, - where the shortest rotation to the target position is the desired motion. - - Default: false .. _ROS 2 interface: @@ -274,8 +137,7 @@ There are two mechanisms for sending trajectories to the controller: * via action, see :ref:`actions ` * via topic, see :ref:`subscriber ` -Both use the ``trajectory_msgs/JointTrajectory`` message to specify trajectories, and require specifying values for all the controller joints (as opposed to only a subset) if ``allow_partial_joints_goal`` is not set to ``True``. - +Both use the ``trajectory_msgs/msg/JointTrajectory`` message to specify trajectories, and require specifying values for all the controller joints (as opposed to only a subset) if ``allow_partial_joints_goal`` is not set to ``True``. For further information on the message format, see :ref:`trajectory representation `. .. _Actions: @@ -318,17 +180,27 @@ Services Query controller state at any future time -Specialized versions of JointTrajectoryController (TBD in ...) +Specialized versions of JointTrajectoryController -------------------------------------------------------------- +(TBD in ...) -The controller types are placed into namespaces according to their command types for the hardware (see `general introduction into controllers <../../index.rst>`_). +The controller types are placed into namespaces according to their command types for the hardware (see :ref:`controllers`). The following version of the Joint Trajectory Controller are available mapping the following interfaces: * position_controllers::JointTrajectoryController +Further information +-------------------------------------------------------------- + +.. toctree:: + :titlesonly: + + Trajectory Representation + joint_trajectory_controller Parameters + + .. rubric:: Footnote .. [#f1] Adolfo Rodriguez: `joint_trajectory_controller `_ -.. [#f2] Adolfo Rodriguez: `Understanding trajectory replacement `_ From 76de69d40e79e9291536aa75c011c7c12d3cf857 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 12:19:19 +0100 Subject: [PATCH 10/39] Remove wrong description (#742) (#747) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 5178503f1044cc988663c196c32a0039c72418b0) Co-authored-by: Christoph Fröhlich --- joint_trajectory_controller/doc/userdoc.rst | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/joint_trajectory_controller/doc/userdoc.rst b/joint_trajectory_controller/doc/userdoc.rst index 281904e867..92f0f9629d 100644 --- a/joint_trajectory_controller/doc/userdoc.rst +++ b/joint_trajectory_controller/doc/userdoc.rst @@ -180,17 +180,6 @@ Services Query controller state at any future time -Specialized versions of JointTrajectoryController --------------------------------------------------------------- -(TBD in ...) - -The controller types are placed into namespaces according to their command types for the hardware (see :ref:`controllers`). - -The following version of the Joint Trajectory Controller are available mapping the following interfaces: - -* position_controllers::JointTrajectoryController - - Further information -------------------------------------------------------------- From 4992fd474a92be00143d45594242956f46f976cc Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 12:19:39 +0100 Subject: [PATCH 11/39] Use tabs (#743) (#746) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bence Magyar (cherry picked from commit af54985bc09121d4ca5d45fba68effc279cb2689) Co-authored-by: Christoph Fröhlich --- forward_command_controller/doc/userdoc.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/forward_command_controller/doc/userdoc.rst b/forward_command_controller/doc/userdoc.rst index ee0af57d7b..a91479c9af 100644 --- a/forward_command_controller/doc/userdoc.rst +++ b/forward_command_controller/doc/userdoc.rst @@ -21,12 +21,12 @@ Parameters This controller uses the `generate_parameter_library `_ to handle its parameters. -forward_command_controller -^^^^^^^^^^^^^^^^^^^^^^^^^^ + .. tabs:: + + .. group-tab:: forward_command_controller -.. generate_parameter_library_details:: ../src/forward_command_controller_parameters.yaml + .. generate_parameter_library_details:: ../src/forward_command_controller_parameters.yaml -multi_interface_forward_command_controller -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + .. group-tab:: multi_interface_forward_command_controller -.. generate_parameter_library_details:: ../src/multi_interface_forward_command_controller_parameters.yaml + .. generate_parameter_library_details:: ../src/multi_interface_forward_command_controller_parameters.yaml From a58243bca5919e827f93480fa9b019aa8b7ae471 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 11:45:19 +0100 Subject: [PATCH 12/39] Update docs for diff drive controller (#751) (#753) --- admittance_controller/doc/userdoc.rst | 2 +- diff_drive_controller/doc/userdoc.rst | 61 ++++++++++++--------------- doc/writing_new_controller.rst | 2 +- 3 files changed, 30 insertions(+), 35 deletions(-) diff --git a/admittance_controller/doc/userdoc.rst b/admittance_controller/doc/userdoc.rst index 152ed890dc..0e4469cd50 100644 --- a/admittance_controller/doc/userdoc.rst +++ b/admittance_controller/doc/userdoc.rst @@ -11,7 +11,7 @@ The controller implements ``ChainedControllerInterface``, so it is possible to a The controller requires an external kinematics plugin to function. The `kinematics_interface `_ repository provides an interface and an implementation that the admittance controller can use. -ROS2 interface of the controller +ROS 2 interface of the controller --------------------------------- Parameters diff --git a/diff_drive_controller/doc/userdoc.rst b/diff_drive_controller/doc/userdoc.rst index 6bd682af26..f8318bc4b8 100644 --- a/diff_drive_controller/doc/userdoc.rst +++ b/diff_drive_controller/doc/userdoc.rst @@ -6,71 +6,66 @@ diff_drive_controller ===================== Controller for mobile robots with differential drive. -Input for control are robot body velocity commands which are translated to wheel commands for the differential drive base. -Odometry is computed from hardware feedback and published. - -Velocity commands ------------------ -The controller works with a velocity twist from which it extracts the x component of the linear velocity and the z component of the angular velocity. Velocities on other components are ignored. +As input it takes velocity commands for the robot body, which are translated to wheel commands for the differential drive base. -Hardware interface type ------------------------ - -The controller works with wheel joints through a velocity interface. +Odometry is computed from hardware feedback and published. Other features -------------- - Realtime-safe implementation. - Odometry publishing - Task-space velocity, acceleration and jerk limits - Automatic stop after command time-out + + Realtime-safe implementation. + + Odometry publishing + + Task-space velocity, acceleration and jerk limits + + Automatic stop after command time-out -ros2_control Interfaces ------------------------- +Description of controller's interfaces +------------------------------------------------ References -,,,,,,,,,,, +,,,,,,,,,,,,,,,,,, +(the controller is not yet implemented as chainable controller) -States -,,,,,,, +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. -Commands +Output ,,,,,,,,, +Joints' velocity (``hardware_interface::HW_IF_VELOCITY``) are used. -ROS2 Interfaces ----------------- + +ROS 2 Interfaces +------------------------ Subscribers ,,,,,,,,,,,, + ~/cmd_vel [geometry_msgs/msg/TwistStamped] - Velocity command for the controller. + Velocity command for the controller, if ``use_stamped_vel=true``. The controller extracts the x component of the linear velocity and the z component of the angular velocity. Velocities on other components are ignored. ~/cmd_vel_unstamped [geometry_msgs::msg::Twist] - -~/cmd_vel_out [] - - + Velocity command for the controller, if ``use_stamped_vel=false``. The controller extracts the x component of the linear velocity and the z component of the angular velocity. Velocities on other components are ignored. Publishers ,,,,,,,,,,, -~/odom [] +~/odom [nav_msgs::msg::Odometry] + This represents an estimate of the robot's position and velocity in free space. -/tf +/tf [tf2_msgs::msg::TFMessage] + tf tree. Published only if ``enable_odom_tf=true`` - -Services -,,,,,,,,, +~/cmd_vel_out [geometry_msgs/msg/TwistStamped] + Velocity command for the controller, where limits were applied. Published only if ``publish_limited_velocity=true`` Parameters ------------- +,,,,,,,,,,,, Check `parameter definition file for details `_. diff --git a/doc/writing_new_controller.rst b/doc/writing_new_controller.rst index 4d8c3752ae..6138fdecfd 100644 --- a/doc/writing_new_controller.rst +++ b/doc/writing_new_controller.rst @@ -27,7 +27,7 @@ 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. ROS2-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. (For more information on this, a search engine is your friend :) ). 2. include ``"controller_interface/controller_interface.hpp"`` and ``visibility_control.h`` if you are using one. From 490664541c9b99d715821c329c72ebd596b31699 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 08:55:05 +0100 Subject: [PATCH 13/39] removed duplicated previous_publish_timestamp_ increment by publish_period_ in diff_drive_controller.cpp (#644) (#777) Co-authored-by: Jules CARPENTIER (cherry picked from commit 77420cb47482c3c580de51e0086622533d82f7d4) Co-authored-by: julescarpentier <44528057+julescarpentier@users.noreply.github.com> --- diff_drive_controller/src/diff_drive_controller.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/diff_drive_controller/src/diff_drive_controller.cpp b/diff_drive_controller/src/diff_drive_controller.cpp index f5dd2e3c0f..2913838138 100644 --- a/diff_drive_controller/src/diff_drive_controller.cpp +++ b/diff_drive_controller/src/diff_drive_controller.cpp @@ -203,8 +203,6 @@ controller_interface::return_type DiffDriveController::update( if (should_publish) { - previous_publish_timestamp_ += publish_period_; - if (realtime_odometry_publisher_->trylock()) { auto & odometry_message = realtime_odometry_publisher_->msg_; From faa08e26be110dfb5b07b14737cad5c71a84ebb0 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 11:40:58 +0100 Subject: [PATCH 14/39] [JTC] Rename parameter: normalize_error to angle_wraparound (#772) (#776) --- joint_trajectory_controller/doc/parameters.rst | 10 ++++++---- .../src/joint_trajectory_controller.cpp | 13 +++++++++++-- .../src/joint_trajectory_controller_parameters.yaml | 8 +++++++- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/joint_trajectory_controller/doc/parameters.rst b/joint_trajectory_controller/doc/parameters.rst index 8be135ff4b..f62320870c 100644 --- a/joint_trajectory_controller/doc/parameters.rst +++ b/joint_trajectory_controller/doc/parameters.rst @@ -100,7 +100,7 @@ gains (structure) 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), + with the desired velocity :math:`v_d`, the measured velocity :math:`v`, the position error :math:`e` (definition see ``angle_wraparound`` below), the controller period :math:`dt`, and the ``velocity`` or ``effort`` manipulated variable (control variable) :math:`u`, respectively. gains..p (double) @@ -128,10 +128,12 @@ gains..ff_velocity_scale (double) Default: 0.0 -gains..normalize_error (bool) +gains..angle_wraparound (bool) + For joints that wrap around (without end stop, ie. are continuous), + where the shortest rotation to the target position is the desired motion. If true, the position error :math:`e = normalize(s_d - s)` is normalized between :math:`-\pi, \pi`. 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. Use this for revolute joints without end stop, - where the shortest rotation to the target position is the desired motion. + position :math:`s` from the state interface. + Default: false diff --git a/joint_trajectory_controller/src/joint_trajectory_controller.cpp b/joint_trajectory_controller/src/joint_trajectory_controller.cpp index d85d23b37b..cff2918b75 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller.cpp +++ b/joint_trajectory_controller/src/joint_trajectory_controller.cpp @@ -722,12 +722,21 @@ controller_interface::CallbackReturn JointTrajectoryController::on_configure( } } - // Configure joint position error normalization from ROS parameters + // Configure joint position error normalization from ROS parameters (angle_wraparound) normalize_joint_error_.resize(dof_); for (size_t i = 0; i < dof_; ++i) { const auto & gains = params_.gains.joints_map.at(params_.joints[i]); - normalize_joint_error_[i] = gains.normalize_error; + if (gains.normalize_error) + { + // TODO(anyone): Remove deprecation warning in the end of 2023 + RCLCPP_INFO(logger, "`normalize_error` is deprecated, use `angle_wraparound` instead!"); + normalize_joint_error_[i] = gains.normalize_error; + } + else + { + normalize_joint_error_[i] = gains.angle_wraparound; + } } if (params_.state_interfaces.empty()) diff --git a/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml b/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml index a754929ef7..bb0b45bb80 100644 --- a/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml +++ b/joint_trajectory_controller/src/joint_trajectory_controller_parameters.yaml @@ -109,7 +109,13 @@ joint_trajectory_controller: normalize_error: { type: bool, default_value: false, - description: "Use position error normalization to -pi to pi." + description: "(Deprecated) Use position error normalization to -pi to pi." + } + angle_wraparound: { + type: bool, + default_value: false, + description: "For joints that wrap around (ie. are continuous). + Normalizes position-error to -pi to pi." } constraints: stopped_velocity_tolerance: { From 1741109863184a281517dd7558d93a16fc266e4e Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Fri, 15 Sep 2023 12:07:34 +0100 Subject: [PATCH 15/39] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 3 +++ admittance_controller/CHANGELOG.rst | 5 +++++ 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 | 5 +++++ gripper_controllers/CHANGELOG.rst | 3 +++ imu_sensor_broadcaster/CHANGELOG.rst | 3 +++ joint_state_broadcaster/CHANGELOG.rst | 3 +++ joint_trajectory_controller/CHANGELOG.rst | 7 +++++++ position_controllers/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 +++ 19 files changed, 68 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 2e03ed85cd..24ce981d85 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 06c9fe96b4..7245435046 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Update docs for diff drive controller (`#751 `_) (`#753 `_) +* Contributors: Christoph Fröhlich + 2.24.0 (2023-08-07) ------------------- * Activate AdmittanceControllerTestParameterizedInvalidParameters (`#711 `_) (`#733 `_) diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index fc43ad7788..8cbda80e0a 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index b5f99dea81..c3df199150 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* removed duplicated previous_publish_timestamp\_ increment by publish_period\_ in diff_drive_controller.cpp (`#644 `_) (`#777 `_) +* Update docs for diff drive controller (`#751 `_) (`#753 `_) +* Contributors: Christoph Fröhlich, Jules CARPENTIER + 2.24.0 (2023-08-07) ------------------- diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 887c841b04..5e1d8b3645 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 67279aa991..5529888fb7 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 +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index c809ee1be4..53123f6257 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 tabs (`#743 `_) (`#746 `_) +* Contributors: Christoph Fröhlich + 2.24.0 (2023-08-07) ------------------- diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 880217f563..816e79f056 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index a479b97330..27d6d463d7 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index fbb89a363f..91f4ed8fdc 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 04dad95c49..63711a321d 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] Rename parameter: normalize_error to angle_wraparound (`#772 `_) (`#776 `_) +* Remove wrong description (`#742 `_) (`#747 `_) +* [JTC] Update trajectory documentation (`#714 `_) (`#741 `_) +* Contributors: Christoph Fröhlich + 2.24.0 (2023-08-07) ------------------- * [JTC] Disable use of closed-loop PID adapter if controller is used in open-loop mode. (`#551 `_) (`#740 `_) diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 82fe42a2a3..e0cbac1e85 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 22910f088c..c31262023e 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index d49958b127..0be1a596d3 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 +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 0ed4429d54..966a7787ec 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 +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 11eac10521..1fa79e57ad 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 602e965be3..d8d7a49a89 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 86b21fd93c..8ca4773dbd 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index dc3f7ecc8c..4a0579b22c 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.24.0 (2023-08-07) ------------------- From c8fc1a3ad7106c0de1d19bc18cf61f7544e36dfb Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Fri, 15 Sep 2023 12:07:50 +0100 Subject: [PATCH 16/39] 2.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 +- 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 +- position_controllers/CHANGELOG.rst | 4 ++-- position_controllers/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 +- 40 files changed, 59 insertions(+), 59 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 24ce981d85..bc6701ddea 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index 14020f408b..8b26cf563b 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 2.24.0 + 2.25.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Apache License 2.0 Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 7245435046..5d5651cc7f 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- * Update docs for diff drive controller (`#751 `_) (`#753 `_) * Contributors: Christoph Fröhlich diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index 5a7ac89ce9..da34ea8bff 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 2.24.0 + 2.25.0 Implementation of admittance controllers for different input and output interface. Denis Štogl Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 8cbda80e0a..59ffc54431 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index e351384728..e6715f62f8 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 2.24.0 + 2.25.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index c3df199150..d86b43d21e 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- * removed duplicated previous_publish_timestamp\_ increment by publish_period\_ in diff_drive_controller.cpp (`#644 `_) (`#777 `_) * Update docs for diff drive controller (`#751 `_) (`#753 `_) * Contributors: Christoph Fröhlich, Jules CARPENTIER diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 5b369a9a3b..00cbf9a82d 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 2.24.0 + 2.25.0 Controller for a differential drive mobile base. Bence Magyar Jordan Palacios diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 5e1d8b3645..75d86f2ce0 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index 961830a1c7..a4d8c0ba5a 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 2.24.0 + 2.25.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 5529888fb7..a5022ddda2 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 ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 6e7568f7a2..d13841e5bb 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 2.24.0 + 2.25.0 Controller to publish state of force-torque sensors. Bence Magyar Denis Štogl diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 53123f6257..ff3aa46a48 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- * Use tabs (`#743 `_) (`#746 `_) * Contributors: Christoph Fröhlich diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index 17674e1a52..76e3440e13 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 2.24.0 + 2.25.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 816e79f056..de6f0ae018 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index 988fcf0e12..12c0160fea 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 2.24.0 + 2.25.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 27d6d463d7..9e81396179 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index 1add6dd6b5..5756550cad 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 2.24.0 + 2.25.0 Controller to publish readings of IMU sensors. Bence Magyar Denis Štogl diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 91f4ed8fdc..0c9a6ca079 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index a46c3e9404..b1aca75b35 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 2.24.0 + 2.25.0 Broadcaster to publish joint state Bence Magyar Denis Stogl diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 63711a321d..f917646ab4 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- * [JTC] Rename parameter: normalize_error to angle_wraparound (`#772 `_) (`#776 `_) * Remove wrong description (`#742 `_) (`#747 `_) * [JTC] Update trajectory documentation (`#714 `_) (`#741 `_) diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 77b4cf108c..cbf5e753c0 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 2.24.0 + 2.25.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar Jordan Palacios diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index e0cbac1e85..d5017c0cfd 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index 96e43ec041..f756afd791 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 2.24.0 + 2.25.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index c31262023e..a953921f7f 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 96e5e75de2..7aa9276267 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 2.24.0 + 2.25.0 Metapackage for ROS2 controllers related packages Bence Magyar Jordan Palacios diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 0be1a596d3..f433d23ec0 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 ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 8704e0af60..0f17d8ffc9 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 2.24.0 + 2.25.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Denis Štogl diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index 31d7bd704a..3f007e2b7b 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="2.24.0", + version="2.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 966a7787ec..c4690eb802 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 ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 0f02c95bf7..6088522566 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 - 2.24.0 + 2.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 11138b8aed..52d9ea5742 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -7,7 +7,7 @@ setup( name=package_name, - version="2.24.0", + version="2.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 1fa79e57ad..65485d3cc1 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index 243e96b4c2..3af601dbe4 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 2.24.0 + 2.25.0 Package for steering robot configurations including odometry and interfaces. Apache License 2.0 Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index d8d7a49a89..f0a495bbc5 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index 801706eb90..a2f84a7877 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 2.24.0 + 2.25.0 Controller for a tricycle drive mobile base Bence Magyar Tony Najjar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 8ca4773dbd..3fef1500fd 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index 24adc6bb94..c83393da47 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 2.24.0 + 2.25.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 4a0579b22c..f1068397c7 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.25.0 (2023-09-15) +------------------- 2.24.0 (2023-08-07) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index 53fd6221ef..eb566d04b8 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 2.24.0 + 2.25.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios From 7962d3350ae95601f4b4c11aa0ac3dd2cb88d3f7 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sun, 17 Sep 2023 15:24:26 +0100 Subject: [PATCH 17/39] add a broadcaster for range sensor (backport #725) (#766) --- .github/workflows/ci-ros-lint.yml | 2 + doc/controllers_index.rst | 5 +- range_sensor_broadcaster/CMakeLists.txt | 106 ++++++++ range_sensor_broadcaster/README.md | 8 + range_sensor_broadcaster/doc/userdoc.rst | 15 ++ .../range_sensor_broadcaster.hpp | 77 ++++++ .../visibility_control.h | 53 ++++ range_sensor_broadcaster/package.xml | 31 +++ .../range_sensor_broadcaster.xml | 8 + .../src/range_sensor_broadcaster.cpp | 137 ++++++++++ .../range_sensor_broadcaster_parameters.yaml | 15 ++ .../test/range_sensor_broadcaster_params.yaml | 11 + .../test_load_range_sensor_broadcaster.cpp | 52 ++++ .../test/test_range_sensor_broadcaster.cpp | 247 ++++++++++++++++++ .../test/test_range_sensor_broadcaster.hpp | 58 ++++ ros2_controllers/package.xml | 1 + 16 files changed, 824 insertions(+), 2 deletions(-) create mode 100644 range_sensor_broadcaster/CMakeLists.txt create mode 100644 range_sensor_broadcaster/README.md create mode 100644 range_sensor_broadcaster/doc/userdoc.rst create mode 100644 range_sensor_broadcaster/include/range_sensor_broadcaster/range_sensor_broadcaster.hpp create mode 100644 range_sensor_broadcaster/include/range_sensor_broadcaster/visibility_control.h create mode 100644 range_sensor_broadcaster/package.xml create mode 100644 range_sensor_broadcaster/range_sensor_broadcaster.xml create mode 100644 range_sensor_broadcaster/src/range_sensor_broadcaster.cpp create mode 100644 range_sensor_broadcaster/src/range_sensor_broadcaster_parameters.yaml create mode 100644 range_sensor_broadcaster/test/range_sensor_broadcaster_params.yaml create mode 100644 range_sensor_broadcaster/test/test_load_range_sensor_broadcaster.cpp create mode 100644 range_sensor_broadcaster/test/test_range_sensor_broadcaster.cpp create mode 100644 range_sensor_broadcaster/test/test_range_sensor_broadcaster.hpp diff --git a/.github/workflows/ci-ros-lint.yml b/.github/workflows/ci-ros-lint.yml index d8f77a323a..174f5efcd3 100644 --- a/.github/workflows/ci-ros-lint.yml +++ b/.github/workflows/ci-ros-lint.yml @@ -26,6 +26,7 @@ jobs: joint_trajectory_controller gripper_controllers position_controllers + range_sensor_broadcaster ros2_controllers ros2_controllers_test_nodes tricycle_controller @@ -56,6 +57,7 @@ jobs: joint_trajectory_controller gripper_controllers position_controllers + range_sensor_broadcaster ros2_controllers ros2_controllers_test_nodes tricycle_controller diff --git a/doc/controllers_index.rst b/doc/controllers_index.rst index 763381c065..de33c3284c 100644 --- a/doc/controllers_index.rst +++ b/doc/controllers_index.rst @@ -63,6 +63,7 @@ Available Broadcasters .. toctree:: :titlesonly: - Joint State Broadcaster <../joint_state_broadcaster/doc/userdoc.rst> - Imu Sensor Broadcaster <../imu_sensor_broadcaster/doc/userdoc.rst> Force Torque Sensor Broadcaster <../force_torque_sensor_broadcaster/doc/userdoc.rst> + Imu Sensor Broadcaster <../imu_sensor_broadcaster/doc/userdoc.rst> + Joint State Broadcaster <../joint_state_broadcaster/doc/userdoc.rst> + Range Sensor Broadcaster <../range_sensor_broadcaster/doc/userdoc.rst> diff --git a/range_sensor_broadcaster/CMakeLists.txt b/range_sensor_broadcaster/CMakeLists.txt new file mode 100644 index 0000000000..00da395db5 --- /dev/null +++ b/range_sensor_broadcaster/CMakeLists.txt @@ -0,0 +1,106 @@ +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() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +set(THIS_PACKAGE_INCLUDE_DEPENDS + controller_interface + generate_parameter_library + hardware_interface + pluginlib + rclcpp + rclcpp_lifecycle + realtime_tools + sensor_msgs +) + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(backward_ros REQUIRED) +foreach(Dependency IN ITEMS ${THIS_PACKAGE_INCLUDE_DEPENDS}) + find_package(${Dependency} REQUIRED) +endforeach() + + +generate_parameter_library(range_sensor_broadcaster_parameters + src/range_sensor_broadcaster_parameters.yaml +) + +add_library( + range_sensor_broadcaster SHARED + src/range_sensor_broadcaster.cpp +) +target_include_directories(range_sensor_broadcaster + PRIVATE $ + PRIVATE $ +) +ament_target_dependencies(range_sensor_broadcaster ${THIS_PACKAGE_INCLUDE_DEPENDS}) +# Causes the visibility macros to use dllexport rather than dllimport, +# which is appropriate when building the dll but not consuming it. +target_compile_definitions(range_sensor_broadcaster PRIVATE "RANGE_SENSOR_BROADCASTER_BUILDING_DLL") +target_link_libraries(range_sensor_broadcaster + range_sensor_broadcaster_parameters +) + +pluginlib_export_plugin_description_file( + controller_interface range_sensor_broadcaster.xml) + +if(BUILD_TESTING) + find_package(ament_cmake_gmock REQUIRED) + find_package(controller_manager REQUIRED) + find_package(hardware_interface REQUIRED) + find_package(ros2_control_test_assets REQUIRED) + + add_rostest_with_parameters_gmock(test_load_range_sensor_broadcaster + test/test_load_range_sensor_broadcaster.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test/range_sensor_broadcaster_params.yaml) + 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 + ) + + add_rostest_with_parameters_gmock(test_range_sensor_broadcaster + test/test_range_sensor_broadcaster.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test/range_sensor_broadcaster_params.yaml) + target_include_directories(test_range_sensor_broadcaster PRIVATE include) + target_link_libraries(test_range_sensor_broadcaster + range_sensor_broadcaster + ) + ament_target_dependencies(test_range_sensor_broadcaster + hardware_interface + ) +endif() + +install( + DIRECTORY include/ + DESTINATION include +) + +install( + TARGETS + range_sensor_broadcaster + range_sensor_broadcaster_parameters + EXPORT export_range_sensor_broadcaster + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + INCLUDES DESTINATION include +) + +ament_export_targets(export_range_sensor_broadcaster HAS_LIBRARY_TARGET) +ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS}) + +ament_package() diff --git a/range_sensor_broadcaster/README.md b/range_sensor_broadcaster/README.md new file mode 100644 index 0000000000..33195d272b --- /dev/null +++ b/range_sensor_broadcaster/README.md @@ -0,0 +1,8 @@ +range_sensor_broadcaster +========================================== + +Controller to publish readings of Range sensors. + +Pluginlib-Library: range_sensor_broadcaster + +Plugin: range_sensor_broadcaster/RangeSensorBroadcaster (controller_interface::ControllerInterface) diff --git a/range_sensor_broadcaster/doc/userdoc.rst b/range_sensor_broadcaster/doc/userdoc.rst new file mode 100644 index 0000000000..e35bec67ad --- /dev/null +++ b/range_sensor_broadcaster/doc/userdoc.rst @@ -0,0 +1,15 @@ +:github_url: https://github.com/ros-controls/ros2_controllers/blob/{REPOS_FILE_BRANCH}/range_sensor_broadcaster/doc/userdoc.rst + +.. _range_sensor_broadcaster_userdoc: + +Range Sensor Broadcaster +-------------------------------- +Broadcaster of messages from Range sensor. +The published message type is ``sensor_msgs/msg/Range``. + +The controller is a wrapper around ``RangeSensor`` semantic component (see ``controller_interface`` package). + +Parameters +^^^^^^^^^^^ + +.. generate_parameter_library_details:: ../src/range_sensor_broadcaster_parameters.yaml 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 new file mode 100644 index 0000000000..b2e5fbfac0 --- /dev/null +++ b/range_sensor_broadcaster/include/range_sensor_broadcaster/range_sensor_broadcaster.hpp @@ -0,0 +1,77 @@ +// Copyright 2021 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. + +/* + * Authors: Subhas Das, Denis Stogl, Victor Lopez + */ + +#ifndef RANGE_SENSOR_BROADCASTER__RANGE_SENSOR_BROADCASTER_HPP_ +#define RANGE_SENSOR_BROADCASTER__RANGE_SENSOR_BROADCASTER_HPP_ + +#include +#include +#include + +#include "controller_interface/controller_interface.hpp" +#include "range_sensor_broadcaster/visibility_control.h" +#include "range_sensor_broadcaster_parameters.hpp" +#include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp" +#include "rclcpp_lifecycle/state.hpp" +#include "realtime_tools/realtime_publisher.h" +#include "semantic_components/range_sensor.hpp" +#include "sensor_msgs/msg/range.hpp" + +namespace range_sensor_broadcaster +{ +class RangeSensorBroadcaster : public controller_interface::ControllerInterface +{ +public: + RANGE_SENSOR_BROADCASTER_PUBLIC + controller_interface::InterfaceConfiguration command_interface_configuration() const override; + + RANGE_SENSOR_BROADCASTER_PUBLIC + controller_interface::InterfaceConfiguration state_interface_configuration() const override; + + RANGE_SENSOR_BROADCASTER_PUBLIC controller_interface::CallbackReturn on_init() override; + + RANGE_SENSOR_BROADCASTER_PUBLIC + controller_interface::CallbackReturn on_configure( + const rclcpp_lifecycle::State & previous_state) override; + + RANGE_SENSOR_BROADCASTER_PUBLIC + controller_interface::CallbackReturn on_activate( + const rclcpp_lifecycle::State & previous_state) override; + + RANGE_SENSOR_BROADCASTER_PUBLIC + controller_interface::CallbackReturn on_deactivate( + const rclcpp_lifecycle::State & previous_state) override; + + RANGE_SENSOR_BROADCASTER_PUBLIC + controller_interface::return_type update( + const rclcpp::Time & time, const rclcpp::Duration & period) override; + +protected: + std::shared_ptr param_listener_; + Params params_; + + std::unique_ptr range_sensor_; + + using StatePublisher = realtime_tools::RealtimePublisher; + rclcpp::Publisher::SharedPtr sensor_state_publisher_; + std::unique_ptr realtime_publisher_; +}; + +} // namespace range_sensor_broadcaster + +#endif // RANGE_SENSOR_BROADCASTER__RANGE_SENSOR_BROADCASTER_HPP_ diff --git a/range_sensor_broadcaster/include/range_sensor_broadcaster/visibility_control.h b/range_sensor_broadcaster/include/range_sensor_broadcaster/visibility_control.h new file mode 100644 index 0000000000..0a9a9f53a8 --- /dev/null +++ b/range_sensor_broadcaster/include/range_sensor_broadcaster/visibility_control.h @@ -0,0 +1,53 @@ +// Copyright (c) 2021, Stogl Robotics Consulting UG (haftungsbeschränkt) +// +// 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. + +/* + * Author: Subhas Das, Denis Stogl + */ + +#ifndef RANGE_SENSOR_BROADCASTER__VISIBILITY_CONTROL_H_ +#define RANGE_SENSOR_BROADCASTER__VISIBILITY_CONTROL_H_ + +// This logic was borrowed (then namespaced) from the examples on the gcc wiki: +// https://gcc.gnu.org/wiki/Visibility + +#if defined _WIN32 || defined __CYGWIN__ +#ifdef __GNUC__ +#define RANGE_SENSOR_BROADCASTER_EXPORT __attribute__((dllexport)) +#define RANGE_SENSOR_BROADCASTER_IMPORT __attribute__((dllimport)) +#else +#define RANGE_SENSOR_BROADCASTER_EXPORT __declspec(dllexport) +#define RANGE_SENSOR_BROADCASTER_IMPORT __declspec(dllimport) +#endif +#ifdef RANGE_SENSOR_BROADCASTER_BUILDING_DLL +#define RANGE_SENSOR_BROADCASTER_PUBLIC RANGE_SENSOR_BROADCASTER_EXPORT +#else +#define RANGE_SENSOR_BROADCASTER_PUBLIC RANGE_SENSOR_BROADCASTER_IMPORT +#endif +#define RANGE_SENSOR_BROADCASTER_PUBLIC_TYPE RANGE_SENSOR_BROADCASTER_PUBLIC +#define RANGE_SENSOR_BROADCASTER_LOCAL +#else +#define RANGE_SENSOR_BROADCASTER_EXPORT __attribute__((visibility("default"))) +#define RANGE_SENSOR_BROADCASTER_IMPORT +#if __GNUC__ >= 4 +#define RANGE_SENSOR_BROADCASTER_PUBLIC __attribute__((visibility("default"))) +#define RANGE_SENSOR_BROADCASTER_LOCAL __attribute__((visibility("hidden"))) +#else +#define RANGE_SENSOR_BROADCASTER_PUBLIC +#define RANGE_SENSOR_BROADCASTER_LOCAL +#endif +#define RANGE_SENSOR_BROADCASTER_PUBLIC_TYPE +#endif + +#endif // RANGE_SENSOR_BROADCASTER__VISIBILITY_CONTROL_H_ diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml new file mode 100644 index 0000000000..11175d9f03 --- /dev/null +++ b/range_sensor_broadcaster/package.xml @@ -0,0 +1,31 @@ + + + + range_sensor_broadcaster + 3.14.0 + Controller to publish readings of Range sensors. + Bence Magyar + Florent Chretien + Apache License 2.0 + + ament_cmake + + backward_ros + controller_interface + generate_parameter_library + hardware_interface + pluginlib + rclcpp + rclcpp_lifecycle + realtime_tools + sensor_msgs + + ament_cmake_gmock + controller_manager + hardware_interface + ros2_control_test_assets + + + ament_cmake + + diff --git a/range_sensor_broadcaster/range_sensor_broadcaster.xml b/range_sensor_broadcaster/range_sensor_broadcaster.xml new file mode 100644 index 0000000000..fd82c7ae25 --- /dev/null +++ b/range_sensor_broadcaster/range_sensor_broadcaster.xml @@ -0,0 +1,8 @@ + + + + This controller publishes the readings of an Range sensor as sensor_msgs/Range message. + + + diff --git a/range_sensor_broadcaster/src/range_sensor_broadcaster.cpp b/range_sensor_broadcaster/src/range_sensor_broadcaster.cpp new file mode 100644 index 0000000000..72fdac3a5e --- /dev/null +++ b/range_sensor_broadcaster/src/range_sensor_broadcaster.cpp @@ -0,0 +1,137 @@ +// Copyright 2021 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. + +/* + * Authors: Subhas Das, Denis Stogl, Victor Lopez + */ + +#include "range_sensor_broadcaster/range_sensor_broadcaster.hpp" + +#include +#include + +namespace range_sensor_broadcaster +{ +controller_interface::CallbackReturn RangeSensorBroadcaster::on_init() +{ + try + { + param_listener_ = std::make_shared(get_node()); + params_ = param_listener_->get_params(); + } + catch (const std::exception & e) + { + RCLCPP_ERROR( + get_node()->get_logger(), "Exception thrown during init stage with message: %s \n", e.what()); + return CallbackReturn::ERROR; + } + + return CallbackReturn::SUCCESS; +} + +controller_interface::CallbackReturn RangeSensorBroadcaster::on_configure( + const rclcpp_lifecycle::State & /*previous_state*/) +{ + params_ = param_listener_->get_params(); + if (params_.sensor_name.empty()) + { + RCLCPP_ERROR(get_node()->get_logger(), "'sensor_name' parameter has to be specified."); + return CallbackReturn::ERROR; + } + + if (params_.frame_id.empty()) + { + RCLCPP_ERROR(get_node()->get_logger(), "'frame_id' parameter has to be provided."); + return CallbackReturn::ERROR; + } + + range_sensor_ = std::make_unique( + semantic_components::RangeSensor(params_.sensor_name)); + try + { + // register ft sensor data publisher + sensor_state_publisher_ = + get_node()->create_publisher("~/range", rclcpp::SystemDefaultsQoS()); + realtime_publisher_ = std::make_unique(sensor_state_publisher_); + } + catch (const std::exception & e) + { + fprintf( + stderr, "Exception thrown during publisher creation at configure stage with message : %s \n", + e.what()); + return CallbackReturn::ERROR; + } + + realtime_publisher_->lock(); + realtime_publisher_->msg_.header.frame_id = params_.frame_id; + realtime_publisher_->msg_.radiation_type = params_.radiation_type; + realtime_publisher_->msg_.field_of_view = params_.field_of_view; + realtime_publisher_->msg_.min_range = params_.min_range; + realtime_publisher_->msg_.max_range = params_.max_range; + realtime_publisher_->unlock(); + + RCLCPP_DEBUG(get_node()->get_logger(), "configure successful"); + return CallbackReturn::SUCCESS; +} + +controller_interface::InterfaceConfiguration +RangeSensorBroadcaster::command_interface_configuration() const +{ + controller_interface::InterfaceConfiguration command_interfaces_config; + command_interfaces_config.type = controller_interface::interface_configuration_type::NONE; + return command_interfaces_config; +} + +controller_interface::InterfaceConfiguration RangeSensorBroadcaster::state_interface_configuration() + const +{ + controller_interface::InterfaceConfiguration state_interfaces_config; + state_interfaces_config.type = controller_interface::interface_configuration_type::INDIVIDUAL; + state_interfaces_config.names = range_sensor_->get_state_interface_names(); + return state_interfaces_config; +} + +controller_interface::CallbackReturn RangeSensorBroadcaster::on_activate( + const rclcpp_lifecycle::State & /*previous_state*/) +{ + range_sensor_->assign_loaned_state_interfaces(state_interfaces_); + return CallbackReturn::SUCCESS; +} + +controller_interface::CallbackReturn RangeSensorBroadcaster::on_deactivate( + const rclcpp_lifecycle::State & /*previous_state*/) +{ + range_sensor_->release_interfaces(); + return CallbackReturn::SUCCESS; +} + +controller_interface::return_type RangeSensorBroadcaster::update( + const rclcpp::Time & time, const rclcpp::Duration & /*period*/) +{ + if (realtime_publisher_ && realtime_publisher_->trylock()) + { + realtime_publisher_->msg_.header.stamp = time; + range_sensor_->get_values_as_message(realtime_publisher_->msg_); + realtime_publisher_->unlockAndPublish(); + } + + return controller_interface::return_type::OK; +} + +} // namespace range_sensor_broadcaster + +#include "pluginlib/class_list_macros.hpp" + +PLUGINLIB_EXPORT_CLASS( + range_sensor_broadcaster::RangeSensorBroadcaster, controller_interface::ControllerInterface) diff --git a/range_sensor_broadcaster/src/range_sensor_broadcaster_parameters.yaml b/range_sensor_broadcaster/src/range_sensor_broadcaster_parameters.yaml new file mode 100644 index 0000000000..c869cc27f2 --- /dev/null +++ b/range_sensor_broadcaster/src/range_sensor_broadcaster_parameters.yaml @@ -0,0 +1,15 @@ +range_sensor_broadcaster: + sensor_name: { + type: string, + default_value: "", + description: "Name of the sensor used as prefix for interfaces if there are no individual interface names defined.", + } + frame_id: { + type: string, + default_value: "", + description: "Sensor's frame_id in which values are published.", + } + radiation_type: {type: int, default_value: 0, description: "The type of radiation used by the sensor / 0 = Ultrason / 1 = Infrared",} + field_of_view: {type: double, default_value: 0.52, description: "The size of the arc that the distance reading is valid for [rad]",} + min_range: {type: double, default_value: 0.52, description: "Minimum range value [m]",} + max_range: {type: double, default_value: 4.0, description: "Maximum range value [m]",} diff --git a/range_sensor_broadcaster/test/range_sensor_broadcaster_params.yaml b/range_sensor_broadcaster/test/range_sensor_broadcaster_params.yaml new file mode 100644 index 0000000000..7dae66a611 --- /dev/null +++ b/range_sensor_broadcaster/test/range_sensor_broadcaster_params.yaml @@ -0,0 +1,11 @@ +test_range_sensor_broadcaster: + ros__parameters: + # Setting mendatory parameters + sensor_name: "range_sensor" + frame_id: "range_sensor_frame" + + # Setting parameters with changed default value to check those are used + radiation_type: 1 + field_of_view: 0.1 + min_range: 0.10 + max_range: 7.0 diff --git a/range_sensor_broadcaster/test/test_load_range_sensor_broadcaster.cpp b/range_sensor_broadcaster/test/test_load_range_sensor_broadcaster.cpp new file mode 100644 index 0000000000..5c400bef91 --- /dev/null +++ b/range_sensor_broadcaster/test/test_load_range_sensor_broadcaster.cpp @@ -0,0 +1,52 @@ +// Copyright (c) 2021, Stogl Robotics Consulting UG (haftungsbeschränkt) +// +// 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. + +/* + * Author: Subhas Das, Denis Stogl, Florent Chretien + */ + +#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(TestLoadRangeSensorBroadcaster, load_controller) +{ + std::shared_ptr executor = + std::make_shared(); + + controller_manager::ControllerManager cm( + std::make_unique( + ros2_control_test_assets::minimal_robot_urdf), + executor, "test_controller_manager"); + + ASSERT_NE( + cm.load_controller( + "test_range_sensor_broadcaster", "range_sensor_broadcaster/RangeSensorBroadcaster"), + nullptr); +} + +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/range_sensor_broadcaster/test/test_range_sensor_broadcaster.cpp b/range_sensor_broadcaster/test/test_range_sensor_broadcaster.cpp new file mode 100644 index 0000000000..02d7de814e --- /dev/null +++ b/range_sensor_broadcaster/test/test_range_sensor_broadcaster.cpp @@ -0,0 +1,247 @@ +// Copyright 2023 flochre +// +// 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: flochre + */ + +#include + +#include "test_range_sensor_broadcaster.hpp" + +#include "hardware_interface/loaned_state_interface.hpp" + +void RangeSensorBroadcasterTest::SetUp() +{ + // initialize controller + range_broadcaster_ = std::make_unique(); +} + +void RangeSensorBroadcasterTest::TearDown() { range_broadcaster_.reset(nullptr); } + +controller_interface::return_type RangeSensorBroadcasterTest::init_broadcaster( + std::string broadcaster_name) +{ + controller_interface::return_type result = controller_interface::return_type::ERROR; + result = range_broadcaster_->init(broadcaster_name); + + if (controller_interface::return_type::OK == result) + { + std::vector state_interfaces; + state_interfaces.emplace_back(range_); + + range_broadcaster_->assign_interfaces({}, std::move(state_interfaces)); + } + + return result; +} + +controller_interface::CallbackReturn RangeSensorBroadcasterTest::configure_broadcaster( + std::vector & parameters) +{ + // Configure the broadcaster + for (auto parameter : parameters) + { + range_broadcaster_->get_node()->set_parameter(parameter); + } + + return range_broadcaster_->on_configure(rclcpp_lifecycle::State()); +} + +void RangeSensorBroadcasterTest::subscribe_and_get_message(sensor_msgs::msg::Range & range_msg) +{ + // create a new subscriber + rclcpp::Node test_subscription_node("test_subscription_node"); + auto subs_callback = [&](const sensor_msgs::msg::Range::SharedPtr) {}; + auto subscription = test_subscription_node.create_subscription( + "/test_range_sensor_broadcaster/range", 10, subs_callback); + + // call update to publish the test value + // since update doesn't guarantee a published message, republish until received + int max_sub_check_loop_count = 5; // max number of tries for pub/sub loop + rclcpp::WaitSet wait_set; // block used to wait on message + wait_set.add_subscription(subscription); + while (max_sub_check_loop_count--) + { + range_broadcaster_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)); + // check if message has been received + if (wait_set.wait(std::chrono::milliseconds(2)).kind() == rclcpp::WaitResultKind::Ready) + { + break; + } + } + ASSERT_GE(max_sub_check_loop_count, 0) << "Test was unable to publish a message through " + "controller/broadcaster update loop"; + + // take message from subscription + rclcpp::MessageInfo msg_info; + ASSERT_TRUE(subscription->take(range_msg, msg_info)); +} + +TEST_F(RangeSensorBroadcasterTest, Initialize_RangeBroadcaster_Exception) +{ + ASSERT_THROW(init_broadcaster(""), std::exception); +} + +TEST_F(RangeSensorBroadcasterTest, Initialize_RangeBroadcaster_Success) +{ + ASSERT_EQ( + init_broadcaster("test_range_sensor_broadcaster"), controller_interface::return_type::OK); +} + +TEST_F(RangeSensorBroadcasterTest, Configure_RangeBroadcaster_Error_1) +{ + // First Test without frame_id ERROR Expected + init_broadcaster("test_range_sensor_broadcaster"); + + std::vector parameters; + // explicitly give an empty sensor name to generate an error + parameters.emplace_back(rclcpp::Parameter("sensor_name", "")); + ASSERT_EQ(configure_broadcaster(parameters), controller_interface::CallbackReturn::ERROR); +} + +TEST_F(RangeSensorBroadcasterTest, Configure_RangeBroadcaster_Error_2) +{ + // Second Test without sensor_name ERROR Expected + init_broadcaster("test_range_sensor_broadcaster"); + + std::vector parameters; + // explicitly give an empty frame_id to generate an error + parameters.emplace_back(rclcpp::Parameter("frame_id", "")); + ASSERT_EQ(configure_broadcaster(parameters), controller_interface::CallbackReturn::ERROR); +} + +TEST_F(RangeSensorBroadcasterTest, Configure_RangeBroadcaster_Success) +{ + // Third Test without sensor_name SUCCESS Expected + init_broadcaster("test_range_sensor_broadcaster"); + + ASSERT_EQ( + range_broadcaster_->on_configure(rclcpp_lifecycle::State()), + controller_interface::CallbackReturn::SUCCESS); +} + +TEST_F(RangeSensorBroadcasterTest, Activate_RangeBroadcaster_Success) +{ + init_broadcaster("test_range_sensor_broadcaster"); + + range_broadcaster_->on_configure(rclcpp_lifecycle::State()); + + ASSERT_EQ( + range_broadcaster_->on_activate(rclcpp_lifecycle::State()), + controller_interface::CallbackReturn::SUCCESS); +} + +TEST_F(RangeSensorBroadcasterTest, Update_RangeBroadcaster_Success) +{ + init_broadcaster("test_range_sensor_broadcaster"); + + range_broadcaster_->on_configure(rclcpp_lifecycle::State()); + ASSERT_EQ( + range_broadcaster_->on_activate(rclcpp_lifecycle::State()), + controller_interface::CallbackReturn::SUCCESS); + auto result = range_broadcaster_->update( + range_broadcaster_->get_node()->get_clock()->now(), rclcpp::Duration::from_seconds(0.01)); + + ASSERT_EQ(result, controller_interface::return_type::OK); +} + +TEST_F(RangeSensorBroadcasterTest, Publish_RangeBroadcaster_Success) +{ + init_broadcaster("test_range_sensor_broadcaster"); + + range_broadcaster_->on_configure(rclcpp_lifecycle::State()); + range_broadcaster_->on_activate(rclcpp_lifecycle::State()); + + sensor_msgs::msg::Range range_msg; + subscribe_and_get_message(range_msg); + + EXPECT_EQ(range_msg.header.frame_id, frame_id_); + EXPECT_THAT(range_msg.range, ::testing::FloatEq(sensor_range_)); + EXPECT_EQ(range_msg.radiation_type, radiation_type_); + EXPECT_THAT(range_msg.field_of_view, ::testing::FloatEq(field_of_view_)); + EXPECT_THAT(range_msg.min_range, ::testing::FloatEq(min_range_)); + EXPECT_THAT(range_msg.max_range, ::testing::FloatEq(max_range_)); +} + +TEST_F(RangeSensorBroadcasterTest, Publish_Bandaries_RangeBroadcaster_Success) +{ + init_broadcaster("test_range_sensor_broadcaster"); + + range_broadcaster_->on_configure(rclcpp_lifecycle::State()); + range_broadcaster_->on_activate(rclcpp_lifecycle::State()); + + sensor_msgs::msg::Range range_msg; + + sensor_range_ = 0.10; + subscribe_and_get_message(range_msg); + + EXPECT_EQ(range_msg.header.frame_id, frame_id_); + EXPECT_THAT(range_msg.range, ::testing::FloatEq(sensor_range_)); + EXPECT_EQ(range_msg.radiation_type, radiation_type_); + EXPECT_THAT(range_msg.field_of_view, ::testing::FloatEq(field_of_view_)); + EXPECT_THAT(range_msg.min_range, ::testing::FloatEq(min_range_)); + EXPECT_THAT(range_msg.max_range, ::testing::FloatEq(max_range_)); + + sensor_range_ = 4.0; + subscribe_and_get_message(range_msg); + + EXPECT_EQ(range_msg.header.frame_id, frame_id_); + EXPECT_THAT(range_msg.range, ::testing::FloatEq(sensor_range_)); + EXPECT_EQ(range_msg.radiation_type, radiation_type_); + EXPECT_THAT(range_msg.field_of_view, ::testing::FloatEq(field_of_view_)); + EXPECT_THAT(range_msg.min_range, ::testing::FloatEq(min_range_)); + EXPECT_THAT(range_msg.max_range, ::testing::FloatEq(max_range_)); +} + +TEST_F(RangeSensorBroadcasterTest, Publish_OutOfBandaries_RangeBroadcaster_Success) +{ + init_broadcaster("test_range_sensor_broadcaster"); + + range_broadcaster_->on_configure(rclcpp_lifecycle::State()); + range_broadcaster_->on_activate(rclcpp_lifecycle::State()); + + sensor_msgs::msg::Range range_msg; + + sensor_range_ = 0.0; + subscribe_and_get_message(range_msg); + + EXPECT_EQ(range_msg.header.frame_id, frame_id_); + // Even out of boundaries you will get the out_of_range range value + EXPECT_THAT(range_msg.range, ::testing::FloatEq(sensor_range_)); + EXPECT_EQ(range_msg.radiation_type, radiation_type_); + EXPECT_THAT(range_msg.field_of_view, ::testing::FloatEq(field_of_view_)); + EXPECT_THAT(range_msg.min_range, ::testing::FloatEq(min_range_)); + EXPECT_THAT(range_msg.max_range, ::testing::FloatEq(max_range_)); + + sensor_range_ = 6.0; + subscribe_and_get_message(range_msg); + + EXPECT_EQ(range_msg.header.frame_id, frame_id_); + // Even out of boundaries you will get the out_of_range range value + EXPECT_THAT(range_msg.range, ::testing::FloatEq(sensor_range_)); + EXPECT_EQ(range_msg.radiation_type, radiation_type_); + EXPECT_THAT(range_msg.field_of_view, ::testing::FloatEq(field_of_view_)); + EXPECT_THAT(range_msg.min_range, ::testing::FloatEq(min_range_)); + EXPECT_THAT(range_msg.max_range, ::testing::FloatEq(max_range_)); +} + +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/range_sensor_broadcaster/test/test_range_sensor_broadcaster.hpp b/range_sensor_broadcaster/test/test_range_sensor_broadcaster.hpp new file mode 100644 index 0000000000..2b38cfa53c --- /dev/null +++ b/range_sensor_broadcaster/test/test_range_sensor_broadcaster.hpp @@ -0,0 +1,58 @@ +// Copyright 2023 flochre +// +// 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: flochre + */ + +#ifndef TEST_RANGE_SENSOR_BROADCASTER_HPP_ +#define TEST_RANGE_SENSOR_BROADCASTER_HPP_ + +#include +#include +#include + +#include "gmock/gmock.h" + +#include "range_sensor_broadcaster/range_sensor_broadcaster.hpp" + +class RangeSensorBroadcasterTest : public ::testing::Test +{ +public: + void SetUp(); + void TearDown(); + +protected: + // for the sake of the test + // defining the parameter names same as in test/range_sensor_broadcaster_params.yaml + const std::string sensor_name_ = "range_sensor"; + const std::string frame_id_ = "range_sensor_frame"; + + const double field_of_view_ = 0.1; + const int radiation_type_ = 1; + const double min_range_ = 0.1; + const double max_range_ = 7.0; + + double sensor_range_ = 3.1; + hardware_interface::StateInterface range_{sensor_name_, "range", &sensor_range_}; + + std::unique_ptr range_broadcaster_; + + controller_interface::return_type init_broadcaster(std::string broadcaster_name); + controller_interface::CallbackReturn configure_broadcaster( + std::vector & parameters); + void subscribe_and_get_message(sensor_msgs::msg::Range & range_msg); +}; + +#endif // TEST_RANGE_SENSOR_BROADCASTER_HPP_ diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 7aa9276267..dfcc283fc0 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -21,6 +21,7 @@ joint_state_broadcaster joint_trajectory_controller position_controllers + range_sensor_broadcaster steering_controllers_library tricycle_controller tricycle_steering_controller From 255b2f9290b7c3c83984ac285fe3572de275c21d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 06:48:44 +0100 Subject: [PATCH 18/39] [Doc] Add specific documentation on the available fw cmd controllers (#765) (#778) --- effort_controllers/doc/userdoc.rst | 40 ++++++++++++++++++++-- forward_command_controller/doc/userdoc.rst | 12 ++++++- position_controllers/doc/userdoc.rst | 40 ++++++++++++++++++++-- velocity_controllers/doc/userdoc.rst | 40 ++++++++++++++++++++-- 4 files changed, 122 insertions(+), 10 deletions(-) diff --git a/effort_controllers/doc/userdoc.rst b/effort_controllers/doc/userdoc.rst index 74caf63391..62e98a75f9 100644 --- a/effort_controllers/doc/userdoc.rst +++ b/effort_controllers/doc/userdoc.rst @@ -7,7 +7,41 @@ effort_controllers This is a collection of controllers that work using the "effort" joint command interface but may accept different joint-level commands at the controller level, e.g. controlling the effort on a certain joint to achieve a set position. -Hardware interface type ------------------------ +The package contains the following controllers: -These controllers work with joints using the "effort" command interface. +effort_controllers/JointGroupEffortController +------------------------------------------------- + +This is specialization of the :ref:`forward_command_controller ` that works using the "effort" joint interface. + + +ROS 2 interface of the controller +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Topics +,,,,,,,,,,,,,,,,,, + +~/commands (input topic) [std_msgs::msg::Float64MultiArray] + Joints' effort commands + + +Parameters +,,,,,,,,,,,,,,,,,, +This controller overrides the interface parameter from :ref:`forward_command_controller `, and the +``joints`` parameter is the only one that is required. + +An example parameter file is given here + +.. code-block:: yaml + + controller_manager: + ros__parameters: + update_rate: 100 # Hz + + effort_controller: + type: effort_controllers/JointGroupEffortController + + effort_controller: + ros__parameters: + joints: + - slider_to_cart diff --git a/forward_command_controller/doc/userdoc.rst b/forward_command_controller/doc/userdoc.rst index a91479c9af..01aa2492a8 100644 --- a/forward_command_controller/doc/userdoc.rst +++ b/forward_command_controller/doc/userdoc.rst @@ -16,8 +16,18 @@ Hardware interface type This controller can be used for every type of command interface. + +ROS 2 interface of the controller +--------------------------------- + +Topics +^^^^^^^ + +~/commands (input topic) [std_msgs::msg::Float64MultiArray] + Target joint commands + Parameters ------------- +^^^^^^^^^^^^^^ This controller uses the `generate_parameter_library `_ to handle its parameters. diff --git a/position_controllers/doc/userdoc.rst b/position_controllers/doc/userdoc.rst index f321e8a698..89766df9d4 100644 --- a/position_controllers/doc/userdoc.rst +++ b/position_controllers/doc/userdoc.rst @@ -7,7 +7,41 @@ position_controllers This is a collection of controllers that work using the "position" joint command interface but may accept different joint-level commands at the controller level, e.g. controlling the position on a certain joint to achieve a set velocity. -Hardware interface type ------------------------ +The package contains the following controllers: -These controllers work with joints using the "position" command interface. +position_controllers/JointGroupPositionController +------------------------------------------------- + +This is specialization of the :ref:`forward_command_controller ` that works using the "position" joint interface. + + +ROS 2 interface of the controller +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Topics +,,,,,,,,,,,,,,,,,, + +~/commands (input topic) [std_msgs::msg::Float64MultiArray] + Joints' position commands + + +Parameters +,,,,,,,,,,,,,,,,,, +This controller overrides the interface parameter from :ref:`forward_command_controller `, and the +``joints`` parameter is the only one that is required. + +An example parameter file is given here + +.. code-block:: yaml + + controller_manager: + ros__parameters: + update_rate: 100 # Hz + + position_controller: + type: position_controllers/JointGroupPositionController + + position_controller: + ros__parameters: + joints: + - slider_to_cart diff --git a/velocity_controllers/doc/userdoc.rst b/velocity_controllers/doc/userdoc.rst index fa7e36062e..469b975a97 100644 --- a/velocity_controllers/doc/userdoc.rst +++ b/velocity_controllers/doc/userdoc.rst @@ -7,7 +7,41 @@ velocity_controllers This is a collection of controllers that work using the "velocity" joint command interface but may accept different joint-level commands at the controller level, e.g. controlling the velocity on a certain joint to achieve a set position. -Hardware interface type ------------------------ +The package contains the following controllers: -These controllers work with joints using the "velocity" command interface. +velocity_controllers/JointGroupVelocityController +------------------------------------------------- + +This is specialization of the :ref:`forward_command_controller ` that works using the "velocity" joint interface. + + +ROS 2 interface of the controller +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Topics +,,,,,,,,,,,,,,,,,, + +~/commands (input topic) [std_msgs::msg::Float64MultiArray] + Joints' velocity commands + + +Parameters +,,,,,,,,,,,,,,,,,, +This controller overrides the interface parameter from :ref:`forward_command_controller `, and the +``joints`` parameter is the only one that is required. + +An example parameter file is given here + +.. code-block:: yaml + + controller_manager: + ros__parameters: + update_rate: 100 # Hz + + velocity_controller: + type: velocity_controllers/JointGroupVelocityController + + velocity_controller: + ros__parameters: + joints: + - slider_to_cart From d92bd9fdf320a7abc88d8960a99bbc07d8773931 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Tue, 3 Oct 2023 19:16:56 +0100 Subject: [PATCH 19/39] 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 | 5 + force_torque_sensor_broadcaster/CHANGELOG.rst | 3 + forward_command_controller/CHANGELOG.rst | 5 + gripper_controllers/CHANGELOG.rst | 3 + imu_sensor_broadcaster/CHANGELOG.rst | 3 + joint_state_broadcaster/CHANGELOG.rst | 3 + joint_trajectory_controller/CHANGELOG.rst | 3 + position_controllers/CHANGELOG.rst | 5 + range_sensor_broadcaster/CHANGELOG.rst | 146 ++++++++++++++++++ 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 | 5 + 20 files changed, 213 insertions(+) create mode 100644 range_sensor_broadcaster/CHANGELOG.rst diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index bc6701ddea..ff77ea12a0 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.25.0 (2023-09-15) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 5d5651cc7f..629fa35833 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.25.0 (2023-09-15) ------------------- * Update docs for diff drive controller (`#751 `_) (`#753 `_) diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 59ffc54431..3d4dbeda53 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.25.0 (2023-09-15) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index d86b43d21e..1ce45529bb 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.25.0 (2023-09-15) ------------------- * removed duplicated previous_publish_timestamp\_ increment by publish_period\_ in diff_drive_controller.cpp (`#644 `_) (`#777 `_) diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 75d86f2ce0..43bb830a84 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) +* Contributors: mergify[bot] + 2.25.0 (2023-09-15) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index a5022ddda2..7cbcce311b 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 +----------- + 2.25.0 (2023-09-15) ------------------- diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index ff3aa46a48..cd0b0c9d03 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) +* Contributors: mergify[bot] + 2.25.0 (2023-09-15) ------------------- * Use tabs (`#743 `_) (`#746 `_) diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index de6f0ae018..ba8ad2ab08 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.25.0 (2023-09-15) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 9e81396179..fd34263f03 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.25.0 (2023-09-15) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 0c9a6ca079..3989aa98f1 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.25.0 (2023-09-15) ------------------- diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index f917646ab4..0d5a99cf8f 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.25.0 (2023-09-15) ------------------- * [JTC] Rename parameter: normalize_error to angle_wraparound (`#772 `_) (`#776 `_) diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index d5017c0cfd..c028c2284f 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) +* Contributors: mergify[bot] + 2.25.0 (2023-09-15) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst new file mode 100644 index 0000000000..1b9c00253e --- /dev/null +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -0,0 +1,146 @@ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Changelog for package range_sensor_broadcaster +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Forthcoming +----------- +* add a broadcaster for range sensor (backport `#725 `_) (`#766 `_) +* Contributors: mergify[bot] + +* add a broadcaster for range sensor (backport `#725 `_) (`#766 `_) +* Contributors: mergify[bot] + +2.25.0 (2023-09-15) +------------------- + +2.24.0 (2023-08-07) +------------------- + +2.23.0 (2023-06-23) +------------------- + +2.22.0 (2023-06-14) +------------------- + +2.21.0 (2023-05-28) +------------------- + +2.20.0 (2023-05-14) +------------------- + +2.19.0 (2023-05-02) +------------------- + +2.18.0 (2023-04-29) +------------------- + +2.17.3 (2023-04-14) +------------------- + +2.17.2 (2023-03-07) +------------------- + +2.17.1 (2023-02-20) +------------------- + +2.17.0 (2023-02-13) +------------------- + +2.16.1 (2023-01-31) +------------------- + +2.16.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/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index a953921f7f..2e7430db84 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* add a broadcaster for range sensor (backport `#725 `_) (`#766 `_) +* Contributors: mergify[bot] + 2.25.0 (2023-09-15) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index f433d23ec0..a13451ebc3 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 +----------- + 2.25.0 (2023-09-15) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index c4690eb802..438fbf5f18 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 +----------- + 2.25.0 (2023-09-15) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 65485d3cc1..ba9a990ae8 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.25.0 (2023-09-15) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index f0a495bbc5..cdcc21521b 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.25.0 (2023-09-15) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 3fef1500fd..bcdf97037c 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.25.0 (2023-09-15) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index f1068397c7..4e5643a4b0 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) +* Contributors: mergify[bot] + 2.25.0 (2023-09-15) ------------------- From 8a9f1c5cc319fdbead8cf3fdc1a7825b2662c9ef Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Tue, 3 Oct 2023 19:18:17 +0100 Subject: [PATCH 20/39] Fix version --- range_sensor_broadcaster/package.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index 11175d9f03..6ac99ea9c2 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 3.14.0 + 2.25.0 Controller to publish readings of Range sensors. Bence Magyar Florent Chretien From 8f33ba8363bfac84adaf362244b430785fac91dc Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Tue, 3 Oct 2023 19:20:07 +0100 Subject: [PATCH 21/39] Fix changelog --- range_sensor_broadcaster/CHANGELOG.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 1b9c00253e..40ccb58c39 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -7,9 +7,6 @@ Forthcoming * add a broadcaster for range sensor (backport `#725 `_) (`#766 `_) * Contributors: mergify[bot] -* add a broadcaster for range sensor (backport `#725 `_) (`#766 `_) -* Contributors: mergify[bot] - 2.25.0 (2023-09-15) ------------------- From 5e1e69577ea0629c17fa067e636ed7133f2a847c Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Tue, 3 Oct 2023 19:21:08 +0100 Subject: [PATCH 22/39] 2.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 +- 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 +- 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 +- 42 files changed, 62 insertions(+), 62 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index ff77ea12a0..ced65a969e 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index 8b26cf563b..47fecc4d99 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 2.25.0 + 2.26.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Apache License 2.0 Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 629fa35833..4819e5cc46 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index da34ea8bff..a091650744 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 2.25.0 + 2.26.0 Implementation of admittance controllers for different input and output interface. Denis Štogl Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 3d4dbeda53..fa23748571 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index e6715f62f8..edaac64615 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 2.25.0 + 2.26.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 1ce45529bb..0997d46618 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 00cbf9a82d..7e86f93f34 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 2.25.0 + 2.26.0 Controller for a differential drive mobile base. Bence Magyar Jordan Palacios diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 43bb830a84..27b6852d2b 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- * [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) * Contributors: mergify[bot] diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index a4d8c0ba5a..624627bad8 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 2.25.0 + 2.26.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 7cbcce311b..88a00dc3af 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 ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index d13841e5bb..af8eabff1c 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 2.25.0 + 2.26.0 Controller to publish state of force-torque sensors. Bence Magyar Denis Štogl diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index cd0b0c9d03..b2f9fd9f41 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- * [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) * Contributors: mergify[bot] diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index 76e3440e13..9b8c96d168 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 2.25.0 + 2.26.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index ba8ad2ab08..bbb147b6cf 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index 12c0160fea..f59f8b87bf 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 2.25.0 + 2.26.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index fd34263f03..237adf55f2 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index 5756550cad..fca4a4e0a8 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 2.25.0 + 2.26.0 Controller to publish readings of IMU sensors. Bence Magyar Denis Štogl diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 3989aa98f1..55238cb00e 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index b1aca75b35..da29197003 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 2.25.0 + 2.26.0 Broadcaster to publish joint state Bence Magyar Denis Stogl diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 0d5a99cf8f..4eb740fab4 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index cbf5e753c0..daaac01c6f 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 2.25.0 + 2.26.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar Jordan Palacios diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index c028c2284f..640854f6fc 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- * [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) * Contributors: mergify[bot] diff --git a/position_controllers/package.xml b/position_controllers/package.xml index f756afd791..1d4784bf57 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 2.25.0 + 2.26.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 40ccb58c39..864dc5cc74 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- * add a broadcaster for range sensor (backport `#725 `_) (`#766 `_) * Contributors: mergify[bot] diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index 6ac99ea9c2..02c28f3249 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 2.25.0 + 2.26.0 Controller to publish readings of Range sensors. Bence Magyar Florent Chretien diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 2e7430db84..bf72ef0f3e 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- * add a broadcaster for range sensor (backport `#725 `_) (`#766 `_) * Contributors: mergify[bot] diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index dfcc283fc0..d4619152b3 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 2.25.0 + 2.26.0 Metapackage for ROS2 controllers related packages Bence Magyar Jordan Palacios diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index a13451ebc3..aa57ca5a30 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 ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 0f17d8ffc9..33dfea64ec 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 2.25.0 + 2.26.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Denis Štogl diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index 3f007e2b7b..bc709cf082 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="2.25.0", + version="2.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 438fbf5f18..36ff0cb38d 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 ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 6088522566..d7e2b3ca99 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 - 2.25.0 + 2.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 52d9ea5742..e2c1700f59 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -7,7 +7,7 @@ setup( name=package_name, - version="2.25.0", + version="2.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 ba9a990ae8..fbfa4b7f20 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index 3af601dbe4..ecd1dd8e30 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 2.25.0 + 2.26.0 Package for steering robot configurations including odometry and interfaces. Apache License 2.0 Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index cdcc21521b..d475d17442 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index a2f84a7877..0edee1d7b9 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 2.25.0 + 2.26.0 Controller for a tricycle drive mobile base Bence Magyar Tony Najjar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index bcdf97037c..fdd4e1ec06 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- 2.25.0 (2023-09-15) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index c83393da47..d55635f9a4 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 2.25.0 + 2.26.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 4e5643a4b0..3c19d10445 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.26.0 (2023-10-03) +------------------- * [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) * Contributors: mergify[bot] diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index eb566d04b8..04ce93fa30 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 2.25.0 + 2.26.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios From fdec988abb604c0ffefd26f8a12ba5bc448fc7d1 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 5 Oct 2023 20:26:12 +0100 Subject: [PATCH 23/39] Improve docs (#785) (#786) --- ackermann_steering_controller/doc/userdoc.rst | 2 ++ bicycle_steering_controller/doc/userdoc.rst | 2 ++ .../src/steering_controllers_library.yaml | 12 ++++++------ tricycle_steering_controller/doc/userdoc.rst | 2 ++ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ackermann_steering_controller/doc/userdoc.rst b/ackermann_steering_controller/doc/userdoc.rst index c4ae35e5b0..daf4561861 100644 --- a/ackermann_steering_controller/doc/userdoc.rst +++ b/ackermann_steering_controller/doc/userdoc.rst @@ -19,4 +19,6 @@ This controller uses the `generate_parameter_library `, this controller adds the following parameters: + .. generate_parameter_library_details:: ../src/ackermann_steering_controller.yaml diff --git a/bicycle_steering_controller/doc/userdoc.rst b/bicycle_steering_controller/doc/userdoc.rst index a720ff887d..6fccaf7b73 100644 --- a/bicycle_steering_controller/doc/userdoc.rst +++ b/bicycle_steering_controller/doc/userdoc.rst @@ -20,4 +20,6 @@ This controller uses the `generate_parameter_library `, this controller adds the following parameters: + .. generate_parameter_library_details:: ../src/bicycle_steering_controller.yaml diff --git a/steering_controllers_library/src/steering_controllers_library.yaml b/steering_controllers_library/src/steering_controllers_library.yaml index 86acb01dae..8acdfb1448 100644 --- a/steering_controllers_library/src/steering_controllers_library.yaml +++ b/steering_controllers_library/src/steering_controllers_library.yaml @@ -59,7 +59,7 @@ steering_controllers_library: open_loop: { type: bool, default_value: false, - description: "bool parameter decides if open oop or not (feedback).", + description: "Choose if open-loop or not (feedback) is used for odometry calculation.", read_only: false, } @@ -87,7 +87,7 @@ steering_controllers_library: enable_odom_tf: { type: bool, default_value: true, - description: "Publishing to tf is enabled or disabled ?.", + description: "Publishing to tf is enabled or disabled?", read_only: false, } @@ -108,15 +108,15 @@ steering_controllers_library: position_feedback: { type: bool, default_value: false, - description: "Choice of feedback type, if position_feedback is false then HW_IF_VELOCITY is taken as interface type, if - position_feedback is true then HW_IF_POSITION is taken as interface type", + description: "Choice of feedback type, if position_feedback is false then ``HW_IF_VELOCITY`` is taken as interface type, if + position_feedback is true then ``HW_IF_POSITION`` is taken as interface type", read_only: false, } use_stamped_vel: { type: bool, default_value: false, - description: "Choice of vel type, if use_stamped_vel is false then geometry_msgs::msg::Twist is taken as vel msg type, if - use_stamped_vel is true then geometry_msgs::msg::TwistStamped is taken as vel msg type", + description: "Choice of vel type, if use_stamped_vel is false then ``geometry_msgs::msg::Twist`` is taken as vel msg type, if + use_stamped_vel is true then ``geometry_msgs::msg::TwistStamped`` is taken as vel msg type", read_only: false, } diff --git a/tricycle_steering_controller/doc/userdoc.rst b/tricycle_steering_controller/doc/userdoc.rst index d76f489745..618d7f04a7 100644 --- a/tricycle_steering_controller/doc/userdoc.rst +++ b/tricycle_steering_controller/doc/userdoc.rst @@ -19,4 +19,6 @@ This controller uses the `generate_parameter_library `, this controller adds the following parameters: + .. generate_parameter_library_details:: ../src/tricycle_steering_controller.yaml From 7dfdcaa497ecdc1f2124ce364c138c2eb005b3a2 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 7 Oct 2023 09:54:44 +0100 Subject: [PATCH 24/39] writing_new_controller docs fix (#790) (#791) --- doc/writing_new_controller.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/writing_new_controller.rst b/doc/writing_new_controller.rst index 6138fdecfd..5d8797628e 100644 --- a/doc/writing_new_controller.rst +++ b/doc/writing_new_controller.rst @@ -34,10 +34,12 @@ The following is a step-by-step guide to create source files, basic tests, and c 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., + .. code:: c++ - class ControllerName : public controller_interface::ControllerInterface - 5. Add a constructor without parameters and the following public methods overriding the ``ControllerInterface`` definition: ``init``, ``command_interface_configuration``, ``state_interface_configuration``, ``on_configure``, ``on_activate``, ``on_deactivate``, ``update``. + class ControllerName : public controller_interface::ControllerInterface + + 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 `_. 6. (optional) Often, controllers accept lists of joint names and interface names as parameters. @@ -48,9 +50,9 @@ The following is a step-by-step guide to create source files, basic tests, and c 1. Include the header file of your controller and add a namespace definition to simplify further development. 2. (optional) Implement a constructor if needed. There, you could initialize member variables. - This could also be done in the ``init`` method. + This could also be done in the ``on_init`` method. - 3. Implement the ``init`` method. The first line usually calls the parent ``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. 4. Write the ``on_configure`` method. Parameters are usually read here, and everything is prepared so that the controller can be started. @@ -105,6 +107,7 @@ The following is a step-by-step guide to create source files, basic tests, and c 4. Add ament dependencies needed by the library. You should add at least those listed under 1. 5. Export for pluginlib description file using the following command: + .. code:: cmake pluginlib_export_plugin_description_file(controller_interface .xml) From dc5b3b4c10a2b16ab3e0bd8c9987c73d91d4e8b3 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:47:56 +0000 Subject: [PATCH 25/39] Steering controllers library: fix open loop mode (#793) (#800) --- .../steering_controllers_library/steering_odometry.hpp | 3 ++- .../src/steering_controllers_library.cpp | 7 ++++--- steering_controllers_library/src/steering_odometry.cpp | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/steering_controllers_library/include/steering_controllers_library/steering_odometry.hpp b/steering_controllers_library/include/steering_controllers_library/steering_odometry.hpp index 00516b716f..25d0235818 100644 --- a/steering_controllers_library/include/steering_controllers_library/steering_odometry.hpp +++ b/steering_controllers_library/include/steering_controllers_library/steering_odometry.hpp @@ -184,7 +184,8 @@ class SteeringOdometry * \param theta_dot Desired angular velocity [rad/s] * \return Tuple of velocity commands and steering commands */ - std::tuple, std::vector> get_commands(double Vx, double theta_dot); + std::tuple, std::vector> get_commands( + const double Vx, const double theta_dot); /** * \brief Reset poses, heading, and accumulators diff --git a/steering_controllers_library/src/steering_controllers_library.cpp b/steering_controllers_library/src/steering_controllers_library.cpp index 179fc39869..26207d54b7 100644 --- a/steering_controllers_library/src/steering_controllers_library.cpp +++ b/steering_controllers_library/src/steering_controllers_library.cpp @@ -448,10 +448,11 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c if (!std::isnan(reference_interfaces_[0]) && !std::isnan(reference_interfaces_[1])) { // store and set commands - const double linear_command = reference_interfaces_[0]; - const double angular_command = reference_interfaces_[1]; + last_linear_velocity_ = reference_interfaces_[0]; + last_angular_velocity_ = reference_interfaces_[1]; + auto [traction_commands, steering_commands] = - odometry_.get_commands(linear_command, angular_command); + odometry_.get_commands(last_linear_velocity_, last_angular_velocity_); if (params_.front_steering) { for (size_t i = 0; i < params_.rear_wheels_names.size(); i++) diff --git a/steering_controllers_library/src/steering_odometry.cpp b/steering_controllers_library/src/steering_odometry.cpp index 98a4f656f4..e8c3965b3f 100644 --- a/steering_controllers_library/src/steering_odometry.cpp +++ b/steering_controllers_library/src/steering_odometry.cpp @@ -212,7 +212,7 @@ double SteeringOdometry::convert_trans_rot_vel_to_steering_angle(double Vx, doub } std::tuple, std::vector> SteeringOdometry::get_commands( - double Vx, double theta_dot) + const double Vx, const double theta_dot) { // desired velocity and steering angle of the middle of traction and steering axis double Ws, alpha; From cc84c5ba0c4f8256d95a7ed6be77b114a9a28b16 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 10 Nov 2023 11:08:24 +0000 Subject: [PATCH 26/39] [diff_drive_controller] Fixed typos in diff_drive_controller_parameter.yaml. (#822) (#823) (cherry picked from commit 0196eeb29ad0e2c908b547f57d31a8a1ea13e869) Co-authored-by: Tony Baltovski --- .../src/diff_drive_controller_parameter.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/diff_drive_controller/src/diff_drive_controller_parameter.yaml b/diff_drive_controller/src/diff_drive_controller_parameter.yaml index f909b27e8b..7541f61d59 100644 --- a/diff_drive_controller/src/diff_drive_controller_parameter.yaml +++ b/diff_drive_controller/src/diff_drive_controller_parameter.yaml @@ -17,7 +17,7 @@ diff_drive_controller: wheels_per_side: { type: int, default_value: 0, - description: "Number of wheels on each wide of the robot. This is important to take the wheels slip into account when multiple wheels on each side are present. If there are more wheels then control signals for each side, you should enter number or control signals. For example, Husky has two wheels on each side, but they use one control signal, in this case '1' is the correct value of the parameter.", + description: "Number of wheels on each side of the robot. This is important to take the wheels slip into account when multiple wheels on each side are present. If there are more wheels then control signals for each side, you should enter number for control signals. For example, Husky has two wheels on each side, but they use one control signal, in this case '1' is the correct value of the parameter.", } wheel_radius: { type: double, @@ -77,7 +77,7 @@ diff_drive_controller: cmd_vel_timeout: { type: double, default_value: 0.5, # seconds - description: "Timeout after which input command on ``cmd_vel`` topic is considered staled.", + description: "Timeout in seconds, after which input command on ``cmd_vel`` topic is considered staled.", } publish_limited_velocity: { type: bool, From 6d75314400ddc781a73a3c471e5c7ed26129f6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Sun, 12 Nov 2023 07:24:54 +0100 Subject: [PATCH 27/39] [CI] Codecov humble (backport #819) (#830) --- .../workflows/ci-coverage-build-humble.yml | 65 +++++++++++++++++++ .../reusable-ros-tooling-source-build.yml | 19 ++++++ README.md | 3 + 3 files changed, 87 insertions(+) create mode 100644 .github/workflows/ci-coverage-build-humble.yml diff --git a/.github/workflows/ci-coverage-build-humble.yml b/.github/workflows/ci-coverage-build-humble.yml new file mode 100644 index 0000000000..46922ccaac --- /dev/null +++ b/.github/workflows/ci-coverage-build-humble.yml @@ -0,0 +1,65 @@ +name: Coverage Build - Humble +on: + workflow_dispatch: + push: + branches: + - humble + pull_request: + branches: + - humble + +jobs: + coverage: + name: coverage build + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + env: + ROS_DISTRO: humble + steps: + - uses: ros-tooling/setup-ros@0.7.0 + with: + required-ros-distributions: ${{ env.ROS_DISTRO }} + - uses: actions/checkout@v4 + - uses: ros-tooling/action-ros-ci@0.3.4 + with: + target-ros2-distro: ${{ env.ROS_DISTRO }} + import-token: ${{ secrets.GITHUB_TOKEN }} + # build all packages listed here + package-name: + ackermann_steering_controller + admittance_controller + bicycle_steering_controller + diff_drive_controller + effort_controllers + force_torque_sensor_broadcaster + forward_command_controller + gripper_controllers + imu_sensor_broadcaster + joint_state_broadcaster + joint_trajectory_controller + position_controllers + range_sensor_broadcaster + steering_controllers_library + tricycle_controller + tricycle_steering_controller + velocity_controllers + + vcs-repo-file-url: | + https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}/ros2_controllers.${{ env.ROS_DISTRO }}.repos?token=${{ secrets.GITHUB_TOKEN }} + colcon-defaults: | + { + "build": { + "mixin": ["coverage-gcc"] + } + } + colcon-mixin-repository: https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml + - uses: codecov/codecov-action@v3.1.4 + with: + file: ros_ws/lcov/total_coverage.info + flags: unittests + name: codecov-umbrella + - uses: actions/upload-artifact@v3.1.3 + with: + name: colcon-logs-coverage-humble + path: ros_ws/log diff --git a/.github/workflows/reusable-ros-tooling-source-build.yml b/.github/workflows/reusable-ros-tooling-source-build.yml index 2ad549b0f8..1dc51cca27 100644 --- a/.github/workflows/reusable-ros-tooling-source-build.yml +++ b/.github/workflows/reusable-ros-tooling-source-build.yml @@ -37,7 +37,26 @@ jobs: target-ros2-distro: ${{ inputs.ros_distro }} # build all packages listed in the meta package package-name: + ackermann_steering_controller + admittance_controller + bicycle_steering_controller diff_drive_controller + effort_controllers + force_torque_sensor_broadcaster + forward_command_controller + gripper_controllers + imu_sensor_broadcaster + joint_state_broadcaster + joint_trajectory_controller + position_controllers + range_sensor_broadcaster + ros2_controllers + ros2_controllers_test_nodes + rqt_joint_trajectory_controller + steering_controllers_library + tricycle_controller + tricycle_steering_controller + velocity_controllers vcs-repo-file-url: | https://raw.githubusercontent.com/ros2/ros2/${{ inputs.ros2_repo_branch }}/ros2.repos diff --git a/README.md b/README.md index 6a59d0054e..f1da78fc92 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # ros2_controllers +[![Licence](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/branch/humble/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 Navigation2. ## Build status From 52e01e2feef964c8a3503b48d49b471fb0e73696 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Tue, 14 Nov 2023 12:13:17 +0000 Subject: [PATCH 28/39] Update changelogs --- ackermann_steering_controller/CHANGELOG.rst | 5 +++++ admittance_controller/CHANGELOG.rst | 3 +++ bicycle_steering_controller/CHANGELOG.rst | 5 +++++ diff_drive_controller/CHANGELOG.rst | 5 +++++ effort_controllers/CHANGELOG.rst | 3 +++ force_torque_sensor_broadcaster/CHANGELOG.rst | 3 +++ forward_command_controller/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 +++ 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 | 6 ++++++ tricycle_controller/CHANGELOG.rst | 3 +++ tricycle_steering_controller/CHANGELOG.rst | 5 +++++ velocity_controllers/CHANGELOG.rst | 3 +++ 20 files changed, 71 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index ced65a969e..cbc70a9988 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Improve docs (`#785 `_) (`#786 `_) +* Contributors: mergify[bot] + 2.26.0 (2023-10-03) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 4819e5cc46..68f156e73a 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index fa23748571..6b36a665bb 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Improve docs (`#785 `_) (`#786 `_) +* Contributors: mergify[bot] + 2.26.0 (2023-10-03) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 0997d46618..c067289973 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* [diff_drive_controller] Fixed typos in diff_drive_controller_parameter.yaml. (`#822 `_) (`#823 `_) +* Contributors: Tony Baltovski + 2.26.0 (2023-10-03) ------------------- diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 27b6852d2b..97b4498685 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- * [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 88a00dc3af..e3f65808ed 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 +----------- + 2.26.0 (2023-10-03) ------------------- diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index b2f9fd9f41..e1f18d8351 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- * [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index bbb147b6cf..e2f4449647 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 237adf55f2..055451f826 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 55238cb00e..8eb2fcfcb9 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 4eb740fab4..81b4c99587 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 640854f6fc..fc32d5025c 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- * [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 864dc5cc74..abda4bede3 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- * add a broadcaster for range sensor (backport `#725 `_) (`#766 `_) diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index bf72ef0f3e..769defb706 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- * add a broadcaster for range sensor (backport `#725 `_) (`#766 `_) diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index aa57ca5a30..cd7ecf11b3 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 +----------- + 2.26.0 (2023-10-03) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 36ff0cb38d..6d60f1da96 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 +----------- + 2.26.0 (2023-10-03) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index fbfa4b7f20..85bdf8926c 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Steering controllers library: fix open loop mode (`#793 `_) (`#800 `_) +* Improve docs (`#785 `_) (`#786 `_) +* Contributors: mergify[bot] + 2.26.0 (2023-10-03) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index d475d17442..3c40e4b010 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index fdd4e1ec06..2954918d69 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Improve docs (`#785 `_) (`#786 `_) +* Contributors: mergify[bot] + 2.26.0 (2023-10-03) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 3c19d10445..8f029d4410 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.26.0 (2023-10-03) ------------------- * [Doc] Add specific documentation on the available fw cmd controllers (`#765 `_) (`#778 `_) From bc66e1b493118abb7a6c82603a5e05b61ed7afa1 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Tue, 14 Nov 2023 12:13:58 +0000 Subject: [PATCH 29/39] 2.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 +- 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 +- 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 +- 42 files changed, 62 insertions(+), 62 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index cbc70a9988..6c20cdb2a8 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- * Improve docs (`#785 `_) (`#786 `_) * Contributors: mergify[bot] diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index 47fecc4d99..845b542fd7 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 2.26.0 + 2.27.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Apache License 2.0 Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 68f156e73a..22059fa82c 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index a091650744..121d63a396 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 2.26.0 + 2.27.0 Implementation of admittance controllers for different input and output interface. Denis Štogl Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 6b36a665bb..be27da6c2d 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- * Improve docs (`#785 `_) (`#786 `_) * Contributors: mergify[bot] diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index edaac64615..209c6a9bbd 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 2.26.0 + 2.27.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index c067289973..093b929eb3 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- * [diff_drive_controller] Fixed typos in diff_drive_controller_parameter.yaml. (`#822 `_) (`#823 `_) * Contributors: Tony Baltovski diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 7e86f93f34..63ce46b56e 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 2.26.0 + 2.27.0 Controller for a differential drive mobile base. Bence Magyar Jordan Palacios diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 97b4498685..000d794453 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index 624627bad8..fd1b5d9659 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 2.26.0 + 2.27.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index e3f65808ed..692f8f48ef 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 ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index af8eabff1c..5b6bc83a77 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 2.26.0 + 2.27.0 Controller to publish state of force-torque sensors. Bence Magyar Denis Štogl diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index e1f18d8351..a99c267929 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index 9b8c96d168..a316b8cb40 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 2.26.0 + 2.27.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index e2f4449647..8c86a385de 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index f59f8b87bf..e47ddc03d6 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 2.26.0 + 2.27.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 055451f826..204177c217 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index fca4a4e0a8..cedfb2f30d 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 2.26.0 + 2.27.0 Controller to publish readings of IMU sensors. Bence Magyar Denis Štogl diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 8eb2fcfcb9..517d0ffd41 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index da29197003..f1dd261705 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 2.26.0 + 2.27.0 Broadcaster to publish joint state Bence Magyar Denis Stogl diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 81b4c99587..8d4b439535 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index daaac01c6f..ee6b4f2e64 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 2.26.0 + 2.27.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar Jordan Palacios diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index fc32d5025c..6a4f4b9de7 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index 1d4784bf57..a777165a43 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 2.26.0 + 2.27.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index abda4bede3..f803e222be 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index 02c28f3249..fc8754fb15 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 2.26.0 + 2.27.0 Controller to publish readings of Range sensors. Bence Magyar Florent Chretien diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 769defb706..25373d4324 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index d4619152b3..2561c54ad5 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 2.26.0 + 2.27.0 Metapackage for ROS2 controllers related packages Bence Magyar Jordan Palacios diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index cd7ecf11b3..49e388d82f 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 ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 33dfea64ec..40ec8f7cac 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 2.26.0 + 2.27.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Denis Štogl diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index bc709cf082..47495a345a 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="2.26.0", + version="2.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 6d60f1da96..91c0a0c95a 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 ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index d7e2b3ca99..717b7239d6 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 - 2.26.0 + 2.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 e2c1700f59..e406d9e57a 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -7,7 +7,7 @@ setup( name=package_name, - version="2.26.0", + version="2.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 85bdf8926c..bab0eaf741 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- * Steering controllers library: fix open loop mode (`#793 `_) (`#800 `_) * Improve docs (`#785 `_) (`#786 `_) * Contributors: mergify[bot] diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index ecd1dd8e30..e462a53ac4 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 2.26.0 + 2.27.0 Package for steering robot configurations including odometry and interfaces. Apache License 2.0 Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 3c40e4b010..bc4f4b6ba8 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index 0edee1d7b9..01daa4e5e2 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 2.26.0 + 2.27.0 Controller for a tricycle drive mobile base Bence Magyar Tony Najjar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 2954918d69..0b8f4a7489 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- * Improve docs (`#785 `_) (`#786 `_) * Contributors: mergify[bot] diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index d55635f9a4..cabae83905 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 2.26.0 + 2.27.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 8f029d4410..e294117c05 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.27.0 (2023-11-14) +------------------- 2.26.0 (2023-10-03) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index 04ce93fa30..84a083d576 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 2.26.0 + 2.27.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios From 71b166ec067105eeddd528d764101ad63b33c5e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Fri, 17 Nov 2023 11:32:48 +0100 Subject: [PATCH 30/39] Ignore test code for codecov (#844) --- codecov.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/codecov.yml b/codecov.yml index 02deea2321..ca8c1cc0ac 100644 --- a/codecov.yml +++ b/codecov.yml @@ -9,6 +9,8 @@ coverage: patch: off fixes: - "ros_ws/src/ros2_controllers/::" +ignore: + - "**/test" comment: layout: "diff, flags, files" behavior: default From d7c41b329751c72d863fa23aa73d70ee9dfdb4ec Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 17:55:21 +0000 Subject: [PATCH 31/39] Rearrange controllers overview page (#846) (#847) --- README.md | 2 +- doc/controllers_index.rst | 55 ++++++++++++---------- forward_command_controller/doc/userdoc.rst | 2 +- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index f1da78fc92..d8091e0b63 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Licence](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/branch/humble/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 Navigation2. +Commonly used and generalized controllers for ros2-control framework that are ready to use with many robots, MoveIt2 and Nav2. ## Build status diff --git a/doc/controllers_index.rst b/doc/controllers_index.rst index de33c3284c..9fceb90fd3 100644 --- a/doc/controllers_index.rst +++ b/doc/controllers_index.rst @@ -6,24 +6,9 @@ ros2_controllers ################# -`GitHub Repository `_ - - -Nomenclature -************ - -The ros2_control framework uses namespaces to sort controller according to the type of command interface they are using. -The controllers are using `common hardware interface definitions`_. -The controllers' namespaces are commanding the following command interface types: - - - ``position_controllers``: ``hardware_interface::HW_IF_POSITION`` - - ``velocity_controller``: ``hardware_interface::HW_IF_VELOCITY`` - - ``effort_controllers``: ``hardware_interface::HW_IF_ACCELERATION`` - - ``effort_controllers``: ``hardware_interface::HW_IF_EFFORT`` - - ... - -.. _common hardware interface definitions: https://github.com/ros-controls/ros2_control/blob/{REPOS_FILE_BRANCH}/hardware_interface/include/hardware_interface/types/hardware_interface_type_values.hpp +Commonly used and generalized controllers for ros2_control framework that are ready to use with many robots, `MoveIt2 `_ and `Nav2 `_. +`Link to GitHub Repository `_ Guidelines and Best Practices @@ -36,34 +21,54 @@ Guidelines and Best Practices * -Available Controllers -********************* +Controllers for Mobile Robots +***************************** .. toctree:: :titlesonly: Ackermann Steering Controller <../ackermann_steering_controller/doc/userdoc.rst> - Admittance Controller <../admittance_controller/doc/userdoc.rst> Bicycle Steering Controller <../bicycle_steering_controller/doc/userdoc.rst> Differential Drive Controller <../diff_drive_controller/doc/userdoc.rst> + Steering Controllers Library <../steering_controllers_library/doc/userdoc.rst> + Tricycle Controller <../tricycle_controller/doc/userdoc.rst> + Tricycle Steering Controller <../tricycle_steering_controller/doc/userdoc.rst> + +Controllers for Manipulators and Other Robots +********************************************* + +The controllers are using `common hardware interface definitions`_, and may use namespaces depending on the following command interface types: + + - ``position_controllers``: ``hardware_interface::HW_IF_POSITION`` + - ``velocity_controller``: ``hardware_interface::HW_IF_VELOCITY`` + - ``effort_controllers``: ``hardware_interface::HW_IF_ACCELERATION`` + - ``effort_controllers``: ``hardware_interface::HW_IF_EFFORT`` + +.. _common hardware interface definitions: https://github.com/ros-controls/ros2_control/blob/{REPOS_FILE_BRANCH}/hardware_interface/include/hardware_interface/types/hardware_interface_type_values.hpp + + +.. toctree:: + :titlesonly: + + Admittance Controller <../admittance_controller/doc/userdoc.rst> Effort Controllers <../effort_controllers/doc/userdoc.rst> Forward Command Controller <../forward_command_controller/doc/userdoc.rst> Gripper Controller <../gripper_controllers/doc/userdoc.rst> Joint Trajectory Controller <../joint_trajectory_controller/doc/userdoc.rst> Position Controllers <../position_controllers/doc/userdoc.rst> - Steering Controllers Library <../steering_controllers_library/doc/userdoc.rst> - Tricycle Controller <../tricycle_controller/doc/userdoc.rst> - Tricycle Steering Controller <../tricycle_steering_controller/doc/userdoc.rst> Velocity Controllers <../velocity_controllers/doc/userdoc.rst> -Available Broadcasters +Broadcasters ********************** +Broadcasters are used to publish sensor data from hardware components to ROS topics. +In the sense of ros2_control, broadcasters are still controllers using the same controller interface as the other controllers above. + .. toctree:: :titlesonly: Force Torque Sensor Broadcaster <../force_torque_sensor_broadcaster/doc/userdoc.rst> - Imu Sensor Broadcaster <../imu_sensor_broadcaster/doc/userdoc.rst> + IMU Sensor Broadcaster <../imu_sensor_broadcaster/doc/userdoc.rst> Joint State Broadcaster <../joint_state_broadcaster/doc/userdoc.rst> Range Sensor Broadcaster <../range_sensor_broadcaster/doc/userdoc.rst> diff --git a/forward_command_controller/doc/userdoc.rst b/forward_command_controller/doc/userdoc.rst index 01aa2492a8..cd623a5acb 100644 --- a/forward_command_controller/doc/userdoc.rst +++ b/forward_command_controller/doc/userdoc.rst @@ -5,7 +5,7 @@ forward_command_controller ========================== -This is a base class implementing a feedforward controller. Specific implementations can be found in: +This is a base class implementing a feedforward controller. Specific implementations of this base class can be found in: * :ref:`position_controllers_userdoc` * :ref:`velocity_controllers_userdoc` From b4b465d62396c4e8ed64b551231225d8e710cc3c Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 13:56:24 +0000 Subject: [PATCH 32/39] joint_state_broadcaster: Add proper subscription to TestCustomInterfaceMappingUpdate (#859) (#863) --- .../test/test_joint_state_broadcaster.cpp | 21 +++++++++---------- .../test/test_joint_state_broadcaster.hpp | 3 +++ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp b/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp index 7f95e232e2..98dac68924 100644 --- a/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp +++ b/joint_state_broadcaster/test/test_joint_state_broadcaster.cpp @@ -531,19 +531,12 @@ TEST_F(JointStateBroadcasterTest, TestCustomInterfaceMappingUpdate) state_broadcaster_->get_node()->set_parameter( {std::string("map_interface_to_joint_state.") + HW_IF_POSITION, custom_interface_name_}); - // configure ok - ASSERT_EQ(state_broadcaster_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS); - - ASSERT_EQ(state_broadcaster_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS); - - ASSERT_EQ( - state_broadcaster_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)), - controller_interface::return_type::OK); + sensor_msgs::msg::JointState joint_state_msg; + activate_and_get_joint_state_message("joint_states", joint_state_msg); const size_t NUM_JOINTS = JOINT_NAMES.size(); // joint state initialized - const auto & joint_state_msg = state_broadcaster_->realtime_joint_state_publisher_->msg_; 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_); @@ -585,7 +578,8 @@ TEST_F(JointStateBroadcasterTest, UpdateTest) controller_interface::return_type::OK); } -void JointStateBroadcasterTest::test_published_joint_state_message(const std::string & topic) +void JointStateBroadcasterTest::activate_and_get_joint_state_message( + const std::string & topic, sensor_msgs::msg::JointState & joint_state_msg) { auto node_state = state_broadcaster_->get_node()->configure(); ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE); @@ -616,9 +610,14 @@ void JointStateBroadcasterTest::test_published_joint_state_message(const std::st "controller/broadcaster update loop"; // take message from subscription - sensor_msgs::msg::JointState joint_state_msg; rclcpp::MessageInfo msg_info; ASSERT_TRUE(subscription->take(joint_state_msg, msg_info)); +} + +void JointStateBroadcasterTest::test_published_joint_state_message(const std::string & topic) +{ + sensor_msgs::msg::JointState joint_state_msg; + activate_and_get_joint_state_message(topic, joint_state_msg); const size_t NUM_JOINTS = joint_names_.size(); ASSERT_THAT(joint_state_msg.name, 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 63cc7a5483..fcaa40e8d5 100644 --- a/joint_state_broadcaster/test/test_joint_state_broadcaster.hpp +++ b/joint_state_broadcaster/test/test_joint_state_broadcaster.hpp @@ -71,6 +71,9 @@ class JointStateBroadcasterTest : public ::testing::Test void test_published_dynamic_joint_state_message(const std::string & topic); + void activate_and_get_joint_state_message( + const std::string & topic, sensor_msgs::msg::JointState & msg); + protected: // dummy joint state values used for tests const std::vector joint_names_ = {"joint1", "joint2", "joint3"}; From c8f1b449d45b28efbf1d82d91305d5684af0b8ce Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 20:25:14 +0000 Subject: [PATCH 33/39] Fixed implementation so that effort_controllers/GripperActionController works. (#756) (#868) (cherry picked from commit 6352a70d210a6bdec6228a24f41b6d542d0e4364) Co-authored-by: chama1176 --- .../gripper_action_controller.hpp | 2 +- .../gripper_action_controller_impl.hpp | 23 ++++++++++--------- .../hardware_interface_adapter.hpp | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/gripper_controllers/include/gripper_controllers/gripper_action_controller.hpp b/gripper_controllers/include/gripper_controllers/gripper_action_controller.hpp index 89bf232fad..cf3ec193f3 100644 --- a/gripper_controllers/include/gripper_controllers/gripper_action_controller.hpp +++ b/gripper_controllers/include/gripper_controllers/gripper_action_controller.hpp @@ -124,7 +124,7 @@ class GripperActionController : public controller_interface::ControllerInterface bool verbose_ = false; ///< Hard coded verbose flag to help in debugging std::string name_; ///< Controller name. std::optional> - joint_position_command_interface_; + joint_command_interface_; std::optional> joint_position_state_interface_; std::optional> 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 666fced1c0..77598591ae 100644 --- a/gripper_controllers/include/gripper_controllers/gripper_action_controller_impl.hpp +++ b/gripper_controllers/include/gripper_controllers/gripper_action_controller_impl.hpp @@ -226,20 +226,21 @@ template controller_interface::CallbackReturn GripperActionController::on_activate( const rclcpp_lifecycle::State &) { - auto position_command_interface_it = std::find_if( + auto command_interface_it = std::find_if( command_interfaces_.begin(), command_interfaces_.end(), [](const hardware_interface::LoanedCommandInterface & command_interface) - { return command_interface.get_interface_name() == hardware_interface::HW_IF_POSITION; }); - if (position_command_interface_it == command_interfaces_.end()) + { return command_interface.get_interface_name() == HardwareInterface; }); + if (command_interface_it == command_interfaces_.end()) { - RCLCPP_ERROR(get_node()->get_logger(), "Expected 1 position command interface"); + RCLCPP_ERROR_STREAM( + get_node()->get_logger(), "Expected 1 " << HardwareInterface << " command interface"); return controller_interface::CallbackReturn::ERROR; } - if (position_command_interface_it->get_prefix_name() != params_.joint) + if (command_interface_it->get_prefix_name() != params_.joint) { RCLCPP_ERROR_STREAM( - get_node()->get_logger(), "Position command interface is different than joint name `" - << position_command_interface_it->get_prefix_name() << "` != `" + get_node()->get_logger(), "Command interface is different than joint name `" + << command_interface_it->get_prefix_name() << "` != `" << params_.joint << "`"); return controller_interface::CallbackReturn::ERROR; } @@ -278,12 +279,12 @@ controller_interface::CallbackReturn GripperActionController: return controller_interface::CallbackReturn::ERROR; } - joint_position_command_interface_ = *position_command_interface_it; + joint_command_interface_ = *command_interface_it; joint_position_state_interface_ = *position_state_interface_it; joint_velocity_state_interface_ = *velocity_state_interface_it; // Hardware interface adapter - hw_iface_adapter_.init(joint_position_command_interface_, get_node()); + hw_iface_adapter_.init(joint_command_interface_, get_node()); // Command - non RT version command_struct_.position_ = joint_position_state_interface_->get().get_value(); @@ -311,7 +312,7 @@ template controller_interface::CallbackReturn GripperActionController::on_deactivate( const rclcpp_lifecycle::State &) { - joint_position_command_interface_ = std::nullopt; + joint_command_interface_ = std::nullopt; joint_position_state_interface_ = std::nullopt; joint_velocity_state_interface_ = std::nullopt; release_interfaces(); @@ -324,7 +325,7 @@ GripperActionController::command_interface_configuration() co { return { controller_interface::interface_configuration_type::INDIVIDUAL, - {params_.joint + "/" + hardware_interface::HW_IF_POSITION}}; + {params_.joint + "/" + HardwareInterface}}; } template diff --git a/gripper_controllers/include/gripper_controllers/hardware_interface_adapter.hpp b/gripper_controllers/include/gripper_controllers/hardware_interface_adapter.hpp index 97ebbb1f4b..b125ab12d0 100644 --- a/gripper_controllers/include/gripper_controllers/hardware_interface_adapter.hpp +++ b/gripper_controllers/include/gripper_controllers/hardware_interface_adapter.hpp @@ -131,7 +131,7 @@ class HardwareInterfaceAdapter { joint_handle_ = joint_handle; // Init PID gains from ROS parameter server - const std::string prefix = "gains." + joint_handle_->get().get_name(); + const std::string prefix = "gains." + joint_handle_->get().get_prefix_name(); const auto k_p = auto_declare(node, prefix + ".p", 0.0); const auto k_i = auto_declare(node, prefix + ".i", 0.0); const auto k_d = auto_declare(node, prefix + ".d", 0.0); From 5b783bb9078d0f9a4378e521712c0c0767d0975b Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Thu, 30 Nov 2023 18:37:54 +0000 Subject: [PATCH 34/39] 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 +++++ gripper_controllers/CHANGELOG.rst | 5 +++++ imu_sensor_broadcaster/CHANGELOG.rst | 3 +++ joint_state_broadcaster/CHANGELOG.rst | 5 +++++ joint_trajectory_controller/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 +++ 20 files changed, 66 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 6c20cdb2a8..52a76f9166 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- * Improve docs (`#785 `_) (`#786 `_) diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 22059fa82c..12463a5048 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index be27da6c2d..05e27551bd 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- * Improve docs (`#785 `_) (`#786 `_) diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 093b929eb3..055f4da238 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- * [diff_drive_controller] Fixed typos in diff_drive_controller_parameter.yaml. (`#822 `_) (`#823 `_) diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 000d794453..5afd128474 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 692f8f48ef..a1ceae136b 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 +----------- + 2.27.0 (2023-11-14) ------------------- diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index a99c267929..83b583c60a 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Rearrange controllers overview page (`#846 `_) (`#847 `_) +* Contributors: mergify[bot] + 2.27.0 (2023-11-14) ------------------- diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index 8c86a385de..b37b0715ff 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Fixed implementation so that effort_controllers/GripperActionController works. (`#756 `_) (`#868 `_) +* Contributors: mergify[bot] + 2.27.0 (2023-11-14) ------------------- diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 204177c217..6fde9ffa97 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 517d0ffd41..86f0980fd9 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* joint_state_broadcaster: Add proper subscription to TestCustomInterfaceMappingUpdate (`#859 `_) (`#863 `_) +* Contributors: mergify[bot] + 2.27.0 (2023-11-14) ------------------- diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 8d4b439535..a599c60fd0 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 6a4f4b9de7..a9791f01bd 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index f803e222be..3d8576c692 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 25373d4324..36769b37dd 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 49e388d82f..37ac51ba04 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 +----------- + 2.27.0 (2023-11-14) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index 91c0a0c95a..0717707fcd 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 +----------- + 2.27.0 (2023-11-14) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index bab0eaf741..f0b919f845 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- * Steering controllers library: fix open loop mode (`#793 `_) (`#800 `_) diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index bc4f4b6ba8..560fb84e59 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 0b8f4a7489..1d34347a8e 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- * Improve docs (`#785 `_) (`#786 `_) diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index e294117c05..d1baa6da09 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.27.0 (2023-11-14) ------------------- From 16fb6cfcea908484908bc4eea982b9ddc9891c46 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Thu, 30 Nov 2023 18:38:20 +0000 Subject: [PATCH 35/39] 2.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 +- 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 +- 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 +- 42 files changed, 62 insertions(+), 62 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index 52a76f9166..f210ac888f 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index 845b542fd7..571cb8310a 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 2.27.0 + 2.28.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Apache License 2.0 Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 12463a5048..443df5d887 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index 121d63a396..99ec33b1ff 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 2.27.0 + 2.28.0 Implementation of admittance controllers for different input and output interface. Denis Štogl Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 05e27551bd..833b4ef326 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index 209c6a9bbd..dee9825c88 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 2.27.0 + 2.28.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 055f4da238..19c49c06b2 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 63ce46b56e..58776f0dc7 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 2.27.0 + 2.28.0 Controller for a differential drive mobile base. Bence Magyar Jordan Palacios diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 5afd128474..499971c79f 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index fd1b5d9659..1ab0e51d2f 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 2.27.0 + 2.28.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index a1ceae136b..6e43898d19 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 ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 5b6bc83a77..5c9d8c0980 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 2.27.0 + 2.28.0 Controller to publish state of force-torque sensors. Bence Magyar Denis Štogl diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 83b583c60a..545adef107 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- * Rearrange controllers overview page (`#846 `_) (`#847 `_) * Contributors: mergify[bot] diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index a316b8cb40..d9b9d93f0a 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 2.27.0 + 2.28.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index b37b0715ff..a3606bccd0 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- * Fixed implementation so that effort_controllers/GripperActionController works. (`#756 `_) (`#868 `_) * Contributors: mergify[bot] diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index e47ddc03d6..f86777a4ca 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 2.27.0 + 2.28.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 6fde9ffa97..7e53e69a26 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index cedfb2f30d..0943f9224a 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 2.27.0 + 2.28.0 Controller to publish readings of IMU sensors. Bence Magyar Denis Štogl diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 86f0980fd9..2e846d1d90 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- * joint_state_broadcaster: Add proper subscription to TestCustomInterfaceMappingUpdate (`#859 `_) (`#863 `_) * Contributors: mergify[bot] diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index f1dd261705..6085246006 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 2.27.0 + 2.28.0 Broadcaster to publish joint state Bence Magyar Denis Stogl diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index a599c60fd0..563201fc78 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index ee6b4f2e64..998de9e38c 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 2.27.0 + 2.28.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar Jordan Palacios diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index a9791f01bd..010cb40e20 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index a777165a43..f2f9348713 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 2.27.0 + 2.28.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 3d8576c692..33e459a6be 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index fc8754fb15..95492b3eaf 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 2.27.0 + 2.28.0 Controller to publish readings of Range sensors. Bence Magyar Florent Chretien diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 36769b37dd..040db42ff1 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 2561c54ad5..72fa18f0fa 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 2.27.0 + 2.28.0 Metapackage for ROS2 controllers related packages Bence Magyar Jordan Palacios diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 37ac51ba04..a9b14be634 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 ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 40ec8f7cac..3755bff7f9 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 2.27.0 + 2.28.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Denis Štogl diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index 47495a345a..c78fc6fa1c 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="2.27.0", + version="2.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 0717707fcd..e98f38de6c 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 ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 717b7239d6..3446ac577e 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 - 2.27.0 + 2.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 e406d9e57a..815e4b9f99 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -7,7 +7,7 @@ setup( name=package_name, - version="2.27.0", + version="2.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 f0b919f845..5f414d8b93 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index e462a53ac4..c7c78c002b 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 2.27.0 + 2.28.0 Package for steering robot configurations including odometry and interfaces. Apache License 2.0 Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index 560fb84e59..cf04bca37c 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index 01daa4e5e2..31454d0365 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 2.27.0 + 2.28.0 Controller for a tricycle drive mobile base Bence Magyar Tony Najjar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 1d34347a8e..4c6260ceb9 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index cabae83905..7ed6fbfa61 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 2.27.0 + 2.28.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index d1baa6da09..a568affc91 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.28.0 (2023-11-30) +------------------- 2.27.0 (2023-11-14) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index 84a083d576..d879e15e66 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 2.27.0 + 2.28.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios From 13ba381b1d421b4a5dc2ba6f0aae2aca08b82cdd Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 18:43:34 +0000 Subject: [PATCH 36/39] Add test for effort gripper controller (#769) (#867) --- .../test/test_gripper_controllers.cpp | 103 +++++++++++------- .../test/test_gripper_controllers.hpp | 10 +- 2 files changed, 67 insertions(+), 46 deletions(-) diff --git a/gripper_controllers/test/test_gripper_controllers.cpp b/gripper_controllers/test/test_gripper_controllers.cpp index 4c82eb6961..506f968b99 100644 --- a/gripper_controllers/test/test_gripper_controllers.cpp +++ b/gripper_controllers/test/test_gripper_controllers.cpp @@ -32,123 +32,142 @@ using hardware_interface::LoanedStateInterface; using GripperCommandAction = control_msgs::action::GripperCommand; using GoalHandle = rclcpp_action::ServerGoalHandle; -void GripperControllerTest::SetUpTestCase() { rclcpp::init(0, nullptr); } +template +void GripperControllerTest::SetUpTestCase() +{ + rclcpp::init(0, nullptr); +} -void GripperControllerTest::TearDownTestCase() { rclcpp::shutdown(); } +template +void GripperControllerTest::TearDownTestCase() +{ + rclcpp::shutdown(); +} -void GripperControllerTest::SetUp() +template +void GripperControllerTest::SetUp() { // initialize controller - controller_ = std::make_unique(); + controller_ = std::make_unique>(); } -void GripperControllerTest::TearDown() { controller_.reset(nullptr); } +template +void GripperControllerTest::TearDown() +{ + controller_.reset(nullptr); +} -void GripperControllerTest::SetUpController() +template +void GripperControllerTest::SetUpController() { const auto result = controller_->init("gripper_controller"); ASSERT_EQ(result, controller_interface::return_type::OK); std::vector command_ifs; - command_ifs.emplace_back(joint_1_pos_cmd_); + command_ifs.emplace_back(this->joint_1_cmd_); std::vector state_ifs; - state_ifs.emplace_back(joint_1_pos_state_); - state_ifs.emplace_back(joint_1_vel_state_); + state_ifs.emplace_back(this->joint_1_pos_state_); + state_ifs.emplace_back(this->joint_1_vel_state_); controller_->assign_interfaces(std::move(command_ifs), std::move(state_ifs)); } -TEST_F(GripperControllerTest, ParametersNotSet) +using TestTypes = ::testing::Types< + std::integral_constant, + std::integral_constant>; +TYPED_TEST_SUITE(GripperControllerTest, TestTypes); + +TYPED_TEST(GripperControllerTest, ParametersNotSet) { - SetUpController(); + this->SetUpController(); // configure failed, 'joints' parameter not set ASSERT_EQ( - controller_->on_configure(rclcpp_lifecycle::State()), + this->controller_->on_configure(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::ERROR); } -TEST_F(GripperControllerTest, JointParameterIsEmpty) +TYPED_TEST(GripperControllerTest, JointParameterIsEmpty) { - SetUpController(); + this->SetUpController(); - controller_->get_node()->set_parameter({"joint", ""}); + this->controller_->get_node()->set_parameter({"joint", ""}); // configure failed, 'joints' is empty ASSERT_EQ( - controller_->on_configure(rclcpp_lifecycle::State()), + this->controller_->on_configure(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::ERROR); } -TEST_F(GripperControllerTest, ConfigureParamsSuccess) +TYPED_TEST(GripperControllerTest, ConfigureParamsSuccess) { - SetUpController(); + this->SetUpController(); - controller_->get_node()->set_parameter({"joint", "joint_1"}); + this->controller_->get_node()->set_parameter({"joint", "joint_1"}); // configure successful ASSERT_EQ( - controller_->on_configure(rclcpp_lifecycle::State()), + this->controller_->on_configure(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::SUCCESS); } -TEST_F(GripperControllerTest, ActivateWithWrongJointsNamesFails) +TYPED_TEST(GripperControllerTest, ActivateWithWrongJointsNamesFails) { - SetUpController(); + this->SetUpController(); - controller_->get_node()->set_parameter({"joint", "unicorn_joint"}); + this->controller_->get_node()->set_parameter({"joint", "unicorn_joint"}); // activate failed, 'joint4' is not a valid joint name for the hardware ASSERT_EQ( - controller_->on_configure(rclcpp_lifecycle::State()), + this->controller_->on_configure(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::SUCCESS); ASSERT_EQ( - controller_->on_activate(rclcpp_lifecycle::State()), + this->controller_->on_activate(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::ERROR); } -TEST_F(GripperControllerTest, ActivateSuccess) +TYPED_TEST(GripperControllerTest, ActivateSuccess) { - SetUpController(); + this->SetUpController(); - controller_->get_node()->set_parameter({"joint", "joint1"}); + this->controller_->get_node()->set_parameter({"joint", "joint1"}); // activate successful ASSERT_EQ( - controller_->on_configure(rclcpp_lifecycle::State()), + this->controller_->on_configure(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::SUCCESS); ASSERT_EQ( - controller_->on_activate(rclcpp_lifecycle::State()), + this->controller_->on_activate(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::SUCCESS); } -TEST_F(GripperControllerTest, ActivateDeactivateActivateSuccess) +TYPED_TEST(GripperControllerTest, ActivateDeactivateActivateSuccess) { - SetUpController(); + this->SetUpController(); - controller_->get_node()->set_parameter({"joint", "joint1"}); + this->controller_->get_node()->set_parameter({"joint", "joint1"}); ASSERT_EQ( - controller_->on_configure(rclcpp_lifecycle::State()), + this->controller_->on_configure(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::SUCCESS); ASSERT_EQ( - controller_->on_activate(rclcpp_lifecycle::State()), + this->controller_->on_activate(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::SUCCESS); ASSERT_EQ( - controller_->on_deactivate(rclcpp_lifecycle::State()), + this->controller_->on_deactivate(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::SUCCESS); // re-assign interfaces std::vector command_ifs; - command_ifs.emplace_back(joint_1_pos_cmd_); + command_ifs.emplace_back(this->joint_1_cmd_); std::vector state_ifs; - state_ifs.emplace_back(joint_1_pos_state_); - state_ifs.emplace_back(joint_1_vel_state_); - controller_->assign_interfaces(std::move(command_ifs), std::move(state_ifs)); + state_ifs.emplace_back(this->joint_1_pos_state_); + state_ifs.emplace_back(this->joint_1_vel_state_); + this->controller_->assign_interfaces(std::move(command_ifs), std::move(state_ifs)); ASSERT_EQ( - controller_->on_configure(rclcpp_lifecycle::State()), + this->controller_->on_configure(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::SUCCESS); ASSERT_EQ( - controller_->on_activate(rclcpp_lifecycle::State()), + this->controller_->on_activate(rclcpp_lifecycle::State()), controller_interface::CallbackReturn::SUCCESS); } diff --git a/gripper_controllers/test/test_gripper_controllers.hpp b/gripper_controllers/test/test_gripper_controllers.hpp index 350e551cb8..4983c8102d 100644 --- a/gripper_controllers/test/test_gripper_controllers.hpp +++ b/gripper_controllers/test/test_gripper_controllers.hpp @@ -26,20 +26,22 @@ #include "hardware_interface/types/hardware_interface_type_values.hpp" using hardware_interface::CommandInterface; +using hardware_interface::HW_IF_EFFORT; using hardware_interface::HW_IF_POSITION; using hardware_interface::HW_IF_VELOCITY; using hardware_interface::StateInterface; namespace { - // subclassing and friending so we can access member variables +template class FriendGripperController -: public gripper_action_controller::GripperActionController +: public gripper_action_controller::GripperActionController { FRIEND_TEST(GripperControllerTest, CommandSuccessTest); }; +template class GripperControllerTest : public ::testing::Test { public: @@ -53,7 +55,7 @@ class GripperControllerTest : public ::testing::Test void SetUpHandles(); protected: - std::unique_ptr controller_; + std::unique_ptr> controller_; // dummy joint state values used for tests const std::string joint_name_ = "joint1"; @@ -62,7 +64,7 @@ class GripperControllerTest : public ::testing::Test StateInterface joint_1_pos_state_{joint_name_, HW_IF_POSITION, &joint_states_[0]}; StateInterface joint_1_vel_state_{joint_name_, HW_IF_VELOCITY, &joint_states_[1]}; - CommandInterface joint_1_pos_cmd_{joint_name_, HW_IF_POSITION, &joint_commands_[0]}; + CommandInterface joint_1_cmd_{joint_name_, T::value, &joint_commands_[0]}; }; } // anonymous namespace From 2916b792f4db83bb1efdb9fc14523cbb6212f6cd Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 21:03:51 +0100 Subject: [PATCH 37/39] [ForceTorqueSensorBroadcaster] Create ParamListener and get parameters on configure (backport #698) (#750) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [ForceTorqueSensorBroadcaster] Create ParamListener and get parameters on configure (#698) * Create ParamListener and get parameters on configure * Declare parameters for test_force_torque_sensor_broadcaster Since the parameters are not declared on init anymore, they cannot be set without declaring them before --------- Co-authored-by: Bence Magyar (cherry picked from commit 32aaef7552638826aba0b3f3a72b1c1453739afa) * Fix "parameter is already declared" error --------- Co-authored-by: Noel Jiménez García Co-authored-by: Christoph Froehlich --- .../src/force_torque_sensor_broadcaster.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 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 9b570d353f..e9a173380b 100644 --- a/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp +++ b/force_torque_sensor_broadcaster/src/force_torque_sensor_broadcaster.cpp @@ -29,6 +29,12 @@ ForceTorqueSensorBroadcaster::ForceTorqueSensorBroadcaster() } controller_interface::CallbackReturn ForceTorqueSensorBroadcaster::on_init() +{ + return controller_interface::CallbackReturn::SUCCESS; +} + +controller_interface::CallbackReturn ForceTorqueSensorBroadcaster::on_configure( + const rclcpp_lifecycle::State & /*previous_state*/) { try { @@ -37,18 +43,10 @@ controller_interface::CallbackReturn ForceTorqueSensorBroadcaster::on_init() } catch (const std::exception & e) { - fprintf(stderr, "Exception thrown during init stage with message: %s \n", e.what()); + 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 ForceTorqueSensorBroadcaster::on_configure( - const rclcpp_lifecycle::State & /*previous_state*/) -{ - params_ = param_listener_->get_params(); - const bool no_interface_names_defined = params_.interface_names.force.x.empty() && params_.interface_names.force.y.empty() && params_.interface_names.force.z.empty() && params_.interface_names.torque.x.empty() && From 965144754c4e110c1a2f7be0fbc9d7f50973d6f4 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Tue, 5 Dec 2023 20:10:33 +0000 Subject: [PATCH 38/39] 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 | 17 +++++++++++++++++ forward_command_controller/CHANGELOG.rst | 3 +++ gripper_controllers/CHANGELOG.rst | 5 +++++ imu_sensor_broadcaster/CHANGELOG.rst | 3 +++ joint_state_broadcaster/CHANGELOG.rst | 3 +++ joint_trajectory_controller/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 +++ 20 files changed, 76 insertions(+) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index f210ac888f..c7823d8d61 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 443df5d887..6a38baaed9 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index 833b4ef326..ed03737a03 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 19c49c06b2..594de0ec29 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 499971c79f..3b52b56807 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index 6e43898d19..af04fbe202 100644 --- a/force_torque_sensor_broadcaster/CHANGELOG.rst +++ b/force_torque_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,23 @@ Changelog for package force_torque_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* [ForceTorqueSensorBroadcaster] Create ParamListener and get parameters on configure (backport `#698 `_) (`#750 `_) + * [ForceTorqueSensorBroadcaster] Create ParamListener and get parameters on configure (`#698 `_) + * Create ParamListener and get parameters on configure + * Declare parameters for test_force_torque_sensor_broadcaster + Since the parameters are not declared on init anymore, they cannot be + set without declaring them before + --------- + Co-authored-by: Bence Magyar + (cherry picked from commit 32aaef7552638826aba0b3f3a72b1c1453739afa) + * Fix "parameter is already declared" error + --------- + Co-authored-by: Noel Jiménez García + Co-authored-by: Christoph Froehlich +* Contributors: mergify[bot] + 2.28.0 (2023-11-30) ------------------- diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 545adef107..9e457bfec1 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- * Rearrange controllers overview page (`#846 `_) (`#847 `_) diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index a3606bccd0..e7377cb879 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- +* Add test for effort gripper controller (`#769 `_) (`#867 `_) +* Contributors: mergify[bot] + 2.28.0 (2023-11-30) ------------------- * Fixed implementation so that effort_controllers/GripperActionController works. (`#756 `_) (`#868 `_) diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index 7e53e69a26..cdef027d41 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index 2e846d1d90..ed58ad5808 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- * joint_state_broadcaster: Add proper subscription to TestCustomInterfaceMappingUpdate (`#859 `_) (`#863 `_) diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 563201fc78..5a5b7e4d6d 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 010cb40e20..4307a1b271 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 33e459a6be..37f28dc92d 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index 040db42ff1..c7131a4295 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index a9b14be634..42e5982c8e 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 +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/rqt_joint_trajectory_controller/CHANGELOG.rst b/rqt_joint_trajectory_controller/CHANGELOG.rst index e98f38de6c..3b1471c68c 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 +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/steering_controllers_library/CHANGELOG.rst b/steering_controllers_library/CHANGELOG.rst index 5f414d8b93..2b6295bbe0 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index cf04bca37c..a104d18f0d 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index 4c6260ceb9..e6ba19bcfd 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index a568affc91..4a18cbea2f 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Forthcoming +----------- + 2.28.0 (2023-11-30) ------------------- From 53ec31b47f9d391aaccfa9b3b8ecf4f37c36cf51 Mon Sep 17 00:00:00 2001 From: Bence Magyar Date: Tue, 5 Dec 2023 20:10:57 +0000 Subject: [PATCH 39/39] 2.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 +- 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 +- 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 +- 42 files changed, 62 insertions(+), 62 deletions(-) diff --git a/ackermann_steering_controller/CHANGELOG.rst b/ackermann_steering_controller/CHANGELOG.rst index c7823d8d61..9094e77913 100644 --- a/ackermann_steering_controller/CHANGELOG.rst +++ b/ackermann_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ackermann_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/ackermann_steering_controller/package.xml b/ackermann_steering_controller/package.xml index 571cb8310a..f6d00dc8fd 100644 --- a/ackermann_steering_controller/package.xml +++ b/ackermann_steering_controller/package.xml @@ -2,7 +2,7 @@ ackermann_steering_controller - 2.28.0 + 2.29.0 Steering controller for Ackermann kinematics. Rear fixed wheels are powering the vehicle and front wheels are steering it. Apache License 2.0 Bence Magyar diff --git a/admittance_controller/CHANGELOG.rst b/admittance_controller/CHANGELOG.rst index 6a38baaed9..25d8f756cb 100644 --- a/admittance_controller/CHANGELOG.rst +++ b/admittance_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package admittance_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/admittance_controller/package.xml b/admittance_controller/package.xml index 99ec33b1ff..67b8da731d 100644 --- a/admittance_controller/package.xml +++ b/admittance_controller/package.xml @@ -2,7 +2,7 @@ admittance_controller - 2.28.0 + 2.29.0 Implementation of admittance controllers for different input and output interface. Denis Štogl Bence Magyar diff --git a/bicycle_steering_controller/CHANGELOG.rst b/bicycle_steering_controller/CHANGELOG.rst index ed03737a03..f051455010 100644 --- a/bicycle_steering_controller/CHANGELOG.rst +++ b/bicycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package bicycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/bicycle_steering_controller/package.xml b/bicycle_steering_controller/package.xml index dee9825c88..be0011cc5e 100644 --- a/bicycle_steering_controller/package.xml +++ b/bicycle_steering_controller/package.xml @@ -2,7 +2,7 @@ bicycle_steering_controller - 2.28.0 + 2.29.0 Steering controller with bicycle kinematics. Rear fixed wheel is powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/diff_drive_controller/CHANGELOG.rst b/diff_drive_controller/CHANGELOG.rst index 594de0ec29..4a2815d6e9 100644 --- a/diff_drive_controller/CHANGELOG.rst +++ b/diff_drive_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package diff_drive_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/diff_drive_controller/package.xml b/diff_drive_controller/package.xml index 58776f0dc7..d09bb640dd 100644 --- a/diff_drive_controller/package.xml +++ b/diff_drive_controller/package.xml @@ -1,7 +1,7 @@ diff_drive_controller - 2.28.0 + 2.29.0 Controller for a differential drive mobile base. Bence Magyar Jordan Palacios diff --git a/effort_controllers/CHANGELOG.rst b/effort_controllers/CHANGELOG.rst index 3b52b56807..38a60737e5 100644 --- a/effort_controllers/CHANGELOG.rst +++ b/effort_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package effort_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/effort_controllers/package.xml b/effort_controllers/package.xml index 1ab0e51d2f..ec801db332 100644 --- a/effort_controllers/package.xml +++ b/effort_controllers/package.xml @@ -1,7 +1,7 @@ effort_controllers - 2.28.0 + 2.29.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/force_torque_sensor_broadcaster/CHANGELOG.rst b/force_torque_sensor_broadcaster/CHANGELOG.rst index af04fbe202..6e4942f013 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 ------------ +2.29.0 (2023-12-05) +------------------- * [ForceTorqueSensorBroadcaster] Create ParamListener and get parameters on configure (backport `#698 `_) (`#750 `_) * [ForceTorqueSensorBroadcaster] Create ParamListener and get parameters on configure (`#698 `_) * Create ParamListener and get parameters on configure diff --git a/force_torque_sensor_broadcaster/package.xml b/force_torque_sensor_broadcaster/package.xml index 5c9d8c0980..7c35b17cb7 100644 --- a/force_torque_sensor_broadcaster/package.xml +++ b/force_torque_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ force_torque_sensor_broadcaster - 2.28.0 + 2.29.0 Controller to publish state of force-torque sensors. Bence Magyar Denis Štogl diff --git a/forward_command_controller/CHANGELOG.rst b/forward_command_controller/CHANGELOG.rst index 9e457bfec1..2bec94c307 100644 --- a/forward_command_controller/CHANGELOG.rst +++ b/forward_command_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package forward_command_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/forward_command_controller/package.xml b/forward_command_controller/package.xml index d9b9d93f0a..24a349f2db 100644 --- a/forward_command_controller/package.xml +++ b/forward_command_controller/package.xml @@ -1,7 +1,7 @@ forward_command_controller - 2.28.0 + 2.29.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/gripper_controllers/CHANGELOG.rst b/gripper_controllers/CHANGELOG.rst index e7377cb879..b3d5b93a60 100644 --- a/gripper_controllers/CHANGELOG.rst +++ b/gripper_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package gripper_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- * Add test for effort gripper controller (`#769 `_) (`#867 `_) * Contributors: mergify[bot] diff --git a/gripper_controllers/package.xml b/gripper_controllers/package.xml index f86777a4ca..2730d3287f 100644 --- a/gripper_controllers/package.xml +++ b/gripper_controllers/package.xml @@ -4,7 +4,7 @@ schematypens="http://www.w3.org/2001/XMLSchema"?> gripper_controllers - 2.28.0 + 2.29.0 The gripper_controllers package Bence Magyar diff --git a/imu_sensor_broadcaster/CHANGELOG.rst b/imu_sensor_broadcaster/CHANGELOG.rst index cdef027d41..2b2a86d60d 100644 --- a/imu_sensor_broadcaster/CHANGELOG.rst +++ b/imu_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package imu_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/imu_sensor_broadcaster/package.xml b/imu_sensor_broadcaster/package.xml index 0943f9224a..6b079c70d7 100644 --- a/imu_sensor_broadcaster/package.xml +++ b/imu_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ imu_sensor_broadcaster - 2.28.0 + 2.29.0 Controller to publish readings of IMU sensors. Bence Magyar Denis Štogl diff --git a/joint_state_broadcaster/CHANGELOG.rst b/joint_state_broadcaster/CHANGELOG.rst index ed58ad5808..1f163cd33c 100644 --- a/joint_state_broadcaster/CHANGELOG.rst +++ b/joint_state_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_state_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/joint_state_broadcaster/package.xml b/joint_state_broadcaster/package.xml index 6085246006..6263f3bce6 100644 --- a/joint_state_broadcaster/package.xml +++ b/joint_state_broadcaster/package.xml @@ -1,7 +1,7 @@ joint_state_broadcaster - 2.28.0 + 2.29.0 Broadcaster to publish joint state Bence Magyar Denis Stogl diff --git a/joint_trajectory_controller/CHANGELOG.rst b/joint_trajectory_controller/CHANGELOG.rst index 5a5b7e4d6d..cea342497b 100644 --- a/joint_trajectory_controller/CHANGELOG.rst +++ b/joint_trajectory_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package joint_trajectory_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/joint_trajectory_controller/package.xml b/joint_trajectory_controller/package.xml index 998de9e38c..8a0c9840dd 100644 --- a/joint_trajectory_controller/package.xml +++ b/joint_trajectory_controller/package.xml @@ -1,7 +1,7 @@ joint_trajectory_controller - 2.28.0 + 2.29.0 Controller for executing joint-space trajectories on a group of joints Bence Magyar Jordan Palacios diff --git a/position_controllers/CHANGELOG.rst b/position_controllers/CHANGELOG.rst index 4307a1b271..7aec5c01b3 100644 --- a/position_controllers/CHANGELOG.rst +++ b/position_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package position_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/position_controllers/package.xml b/position_controllers/package.xml index f2f9348713..870ab7639f 100644 --- a/position_controllers/package.xml +++ b/position_controllers/package.xml @@ -1,7 +1,7 @@ position_controllers - 2.28.0 + 2.29.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios diff --git a/range_sensor_broadcaster/CHANGELOG.rst b/range_sensor_broadcaster/CHANGELOG.rst index 37f28dc92d..a7edb84aed 100644 --- a/range_sensor_broadcaster/CHANGELOG.rst +++ b/range_sensor_broadcaster/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package range_sensor_broadcaster ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/range_sensor_broadcaster/package.xml b/range_sensor_broadcaster/package.xml index 95492b3eaf..3c945505d9 100644 --- a/range_sensor_broadcaster/package.xml +++ b/range_sensor_broadcaster/package.xml @@ -2,7 +2,7 @@ range_sensor_broadcaster - 2.28.0 + 2.29.0 Controller to publish readings of Range sensors. Bence Magyar Florent Chretien diff --git a/ros2_controllers/CHANGELOG.rst b/ros2_controllers/CHANGELOG.rst index c7131a4295..17ce2aab02 100644 --- a/ros2_controllers/CHANGELOG.rst +++ b/ros2_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package ros2_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/ros2_controllers/package.xml b/ros2_controllers/package.xml index 72fa18f0fa..70f4253a40 100644 --- a/ros2_controllers/package.xml +++ b/ros2_controllers/package.xml @@ -1,7 +1,7 @@ ros2_controllers - 2.28.0 + 2.29.0 Metapackage for ROS2 controllers related packages Bence Magyar Jordan Palacios diff --git a/ros2_controllers_test_nodes/CHANGELOG.rst b/ros2_controllers_test_nodes/CHANGELOG.rst index 42e5982c8e..c45c4188bf 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 ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/ros2_controllers_test_nodes/package.xml b/ros2_controllers_test_nodes/package.xml index 3755bff7f9..71b5ff70b4 100644 --- a/ros2_controllers_test_nodes/package.xml +++ b/ros2_controllers_test_nodes/package.xml @@ -2,7 +2,7 @@ ros2_controllers_test_nodes - 2.28.0 + 2.29.0 Demo nodes for showing and testing functionalities of the ros2_control framework. Denis Štogl diff --git a/ros2_controllers_test_nodes/setup.py b/ros2_controllers_test_nodes/setup.py index c78fc6fa1c..96b986fc43 100644 --- a/ros2_controllers_test_nodes/setup.py +++ b/ros2_controllers_test_nodes/setup.py @@ -20,7 +20,7 @@ setup( name=package_name, - version="2.28.0", + version="2.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 3b1471c68c..aeacc048f8 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 ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/rqt_joint_trajectory_controller/package.xml b/rqt_joint_trajectory_controller/package.xml index 3446ac577e..ea28002de9 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 - 2.28.0 + 2.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 815e4b9f99..6e1874ee06 100644 --- a/rqt_joint_trajectory_controller/setup.py +++ b/rqt_joint_trajectory_controller/setup.py @@ -7,7 +7,7 @@ setup( name=package_name, - version="2.28.0", + version="2.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 2b6295bbe0..eca3aa3110 100644 --- a/steering_controllers_library/CHANGELOG.rst +++ b/steering_controllers_library/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package steering_controllers_library ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/steering_controllers_library/package.xml b/steering_controllers_library/package.xml index c7c78c002b..3e40903573 100644 --- a/steering_controllers_library/package.xml +++ b/steering_controllers_library/package.xml @@ -2,7 +2,7 @@ steering_controllers_library - 2.28.0 + 2.29.0 Package for steering robot configurations including odometry and interfaces. Apache License 2.0 Bence Magyar diff --git a/tricycle_controller/CHANGELOG.rst b/tricycle_controller/CHANGELOG.rst index a104d18f0d..3629cb7ab7 100644 --- a/tricycle_controller/CHANGELOG.rst +++ b/tricycle_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/tricycle_controller/package.xml b/tricycle_controller/package.xml index 31454d0365..a56dedd0af 100644 --- a/tricycle_controller/package.xml +++ b/tricycle_controller/package.xml @@ -2,7 +2,7 @@ tricycle_controller - 2.28.0 + 2.29.0 Controller for a tricycle drive mobile base Bence Magyar Tony Najjar diff --git a/tricycle_steering_controller/CHANGELOG.rst b/tricycle_steering_controller/CHANGELOG.rst index e6ba19bcfd..c45dac4bac 100644 --- a/tricycle_steering_controller/CHANGELOG.rst +++ b/tricycle_steering_controller/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package tricycle_steering_controller ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/tricycle_steering_controller/package.xml b/tricycle_steering_controller/package.xml index 7ed6fbfa61..e60c736b56 100644 --- a/tricycle_steering_controller/package.xml +++ b/tricycle_steering_controller/package.xml @@ -2,7 +2,7 @@ tricycle_steering_controller - 2.28.0 + 2.29.0 Steering controller with tricycle kinematics. Rear fixed wheels are powering the vehicle and front wheel is steering. Apache License 2.0 Bence Magyar diff --git a/velocity_controllers/CHANGELOG.rst b/velocity_controllers/CHANGELOG.rst index 4a18cbea2f..eadc0db3cd 100644 --- a/velocity_controllers/CHANGELOG.rst +++ b/velocity_controllers/CHANGELOG.rst @@ -2,8 +2,8 @@ Changelog for package velocity_controllers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Forthcoming ------------ +2.29.0 (2023-12-05) +------------------- 2.28.0 (2023-11-30) ------------------- diff --git a/velocity_controllers/package.xml b/velocity_controllers/package.xml index d879e15e66..eff54c00ea 100644 --- a/velocity_controllers/package.xml +++ b/velocity_controllers/package.xml @@ -1,7 +1,7 @@ velocity_controllers - 2.28.0 + 2.29.0 Generic controller for forwarding commands. Bence Magyar Jordan Palacios