ROS control-----controller_manager简介

本文详细介绍了ros_control中的controller_manager组件,它通过硬实时控制环控制抽象机器人对象hardware_interface::RobotHW,并支持加载、卸载、启动和停止控制器。文章还提供了controller_manager的使用方法,包括命令行工具、启动文件配置、图形化工具和ROS API。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   ros_control中的controller_manager通过硬实时控制环来控制抽象机器人对象hardware_interface::RobotHW,另外支持controller的加载,卸载,启动和停止。当controller_manager加载controller时候会将controller name作为其所有参数的root,及type(决定加载哪个插件)。

一 controller_manager重要数据结构

1 controller_manager::ControllerLoader< T > Class Template

缺省controller加载器使用pluginlib来加载并实例化controller插件库。 模板参数T是要加载的controller类型的基类。



2 controller_manager::ControllerLoaderInterface Class

这个接口被用以实现以source方式加载和实例化controllers,而非基于插件的方式。 from sources other than the pluginlib-based ControllerLoader.



3 controller_manager::ControllerSpec Struct

该struct含有指向给定controller的指针和controller info。


4 controller_manager::ControllerManager Class

ROS Controller Manager and Runner

该class支持ROS interface for loading, unloading, starting, and stopping ros_control-based controllers。 它也update接口序列化运行controller。

 class ControllerManager{
   
   public:
     //Parameters
     //robot_hw	A pointer to a robot hardware interface
     //nh	The ros::NodeHandle in whose namespace all ROS interfaces should operate. 
     ControllerManager(hardware_interface::RobotHW *robot_hw,
                       const ros::NodeHandle& nh=ros::NodeHandle());
     virtual ~ControllerManager();
    
     //Update all active controllers.
     //When controllers are started or stopped (or switched), those calls are made in this function.
     //Parameters
     //time	The current time
     //period	The change in time since the last call to update
     //reset_controllers	If true, stop and start all running controllers before updating 
      void update(const ros::Time& time, const ros::Duration& period, bool reset_controllers=false);
      
    
     //Load a new controller by name.
     //This dynamically loads a controller called name and initializes the newly loaded controller.
     //It determines the controller type by accessing the ROS parameter "type" in the namespace given by name relative to the namespace of root_nh_.
     //It then initializes the controller with the hardware_interface::RobotHW pointer robot_hw_,
     //the ros::NodeHandle describing this namespace, and a reference to a std::set to retrieve the resources needed by this controller.
     //A controller cannot be loaded while already loaded. To re-load a controller, first unloadController and then loadController.

     //Parameters
     //name The name of the controller as well as the ROS namespace under which the controller should be loaded

     //Returns
     //True on success 
     //False on failure 
     bool loadController(const std::string& name);
   
     bool unloadController(const std::string &name);
   
     //Switch multiple controllers simultaneously.
     //Parameters
     //start_controllers	A vector of controller names to be started
     //stop_controllers	A vector of controller names to be stopped
     //strictness	How important it is that the requested controllers are started and stopped.
     //The levels are defined in the controller_manager_msgs/SwitchControllers service as either BEST_EFFORT or STRICT. 
     //BEST_EFFORT means that switchController can still succeed if a non-existent controller is requested to be stopped or started. 
     bool switchController(const std::vector<std::string>& start_controllers,
                           const std::vector<std::string>& stop_controllers,
                           const int strictness);
   
     //Get a controller by name
     virtual controller_interface::ControllerBase* getControllerByName(const std::string& name);

     //Register a controller loader.
     //By default, the pluginlib-based ControllerLoader is registered on construction of this class.
     //To load controllers through alternate means, register alternate controller loaders here. 
     //Note, however, that when controllers are loaded by loadController the controller loaders are queried in the order that they were registered.
     //This means that if a controller CAN be loaded by the pluginlib-based ControllerLoader, then it WILL, regardless of which other loaders are registered.

     //Parameters
     //controller_loader	A pointer to the loader to be registered 
     void registerControllerLoader(boost::shared_ptr<ControllerLoaderInterface> controller_loader);
     
  
   
   private:
     void getControllerNames(std::vector<std::string> &v);
   
     hardware_interface::RobotHW* robot_hw_;
   
     ros::NodeHandle root_nh_, cm_node_;
   
     typedef boost::shared_ptr<ControllerLoaderInterface> LoaderPtr;
     std::list<LoaderPtr> controller_loaders_;
  
     std::vector<controller_interface::ControllerBase*> start_request_, stop_request_;
     std::list<hardware_interface::ControllerInfo> switch_start_list_, switch_stop_list_;
     bool please_switch_;
     int switch_strictness_;
     
  
     boost::recursive_mutex controllers_lock_;
     std::vector<ControllerSpec> controllers_lists_[2];
     int current_controllers_list_;
     int used_by_realtime_;
     
   
  
     bool listControllerTypesSrv(controller_manager_msgs::ListControllerTypes::Request &req,
                                controller_manager_msgs::ListControllerTypes::Response &resp);
     bool listControllersSrv(controller_manager_msgs::ListControllers::Request &req,
                             controller_manager_msgs::ListControllers::Response &resp);
     bool switchControllerSrv(controller_manager_msgs::SwitchController::Request &req,
                              controller_manager_msgs::SwitchController::Response &resp);
     bool loadControllerSrv(controller_manager_msgs::LoadController::Request &req,
                            controller_manager_msgs::LoadController::Response &resp);
    bool unloadControllerSrv(controller_manager_msgs::UnloadController::Request &req,
                           controller_manager_msgs::UnloadController::Response &resp);
     bool reloadControllerLibrariesSrv(controller_manager_msgs::ReloadControllerLibraries::Request &req,
                                       controller_manager_msgs::ReloadControllerLibraries::Response &resp);
     boost::mutex services_lock_;
     ros::ServiceServer srv_list_controllers_, srv_list_controller_types_, srv_load_controller_;
    ros::ServiceServer srv_unload_controller_, srv_switch_controller_, srv_reload_libraries_;
     
   };



