ROS control-----hardware_interface简介

本文详细介绍了ROS_Control中的hardware_interface模块,包括其主要数据结构如resource_handle、hardware_interface和RobotHW等,以及如何通过自定义实现扩展功能。同时给出了具体的代码示例。
   hardware_interface在ros_control中占有重要地位,controller通过hardware_interface与机器人硬件获得连接。


1 hardware_interface主要数据结构

1.1 resource handle

    这些handle主要功能包括存入resource,并提供相应获取resource接口。




1.2 hardware interface

    这些硬件接口主要功能有register handle/get handle/和claim resource/clearclaim/getclaims等。


1.3 RobotHW

    定义了一些框架接口如下,用户可以填充实现。

a)hardware interface切换:

virtual bool init (ros::NodeHandle &root_nh,ros::NodeHandle &robot_hw_nh)

virtual bool prepareSwitch (const std::list< ControllerInfo > &start_list, const std::list< ControllerInfo > &stop_list)

virtual void doSwitch (const std::list< ControllerInfo > &, const std::list< ControllerInfo > &)

virtual void read (const ros::Time &time, constros::Duration &period)

virtual void write (const ros::Time &time, constros::Duration &period)

b)resource管理

virtual bool checkForConflict (const std::list< ControllerInfo > &info) const

另外由于该接口继承了hardware_interface::InterfaceManager所以还支持:

T * get ()

std::vector< std::string > getInterfaceResources (std::string iface_type) const

std::vector< std::string > getNames () const

void registerInterface (T *iface)

void registerInterfaceManager (InterfaceManager *iface_man)




2 应用示例

  这里参考了ROS wiki给出如何定义自己robot并使用controller manager控制它。

  目前ros_control已经支持了一些常用标准hardware interface和controller,如果能满足需求可以直接使用,如果不能满足需求可以自定义扩展自己的接口和controller,如下示意图所示:


      上图中白色框中接口是ros_control已经支持的标准hardware接口,对应是已经支持的controller,下面Robot Specific controller是用户扩展定义的controller。


#include <hardware_interface/joint_command_interface.h>
#include <hardware_interface/joint_state_interface.h>
#include <hardware_interface/robot_hw.h>

class MyRobot : public hardware_interface::RobotHW
{
public:
  MyRobot() 
 { 

   //register and use existing robot standard hardware interfaces
   // connect and register the joint state interface
   hardware_interface::JointStateHandle state_handle_a("A", &pos[0], &vel[0], &eff[0]);
   jnt_state_interface.registerHandle(state_handle_a);

   hardware_interface::JointStateHandle state_handle_b("B", &pos[1], &vel[1], &eff[1]);
   jnt_state_interface.registerHandle(state_handle_b);

   registerInterface(&jnt_state_interface);

   // connect and register the joint position interface
   hardware_interface::JointHandle pos_handle_a(jnt_state_interface.getHandle("A"), &cmd[0]);
   jnt_pos_interface.registerHandle(pos_handle_a);

   hardware_interface::JointHandle pos_handle_b(jnt_state_interface.getHandle("B"), &cmd[1]);
   jnt_pos_interface.registerHandle(pos_handle_b);

   registerInterface(&jnt_pos_interface);

   
   //register some robot specific interfaces
registerInterface(&cool_interface);
//Implement robot-specific resouce management
bool checkForConflict(const std::list<ControllerInfo>& info) const
{ // this list of controllers cannot be running at the same time
 ... return true;
// this list of controller can be running at the same time
...
return false;
}

}

private: hardware_interface::JointStateInterface jnt_state_interface;
//standard hardware interface
hardware_interface::PositionJointInterface jnt_pos_interface;//standard hardware interface
MyCustomInterface cool_interface; //custom specific hardware interface
double cmd[2]; double pos[2]; double vel[2]; double eff[2];

}




以上添加了custom hardware interface来支持用特定controller做特定控制;另一种方式是在MyRobot仅仅添加一些特定函数接口实现特定控制(没有定义特定硬件接口class),通过MyRobot类自注册实现这些接口的可访问如下,

#include <hardware_interface/joint_command_interface.h>
#include <hardware_interface/joint_state_interface.h>
#include <hardware_interface/robot_hw.h>

