이번에도 토픽을 주고받는 패키지를 간단하게 만들어보자.
많이 만들어봐야 익숙해진다.
본인은 ROS2로 시작해서, ROS1의 문법에는 아직 안익숙하다 ^^;;
참고한 링크는 다음과 같다.
https://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29
$ cd catkin_ws/src
$ catkin_create_pkg beginner_tutorials std_msgs roscpp
<?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>
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)
# 마찬가지로 메시지 헤더를 사용하기 전에 생성하라는 명령어이다.
$ cd begineer_tutorials
$ mkdir -p msg
$ mkdir -p srv
이후 VScode를 통해 msg 폴더에는 다음과 같은 Num.msg 파일을 작성한다.
int64 num
그리고 srv 폴더에는 다음과 같은 AddTwoInts.srv 파일을 작성한다.
int64 a
int64 b
---
int64 sum
#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
그러면 그래프를 통해서 노드 간의 토픽(메시지) 전달이 시각화 된다.