ros2 pkg create py_srvcli --build-type ament_python --dependencies rclpy example_interfaces
from example_interfaces.srv import AddTwoInts # AddTwoInts 서비스 메시지 타입 임포트
import rclpy # ROS 2 Python 클라이언트 라이브러리 임포트
from rclpy.node import Node # ROS 2 노드를 만들기 위한 Node 클래스 임포트
# AddTwoInts 서비스를 제공하는 서비스 서버 클래스 정의
class MinimalService(Node):
# 생성자, 서비스 서버를 초기화
def __init__(self):
super().__init__('minimal_service') # 부모 클래스(Node) 생성자 호출, 고유한 노드 이름 설정
# 'add_two_ints' 서비스 생성, 이 서비스는 AddTwoInts 타입의 요청과 응답을 처리
# 서비스가 호출되면 add_two_ints_callback 함수가 호출됩니다.
self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_two_ints_callback)
# AddTwoInts 서비스 요청을 처리하는 콜백 함수
def add_two_ints_callback(self, request, response):
# 요청으로 받은 a와 b를 더하여 응답 객체의 sum 필드에 저장
response.sum = request.a + request.b
# 요청 받은 값을 로그로 출력
self.get_logger().info('Incoming request\na: %d b: %d' % (request.a, request.b))
# 응답 객체를 반환하여 클라이언트에 결과를 전달
return response
# 메인 함수, ROS 2 시스템 초기화 및 서비스 서버 실행
def main(args=None):
rclpy.init(args=args) # ROS 2 Python 클라이언트 라이브러리 초기화
# MinimalService 서비스 서버 인스턴스 생성
minimal_service = MinimalService()
# 서비스가 요청을 받을 수 있도록 대기
rclpy.spin(minimal_service)
# 노드 종료 후 rclpy.shutdown() 호출하여 ROS 2 클라이언트 라이브러리 종료
rclpy.shutdown()
# 이 파일이 직접 실행될 경우 main 함수 호출
if __name__ == '__main__':
main()
import sys # 커맨드 라인 인수 접근을 위한 sys 모듈 임포트
# example_interfaces 패키지에서 AddTwoInts 서비스 메시지 타입 임포트
from example_interfaces.srv import AddTwoInts
import rclpy # ROS 2 Python 클라이언트 라이브러리 임포트
from rclpy.node import Node # ROS 2 노드를 만들기 위한 Node 클래스 임포트
# AddTwoInts 서비스 클라이언트를 위한 MinimalClientAsync 클래스 정의
class MinimalClientAsync(Node):
# 생성자, 클라이언트 노드를 초기화
def __init__(self):
super().__init__('minimal_client_async') # 부모 클래스(Node) 생성자 호출, 고유한 노드 이름 설정
# 'add_two_ints' 서비스와 통신하기 위한 클라이언트 생성
self.cli = self.create_client(AddTwoInts, 'add_two_ints')
# 서비스가 사용 가능할 때까지 1초마다 대기
while not self.cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('service not available, waiting again...')
# AddTwoInts 서비스 요청 객체 생성
self.req = AddTwoInts.Request()
# a와 b 두 숫자를 받아서 요청을 보내는 메서드
def send_request(self, a, b):
# 요청 객체의 a와 b 필드에 값을 설정
self.req.a = a
self.req.b = b
# 서비스를 비동기적으로 호출하고 미래(future) 객체에 결과를 저장
self.future = self.cli.call_async(self.req)
# 서비스 응답이 올 때까지 블로킹하여 대기
rclpy.spin_until_future_complete(self, self.future)
# 서비스 호출 결과를 반환
return self.future.result()
# 메인 함수, ROS 2 시스템 초기화 및 서비스 호출
def main(args=None):
rclpy.init(args=args) # ROS 2 Python 클라이언트 라이브러리 초기화
# MinimalClientAsync 클라이언트 노드 인스턴스 생성
minimal_client = MinimalClientAsync()
# 커맨드 라인 인수로 받은 두 숫자를 send_request 메서드에 전달하여 서비스 호출
# sys.argv[1]과 sys.argv[2]는 커맨드 라인에서 입력된 두 숫자
response = minimal_client.send_request(int(sys.argv[1]), int(sys.argv[2]))
# 서비스 호출 결과 로그로 출력 (두 숫자의 합)
minimal_client.get_logger().info(
'Result of add_two_ints: for %d + %d = %d' %
(int(sys.argv[1]), int(sys.argv[2]), response.sum))
# 서비스 호출이 끝난 후 노드 파괴
minimal_client.destroy_node()
# ROS 2 클라이언트 라이브러리 종료
rclpy.shutdown()
# 이 파일이 직접 실행될 경우 main 함수 호출
if __name__ == '__main__':
main()
entry_points={
'console_scripts': [
'service = py_srvcli.service_member_function:main',
'client = py_srvcli.client_member_function:main',
],
},
ros2 service list
/*
/add_two_ints
/minimal_service/describe_parameters
/minimal_service/get_parameter_types
/minimal_service/get_parameters
/minimal_service/list_parameters
/minimal_service/set_parameters
/minimal_service/set_parameters_atomically
*/
ros2 service type /add_two_ints
/*
example_interfaces/srv/AddTwoInts
*/
ros2 service call /add_two_ints example_interfaces/srv/AddTwoInts "{a: 12, b: 22}"
/*
waiting for service to become available...
requester: making request: example_interfaces.srv.AddTwoInts_Request(a=12, b=22)
response:
example_interfaces.srv.AddTwoInts_Response(sum=34)
*/
Comments