본문으로 건너뛰기

패키지, 노드 생성 및 실행

Package 생성

ROS는 파이썬과 C++을 공식적으로 지원하고 있습니다. 각각의 언어는 아래와 같은 특징을 가지고 있습니다.

  • 파이썬

    커뮤니티의 다양한 모듈(확장)을 지원해 기능 구현의 난이도가 C++에 비해 상대적으로 낮습니다. 이러한 장점으로 빠른 개발이 가능해 교육 및 프로토타이핑 목적으로 자주 사용합니다.

  • C++

    대부분의 기능을 사용자가 직접 구현해야 하는 경우가 많아 코드 작성 난이도가 Python 대비 높은 편입니다. 반면, 빠르고 효율적인 동작이 가능해 센서 드라이버와같이 빠른 동작이 필요한 부위에서 자주 사용합니다.

이어지는 가이드에서는 파이썬을 주로 사용할 예정입니다. 따라서 C++ 기반의 패키지는 생성 과정만 간단하게 알아보고 넘어가겠습니다.

ROS의 모든 개발은 워크스페이스의 src 폴더에서 진행합니다. 앞선 과정을 통해 ROS를 설치하였다면 워크스페이스가 설정되어 있을 것입니다. 터미널에 cd 명령어를 입력하여 패키지를 생성할 경로로 이동합니다. cd 명령어는 change directory의 줄임말로 현재 위치를 다른 폴더로 이동할 때 사용하는 명령어입니다. 커서 좌측을 보면 경로가 변경된 것을 확인할 수 있습니다.

터미널 실행 시 커서 좌측의 문구는 순서대로 사용자 이름, PC 이름, 현재 경로를 의미합니다. 사용자 이름과 PC 이름은 OS 설치 시 입력한 내용에 맞게 변경될 수 있으나, 경로는 기재되어 있는 것과 동일해야 합니다.

이번 가이드에서는 터미널에 입력하는 모든 명령에 대해 경로를 표시해 두었으니 참고해 주세요.

# [사용자 이름]@[PC 이름]:[현재 경로]$
ubuntu@ubuntu-pc:~$

ls 명령어는 List의 줄임말로 현재 위치나 특정 경로의 파일 목록을 조회할 때 사용합니다. ls 명령어 뒤에 추가적인 내용을 입력하지 않으면 현재 경로의 파일 목록을 조회하는데요. 아직 src 폴더에서 작업을 진행하지 않았기 때문에 텅 비어 있는 것을 확인할 수 있습니다.

ubuntu@ubuntu-pc:~$ cd ros2_ws/src
ubuntu@ubuntu-pc:~/ros2_ws/src$ ls

ls 실행 예시

ROS 2 Package 생성 명령어
ros2 pkg create <pkg-name> --build-type <build-type>
  • pkg-name : 생성할 패키지 이름
  • build-type : 빌드 타입 (ament_cmake 또는 ament_python)

패키지를 생성할 때는 ros2 pkg create 명령어 뒤에 빌드 타입패키지 이름을 입력해야 합니다. 빌드 타입에는 파이썬을 사용하는 ament_python과 C++을 사용하는 ament_cmake가 있습니다.

명령어가 너무 길어서 타이핑이 힘들 때는 tab 키를 눌러 자동완성이 가능합니다. 자동완성이 가능한 경우가 2가지 이상일 경우 tab 키를 두 번 눌러 자동완성이 가능한 목록을 확인할 수 있습니다. 예를 들어, ros2 pkg create --build-type a까지 입력한 후 tab 키를 누르면 ament_까지 자동완성이 됩니다. 이후 tab 키를 두 번 누르면 amet_python과 ament_cmake로 두 가지 옵션이 뜨는 것을 확인할 수 있습니다. p를 누르고 다시 tab키를 눌러주면 ament_python까지 빠르게 입력이 가능합니다.

Package 생성하기

정보

Package 생성 실습은 ROS 2 Jazzy 공식 Docs의 자료를 사용합니다. 보다 자세한 내용은 아래 링크를 참고해 주세요.

ubuntu@ubuntu-pc:~/ros2_ws/src$ ros2 pkg create --build-type ament_python py_pubsub

Python Package 생성 예시

위 코드를 커맨드 창에 입력하면 패키지를 생성할 수 있습니다. 패키지 구조를 확인하기 위해 tree 명령어를 사용해 보겠습니다. 우선 tree 명령어를 사용하기 위해 설치를 진행하겠습니다.

ubuntu@ubuntu-pc:~/ros2_ws/src$ sudo apt install tree -y
ubuntu@ubuntu-pc:~/ros2_ws/src$ tree ~/ros2_ws/src/py_pubsub

tree 설치 예시

tree 실행 예시

tree 명령어 뒤에 폴더 경로를 입력하면 입력한 경로의 구조를 확인할 수 있습니다.

