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 组件最重要的一部分,做了以下抽象
而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
|
|
来自: Jack_WangChong > 《待分类》