ROS 토픽

2024. 4. 8. 21:27ROS

  • ROS에서 단방향으로 데이터를 송수신하는 토픽(Topic) 기능이 있음
  • 송신하는 노드를 퍼블리셔(publisher) 수신하는 노드를 서브스크라이버(subscriber)라고 함
cd ~/catkin_ws/src
catkin_create_pkg ros_topic message_generation std_msgs roscpp

 

1. CMakeLists.txt 파일 수정

CMakeLists.txt

 

2. 메시지 파일 생성

pwd
/home/ch/catkin_ws/src/ros_topic
mkdir msg
cd msg
nano Message1.msg

 

2.1 아래 데이터 입력하고 저장

time stamp
int32 data

 

3. 토픽 퍼블리셔 노드 코드 만들기

#include "ros/ros.h"                            // ROS Default Header File
#include "ros_topic/Message1.h"    // MsgTutorial Message File Header. The header file is automatically created when building the package.

int main(int argc, char **argv)                 // Node Main Function
{
  ros::init(argc, argv, "ros_topic_publisher");     // Initializes Node Name
  ros::NodeHandle nh;                           // Node handle declaration for communication with ROS system

  // Declare publisher, create publisher 'ros_topic_publisher' using the 'Message1'
  // message file from the 'ros_topic' package. The topic name is
  // 'ros_topic_msg' and the size of the publisher queue is set to 100.
  ros::Publisher ros_topic_pub = nh.advertise<ros_topic::Message1>("ros_topic_msg", 100);

  // Set the loop period. '10' refers to 10 Hz and the main loop repeats at 0.1 second intervals
  ros::Rate loop_rate(10);

  ros_topic::Message1 msg;     // Declares message 'msg' in 'Message1' message file format
  int count = 0;                            // Variable to be used in message

  while (ros::ok())
  {
    msg.stamp = ros::Time::now();           // Save current time in the stamp of 'msg'
    msg.data  = count;                      // Save the the 'count' value in the data of 'msg'

    ROS_INFO("send msg = %d", msg.stamp.sec);   // Prints the 'stamp.sec' message
    ROS_INFO("send msg = %d", msg.stamp.nsec);  // Prints the 'stamp.nsec' message
    ROS_INFO("send msg = %d", msg.data);        // Prints the 'data' message

    ros_topic_pub.publish(msg);          // Publishes 'msg' message

    loop_rate.sleep();                      // Goes to sleep according to the loop rate defined above.

    ++count;                                // Increase count variable by one
  }

  return 0;
}

 

4. 토픽 서브스크라이버 노드 코드 만들기

#include "ros/ros.h"                          // ROS Default Header File
#include "ros_topic/Message1.h"  // MsgTutorial Message File Header. The header file is automatically created when building the package.

// Message callback function. This is a function is called when a topic
// message named 'ros_topic_msg' is received. As an input message,
// the 'Message1' message of the 'ros_topic' package is received.
void msgCallback(const ros_topic::Message1::ConstPtr& msg)
{
  ROS_INFO("recieve msg = %d", msg->stamp.sec);   // Prints the 'stamp.sec' message
  ROS_INFO("recieve msg = %d", msg->stamp.nsec);  // Prints the 'stamp.nsec' message
  ROS_INFO("recieve msg = %d", msg->data);        // Prints the 'data' message
}

int main(int argc, char **argv)                         // Node Main Function
{
  ros::init(argc, argv, "ros_topic_subscriber");            // Initializes Node Name

  ros::NodeHandle nh;                                   // Node handle declaration for communication with ROS system

  // Declares subscriber. Create subscriber 'ros_topic_subscriber' using the 'Message1'
  // message file from the 'ros_topic' package. The topic name is
  // 'ros_topic_msg' and the size of the publisher queue is set to 100.
  ros::Subscriber ros_topic_sub = nh.subscribe("ros_topic_msg", 100, msgCallback);

  // A function for calling a callback function, waiting for a message to be
  // received, and executing a callback function when it is received.
  ros::spin();

  return 0;
}

 

5. 패키지 빌드하기

cd ~/catkin_ws
catkin_make

 

6. 패키지 실행하기

rosrun ros_topic ros_topic_publisher
rosrun ros_topic ros_topic_subscriber

 

-추가

랜덤값 보내는 publisher 코드

#include "ros/ros.h"                            // ROS Default Header File
#include "ros_topic_sensorsim/Message11.h"    // MsgTutorial Message File Header. The header file is automatically created when building the package.
#include <random>
int main(int argc, char **argv)                 // Node Main Function
{ 
  std::random_device rd;
  std::mt19937 gen(rd()); 
  std::uniform_int_distribution<> dis(1, 100);
  
  ros::init(argc, argv, "ros_topic_ppublisher");     // Initializes Node Name
  ros::NodeHandle nh;                           // Node handle declaration for communication with ROS system

  // Declare publisher, create publisher 'ros_topic_publisher' using the 'Message1'
  // message file from the 'ros_topic' package. The topic name is
  // 'ros_topic_msg' and the size of the publisher queue is set to 100.
  ros::Publisher ros_topic_pub = nh.advertise<ros_topic_sensorsim::Message11>("ros_topic_msg", 100);

  // Set the loop period. '10' refers to 10 Hz and the main loop repeats at 0.1 second intervals
  ros::Rate loop_rate(10);

  ros_topic_sensorsim::Message11 msg;     // Declares message 'msg' in 'Message1' message file format
  int count = 0;                            // Variable to be used in message

  while (ros::ok())
  { 
    
               // Save current time in the stamp of 'msg'
    msg.data  = count;                      // Save the the 'count' value in the data of 'msg'

      // Prints the 'stamp.nsec' message
    ROS_INFO("send msg = %d", msg.data);        // Prints the 'data' message

    ros_topic_pub.publish(msg);          // Publishes 'msg' message

    loop_rate.sleep();                      // Goes to sleep according to the loop rate defined above.

    count = dis(gen);                                // Increase count variable by one
  }

  return 0;
}

'ROS' 카테고리의 다른 글

ROS opencv  (0) 2024.04.17
ROS roslaunch  (0) 2024.04.17
ROS 파라미터  (0) 2024.04.17
ROS 서비스  (0) 2024.04.17
ROS 기본(20.04)  (0) 2024.04.02