## For instruction on writing tutorials ## http://www.ros.org/wiki/WritingTutorials #################################### ##FILL ME IN #################################### ## for a custom note with links: ## note = ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0= ## descriptive title for the tutorial ## title = Writing a Simple Action Server using the Execute Callback (Python) ## multi-line description to be displayed in search ## description = This tutorial covers using the simple_action_server library to create a Fibonacci action server in Python. This example action server generates a Fibonacci sequence, ## For instruction on writing tutorials ## http://www.ros.org/wiki/WritingTutorials #################################### ##FILL ME IN #################################### ## for a custom note with links: ## note = ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0= ## descriptive title for the tutorial ## title = Writing a Simple Action Server using the Execute Callback (Python) ## multi-line description to be displayed in search ## description = This tutorial covers using the simple_action_server library to create a Fibonacci action server in Python. This example action server generates a Fibonacci sequence, the goal is the order of the sequence, the feedback is the sequence as it is computed, and the result is the final sequence. ## the next tutorial description (optional) ## next = ## links to next tutorial (optional) ## next.0.link= [[actionlib_tutorials/Tutorials/Writing a Simple Action Client (Python)|Writing a Simple Action Client (Python)]] ## next.1.link= ## what level user is this tutorial for ## level= BeginnerCategory ## keywords = #################################### <> <> == Creating the Action Messages == See [[http://www.ros.org/wiki/actionlib_tutorials/Tutorials/SimpleActionServer%28ExecuteCallbackMethod%29#actionlib_tutorials.2BAC8-Tutorials.2BAC8-SimpleActionServer.28ExecuteCallbackMethod.29.2BAC8-groovy.Creating_the_Action_Messages|C++ version tutorial]] and come back when you've finished creating messages. == Writing a Simple Server == The code and examples used in this tutorial can be found in the [[actionlib_tutorials]] package. You may want to read about the [[actionlib]] package before starting this tutorial. === The Code === The following code can be found in `actionlib_tutorials/simple_action_servers/fibonacci_server.py`, and implements a python action server for the [[http://docs.ros.org/api/actionlib_tutorials/html/classfibonacci__server_1_1FibonacciAction.html|fibonacci action]]. {{{ #!python block=action #! /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() }}} === The Code, explained === <> This line imports the actionlib library used for implementing simple actions. <> The action specification generates several messages for sending goals, receiving feedback, etc... This line imports the generated messages. <> Here, the !SimpleActionServer is created, we pass it a name (used as a `namespace`), an action type, and optionally an execute callback. Since we've specified an execute callback in this example, a thread will be spun for us which allows us to take long running actions in a callback received when a new goal comes in. Note you should always set `auto_start` to `False` explicitly, unless you know what you're doing ([[https://github.com/ros/actionlib/pull/60|ref]]). <> This is the execute callback function that we'll run everytime a new goal is received. <> Here, the internals of the action are created. In this example `rospy.loginfo` is published to let the user know that the action is executing. <> An important component of an action server is the ability to allow an action client to request that the goal under execution be canceled. When a client requests that the current goal be preempted, the action server should cancel the goal, perform any necessary cleanup, and call the `set_preempted` function, which signals that the action has been preempted by user request. Here, we'll check if we've been preempted every second. We could, alternatively, receive a callback when a preempt request is received. <> Here, the Fibonacci sequence is put into the feedback variable and then published on the feedback channel provided by the action server. Then, the action continues looping and publishing feedback. <> Once the action has finished computing the Fibonacci sequence, the action server notifies the action client that the goal is complete by calling `set_succeeded`. <> Finally, the main function, creates the action server and spins the node. == Compiling == Only initially when you just created your tutorial package, you need to compile to generate shell config files. {{{ cd %TOPDIR_YOUR_CATKIN_WORKSPACE% catkin_make source devel/setup.bash }}} == Running the Action Server == Run: {{{ roscore }}} Then on a new terminal, the following command will run the action server. {{{ rosrun actionlib_tutorials fibonacci_server.py }}} ## AUTOGENERATED DO NOT DELETE