使用moveit!控制真实机械臂(4)——了解moveit!所使用的action

action知识要点回顾:

action是ROS下节点间数据通信的一种方式,这种方式本质也是基于ros消息的,之前你应该频繁的使用或ros的消息,应该能够基本掌握订阅、发布消息,此时,能够用到action表明你已经进入到ros编程的一个新阶段。action的基础内容可以先看一下ros 官网和古月的博客,可以这样简单理解:action打包了同一行为下的多个消息,使用action可以将你从繁琐的消息订阅与发布编程中解放出来,并且使节点间的信息交互能力大大提升,对于如何使用action,网上别的教程都讲了很多,这里只强调几个我所认为的要点:
1、action是需要配对的。客户端与服务端配对,插座与插头的关系,产生联系的纽带是你定义action时指定的action名字。

//以下是官网代码摘抄

//来自服务端
typedef actionlib::SimpleActionServer<chores::DoDishesAction> Server;
Server server(n, "do_dishes", boost::bind(&execute, _1, &server), false);

//来自客户端
typedef actionlib::SimpleActionClient<chores::DoDishesAction> Client;
Client client("do_dishes", true);

2、action是有类型的。无论你定义action客户端/服务端变量,还是编写action的相关回调函数,这些变量、回调函数都需要你指定一个action数据类型,客户端、服务端不匹配的数据类型将在编译时报错。比如下面的定义,as_是一个服务端的action,<>是模板的用法,里面放入什么action类型,定义的action就是什么类型。

//定义了一个control_msgs::FollowJointTrajectoryAction类型的action,不认识这个类型没关系,只需明白这是一种action类型就好
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction> as_;   

3、action是需要“提前”初始化的。比如你定义了一个类,成员包含一个action服务端变量as_,那么,在你这个类的实例执行构造函数之前,as_就得初始化,具体方法就是将as_的初始化放到类的构造函数初始化列表中。如果action变量不是C++类的成员,则不存在这个问题。

了解Moveit!中的action:

官网上的教程和许多网上博文在讲action时,一般是教你编写一个action客户端和一个action服务端,告诉你新建一个action文件夹,再编写action的描述文件……这是在使用自定义的action,就像ros的消息系统中的自定义消息一样,但在使用moveit!时,不需要你自定义action,因为系统中有很多现成的action拿出来使用就行,因此,需要你自己写的代码其实很没那么多,先了解一下moveit!都使用了哪些action,看一看下图:
使用moveit!控制真实机械臂(4)——了解moveit!所使用的action_第1张图片
这张图是我使用moveit!配置助手生成了一份配置文件后,只启动配置文件demo.launch产生的节点图(rqt_graph界面中没有勾选action选项,因为这样看反而更清晰一些),如何生成moveit配置文件参见这里,如果你也启动了你的demo.launch,发现和上图不太一样,没事,看主要部分就好。我们重点关注这些信息:
1、action是什么样子的?
上图中右侧有4个大方框,每个方框包含了好几个消息,这些消息有一个共有的特点:结尾都是/goal 、 /cancel、 /result、/feedback、 /status,这个方框里的全部就构成了一个action,这与下图的表述也是一致的。
使用moveit!控制真实机械臂(4)——了解moveit!所使用的action_第2张图片
2、moveit用了哪些action?
可以肯定的是,moveit!使用了不止一个action,每个action的名称就是将/goal 、 /cancel、 /result、/feedback、 /status,这些后缀去掉后,前面共有的部分。比如上图中move_group、execute_trajectory、place、pickup,每个action各自掌管着一些行为,这些action我也只能从名字上会意一下,从下图的moveit!结构图中也可以看到,这些action是外部节点与move_group(moveit!的核心)交互的重要桥梁。
使用moveit!控制真实机械臂(4)——了解moveit!所使用的action_第3张图片
3、moveit使用哪个action控制真实机器人?
我们的目的是使用moveit控制真实的机械臂,而我们真正需要的action是FollowJointTrajectoryAction(上图蓝色箭头所指),这个action是moveit留出来专门控制真实机器人的,官网对此的描述如下:
使用moveit!控制真实机械臂(4)——了解moveit!所使用的action_第4张图片
上图英文中也涉及到一点重要概念:关于这个action接口,moveit扮演的角色是客户端,服务端才是我们需要编写的部分,不要搞反了。

然而,从文章最上部的图1可以看出,启动刚开始生成的moveit!配置文件中的demo.launch文件后,节点图中并没有出现FollowJointTrajectoryAction这个action,这是因为刚生成的moveit!配置文件默认是用来控制虚拟机器人的,并不是针对真实机器人的,启动文件里有个参数可以选择是否控制真实机械臂,并且还得自己写/修改几个配置文件,修改后再次启动demo.launch文件,就能看见FollowJointTrajectoryAction,具体方法会写在下一篇博文。这里先提前放个图,预览一下FollowJointTrajectoryAction的样子(红框内话题的前缀是机械臂的名字)。

这里我们还是重点关注FollowJointTrajectoryAction这个action,有兴趣可以看一下control_msgs/FollowJointTrajectory Action的具体定义,它的内部有一个重要成员 trajectory,当你使用moveit规划了一个机械臂运动路径时,它记录了机械臂运动的各个轨迹点,每个轨迹点以机械臂关节角的形式表述,这个数据也是我们最终控制机械臂所想要的最终数据,如何编写程序利用这个数据控制机械臂,会写在下一篇文章。

你可能感兴趣的:(机器人,嵌入式系统设计,程序设计,ROS,ROS程序开发自学笔记)