I’m struggling to find out if I’m correctly triggering the get_result_callback in my action client. I’m not sure if I’m not correctly publishing the information within the server, or if I’m not correctly calling it in the client. In my action client, I have these callbacks:
def send_goal(self):
goal_msg = OdomRecord.Goal()
self._action_client.wait_for_server()
self._send_goal_future = self._action_client.send_goal_async(goal_msg, feedback_callback=self.feedback_callback)
self._send_goal_future.add_done_callback(self.goal_response_callback)
def goal_response_callback(self, future):
goal_handle = future.result()
if not goal_handle.accepted:
self.get_logger().info('Goal rejected :(')
return
self.get_logger().info('Goal accepted :)')
self._get_result_future = goal_handle.get_result_async()
self.get_logger().info('Waiting for result..."%s"' % str(self._get_result_future))
self._get_result_future.add_done_callback(self.get_result_callback)
def get_result_callback(self, future):
lapresult = future.result().result
self.get_logger().info('Result: {0}'.format(lapresult.current_total))
self.get_logger().info('1 Lap Completed. Stopping Robot')
self.movement.angular.z = 0.0
self.movement.linear.x = 0.0
self.pubisher_.publish(self.movement)
rclpy.shutdown()
def feedback_callback(self, feedback_msg):
feedback = feedback_msg.feedback
self.get_logger().info('Dist: {0:.4f}'.format(feedback.current_total))
If I understand correctly, within the goal_response_callback, the ‘add_done_callback’ should trigger when goal_handle.get_result_async() has succeeded. This should then call get_result_callback, but I’ve never gotten that far. I think these callbacks are written correctly, so I thought that I was publishing that information incorrectly within the server. here is my execute_callback and the method it references within (just in case that matters, but I don’t think its relevant).
def execute_callback(self, goal_handle):
self.get_logger().info('Executing goal...')
self.execute_goal = True
self.total_distance = 0.0
self.first_odom = Point()
self.last_odom = Point()
self.odom_record = []
self.stored_init_meas = False
while self.execute_goal is True:
time.sleep(1)
self.dist_calc()
goal_handle.publish_feedback(self.feedback_msg)
#self.get_logger().info('Exited while loop in Execute Callback')
goal_handle.succeed()
self.get_logger().info('goal_handle"%s"' % str(goal_handle.succeed))
result = OdomRecord.Result()
result.list_of_odoms = self.odom_record
self.get_logger().info('result"%s"' % str(result))
return result
def dist_calc(self):
if len(self.odom_record) >= 2:
dist_p1_p2 = ((self.odom_record[-1].x - self.odom_record[-2].x) ** 2 + (self.odom_record[-1].y - self.odom_record[-2].y) ** 2) ** 0.5
self.total_distance += dist_p1_p2
dist_to_start = (((self.odom_record[-1].x - self.first_odom.x) ** 2 + (self.odom_record[-1].y - self.first_odom.y) ** 2) ** 0.5)
if dist_to_start < 0.1 and len(self.odom_record) >= 180:
self.get_logger().info('Robot has returned to the initial position.')
self.execute_goal = False
self.stored_init_meas = False
#self.get_logger().info(
# f"self.odom_record list length: {len(self.odom_record)}, "
# f"total_distance: {self.total_distance:.3f}, "
# f"dist_to_start: {dist_to_start:.3f}"
#)
self.feedback_msg.current_total = self.total_distance
self.distance_publisher.publish(Float64(data=self.total_distance))
I don’t think the action server is telling the action client that the goal is complete so get_result_callback is never called. What am I missing?