Skip to content

Commit

Permalink
Merge branch 'master' into semantic_components_cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
christophfroehlich authored Dec 22, 2024
2 parents 8809973 + 038a05f commit 61a3e9b
Show file tree
Hide file tree
Showing 59 changed files with 1,196 additions and 182 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/good-first-issue.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: Good first issue
about: Create an issue to welcome a new contributor into the community.
title: ''
labels: good-first-issue
labels: ["good first issue"]
assignees: ''

---
Expand Down
6 changes: 6 additions & 0 deletions controller_interface/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
Changelog for package controller_interface
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

4.22.0 (2024-12-20)
-------------------
* Fixed typo. Added s to state_interfaces\_ (`#1930 <https://github.com/ros-controls/ros2_control/issues/1930>`_)
* [CI] Add clang job, setup concurrency, use rt_tools humble branch (`#1910 <https://github.com/ros-controls/ros2_control/issues/1910>`_)
* Contributors: Christoph Fröhlich, louietouie

4.21.0 (2024-12-06)
-------------------
* [Diagnostics] Add diagnostics of execution time and periodicity of the controllers and controller_manager (`#1871 <https://github.com/ros-controls/ros2_control/issues/1871>`_)
Expand Down
2 changes: 1 addition & 1 deletion controller_interface/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="2">
<name>controller_interface</name>
<version>4.21.0</version>
<version>4.22.0</version>
<description>Description of controller_interface</description>
<maintainer email="[email protected]">Bence Magyar</maintainer>
<maintainer email="[email protected]">Denis Štogl</maintainer>
Expand Down
13 changes: 13 additions & 0 deletions controller_manager/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@
Changelog for package controller_manager
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

4.22.0 (2024-12-20)
-------------------
* Async Hardware Components (`#1567 <https://github.com/ros-controls/ros2_control/issues/1567>`_)
* Add controller node options args to be able to set controller specific node arguments (`#1713 <https://github.com/ros-controls/ros2_control/issues/1713>`_)
* Use singleton approach to store and reuse the service clients (`#1949 <https://github.com/ros-controls/ros2_control/issues/1949>`_)
* Increase the max and min periodicity tolerances to fix flaky tests (`#1937 <https://github.com/ros-controls/ros2_control/issues/1937>`_)
* Fix the spawner to support full wildcard parameter entries (`#1933 <https://github.com/ros-controls/ros2_control/issues/1933>`_)
* Suppress unnecessary warnings in clock received validation (`#1935 <https://github.com/ros-controls/ros2_control/issues/1935>`_)
* Optimize the valid time check in the update loop (`#1923 <https://github.com/ros-controls/ros2_control/issues/1923>`_)
* [CI] Add clang job, setup concurrency, use rt_tools humble branch (`#1910 <https://github.com/ros-controls/ros2_control/issues/1910>`_)
* Update CPU affinity parameter to be able to set multiple CPUs (`#1915 <https://github.com/ros-controls/ros2_control/issues/1915>`_)
* Contributors: Christoph Fröhlich, Sai Kishor Kothakota, Takashi Sato

