[ROS] ROS Concepts - ROS 구성 요소와 패키지 실습

김희정·2023년 2월 2일
3

ROS

목록 보기
2/4
post-thumbnail

💎 들어가며

앞선 포스팅에서 ROS의 환경을 구축했으니, 이제 주요 개념에 대해 알아봅시다.

ROS 구조 간략 정리

  • ROS는 패키지(모듈)의 집단으로 구성.
  • 각 패키지는 하나 이상의 노드를 가짐.
  • 노드는 실제 작업의 단위 (프로세스)
  • 노드를 구성하는 것이 프로그램

이러한 노드는 Topic, Service, Action 등 여러가지 방법으로 통신될 수 있습니다.



1. ROS 주요 용어

ROS의 주요 용어는 Node, Package, Message로 구성되어 있으며, 각 노드끼리의 여러가지 통신 방법이 있습니다.


🐬 Node

  • Node란 ROS의 최소 단위의 실행 가능한 프로세스
  • ROS에서는 최소한의 실행 단위로 프로그램을 나누어 작업
  • 각 노드는 메시지 통신으로 데이터를 주고 받는다.

📑 Package

  • 하나 이상의 노드와 노드 실행을 위한 정보 등을 묶어둔 것

💬 Message

  • 노드 간의 주고 받는 데이터를 지칭
  • 메시지는 변수 형태(integer, floating point, boolean, 등)이다.

💌 Interaction between Nodes

노드 간의 메세지를 주고 받는 방법에는 토픽, 서비스, 액션, 파라미터가 있다.



2. Node 간 통신 방법

2.1 Topic (Publisher / Subscriber)

Ros Topic 통신 구조

토픽(topic) : 비동기식 단방향 메시지 송수신 방식

  • 메시지를 발간하는 송신자(Publisher)수신자(Subscriber) 간의 통신.
  • 메세지 형태: msg 메시지
  • 이는 1:N, N:1, N:N 통신도 가능하며, ROS 메시지 통신에서 가장 널리 사용된다.
  • 토픽 방식에서는 접속을 끊지 않는 이상 지속적으로 메시지를 전송한다. (연속성)

2.2 Service (Server / Client)

Ros Service 통신 구조

서비스(Service) : 동기식 양방향 메시지 송수신 방식

  • 서비스의 요청(request)하는 Client 와 요청에 응답(response)하는 Server 간의 통신
  • 서비스는 토픽과 달리 1회에 한해 접속하고 서비스 요청 및 서비스 응답을 수행한 후 서로의 접속(Connection)을 끊습니다. (1회성)

3. Action (Server / Client)

액션(Action) : 비동기식+동기식 양방향 메시지 송수신 방식

  • 액션 목표 Goal을 지정하는 client와 액션 목표를 받아
  • 특정 태스크를 수행하면서 발생하는 값들을 Server에서 전송
    중간 결과 값 피드백(Feedback) 전송
    최종 결과 값 결과(Result) 전송


3. ROS Package

ROS의 시작과 끝은 패키지(Package)로 이루어져 있습니다.

이번 단락에서는 아래 내용들을 실습해보겠습니다.

  • Package 생성
  • python으로 프로그램 작성, 빌드, 실행
  • Package 삭제

3.1 패키지 생성

패키지 생성 명령어

catkin_create_pkg

catkin_create_pkg 명령어로 패키지를 생성합니다.

$ catkin_create_pkg 패키지명 [dependencies]

저는 package_tutorials이라는 package를 만들고, python3 개발 테스트를 위해 rospy 의존성을 추가해 주었습니다.

$ cd ~/catkin_ws/src
$ catkin_create_pkg package_tutorials rospy

python3 설치

ROS Melodic은 기본적으로 파이썬 2 버전을 이용하기 때문에 아래와 같이 python 3 버전을 설치해줍니다.

$ sudo apt install python3-pip python3-all-dev python3-rospkg
$ sudo apt install ros-melodic-desktop-full --fix-missing

패키지 생성 예시

catkin_create_pkg package_tutorials rospy roscpp 
message_generation message_runtime std_srvs std_msgs

3.2 패키지 구성요소

패키지를 생성하면 아래와 같은 파일 및 폴더들이 생성됩니다.

$ pwd
/root/catkin_ws/src/package_tutorials
(= ~/catkin_ws/src/package_tutorials)

$ ll (또는 ls -l)
total 28
drwxr-xr-x 4 root root 4096 Feb  2 10:38 ./
drwxr-xr-x 3 root root 4096 Feb  2 10:30 ../
-rw-r--r-- 1 root root 7077 Feb  2 10:30 CMakeLists.txt
-rw-r--r-- 1 root root 2875 Feb  2 10:30 package.xml
drwxr-xr-x 2 root root 4096 Feb  2 10:30 src/

패키지에는 에는 아래와 같은 3가지 구성요소가 있는데요. 각 설명은 아래와 같습니다.

  • CMakeLists.txt: 패키지 빌드를 위한 빌드 기술 파일
  • package.xml: 패키지의 설명, 라이선스, 종속성, 등 패키지의 정보를 기술한 메타파일
  • src 폴더: 소스폴더 위치

1) Package.xml

제일 먼저 package.xml을 살펴보겠습니다.

