TIKI-MINI로 시작하는 ROS2 실무
목차

3. 개발 PC 환경

3.11TIKI-MINI 패키지 구성과 빌드

TIKI-MINI의 ROS2 소프트웨어는 패키지 6개로 나뉘어 있습니다. 이 장에서는 각 패키지가 무엇을 담당하는지 파일 단위로 읽고, OVA의 VM에 들어 있는 두 패키지를 직접 확인합니다. 패키지는 3.6장에서 배운 대로 ament_cmake 방식이고 모두 package.xml과 CMakeLists.txt를 가집니다.

6개 패키지 한눈에 보기

패키지한 줄 역할런치 파일실행 위치
tiki_descriptionURDF(xacro), RViz 설정tiki_description.launch.py로봇
tiki_base모터 보드와 시리얼로 통신하는 ros2_control 하드웨어 플러그인없음로봇
tiki_controldiff_controller 설정과 controller_manager 실행tiki_control.launch.py로봇
tiki_bringup로봇 기동용 최상위 런치tiki.launch.py, rplidar.launch.py로봇
tiki_slamslam_toolbox 실행과 설정slam.launch.pyVM (OVA에 있음)
tiki_navigationNav2 실행과 설정bringup.launch.pyVM (OVA에 있음)

아래 도구에서 패키지를 눌러 보세요. 선택한 패키지와 관련된 패키지가 강조됩니다. package.xml에 적힌 의존과 런치 파일이 실제로 가져다 쓰는 의존을 따로 표시했는데, 둘이 다른 곳이 있습니다.

패키지를 누르면 역할, 파일, 런치, 의존 관계가 아래에 나옵니다.

실행 진입점

제어

기반

tiki_control

controller_manager와 두 컨트롤러(joint_state_broadcaster, diff_controller)의 설정과 런치입니다. /cmd_vel을 바퀴 속도로, 바퀴 상태를 /odom으로 바꿉니다.

로봇에서 실행 (OVA의 VM에는 없음) · 노드는 뜨지만 모터 보드가 없어 바퀴 상태를 읽지 못합니다. 실기기 장(4.4)에서 다룹니다.

package.xml 의존

  • exec_depend: tiki_base, tiki_description, controller_manager, diff_drive_controller, joint_state_broadcaster, ros2controlcli

주요 파일

  • config/tiki_controllers.yaml 50 Hz, wheel_separation 0.1924, 속도 한계 0.2 m/s와 0.85 rad/s

런치 파일

  • tiki_control.launch.py ros2_control_node 실행, /cmd_vel과 /odom 리매핑, joint_state_broadcaster를 먼저 띄운 뒤 diff_controller 실행

robot_description을 /robot_state_publisher 노드에서 ros2 param get으로 가져오므로 description 쪽이 먼저 떠 있어야 합니다.

의존 관계를 글로 정리하면 이렇습니다.

  • tiki_control은 tiki_base와 tiki_description을 exec_depend로 선언합니다. 컨트롤러가 URDF의 ros2_control 블록을 읽고 그 블록이 가리키는 플러그인을 불러오기 때문입니다.
  • tiki_bringup은 package.xml에 의존이 하나도 없는데 tiki.launch.py가 tiki_description과 tiki_control의 런치를 포함하고, rplidar.launch.py는 rplidar_ros의 노드를 실행합니다.
  • tiki_slam과 tiki_navigation은 다른 tiki 패키지를 가져다 쓰지 않습니다. 각각 slam_toolbox, nav2_bringup의 런치와 파라미터만 감쌉니다.

tiki_bringup의 tiki.launch.py는 세 부분을 시간차를 두고 올립니다. description은 즉시, LiDAR(rplidar)는 3초 뒤, control은 7초 뒤입니다. tiki_control이 robot_state_publisher에서 robot_description을 가져와야 해서 순서를 시간으로 맞춘 것입니다.

OVA의 VM에서 확인하기

