ros topic 다음으로 자주 쓰이는 개념이 service이다.
거두절미 하고 바로 service에 대해 배워보자
Let's go
목표
ROS2 Service의 개념에 대해서 배운다!
예상 소요시간
10분
Service란 무엇일까?
이름에서 한 번 유추해보자. 1분의 시간을 주겠다.
Service란 이름대로 무엇가를 요청하는 것하는 것을 의미한다. 보통 요청했으면 어떤 반응을 얻지 않는가?
예를 들어 식당에 전화해 음식 배달 서비스를 요청했다고 해보자. 그러면 요청한 서비스가 접수되고 음식 서비스가 가능한지 여부를 상대방에게서 듣게된다.
이렇듯 서비스는 요청(이하 call) 그리고 응답(response)형태로 이루어진 node간 통신 방식을 의미한다.
하단의 그림 2개를 살펴보자
<그림1>
그림 1에서 보면 service client(고객이라고 생각하면 쉽다)는 요청사항을 request message를 생성해 service server(서비스를 세공하는 식당이라고 생각하자)에 요청(request)한다. 그러면 server는 이를 받아 처리한 후 고객이 요청한 서비스가 어떻게 처리 됐는지 응답(response) 형태로 고객에게 알려준다.
<그림2>
그림 2는 2명의 서로 다른 고객(2개의 node)이 같은 형태의 서비스를 service server(식당)에 요청하고 있다.
sudo apt-get install terminator
/turtlesim 과 /teleop_turtle node를 다음 명령어를 통해 각각 실행한다.
ros2 run turtlesim turtlesim_node
ros2 run turtlesim turtle_teleop_key
명령어 이름에서도 짐작할 수 있듯이 ros2 servie list라는 명령어는 현재 실행된 node에 의해 제공되는 모든 사용가능한 service를 나열해준다.
다음 명령어를 실행해보자.
ros2 service list
그렇다면 /turtlesim과 /teleop_turtle node에 의해 제공되는 service들의 이름이 다음과 같이 나열될 것이다.
/clear
/kill
/reset
/spawn
/teleop_turtle/describe_parameters
/teleop_turtle/get_parameter_types
/teleop_turtle/get_parameters
/teleop_turtle/list_parameters
/teleop_turtle/set_parameters
/teleop_turtle/set_parameters_atomically
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/describe_parameters
/turtlesim/get_parameter_types
/turtlesim/get_parameters
/turtlesim/list_parameters
/turtlesim/set_parameters
/turtlesim/set_parameters_atomically
아... 보기만 해도 뭐가 뭔지 어질어질 하네..
그렇지만 I Robo U와 함께라면 걱정할 필요가 없다.
"turtlesim 관련 패키지 설치하기(turtlesim 패키지 설치 설명 포스트 바로가기)" 글을 본 사람들은 /spawn이나 /turtle1/set_pen과 같은 service를 몇 번 사용해본 경험이 있을 것이다.
없다고? 괜찮다. 차근차근 살펴볼 것이다.
우리가 살면서 서비스를 요청할 때 요구하는 사항이 뭔지 잘 정리해서 요구하듯이 ROS Service에도 내가 무엇을 요청하려는지 잘 정리해서 보내야한다. 이렇게 정해진 형태를 service type이라고 한다.
예를 들어 음식 주문 서비스를 이용할 때는 기본적으로 주문할 음식 이름, 배달 장소 등을 직원에게 전달해야 한다.
그럼 이런 service별로 정의된 type을 어떻게 알 수 있을까?
ros2 service type을 사용하면 되는데 문법은 다음과 같다.
ros2 service type <서비스 이름>
예를 들어 /clear 라는 서비스의 type을 알아보자
다음 명령어를 실행하자.
ros2 service type /clear
다음과 같은 내용이 반환될 것이다.
std_srvs/srv/Empty
이말은 std_srvs라는 패키지에 srv라는 폴더안에 Empty라는 service type을 사용한다는 말이다.
Empty는 요청할 때 아무 데이터도 채워 넣지 않고 그냥 요청하면 될 때 사용한다. 또한 응답 데이터도 없다.
이게 뭔 말인가 싶을것이다. 나도 뭔지 처음에는 이해하기 어려웠다.
학습하다보면 점점 익숙해지므로 지금은 그러려니 하고 넘어가면 된다.
ros2 service list 명령어와 같이 사용할 수 있는 -t 라는 인자가 있다.
이는 type을 의미하는데 service의 이름들과 해당 service의 type들도 같이 표시해준다.
다음 명령어를 입력해보자.
ros2 service list -t
다음과 같은 화면이 뜰 것이다.
/clear [std_srvs/srv/Empty]
/kill [turtlesim/srv/Kill]
/reset [std_srvs/srv/Empty]
/spawn [turtlesim/srv/Spawn]
...
/turtle1/set_pen [turtlesim/srv/SetPen]
/turtle1/teleport_absolute [turtlesim/srv/TeleportAbsolute]
/turtle1/teleport_relative [turtlesim/srv/TeleportRelative]
...
또 다른 유용한 명령어는 ros2 service find인데, 이 명령어를 사용하면 이 특정 service type을 갖는 service들을 찾아준다.
다음 명령어는 std_srvs패키지 안에 srv 폴더에 있는 Empty와 같은 type을 사용하는 service를 찾아줘~ 라는 의미이다.
ros2 service find std_srvs/srv/Empty
다음을 반환 할 것이다.
/clear
/reset
즉 /clear와 /reset service는 Empty라는 service type을 사용한다.
다음으로 살펴볼 명령어는 ros2 interface show라는 명령어이다.
이 명령어를 사용하면 특정 service type의 구조(request와 response정보)를 보여준다(show).
아까 살펴봤던 Empty의 구조를 살펴보자.
다음 명령어를 입력하면,
ros2 interface show std_srvs/srv/Empty
다음과 같이 화면에 뜬다.
---
오잉? 작은 막대기 3개가 나타나고 끝났다.
오타아니야? 라고 생각할 수 있겠지만 이게 정상이다.
이 작은 막대기 3개는 request와 response를 구분 짓는 구분선이다.
구분선 위로는 request의 필요한 구조가, 구분선 밑으로는 response의 필요한 구조가 표시된다.
Empty type의 경우 request와 response는 아무 것도 필요하지 않음을 의미한다.
그렇다면 다른 type을 살펴보자.
turtlesim패키지 안에 있는 srv폴더안 Spawn이라는 service type을 살펴보기 위해 다음 명령어를 실행하자.
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
천천히 살펴보면 구분선 위 request부분에는 float32 x, float32 y, float32 theta, string name 이렇게 있는데 float32와 string은 데이터 타입을 의미하고, x,y,theta는 turtle이 생성될 위치와 각도, 그리고 name은 생성될 turtle의 이름을 의미한다.
구분 선 아래 response부분에는 string name이 있는데 생성할 때 지정했던 이름이 반환된다고 보면 된다. 이게 있는 이유는 request할 때 이름을 특정하게 지정하지 않으면 고유한 이름을 지어주는데 그 고유한 이름을 사용자가 response형태로 받아볼 수 있게 하기 위함이다.
지금 까지 서비스 이름은 무엇이고 서비스는 어떻게 구성되어있는지 알려주는 명령어를 배웠는데,
그 이유는 ros2 service call이라는 명령어를 사용하기 위한 빌드업이였다!
ros2 service call은 터미널에서 원하는 서비스를 요청하는데 사용할 수 있는 명령어이다.
문법은 다음과 같다.
ros2 service call <요청하고자 하는 서비스 이름> <해당 서비스의 타입> <서비스 타입의 request 구조>
예를 들어 /clear 서비스를 요청하려면 다음과 같은 명령어를 사용할 수 있다.
ros2 service call /clear std_srvs/srv/Empty
위의 명령어는 /clear라는 서비스중 std_srvs 패키지의 srv 폴더에 있는 Empty라는 타입을 사용하는 서비스를 불러줘.
근데 Empty는 앞서 살펴봤듯이 아무 것도 작성할 필요가 없으니까 서비스 타입의 request 구조란은 비워 놓겠어.
라는 의미이다.
turtle을 조금 움직인 후 해당 명렁어를 입력하면 다음과 같이 흰색으로 표시됐던 지나온 경로가 모두 지워지는 것을 확인 할 수 있다.
또 다른 예시로 spawn을 사용해보자.
사용하는 명령어는 다음과 같다.
ros2 service call /spawn turtlesim/srv/Spawn "{x: 2, y: 2, theta: 0.2, name: ''}"
하나씩 뜯어보면 /spawn이라는 서비스 중에 turtlesim 패키지의 srv폴더 안에 있는 Spawn이라는 서비스 타입을 사용하는 녀석을 요청할거야. 근데 요청할 때 x는 2, y는 2 theta는 0.2로 부탁해.
이름은 따로 적지 않을게~
라는 의미를 갖는다.
이 명령어를 터미널에서 실행하면 아래와 유사하게 turtle하나가 생성될 것이다.
여태까지 서비스의 개념부터 관련된 명령어 도구들을 엄청 배웠다.
ROS2로 인공지능 & 로봇 개발을 하다보면 디버깅 할 때나 실험할 때 자주 사용될 수 있는 명령어들이라서 지금 익숙하지 않더라도 나중에 쓰다보면 익숙해질 것이다.
까먹어도 인터넷에서 다시 찾아서 하면 되니 걱정안해도 된다.
여기까지 왔으니까 스스로에게 칭찬 한 마디 해주자.
"넌 역시 대단해 ㅎㅎ"
질문하고 싶거나 인공지능 & 로봇 개발에 대해 다뤄줬으면 하는 주제를 댓글로 남겨주기 바란다~!
문의메일: irobou0915@gmail.com
오픈톡 문의: https://open.kakao.com/o/sXMqcQAf
IRoboU 유튜브 채널: https://www.youtube.com/channel/UC2-d99PrBwJy15MjPa32zYg