ROS 2 Package 기본 구조 (Python)
<pkg-name>/
<pkg-name>/
__init__.py
package.xml
resource/
<pkg-name>
setup.cfg
setup.py
test/
  • setup.py : 패키지 내에서 코드를 빌드하는 방법을 설명하는 파일
  • package.xml : 패키지에 대한 메타 정보를 포함하는 파일

파일이 많고 복잡해 보이지만 실제로 사용하게 되는 파일은 많지 않습니다. 조금 더 자세한 내용은 노드 작성 실습과 함께 살펴보겠습니다.

Node 생성

노드는 로봇의 실질적인 동작을 담당합니다. 즉, 단순한 명령어를 통해 생성할 수 있었던 패키지와는 달리 노드를 생성하기 위해선 원하는 기능에 맞게 코드를 작성해야 합니다.

Python Topic Publisher 노드 생성하기

우선 코드를 작성하기 위해 VSCode를 실행합니다.

VSCode 실행 예시

py_pubsub 패키지의 노드를 작성하기 위해 py_pubsub 패키지를 열어줍니다. VSCode 좌측 상단의 [File] >> [Open Folder…] 버튼을 누른 후 패키지 경로(/home/ubuntu/ros2_ws/src/py_pubsub)를 지정해 Open 버튼을 누릅니다.

VSCode 패키지 불러오기 예시1

VSCode 패키지 불러오기 예시2

VSCode 패키지 불러오기 예시3

VSCode 패키지 불러오기 예시4

이런 방법이 불편하다면 폴더를 끌어당기는 방식으로 패키지를 불러올 수도 있습니다. 본인에게 더 편한 방법으로 진행해 주시면 됩니다.

VSCode 패키지 불러오기 예시5

패키지를 불러왔다면 좌측 창에 py_pubsub 패키지가 표시됩니다. 우선 간단하게 패키지 안에 생성된 파일들을 살펴보겠습니다. 패키지를 생성하게 되면 패키지 이름과 동일한 상위 폴더가 생성되고 내부에 여러 폴더와 파일들이 생성됩니다.

VSCode 좌측 창 예시

상위 폴더를 열면 패키지와 동일한 이름의 폴더가 하나 더 생성된 것을 확인할 수 있습니다. 이 폴더 안에는 __init__.py 라는 이름의 파일이 들어있는데요. 열어보면 비어 있는 것을 확인할 수 있지만, 삭제하게 되면 추후 빌드 과정에서 문제가 발생하게 되어 삭제되지 않도록 주의해야 합니다.

__init__.py 파일 예시

resourcetest 폴더는 코드를 작성할 때는 사용되지 않기 때문에 신경 쓰지 않아도 괜찮습니다.

package.xml은 패키지에 대한 메타 정보를 포함하는 파일입니다. 열어보면 패키지의 버전, 작성자, 라이선스 등 각종 정보가 포함되어 있습니다. setup.cfg 파일도 코드를 작성할 때는 사용되지 않기 때문에 신경 쓰지 않아도 괜찮습니다.

package.xml 파일 예시

setup.py는 빌드와 관련된 정보를 포함하는 파일입니다. package.xml과 유사한 내용이 포함되어 있지만, setup.py 파일에는 이후에 작성할 노드에 관한 빌드 방법을 추가로 입력하게 됩니다.

setup.py 파일 예시

노드는 패키지 이름과 동일한 폴더에 작성되어야 합니다. py_pubsub 폴더에 publisher_member_function.py 라는 이름의 새 파일을 만들어줍니다. 폴더를 우클릭하고 [새 파일…] 버튼을 누르거나 폴더를 클릭한 상태로 파일 생성 버튼(📄)을 클릭하면 새로운 파일을 생성할 수 있습니다.

파일 생성 예시

파일 생성 예시2

이후 publisher_member_function.py 파일을 더블클릭해 열어준 뒤 아래 코드를 붙여 넣고 저장합니다.

publisher_member_function.py
import rclpy
from rclpy.node import Node

from std_msgs.msg import String

class MinimalPublisher(Node):

def __init__(self):
super().__init__('minimal_publisher')
self.publisher_ = self.create_publisher(String, 'topic', 10)
timer_period = 0.5 # seconds
self.timer = self.create_timer(timer_period, self.timer_callback)
self.i = 0

def timer_callback(self):
msg = String()
msg.data = 'Hello World: %d' % self.i
self.publisher_.publish(msg)
self.get_logger().info('Publishing: "%s"' % msg.data)
self.i += 1

def main(args=None):
rclpy.init(args=args)

minimal_publisher = MinimalPublisher()

rclpy.spin(minimal_publisher)

# Destroy the node explicitly
# (optional - otherwise it will be done automatically
# when the garbage collector destroys the node object)
minimal_publisher.destroy_node()
rclpy.shutdown()

