前面我们探讨了ros的两种通信方式,话题和服务,服务机制常用于同步的请求/响应交互方式。
话题则是单工通信,尤其是接收方有多时(比如传感器数据流),然而,当需要完成的任务比较复杂时,
服务和话题都不是一个很好的选择,为了解决这些问题,ros引入了动作机制,ros的动作机制非常适合作为时间
不确定,目标导向型的操作的接口,服务是同步的,动作是异步的,与服务的请求/响应结构类似,从原理上来看,
动作使用话题来实现,其本质相当于一个规定了一系列话题(目标,结果,反馈)的组合使用方法的高层协议。
动作的定义
创建一个动作,首先要在动作文件中定义目标,结果和反馈的消息格式。动作定义文件的后缀名为.action。其组成与服务的.srv文件非常类似。只是多了一个消息项。
在编译的过程中,.action文件也会打包为一个消息类型。
为了方便,我们定义一个行为类似定时器的动作。
例:定义一个人满足定时器要求的动作(Timer.action)
1 # This is an action definition file, which has three parts: the goal, 2 #the 3 # result, and the feedback. 4 # 5 # Part 1: the goal, to be sent by the client 6 # 7 # The amount of time we want to wait 8 duration time_to_wait 9 --- 10 # Part 2: the result, to be sent by the server upon completion 11 # 12 # How much time we waited 13 duration time_elapsed 14 # How many updates we provided along the way 15 uint32 updates_sent 16 --- 17 # Part 3: the feedback, to be sent periodically by the server during 18 # execution. 19 # 20 # The amount of time that has elapsed from the start 21 duration time_elapsed 22 # The amount of time remaining until we're done 23 duration time_remaining
就像定义服务文件一样,我们用三个短划线表示不同部分的分隔符,动作文件有三个部分(目标,结裹,和反馈)。动作定义文件Timer.action应该ROS包的目录下。位于basic包下。
编写好定义文件后,下一步就是运行catkin_make,创建该动作实际使用的代码和类定义。需要在CMakeLists.txt中和package.xml中添加一些内容。
首先在CMakeLists.txt中添加如下
将actionlib_msgs附加在包下
10 find_package(catkin REQUIRED COMPONENTS 11 roscpp 12 rospy 13 std_msgs 14 #other packages are aleardy listed here 15 actionlib_msgs
确保你已经在generate_message()中列出所有的消息依赖。
75 generate_messages( 76 DEPENDENCIES 77 std_msgs 78 actionlib_msgs 79 )
最后在catkin_package中添加actionlib_msg依赖
110 catkin_package( 111 # INCLUDE_DIRS include 112 # LIBRARIES basic 113 CATKIN_DEPENDS roscpp rospy std_msgs message_runtime actionlib_msgs 114 # DEPENDS actionlib_msgs
其次在package.xml中添加依赖如下
<build_depend>actionlib_msgs</build_depend>
<build_export_depend>actionlib_msgs</build_export_depend>
一定要添加不然没有依赖就运行不了
上述所有工作到位后,在catkin工作区的顶层目录运行catkin_make.动作被正确编译后会生成一些消息文件,包括Timer.action ,TimerActionFeedback.msg ,TimerActionGoal.msg ,TimerActionResult.msg ,TimerFeedback.msg ,TimerGoal.msg和TimerResult.msg。这些消息文件就会被用于实现动作的client/server协议。
这样就完成了动作的定义。