二 controller_manager使用方法

  controller_manager可以基于你运行controller的不同方式(启动文件的方式,命令行的方式,ROS node方式)诉求, 提供相应的工具来运行controller,以下是controller_manager运行controller的简单状态机,

 


下面基于不同方式,介绍controller_manager如何运行controller:


1 Command-line tools

 

1.1 controller_manager

可以使用controller_manager脚本实现controller_manager与controller交互。


(1)controller_manager与controller交互命令

$ rosrun controller_manager controller_manager <command> <controller_name>

命令选项:

  • load: 加载controller (controller构造和初始化)

  • unload: 卸载controller (析构controller)

  • start: 启动controller

  • stop: 停止controller

  • spawn: 加载并启动controller

  • kill: 停止并卸载controller

(2)获取controller状态的命令

 $ rosrun controller_manager controller_manager <command>

命令选项:

  • list: 按照controller启动运行顺序给出每个controller的状态

  • list-types: 列出所有controller_manager管理的controller类型。如果你要使用controller不在该列表你 就不能启动它

  • reload-libraries: 重载所有controller插件库。插件方式的controller库在开发新的controller是非常便于测试,不需要每次重启robot。这不会重启之前运行的controllers

  • reload-libraries --restore:  重载所有controller插件并恢复controller到原始状态。


1.2 spawner

使用该工具可以实现一次自动加载并启动所有controller,一次自动停止并卸载所有controller。

$ rosrun controller_manager spawner [--stopped] name1 name2 name3

当你运行spawner且没有指定--stoped时候,所有命令中列举的controller将被加载和启动。 the listed controllers will get loaded and started (unless you specify --stopped). 如果controller出于up状态,Spawner会保持运行它。当你执行ctrl-c或者kill spawner时候,将自动停止并卸载之间加载启动的controller。

1.3 unspawner

   实现自动停止,然后重启controller的功能,

$ rosrun controller_manager unspawner name1 name2 name3

命令列举的controllers会被停止,但是不会被卸载。 一旦spawner关闭,controller将被重启。


