proxy_action_client.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import roslib; roslib.load_manifest('flexbe_core')
4 import rospy
5 import actionlib
6 from threading import Timer
7 import time
8 
9 from flexbe_core.logger import Logger
10 
11 
12 class ProxyActionClient(object):
13  """
14  A proxy for calling actions.
15  """
16  _clients = {}
17 
18  _result = {}
19  _feedback = {}
20 
21  def __init__(self, topics={}, wait_duration=10):
22  """
23  Initializes the proxy with optionally a given set of clients.
24 
25  @type topics: dictionary string - message class
26  @param topics: A dictionay containing a collection of topic - message type pairs.
27 
28  @type wait_duration: int
29  @param wait_duration: Defines how long to wait for each client in the
30  given set to become available (if it is not already available).
31  """
32 
33  for topic, msg_type in topics.iteritems():
34  self.setupClient(topic, msg_type, wait_duration)
35 
36 
37  def setupClient(self, topic, msg_type, wait_duration=10):
38  """
39  Tries to set up an action client for calling it later.
40 
41  @type topic: string
42  @param topic: The topic of the action to call.
43 
44  @type msg_type: msg type
45  @param msg_type: The type of messages of this action client.
46 
47  @type wait_duration: int
48  @param wait_duration: Defines how long to wait for the given client if it is not available right now.
49  """
50  if topic not in ProxyActionClient._clients:
51  client = actionlib.SimpleActionClient(topic, msg_type)
52  t = Timer(1, self._print_wait_warning, [topic])
53  t.start()
54  available = client.wait_for_server(rospy.Duration.from_sec(wait_duration))
55  warning_sent = False
56  try:
57  t.cancel()
58  except Exception as ve:
59  # already printed the warning
60  warning_sent = True
61 
62  if not available:
63  Logger.logerr("Action client %s timed out!" % topic)
64  else:
65  ProxyActionClient._clients[topic] = client
66  if warning_sent:
67  Logger.loginfo("Finally found action client %s..." % (topic))
68 
69 
70  def send_goal(self, topic, goal):
71  """
72  Performs an action call on the given topic.
73 
74  @type topic: string
75  @param topic: The topic to call.
76 
77  @type goal: action goal
78  @param goal: The request to send to the action server.
79  """
80  if topic not in ProxyActionClient._clients:
81  raise ValueError('ProxyActionClient: topic %s not yet registered!' % topic)
82 
83  ProxyActionClient._result[topic] = None
84  ProxyActionClient._feedback[topic] = None
85 
86  ProxyActionClient._clients[topic].send_goal(goal,
87  done_cb = lambda ts, r: self._done_callback(topic, ts, r),
88  feedback_cb = lambda f: self._feedback_callback(topic, f)
89  )
90 
91  def _done_callback(self, topic, terminal_state, result):
92  ProxyActionClient._result[topic] = result
93 
94  def _feedback_callback(self, topic, feedback):
95  ProxyActionClient._feedback[topic] = feedback
96 
97 
98  def is_available(self, topic):
99  """
100  Checks if the client on the given action topic is available.
101 
102  @type topic: string
103  @param topic: The topic of interest.
104  """
105  return topic in ProxyActionClient._clients
106 
107  def has_result(self, topic):
108  """
109  Checks if the given action call already has a result.
110 
111  @type topic: string
112  @param topic: The topic of interest.
113  """
114  return ProxyActionClient._result[topic] is not None
115 
116  def get_result(self, topic):
117  """
118  Returns the result message of the given action call.
119 
120  @type topic: string
121  @param topic: The topic of interest.
122  """
123  return ProxyActionClient._result[topic]
124 
125  def remove_result(self, topic):
126  """
127  Removes the latest result message of the given action call.
128 
129  @type topic: string
130  @param topic: The topic of interest.
131  """
132  ProxyActionClient._result[topic] = None
133 
134  def has_feedback(self, topic):
135  """
136  Checks if the given action call has any feedback.
137 
138  @type topic: string
139  @param topic: The topic of interest.
140  """
141  return ProxyActionClient._feedback[topic] is not None
142 
143  def get_feedback(self, topic):
144  """
145  Returns the latest feedback message of the given action call.
146 
147  @type topic: string
148  @param topic: The topic of interest.
149  """
150  return ProxyActionClient._feedback[topic]
151 
152  def remove_feedback(self, topic):
153  """
154  Removes the latest feedback message of the given action call.
155 
156  @type topic: string
157  @param topic: The topic of interest.
158  """
159  ProxyActionClient._feedback[topic] = None
160 
161  def get_state(self, topic):
162  """
163  Determines the current actionlib state of the given action topic.
164  A list of possible states is defined in actionlib_msgs/GoalStatus.
165 
166  @type topic: string
167  @param topic: The topic of interest.
168  """
169  return ProxyActionClient._clients[topic].get_state()
170 
171  def is_active(self, topic):
172  """
173  Determines if an action request is already being processed on the given topic.
174 
175  @type topic: string
176  @param topic: The topic of interest.
177  """
178  return ProxyActionClient._clients[topic].simple_state != actionlib.SimpleGoalState.DONE
179 
180  def cancel(self, topic):
181  """
182  Cancels the current action call on the given action topic.
183 
184  @type topic: string
185  @param topic: The topic of interest.
186  """
187  ProxyActionClient._clients[topic].cancel_goal()
188 
189  def _print_wait_warning(self, topic):
190  Logger.logwarn("Waiting for action client %s..." % (topic))
def _done_callback(self, topic, terminal_state, result)
def setupClient(self, topic, msg_type, wait_duration=10)


flexbe_core
Author(s): Philipp Schillinger
autogenerated on Wed Jun 5 2019 21:51:59