<?xml version="1.0"?>
<package format="2">
  <!-- 패키지명 -->
  <name>package_tutorials</name>
  <!-- 패키지 버전 -->
  <version>0.0.0</version>
  <!-- 패키지설명 -->
  <description>Simple Example Package</description>

  <!-- 유지보수자 -->
  <maintainer email="root@todo.todo">root</maintainer>
  
  <!-- 라이선스를 입력하세요 -->
  <!-- Commonly used license strings: 
	BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3
  -->
  <license>TODO</license>

  <buildtool_depend>catkin</buildtool_depend>
  
<!--
  rospy의 의존성입니다.
  catkin_create_pkg를 이용하여 package를 생성했을 때, 기술한 의존성들이 나열됩니다.
  의존성 별로, build_depend, build_export_depend, exec_depend 태그가 있습니다.
-->
  <build_depend>rospy</build_depend>
  <build_export_depend>rospy</build_export_depend>
  <exec_depend>rospy</exec_depend>

  <export>
  </export>
</package>

2) CMakeLists.txt

그 다음에는 CMakeLists.txt 파일을 살펴보겠습니다.

cmake_minimum_required(VERSION 3.0.2) // CMake 버전
project(package_tutorials) // 패키지명

find_package(catkin REQUIRED COMPONENTS // 빌드를 위한 다른 CMake/Catkin 패키지
  rospy
)

catkin_package ( // 패키지 빌드 정보
#  INCLUDE_DIRS include
#  LIBRARIES package_tutorials
#  CATKIN_DEPENDS rospy
#  DEPENDS system_lib
)

include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

CMakeLists 정의

CMakeLists.txt 파일은 소프트웨어 패키지 빌드를 위한 CMake 빌드 시스템의 입력 파일이다. CMake와 호환되는 패키지는 하나 이상의 CMakeLists.txt 파일을 가지며, 이 파일을 통해 어떻게 패키지 내의 코드를 빌드하고 어디에 설치할 지를 기술하게 된다.

catkin 프로젝트를 위한 CMakeLists.txt 파일은 표준적인 CMakeLists.txt 파일 형식에 몇가지 추가적인 제약사항을 더한 것이다.

  • CMakeLists.txt의 순서
  1. 최소 CMake 버전 요구사항 (cmake_minimum_required)
  2. 패키지 이름 (project())
  3. 빌드를 위해 필요한 다른 CMake/Catkin 패키지 (find_package())
  4. 파이썬 모듈 지원 여부 (catkin_python_setup())
  5. 메시지/서비스/액션 생성자 (add_message_files(), add_service_files(), add_action_files())
  6. 메시지/서비스/액션 생성 실행 (generate_messages())
  7. 패키지 빌드 정보 (catkin_package())
  8. 빌드할 라이브러리와 실행파일 (add_library()/add_executable()/target_link_libraries())
  9. 테스트 (catkin_add_gtest())
  10. 설치 룰 (install())

[출저] ROS WIKI


3.3 Test Program (With Python)

ros package에서 python 프로그램(.py 파일)을 실행시켜보겠습니다.

실습 단계는 다음과 같습니다.

  1. 프로그램(.py) 작성 => CMakeLists에 추가, 실행 권한 추가
  2. catkin 빌드
  3. 프로그램 실행

1) Create Python program (.py)

파일 생성

우선, 패키지 밑에 src 폴더 밑에 test.py 파일을 생성합니다.

$ cd ~/catkin_ws/src/package_tutorials/src
$ vi test.py

테스트 프로그램 작성

📑 test.py 는 정말 간단하게 Hello, ROS Package를 찍어볼게요.

#!/usr/bin/env python

print("Hello, ROS Package")

#!/usr/bin/env python의 의미

필자는 #!/usr/bin/env python를 안쓰고 실행했다가 syntax error를 맞이하고, 검색한 끝에 해당 라인을 추가했습니다.

[Error] syntax error near unexpected token '('

해당 라인의 의미는 env 환경 변수에서 지정한 언어의 위치를 찾아 실행하라는 뜻이라네요:)


CMakeLists 에 작성한 프로그램 추가

CMakeLists.txt 파일에 작성한 파일의 위치를 추가해줘야합니다.

catkin_install_python(
  PROGRAMS src/test.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

파일 실행 권한 부여

💡 파일을 실행할 수 있도록 실행 권한도 추가합니다.

$ chmod +x package_tutorials/src/text.py

2) Catkin Build

자 이제 모든 준비가 끝났습니다.

작업을 완료했으면 Workspace 루트 폴더로 가서 빌드합니다.

$ cd ~/catkin_ws/
$ catkin_make

3) Execute Program

💡 rosrun 명령어를 이용하여 프로그램을 실행합니다.

$ rosrun package_tutorials test.py

3.3 패키지 삭제

패키지 삭제는 어렵지 않습니다. 해당 폴더를 삭제한 뒤 빌드하면 됩니다. 👏

# workspace로 이동
$ cd ~/catkin_ws/src
$ rm -rf 패키지명

# catkin 빌드
$ cd ../
$ catkin_make


💎 마치며

ROS의 이론을 공부하면서 가장 난해했던 부분이 PackageNode 였는데, Python으로 간단하게 Package를 만드는 실습을 진행하면서 어떻게 구성되어 있는지, 어떻게 실행되는지를 알 수 있게 되었습니다.

이번 포스팅에서는 Package의 뼈대(bone)을 파악해보았고, 각 노드끼리 통신하는 방법에 대해 정리해보았습니다.

이 포스팅을 통해 Package에 대해 이해할 수 있게 되었기를 바랍니다. 🤗

profile
Java, Spring 기반 풀스택 개발자의 개발 블로그입니다.

0개의 댓글