4.21.0 (2024-12-06)
-------------------
* Use the .hpp headers from realtime_tools package (`#1916 <https://github.com/ros-controls/ros2_control/issues/1916>`_)
Expand Down
21 changes: 10 additions & 11 deletions controller_manager/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ target_link_libraries(ros2_control_node PRIVATE
if(BUILD_TESTING)
find_package(ament_cmake_gmock REQUIRED)
find_package(ros2_control_test_assets REQUIRED)
find_package(example_interfaces REQUIRED)

# Plugin Libraries that are built and installed for use in testing
add_library(test_controller SHARED test/test_controller/test_controller.cpp)
target_link_libraries(test_controller PUBLIC controller_manager)
ament_target_dependencies(test_controller PUBLIC example_interfaces)
target_compile_definitions(test_controller PRIVATE "CONTROLLER_MANAGER_BUILDING_DLL")
pluginlib_export_plugin_description_file(controller_interface test/test_controller/test_controller.xml)
install(
Expand Down Expand Up @@ -210,20 +212,17 @@ if(BUILD_TESTING)
)
target_link_libraries(test_hardware_spawner
controller_manager
test_controller
ros2_control_test_assets::ros2_control_test_assets
)

install(FILES test/test_controller_spawner_with_fallback_controllers.yaml
DESTINATION test)

install(FILES test/test_controller_spawner_with_type.yaml
DESTINATION test)

install(FILES test/test_controller_overriding_parameters.yaml
DESTINATION test)

install(FILES test/test_controller_spawner_wildcard_entries.yaml
DESTINATION test)
install(FILES
test/test_controller_spawner_with_type.yaml
test/test_controller_overriding_parameters.yaml
test/test_controller_spawner_with_fallback_controllers.yaml
test/test_controller_spawner_wildcard_entries.yaml
test/test_controller_spawner_with_interfaces.yaml
DESTINATION test)

ament_add_gmock(test_hardware_management_srvs
test/test_hardware_management_srvs.cpp
Expand Down
20 changes: 18 additions & 2 deletions controller_manager/controller_manager/spawner.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
load_controller,
switch_controllers,
unload_controller,
set_controller_parameters,
set_controller_parameters_from_param_files,
bcolors,
)
Expand Down Expand Up @@ -145,6 +146,12 @@ def main(args=None):
action="store_true",
required=False,
)
parser.add_argument(
"--controller-ros-args",
help="The --ros-args to be passed to the controller node for remapping topics etc",
default=None,
required=False,
)

command_line_args = rclpy.utilities.remove_ros_args(args=sys.argv)[1:]
args = parser.parse_args(command_line_args)
Expand Down Expand Up @@ -203,6 +210,15 @@ def main(args=None):
+ bcolors.ENDC
)
else:
if controller_ros_args := args.controller_ros_args:
if not set_controller_parameters(
node,
controller_manager_name,
controller_name,
"node_options_args",
controller_ros_args.split(),
):
return 1
if param_files:
if not set_controller_parameters_from_param_files(
node,
Expand Down Expand Up @@ -254,7 +270,7 @@ def main(args=None):
)
if not ret.ok:
node.get_logger().error(
bcolors.FAIL + "Failed to activate controller" + bcolors.ENDC
f"{bcolors.FAIL}Failed to activate controller : {controller_name}{bcolors.ENDC}"
)
return 1

Expand All @@ -279,7 +295,7 @@ def main(args=None):
)
if not ret.ok:
node.get_logger().error(
bcolors.FAIL + "Failed to activate the parsed controllers list" + bcolors.ENDC
f"{bcolors.FAIL}Failed to activate the parsed controllers list : {controller_names}{bcolors.ENDC}"
)
return 1

Expand Down
4 changes: 3 additions & 1 deletion controller_manager/doc/userdoc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ There are two scripts to interact with controller manager from launch files:
$ ros2 run controller_manager spawner -h
usage: spawner [-h] [-c CONTROLLER_MANAGER] [-p PARAM_FILE] [-n NAMESPACE] [--load-only] [--inactive] [-u] [--controller-manager-timeout CONTROLLER_MANAGER_TIMEOUT]
[--switch-timeout SWITCH_TIMEOUT] [--activate-as-group] [--service-call-timeout SERVICE_CALL_TIMEOUT]
[--switch-timeout SWITCH_TIMEOUT] [--activate-as-group] [--service-call-timeout SERVICE_CALL_TIMEOUT] [--controller-ros-args CONTROLLER_ROS_ARGS]
controller_names [controller_names ...]
positional arguments:
Expand All @@ -167,6 +167,8 @@ There are two scripts to interact with controller manager from launch files:
Time to wait for a successful state switch of controllers. Useful if controllers cannot be switched immediately, e.g., paused
simulations at startup
--activate-as-group Activates all the parsed controllers list together instead of one by one. Useful for activating all chainable controllers altogether
--controller-ros-args CONTROLLER_ROS_ARGS
The --ros-args to be passed to the controller node for remapping topics etc
The parsed controller config file can follow the same conventions as the typical ROS 2 parameter file format. Now, the spawner can handle config files with wildcard entries and also the controller name in the absolute namespace. See the following examples on the config files:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,6 @@ class ControllerManager : public rclcpp::Node
CONTROLLER_MANAGER_PUBLIC
unsigned int get_update_rate() const;

