[ROS2] (19)-패키지 내에서 msg파일 만들어 사용하기
패키지 내에서 msg 파일 만들기Permalink
.msg
, .srv
파일들은 별도의 패키지로 구성하는 것이 선호되지만, 때로는 같은 패키지 내에서 해당 파일들을 만들어서 사용해야 하는 경우도 있다. 다만, 이전 포스팅에서 언급한 것처럼 CMake 패키지로만 메시지 파일들을 정의할 수 있다. 여기서는 .msg
파일만 만들어 보기로 한다.
패키지 만들기Permalink
src
폴더에 more_interfaces
라는 패키지를 만들고, 패키지 내에 msg
폴더를 생성한다.
$ cd ~/dev_ws/src
$ ros2 pkg create --build-type ament_cmake more_interfaces
$ mkdir more_interfaces/msg
메시지 파일 생성 및 빌드하기Permalink
more_interfaces/msg
폴더 내에 AddressBook.msg
파일을 생성하고 아래 내용을 붙여넣는다.
bool FEMALE=true
bool MALE=false
string first_name
string last_name
bool gender
uint8 age
string address
여기서는 first_name
, last_name
, gender
, age
, address
5가지 영역과 2개의 상수(constant) 값 FEMALE
, MALE
을 정의하고 있다.
.msg
파일 빌드를 위해 의존성을 추가해줘야 한다. 먼저, package.xml
파일을 열어 아래 내용을 추가해준다.
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
다음으로 CMakeLists.txt
파일을 열어서 아래 내용을 추가해준다.
find_package(rosidl_default_generators REQUIRED)
set(msg_files
"msg/AddressBook.msg"
)
rosidl_generate_interfaces(${PROJECT_NAME}
${msg_files}
)
ament_export_dependencies(rosidl_default_runtime)
메시지 파일이 여러 개인 경우, 아래와 같이 모두 추가해주어야 한다.
set(msg_files
"msg/Message1.msg"
"msg/Message2.msg"
# etc
)
set(srv_files
"srv/Service1.srv"
"srv/Service2.srv"
# etc
)
패키지 내에서 msg 파일 사용하기Permalink
more_interfaces/src
폴더에 publish_address_book.cpp
파일을 생성하고, 아래 내용을 붙여넣는다.
#include <chrono>
#include <memory>
#include "rclcpp/rclcpp.hpp"
#include "more_interfaces/msg/address_book.hpp"
using namespace std::chrono_literals;
class AddressBookPublisher : public rclcpp::Node
{
public:
AddressBookPublisher()
: Node("address_book_publisher")
{
address_book_publisher_ =
this->create_publisher<more_interfaces::msg::AddressBook>("address_book", 10);
auto publish_msg = [this]() -> void {
auto message = more_interfaces::msg::AddressBook();
message.first_name = "John";
message.last_name = "Doe";
message.age = 30;
message.gender = message.MALE;
message.address = "unknown";
std::cout << "Publishing Contact\nFirst:" << message.first_name <<
" Last:" << message.last_name << std::endl;
this->address_book_publisher_->publish(message);
};
timer_ = this->create_wall_timer(1s, publish_msg);
}
private:
rclcpp::Publisher<more_interfaces::msg::AddressBook>::SharedPtr address_book_publisher_;
rclcpp::TimerBase::SharedPtr timer_;
};
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<AddressBookPublisher>());
rclcpp::shutdown();
return 0;
}
빌드를 위해 의존성을 추가해 준다. CMakeLists.txt
파일을 열고, 아래 내용을 추가해준다.
find_package(rclcpp REQUIRED)
add_executable(publish_address_book
src/publish_address_book.cpp
)
ament_target_dependencies(publish_address_book
"rclcpp"
)
install(TARGETS publish_address_book
DESTINATION lib/${PROJECT_NAME})
패키지 내에서 만든 메시지 타입을 사용하기 위해서 아래 내용도 CMakeLists.txt
파일에 추가해준다. 별도의 패키지에서 빌드한 메시지 타입을 사용할 때는 아래 내용은 필요없다.
rosidl_target_interfaces(publish_address_book
${PROJECT_NAME} "rosidl_typesupport_cpp")
실행하기Permalink
먼저, 패키지를 빌드한다.
$ cd ~/dev_ws
$ colcon build --packages-up-to more_interfaces
이제 환경변수를 설정하고, publisher 노드를 실행한다.
$ source install/local_setup.bash
$ ros2 run more_interfaces publish_address_book
토픽이 제대로 퍼블리시되고 있는지 확인하기 위해 새로운 터미널 창을 열고, 토픽을 출력해본다.
$ cd ~/dev_ws
$ source install/setup.bash
$ ros2 topic echo /address_book
메시지가 잘 출력된다면 정상 동작하고 있는 것이다.
댓글남기기