# 패키지 생성 및 관리

#### 패키지 생성

ROS2에서 패키지를 생성하는 기본 명령은 `ros2 pkg create`이다. 이 명령을 통해 패키지를 생성할 때, 패키지의 이름과 의존성을 지정할 수 있다. 예를 들어, C++ 언어를 사용하는 패키지를 생성하고자 할 때는 다음과 같은 명령을 사용할 수 있다:

```bash
ros2 pkg create --build-type ament_cmake <패키지_이름>
```

이 명령은 패키지의 구조를 자동으로 생성하며, `ament_cmake` 빌드 시스템을 사용하는 C++ 기반 패키지를 만든다. 파이썬 기반 패키지를 생성하고자 할 때는 다음과 같은 명령을 사용할 수 있다:

```bash
ros2 pkg create --build-type ament_python <패키지_이름>
```

#### 패키지의 기본 구조

패키지를 생성한 후, 패키지 디렉터리 안에는 여러 파일과 폴더가 생성된다. 기본적인 패키지 구조는 다음과 같다:

```
<패키지_이름>/
├── CMakeLists.txt
├── package.xml
├── src/
└── include/
```

* `CMakeLists.txt`: 패키지의 빌드를 위한 설정 파일이다. 이 파일을 통해 컴파일러 옵션, 의존성, 빌드 타겟 등을 정의할 수 있다.
* `package.xml`: 패키지의 메타데이터와 의존성을 정의하는 파일이다. ROS2에서는 패키지 의존성을 정의할 때 이 파일을 수정한다.
* `src/`: C++ 코드를 위한 디렉터리이다. 이 디렉터리 안에 노드 코드를 작성할 수 있다.
* `include/`: 헤더 파일을 포함하는 디렉터리이다. C++에서 사용하는 헤더 파일들은 이 디렉터리에 포함시킨다.

#### CMakeLists.txt 파일 구성

ROS2 패키지를 생성하면 `CMakeLists.txt` 파일이 자동으로 생성되며, 이 파일은 패키지의 빌드 절차를 정의하는 핵심 파일이다. `CMakeLists.txt` 파일에서 주로 사용하는 명령어는 다음과 같다:

* `find_package`: 패키지의 의존성을 선언한다. 예를 들어, ROS2에서 필수적으로 사용하는 `rclcpp` 패키지의 의존성을 추가할 때는 다음과 같은 명령어를 사용할 수 있다:

```cmake
find_package(rclcpp REQUIRED)
```

* `add_executable`: 실행 파일을 정의한다. C++ 노드를 컴파일하기 위한 명령어로, `src` 디렉터리 안에 있는 소스 파일을 실행 파일로 빌드할 때 사용한다:

```cmake
add_executable(my_node src/my_node.cpp)
```

* `ament_target_dependencies`: 실행 파일의 의존성을 설정하는 명령어이다. 노드를 빌드할 때 ROS2 패키지의 의존성을 명시할 수 있다:

```cmake
ament_target_dependencies(my_node rclcpp)
```

* `install`: 빌드된 실행 파일을 설치하는 경로를 지정한다:

```cmake
install(TARGETS
  my_node
  DESTINATION lib/${PROJECT_NAME})
```

#### package.xml 파일 구성

`package.xml` 파일은 ROS2 패키지의 메타데이터와 의존성을 정의하는 파일로, ROS1의 `manifest.xml` 파일과 유사한 역할을 한다. 이 파일에서 주로 사용하는 태그는 다음과 같다:

* `<name>`: 패키지의 이름을 정의한다.
* `<version>`: 패키지의 버전을 정의한다.
* `<description>`: 패키지에 대한 설명을 작성한다.
* `<maintainer>`: 패키지의 유지관리자를 정의한다.
* `<license>`: 패키지의 라이선스를 정의한다.
* `<depend>`: 패키지의 의존성을 선언한다.

```xml
<package format="3">
  <name>my_package</name>
  <version>0.0.1</version>
  <description>My first ROS2 package</description>
  <maintainer email="maintainer@example.com">Maintainer Name</maintainer>
  <license>Apache 2.0</license>

  <buildtool_depend>ament_cmake</buildtool_depend>
  <exec_depend>rclcpp</exec_depend>
</package>
```

위와 같은 `package.xml` 파일은 패키지의 빌드 도구로 `ament_cmake`를 사용하고, 실행 시 `rclcpp` 패키지를 필요로 한다는 내용을 포함한다.

#### 패키지 관리

패키지를 생성하고 기본적인 구조를 이해한 후, ROS2에서는 패키지의 빌드와 관리를 위한 몇 가지 중요한 도구들을 사용할 수 있다. 그 중에서도 중요한 것이 `colcon` 빌드 도구이다.

**colcon 빌드 도구 사용법**