/// Deletes all async controllers and components.
/**
* Needed to join the threads immediately after the control loop is ended
* to avoid unnecessary iterations. Otherwise
* the threads will be joined only when the controller manager gets destroyed.
*/
CONTROLLER_MANAGER_PUBLIC
void shutdown_async_controllers_and_components();

protected:
CONTROLLER_MANAGER_PUBLIC
void init_services();
Expand Down
3 changes: 2 additions & 1 deletion controller_manager/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="2">
<name>controller_manager</name>
<version>4.21.0</version>
<version>4.22.0</version>
<description>Description of controller_manager</description>
<maintainer email="[email protected]">Bence Magyar</maintainer>
<maintainer email="[email protected]">Denis Štogl</maintainer>
Expand Down Expand Up @@ -36,6 +36,7 @@
<test_depend>python3-coverage</test_depend>
<test_depend>hardware_interface_testing</test_depend>
<test_depend>ros2_control_test_assets</test_depend>
<test_depend>example_interfaces</test_depend>

<export>
<build_type>ament_cmake</build_type>
Expand Down
77 changes: 70 additions & 7 deletions controller_manager/src/controller_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,17 @@ controller_interface::ControllerInterfaceBaseSharedPtr ControllerManager::load_c
controller_spec.info.fallback_controllers_names = fallback_controllers;
}

const std::string node_options_args_param = controller_name + ".node_options_args";
std::vector<std::string> node_options_args;
if (!has_parameter(node_options_args_param))
{
declare_parameter(node_options_args_param, rclcpp::ParameterType::PARAMETER_STRING_ARRAY);
}
if (get_parameter(node_options_args_param, node_options_args) && !node_options_args.empty())
{
controller_spec.info.node_options_args = node_options_args;
}

return add_controller_impl(controller_spec);
}

