3 import clearpath_navigation_msgs.msg
10 MISSION_ACTION_NAME =
'mission'
14 """A sequence of waypoints with optional tasks."""
16 def __init__(self, name, uuid, waypoints, on_start_tasks, on_stop_tasks,
17 from_start=True, start_waypoint_num=0, onav_config="",
18 progress_callback=None, done_callback=None):
19 """Builds up the data structure containing the details of the mission.
24 The name of the mission
27 UUID string used to uniquely identify this mission
29 waypoints : Waypoint[]
30 A list of Waypoint objects, to be executed in sequence
33 An array of Tasks to execute on Mission start
36 An array of Tasks to execute on Mission stop. These
37 Tasks will execute regardless of mission success or failure
40 Whether or not the mission should start from the first Waypoint
42 start_waypoint_num: int
43 The index representing the Waypoint in the list of Waypoint, from which the
47 Configuration parameters for the mission
49 progress_callback : fn(feedback_str), optional
50 A callback function that is called at regular intervals while the mission
51 is being executed to provide progress updates. The function should take
52 the "feedback_str" string parameter. If set to None, no feedback will be provided
53 and the mission will execute to completion.
55 done_callback : fn(bool), optional
56 A callback function that is called when the mission is complete. The function
57 should take one parameter: a bool to indicate if the mission was completed
76 """Gets the mission message.
80 clearpath_navigation_msgs.msg.Mission
84 mission_msg = clearpath_navigation_msgs.msg.Mission()
85 mission_msg.name = self.
_name
86 mission_msg.uuid = self.
_uuid
90 waypoint_msgs.append(waypoint.getWaypointMsg())
91 mission_msg.waypoints = waypoint_msgs
94 on_start_tasks.append(task.getTaskMsg())
95 mission_msg.on_start = on_start_tasks
98 on_stop_tasks.append(task.getTaskMsg())
99 mission_msg.on_stop = on_stop_tasks
103 """Executes when 'feedback' is received from the mission execution.
105 Forwards the callback to the user-provided mission feedback callback.
108 rospy.logdebug(
"Mission %s: %s" % (self.
_name, feedback.state))
113 """Executes when 'done' is received from the mission execution.
115 Forwards the callback to the user-provided mission done callback.
122 if mission_state != actionlib.GoalStatus.SUCCEEDED
or not result:
123 mission_result_str =
"Failed"
125 rospy.logdebug(
"Mission complete, but not successful.")
127 mission_result_str =
"Succeeded"
129 mission_feedback =
"Mission %s: %s" % (self.
_name, mission_result_str)
130 rospy.logdebug(mission_feedback)
135 """Sends the mission to the action server.
140 True on successful dispatch, else False
144 rospy.logerr(
'Action client not started. Cannot send mission.')
148 mission_goal_msg = clearpath_navigation_msgs.msg.MissionGoal()
151 if not mission_goal_msg.from_start:
156 print(
'Trying to connect to mission server...')
157 if not self.
_client.wait_for_server(timeout=rospy.Duration()):
158 rospy.logerr(
"Failed to connect to server")
160 print(
'Connected to mission server')
161 self.
_client.send_goal(mission_goal_msg,
164 print(
'Mission executing...')
165 except rospy.ROSInterruptException:
166 rospy.logerr(
"mission server is not available; exception detected")
171 """Gets the name of the mission
176 The name of the mission
182 """Set the callbacks for the mission.
184 Provides a way to set the callbacks if not done during object creation,
185 which is the case when creating the object from a YAML file.
189 progress_callback : fn(feedback_str), optional
190 A callback function that is called at regular intervals while the mission
191 is being executed to provide progress updates. The function should take
192 the "feedback_str" string parameter. If set to None, no feedback will be provided
193 and the mission will execute to completion.
195 done_callback : fn(bool), optional
196 A callback function that is called when the mission is complete. The function
197 should take one parameters: a bool to indicate if the mission was completed
205 """Gets the current status of the mission.
207 If the mission is still in progress, reports the current status. If the
208 mission is complete, reports the overall mission status.
210 See also isMissionComplete().
215 True if the mission is running successfully so far, else False
221 """Determines if the mission is complete.
223 See also getMissionSuccess().
228 True if the mission is complete, else False if mission is still running
234 """Starts the execution of the mission.
236 This function returns as soon as the mission is started. See isMissionComplete()
237 and getMissionSuccess() to determine mission status. If there is already an
238 active mission, a new one cannot be started until the active mission completes
241 See also stopMission().
246 True on successful mission start, else False
251 print(
'Creating mission client')
253 clearpath_navigation_msgs.msg.MissionAction)
256 rospy.logwarn(
"Existing mission is still active. Cannot start new mission.")
261 rospy.logerr(
"Cannot send mission. Failed to start mission.")
267 """Stops the mission that is currently executing.
272 True if the mission was stopped successfully, else False"""
275 self.
_client.cancel_all_goals()
276 rospy.logdebug(
"Stopping mission. All goals cancelled. Setting success to False.")
281 """Converts the mission to YAML format, for writing to disk.
286 A YAML-compatible dictionary representation of the object.
291 for waypoint
in waypoints:
292 waypoint_yaml = waypoint.toYaml()
293 waypoints_yaml.append(waypoint_yaml)
296 on_start_tasks_yaml = []
297 for task
in on_start_tasks:
298 on_start_task_yaml = task.toYaml()
299 on_start_tasks_yaml.append(on_start_task_yaml)
302 on_stop_tasks_yaml = []
303 for task
in on_stop_tasks:
304 on_stop_task_yaml = task.toYaml()
305 on_stop_tasks_yaml.append(on_stop_task_yaml)
310 'waypoints': waypoints_yaml,
311 'on_start_tasks': on_start_tasks_yaml,
312 'on_stop_tasks': on_stop_tasks_yaml,
319 """Creates a Mission object from a YAML-compatible dictionary representation.
324 The YAML-compatible dictionary representation of a Mission object
327 if 'name' not in mission_yaml:
328 rospy.logerr(
"yamlFileToMission: missing 'name' field")
330 if 'uuid' not in mission_yaml:
331 rospy.logerr(
"yamlFileToMission: missing 'uuid' field")
333 if 'waypoints' not in mission_yaml:
334 rospy.logerr(
"yamlFileToMission: missing 'waypoints' field")
336 if 'on_start_tasks' not in mission_yaml:
337 rospy.logerr(
"yamlFileToMission: missing 'on_start_tasks' field")
339 if 'on_stop_tasks' not in mission_yaml:
340 rospy.logerr(
"yamlFileToMission: missing 'on_stop_tasks' field")
342 if 'onav_config' not in mission_yaml:
343 rospy.logerr(
"yamlFileToMission: missing 'onav_config' field")
345 name = mission_yaml[
'name']
346 uuid = mission_yaml[
'uuid']
347 onav_config = mission_yaml[
'onav_config']
349 waypoints_yaml = mission_yaml[
'waypoints']
350 for waypoint_yaml
in waypoints_yaml:
351 waypoint = Waypoint.fromYaml(waypoint_yaml)
353 rospy.logerr(
"yamlFileToMission: could not parse 'waypoints'")
355 waypoints.append(waypoint)
358 on_start_tasks_yaml = mission_yaml[
'on_start_tasks']
359 for on_start_task_yaml
in on_start_tasks_yaml:
360 task = Task.fromYaml(on_start_task_yaml)
362 rospy.logerr(
"yamlFileToMission: could not parse 'on_start_tasks'")
364 on_start_tasks.append(task)
367 on_stop_tasks_yaml = mission_yaml[
'on_stop_tasks']
368 for on_stop_task_yaml
in on_stop_tasks_yaml:
369 task = Task.fromYaml(on_stop_task_yaml)
371 rospy.logerr(
"yamlFileToMission: could not parse 'on_stop_tasks'")
373 on_stop_tasks.append(task)
375 return Mission(name, uuid, waypoints, on_start_tasks, on_stop_tasks, onav_config)