class MyRobot : public hardware_interface::RobotHW, public hardware_interface::HardwareInterface
{
public:
  MyRobot()
 {
   //register and use existing robot standard hardware interfaces
   // connect and register the joint state interface

   hardware_interface::JointStateHandle state_handle_a("A", &pos[0], &vel[0], &eff[0]);
   jnt_state_interface.registerHandle(state_handle_a);

   hardware_interface::JointStateHandle state_handle_b("B", &pos[1], &vel[1], &eff[1]);
   jnt_state_interface.registerHandle(state_handle_b);

   registerInterface(&jnt_state_interface);

   // connect and register the joint position interface
   hardware_interface::JointHandle pos_handle_a(jnt_state_interface.getHandle("A"), &cmd[0]);
   jnt_pos_interface.registerHandle(pos_handle_a);

   hardware_interface::JointHandle pos_handle_b(jnt_state_interface.getHandle("B"), &cmd[1]);
   jnt_pos_interface.registerHandle(pos_handle_b);

   registerInterface(&jnt_pos_interface);

 

    // register the MyRobot class itself to make the 'someCoolFunction' available
    // the MyRobot class inherits from HardwareInterface to make this possible


     registerInterface(this);

     void someCoolFunction();


   // Implement robot-specific resouce management
    bool checkForConflict(const std::list<ControllerInfo>& info) const
    {
       // this list of controllers cannot be running at the same time
       ...
       return true;

       // this list of controller can be running at the same time
       ...
       return false;
    }


  }

  private:
  hardware_interface::JointStateInterface jnt_state_interface; //standard hardware interface
  hardware_interface::PositionJointInterface jnt_pos_interface;//standard hardware interface
  double cmd[2]; double pos[2]; double vel[2]; double eff[2];

};



以上的MyRbot class通过如下代码,就可以被controller manager和controller使用了:


main()
{
   MyRobot robot;
  controller_manager::ControllerManager cm(&robot);

  while (true)
  {
     robot.read(); //to access hardware driver, generally need do some wrap and customization in MyRobot class
     cm.update(robot.get_time(), robot.get_period());
     robot.write(); //to access hardware driver, generally need do some wrap and customization in MyRobot class
     sleep();
  }
}




3 参考文献

  参考ROS WiKi改编。