VM에서 Tilix를 열고 워크스페이스에 무엇이 있는지 확인합니다.

cd ~/ros2_ws
colcon list
ros2 pkg list | grep tiki
ros2 pkg prefix tiki_slam
ls install/tiki_slam/share/tiki_slam install/tiki_navigation/share/tiki_navigation
colcon list와 ros2 pkg list 결과, 설치 폴더 목록. 각 줄에 번호 표시
  • ① colcon list: 워크스페이스의 패키지 이름, 위치, 빌드 방식. 두 패키지 모두 ros.ament_cmake입니다.
  • ② ros2 pkg list | grep tiki: ROS2가 인식하는 TIKI 패키지 두 개
  • ③ ros2 pkg prefix tiki_slam: 설치된 곳은 ~/ros2_ws/install/tiki_slam
  • ④ install/.../share/에 설치된 폴더. tiki_slam에는 config와 launch, tiki_navigation에는 launch와 params가 있습니다. ros2 launch가 런치 파일을 찾으려면 이 설치 단계가 있어야 합니다.

소스는 ~/ros2_ws/src 아래에 이 구조로 들어 있습니다. 두 패키지가 가진 파일은 이게 전부입니다.

패키지파일package.xml이 선언한 의존
tiki_slamconfig/slam.yaml, launch/slam.launch.pyslam_toolbox
tiki_navigationparams/nav2_params.yaml, launch/bringup.launch.pylaunch_ros, navigation2, nav2_bringup, rviz2

런치 파일이 받는 인자는 --show-args로 확인합니다.

ros2 launch tiki_slam slam.launch.py --show-args
ros2 launch tiki_navigation bringup.launch.py --show-args
두 런치 파일의 --show-args 출력. 명령, slam_params_file, slam 인자, map 인자에 번호 표시
  • ① 두 명령을 한 줄로 이어서 실행했습니다.
  • ② slam_params_file: 기본값이 설치된 config/slam.yaml입니다. 파라미터 파일을 바꿔서 실행하려면 slam_params_file:=내파일.yaml로 줍니다.
  • ③ slam: Nav2에 SLAM을 함께 켤지 정하는 인자. 기본값은 False입니다.
  • ④ map: 이미 만든 지도 파일 경로. slam을 켜지 않고 지도를 쓸 때 줍니다.

tiki_slam의 런치 파일이 하는 일은 slam_toolbox의 async_slam_toolbox_node 하나를 slam.yaml과 함께 실행하는 것이 전부입니다. 실제로 VM에서 실행해 보면 노드는 뜨지만 스캔이 없어 조용합니다.

ros2 launch tiki_slam slam.launch.py
slam.launch.py 실행 직후의 로그. 명령, 프로세스 시작 줄, solver 설정 줄에 번호 표시
  • ① 런치 명령
  • ② process started: async_slam_toolbox_node 프로세스가 올라갔습니다.
  • ③ Using solver plugin ... CeresSolver 같은 초기 설정 로그. 이후에는 새 줄이 나오지 않습니다. 입력(/scan, /odom, TF)이 없기 때문이며 오류가 아닙니다.

Ctrl+C로 끕니다. 로봇이 켜지면 같은 명령에서 지도가 만들어지기 시작합니다(4부).

package.xml과 CMakeLists.txt 읽기: tiki_base의 플러그인

3.6장에서 package.xml은 이름과 의존을, 빌드 설정 파일은 무엇을 만들고 설치하는지를 적는다고 배웠습니다. 로봇 쪽 tiki_base로 실제 파일을 읽어 봅시다. 이 패키지는 OVA에 없으므로 읽기 자료로만 보세요. 먼저 의존 선언입니다.

<buildtool_depend>ament_cmake</buildtool_depend>
<buildtool_depend>pkg-config</buildtool_depend>

<depend>hardware_interface</depend>
<depend>libgflags-dev</depend>
<depend>libserial-dev</depend>
<depend>rclcpp</depend>
<depend>rclcpp_lifecycle</depend>
<depend>pluginlib</depend>

