goal.py
Go to the documentation of this file.
1 import rospy
2 import clearpath_navigation_msgs.msg
3 
4 
5 class Goal:
6  """A single goal (part of a mission).
7 
8  Contains a goalpoint, optional viapoints, optional tasks to run
9  at the goalpoint, and various other optional parameters related
10  to the specifics at the goal point.
11 
12  A series of goals can be run in sequence to build a larger mission.
13  """
14 
15  @staticmethod
16  def createGoal(name, datum_latlon, goalpoint_latlon, viapoints_latlon=[], tasks=[],
17  enable_final_heading=False, goalpoint_heading=0,
18  enable_goal_tolerance=False, position_tolerance=0.1, yaw_tolerance=0.2):
19  """Creates a Goal object from the given parameters.
20 
21  Parameters
22  ----------
23  name : str
24  The name or ID of the goal, used for tracking/reporting
25 
26  datum_latlon : CoordinateLatLon
27  The latitude/longitude position of the datum
28 
29  goalpoint_latlon : CoordinateLatLon
30  The latitude/longitude position of the goalpoint
31 
32  viapoints_latlon : CoordinateLatLon[], optional
33  A list of latitude/longitude positions of the viapoints,
34  starting from the beginning of the path and finishing
35  toward the goalpoint (default is no viapoints)
36 
37  tasks : clearpath_navigation_msgs.msg.Task[], optional
38  A list of tasks to run at the goalpoint (default is no tasks)
39 
40  enable_final_heading : bool, optional
41  Whether or not to apply a heading at the goalpoint (default is False)
42 
43  goalpoint_heading : float64, optional
44  The heading, in degrees, to apply at the goalpoint (default is 0);
45  only gets applied when enable_final_heading is True
46 
47  enable_goal_tolerance : bool, optional
48  Whether or not to enforce a tolerance at the goalpoint (default is False)
49 
50  position_tolerance : float64, optional
51  The pose (x,y) tolerance, in meters, to apply at the goalpoint (default is 0.1);
52  only gets applied when enable_goal_tolerance is True
53 
54  yaw_tolerance : float64, optional
55  The yaw tolerance, in radians, to apply at the goalpoint (default is 0.2);
56  only gets applied when enable_goal_tolerance is True
57 
58  Returns
59  -------
60  Goal
61  the created goal
62  """
63 
64  goalpoint_xy = goalpoint_latlon.toXY(datum_latlon)
65  goal_msg = clearpath_navigation_msgs.msg.MissionGoal()
66  goal_msg.mission.enable_final_heading = enable_final_heading
67  goal_msg.mission.goalpoint_heading = goalpoint_heading
68  goal_msg.mission.enable_goal_tolerance = enable_goal_tolerance
69  goal_msg.mission.position_tolerance = position_tolerance
70  goal_msg.mission.yaw_tolerance = yaw_tolerance
71  goal_msg.mission.goalpoint.x = goalpoint_xy.getX()
72  goal_msg.mission.goalpoint.y = goalpoint_xy.getY()
73 
74  # Need viapoints in reverse order here to match what is expected by the API
75  goal_msg.mission.viapoints = []
76  goal_msg.mission.tasks = tasks
77  for viapoint_latlon in reversed(viapoints_latlon):
78  viapoint_xy = viapoint_latlon.toXY(datum_latlon)
79  viapoint = clearpath_navigation_msgs.msg.Waypoint()
80  viapoint.x = viapoint_xy.getX()
81  viapoint.y = viapoint_xy.getY()
82  goal_msg.mission.viapoints.append(viapoint)
83 
84  return Goal(name, goal_msg)
85 
86  def __init__(self, name, goal_msg):
87  """A new Goal object.
88 
89  Parameters
90  ----------
91  name : str
92  The name of the goal
93 
94  goal_msg : clearpath_navigation_msgs.msg.MissionGoal
95  The goal message to be sent to the action server
96  """
97 
98  self._name = name
99  self._goal_msg = goal_msg
100 
101  def getName(self):
102  """Gets the name of the goal.
103 
104  Returns
105  -------
106  str
107  the name of the goal
108  """
109 
110  return self._name
111 
112  def getGoalMsg(self):
113  """Gets the goal message.
114 
115  Returns
116  -------
117  clearpath_navigation_msgs.msg.MissionGoal
118  the goal message
119  """
120 
121  return self._goal_msg
122 
123  def sendGoal(self, actionlib_client, progress_callback=None, done_callback=None):
124  """Sends to goal to be executed.
125 
126  This function returns immediately once the goal has been sent to
127  the navigation engine; it does not wait for the goal to complete.
128 
129  Parameters
130  ----------
131  actionlib_client : actionlib.SimpleActionClient reference
132  Reference to an instance of actionlib.SimpleActionClient use to make calls to
133  the appropriate actionlib server
134 
135  progress_callback : fn(feedback_str), optional
136  A callback function that is called at regular intervals while the goal
137  is being executed to provide progress updates. The function should take
138  the "feedback_str" string parameter. If set to None, no feedback will be provided
139  and the goal will execute to completion.
140 
141  done_callback : fn(enum, bool), optional
142  A callback function that is called when the goal is complete. The function should take
143  two parameters: the terminal state (as an integer from actionlib_msgs/GoalStatus) and
144  the result.
145 
146  Returns
147  -------
148  bool
149  True on successful goal dispatch, else False
150  """
151 
152  try:
153  # Waits until the action server has started up and started
154  # listening for goals, then sends the goal
155  if not actionlib_client.wait_for_server(timeout=rospy.Duration()):
156  rospy.logerr("Failed to connect to server")
157  return False
158  actionlib_client.send_goal(self._goal_msg,
159  feedback_cb=progress_callback,
160  done_cb=done_callback)
161  except rospy.ROSInterruptException:
162  rospy.logerr("mission server is not available; exception detected")
163  return False
164  return True
165 
166  def waitForGoalCompletion(self, actionlib_client, timeout=rospy.Duration()):
167  """Waits for goal to be executed.
168 
169  This function blocks until the goal has been executed fully.
170 
171  Parameters
172  ----------
173  actionlib_client : actionlib.SimpleActionClient reference
174  Reference to an instance of actionlib.SimpleActionClient use to make calls to
175  the appropriate actionlib server
176 
177  timeout : rospy.Duration, optional
178  Amount of time to wait for the goal to complete (default is to wait forever)
179 
180  Returns
181  -------
182  bool
183  True on successful goal completion, else False
184  """
185 
186  try:
187  # Waits until the action server has started up and started
188  # listening for goals, then sends the goal
189  if not actionlib_client.wait_for_server(timeout=rospy.Duration()):
190  return False
191 
192  # Wait for the server to finish performing the action
193  actionlib_client.wait_for_result(timeout)
194 
195  # Return the result of executing the action (result is a bool)
196  return actionlib_client.get_result()
197  except rospy.ROSInterruptException:
198  rospy.logerr("mission server is not available; exception detected")
199  return False
200 
201  def sendGoalAndWait(self, actionlib_client):
202  """Sends the goal to be executed and waits until completed.
203 
204  This function blocks until the goal has been executed fully.
205 
206  Parameters
207  ----------
208  actionlib_client : actionlib.SimpleActionClient reference
209  Reference to an instance of actionlib.SimpleActionClient use to make calls to
210  the appropriate actionlib server
211 
212  Returns
213  -------
214  bool
215  True on successful goal completion, else False
216  """
217 
218  if not self.sendGoal(actionlib_client):
219  return False
220  if not self.waitForGoalCompletion(actionlib_client):
221  return False
222 
223  def cancelGoal(self, actionlib_client):
224  """Cancels the goal that we are currently executing
225 
226  Parameters
227  ----------
228  actionlib_client : actionlib.SimpleActionClient reference
229  Reference to an instance of actionlib.SimpleActionClient use to make calls to
230  the appropriate actionlib server
231  """
232 
233  actionlib_client.cancel_goal()
234 
235  def toYaml(self):
236  """Converts the goal to YAML format, for writing to disk.
237 
238  Returns
239  -------
240  dict
241  A YAML-compatible dictionary representation of the object.
242  """
243 
244  name = self.getName()
245  goal_msg = self.getGoalMsg()
246  viapoints_yaml = []
247  for viapoint in goal_msg.mission.viapoints:
248  viapoints_yaml.append({
249  'x': float(viapoint.x),
250  'y': float(viapoint.y)
251  })
252  tasks_yaml = []
253  for task in goal_msg.mission.tasks:
254  tasks_yaml.append({
255  'task_name': task.task_name,
256  'action_server_name': task.action_server_name,
257  'version': task.version,
258  'floats': task.floats,
259  'strings': task.strings
260  })
261  goal_msg_yaml = {
262  'goalpoint': {
263  'x': float(goal_msg.mission.goalpoint.x),
264  'y': float(goal_msg.mission.goalpoint.y)
265  },
266  'enable_final_heading': goal_msg.mission.enable_final_heading,
267  'goalpoint_heading': goal_msg.mission.goalpoint_heading,
268  'enable_goal_tolerance': goal_msg.mission.enable_goal_tolerance,
269  'position_tolerance': goal_msg.mission.position_tolerance,
270  'yaw_tolerance': goal_msg.mission.yaw_tolerance,
271  'viapoints': viapoints_yaml,
272  'tasks': tasks_yaml
273  }
274  goal_yaml = {
275  'name': name,
276  'msg': goal_msg_yaml
277  }
278  return goal_yaml
279 
280  @staticmethod
281  def fromYaml(goal_yaml):
282  """Creates a Goal object from a YAML-compatible dictionary representation.
283 
284  Parameters
285  ----------
286  goal_yaml : dict
287  The YAML-compatible dictionary representation of a Goal object
288  """
289 
290  try:
291  name = goal_yaml['name']
292  goal_msg_yaml = goal_yaml['msg']
293  goal_msg = clearpath_navigation_msgs.msg.MissionGoal()
294 
295  goal_msg.mission.goalpoint.x = goal_msg_yaml['goalpoint']['x']
296  goal_msg.mission.goalpoint.y = goal_msg_yaml['goalpoint']['y']
297 
298  goal_msg.mission.enable_final_heading = goal_msg_yaml['enable_final_heading']
299  goal_msg.mission.goalpoint_heading = goal_msg_yaml['goalpoint_heading']
300  goal_msg.mission.enable_goal_tolerance = goal_msg_yaml['enable_goal_tolerance']
301  goal_msg.mission.position_tolerance = goal_msg_yaml['position_tolerance']
302  goal_msg.mission.yaw_tolerance = goal_msg_yaml['yaw_tolerance']
303 
304  viapoints_yaml = goal_msg_yaml['viapoints']
305  goal_msg.mission.viapoints = []
306  for viapoint_yaml in viapoints_yaml:
307  viapoint = clearpath_navigation_msgs.msg.Waypoint()
308  viapoint.x = viapoint_yaml['x']
309  viapoint.y = viapoint_yaml['y']
310  goal_msg.mission.viapoints.append(viapoint)
311 
312  tasks_yaml = goal_msg_yaml['tasks']
313  goal_msg.mission.tasks = []
314  for task_yaml in tasks_yaml:
315  task = clearpath_navigation_msgs.msg.Task()
316  task.task_name = task_yaml['task_name']
317  task.action_server_name = task_yaml['action_server_name']
318  task.version = task_yaml['version']
319  task.floats = task_yaml['floats']
320  task.strings = task_yaml['strings']
321  goal_msg.mission.tasks.append(task)
322 
323  goal = Goal(name, goal_msg)
324  return goal
325  except KeyError as e:
326  rospy.logerr('Unable to parse yaml for goal: %s' % e)
327  return None
clearpath_onav_api_examples_lib.goal.Goal.getName
def getName(self)
Definition: goal.py:101
clearpath_onav_api_examples_lib.goal.Goal.cancelGoal
def cancelGoal(self, actionlib_client)
Definition: goal.py:223
clearpath_onav_api_examples_lib.goal.Goal.createGoal
def createGoal(name, datum_latlon, goalpoint_latlon, viapoints_latlon=[], tasks=[], enable_final_heading=False, goalpoint_heading=0, enable_goal_tolerance=False, position_tolerance=0.1, yaw_tolerance=0.2)
Definition: goal.py:16
clearpath_onav_api_examples_lib.goal.Goal.getGoalMsg
def getGoalMsg(self)
Definition: goal.py:112
clearpath_onav_api_examples_lib.goal.Goal.waitForGoalCompletion
def waitForGoalCompletion(self, actionlib_client, timeout=rospy.Duration())
Definition: goal.py:166
clearpath_onav_api_examples_lib.goal.Goal._name
_name
Definition: goal.py:98
clearpath_onav_api_examples_lib.goal.Goal.fromYaml
def fromYaml(goal_yaml)
Definition: goal.py:281
clearpath_onav_api_examples_lib.goal.Goal.sendGoal
def sendGoal(self, actionlib_client, progress_callback=None, done_callback=None)
Definition: goal.py:123
clearpath_onav_api_examples_lib.goal.Goal.sendGoalAndWait
def sendGoalAndWait(self, actionlib_client)
Definition: goal.py:201
clearpath_onav_api_examples_lib.goal.Goal.toYaml
def toYaml(self)
Definition: goal.py:235
clearpath_onav_api_examples_lib.goal.Goal
Definition: goal.py:5
clearpath_onav_api_examples_lib.goal.Goal._goal_msg
_goal_msg
Definition: goal.py:99
clearpath_onav_api_examples_lib.goal.Goal.__init__
def __init__(self, name, goal_msg)
Definition: goal.py:86


clearpath_onav_api_examples_lib
Author(s):
autogenerated on Sun Nov 12 2023 03:29:19