환경 : 우분투 20.04 + ROS2 foxy + CPP
ROS2 패키지를 쌩으로 하나 만들고 싶을 때 어떻게 하는 지를 서술한다.
+ CMakelist.txt, package.xml 파일의 내용을 살펴본다.
1. 워크스페이스 만들기
아래 명령어로 ws를 만들고 colcon build 실행한다. 워크스페이스 이름은 자유다.
$ mkdir -p ~/my_ros2_ws/src && cd ~/my_ros2_ws/ && colcon build
tree 로 폴더 구조를 보면 아래와 같은 구조다. 굳이 확인 안해봐도 된다.
$tree
.
├── build
│ └── COLCON_IGNORE
├── install
│ ├── COLCON_IGNORE
│ ├── local_setup.bash
│ ├── local_setup.ps1
│ ├── local_setup.sh
│ ├── _local_setup_util_ps1.py
│ ├── _local_setup_util_sh.py
│ ├── local_setup.zsh
│ ├── setup.bash
│ ├── setup.ps1
│ ├── setup.sh
│ └── setup.zsh
├── log
│ ├── build_2000-00-00_00-00-00
│ │ ├── events.log
│ │ └── logger_all.log
│ ├── COLCON_IGNORE
│ ├── latest -> latest_build
│ └── latest_build -> build_2000-00-00_00-00-00
└── src
2.패키지 만들기
아래 명령어를 통해 패키지를 만든다. 패키지를 구성하는 요소들, 기본적인 틀이 좌라락 설치된다.
$ cd ~/my_ros2_ws/src/
$ ros2 pkg create my_pkg --build-type ament_cmake
package name: my_pkg
destination directory: /home/user/my_ros2_ws/src
package format: 3
version: 0.0.0
description: TODO: Package description
maintainer: ['robotlab <my@email.com>']
licenses: ['TODO: License declaration']
build type: ament_cmake
dependencies: []
creating folder ./my_pkg
creating ./my_pkg/package.xml
creating source and include folder
creating folder ./my_pkg/src
creating folder ./my_pkg/include/my_pkg
creating ./my_pkg/CMakeLists.txt
패키지의 구조를 보면 아래와 같은 상황. 내부에 있는 것들이 뭔지 알아보자.
my_pkg/
├── CMakeLists.txt
├── include
│ └── my_pkg
├── package.xml
└── src
3.패키지 내부 파일들 알아보기( src폴더, include폴더, package.xml , CMakeList.txt)
src 폴더
소스파일이 들어가는 폴더다. 예를들면 노드 클래스를 작성한 .cpp파일 , main함수가 들어 있는 main.cpp가 들어갈 수 있다.
include 폴더
안에 my_pkg가 들어있을 것이다. ROS2에서는 객체지향 프로그래밍(OOP)이 권장된다. 이 폴더에는 그를 위한 클래스와 메써드가 선언되어 있는 .hpp를 작성해 넣게 된다. 당연히 export하기 원하는 라이브러리 헤더파일도 들어간다.
package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>my_pkg</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="my@email.com">Name</maintainer>
<license>TODO: License declaration</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
다음과 같은 정보를 담고 있다.
- 버전
- description
- maintainer
- license
위는 빌드에 상관없는 정보들이고(맘껏 작성해도 되고 없어도 된다)
<buildtool_depend>, <test_depend>등 이 패키지의 dependency(의존성), 빌드 타입 등을 서술해주는 역할을 한다.(잘 정의해줘야 빌드된다)
CMakeLists.txt
아주 중요한 파일로 컴파일러에게 어떻게 노드를 만들건지, 컴파일에 필요한 정보를 알려준다.(+링커에 필요한 정보)
어디에 설치할지 executable 파일의 이름은 무엇으로 할지, 라이브러리 링크, 의존성은 어떻게 되는지 등이 서술되어 있다. 열어보면 기본적으로 작성이 되어 있으나 아래와 같이 가장 기본적인거만 남기고 다 날리자. Default to C99도 cpp14를 쓸거기 때문에 날린다.
cmake_minimum_required(VERSION 3.5)
project(my_pkg)
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
find_package(ament_cmake REQUIRED)
#여기다가 채울겁니다
ament_package()
이제 find_package(ament_cmake REQUIRED) 와 ament_package()사이에 필요한 내용을 채우며 기본적인 것을 알아보자.
4.패키지 컴파일(빌드) 하기
$ colcon build --packages-select my_pkg
Starting >>> my_cpp_pkg
Finished <<< my_cpp_pkg [1.71s]
Summary: 1 package finished [1.84s]
colcon build 명령어로 컴파일(빌드랑 같은말은 아니지만 그냥 컴파일로 함)한다. 뒤에 붙은 --packages-select는 선택한 패키지만 컴파일해주는 옵션이다. CMakeList.txt에 작성된대로 컴파일한다. 현재는 src폴더에 소스파일을 비롯하여 excutable파일, install 정보 등을 CMakeList.txt에 제대로 작성한게 아니기 때문에 그냥 공책이 빌드된 상태다. 이제 아주 간단한 노드를 작성하여 실행시켜보자.
5.패키지에 노드 작성하기
아래 명령어를 통해 my_pkg/src 폴더 내에 소스 파일을 하나 만든다.
$ cd ~/my_ros2_ws/src/my_pkg/src/
$ touch my_node.cpp
#include "rclcpp/rclcpp.hpp"
class RobotNode : public rclcpp::Node
{
public:
RobotNode() : Node("robot_node")
{
RCLCPP_INFO(this->get_logger(), "robot_node 기본 생성자");
}
private:
};
int main(int argc, char** argv){
rclcpp::init(argc,argv);
auto node = std::make_shared<RobotNode>();
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
아무 기능 없이 기본생성자 호출문구만 한번 뜨는 내용이다. 소스 코드에 대한 자세한 설명은 이후 포스팅에서 다룬다. 우선 패키지 완성을 목표로 한다.
3. 패키지 내부 파일들 알아보기에서 보았던 CMakeList.txt를 열어 아래와 같은 내용을 find_package(ament_cmake REQUIRED) 와 ament_package()사이에 채운다.
...
find_package(rclcpp REQUIRED)
add_executable(${PROJECT_NAME}_node src/my_node.cpp)
ament_target_dependencies(${PROJECT_NAME}_node rclcpp)
install(TARGETS
${PROJECT_NAME}_node
DESTINATION lib/${PROJECT_NAME}
)
...
이를 추가함으로써 my_pkg_node라는 executable파일이 생성될 것이고, install 명령어를 통해 lib/my_pkg 폴더 내에 그것이 설치될 것이다. ${PROJECT_NAME}에는 패키지 이름이 들어간다(my_pkg).
패키지 이름(my_pkg), 소스파일 이름(my_node), 노드이름(robot_node)가 다른 것을 볼 수 있는데, 셋다 같아도 문제없이 작동한다. 하지만 혼동을 피하기위해서 셋의 이름을 보통 구분한다.(어쩌면 더 헷갈릴 수도 있겠지만 본인만의 규칙을 정하면 이름만 보고도 소스를 칭하는 건지 패키지 명을 얘기하는 건지 등을 잘 구분할 수 있게 된다.
마지막으로 3번 설명에서 봤던 package.xml에 아래와 같이 <depend>rclcpp</depend>라인<buildtool_depend>ament_cmake</buildtool_depend>바로 아래에 추가해준다.
...
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rclcpp</depend>
...
그 다음 패키지를 빌드해준다.
$ colcon build --packages-select my_pkg
아래의 명령어로 노드를 실행시켜보자
$ ros2 run my_pkg my_pkg_node
[INFO] [1700000000.460000960] [robot_node]: robot_node 기본 생성자
+추가정보
아까 executable 파일을 생성하여 설치할 때 사용한 CMakeLIst.txt 내의 install 명령어를 기억할 것이다.
이 install 명령어를 사용하면 나중에 사용하게 될 launch파일, config파일, 기타등등 내가 설치하고 싶은 디렉토리, 폴더 등을 install 내의 특정 폴더에 설치할 수 있다. (후에 포스팅할 launch.py 파일 등에서 접근하기 편하다는 점 등 다 용도가 있다.) 아래와 같이 CMakeList.txt를 수정해보자. 워크스페이스의 install/share에 지정한 파일들이 설치되어 있을 것이다.
cmake_minimum_required(VERSION 3.5)
project(my_pkg)
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
add_executable(${PROJECT_NAME}_node src/my_node.cpp)
ament_target_dependencies(${PROJECT_NAME}_node rclcpp)
install(TARGETS
${PROJECT_NAME}_node
DESTINATION lib/${PROJECT_NAME}
)
install(DIRECTORY
config
launch
mydir
DESTINATION share/${PROJECT_NAME}
)
next. 노드 소스코드에 대한 자세한 설명
'로보틱스' 카테고리의 다른 글
ROS2 cpp 커스텀 메세지 및 서비스 작성 (custom msgs & srv) (0) | 2024.04.07 |
---|---|
ROS2 cpp 파라미터 선언 및 코드 내 활용(2) - yaml 파일 활용하기 (0) | 2024.03.05 |
ROS2 cpp 파라미터 선언 및 코드 내 활용(1) (0) | 2024.02.24 |
Ubuntu 20.04(우분투 20.04) ROS2(foxy)설치 (0) | 2024.02.19 |