if __name__ == '__main__':
main()

publisher_member_function.py 파일 예시

아래 사진과 같이 파일명 우측에 점이 있다면 파일에 변경 사항이 반영되지 않은 것입니다. Ctrl + S 또는 [File] >> [Save] 버튼을 눌러 파일을 꼭 저장해주세요.

파일 저장 주의사항

이전에 Black Formatter 설정을 완료하였다면 코드를 저장할 때마다 코드가 정렬됩니다. 코드 정렬 과정에서 코드가 움직이는 듯한 느낌이 들거나 커서의 위치가 변경될 수 있습니다.

Package 빌드 준비

위에서 생성한 노드를 실행하기 위해서는 빌드 과정을 거쳐야 합니다. 빌드 과정은 워크스페이스 내의 src 디렉터리의 여러 패키지를 빌드해 워크스페이스 아래의 install 디렉터리에 설치합니다.

빌드를 진행하기 전, 빌드를 위한 정보를 입력해 줘야 합니다. 먼저 package.xml 파일을 수정해 보겠습니다.

package.xml
<exec_depend>rclpy</exec_depend>
<exec_depend>std_msgs</exec_depend>

package.xml 파일 수정 예시

위 사진과 같이 TODO로 표시된 부분을 적절하게 수정합니다. 각각 패키지의 간단한 설명, 개발자 정보, 오픈소스 라이선스를 의미합니다. 라이선스 태그 뒤에 위의 두 태그를 추가합니다. exec_depend 태그는 빌드를 위해 필요한 패키지(의존성)를 알려주기 위해 사용합니다.

rclpy는 파이썬에서 ROS를 사용하기 위한 라이브러리, std_msgs는 Topic 모델을 통해 전송할 예시 메시지의 타입 묶음인 std_msgs를 정의하는 라이브러리입니다.

다음으로 setup.py 파일을 수정하겠습니다.

setup.py
'talker = py_pubsub.publisher_member_function:main',

setup.py 파일 수정 예시

마찬가지로 TODO로 표시된 정보를 입력해 줍니다. 앞선 XML 파일과 동일하게 입력해 주시면 됩니다. entry_points 딕셔너리의 console_scripts 배열에 위 문자열을 추가합니다. console_scripts는 ros2 run 명령을 통해 노드를 실행할 때 패키지의 이름과 실제 파일을 연결하는 역할을 합니다.

위와 같이 entry_points를 설정하면 talker라는 이름으로 publisher_member_function 파일의 main 함수를 실행할 수 있습니다.

Package 빌드

이제 터미널에서 패키지를 빌드해 보겠습니다. 빌드를 하기 위해서는 워크스페이스로 이동하고 빌드를 위한 명령과 옵션을 입력해야 합니다. 이런 과정을 쉽게 하기 위해 ROS 2 설치 과정에서 cb 라는 명령어를 만들었습니다. 이전의 Ubuntu 24.04 설치 페이지의 ROS 2 설치를 그대로 따라 했다면 앞으로 cb 명령어로 빌드를 진행하면 됩니다.

cb 명령어는 다음 명령을 수행합니다. cb 명령어가 등록되지 않은 경우 아래 명령어를 입력하여 동일한 동작을 수행할 수 있습니다.

cd ~/ros2_ws && colcon build --symlink-install && source ~/ros2_ws/install/local_setup.bash

빌드 명령어는 터미널 창에 입력해 주면 되기 때문에 기존과 동일하게 터미널 창을 열어 빌드를 진행해도 되고 VSCode 상에서 터미널 창을 열어 진행해도 됩니다. 이번엔 VSCode 상에서 빌드를 진행해 보겠습니다.

우선 VSCode에서 터미널 창을 띄우기 위해선 Ctrl + `(물결 표시 아래 따옴표)를 누르거나 VSCode 상단의 [Termical] >> [New Terminal] 버튼을 누르면 됩니다.

Ctrl + Alt + T 또는, 아이콘을 눌러 터미널을 실행하게 되면 기본적으로 홈 폴더에 위치하게 되는데요. vscode에서 터미널을 실행하게 되면 현재 열려있는 폴더 경로에 위치하게 됩니다. 이 부분을 제외하면 결국 동일한 터미널이니 편한 방법으로 사용해주시면 됩니다.

터미널 창 열기 예시

위의 사진처럼 코드 아래쪽에 터미널 창이 뜨면 cb를 입력하여 빌드를 진행합니다.

cb 명령어 실행 예시

빌드가 정상적으로 완료되었다면 콘솔 창에 아래 명령어를 입력하여 방금 작성한 노드를 실행할 수 있습니다.

ubuntu@ubuntu-pc:~/ros2_ws$ ros2 run py_pubsub talker

노드 실행 예시

데이터를 전송하고 있음을 터미널의 로그로 확인할 수 있습니다.