[ ROS ] ROS를 이해해보자 #3
0. 머리말
지난 번에는 Topic을 주고 받는 Publisher와 Subscriber를 소개하였으며, Topic을 이용한 통신 방식에 대한 특징들도 알아보았다. 이번에는 직접 코드를 적용해서 경험해보도록 하자. 앞선 글에서 짤막한 코드만으로는 Publisher와 Subscriber를 사용하기에 어려울 수 있다고 생각하여 같이 해보는 글을 준비했다.
시작에 앞서, 나는 Ubuntu 18.04, ROS Melodic을 사용했다. 그리고, 이 글은 ROS wiki의 튜토리얼(C++)을 기반으로 진행했다.
1. 다운로드
우선, 아래의 커맨드를 통해 워크 스페이스(e.g. catkin_ws)를 만들고 그 안에 있는 src 폴더에 튜토리얼 패키지를 다운로드해주자. catkin_ws인 워크 스페이스의 이름은 원하는 대로 바꿔도 된다. e.g. ros_ws, robot_ws, hello ... 대신 src 폴더의 이름은 src 이어야만 한다. 이는 빌드할 때, 해당 워크 스페이스에서 src 폴더를 찾아 빌드를 하기 때문이다. (아마도?)
$ mkdir -p ~/catkin_ws/src && cd ~/catkin_ws/src
$ git clone https://github.com/ros/ros_tutorials.git
2. 빌드
워크 스페이스의 src 폴더 안에 다운로드 받은 ros_tutorials는 여러 가지 노드가 있는 하나의 큰 패키지이다. ros_tutorials 안에서 roscpp_tutorials로 들어가보면 listener와 talker 폴더를 찾을 수 있을 것이다. listener와 talker 각각의 폴더 안에는 빌드를 위한 CMakeLists.txt 파일과 소스 파일(listener.cpp 또는 talker.cpp)가 있을 것이다.
$ ls ~/catkin_ws/src/ros_tutorials/roscpp_tutorials/listener
$ ls ~/catkin_ws/src/ros_tutorials/roscpp_tutorials/talker
위 튜토리얼에서 토픽을 publish하는 노드는 talker이며, subscribe하는 노드는 listener이다. 여기서, 노드는 특정한 역할을 하는 프로그램이라고 생각하면 된다. 즉, talker는 토픽을 publish하는 프로그램, listener는 토픽을 subscribe하는 프로그램이다. 더 나아가 우리는 직접 노드를 만들어서 우리가 원하는 과정을 수행할 수도 있고, 다른 프로그램에서 publish된 토픽을 subscribe하고, 계산하여 얻은 결과를 topic으로 publish할 수도 있다.
아무튼, 잘 다운로드했다면 다시 워크 스페이스로 돌아가서 빌드(catkin_make)를 해주도록 하자.
$ cd ~/catkin_ws
$ catkin_make
빌드가 잘 되었다면, 워크 스페이스에 build 폴더와 devel 폴더가 생긴 것을 확인할 수 있을 것이다.
3. 실행
실행은 간단하다. 우선, roscore로 master 노드를 실행하고, listener와 talker 노드를 실행하면 된다.
하나의 터미널에서 하나의 노드를 실행하면 된다.
$ roscore
$ rosrun roscpp_tutorials listener
$ rosrun roscpp_tutorials talker
만약 아래와 같은 에러 메세지와 함께 실행이 되지 않는다면, 해결 방법 커맨드를 실행한 후 다시 시도해보길 바란다.
에러 메세지
$ [rosrun] Couldn't find executable named talker below /opt/ros/melodic/share/roscpp_tutorials
또는
$ [rosrun] Couldn't find executable named listener below /opt/ros/melodic/share/roscpp_tutorials
해결 방법 커맨드는 다음과 같으며, 워크 스페이스의 devel 폴더에 setup.bash(또는 setup.zsh) 파일을 통해 터미널에서 빌드한 패키지들을 적용한다고 생각하면 된다.
해결 방법
$ source ~/catkin_ws/devel/setup.bash
만약, zsh을 사용한다면
$ source ~/catkin_ws/devel/setup.zsh
4. 결과
rosrun을 통해 각각의 노드를 실행하면 다음과 같은 결과를 확인할 수 있다. 우선, talker 노드에서는 "hello world #"의 string을 가진 chatter라는 이름의 토픽을 publish하며, 동시에 해당 string을 출력하는 것을 터미널에서 볼 수 있고, listener 노드에서는 chatter라는 이름의 토픽을 subscribe하며, 동시에 토픽이 가진 문자열 "hello world #"에 "I heard: [" 와 "]"를 앞뒤로 이어붙인 string을 만들어서 출력하는 것을 볼 수 있다.
여기서 chatter라는 토픽을 직접 확인하고 싶다면, 아래와 같은 커맨드를 통해 chatter 토픽을 확인할 수 있다.
$ rostopic echo /chatter
해당 커맨드에 대한 결과는 다음과 같이 나온다.
5. 정리
정리하면, talker라는 노드에서는 chatter라는 이름의 토픽을 송신(publish)하고, listener라는 노드에서는 chatter라는 토픽을 수신(subscribe)하여 이를 가공하여 출력했다고 보면 된다. 이러한 ROS의 통신 방법을 이해하고 활용할 수 있으면, 우리는 간단한 정수나 문자열을 송수신하는 것을 넘어서 Pose, Point Cloud, Laser Scan 과 같은 다양한 형태의 데이터를 주고 받으며 풀고자 하는 문제의 해답을 얻거나 가공된 데이터를 얻을 수 있다.