[ROS] [C++ 패키지] 토픽을 발행해보자(2)

HY K·2024년 8월 17일

ROS1

목록 보기
23/34

이번에도 토픽을 주고받는 패키지를 간단하게 만들어보자.
많이 만들어봐야 익숙해진다.
본인은 ROS2로 시작해서, ROS1의 문법에는 아직 안익숙하다 ^^;;
참고한 링크는 다음과 같다.
https://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29


1. 패키지 생성하기

$ cd catkin_ws/src
$ catkin_create_pkg beginner_tutorials std_msgs roscpp

2. package.xml과 CMakeLists.txt 파일 수정하기

package.xml

<?xml version="1.0"?>
<package format="2">
  <name>beginner_tutorials</name>
  <version>0.1.0</version>
  <description>The beginner_tutorials package</description>
  <maintainer email="alpha12334@naver.com">kimhoyun</maintainer>
  <license>Apache 2.0</license>

  <buildtool_depend>catkin</buildtool_depend>

  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_depend>message_generation</build_depend>

  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>

  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>message_runtime</exec_depend>

  <export>
  </export>
</package>

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.2)
project(beginner_tutorials)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)

add_message_files(
  FILES
  Num.msg
)

add_service_files(
  FILES
  AddTwoInts.srv
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES beginner_tutorials
  CATKIN_DEPENDS roscpp rospy std_msgs message_generation
)

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
)

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)
# 메시지 헤더가 사용되기 전에 생성하라고 명령하는 내용이다.

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages_cpp)
# 마찬가지로 메시지 헤더를 사용하기 전에 생성하라는 명령어이다.

3.메시지 및 srv 파일 생성하기

$ cd begineer_tutorials
$ mkdir -p msg
$ mkdir -p srv

이후 VScode를 통해 msg 폴더에는 다음과 같은 Num.msg 파일을 작성한다.

int64 num

그리고 srv 폴더에는 다음과 같은 AddTwoInts.srv 파일을 작성한다.

int64 a
int64 b
---
int64 sum

4. 퍼블리셔와 서브스크라이버 노드 작성하기

퍼블리셔 노드

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>

int main(int argc, char **argv){
    ros::init(argc, argv, "talker");
    // 초기화 하기
    ros::NodeHandle n;
    // NodeHandel은 ROS 시스템과 노드 간의 상호작용(통신)을 위해 필요하다.

    ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter",  1000);
    // 퍼블리셔를 chatter_pub이라는 변수 이름으로, chatter라는 토픽을 발행하도록 선언한다.

    ros::Rate loop_rate(10);
    // 10Hz(0.1초) 주기로 발행하도록 선언한다.

    int count = 0;
    while(ros::ok()){ // ROS 노드가 살아있는 한
        std_msgs::String msg;
        std::stringstream ss;

        ss<<"Hello, World"<<count;
        msg.data = ss.str();
        ROS_INFO("%s", msg.data.c_str());
        // msg에 Hello wordl와 count를 추가한다.

        chatter_pub.publish(msg); // 토픽 발행하기
        ros::spinOnce();
        loop_rate.sleep();
        ++count;
    }
}

서브스크라이버 노드

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

void chatterCallback(const std_msgs::String::ConstPtr& msg){
    ROS_INFO("I heard [%s]", msg->data.c_str());
}

int main(int argc, char **argv){
    ros::init(argc, argv, "listener");
    ros::NodeHandle n;

    ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
    // 서브스크라이버 생성하기
    // 콜백 함수를 호출한다.

    ros::spin();
}

빌드하고 실행하기

빌드

$ cd catkin_ws
$ catkin_make

실행

// 1번째 터미널
$ roscore

// 2번째 터미널
$ cd catkin_ws && source devel/setup.bash
$ rosrun beginner_tutorials talker

// 3번째 터미널
$ cd catkin_ws && source devel/setup.bash
$ rosrun begineer_tutorials listener

그러면 다음과 같은 결과를 확인할 수 있다.

두 터미널을 겹쳐서 찍은 것이다.
다음 명령어를 통해서도 확인이 가능하다.

rqt_graph

그러면 그래프를 통해서 노드 간의 토픽(메시지) 전달이 시각화 된다.

profile
로봇, 드론, SLAM, 제어 공학 초보

0개의 댓글