<think>嗯……用户这次提出了一个非常具体的ROS 2技术问题,关于启动launch文件时找不到franka_ign_ros2_control-system的错误。从问题描述的精确性来看,用户应该是个 robotics方向的开发者,正在部署Franka机械臂的仿真环境。 注意到用户特意强调要参考站内引用,但当前对话历史中并没有相关引用记录。这说明用户可能误操作了,或者是在延续某个中断的对话?考虑到技术问题的连续性,决定聚焦当前报错本身提供解决方案。 用户的核心痛点很明确:缺少关键组件导致launch失败。这个错误通常发生在三种场景:1)安装不完整 2)环境配置错误 3)版本冲突。需要给用户系统化的排查路径。 首先想到的是包安装验证,因为90%的类似报错都是缺依赖。franka_ign_ros2_control-system这个包名带有system后缀,说明它是被设计为系统级控制插件,很可能需要从源码编译。用户可能遗漏了colcon build步骤,或者build时没包含这个包。 环境配置部分要重点检查AMENT_PREFIX_PATH,ROS 2的环境激活是个常见坑点。特别是使用Ignition Gazebo时,它的版本必须和ROS 2发行版严格匹配——比如用户如果用的humble,就必须对应fortress版本。 突然意识到用户没提供ROS版本信息!这会影响方案准确性。不过从包名包含ign_ros2_control来看,大概率是较新的Galactic或Humble。在回复里需要提醒用户确认这点。 编译系统方面,CMakeLists.txt的find_package调用容易出错。打算给用户示范正确的ament依赖声明方式,特别是对ros2_control_test_assets这类测试依赖项,新手经常忘记添加。 最后需要强调debug技巧:ros2 pkg list和colcon list能快速验证包是否存在,而ldd可以检查动态链接——后者对插件加载失败特别有用。用户如果看到libfranka_ign_ros2_control-system.so缺失就真相大白了。 考虑到用户可能急着调试,把解决方案按优先级排序:先验证安装和环境,再检查编译配置,最后考虑源码级修复。每个步骤都给出可直接执行的命令,比如那个关键的find /路径 -name "franka_ign*"搜索模板。 要不要提醒用户检查机械臂许可证?算了下这属于franka_driver层的错误,和当前插件加载无关,先不增加复杂度了。等用户反馈后再深入也不迟。 </think>以下是针对Franka机械臂ROS 2环境下启动launch文件时提示 **找不到`franka_ign_ros2_control-system`** 的解决方案的完整排查流程: --- ### **1. 验证包是否安装** #### 步骤: ```bash # 在ROS 2工作空间下检查包是否存在 source install/setup.bash ros2 pkg list | grep franka_ign_ros2_control ``` - **预期结果**:输出 `franka_ign_ros2_control` - **问题解决**: - 若未输出,说明未安装或编译失败,需重新编译安装(见步骤2)。 --- ### **2. 重新编译安装** #### 关键命令: ```bash # 进入工作空间根目录 cd ~/ros2_ws # 清理旧编译文件(可选) rm -rf build install log # 重新安装依赖并编译 rosdep install --from-paths src --ignore-src -y colcon build --symlink-install --packages-select franka_ign_ros2_control ``` - **必须参数**: - `--packages-select`:仅编译缺失包以节省时间 - `--symlink-install`:防止后续源码修改需重复编译 --- ### **3. 检查环境变量** #### 常见配置问题: ```bash # 确认环境变量已加载 echo $AMENT_PREFIX_PATH | grep franka_ign_ros2_control # 若未输出,手动加载工作空间 source ~/ros2_ws/install/setup.bash ``` - **典型错误**:在未激活工作空间的终端中启动launch文件。 --- ### **4. 验证Ignition版本兼容性** - **版本要求**: - `franka_ign_ros2_control` 需匹配 **ROS 2发行版** 和 **Ignition版本**(如Humble+Ignition Fortress) - 检查方法: ```bash ignition gazebo --versions # 查看Ignition版本 printenv ROS_DISTRO # 查看ROS 2发行版 ``` - **解决方案**: - 版本不匹配时,从Franka官方文档确认兼容矩阵或更新对应软件包[^1]。 --- ### **5. 排查插件声明问题** #### 检查控制插件配置: 在URDF或launch文件中确认是否正确声明插件: ```xml <ros2_control name="FrankaSystem" type="system"> <hardware> <plugin>franka_ign_ros2_control/FrankaSystem</plugin> <!-- 其他参数 --> </hardware> </ros2_control> ``` - **易错点**: - `type="system"` 未声明 - 插件路径 `franka_ign_ros2_control/FrankaSystem` 拼写错误 --- ### **6. 动态链接库检查** #### 查看插件是否被正确链接: ```bash # 定位插件库文件 find ~/ros2_ws/install -name "libfranka_ign_ros2_control-system.so" # 检查LD_LIBRARY_PATH echo $LD_LIBRARY_PATH | grep franka_ign_ros2_control ``` - **修复未链接**: ```bash export LD_LIBRARY_PATH=~/ros2_ws/install/franka_ign_ros2_control/lib:$LD_LIBRARY_PATH ``` --- ### **7. 源码级修复(高级)** 若以上无效,尝试: 1. 检查包依赖声明: ```cmake # 在franka_ign_ros2_control的CMakeLists.txt中 ament_export_dependencies(ros2_control_hardware_interface) ``` 2. 确认插件注册代码: ```cpp #include "franka_ign_ros2_control/franka_system.hpp" PLUGINLIB_EXPORT_CLASS(franka_ign_ros2_control::FrankaSystem, hardware_interface::SystemInterface) ``` --- ### **总结排查流程** ```mermaid graph TD A[启动报错] --> B{包是否存在?} B ----> C[重新编译安装] B ----> D{环境变量正确?} D ----> E[手动加载环境] D ----> F{版本兼容?} F ----> G[更新Ignition/ROS] F ----> H{插件声明正确?} H ----> I[修正URDF/launch] H ----> J{链接库正常?} J ----> K[配置LD_LIBRARY_PATH] J ----> L[检查源码注册] ``` --- ### **相关问题** 1. 如何为Franka机械臂配置Ignition Gazebo仿真环境? 2. ROS 2控制框架中`system`插件与`sensor`插件的区别是什么? 3. 调试ROS 2硬件接口时有哪些常用工具? [^1]: Franka官方ROS 2文档要求确认兼容性: [franka_ros2 Documentation](https://frankaemika.github.io/docs)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值