Ubuntu ROS 실습(13)

zeusqoi·2일 전

개인공부

목록 보기
32/42

이번에는 ROS 2에서 Service를 이용해 노드 간 요청과 응답을 주고받는 방법을 실습했다.

앞서 Topic에서는 Publisher가 메시지를 발행하고 Subscriber가 이를 구독하는 방식으로 통신했다면, Service는 Client가 Server에게 특정 작업을 요청하고 그 결과를 응답받는 방식으로 동작한다.


1. Service란?

ROS 2의 Service는 요청(Request)과 응답(Response)을 주고받는 통신 방식이다.

Service를 사용하는 노드는 크게 두 가지 역할로 나뉜다.

  • Service Client: 작업을 요청하는 쪽
  • Service Server: 요청을 받아 작업을 수행하고 응답하는 쪽

전체적인 구조는 다음과 같다.

Service Client
      │
      │ Request
      ↓
Service Server
      │
      │ Response
      ↓
Service Client

Topic이 지속적으로 데이터를 주고받는 데 적합하다면, Service는 특정 작업을 요청하고 그 결과를 받는 상황에서 사용할 수 있다.


2. Service 목록 확인

현재 ROS 2 시스템에서 사용할 수 있는 Service를 확인하기 위해 다음 명령어를 사용한다.

ros2 service list

Turtlesim을 실행한 상태에서 명령어를 실행하면 다음과 같은 Service들을 확인할 수 있다.

/clear
/kill
/reset
/spawn
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative

이를 통해 현재 실행 중인 노드에서 어떤 Service를 제공하고 있는지 확인할 수 있다.


3. Service 타입 확인

Service의 이름뿐만 아니라 어떤 인터페이스를 사용하는지도 확인할 수 있다.

ros2 service list -t

예를 들어 다음과 같이 확인할 수 있다.

/clear [std_srvs/srv/Empty]
/kill [turtlesim/srv/Kill]
/spawn [turtlesim/srv/Spawn]

특정 Service의 타입만 확인하려면 다음과 같이 사용할 수 있다.

ros2 service type /spawn

실행 결과:

turtlesim/srv/Spawn

즉, /spawn Service는 turtlesim/srv/Spawn이라는 Service 인터페이스를 사용한다.


4. 특정 타입의 Service 찾기

특정 Service 인터페이스를 사용하는 Service를 찾을 수도 있다.

예를 들어 std_srvs/srv/Empty 타입을 사용하는 Service를 찾으려면:

ros2 service find std_srvs/srv/Empty

실행 결과:

/clear
/reset

또한 turtlesim/srv/Kill 타입을 사용하는 Service를 찾을 수도 있다.

ros2 service find turtlesim/srv/Kill

결과:

/kill

이처럼 ros2 service find 명령어를 사용하면 특정 Service 타입이 실제로 어떤 Service에서 사용되고 있는지 확인할 수 있다.


5. Service 호출하기

ros2 service call 명령어를 사용하면 Service에 직접 요청을 보낼 수 있다.

먼저 /clear Service를 호출해 보았다.

ros2 service call /clear std_srvs/srv/Empty

/clear는 별도의 요청 데이터를 필요로 하지 않기 때문에 Empty 타입을 사용한다.

호출이 정상적으로 이루어지면 다음과 같은 요청과 응답을 확인할 수 있다.

requester: making request: std_srvs.srv.Empty_Request()

response:
std_srvs.srv.Empty_Response()

6. Turtlesim Service 호출

이번에는 /reset Service를 호출해 보았다.

ros2 service call /reset std_srvs/srv/Empty

Service가 호출되면 Turtlesim의 상태가 초기화된다.

또한 /kill Service를 이용하면 특정 거북이를 삭제할 수 있다.

ros2 service call /kill turtlesim/srv/Kill "name: 'turtle1'"

여기서는 turtle1이라는 이름을 가진 거북이를 삭제하도록 Service Server에 요청한다.

즉,

Client
  │
  │ name: turtle1
  ↓
/kill Service
  │
  ↓
turtle1 삭제

와 같은 방식으로 동작한다.


7. Service Interface

Service에서는 srv 인터페이스를 사용한다.

Service 인터페이스는 일반적으로 다음과 같이 구성된다.

Request
---
Response

---는 Request와 Response를 구분하는 역할을 한다.

Turtlesim의 /spawn Service에서 사용하는 인터페이스를 확인해 보았다.

ros2 interface show turtlesim/srv/Spawn.srv

결과는 다음과 같은 구조로 되어 있다.

float32 x
float32 y
float32 theta
string name
---
string name

여기서 ---를 기준으로 위쪽은 Request, 아래쪽은 Response이다.

Request
 ├─ x
 ├─ y
 ├─ theta
 └─ name
       │
       ↓
    Service
       │
       ↓
Response
 └─ name

즉, Client가 x, y, theta, name 정보를 전달하면 Service Server가 새로운 거북이를 생성하고, 생성된 거북이의 이름을 Response로 반환하는 구조이다.


8. Topic과 Service 비교

앞에서 실습한 Topic과 이번에 실습한 Service를 비교하면 다음과 같다.

구분TopicService
통신 방식Publisher → SubscriberClient → Server → Client
데이터 흐름단방향요청/응답
인터페이스msgsrv
주요 용도지속적인 데이터 전달특정 작업 요청 및 결과 확인

Topic에서는 메시지를 계속 발행하고 구독하는 반면, Service에서는 필요한 시점에 작업을 요청하고 그에 대한 응답을 받는 방식으로 동작한다.


마무리

이번 실습에서는 ROS 2의 Service 통신 방식을 직접 확인했다.

먼저 ros2 service list를 이용해 현재 실행 중인 Service를 확인하고, ros2 service type을 통해 Service의 인터페이스 타입을 확인했다.

또한 ros2 service find를 이용해 특정 인터페이스를 사용하는 Service를 찾고, ros2 service call을 이용해 실제 Service에 요청을 보내는 과정까지 실습했다.

마지막으로 turtlesim/srv/Spawn의 srv 인터페이스를 확인하면서 Request와 Response가 어떻게 정의되어 있는지도 확인했다.

전체적인 구조를 정리하면 다음과 같다.

ROS 2 Service

Service Client
      │
      │ Request
      ↓
Service Server
      │
      │ Response
      ↓
Service Client

그리고 Service에서 사용하는 인터페이스는 다음과 같이 Request와 Response로 구성된다.

Request
---
Response

따라서 Topic이 지속적인 데이터 전달에 사용된다면, Service는 특정 작업을 요청하고 그 결과를 받는 통신 방식이라고 정리할 수 있다.

0개의 댓글