Expand Down Expand Up @@ -1468,6 +1479,7 @@ controller_interface::return_type ControllerManager::switch_controller(
to = controllers;

// update the claimed interface controller info
auto switch_result = controller_interface::return_type::OK;
for (auto & controller : to)
{
if (is_controller_active(controller.c))
Expand All @@ -1488,6 +1500,32 @@ controller_interface::return_type ControllerManager::switch_controller(
{
controller.info.claimed_interfaces.clear();
}
if (
std::find(activate_request_.begin(), activate_request_.end(), controller.info.name) !=
activate_request_.end())
{
if (!is_controller_active(controller.c))
{
RCLCPP_ERROR(
get_logger(), "Could not activate controller : '%s'", controller.info.name.c_str());
switch_result = controller_interface::return_type::ERROR;
}
}
/// @note The following is the case of the real controllers that are deactivated and doesn't
/// include the chained controllers that are deactivated and activated
if (
std::find(deactivate_request_.begin(), deactivate_request_.end(), controller.info.name) !=
deactivate_request_.end() &&
std::find(activate_request_.begin(), activate_request_.end(), controller.info.name) ==
activate_request_.end())
{
if (is_controller_active(controller.c))
{
RCLCPP_ERROR(
get_logger(), "Could not deactivate controller : '%s'", controller.info.name.c_str());
switch_result = controller_interface::return_type::ERROR;
}
}
}

// switch lists
Expand All @@ -1497,8 +1535,10 @@ controller_interface::return_type ControllerManager::switch_controller(

clear_requests();

RCLCPP_DEBUG(get_logger(), "Successfully switched controllers");
return controller_interface::return_type::OK;
RCLCPP_DEBUG_EXPRESSION(
get_logger(), switch_result == controller_interface::return_type::OK,
"Successfully switched controllers");
return switch_result;
}

controller_interface::ControllerInterfaceBaseSharedPtr ControllerManager::add_controller_impl(
Expand Down Expand Up @@ -1730,6 +1770,7 @@ void ControllerManager::activate_controllers(
get_logger(),
"Resource conflict for controller '%s'. Command interface '%s' is already claimed.",
controller_name.c_str(), command_interface.c_str());
command_loans.clear();
assignment_successful = false;
break;
}
Expand All @@ -1744,6 +1785,7 @@ void ControllerManager::activate_controllers(
"Caught exception of type : %s while claiming the command interfaces. Can't activate "
"controller '%s': %s",
typeid(e).name(), controller_name.c_str(), e.what());
command_loans.clear();
assignment_successful = false;
break;
}
Expand Down Expand Up @@ -1813,13 +1855,15 @@ void ControllerManager::activate_controllers(
RCLCPP_ERROR(
get_logger(), "Caught exception of type : %s while activating the controller '%s': %s",
typeid(e).name(), controller_name.c_str(), e.what());
controller->release_interfaces();
continue;
}
catch (...)
{
RCLCPP_ERROR(
get_logger(), "Caught unknown exception while activating the controller '%s'",
controller_name.c_str());
controller->release_interfaces();
continue;
}

Expand Down Expand Up @@ -2681,11 +2725,6 @@ std::pair<std::string, std::string> ControllerManager::split_command_interface(

unsigned int ControllerManager::get_update_rate() const { return update_rate_; }

void ControllerManager::shutdown_async_controllers_and_components()
{
resource_manager_->shutdown_async_components();
}

void ControllerManager::propagate_deactivation_of_chained_mode(
const std::vector<ControllerSpec> & controllers)
{
Expand Down Expand Up @@ -3453,6 +3492,18 @@ rclcpp::NodeOptions ControllerManager::determine_controller_node_options(
node_options_arguments.push_back(arg);
}

// Add deprecation notice if the arguments are from the controller_manager node
if (
check_for_element(node_options_arguments, RCL_REMAP_FLAG) ||
check_for_element(node_options_arguments, RCL_SHORT_REMAP_FLAG))
{
RCLCPP_WARN(
get_logger(),
"The use of remapping arguments to the controller_manager node is deprecated. Please use the "
"'--controller-ros-args' argument of the spawner to pass remapping arguments to the "
"controller node.");
}

for (const auto & parameters_file : controller.info.parameters_files)
{
if (!check_for_element(node_options_arguments, RCL_ROS_ARGS_FLAG))
Expand All @@ -3475,6 +3526,18 @@ rclcpp::NodeOptions ControllerManager::determine_controller_node_options(
node_options_arguments.push_back("use_sim_time:=true");
}

// Add options parsed through the spawner
if (
!controller.info.node_options_args.empty() &&
!check_for_element(controller.info.node_options_args, RCL_ROS_ARGS_FLAG))
{
node_options_arguments.push_back(RCL_ROS_ARGS_FLAG);
}
for (const auto & arg : controller.info.node_options_args)
{
node_options_arguments.push_back(arg);
}

std::string arguments;
arguments.reserve(1000);
for (const auto & arg : node_options_arguments)
Expand Down
2 changes: 0 additions & 2 deletions controller_manager/src/ros2_control_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,6 @@ int main(int argc, char ** argv)
std::this_thread::sleep_until(next_iteration_time);
}
}

cm->shutdown_async_controllers_and_components();
});

executor->add_node(cm);
Expand Down
Loading

0 comments on commit 61a3e9b

Please sign in to comment.