[ros2] create_service, create_client

About_work·2023년 11월 16일
0

ros2

목록 보기
10/41
  • 서비스(Service)는 노드 간의 요청-응답(Request-Response) 통신 패턴을 구현하는 방법
  • 서비스는 일반적으로 하나의 노드에서 특정 작업을 수행하고, 그 결과를 요청한 노드에 반환

서비스(Service)란?

  1. 서비스 서버(Service Server): 서비스 요청을 받고 처리한 후 응답을 반환
  2. 서비스 클라이언트(Service Client): 서비스 서버에 요청을 보내고 응답을 기다림

create_service 사용법

  • create_service 함수는 ROS 2 노드 내에서 서비스 서버를 생성하는 데 사용
  • 이 함수를 사용하여 서비스 타입, 서비스 이름, 콜백 함수를 지정하여 서비스 서버를 설정할 수 있습니다.

매개변수

  1. srv_type: 서비스 타입을 나타냅니다. 이는 서비스의 요청과 응답 메시지 구조를 정의하는 클래스입니다.
  2. service_name: 서비스의 이름입니다. 이 이름은 ROS 2 네트워크 내에서 서비스를 고유하게 식별하는 데 사용됩니다.
  3. callback: 서비스 요청이 들어올 때 호출될 함수입니다. 이 콜백 함수는 요청을 받고 적절한 응답을 반환해야 합니다.
  4. callback_group (선택적): 콜백이 실행될 콜백 그룹입니다. 이 인자는 선택적이며, 지정하지 않을 경우 기본 콜백 그룹이 사용됩니다.
  5. qos_profile (선택적): 서비스의 Quality of Service(QoS) 프로필입니다. 이 인자는 선택적이며, 지정하지 않을 경우 기본 QoS 설정이 사용됩니다.

코드 예시

import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts  # 예시 서비스 타입

class MyServiceServer(Node):

    def __init__(self):
        super().__init__('my_service_server')
        self.service = self.create_service(AddTwoInts, 'add_two_ints', self.add_two_ints_callback)

    def add_two_ints_callback(self, request, response):
        response.sum = request.a + request.b
        return response

rclpy.init()
node = MyServiceServer()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
  • 이 예시에서, MyServiceServer 노드는 AddTwoInts 서비스 타입으로 add_two_ints 서비스를 생성합니다. add_two_ints_callback 함수는 요청을 처리하고 응답합니다.

create_client 사용법

  • create_client 함수는 ROS 2 노드 내에서 서비스 클라이언트를 생성하는 데 사용됩니다.
  • 이 함수를 사용하여 서비스 타입과 서비스 이름을 지정하여 서비스 클라이언트를 설정할 수 있습니다.

매개변수

  1. srv_type: 서비스 타입을 나타냅니다. 이는 클라이언트가 사용할 서비스의 요청과 응답 메시지 구조를 정의하는 클래스입니다.
  2. service_name: 클라이언트가 연결할 서비스의 이름입니다. 이 이름은 서비스 서버와 일치해야 합니다.
  3. qos_profile (선택적): 서비스의 Quality of Service(QoS) 프로필입니다. 이 인자는 선택적이며, 지정하지 않을 경우 기본 QoS 설정이 사용됩니다.
  4. callback_group (선택적): 클라이언트 콜백이 실행될 콜백 그룹입니다. 이 인자는 선택적이며, 지정하지 않을 경우 기본 콜백 그룹이 사용됩니다.

코드 예시

import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts  # 예시 서비스 타입

class MyServiceClient(Node):

    def __init__(self):
        super().__init__('my_service_client')
        self.client = self.create_client(AddTwoInts, 'add_two_ints')
        while not self.client.wait_for_service(timeout_sec=1.0):
            self.get_logger().info('서비스가 활성화될 때까지 기다리는 중...')
        self.req = AddTwoInts.Request()

    def send_request(self):
        self.req.a = 10
        self.req.b = 20
        self.future = self.client.call_async(self.req)

rclpy.init()
node = MyServiceClient()
node.send_request()

while rclpy.ok():
    rclpy.spin_once(node)
    if node.future.done():
        try:
            response = node.future.result()
        except Exception as e:
            node.get_logger().info('서비스 호출 중 에러 발생: %r' % (e,))
        else:
            node.get_logger().info('결과: %d' % (response.sum))
        break

node.destroy_node()
rclpy.shutdown()
  • rclpy.ok() , rclpy.spin_once(node), rclpy.shutdown(): https://velog.io/@jk01019/rclpy
  • node.future.done(), node.future.result(), node.destroy_node(): https://velog.io/@jk01019/ros2-Node
  • 이 예시에서, MyServiceClient 노드는 AddTwoInts 서비스 타입으로 add_two_ints 서비스에 연결하는 클라이언트를 생성합니다.
  • send_request 메서드는 서비스 요청을 보내고 응답을 기다립니다.

함수 설명

1. self.client.wait_for_service(timeout_sec=1.0)

  • 함수는 서비스 클라이언트가 특정 서비스가 사용 가능해질 때까지 대기하는 데 사용됩니다.
  • 이 함수는 지정된 시간 동안 서비스가 활성화될 때까지 기다립니다.
  • 목적: 서비스 클라이언트가 서비스 요청을 보내기 전에, 해당 서비스 서버가 활성화되어 있고 준비되었는지 확인하는 데 사용
  • 파라미터 timeout_sec:
    • 이 파라미터는 함수가 서비스의 사용 가능 여부를 확인하는 데 대기할 최대 시간(초 단위)을 지정합니다.
    • 지정된 시간 동안 서비스가 활성화되지 않으면 함수는 False를 반환합니다.
  • 응용:
    • 서비스 서버가 아직 준비되지 않았을 때 클라이언트가 서비스 요청을 보내는 것을 방지하기 위해 사용

2. self.client.call_async(self.req)

  • 서비스 클라이언트가 서비스 서버에 비동기적으로 서비스 요청을 보내는 데 사용
  • 이 함수는 서비스 요청을 서버에 전송하고 즉시 반환
  • 서버의 응답은 비동기적으로 처리

  • 목적: 비동기 서비스 요청을 보내어, 서비스 요청의 처리와 응답이 클라이언트의 나머지 처리 흐름을 차단하지 않도록 함
  • 파라미터 self.req: 이는 서비스 요청을 나타내는 객체입니다. 이 객체는 서비스 타입에 따라 정의된 데이터 구조를 포함합니다.
  • 반환 값:
    • 이 함수는 Future 객체를 반환합니다.
    • Future 객체를 사용하여 서비스 응답의 완료 상태와 결과를 나중에 확인할 수 있습니다.
  • 응용:
    • 서비스 클라이언트가 서비스 요청을 보내고, 그 동안 다른 작업을 계속 진행할 수 있도록 합니다.
    • 응답은 Future 객체를 통해 나중에 처리됩니다.

self.srv_cli.call(req)

  • 결론적으로, call 메서드는 동기적으로 서비스 요청을 처리하고, call_async 메서드는 비동기적으로 처리합니다.
  • 비스 클라이언트가 서비스 서버에 동기적으로 서비스 요청을 보내는 데 사용됩니다.
  • 동작 방식: 이 메서드는 서비스 요청을 서버에 보내고 서버로부터 응답을 받을 때까지 실행을 차단합니다. 즉, 응답이 도착할 때까지 프로그램의 실행이 멈추게 됩니다.
  • 사용 상황: 요청의 결과를 즉시 필요로 하고, 요청 처리 시간이 짧은 경우에 적합합니다. 또한 프로그램의 다른 부분이 요청의 결과에 의존적인 경우에도 사용됩니다.

profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글