1 minute read

1. Create a package

package가 생성되길 바라는 경로에서

source /opt/ros/foxy/setup.bash

ros2 pkg create --build-type ament_cmake <package_name>

or

ros2 pkg create --build-type ament_cmake --node-name <node_name> <package_name>

2. Build a package

특정 패키지를 빌드하기 전에 패키지에 필요한 의존성을 먼저 설치해야 한다. 그렇지 않으면 build를 fail한다.

rosdep install --from-paths src --ignore-src -r -y

For all package build

cd ~/ros2_ws

colcon build

For only package build

cd ~/my_package

colcon build --packages-select my_package

3. Source the setup file

source install/local_setup.bash

4. Use the package

ros2 run my_package my_node

6. Customize package.xml

<buildtool_depend>ament_cmake</buildtool_depend>
<buildtool_depend>ament_cmake_ros</buildtool_depend>
  • buildtool_depend : 빌드 도구에 대한 의존성을 명시한다. ROS2에서는 일반적으로 ament_cmake를 사용하여 CMake 기반의 빌드 시스템을 설정
<depend>rclcpp</depend>
<depend>nav2_common</depend>
<depend>nav2_core</depend>
<depend>nav2_util</depend>
<depend>nav2_costmap_2d</depend>
<depend>geometry_msgs</depend>
<depend>visualization_msgs</depend>
<depend>nav2_msgs</depend>
<depend>pluginlib</depend>
<depend>tf2_geometry_msgs</depend>
<depend>tf2</depend>
<depend>tf2_eigen</depend>
<depend>tf2_ros</depend>
<depend>std_msgs</depend>
<depend>xtensor</depend>
<depend>libomp-dev</depend>
<depend>benchmark</depend>
<depend>xsimd</depend>
  • depend : 패키지가 빌드되고 실행될 대 필요한 다른 ROS 패키지에 대한 의존성
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<test_depend>ament_cmake_gtest</test_depend>
  • test_depend : 테스트를 수행할 때 필요한 의존성

7. Remove the package

rm -rf src/<package_name>

rm -rf build/ install/ log/

colcon build

Package Template

├── <package_name>/
│   ├── package.xml
│   ├── CMakeLists.txt
│   ├── include/<package_name>/
│   │   └── lcaol_planner_ros.hpp
│   └── src/
│       ├── local_planner_ros.cpp
│       └── local_planner_node.cpp

package.xml

<depend>rclcpp</depend>
<depend>grid_map_msgs</depend>
<depend>nav_msgs</depend>

새로운 의존성을 추가해야 한다.

CMakeLists.txt

find_package(rclcpp REQUIRED)
include_directories(include/)
ament_target_dependencies(local_planner_node
  rclcpp
  // ...
)

실행 파일을 지정한다.

add_executable(local_planner_node 
  src/local_planner_node.cpp
  src/local_planner_ros.cpp
)

header file의 경로를 설정해줘야 한다.

#include "local_planner/local_planner_ros.hpp"

cpp 파일이나 hpp 파일에서 위와 같이 작성해도 compiler가 경로를 찾을 수 있다.

Header file

가정 먼저 해야 할 것

  • subscriber
  • callback 함수들
    • subscription에 의한 callback 함수
    • timer_callback 함수
#include "local_planner/local_planner_ros.hpp"

LocalPlanner::LocalPlanner() : Node("local_planner_node")
{
    // subscribe
    is_localize_less_mode_ = false;
    topic_name_local_costmap_ = "/local_costmap";
    topic_name_odometry_ = "/odom";

    if (is_localize_less_mode_) {
        sub_local_costmap_ = this->create_subscription<grid_map_msgs::msg::GridMap>(
            topic_name_local_costmap_, 
            10, 
            [this](const grid_map_msgs::msg::GridMap::SharedPtr local_costmap) { this->callback_local_costmap(local_costmap); }
        );
        sub_odometry_ = this->create_subscription<nav_msgs::msg::Odometry>(
            topic_name_odometry_, 
            10, 
            [this](const nav_msgs::msg::Odometry::SharedPtr odometry) { this->callback_odometry(odometry); }
        );
    } else {
        // ...
    }

    // callback_local_costmap
    is_local_costmap_received_ = false;

    // callback_odometry
    is_odometry_received_ = false;

    // callback_timer
    timer_ = this->create_wall_timer(std::chrono::milliseconds(1000), std::bind(&LocalPlanner::callback_timer, this));
}

void LocalPlanner::callback_local_costmap(const grid_map_msgs::msg::GridMap::SharedPtr local_costmap)
{
    is_local_costmap_received_ = true;
}

void LocalPlanner::callback_odometry(const nav_msgs::msg::Odometry::SharedPtr odometry)
{
    is_odometry_received_ = true;
}

void LocalPlanner::callback_timer()
{
    // ...
}

Source code

local_planner.cpp

#include "local_planner/local_planner_ros.hpp"

LocalPlanner::LocalPlanner() : Node("local_planner_node")
{
    // ...
}

// void callback_timer()
// {
//     // ...
// }

// void callback_local_costmap()
// {
//     // ...
// }

// void callback_odometry()
// {
//     // ...
// }

local_planner_node.cpp

#include "local_planner/local_planner_ros.hpp"

int main(int argc, char * argv[])
{
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<LocalPlanner>());
    rclcpp::shutdown();
    return 0;
}

Reference

https://docs.ros.org/en/foxy/Tutorials/Beginner-Client-Libraries/Creating-Your-First-ROS2-Package.html

Categories:

Updated: