ROS 2 Actions tutorials

Actions are used for tasks that take time to complete and may need feedback or be canceled, such as moving to a specific position. Actions allow continuous communication between nodes during long tasks, providing feedback or allowing users to cancel the task midway.

Example: Using Actions in ROS 2

Let's create an action server and client to move a robot to a target position.

  1. Create an Action Server:

    • Open a new file simple_action_server.py and write the following code:

      import rclpy
      from rclpy.node import Node
      from example_interfaces.action import Fibonacci
      from rclpy.action import ActionServer
      
      class FibonacciActionServer(Node):
          def __init__(self):
              super().__init__('fibonacci_action_server')
              self.action_server = ActionServer(self, Fibonacci, 'fibonacci', self.execute_callback)
      
          def execute_callback(self, goal_handle):
              self.get_logger().info('Executing goal...')
              feedback_msg = Fibonacci.Feedback()
              result = Fibonacci.Result()
      
              sequence = [0, 1]
              for i in range(2, goal_handle.request.order):
                  sequence.append(sequence[i-1] + sequence[i-2])
                  feedback_msg.sequence = sequence
                  goal_handle.publish_feedback(feedback_msg)
      
              result.sequence = sequence
              goal_handle.succeed()
              return result
      
      def main(args=None):
          rclpy.init(args=args)
          node = FibonacciActionServer()
          rclpy.spin(node)
          rclpy.shutdown()
      
      if __name__ == '__main__':
          main()
  2. Create an Action Client:

    • Open another file simple_action_client.py and add this code:

      import rclpy
      from rclpy.node import Node
      from example_interfaces.action import Fibonacci
      from rclpy.action import ActionClient
      
      class FibonacciActionClient(Node):
          def __init__(self):
              super().__init__('fibonacci_action_client')
              self.action_client = ActionClient(self, Fibonacci, 'fibonacci')
      
          def send_goal(self, order):
              goal_msg = Fibonacci.Goal()
              goal_msg.order = order
              self.action_client.wait_for_server()
              self._send_goal_future = self.action_client.send_goal_async(goal_msg)
      
      def main(args=None):
          rclpy.init(args=args)
          client = FibonacciActionClient()
          client.send_goal(10)
          rclpy.spin(client)
          rclpy.shutdown()
      
      if __name__ == '__main__':
          main()
  3. Run the Server and Client:

    • Run the action server in one terminal:

      python3 simple_action_server.py
    • Then run the action client in another terminal:

      python3 simple_action_client.py

Last updated