< >
Home » ROS与Python入门教程 » ROS与Python入门教程-actionlib-开发简单的action服务端

ROS与Python入门教程-actionlib-开发简单的action服务端

ROS与Python入门教程-actionlib-开发简单的action服务端

说明

  • 使用simple_action_server库创建Python的Fibonacci(斐波那契数列)action服务端
  • 计算Fibonacci数列的顺序,得到计算后的数列

介绍

代码

#! /usr/bin/env python

import roslib; roslib.load_manifest('actionlib_tutorials')
import rospy

import actionlib

import actionlib_tutorials.msg

class FibonacciAction(object):
  # create messages that are used to publish feedback/result
  _feedback = actionlib_tutorials.msg.FibonacciFeedback()
  _result   = actionlib_tutorials.msg.FibonacciResult()

  def __init__(self, name):
    self._action_name = name
    self._as = actionlib.SimpleActionServer(self._action_name, actionlib_tutorials.msg.FibonacciAction, execute_cb=self.execute_cb, auto_start = False)
    self._as.start()
    
  def execute_cb(self, goal):
    # helper variables
    r = rospy.Rate(1)
    success = True
    
    # append the seeds for the fibonacci sequence
    self._feedback.sequence = []
    self._feedback.sequence.append(0)
    self._feedback.sequence.append(1)
    
    # publish info to the console for the user
    rospy.loginfo('%s: Executing, creating fibonacci sequence of order %i with seeds %i, %i' % (self._action_name, goal.order, self._feedback.sequence[0], self._feedback.sequence[1]))
    
    # start executing the action
    for i in xrange(1, goal.order):
      # check that preempt has not been requested by the client
      if self._as.is_preempt_requested():
        rospy.loginfo('%s: Preempted' % self._action_name)
        self._as.set_preempted()
        success = False
        break
      self._feedback.sequence.append(self._feedback.sequence[i] + self._feedback.sequence[i-1])
      # publish the feedback
      self._as.publish_feedback(self._feedback)
      # this step is not necessary, the sequence is computed at 1 Hz for demonstration purposes
      r.sleep()
      
    if success:
      self._result.sequence = self._feedback.sequence
      rospy.loginfo('%s: Succeeded' % self._action_name)
      self._as.set_succeeded(self._result)
      
if __name__ == '__main__':
  rospy.init_node('fibonacci')
  FibonacciAction(rospy.get_name())
  rospy.spin() 

代码分析

  • 代码:import actionlib

  • 分析:导入actionlib库

  • 代码:import actionlib_tutorials.msg

  • 分析:导入生成的消息,action会生成用于发送目标,接受反馈的消息。

  • 代码:

self._as = actionlib.SimpleActionServer(self._action_name, actionlib_tutorials.msg.FibonacciAction, execute_cb=self.execute_cb, auto_start = False)
self._as.start()
  • 分析:SimpleActionServer创建服务端,需4个参数:action_name、action type、callback函数(可选)、auto_start

  • 代码:

def execute_cb(self, goal):
    r = rospy.Rate(1)
    success = True
    
    # append the seeds for the fibonacci sequence
    self._feedback.sequence = []
    self._feedback.sequence.append(0)
    self._feedback.sequence.append(1)
    
    # publish info to the console for the user
    rospy.loginfo('%s: Executing, creating fibonacci sequence of order %i with seeds %i, %i' % (self._action_name, goal.order, self._feedback.sequence[0], self._feedback.sequence[1]))
  • 分析:定义回调函数,当新目标到达,rospy.loginfo 输出相关信息,可知道正在执行的action.

  • 代码:

# start executing the action
    for i in xrange(1, goal.order):
      # check that preempt has not been requested by the client
      if self._as.is_preempt_requested():
        rospy.loginfo('%s: Preempted' % self._action_name)
        self._as.set_preempted()
        success = False
  • 分析:
    • action服务端重要功能是可以让action客户端可以取消请求。
    • 当客户端替换了目标,服务器端应该取消目标,执行清除,调用set_preempted。
    • 服务端会每秒执行检测客户端是否取消。
  • 代码:
self._feedback.sequence.append(self._feedback.sequence[i] + self._feedback.sequence[i-1])
# publish the feedback
self._as.publish_feedback(self._feedback)
  • 分析:Fibonacci 数列放入反馈变量里,发布反馈。

  • 代码:

if success:
      self._result.sequence = self._feedback.sequence
      rospy.loginfo('%s: Succeeded' % self._action_name)
      self._as.set_succeeded(self._result)
  • 分析:当服务器端完成计算,调用set_succeeded通知客户端,目标已经完成。

启动服务器端

python fibonacci_server.py

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ros与python入门教程