본문 바로가기
자율주행

ROS 노드(node)와 토픽(topic) 소개 및 생성

by icebear3000 2023. 5. 2.
반응형

OS Melodic과 C++를 기준으로 ROS 노드와 토픽의 소개 및 생성에 대해 알아보겠습니다.

 

노드 소개 및 사용

1. 노드 소개

 노드는 ROS에서 가장 기본적인 실행 단위로, 각각의 프로세스가 수행하는 작업을 나타냅니다. 노드는 토픽, 서비스, 액션 등을 통해 서로 통신하며, 이를 통해 로봇 시스템의 전체 기능을 구현합니다.

 

2. 노드 생성

  C++를 사용하여 ROS 노드를 생성하는 방법을 알아보겠습니다. 먼저, my_node.cpp 파일을 작업 공간의 패키지 src 디렉터리에 생성합니다.

#include "ros/ros.h"

int main(int argc, char **argv)
{
  // ROS 노드 초기화
  ros::init(argc, argv, "my_node");

  // 노드 핸들 생성
  ros::NodeHandle nh;

  // 로그 메시지 출력
  ROS_INFO("Hello, ROS!");

  // 노드 실행
  ros::spin();

  return 0;
}

 이 예제에서는 ros::init 함수를 사용하여 ROS 시스템에 노드를 초기화합니다. argc와 argv는 커맨드 라인 인수를 나타내고, "my_node"는 노드의 이름입니다.

 

 ros::NodeHandle 객체를 생성하여 노드를 실행합니다. 이 객체를 통해 ROS 시스템과 상호작용할 수 있습니다.

 

 ROS_INFO 매크로를 사용하여 로그 메시지를 출력합니다. 이 메시지는 ROS 시스템에 의해 처리되고, 로깅 시스템에 기록됩니다.

 

 ros::spin()를 이용하여 ROS 노드를 실행합니다. ros::spin()은 이벤트 루프를 실행하며, 콜백 및 메시지 처리를 수행합니다. 작성한 노드를 빌드하려면 CMakeLists.txt 파일을 수정하여 소스 파일을 추가합니다.

add_executable(my_node src/my_node.cpp)
target_link_libraries(my_node ${catkin_LIBRARIES})

 

이제 빌드하고 노드를 실행할 수 있습니다.

$ cd ~/my_workspace
$ catkin_make
$ source devel/setup.bash
$ rosrun my_package my_node

 

토픽 소개 및 사용

1. 토픽 소개

 토픽은 ROS에서 노드 간 메시지를 주고받는 방식으로, 일반적으로 발행-구독 패턴을 사용합니다. 한 노드는 특정 토픽을 발행하며, 다른 노드는 해당 토픽을 구독하여 메시지를 받습니다.

 

2. 토픽 사용

 C++를 사용하여 노드에서 토픽을 발행하고 구독하는 방법을 알아보겠습니다. 먼저, std_msgs::String 타입의 메시지를 발행하는 노드를 생성합니다.

#include "ros/ros.h"
#include "std_msgs/String.h"

int main(int argc, char **argv)
{
  ros::init(argc, argv, "publisher_node");

  ros::NodeHandle nh;

  // 발행자 객체 생성 및 토픽 설정
  ros::Publisher publisher = nh.advertise<std_msgs::String>("my_topic", 1000);

  // 루프 빈도 설정
  ros::Rate loop_rate(10);

    while (ros::ok())
    {
      // 메시지 객체 생성 및 데이터 설정
      std_msgs::String msg;
      msg.data = "Hello, ROS topic!";

      // 메시지 발행
      publisher.publish(msg);

      // 로그 메시지 출력
      ROS_INFO("Published: %s", msg.data.c_str());

      // 루프 처리
      ros::spinOnce();
      loop_rate.sleep();
    }

  return 0;
}

 

 이 예제에서는 `ros::Publisher` 객체를 사용하여 토픽을 발행하고, `ros::Rate` 객체를 사용하여 루프 빈도를 설정합니다. 다음으로, `std_msgs::String` 타입의 메시지를 구독하는 노드를 생성합니다.

 

#include "ros/ros.h"
#include "std_msgs/String.h"

// 콜백 함수
void messageCallback(const std_msgs::String::ConstPtr& msg)
{
  ROS_INFO("Received: %s", msg->data.c_str());
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "subscriber_node");

  ros::NodeHandle nh;

  // 구독자 객체 생성 및 토픽 설정
  ros::Subscriber subscriber = nh.subscribe("my_topic", 1000, messageCallback);

  // 노드 실행
  ros::spin();

  return 0;
}

 이 예제에서는 ros::Subscriber 객체를 사용하여 토픽을 구독하고, 콜백 함수를 정의하여 메시지를 처리합니다. 발행자 노드와 구독자 노드를 각각 빌드하고 실행하면, 두 노드 간에 메시지가 주고받아지는 것을 확인할 수 있습니다.

반응형

댓글