| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Baekjoon
- deep learning
- On-memory file system
- Linux
- Seoul National University
- SQLD
- Data Science
- Gentoo2
- RNN
- computer vision
- Machine Learning
- do it! 알고리즘 코딩테스트: c++편
- BFS
- Python
- C++
- DFS
- ubuntu 22.04
- Humble
- Operating System
- CPP
- System Call
- Optimization
- 밑바닥부터 시작하는 딥러닝2
- file system
- CNN
- assignment1
- assignment2
- ROS2
- Process
- cs231n
- Today
- Total
newhaneul
[ROS2 Humble] Python으로 서비스 클라이언트 다루기 본문
본 포스팅은 '민형기 저자의 'ROS2 Humble 혼자 공부하는 로봇SW 직접 만들고 코딩하자'를 읽고 공부한 내용을 정리하기 위한 포스팅입니다.
1. Python으로 ROS Service Client 사용하기
1.1 학습을 위한 준비와 Service Client를 위한 노드 생성
마찬가지로 ROS의 기능을 Python으로 사용할 수 있는 rclpy를 rp로 import 한다. 그리고 이번에는 service call을 연습했었던 /turtle1/teleport_absolute 서비스를 Python으로 접근하는 연습을 할 예정인데, /turtle1/teleport_absolute 서비스는 정의는 'ros2 service list -t' 명령으로 확인 가능하다.
ros2 service list -t

'/turtle1/teleport_absolute' 서비스를 사용하기 위해 python에서는 turtle.sim.srv.TeleportAbsolute를 import한다. 그 후 rclpy를 초기화하고, client_test라는 이름의 노드를 test_node로 하나 만들어 둔다.

ros2의 공식 문서로 rclpy의 create_node에 대한 설명 부분을 확인해볼 수 있다. 결과를 보면 return이라는 항목이, Node라는 클래스를 return 한다는 것을 확인할 수 있다.
https://docs.ros.org/en/iron/p/rclpy/api/init_shutdown.html#rclpy.create_node
Initialization, Shutdown, and Spinning — rclpy 3.2.1 documentation
© Copyright 2016-2022, Open Source Robotics Foundation, Inc..
docs.ros.org

create_node가 return 하는 Node 클래스의 공식 문서는 아래에서 확인할 수 있다. 현재 test_node라는 이름으로 Node class를 지정해 두었으니 이제 test_node 변수 뒤에 속성이나 함수를 호출할 수 있는 점을 찍고 호출할 수 있다. 그렇게 사용할 수 있는 함수 중 하나가 create_client이다.


1.2 서비스를 요청하는 service client 생성
test_node라는 변수에 create_node 클래스를 지정하였다. 이제 만들어 둔 test_node에서 create_clinet 함수를 이용해본다. create_client 함수는 서비스 정의와 서비스 이름을 최소한 입력으로 전달해야 한다.
서비스의 이름은 '/turtle1/teleport_absolute'이고 이를 service_name이라는 변수에 저장했다. 그리고 'ros2 service list -t' 명령어를 통해 '/turtle1/teleport_absolute'의 데이터 타입이 'TeleportAbsolute'라는 것을 알고 있으므로 밑에서 import 해 두었다.

여기서 cli라는 변수는 Client라는 클래스를 반환 받은 것이다. 이제 Client의 여러 함수와 속성은 cli라는 변수를 통해 사용할 수 있다.
1.3 서비스 정의를 Python에서 사용할 준비하기
서비스는 요청하면 응답을 받는 것이다. 그리고 요청할 때 사용하는 데이터의 타입과 응답할 때 사용하는 데이터의 타입을 srv라는 파일로 저장해 둔다고 하였다. 그 srv 파일을 서비스 정의 (service definition)라고 한다.
현재 '/turtle1/teleport_absolute'라는 서비스를 다루기 위해 해당 서비스의 정의인 TeleportAbsolute를 import한 상황이다. ROS는 서비스 정의를 포함한 패키지를 사용자가 잘 설정해서 만들어 두었다면 빌드할 때 해당 메시지 정의를 Python 유저가 모듈로 사용할 수 있도록 잘 변환해 준다.
TeleportAbsolute는 대시 3개 (---)로 부터 요청과 응답으로 구분되어 있다. 그래서 요청 부분만 사용하려면 아래 코드를 작성해야 한다.
req = TeleportAbsolute.Request()
위와 같이 코드를 작성하면 req라는 변수에 TeleportAbsolute의 요청 부분만 사용할 수 있게 된다.
이제 req에 TeleportAbsolute.Request()를 지정하고 아래에서처럼 req를 코드 블록 마지막에 위치시켜서 실행하면 req라는 변수의 내용이 출력된 것을 확인할 수 있다. req의 변수 값을 바꾸고 싶은 경우는 x, y, theta 중 원하는 것의 내용을 다시 저장하면 된다.

1.4 간단히 service call을 실행해 보기

Client 관련 내용 중에 call_async가 있다. 이 명령을 사용하려면 'cli.call_async(req)'를 통해 사용할 수 있다.
cli.call_async(req)

이제 req의 x 성분을 3으로 바꾸고, cli에서 call_async를 호출할 때 req를 입력으로 주고, 노드가 한 번 응답이 올 때까지 기다려 보는 코드를 작성하고 실행하면 아래의 결과를 얻을 수 있다.


1.5 wait_for_service 사용해보기
서비스 클라이언트는 해당 서비스 서버를 운영하는 노드가 실행되어야 사용이 가능하다. 그런데 서비스 클라이언트를 포함한 작성하거나 실행하는 노드가, 어떤 서비스 서버를 실행하는 노드보다 먼저 실행되어 있어야 한다면 방금과 같은 방법으로 실행하기가 어렵다. 서비스가 실행될 때까지 코드가 아주 오랜 시간 멈춰버리거나 혹은 에러가 발생할 수 있기 때문이다.
이런 상황 때문에 조금 괜찮은 방법으로 접근할 수 있는 도구가 wait_for_service이다.
아래 코드의 wait_for_service는 cli에서 설정한 서비스가 timeout_sec 옵션에서 설정한 시간 동안 실행되기를 기다린다. 만약 해당 서비스가 실행되지 않으면 False를 반환하기 때문에, 위 코드는 그 앞에 not을 붙여서 사용한다.
while not cli.wait_for_service(timeout_sec = 1.0):


1.6 서비스 클라이언트가 실행되는 상황 확인하기
ROS2 문서에서 service client를 설명하던 하단에 call_async를 설명하는 항목에 보면 call_async는 Future라는 것을 반환한다고 설명한다. Future는 done()과 result()라는 함수가 서비스 클라이언트를 호출한 후의 상황을 알려준다.
아래 코드는 call_async가 반환하는 Future를 future 변수에 저장하고, future.done()이 제공하는 완료가 나타날 때까지, 즉 future.done()이 True가 될 때까지 spin_once를 계속 실행한다. 그리고 future.result()에는 서비스가 잘 실행되고 나면 해당 서비스의 Response()가 명시된다.

'1. Programming > ROS' 카테고리의 다른 글
| [ROS2 Humble] Python으로 ROS2 토픽 다루기 (0) | 2026.01.04 |
|---|---|
| [ROS2 Humble] ROS2 기본 명령어 (1) | 2026.01.01 |
| [ROS2 Humble] 터미널과 bashrc 설정 (0) | 2026.01.01 |