<<PackageHeader(controller_manager)>> <<TOC(4)>> The `controller_manager` provides a '''[[http://www.oit.uci.edu/dcslib/digital_unix/digital-v40d/APS33DTE/TITLE.HTM|hard-realtime]]'''-compatible loop to control a robot mechanism, which is represented by a `hardware_interface::RobotHW` instance (see the [[hardware_interface]] package). The `controller_manager` provides the infrastructure to load, unload, start and stop controllers. When loading a controller, the `controller_manager` will use the controller name as the root for all controller specific parameters, most importantly, `type` which identifies which plugin to load. === Tools for running controllers === {{attachment:controller state.png|controller state.png|width="400px"}} The controller manager provides the infrastructure to interact with controllers. Depending on if you're running controllers from a launch file, from the command line or from a ROS node, the controller manager provides different tools to run controllers. == Command-line tools == === controller_manager === You can interact with the `controller_manager` from the command line, using the `controller_manager` script. To interact with a specific controller, use: {{{ $ rosrun controller_manager controller_manager <command> <name1> <name2> ... }}} The following commands are available: * `load`: load controllers (construct and initialize) * `unload`: unload controllers (destruct) * `start`: start controllers * `stop`: stop controllers * `spawn`: load and start controllers * `kill`: stop and unload controllers To get the state of the controllers, use: {{{ $ rosrun controller_manager controller_manager <command> }}} The following commands are available: * `list`: list all the controllers in the order they are executed, and give the state of each controller * `list-types`: list all the controller types the controller manager knows about. If your controller is not in this list, you won't be able to spawn it. * `reload-libraries`: Reloads all the controller libraries that are available as plugins. This is convenient when you are developing a controller and you want to test your new controller code, without restarting the robot every time. This does not restart controllers which were running before. * `reload-libraries --restore`: Reloads all the controller libraries that are available as plugins and restores all controllers to their original state. === spawner === To automatically load and start a set of controllers at once, and automatically stop and unload those same controllers at once, use the `spawner` tool: {{{ $ rosrun controller_manager spawner [--stopped] <name1> <name2> ... }}} When you run spawner, the listed controllers will get loaded and started (unless you specify --stopped). Spawner will keep running while the controllers are up. When you kill spawner (ctrl-c) it will automatically stop and unload all controllers it initially started. === unspawner === To automatically stop a set of controllers, and restart them later, you can use the `unspawner` tool: {{{ $ rosrun controller_manager unspawner <name1> <name2> ... }}} The listed controllers will be ''stopped'', but not unloaded. Once spawner is shut down, the controllers will be restarted. === controller_group === <<Version(melodic)>> `controller_manager` allows developers to switch controllers at run time, but it is not so convenient when you want to switch from a group of controllers to another for some special purposes. The `controller_group` script makes this easy if such groups are defined in ROS parameter `controller_groups`. It knows all controllers involved, and then controllers that need to be stopped and started when it switches from one group to another. Therefore, different groups can share some controllers. An example of `controller_groups` parameter: {{{ controller_groups: production: - prod_controller_1 - prod_controller_2 development: - devel_controller_1 - devel_controller_2 - shared_controller_3 diagnostics: - diag_controller_1 - diag_controller_2 - shared_controller_3 }}} To run the `controller_group` script:: {{{ $ rosrun controller_manager controller_group <command> <args> }}} The following commands are available: * `list`: list all group definitions found in `controller_groups` parameter * `spawn <group>`: Load and start all the controllers included in the group named `<group>`. This is usually used in a ROS launch file * `switch <group>`: Switch to the group named `<group>`. This means stopping those running controllers that are defined in other groups but not in this group, and starting the controllers defined in this group that are not running. == Creating launch files == You could run `controller_manager` to start controllers from within a launch file. However, the controller would then stay up even after the launch file is taken down. Instead, use the `spawner `tool to automatically load, start, stop and unload a controller from within a launch file. When you start `spawner`, it will load and start the controller. When you stop `spawner` (when the launch file is taken down) it will stop and unload the controller. Your launch file would look something like this: {{{ <launch> <node pkg="controller_manager" type="spawner" args="controller_name1 controller_name2" /> </launch> }}} or, if you just want to load the controller, but not start it yet: {{{ <launch> <node pkg="controller_manager" type="spawner" args="--stopped controller_name1 controller_name2" /> </launch> }}} == Graphical tools == The [[rqt_controller_manager]] is a rqt plugin that allows to graphically load, unload, start and stop controllers, as well as to display information about loaded controllers. It can be started from rqt's Plugin menu, or as a standalone executable with: {{{ rosrun rqt_controller_manager rqt_controller_manager }}} == ROS API == To interact with controllers form another ROS node, the controller manager provides five service calls: {{{ #!clearsilver CS/NodeAPI node.0 { name = controller_manager srv { 0.name = controller_manager/load_controller 0.type = controller_manager_msgs/LoadController 0.desc = the service request contains the name of the controller to load, and the response contains a boolean indicating success or failure. 1.name = controller_manager/unload_controller 1.type = controller_manager_msgs/UnloadController 1.desc = the service request contains the name of the controller to unload, and the response contains a boolean indicating success or failure. A controller can only be unloaded when it is in the stopped state. 2.name = controller_manager/switch_controller 2.type = controller_manager_msgs/SwitchController 2.desc = the service request contains a list of controller names to start, a list of controller names to stop and an int to indicate the strictness (`BEST_EFFORT` or `STRICT`). `STRICT` means that switching will fail and result in a no-op if anything goes wrong (an invalid controller name, a controller that failed to start, etc. ). `BEST_EFFORT` means that even when something goes wrong with on controller, the service will still try to start/stop the remaining controllers. The service response contains a boolean indicating success or failure. The list of controllers to stop or start can be an empty list, if you are only stopping or only starting controllers. 3.name = controller_manager/list_controllers 3.type = controller_manager_msgs/ListControllers 3.desc = the service returns all the controllers that are currently loaded. The response includes the following information: controller name, state (running or stopped), type, hardware interface and claimed resources. 4.name = controller_manager/list_controller_types 4.type = controller_manager_msgs/ListControllerTypes 4.desc = the service returns all the controller types that are known to the controller_manager. Only the controller types that are known can be constructed. 5.name = controller_manager/reload_controller_libraries 5.type = controller_manager_msgs/ReloadControllerLibraries 5.desc = the service reloads all the controller libraries that are available as plugins. This is convenient when you are developing a controller, and you want to test your new controller code without restarting the robot every time. This service only works when there are NO controller loaded. } } }}}