[ROS2] Package
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