<exec_depend>controller_manager</exec_depend>
<exec_depend>joint_state_broadcaster</exec_depend>

depend는 빌드와 실행에 모두 필요하다는 뜻이고, exec_depend는 실행할 때만 필요하다는 뜻입니다. libserial-dev처럼 ros-humble-이 붙지 않는 이름은 Ubuntu 시스템 패키지이며 rosdep이 apt 패키지로 풀어 줍니다.

이 패키지는 C++ 클래스 하나를 플러그인으로 내놓습니다. 이름이 이어지는 경로를 따라가 보세요.

위치내용
src/CMakeLists.txtadd_library(diffdrive_tiki SHARED diffdrive_tiki.cpp)로 공유 라이브러리 생성
src/diffdrive_tiki.cpp 마지막 줄PLUGINLIB_EXPORT_CLASS(tiki_base::DiffDriveTiki, hardware_interface::SystemInterface)
tiki_hw.xml라이브러리 diffdrive_tiki, 클래스 이름 tiki_base/DiffDriveTiki를 등록
CMakeLists.txtpluginlib_export_plugin_description_file(hardware_interface tiki_hw.xml)로 설명 파일을 ament 인덱스에 등록
tiki.urdf.xacroros2_control 블록의 <plugin>tiki_base/DiffDriveTiki</plugin>

tiki_hw.xml의 핵심 부분은 이렇습니다.

<library path="diffdrive_tiki">
  <class name="tiki_base/DiffDriveTiki"
         type="tiki_base::DiffDriveTiki"
         base_class_type="hardware_interface::SystemInterface">

URDF의 문자열 tiki_base/DiffDriveTiki는 tiki_hw.xml의 class name과 정확히 같아야 합니다. controller_manager는 이 문자열로 플러그인 목록을 찾아 diffdrive_tiki 라이브러리를 불러옵니다. 이름이 한 글자라도 다르면 실행 시점에 플러그인을 찾지 못합니다.

플러그인 이름이 이어지는 길tiki.urdf.xacro<plugin>tiki_base/DiffDriveTikicontroller_manager문자열로 플러그인 검색ament 인덱스hardware_interface 목록123tiki_hw.xmlclass name 일치 확인library path=diffdrive_tikidiffdrive_tiki 라이브러리add_library(... SHARED)로 만든 공유 라이브러리DiffDriveTiki 객체PLUGINLIB_EXPORT_CLASS로 등록된 클래스45강조한 두 상자의 tiki_base/DiffDriveTiki가 한 글자도 다르지 않아야 합니다tiki_hw.xml은 빌드 때 CMakeLists.txt가 ament 인덱스에 등록합니다
controller_manager가 URDF의 플러그인 문자열에서 시작해 DiffDriveTiki 객체를 만들기까지 거치는 파일을 번호 순서로 보여 줍니다.

반대로 이 패키지는 launch/도 설정 파일도 설치하지 않습니다. tiki_description의 CMakeLists.txt는 config, launch, urdf, rviz 네 폴더를 share/tiki_description/에 설치하고, tiki_bringup은 launch, tiki_slam은 config와 launch, tiki_navigation은 launch와 params를 설치합니다. ros2 launch가 런치 파일을 찾으려면 이 설치 단계가 있어야 합니다.

VM에서 실행되는 것과 로봇에서 실행되는 것

패키지어디서이유
tiki_description로봇robot_state_publisher가 /robot_description과 TF를 발행. VM의 RViz2는 이것을 받아서 그림
tiki_base로봇시작할 때 /dev/ttyAMA1을 열고 AT 명령을 보냄. 모터 보드가 있어야 함
tiki_control로봇바퀴 엔코더를 읽을 모터 보드가 필요
tiki_bringup로봇LiDAR 노드는 /dev/ttyUSB0의 센서가 필요하고 control도 같은 문제
tiki_slam, tiki_navigationVM (OVA에 있음)로봇이 보내는 /scan, /odom, TF 입력이 있어야 일을 함. 입력이 없으면 노드만 뜨고 조용함

