From a55d9d05965fbb6285e054c9e6f72285ad326b2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Fr=C3=B6hlich?= Date: Mon, 18 Nov 2024 14:33:18 +0100 Subject: [PATCH 1/3] Add CM `switch_controller` service timeout as parameter to spawner.py (#1790) Co-authored-by: Felix Exner (fexner) Co-authored-by: Sai Kishor Kothakota (cherry picked from commit 23bd1c3c06c30d706f010628d85133a7198e226d) # Conflicts: # controller_manager/doc/userdoc.rst # doc/release_notes.rst --- .../controller_manager/spawner.py | 36 +++++++++++++-- .../controller_manager/unspawner.py | 18 +++++++- controller_manager/doc/userdoc.rst | 22 ++++++++-- doc/release_notes.rst | 44 +++++++++++++++++++ 4 files changed, 112 insertions(+), 8 deletions(-) diff --git a/controller_manager/controller_manager/spawner.py b/controller_manager/controller_manager/spawner.py index a6b7215f5a..83b1e2f89d 100644 --- a/controller_manager/controller_manager/spawner.py +++ b/controller_manager/controller_manager/spawner.py @@ -122,7 +122,16 @@ def main(args=None): "--controller-manager-timeout", help="Time to wait for the controller manager", required=False, - default=0, + default=0.0, + type=float, + ) + parser.add_argument( + "--switch-timeout", + help="Time to wait for a successful state switch of controllers." + " Useful when switching cannot be performed immediately, e.g.," + " paused simulations at startup", + required=False, + default=5.0, type=float, ) parser.add_argument( @@ -139,6 +148,7 @@ def main(args=None): controller_manager_name = args.controller_manager param_file = args.param_file controller_manager_timeout = args.controller_manager_timeout + switch_timeout = args.switch_timeout if param_file and not os.path.isfile(param_file): raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), param_file) @@ -216,7 +226,13 @@ def main(args=None): if not args.stopped and not args.inactive and not args.activate_as_group: ret = switch_controllers( - node, controller_manager_name, [], [controller_name], True, True, 5.0 + node, + controller_manager_name, + [], + [controller_name], + True, + True, + switch_timeout, ) if not ret.ok: node.get_logger().error( @@ -234,7 +250,13 @@ def main(args=None): if not args.stopped and not args.inactive and args.activate_as_group: ret = switch_controllers( - node, controller_manager_name, [], controller_names, True, True, 5.0 + node, + controller_manager_name, + [], + controller_names, + True, + True, + switch_timeout, ) if not ret.ok: node.get_logger().error( @@ -262,7 +284,13 @@ def main(args=None): node.get_logger().info("Interrupt captured, deactivating and unloading controller") # TODO(saikishor) we might have an issue in future, if any of these controllers is in chained mode ret = switch_controllers( - node, controller_manager_name, controller_names, [], True, True, 5.0 + node, + controller_manager_name, + controller_names, + [], + True, + True, + switch_timeout, ) if not ret.ok: node.get_logger().error( diff --git a/controller_manager/controller_manager/unspawner.py b/controller_manager/controller_manager/unspawner.py index d7cab49cbd..15f0ec2899 100644 --- a/controller_manager/controller_manager/unspawner.py +++ b/controller_manager/controller_manager/unspawner.py @@ -37,17 +37,33 @@ def main(args=None): default="/controller_manager", required=False, ) + parser.add_argument( + "--switch-timeout", + help="Time to wait for a successful state switch of controllers." + " Useful when switching cannot be performed immediately, e.g.," + " paused simulations at startup", + required=False, + default=5.0, + type=float, + ) command_line_args = rclpy.utilities.remove_ros_args(args=sys.argv)[1:] args = parser.parse_args(command_line_args) controller_names = args.controller_names controller_manager_name = args.controller_manager + switch_timeout = args.switch_timeout node = Node("unspawner_" + controller_names[0]) try: # Ignore returncode, because message is already printed and we'll try to unload anyway ret = switch_controllers( - node, controller_manager_name, controller_names, [], True, True, 5.0 + node, + controller_manager_name, + controller_names, + [], + True, + True, + switch_timeout, ) node.get_logger().info("Deactivated controller") diff --git a/controller_manager/doc/userdoc.rst b/controller_manager/doc/userdoc.rst index acc6275908..b57ec79800 100644 --- a/controller_manager/doc/userdoc.rst +++ b/controller_manager/doc/userdoc.rst @@ -90,9 +90,15 @@ There are two scripts to interact with controller manager from launch files: .. code-block:: console $ ros2 run controller_manager spawner -h +<<<<<<< HEAD usage: spawner [-h] [-c CONTROLLER_MANAGER] [-p PARAM_FILE] [--load-only] [--stopped] [-t CONTROLLER_TYPE] [-u] [--controller-manager-timeout CONTROLLER_MANAGER_TIMEOUT] controller_name +======= + 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] + controller_names [controller_names ...] +>>>>>>> 23bd1c3 (Add CM `switch_controller` service timeout as parameter to spawner.py (#1790)) positional arguments: controller_name Name of the controller @@ -110,6 +116,13 @@ There are two scripts to interact with controller manager from launch files: -u, --unload-on-kill Wait until this application is interrupted and unload controller --controller-manager-timeout CONTROLLER_MANAGER_TIMEOUT Time to wait for the controller manager +<<<<<<< HEAD +======= + --switch-timeout SWITCH_TIMEOUT + 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 +>>>>>>> 23bd1c3 (Add CM `switch_controller` service timeout as parameter to spawner.py (#1790)) 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: @@ -172,15 +185,18 @@ The parsed controller config file can follow the same conventions as the typical .. code-block:: console $ ros2 run controller_manager unspawner -h - usage: unspawner [-h] [-c CONTROLLER_MANAGER] controller_name + usage: unspawner [-h] [-c CONTROLLER_MANAGER] [--switch-timeout SWITCH_TIMEOUT] controller_names [controller_names ...] positional arguments: - controller_name Name of the controller + controller_names Name of the controller - optional arguments: + options: -h, --help show this help message and exit -c CONTROLLER_MANAGER, --controller-manager CONTROLLER_MANAGER Name of the controller manager ROS node + --switch-timeout SWITCH_TIMEOUT + Time to wait for a successful state switch of controllers. Useful if controllers cannot be switched immediately, e.g., paused + simulations at startup ``hardware_spawner`` ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/release_notes.rst b/doc/release_notes.rst index 5ce3cda5fa..dccff21919 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -16,6 +16,50 @@ controller_interface controller_manager ****************** +<<<<<<< HEAD +======= + * Configured chainable controller: Listed exported interfaces are unavailable and unclaimed + * Active chainable controller (not in chained mode): Listed exported interfaces are available but unclaimed + * Active chainable controller (in chained mode): Listed exported interfaces are available and claimed +* Try using SCHED_FIFO on any kernel (`#1142 `_) +* A method to get node options to setup the controller node was added (`#1169 `_): ``get_node_options`` can be overridden by controllers, this would make it easy for other controllers to be able to setup their own custom node options +* CM now subscribes to ``robot_description`` topic instead of ``~/robot_description`` (`#1410 `_). +* Change the controller sorting with an approach similar to directed acyclic graphs (`#1384 `_) +* Changes from `(PR #1256) `__ + + * All ``joints`` defined in the ````-tag have to be present in the URDF received :ref:`by the controller manager `, otherwise the following error is shown: + + The published robot description file (URDF) seems not to be genuine. The following error was caught: not found in URDF. + + This is to ensure that the URDF and the ````-tag are consistent. E.g., for configuration ports use ``gpio`` interface types instead. + + * The syntax for mimic joints is changed to the `official URDF specification `__. + + .. code-block:: xml + + + + + + + + + + + + + + + + + + The parameters within the ``ros2_control`` tag are not supported any more. +* The support for the ``description`` parameter for loading the URDF was removed (`#1358 `_). +* The ``--controller-type`` or ``-t`` spawner arg is removed. Now the controller type is defined in the controller configuration file with ``type`` field (`#1639 `_). +* The ``--namespace`` or ``-n`` spawner arg is deprecated. Now the spawner namespace can be defined using the ROS 2 standard way (`#1640 `_). +* Added support for the wildcard entries for the controller configuration files (`#1724 `_). +* ``--switch-timeout`` was added as parameter to the helper scripts ``spawner.py`` and ``unspawner.py``. Useful if controllers cannot be switched immediately, e.g., paused simulations at startup (`#1790 `_). +>>>>>>> 23bd1c3 (Add CM `switch_controller` service timeout as parameter to spawner.py (#1790)) * ``ros2_control_node`` can now handle the sim time used by different simulators, when ``use_sim_time`` is set to true (`#1810 `_). * The ``ros2_control_node`` node now accepts the ``thread_priority`` parameter to set the scheduler priority of the controller_manager's RT thread (`#1820 `_). * Added support for the wildcard entries for the controller configuration files (`#1724 `_). From 164bca65568fb1fc2b0654f0d2163141bf988b85 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Mon, 18 Nov 2024 13:38:17 +0000 Subject: [PATCH 2/3] Fix conflicts --- doc/release_notes.rst | 45 +------------------------------------------ 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/doc/release_notes.rst b/doc/release_notes.rst index dccff21919..400e234d23 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -16,52 +16,9 @@ controller_interface controller_manager ****************** -<<<<<<< HEAD -======= - * Configured chainable controller: Listed exported interfaces are unavailable and unclaimed - * Active chainable controller (not in chained mode): Listed exported interfaces are available but unclaimed - * Active chainable controller (in chained mode): Listed exported interfaces are available and claimed -* Try using SCHED_FIFO on any kernel (`#1142 `_) -* A method to get node options to setup the controller node was added (`#1169 `_): ``get_node_options`` can be overridden by controllers, this would make it easy for other controllers to be able to setup their own custom node options -* CM now subscribes to ``robot_description`` topic instead of ``~/robot_description`` (`#1410 `_). -* Change the controller sorting with an approach similar to directed acyclic graphs (`#1384 `_) -* Changes from `(PR #1256) `__ - - * All ``joints`` defined in the ````-tag have to be present in the URDF received :ref:`by the controller manager `, otherwise the following error is shown: - - The published robot description file (URDF) seems not to be genuine. The following error was caught: not found in URDF. - - This is to ensure that the URDF and the ````-tag are consistent. E.g., for configuration ports use ``gpio`` interface types instead. - - * The syntax for mimic joints is changed to the `official URDF specification `__. - - .. code-block:: xml - - - - - - - - - - - - - - - - - - The parameters within the ``ros2_control`` tag are not supported any more. -* The support for the ``description`` parameter for loading the URDF was removed (`#1358 `_). -* The ``--controller-type`` or ``-t`` spawner arg is removed. Now the controller type is defined in the controller configuration file with ``type`` field (`#1639 `_). -* The ``--namespace`` or ``-n`` spawner arg is deprecated. Now the spawner namespace can be defined using the ROS 2 standard way (`#1640 `_). -* Added support for the wildcard entries for the controller configuration files (`#1724 `_). -* ``--switch-timeout`` was added as parameter to the helper scripts ``spawner.py`` and ``unspawner.py``. Useful if controllers cannot be switched immediately, e.g., paused simulations at startup (`#1790 `_). ->>>>>>> 23bd1c3 (Add CM `switch_controller` service timeout as parameter to spawner.py (#1790)) * ``ros2_control_node`` can now handle the sim time used by different simulators, when ``use_sim_time`` is set to true (`#1810 `_). * The ``ros2_control_node`` node now accepts the ``thread_priority`` parameter to set the scheduler priority of the controller_manager's RT thread (`#1820 `_). * Added support for the wildcard entries for the controller configuration files (`#1724 `_). * The ``ros2_control_node`` node has a new ``lock_memory`` parameter to lock memory at startup to physical RAM in order to avoid page faults (`#1822 `_). * The ``ros2_control_node`` node has a new ``cpu_affinity`` parameter to bind the process to a specific CPU core. By default, this is not enabled. (`#1852 `_). +* ``--switch-timeout`` was added as parameter to the helper scripts ``spawner.py`` and ``unspawner.py``. Useful if controllers cannot be switched immediately, e.g., paused simulations at startup (`#1790 `_). From 7e3ed11706b87575437cf96c2c048e92a08954ea Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Mon, 18 Nov 2024 13:39:51 +0000 Subject: [PATCH 3/3] Fix conflicts --- controller_manager/doc/userdoc.rst | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/controller_manager/doc/userdoc.rst b/controller_manager/doc/userdoc.rst index b57ec79800..8f1c57161c 100644 --- a/controller_manager/doc/userdoc.rst +++ b/controller_manager/doc/userdoc.rst @@ -90,39 +90,34 @@ There are two scripts to interact with controller manager from launch files: .. code-block:: console $ ros2 run controller_manager spawner -h -<<<<<<< HEAD - usage: spawner [-h] [-c CONTROLLER_MANAGER] [-p PARAM_FILE] [--load-only] [--stopped] [-t CONTROLLER_TYPE] [-u] - [--controller-manager-timeout CONTROLLER_MANAGER_TIMEOUT] - controller_name -======= - 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] + usage: spawner [-h] [-c CONTROLLER_MANAGER] [-p PARAM_FILE] [-n NAMESPACE] [--load-only] [--stopped] [--inactive] [-t CONTROLLER_TYPE] [-u] + [--controller-manager-timeout CONTROLLER_MANAGER_TIMEOUT] [--switch-timeout SWITCH_TIMEOUT] [--activate-as-group] controller_names [controller_names ...] ->>>>>>> 23bd1c3 (Add CM `switch_controller` service timeout as parameter to spawner.py (#1790)) positional arguments: - controller_name Name of the controller + controller_names List of controllers - optional arguments: + options: -h, --help show this help message and exit -c CONTROLLER_MANAGER, --controller-manager CONTROLLER_MANAGER Name of the controller manager ROS node -p PARAM_FILE, --param-file PARAM_FILE Controller param file to be loaded into controller node before configure + -n NAMESPACE, --namespace NAMESPACE + Namespace for the controller --load-only Only load the controller and leave unconfigured. - --stopped Load and configure the controller, however do not start them + --stopped Load and configure the controller, however do not activate them + --inactive Load and configure the controller, however do not activate them -t CONTROLLER_TYPE, --controller-type CONTROLLER_TYPE If not provided it should exist in the controller manager namespace -u, --unload-on-kill Wait until this application is interrupted and unload controller --controller-manager-timeout CONTROLLER_MANAGER_TIMEOUT Time to wait for the controller manager -<<<<<<< HEAD -======= --switch-timeout SWITCH_TIMEOUT - 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 ->>>>>>> 23bd1c3 (Add CM `switch_controller` service timeout as parameter to spawner.py (#1790)) + Time to wait for a successful state switch of controllers. Useful when switching cannot be performed 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 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: