原文链接: ros 自定义action
上一篇: tf.py_func 操作tensor 增强 拓展 tensorflow灵活性
下一篇: Python 小工具 wget 下载文件 flashtext文本替换查找 fuzzywuzzy 字符串比较
完整版,包括了取消等操作
https://github.com/NickKnack15/python-actionlib-demo
项目结构
package
<?xml version="1.0"?>
<package>
<name>actionlib_tutorials</name>
<version>0.1.8</version>
<description>The actionlib_tutorials package</description>
<maintainer email="d.stonier@gmail.com">Daniel Stonier</maintainer>
<license>BSD</license>
<author>Melonee Wise</author>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>actionlib</build_depend>
<build_depend>message_generation</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>actionlib_msgs</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>actionlib</run_depend>
<run_depend>message_runtime</run_depend>
</package>
cmake
cmake_minimum_required(VERSION 2.8.3)
project(actionlib_tutorials)
## Find catkin dependencies
find_package(catkin REQUIRED COMPONENTS actionlib message_generation)
## Find Boost
find_package(Boost REQUIRED COMPONENTS system thread)
## Add actions
add_action_files(DIRECTORY action FILES Fibonacci.action Fib.action)
## Generate messages
generate_messages(DEPENDENCIES std_msgs actionlib_msgs)
## Define catkin exports
catkin_package(
CATKIN_DEPENDS roscpp actionlib
DEPENDS Boost
)
## Setup include dirs
include_directories(include ${catkin_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
## Install scripts and executables
install(PROGRAMS
scripts/fibonacci_client.py
scripts/fibonacci_server.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
action,在不同的域中可以有相同的名字
#goal definition
int32 order
---
#result definition
int32[] sequence
---
#feedback
int32[] sequence
client
#! /usr/bin/env python
import rospy
# Brings in the SimpleActionClient
import actionlib
import time
# Brings in the messages used by the fibonacci action, including the
# goal message and the result message.
import actionlib_tutorials.msg
def cb(fb):
print('cb ',fb)
def fibonacci_client():
# Creates the SimpleActionClient, passing the type of the action
# (FibonacciAction) to the constructor.
client = actionlib.SimpleActionClient('fibonacci', actionlib_tutorials.msg.FibonacciAction)
# Waits until the action server has started up and started
# listening for goals.
client.wait_for_server()
# Creates a goal to send to the action server.
goal = actionlib_tutorials.msg.FibonacciGoal(order=10)
# Sends the goal to the action server.
client.send_goal(goal)
client.feedback_cb = cb # 发送后设置回调函数
print('send ')
# Waits for the server to finish performing the action.
client.wait_for_result()
print('wait')
# Prints out the result of executing the action
return client.get_result() # A FibonacciResult
if __name__ == '__main__':
try:
# Initializes a rospy node so that the SimpleActionClient can
# publish and subscribe over ROS.
rospy.init_node('fibonacci_client_py')
result = fibonacci_client()
print("Result:", ', '.join([str(n) for n in result.sequence]))
except rospy.ROSInterruptException:
print("program interrupted before completion")
server
#! /usr/bin/env python
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 range(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')
server = FibonacciAction(rospy.get_name())
rospy.spin()
运行
roscore
rosrun actionlib_tutorials fibonacci_client.py
rosrun actionlib_tutorials fibonacci_server.py
可以看到wait_for_result后会等待直到服务端执行完毕,发送goal后设置回调函数可以获取服务端发送过来的feedback