tiki_base의 코드를 읽으면 시리얼 포트를 열다 실패해도 예외를 잡아 로그에 CLOSE!만 남기고 초기화는 그대로 진행합니다. 그 뒤 컨트롤러가 값을 읽거나 쓸 때마다 오류를 돌려줍니다. 포트가 열리지 않는 VM에서는 컨트롤러가 정상 동작하지 못하는 것이 정상입니다.

그래서 2부에서는 속도 명령에 로봇이 반응하는 실습을 브라우저 에뮬레이터에서 합니다. 4부에서 로봇이 tiki_bringup 계열 패키지를 실행하고, VM이 tiki_slam과 tiki_navigation으로 그 데이터를 받아 씁니다.

한눈에 정리

  1. TIKI-MINI 패키지 6개는 모두 ament_cmake이고, description, base, control, bringup, slam, navigation으로 나뉜다.
  2. tiki_control은 tiki_base와 tiki_description에 의존하고, 시작 순서는 tiki_bringup의 타이머(rplidar 3초, control 7초)로 맞춘다.
  3. 플러그인 이름 tiki_base/DiffDriveTiki는 URDF, tiki_hw.xml, C++ 등록 매크로에서 서로 이어진다.
  4. OVA에서는 colcon list와 ros2 pkg list | grep tiki로 두 패키지를 확인한다. 의존 패키지와 빌드는 미리 되어 있다.
  5. rplidar_ros, teleop_twist_keyboard, tf2_tools는 package.xml에 없어 apt로 따로 설치한다.
  6. OVA의 VM에는 tiki_slam과 tiki_navigation만 있고 빌드되어 있다. 나머지 네 패키지는 로봇에서 실행하며, 특히 tiki_base는 시리얼 포트가 필요하다.

확인 문제

Q1. 로봇 쪽 네 패키지와 VM 쪽 두 패키지는 각각 무엇을 맡나요?

로봇의 tiki_description, tiki_base, tiki_control, tiki_bringup은 모델 발행, 모터 컨트롤러 통신, 컨트롤러 실행, 전체 기동을 맡고 로봇이 센서와 구동을 다룹니다. VM의 tiki_slam, tiki_navigation은 로봇이 보내는 /scan, /odom, TF를 받아 지도를 만들고 길을 찾습니다.

Q2. URDF의 플러그인 이름을 tiki_base/DiffDrive로 잘못 고쳤습니다. 빌드는 성공할까요, 실행은 성공할까요?

빌드는 성공합니다. 이 문자열은 URDF 안의 텍스트라서 컴파일 시점에 검사되지 않기 때문입니다. 실행하면 controller_manager가 tiki_hw.xml에 등록된 tiki_base/DiffDriveTiki를 찾지 못해 플러그인을 불러오지 못합니다.

Q3. OVA의 VM에서 ros2 launch tiki_slam slam.launch.py를 실행하면 노드는 뜨는데 로그가 거의 나오지 않고 지도도 안 만들어집니다. 오류인가요?

오류가 아닙니다. slam_toolbox는 /scan, /odom, TF 입력을 받아야 일을 하는데 로봇이 연결되어 있지 않아 입력이 없는 상태입니다. 실기기를 연결하면 같은 명령에서 지도가 만들어지기 시작합니다. 한편 tiki_bringup의 tiki.launch.py는 LiDAR(/dev/ttyUSB0)와 모터 보드(/dev/ttyAMA1)가 필요해서 로봇에서만 실행하고, OVA에는 이 패키지가 없습니다.

다음 장

다음 장에서는 tiki_description의 URDF를 줄 단위로 읽고, 바퀴 간격과 LiDAR 위치를 파일의 숫자에서 직접 계산해 봅니다.