34 from actionlib_msgs.msg
import GoalID, GoalStatus, GoalStatusArray
50 rate = rospy.Rate(frequency)
52 rospy.logdebug(
"Starting timer")
53 while not rospy.is_shutdown():
57 except rospy.exceptions.ROSInterruptException:
58 rospy.logdebug(
"Sleep interrupted")
76 def __init__(self, ns, ActionSpec, goal_cb, cancel_cb=nop_cb, auto_start=True):
87 except AttributeError:
88 raise ActionException(
"Type is not an action spec: %s" % str(ActionSpec))
96 self.
lock = threading.RLock()
116 rospy.logwarn(
"You've passed in true for auto_start to the python action server, you should always pass " 117 "in false to avoid race conditions.")
142 self.
status_pub = rospy.Publisher(rospy.remap_name(self.
ns)+
"/status", GoalStatusArray, latch=
True, queue_size=self.
pub_queue_size)
155 resolved_status_frequency_name = rospy.remap_name(self.
ns)+
"/status_frequency" 156 if rospy.has_param(resolved_status_frequency_name):
158 rospy.logwarn(
"You're using the deprecated status_frequency parameter, please switch to actionlib_status_frequency.")
160 search_status_frequency_name = rospy.search_param(
"actionlib_status_frequency")
161 if search_status_frequency_name
is None:
166 status_list_timeout = rospy.get_param(rospy.remap_name(self.
ns)+
"/status_list_timeout", 5.0)
170 self.status_timer.start()
178 ar.header.stamp = rospy.Time.now()
181 if not rospy.is_shutdown():
182 self.result_pub.publish(ar)
191 af.header.stamp = rospy.Time.now()
193 af.feedback = feedback
194 if not rospy.is_shutdown():
195 self.feedback_pub.publish(af)
206 rospy.logdebug(
"The action server has received a new cancel request")
208 goal_id_found =
False 213 cancel_everything = (goal_id.id ==
"" and goal_id.stamp == rospy.Time())
214 cancel_this_one = (goal_id.id == st.status.goal_id.id)
215 cancel_before_stamp = (goal_id.stamp != rospy.Time()
and st.status.goal_id.stamp <= goal_id.stamp)
217 if cancel_everything
or cancel_this_one
or cancel_before_stamp:
219 if goal_id.id == st.status.goal_id.id:
223 handle_tracker = st.handle_tracker
225 if handle_tracker
is None:
228 st.handle_tracker = handle_tracker
231 st.handle_destruction_time = rospy.Time.now()
236 if gh.set_cancel_requested():
241 if goal_id.id !=
"" and not goal_id_found:
243 self.status_list.append(tracker)
245 tracker.handle_destruction_time = rospy.Time.now()
258 rospy.logdebug(
"The action server has received a new goal request")
262 if goal.goal_id.id == st.status.goal_id.id:
263 rospy.logdebug(
"Goal %s was already in the status list with status %i" % (goal.goal_id.id, st.status.status))
265 if st.status.status == GoalStatus.RECALLING:
266 st.status.status = GoalStatus.RECALLED
271 if st.handle_tracker
is None:
272 st.handle_destruction_time = rospy.Time.now()
279 self.status_list.append(st)
284 st.handle_tracker = handle_tracker
288 if goal.goal_id.stamp != rospy.Time()
and goal.goal_id.stamp <= self.
last_cancel:
290 gh.set_canceled(
None,
"This goal handle was canceled by the action server because its timestamp is before the timestamp of the last cancel request")
307 status_array = GoalStatusArray()
315 if st.handle_destruction_time != rospy.Time()
and st.handle_destruction_time + self.
status_list_timeout < rospy.Time.now():
316 rospy.logdebug(
"Item %s with destruction time of %.3f being removed from list. Now = %.3f" %
317 (st.status.goal_id, st.handle_destruction_time.to_sec(), rospy.Time.now().to_sec()))
320 status_array.status_list.append(st.status)
323 status_array.header.stamp = rospy.Time.now()
324 if not rospy.is_shutdown():
325 self.status_pub.publish(status_array)
def start(self)
Start the action server.
def publish_feedback(self, status, feedback)
Publishes feedback for a given goal.
def publish_status_async(self)
Publish status for all goals on a timer event.
def register_cancel_callback(self, cancel_cb)
Register a callback to be invoked when a new cancel is received, this will replace any previously reg...
def initialize(self)
Initialize all ROS connections and setup timers.
def __init__(self, ns, ActionSpec, goal_cb, cancel_cb=nop_cb, auto_start=True)
Constructor for an ActionServer.
def internal_cancel_callback(self, goal_id)
The ROS callback for cancel requests coming into the ActionServer.
def publish_result(self, status, result)
Publishes a result for a given goal.
def register_goal_callback(self, cb)
Register a callback to be invoked when a new goal is received, this will replace any previously regis...
def publish_status(self)
Explicitly publish status.
def ros_timer(callable, frequency)
def internal_goal_callback(self, goal)
The ROS callback for goals coming into the ActionServer.
The ActionServer is a helpful tool for managing goal requests to a node.