参考文:
pr2_mechanism - ROS Wiki
pr2_controller_interface - ROS Wiki
一、 摘要
要学习好ROS-control,先学好PR2。ROS-control的基础是pr2,PR2(Personal Robot 2.简称人形机器人2代)Willow Garage数字2代表第二代机器人是公司设计的机器人平台。本文将在此介绍ROS中的pr2机制及相应的接口开发原理。
PR2(人形机器人2代)有两个手臂,每个手臂有七个关节,手臂末端有一个可以张合的夹爪;PR依靠底部的四个轮子移动,在头部、胸部、肘部、夹爪上分别安装有高分辨率摄像头、激光测距仪、惯性测量单元、触觉传感器等丰富的传感设备。在PR2底部有两台八核电脑作为机器人硬件的控制和通信中心,都安装了Ubuntu和ROS系统。
PR2和ROS有千丝万缕的关系,可以说ROS产生于PR2,也促成了PR2。ROS原本是Willow Garage为复杂的PR2机器人平台设计的软件框架依赖于强大的ROS,PR2可以独立完成各种复杂的任务,如PR可自己开门,找插头给自己充电,打开冰箱取出啤酒,打简单的台球等等。只不过PR目前主要用于学术研究,价格高,能力不能满足商业应用的要求。
可见,PR2是ROS所有的软件代码都依赖于中元老机器人平台ROS,并且全部在ROS为我们学习和应用社区开放源代码ROS资源丰富。
二、Pr几个关键机制
pr2_mechanism 堆栈包括硬实时控制循环中的控制 PR2 机器人基础设施。
如果你想写一个实时控制器和 PR2(或类似)机器人交互,pr2_mechanism 堆栈包含有用的库。这些库包含在以下 ROS 包中:
-
pr2_controller_interface: The C 接口实时控制。interface for a realtime controller
-
pr2_controller_manager:允许您在实时循环中操作和管理多个控制器的基础设施
-
pr2_hardware_interface: The C PR2 硬件接口包括执行器、压力传感器、加速度计、数字输出和投影仪接口。
-
pr2_mechanism_model: 基于机器人模型的努力控制 urdf 机器人描述格式。
-
pr2_mechanism_msgs: 包括实时控制器、关节和执行器状态在内的实时控制电路通信消息。
-
realtime_tools: 实时发布 ROS 主题工具。
三、pr2_controller_interface接口实时控制
该包指定了实时控制器的接口。实现该接口的控制器可由控制器管理器在实时控制循环中执行。这个包基本上包含了所有需要继承的控制器 C 控制器基类。
3.1pr2_controller_interface基类构成
要实现实时控制器,您的控制器需要从 pr2_controller_interface::Controller 基类继承。基类包括
- 初始化、启动、更新和停止四种方法:.
- 还有一种你可以调用的方法:getController。
基类如下:
namespace pr2_controller_interface { class Controller { public: virtual bool init(pr2_mechanism_model::RobotState *robot, ros::NodeHandle &n); virtual void starting(); virtual void update(); virtual void stopping(); bool getController(const std::string& name, int sched, ControllerType*& c); }; }
下图显示了这四种方法的调用顺序(详见下文)。
3.2 初始化接口
init 该方法不实时执行。
virtual bool init(pr2_mechanism_model::RobotState *robot, ros::NodeHandle &n);
加载控制器时会调用 init 初始化控制器的方法。请注意,初始化控制器与启动控制器无关:初始化可在启动控制器前的任何时间完成。 init 该方法有两个参数:
robot:这是对机器人模型的描述 pr2_mechanism_model::RobotState(参见 pr2_mechanism_model)。该模型提供对机器人关节(致动器、编码器等)的访问,并包含机器人机构的运动学/动态描述。
n:这个 ros::NodeHandle 它是控制器的命名空间。在节点句柄的命名空间中,控制器可以从参数服务器读取配置并发布主题。
若初始化成功,init 方法将返回。如果初始化失败,控制器将被控制 pr2_controller_manager 卸载。确保始终使用 ROS_ERROR("explanation");通知用户您的控制器未能初始化的原因。控制器只能初始化一次。若要重新初始化控制器,则需先卸载,再重新加载。
3.3 启动控制器
硬实时执行启动方法。
virtual void starting();
每次启动控制器时,控制器管理器都会调用启动方法。启动在与第一次更新调用相同的循环中执行,在此更新调用之前。
第一次调用 update 之前,starting 方法初始化控制器。控制器管理器可以在不卸载/加载控制器的情况下重新启动控制器。
3.4 更新控制器
硬实时执行更新方法。
virtual void update();
每个控制器的更新方法由 pr2_controller_manager 以 1000 Hz 定期调用频率。这意味着所有控制器组合的执行时间不能超过 1 毫秒。真正的控制工作在更新循环中完成。
3.5 停止控制器
实时执行停止方法。
virtual void stopping();
每次停止控制器时,都会调用一个停止方法。停止在与最后一次更新调用相同的循环中,在此更新调用后。停止方法不返回任何内容,不允许失败。
3.6 请求指向另一个控制器的指针
getController 该方法不实时执行。
bool getController(const std::string& name, int sched, ControllerType*& c);
getController 该方法允许控制器获得指向另一个控制器的指针。这是用来创建控制器的链,每个控制器实时输出到下一个控制器。该系统是非实时的 ROS 通信的替代品。
getController 接受三种方法数:
- name:一个字符串,其中包含您要获取指针的控制器的名称。
- sched:一个 int (ENUM),它指定请求的控制器是否应该在您的控制器之前或之后执行。可能的值为 pr2_controller_interface:BEFORE_ME 和 pr2_controller_interface::AFTER_ME。
- c 这是指向您请求的控制器的指针,其类型与请求的控制器的类型相匹配。该类型也是 getController 方法的模板参数。
四、结尾
以上介绍pr2的controller_interface基类是啥构成,ROS的构建与此类同。事实上,有了以上概念,用户可以自己写控制接口。