分享

ros

 Jack_WangChong 2016-05-09

ros_control 是个什么东西?

 

ros_control 脱胎于pr2 的 硬件封装层部分 pr2_mechanism,经过pal-robotics 和 hidof 两个公司的工程师进行了改写,变得适用于所有机器人的硬件封装库,负责统一管理硬件驱动与传感器底层细节,处理异常,分配资源,向上提供统一接口。作为一个end2end的ROS 机器人系统集成解决方案。

ros_control 是一个类库!! 并不是直接的工具库,需要自己写程序继承特定基类来做到接口的统一。

Ros_control 使用的最直接好处是可以复用 ros-controllers 里面的一些控制算法,以及与支持ros_control的仿真器 gazebo 的良好支持。

ros_control 框架最大的问题,很多模块严重冗余,很多部分设计突出一个没必要,架构过于复杂,很多模块象征意义大于实际意义,我认为更多是提供一个系统集成的思路或者雏形,具体完善到工业级还得好长的路要走,所以想拿这个框架去做产品的群友可以歇着了。(以上个人看法,欢迎交流,不喜勿喷)学习曲线陡峭没文档。

 

澄清一点,下面的模块说明与ROS通讯架构(node topic),文件系统架构(package)都没关系,指的是使用类库写程序的架构, ros_control各个模块与其他第三方模块在一个工程中紧耦合。运行时一般是一个node。

看这个图:

http://wiki./ros_control?action=AttachFile&do=get&target=gazebo_ros_control.png

 

基本架构是这样的:

机器人的硬件通讯库(串口,can, ethercat, 等等)

ros_control 的robot_hw部分

controller_manager 部分 与具体的 controller

controller 部分就会提供给ROS系统中其他上层组件标准控制与感知接口,比如 topic : cmd_vel,joint/command action:trajectory_server 等等。

 

Controller_manager 与很多controller都已经很完善了,需要写的就是robothw部分

一个最简单的ros_control例子:

https://github.com/ros-controls/ros_controllers/blob/indigo-devel/diff_drive_controller/test/diffbot.h

https://github.com/ros-controls/ros_controllers/blob/indigo-devel/diff_drive_controller/test/diffbot.cpp

 

核心代码讲解:

这个代码把diff_drive_controller 单独下下来, 编译,然后launch diff_drive_common.launch就可以运行起来啦。

在diffbot.h 中定义了一个双轮差速小车的模型。

Diffbot 类中定义了小车的joint 信息(位置,速度,扭矩? 力? ,pos, vel,effort),来描述关节的状态,又定义了cmd来存储对关节的控制量。设置了不同的hardware_interface对相应数据进行注册(line 69-73),然后将不同的控制接口注册到robothw上(76-77).

实现了 两个虚方法 read 和write ,因为是个demo,所以处理数据非常简单。

在diffbot.cpp 中给出了ros_control的运行流程,将robothw类传给controller_manager, controller_manager会查看响应对应hardware_interface,使用的时候,通过 service 告诉controller_manager load 对应类型及其相应的参数(launch文件中),启动controller,即可。

(line 47)制定数据更新周期。在(line 50-56)的循环中,进 robothw read读数据,然后controller_manager 调用 controller update, 最后将更新过的数据进 robothw write 写数据。

 

ros_control 核心概念:

通过上面那个最简单的例子,想必大家对ros_control 有了一个直观的了解。以下是最重要的概念讲解:

hardware_interface: 作为ros_control 组件最重要的一部分,做了以下抽象

  1. 将能动的部分(类似于机器人关节)抽象为joint,joint 类型有旋转,平动,固定等等,详见urdf,joint有三个属性,pose,velocity,effort,位置和速度好理解,effort 不同的joint类型有不同的含义,一般是力矩,力(语义比较混乱在各个不同派系的开源代码中)。执行器模型抽象为actuator ,与joint不一样的部分是actuator的属性值需要一定变换才能对应到joint,可以理解为电机减速,或者机构传动。
  2. 根据不同的控制方式或者不同的传感器暴露出相应的数据接口,一般移动机器人底盘是速度闭环,而机械臂上又是位置闭环,根据这些控制方式的不同分出了不同的控制接口,暴露给上层的controller。
  3. 作为机器人的硬件资源与上层的直接接口,可以被运行时产生与删除,结合机器人本身的通讯组件这样实际上实现了一种对机器人硬件资源的低层次管理。

 

而hardware_interface 具体实现方式是存储对应状态变量的指针,用字符串表示不同的joint与 Actuator 资源。robothw 基类是 硬件通讯库与hardware_interface交互的部分。硬件通讯库具体的读写过程都在read 与 write 两个虚方法中实现,更新的数据放在robothw类的成员变量中,这些存储着joint 与actuator 状态与命令的空间被hardware_interface索引,传给controller_manager ,通过controller_manager的接口将数据接给controller。所以ros_control内部不存在进程间通讯。

 

Transmission

专门负责处理actuator to joint pos vel eff的映射,因为机械,电子等一系列原因,上层发出来的joint数据与actuator总是有各种各样的差别,比如有常数偏差offset,或者锥齿轮差动机构,四连杆机构等等。Transmission提供了解决这些的一个工具,就是各种映射公式。(为了支持动态加载这些个不太实用的功能接口整的巨复杂,不太推荐使用)

 

Joint limits interface

用来存储,管理各个joint的极限pos,vel,eff,(也是整的很复杂,不太推荐用)

 

以上两个模块是因为urdf有相应的标签,写了一堆可以直接load的,但是实际用处并不是很大,它设计思想是在urdf中表示更多的信息,这些信息在gazebo中可以给出更多细节。但是解析urdf的程序得robothw中体量很大,而且这些细节因为机器人本体通讯暴露给ROS的细节量不尽相同,而且会显著提高编程复杂度,所以这些信息显得冗余,而应用这些信息的库也就显得冗余。

 

这样的话,ros_control部分就算是写清楚了,具体再去看ros_control 的tutorial 就知道具体怎么使用哪些类库了。

使用ros_control 的具体机器人工程代码:

https://github.com/shadow-robot/ros_ethercat

https://github.com/jhu-lcsr/barrett_control

https://github.com/davetcoleman/baxter_cpp/blob/hydro-devel/baxter_control/src/baxter_hardware_interface.cpp

可以参考这些代码。

下一个写 ros_controllers controllers

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多