`colcon`은 ROS2에서 패키지를 빌드하는 기본 도구이다. ROS1에서 사용되던 `catkin` 대신, ROS2는 패키지 관리 및 빌드를 위해 `colcon`을 채택하였다. `colcon`을 사용하여 패키지를 빌드할 때는 다음과 같은 명령을 사용할 수 있다:

```bash
colcon build
```

이 명령은 현재 워크스페이스 내의 모든 패키지를 빌드한다. 빌드가 완료되면 패키지의 실행 파일 및 라이브러리가 생성되며, 이들은 워크스페이스의 `install` 디렉터리에 위치하게 된다.

**특정 패키지 빌드**

특정 패키지만 빌드하고자 할 때는 `--packages-select` 옵션을 사용할 수 있다. 예를 들어, `my_package`라는 패키지만 빌드하고자 할 때는 다음과 같이 명령을 실행할 수 있다:

```bash
colcon build --packages-select my_package
```

**빌드 옵션**

빌드 시 다양한 옵션을 사용할 수 있다. 다음은 자주 사용되는 `colcon` 빌드 옵션들이다:

* `--symlink-install`: 패키지를 빌드할 때 심볼릭 링크를 사용하여 코드를 설치한다. 이를 통해 코드 변경 시마다 빌드를 다시 할 필요 없이 바로 적용할 수 있다.

```bash
colcon build --symlink-install
```

* `--parallel-workers`: 병렬로 빌드할 작업의 수를 지정한다. 여러 코어를 가진 시스템에서는 이 옵션을 사용하여 빌드 속도를 높일 수 있다.

```bash
colcon build --parallel-workers 4
```

**빌드 오류 해결**

빌드 중 오류가 발생하면, `colcon`은 빌드 로그를 출력한다. 오류가 발생한 패키지 및 관련 파일을 확인하려면 다음 명령어를 사용할 수 있다:

```bash
colcon build --event-handlers console_direct+
```

이 명령은 실시간으로 빌드 로그를 출력해주며, 빌드 실패 시 어느 파일에서 오류가 발생했는지 확인하는 데 도움을 준다.

#### 패키지 의존성 관리

ROS2 패키지를 작성할 때는 종종 다른 패키지에 의존하게 된다. 이러한 의존성을 관리하기 위해 `package.xml` 파일과 `CMakeLists.txt` 파일을 수정해야 한다.

**`package.xml`에서의 의존성 선언**

의존성을 추가하고자 할 때는 `package.xml` 파일에 `<depend>` 태그를 추가해야 한다. 예를 들어, `rclcpp`와 `std_msgs` 패키지에 의존하는 경우 다음과 같이 추가할 수 있다:

```xml
<depend>rclcpp</depend>
<depend>std_msgs</depend>
```

**`CMakeLists.txt`에서의 의존성 추가**

의존성을 추가한 후, `CMakeLists.txt` 파일에서 이를 반영해야 한다. 예를 들어, `rclcpp`와 `std_msgs` 패키지를 사용하는 경우 `CMakeLists.txt` 파일에 다음과 같이 추가한다:

```cmake
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
```

이후, `ament_target_dependencies` 명령을 사용하여 빌드 타겟에 의존성을 추가한다:

```cmake
ament_target_dependencies(my_node rclcpp std_msgs)
```

#### 로컬 및 원격 패키지 관리

로컬 패키지와 원격 패키지를 관리하는 것도 중요한 부분이다. 로컬에서 패키지를 관리하는 경우, 워크스페이스 내에서 직접 패키지를 개발하고 빌드할 수 있다. 반면, 원격 패키지는 ROS2 패키지 인덱스를 통해 다운로드할 수 있다.

**로컬 패키지 관리**

로컬 패키지는 직접 개발하거나 타인이 개발한 패키지를 받아서 사용할 수 있다. 이를 위해 워크스페이스에 해당 패키지를 추가하고 빌드할 수 있다. 워크스페이스는 보통 `src/` 디렉터리를 통해 관리되며, 여기에서 패키지를 클론하여 작업할 수 있다.

예를 들어, GitHub에서 패키지를 클론하고 이를 빌드하는 과정은 다음과 같다:

```bash
cd ~/ros2_ws/src
git clone https://github.com/ros2/example_interfaces.git
cd ~/ros2_ws
colcon build
```

**원격 패키지 관리**

원격 패키지를 설치하기 위해서는 ROS2 패키지 인덱스에서 제공하는 패키지를 설치할 수 있다. Ubuntu를 사용하는 경우 다음 명령어로 ROS2 패키지를 설치할 수 있다:

```bash
sudo apt update
sudo apt install ros-humble-example-interfaces
```

이 명령을 통해 원격에서 제공되는 패키지를 시스템에 설치할 수 있으며, 설치된 패키지는 로컬에서 바로 사용할 수 있다.
