26 ScriptableActionServer allows its users to determine the ActionResult to an ActionGoal. 28 The result-type for e.g. FooAction should be FooResult, not FooActionResult! 30 Goals can be aborted by setting `ABORT_GOAL` as the result. 32 Goals can be ignored by setting `IGNORE_GOAL` as the result. This makes the action client never get a result 34 Note that Actionlib uses the term 'result' for its, well, results, whereas ROS services use 'reply'. 35 The base class `ScriptableBase` uses the 'reply' terminology. 36 `ScriptableActionServer` should be consistent with the action terminology, 37 so it's constructor does some translation between terms and passes 'default_reply=default_result' 38 to the constructor of `ScriptableBase`. 41 SUCCEED_GOAL =
"SUCCEED_GOAL" 42 IGNORE_GOAL =
"IGNORE_GOAL" 43 ABORT_GOAL =
"ABORT_GOAL" 45 def __init__(self, name, action_type, goal_formatter=format, result_formatter=format, default_result=None, default_result_delay=0):
47 Set up a ScriptableActionServer based on the name and the type of Action it should implement 49 :param action_type: action type (e.g. MoveBaseAction) 51 ScriptableBase.__init__(self, name,
52 goal_formatter=goal_formatter,
53 reply_formatter=result_formatter,
54 default_reply=default_result,
55 default_reply_delay=default_result_delay)
59 self._as.register_preempt_callback(self.
_preempt_cb)
62 return "ScriptableActionServer('{}')".format(self.
_name)
66 return self._as.action_server.goal_sub.get_num_connections() >= 1
70 Start the action server and thus listen to goals 75 self._as.action_server.started =
False 76 super(ScriptableActionServer, self).
stop()
80 Called when the underlying action server receives a goal. 81 If the default_result is None, it will wait for a custom result to be set via reply* otherwise 82 return the default_result after the given default_result_delay 84 In the reply-case,it then notifies self.reply* (which should be called by a test script outside this class), 85 after which self.reply* determines the result to the goal. 86 Then it notifies _execute_cb that the result has been determined so that _execute_cb can send it 93 except Exception
as e:
94 rospy.logerr(
"goal_formatter of {} raised an exception: {}".format(self.
_name, e))
96 print(
'{}.execute: Goal: {}'.format(self.
_name, goal_str))
117 Send the result and deal with ignored and aborted goals 119 :param result: a Result associated with the Action-type of this Server 122 if isinstance(result_tuple, tuple):
124 result, action = result_tuple
137 except Exception
as e:
138 rospy.logerr(
"result_formatter of {} raised an exception: {}".format(self.
_name, e))
140 print(
"{}.execute: Result: {}".format(self.
_name, result_str))
141 self._as.set_succeeded(result)
143 print(
"{}.execute: Result: {}, action: {}".format(self.
_name, result, action))
144 self._as.set_aborted(result)
146 print(
"{}.execute: Result: {}, action: {}".format(self.
_name, result, action))
152 Handle action preemption by the action client 154 if self._as.is_active():
156 self._as.set_preempted()