2 launch files

  我们可以在启动文件让controller_manager来启动 controllers,但是这种方式在launch被down时候controller还会保持up。 而在启动文件中使用spawner的话,可以实现controller的自动加载启动和停止卸载(当你启动spawner时候加载并启动controller,当停止spawner<launch文件down>时候停止并卸载controller)。

<launch>
   <node pkg="controller_manager"
         type="spawner"
         args="controller_name1 controller_name2" />
 </launch>

或者你只想加载controller但是不启动的话

 <launch>
   <node pkg="controller_manager"
         type="spawner"
         args="--stopped controller_name1 controller_name2" />
 </launch>

3 Graphical tools

rqt_controller_manager是rqt的一个插件,允许图形化的方式加载,卸载,启动,停止controller, 并显示加载的controller信息。

 从rqt的plugin menu或者如下命令行都可以运行,

rosrun rqt_controller_manager rqt_controller_manager

 

4 ROS API

如果要使用ROS node中与controller交互,可以使用controller_manager提供的5中service调用:

controller_manager/load_controller (controller_manager_msgs/LoadController)

  • 该service请求应该含有要加载的controller名字,service响应以bool指示成功or失败。
controller_manager/unload_controller ( controller_manager_msgs/UnloadController)
  • 该service请求应该含有要加卸载的controller名字,service响应以bool指示成功or失败。注意,仅有出于stopped状态的controller可以被卸载。
controller_manager/switch_controller ( controller_manager_msgs/SwitchController)
  • 该service请求包含要启动的controller名字list,要停止的controller名字list,以及一个表明约束度 (BEST_EFFORT or STRICT)的int变量。 STRICT意思是只要有一个controller无效(如非法controller name,controller不能启动等),switch就会失败。  BEST_EFFORT意思是有些controller无效,但是仍然会启动/停止其它剩余controller。 service响应以bool指示成功or失败。
controller_manager/list_controllers ( controller_manager_msgs/ListControllers)
  • 该service返回目前所有加载了的controller。响应信息包括: controller name, state (running or stopped), type, hardware interface and claimed resources。
controller_manager/list_controller_types ( controller_manager_msgs/ListControllerTypes)
  • 该service返回所有controller_manager注册管理的controller类型。
controller_manager/reload_controller_libraries ( controller_manager_msgs/ReloadControllerLibraries)

            该service重载所有controller插件库。当开发新controller时候,不用每次重启robot就可以测试新code,非常方便。这个service只有当没有controller被加载时候才能work。



### 加载并激活 ROS2 控制器 为了加载并激活 `fishbot_joint_state_broadcaster` 控制器,在 ROS2 中通常需要遵循特定的过程。这涉及到编辑控制器配置文件以及编写启动脚本来确保控制器能够正确初始化。 #### 编辑控制器配置文件 控制器的参数一般定义在一个 YAML 文件中,此文件指定了要使用的具体控制器及其属性。对于 `joint_state_broadcaster` 类型的控制器来说,应该有如下形式的内容: ```yaml controller_manager: ros__parameters: update_rate: 100 # 更新频率设置为每秒100次 fishbot_joint_state_broadcaster: type: joint_state_broadcaster/JointStateBroadcaster ``` 上述代码片段展示了如何指定控制器管理器更新速率和声明 `fishbot_joint_state_broadcaster` 的类型[^1]。 #### 创建启动文件 接下来,创建一个用于加载这些配置并将控制器添加到控制器管理器中的 Python 启动脚本或者 launch 文件。下面是一个简单的例子,演示了怎样利用 Launch API 来实现这一点: ```python from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): return LaunchDescription([ Node( package='controller_manager', executable='spawner.py', arguments=['fishbot_joint_state_broadcaster'], output='screen' ), ]) ``` 这段代码的作用是在运行时调用 controller_manager 提供的 spawner 工具来实例化所需的广播器[^2]。 #### 使用命令行工具激活控制器 除了编程方式外,还可以直接通过命令行工具来进行操作。一旦完成了前面提到的工作空间构建与环境准备之后,可以执行以下指令来加载并启动控制器: ```bash ros2 control load_controller fishbot_joint_state_broadcaster --set-state start ``` 这条命令将会向控制系统发送请求以装载指定名称的控制器,并立即将其状态设为活动模式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值