[ROS2] (6)-Service의 개념

Service란?

서비스는 노드 간에 통신하는 또 다른 방법이다. 토픽이 단방향으로 계속해서 메시지를 전달하는 것과는 다르게 서비스는 요청이 있을 때에만 메시지를 전달한다. 서비스를 요청하는 노드를 client, 요청에 응답하는 노드를 server라고 한다. 하나의 서비스에 여러 개의 클라이언트가 있을 수는 있지만, 서버는 하나밖에 있을 수 없다.

서비스는 일회성이므로, 연속적으로 데이터를 요청해야하는 경우에는 서비스보다 토픽이 더 적합하다.

이번 포스팅에서 사용할 Service 관련 명령어를 정리하면 다음과 같다.

$ ros2 service list
$ ros2 service type <service_name>
$ ros2 service list -t
$ ros2 service find <type_name>
$ ros2 interface show <type_name>.srv
$ ros2 service call <service_name> <service_type> <arguments>

Service 정보 확인

2개의 터미널 창을 열고 아래 2가지 명령을 실행한다.

$ ros2 run turtlesim turtlesim_node
$ ros2 run turtlesim turtle_teleop_key

터미널 창을 새로 열고, ros2 service list를 입력한다. 그러면 현재 활성화된 서비스 목록이 나온다.

서비스의 타입을 확인하는 방법은 Topic과 유사하게 다음의 2가지가 있다. ros2 service type <service_name>, ros2 service list -t 명령어를 통해 서비스의 타입을 확인할 수 있다.

ros2 service find <type_name>을 통해 특정 타입을 갖는 서비스를 모두 찾을 수도 있다.

서비스를 요청하기 위해서는 먼저 서비스의 구조를 알아야 한다. 구조를 확인하기 위해서는 ros2 interface show <type_name>.srv 명령어를 이용하면 된다. 토픽과 다른점은 .srv를 입력해주어야 하는 것이다.

$ ros2 interface show std_srvs/srv/Empty.srv

상기 명령어를 실행하면 ---이라는 결과가 나올 것이다. ---의 위쪽은 요청 데이터 구조이고, 아래쪽은 응답 데이터 구조이다. std_srvs/srv/Empty 타입의 서비스는 어떤 데이터도 주고받지 않기 때문에 ---만 출력되는 것이다.

이제 아래 명령어를 실행해보자.

$ ros2 interface show turtlesim/srv/Spawn

다음의 결과가 나온다.

float32 x
float32 y
float32 theta
string name # Optional.  A unique name will be created and returned if this is empty
---
string name

turtlesim/srv/Spawn 서비스를 요청하기 위해서는 x, y, theta 값을 필수적으로 전달해야 하고, name은 선택사항이라는 것을 알 수 있다. 그리고 해당 서비스는 응답으로 name을 전달해주는 것을 알 수 있다.

터미널 창에서 서비스 요청

토픽과 유사하게 터미널창에서 서비스를 직접 요청할 수도 있다. 서비스를 요청하기 위해서는 ros2 service call <service_name> <service_type> <arguments> 명령어를 사용한다. 토픽과 마찬가지로 <arguments>는 YAML 문법을 사용한다.

서비스 요청을 위해 전달해야 할 데이터가 없는 경우 <arguments>는 생략 가능하다. 예를 들어, 위에서 본 것처럼 std_srvs/srv/Empty 타입의 서비스는 서비스 요청을 할 때, 입력해야 할 데이터가 없다.

$ ros2 service call /clear std_srvs/srv/Empty

상기 명령어를 실행하면 다음과 같이 turtle이 움직인 경로를 모두 제거해준다.

image

image

이제 /spawn 서비스를 통해 새로운 거북이를 생성해보자. (참고로 <argument>를 입력할 때, x:2라고 입력하면 안된다. x: 2 처럼 띄워쓰기를 해주어야 한다.)

$ ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: ''}"

명령어를 입력하면 다음과 같이 turtle2라는 이름으로 새로운 거북이를 만들었다는 응답을 출력한다.

response:
turtlesim.srv.Spawn_Response(name='turtle2')

실제로 새로운 거북이가 생성되었다.

image

댓글남기기