Hi all! I’m working on setting up our Stretch RE1 as a tour guide of a newly renovated lab space at RPI. I’m having a bit of trouble getting the stretch to stop at each way point until the audio finishes playing, and then move on. I have something working, but it’s a bit of a dirty solution, so I was hoping someone could give a bit of advice on how to better accomplish this. For context, here is how I am currently doing it:
def audio_response_callback(self, future):
goal_handle = future.result()
if not goal_handle.accepted:
self.get_logger().info('Audio Msg Declined')
return
self.get_logger().info('Audio Msg Accepted')
self.ready_to_move = False
self._get_result_future = goal_handle.get_result_async()
self._get_result_future.add_done_callback(self.get_result_callback)
def get_result_callback(self, future):
self.audio_result = future.result().result
self.ready_to_move = True
if self.audio_result.finished == MercerAudio.Result.SUCCESS:
self.get_logger().info("Audio played successfully")
else:
self.get_logger().info("Audio failed to play")
def main(self):
self.parse_pose_dict_to_poses()
self.audio_result = None
self.audio_msg = MercerAudio.Goal()
self.audio_msg.file_path = self.audio_file_path + 'origin.wav'
self.audio_future = self.audio_cue_client.send_goal_async(self.audio_msg)
self.audio_future.add_done_callback(self.audio_response_callback)
while self.audio_result is None:
rclpy.spin_once(self, timeout_sec=1.0)
self.get_logger().info("Audio finished playing!")
for pose in self.route_poses:
self.get_logger().info("Pose: {0}".format(pose['id']))
self.audio_result = None
self.result = TaskResult.UNKNOWN
self.go_to_waypoint(pose['pose'])
i = 0
while not self.navigator.isTaskComplete():
i += 1
feedback = self.navigator.getFeedback()
if feedback and i % 5 == 0:
self.get_logger().info('Executing current waypoint')
self.get_logger().info("Result: {0}".format(self.result))
if self.result == TaskResult.SUCCEEDED:
self.get_logger().info("Navigation to waypoint successful!")
else:
if self.result == TaskResult.UNKNOWN:
while not self.navigator.isTaskComplete():
rclpy.spin_once(self, timeout_sec=1.0)
self.get_logger().info("Still spinning {0}".format(pose['id']))
self.audio_msg = MercerAudio.Goal()
self.audio_msg.file_path = self.audio_file_path + pose['id'] + '.wav'
self.audio_future = self.audio_cue_client.send_goal_async(self.audio_msg)
self.audio_future.add_done_callback(self.audio_response_callback)
while self.audio_result is None:
# self.get_logger().info("Waiting for audio to finish playing...")
rclpy.spin_once(self, timeout_sec=0.2)
server_reached = self.audio_cue_client.wait_for_server(timeout_sec=60.0)
if not server_reached:
self.get_logger().error('Unable to connect to audio action server. Timeout exceeded.')
sys.exit()
self.get_logger().info("Audio finished playing!")
self.audio_msg = MercerAudio.Goal()
self.audio_msg.file_path = self.audio_file_path + 'end.wav'
self.audio_future = self.audio_cue_client.send_goal_async(self.audio_msg)
self.audio_future.add_done_callback(self.audio_response_callback)
self.get_logger().info("Navigation complete!")
It works, but only just. I’m reading in waypoints from a JSON file, and then based on the name of the waypoint, playing audio. Let me know what you guys think! Thanks!