ROS 2

ROS 2 Tutorials : Creating custom msg and srv files

정지홍 2025. 2. 27. 14:26

https://docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries/Custom-ROS2-Interfaces.html

 

Creating custom msg and srv files — ROS 2 Documentation: Jazzy documentation

Because the interfaces rely on rosidl_default_generators for generating language-specific code, you need to declare a build tool dependency on it. rosidl_default_runtime is a runtime or execution-stage dependency, needed to be able to use the interfaces la

docs.ros.org

 

 

background

  • 이전의 튜토리얼에서는 message와 service 인터페이스를 작성해보았다. 이때 사용한 인터페이스들은 미리 정의된 것 들 이었다.
    • 미리 정의된 인터페이스를 사용하는 것은 좋은 습관이지만, 간혹가다가 나만의 message와 service를 정의해야할 필요가 있을때가 있다. 이번에는 사용자 정의 인터페이스 정의를 만드는 간단한 방법을 소개한다.
    • ros에서 interface는 표준화된 데이터 형식을 의미

 

task

  • 1. create a new package
    • 이번에는 .msg와 .srv를 그들의 패키지에 만들어 볼것이다. 그리고 그들울 별도의 패키지에서 사용하는 방법을 배운다. 두 패키지는 같은 workspace에 존재해야한다.
    • 이전 튜토리얼에서 만든 pub/sub과 service/client 패키지를 사용할것이니 해당 공간에 2개의 패키지가 존재하는지 확인하고, 아래의 명령어로 패키지를 생성하자.
      • 패키지가 생성되면 해당 폴더로 들어가서 msg srv 디렉토리 2개를 만들자.

다음과 같이 명령어를 입력하자.

ros2 pkg create --build-type ament_cmake --license Apache-2.0 tutorial_interfaces

cd tutorial_interfaces
mkdir srv msg

 

 

  • 2.  우선 msg를 정의하자.
    • 2-1. msg dir에 들어가자.
    • 2-2. Num.msg파일을 만들어서 int64 num문장 하나만 써주자.
    • 2-3. Sphere.msg 파일을 만들어서 2개의 문장을 써주자.
cd msg
echo "int64 num" >> Num.msg
echo -e "geometry_msgs/Point center\n""float64 radius" >> Sphere.msg

 

 

  • 3. srv정의하자
    • 2-1. srv dir에 들어가자.
    • 2-2. AddTreeInts.srv파일을 만들자.
echo -e "int64 a\nint64 b\nint64 c\n---\nint64 sum" >> AddThreeInts.srv

 

 

  • 4. CMakeList.txt를 수정
find_package(geometry_msgs REQUIED)
find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/Num.msg"
  "msg/Sphere.msg"
  "srv/AddThreeInts.srv"
  DEPENDENCIES geometry_msgs
)

 

 

  • 5. package.xml도 수정하자.
    • 이를 수정하는 이유는 interfaces가 rosidl_default_generators에게 의존한다. 그래서 need to declare a build tool dependency on it.
<depend>geometry_msgs</depend>
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>

 

 

6. 빌드

colcon build --packages-select tutorial_interfaces

 

 

7. source하기

source install/setup.bash

 

 

8. 확인 하기

ros2 interface show tutorial_interfaces/msg/Num
ros2 interface show tutorial_interfaces/msg/Sphere
ros2 interface show tutorial_interfaces/srv/AddThreeInts

 

 

 

9. cpp_pubsub패키지로 가서 publisher와 subscriber를 수정하자.

#include <chrono>
#include <memory>

#include "rclcpp/rclcpp.hpp"
#include "tutorial_interfaces/msg/num.hpp"                                            // CHANGE

using namespace std::chrono_literals;

class MinimalPublisher : public rclcpp::Node
{
public:
  MinimalPublisher()
  : Node("minimal_publisher"), count_(0)
  {
    publisher_ = this->create_publisher<tutorial_interfaces::msg::Num>("topic", 10);  // CHANGE

    auto timer_callback = [this](){
      auto message = tutorial_interfaces::msg::Num();                                   // CHANGE
      message.num = this->count_++;                                                     // CHANGE
      RCLCPP_INFO_STREAM(this->get_logger(), "Publishing: '" << message.num << "'");    // CHANGE
      publisher_->publish(message);
    };
    timer_ = this->create_wall_timer(500ms, timer_callback);
  }

private:
  rclcpp::TimerBase::SharedPtr timer_;
  rclcpp::Publisher<tutorial_interfaces::msg::Num>::SharedPtr publisher_;             // CHANGE
  size_t count_;
};

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

#include "rclcpp/rclcpp.hpp"
#include "tutorial_interfaces/msg/num.hpp"                                       // CHANGE

using std::placeholders::_1;

class MinimalSubscriber : public rclcpp::Node
{
public:
  MinimalSubscriber()
  : Node("minimal_subscriber")
  {
    auto topic_callback = [this](const tutorial_interfaces::msg::Num & msg){     // CHANGE
      RCLCPP_INFO_STREAM(this->get_logger(), "I heard: '" << msg.num << "'");    // CHANGE
    };
    subscription_ = this->create_subscription<tutorial_interfaces::msg::Num>(    // CHANGE
      "topic", 10, topic_callback);
  }

private:
  rclcpp::Subscription<tutorial_interfaces::msg::Num>::SharedPtr subscription_;  // CHANGE
};

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

 

 

 

  • 10. CMakelist도 수정
cmake_minimum_required(VERSION 3.8)
project(cpp_pubsub)

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)
# find_package(std_msgs REQUIRED)
find_package(tutorial_interfaces REQUIRED)

add_executable(talker src/publisher_lambda_function.cpp)
# ament_target_dependencies(talker rclcpp std_msgs)
ament_target_dependencies(talker rclcpp tutorial_interfaces)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  set(ament_cmake_copyright_FOUND TRUE)
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

add_executable(listener src/subscriber_lambda_function.cpp)
# ament_target_dependencies(listener rclcpp std_msgs)
ament_target_dependencies(listener rclcpp tutorial_interfaces)

install(TARGETS
  talker
  listener
  DESTINATION lib/${PROJECT_NAME})
  
ament_package()

 

 

 

  • 11. package.xml에는 다음 라인을 추가하자.
    • <depend>tutorial_interfaces</depend>

 

  • 12. pubsub 빌드 
    • colcon build --packages-select cpp_pubsub  

 

  • 13. 다시 소스
source install/setup.bash

 

 

  • 14. 터미널 2개로 확인
ros2 run cpp_pubsub talker
ros2 run cpp_pubsub listener

 

 

  • 15. 위에서 publisher subscriber를 수정한것처럼 server와 client도 수정
  • 16. Cmake , package 두개 수정
    • 15번16번은 링크가서 확인
  • 17. colcon build --packages-select cpp_srvcli 입력
  • 18. 소스 다시 하기
  • 19. 실행해서 결과 확인

 

'ROS 2' 카테고리의 다른 글

ros2 lifecycle이란?  (0) 2025.03.24
ROS2에서 TF란?  (0) 2025.03.14
gazebo tutlebot4 카메라 보기  (0) 2025.02.24
ROS2 turtlebot4을 gazebo sim에 띄워보기  (0) 2025.02.23
Launch file  (0) 2025.02.05