본 블로그 포스팅은 https://www.youtube.com/@pinklab_studio/playlists
에서 현재 강의 중에 있는
ROS2 무작정 따라하기강의의 내용을 필자가 다시 복기하여 기록하는 내용에 관한 것이다.
사전에 알아야 할 지식으로 ROS2, ROS는 모두 배포판(Distributions)의 이름으로 버전을 관리하며, 이 버전은 모드 Ubuntu의 버전에 종속되어 관리되는 부분이 있다.
예를들어 Ubunut 18.04버전에 ROS를 설치한다면 ROS Melodic 버전이 설치가 가능하고 20.04 버전에는 ROS Noetic이 설치가 가능한 버전으로 하나의 우분투 버전에 하나의 ROS버전이 설치가 가능하다.
따라서 https://docs.ros.org/en/humble/Releases.html 에 접속하면 ROS2 버전에 따른 출시일이나 해당 ROS2 버전에 대한 document에 접속 가능하게 링크가 걸려있는데, 필자의 WSL-Ubuntu버전은 22.04이기에 Humble버전을 설치한다.
설치 과정은 https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html 의 Humble - Installation - Ubunut 과정을 참조하여 수행한다.
처음 할일은 Ubunut의 국가 및 언어 지원을 확인하는 locale
에 UTF-8
목록이 있는지 확인하는 것이다.
이렇게
locale
명령어를 쳐서 위 사진에는 UTF-8
항목이 모두 존재하지만, 만약 UTF-8
항목이 아닌 다른 항목으로 되어 있다면 아래의 명령어로 UTF-8
을 설치한다.
sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8
LANG=en_US.UTF-8
export LANG=en_US.UTF-8
이때 다른 블로그의 글을 검색해 보니 위 사진과 다르게 en_US.UTF-8
이 아닌 다른 국가의 언어 (ex : ko_KR.UTF-8
을 써도 상관은 없다.
한국어로 터미널 보면서 ROS2설치하고 싶을 때(선택)
sudo apt update && sudo apt install locales
sudo locale-gen ko_KR ko_KR.UTF-8
sudo update-locale LC_ALL=ko_KR.UTF-8
LANG=ko_KR.UTF-8
위 로케일 작업을 완료한 후에는 ROS2 패키지를 다운받기 위한 원격 저장소에 접속하기 위한 설정을 해줘야 한다.
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
위 3개의 명령어를 차례대로 복사해서 터미널에 붙여넣으면 되는데 ROS2는 apt를 통해 패키지를 다운받고 설치하고, 이 apt에 ROS2를 다운받는 위치를 등록해준다... 뭐 이렇게 이해하고 넘어가면 된다..
본격적으로 패키지 다운받고 설치 전 아래의 명령어를 먼저 수행해주자
sudo apt update && sudo apt upgrade
그 후에 패키지 다운&설치 명령어를 실행한다
sudo apt install ros-humble-desktop
그럼 위 사진처럼 패키지를 쭉 받기 시작하는데 대략 2GB정도 되는 걸로 기억한다.
위 ROS2 Humble 설치를 완료한 후에는 Environment setup 챕터에서 아래와 같은 작업을 수행하는 것을 권장하고 있다.
# Replace ".bash" with your shell if you're not using bash
# Possible values are: setup.bash, setup.sh, setup.zsh
source /opt/ros/humble/setup.bash
이 구문을 .bashrc에 사전 등록하면 ROS2를 쓸 때 좀 더 편리한데 이 부분에 대한 설명을 이어나가고자 한다.
우선 ROS2가 설치된 경로
/opt/ros/humble
의 디렉토리 내 파일목록을 확인해 보면setup.bash 라는 파일이 있다.
이 setup.bash 파일을 경로명까지 포함하여 아래의 명령
source /opt/ros/humble/setup.bash
을 리눅스 터미널에 입력을 해줘야만 ROS2 Humble이 제공하는 다양한 패키지, 노드 등을 구동할 수 있다.
위 사진처럼 ROS2 Humble의 기본 예제 노드인
ros2 run demo_nodes_cpp talker
와 ros2 run demo_nodes_py listener
, 그리고 rqt_graph
를 실행하는데 앞서 source /opt/ros/humble/setup.bash
이 명령어를 새로 열린 터미널 창 마다 무조건 쳐 줘야 함을 노란색 박스를 통해 알 수 있다.
즉, ROS2를 실행하려면 사전에 ROS2를 실행하는데 필요한 각종 환경변수, 함수 별명 등이 기록되어 있는 셸 스크립트 파일인 setup.bash 파일을 실행해야 하며, 이를 위해 source [파일 경로]
명령어를 먼저 실행해야 하는 것이다.
그럼 이걸 좀 '자동화' 할 방안이 없을까?
이것은 리눅스 터미널(Shell)이 실행될 때 자동으로 실행하라는 명령어의 모음이 담긴 파일 .bashrc
파일을 편집하면 된다.
우선 위 사진처럼 echo #SHELL
명령어를 수행하면 현재 열려있는 터미널(shell)의 세션이 어느 위치에 있는지 그 경로를 알려주고, 이 세션에 위치한 /bash의 조정을 수행할 수 있는 파일이 .bashrc
라 보면 된다.
이를 vscode로 code .
라는 명령어로 최 상위 디렉토리에서 수행하면 .bashrc
의 열람 및 편집이 가능한데
여기에 위 사진처럼
echo "ROS2 humble is activated!
source /opt/ros/humble/setup.bash
라는 명령어를 기재하면 터미널(Shell)창을 새로 열 시 echo
멸령어에 의거하여 ROS2 humble is activated! 라는 명령어가 자동 실행되고 그 아래 setup.bash파일을 실행하여 ROS2의 패키지 및 노드 구동이 가능해진다.
여기에 응용으로 alias
명령어를 통해 위에 기재한 두줄 짜리 긴 명령어를 humble라는 간단한 명령어로 축약하여 사용할 수 있다.
alias humble="source /opt/ros/humble/setup.bash; echo \"ROS2 humble is activated!\""
여기서 하나 더 설정해줘야 할 것이 있다.
위 사진처럼 실행하는 ROS2의 Domain ID를 부여하는 것이다.
이것을 설정하는 이유는 여러 대의 PC가 하나의 네트워크(공유기)로 물려 있을 시 여러 PC에서 동시에 ROS를 구동하게 되면
다른 PC에서 발행되는 메세지가 내 PC로 튀어오거나 들어올 수 있다.
이걸 채널을 분리해서 사용하자는 뜻인데
ROS에서는 이것이 Roscore
로 그 기능을 수행했다면
ROS2에서는 Domain ID
로 그 기능을 수행한다... 이렇게 이해하면 될 것 같다.
사용자 Domain ID를 부여하는 명령어는 아래와 같다.
export ROS_DOMAIN_ID=[사용하고자 하는 도메인 ID]
사진에서 만든 코드는 alias 명령어를 조합한 코드로써
도메인 ID설정 + 설정한 ID명 출력 -> alias명령어로 묶음
ROS 쉘 스크립트 실행 + 위 첫번째 alis 명령어 실행 + 명령어 수행을 알리는 출력구문 출력
이렇게 5가지의 사전작업을 humble라는 간단한 명령어로 묶음 처리했다 보면 된다.
우선 첫번째로 아래 사진처럼 turtlesim패키지가 설치되어 있는지 확인해보자
apt --installed list ros-humble-t*
-> ros-humble-t로 시작하는 설치된 패키지가 있는지 그 리스트를 출력하라는 명령어
그러면 노란색 박스로 친 ros-humble-turtlesim패키지가 설치되어 있음을 확인할 수 있다.
-> 이거는 ROS humble을 설치하면 자동으로 설치되는 기본 패키지이니 만약 설치가 안됬다면 ROS 설치가 오류가 났을 수 도 있다...
아무튼 위 사진처럼 아래의 명령어를 수행하면 기본 예제 노드인 turtlesim 노드가 실행된다.
humble
-> ./bashrc에 챕터2에서 등록한 ROS 실행에 관한 요약 명령어 실행
ros2 run turtlesim turtlesim_node
-> turtlesim패키지에 포함된 여러 노드 리스트 중 turtlesim_node 노드를 실행시키라는 명령어
이렇게 turtlesim 노드를 실행 시킨 뒤 아래 명령어를 수행하면 현재 ROS2 에서 실행중인 node리스트가 출력된다
ros2 node list
-> 현재 실행중인 node 리스트 출력
여기에 위 사진처럼
ros2 node info [실행중인 노드]
를 추가로 명령어를 실행하면 현재 실행중인 노드인 /turtlesim
의 정보에 대해 알 수 있다.
우선 위 사진처럼 turtlesim_node를 실행하고
turtlesim_node노드에 적용 가능한 service 항목들을 출력해보자
ros2 service list
이 명령어를 수행하면 turtlesim_node노드가 받아 들일 수 있는 서비스의 리스트가 주욱 출력되는데
크게 3가지로 나누어 볼 수 있다
1) 어느 ROS노드건 왠만해서는 꼭 들어가는 공통 서비스 리스트 : /clear
, /kill
, /reset
, /spawn
2) turtlesim_node의 전역설정에 해당하는 서비스 리스트
3) turtlesim_node 내 제어 가능한 robot(turtle1)에 대한 제어 서비스 리스트
이렇게 3가지 서비스 리스트가 존재한다.
이 중 위 사진처럼 turtle1 로봇을 제어하는데 사용되는 서비스인
/turtle1/teleport_absoulte
라는 서비스는 어떠한 메세지를 받았을 때 해당 서비스가 동작하는지 확인해보자
ros2 serivce type /turtle1/teleport_absoulte
-> 서비스 : /turtle1/teleport_absoulte가 받아들일 수 있는 메세지 타입이 무엇인지 출력하라는 명령
-> 이 명령어를 수행하면turtlesim/srv/TeleportAbsolute
라는 메세지 타입을 받을 수 있다라는 결과가 반환됨
/turtle1/teleport_absoulte
라는 서비스를 활성화 시켜 어떠한 제어 결과값을 확인하려면 turtlesim/srv/TeleportAbsolute
라는 메세지가 필요함을 확인했다.
그럼 이 메세지 : turtlesim/srv/TeleportAbsolute
는 어떤 매개변수가 필요하고, 어떤 매개변수를 출력하는지 확인하는 명령어를 작성해보자
ros2 interface show turtlesim/srv/TeleportAbsolute
-> turtlesim/srv/TeleportAbsolute라는 메세지 타입의 인터페이스 구성을 보여줘라
이 명령어를 치면 Request(요청)에 해당하는 매개변수 타입 그리고 이 메세지가 실행되고 나면 Response(응답)에 해당하는 매개변수 리스트가 출력된다.
따라서 위 두 명령어를 통해 알 수 있는 내용은 아래와 같다.
turtle1의 절대 위치를 변경하는 서비스(/turtle1/teleport_absoulte)를 실행하기 위한 메세지 turtlesim/srv/TeleportAbsolute은 필요로 하는 매개변수로 float32 x, float32 y, float32 theta
3가지가 필요하고, 이 매개변수에 값을 넣어서 메세지를 날리면 해당 서비스가 실행되면서 공란
매개변수로 이뤄진 메세지를 반환한다
라고 이해할 수 있다.
이제 아래의 명령어를 입력해보자
ros2 service call /turtle1/teleport_absolute turtlesim/srv/TeleportAbsolute "{x: 2, y: 2, theta: 1.57}"
그러면 위 사진처럼 turtle1에 해당하는 거북이 로봇의 위치 및 방향이 전환된 것을 확인할 수 있다.
그럼 위 명령어를 찬찬히 살펴보자
ros2 service call [서비스명] [서비스가 받는 메세지명] ["{요청 매개변수들}"]
이렇게 구성되어 있음을 알 수 있다.
이것이 서비스를 실행시키라는 명령어 조합이며
/turtle1/teleport_absolute 라는 서비스를 실행시키는데(service call
)
이 서비스는 turtlesim/srv/TeleportAbsolute이 이름으로 된 메세지만 받아 볼 수 있고
이 메세지는 필요로 하는 매개변수가 x, y, theta이니 각각 매개변수에 맞춰서 "{x: 2, y: 2, theta: 1.57}"라고 입력해준 것이다.
그리고 서비스를 해당 서비스가 활성화 되는 메세지를 메세지가 필요로 하는 메세지 규격에 맞춰서 잘 전달하니까
그에 대한 응답으로
turtlesim.srv.TeleportAbsolute_Response()라고 답변이 온 것이다
()
에는 아까 response매개변수가 아무것도 없었기에 공란이 온거라 볼 수 있다
위 과정에 대한 응용으로 /spawn
서비스에 대해서도 탐구를 진행해보자
ros2 serivce type /spawn
ros2 interface shwo turtlesim/srv/Sqawn
ros service call /spawn turtlesim/srv/Spawn "{x: 1, y: 1, theta: 0, name: ''}"
위 명령어로 서비스 spawn이 어떤 메세지 타입을 원하는지, 해당 메세지 타입의 필요 매개변수는 무엇인지 를 알 수있고
이 메세지 필요 매개변수에 의거하여 서비스 실행 명령어를 작성한 후 그에 따라 turtle2라는 새로운 로봇이 스폰 되었음을 확인 할 수 있다.