경희대학교 황효석 교수님의 2021-2 로봇 프로그래밍 수업을 듣고 요약한 것입니다.
ROS 는 모든 단위가 패키지로 되어 있다. 패키지 안에 노드가 하나라도 들어 있으면 그것은 패키지에 포함되어 있어야 한다. 그렇기 때문에 처음에는 패키지를 만들어주고, 그 패키지 내부에 두 개의 노드에 대한 소스파일을 작성해줘야 한다.
그리고 패키지에 관련한 information, 즉 xml 파일이나 빌드를 위한 CMakeList 파일을 편집해주고, 그 이후에 빌드하고, 최종적으로 실행하는 순서로 작업을 진행한다.
publisher : 스탠다드 message (따로 정의 하지 않고 기존에 정의되어 있는 데이터 타입을 이용)
topic_exam_pub
subscriber : 그 정보를 받아 화면에 출력
topic_exam_sub
workspace 상에서 패키지를 만들어야 함.
catkin_create_pkg [package name] std_msgs roscpp
//스탠다드 메시지, roscpp 를 사용할 것이다.
그리고 src 폴더 안에 topic_exam_pub.cpp, topic_exam_sub.cpp
두 개의 파일을 생성해서 코드를 작성한다.
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
int main(int argc, char **argv){
ros::init(argc, argv, "topic_exam_publisher");
ros::NodeHandle n;
ros::Publisher topic_exam_pub = n.advertise<std_msgs::String>("topic_exam_message", 1000);
ros::Rate loop_rate(10);
int count = 0;
while(ros::ok()){
std_msgs::String msg;
std::stringstream ss;
ss << "hello world" << count;
msg.data = ss.str();
ROS_INFO("%s", msg.data.c_str());
topic_exam_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
++count;
}
return 0;
}
주석
ros::init(argc, argv, "topic_exam_publisher");
//
master 한테 topic_exam_publisher 라는 이름으로 노드를 등록해달라고 요청함.
파일 이름으로 노드를 등록하는 게 아니라, rosinit 의 세 번째 argument 로 등록함.
ros::NodeHandle n;
//
핸들을 이용해 노드에 대한 동작이나 특성을 지원할 수 있음.
노드에 대한 접점, 포트가 됨.
ros::Publisher topic_exam_pub = n.advertise<std_msgs::String>("topic_exam_message", 1000);
//
n.advertise: 어떤 것을 publish 할 것인지 미리 얘기하는 것.
subscriber 에게 이 노드의 주소를 미리 알려주기 위함.
등록한다고 생각하면 좋다.
#include "ros/ros.h"
#include "std_msgs/String.h"
void getCallBack(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, "topic_exam_subscriber");
ros::NodeHandle n;
ros::Subscriber topic_exam_sub = n.subscribe("topic_exam_message", 1000, getCallback);
ros::spin();
return 0;
}
주석
subscriber 도 하나의 노드가 여러 topic 을 subscribe 할 수 있다.
하지만, 보내는 애는 내가 원하는 시간에 보낼 수 있지만 subscriber 는 언제 내가 구독한 메시지가 들어올 지 모르는 일이므로,
이에 대한 callback function 을 미리 정의해 둔다.
spin() 은 interrupt 가 걸릴 때 까지 대기하는 것이다.
처음에 패키지를 만들었을 때 있던 파일
cmake_minimum_required(VERSION 3.0.2)
project(topic_exam)
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs)
catkin_package(CATKIN_DEPENDS roscpp std_msgs)
include_directories(include ${catkin_INCLUDE_DIRS})
add_executable(topic_exam_pub src/topic_exam_pub.cpp)
target_link_libraries(topic_exam_pub ${catkin_LIBRARIES})
add_executable(topic_exam_sub src/topic_exam_sub.cpp)
target_link_libraries(topic_exam_sub ${catkin_LIBRARIES})
rosrun [패키지이름] [노드이름]
rosrun topic_exam topic_exam_pub
rosrun topic_exam topic_exam_sub
현재 활성화 된 토픽이 뭐가 있는지를 보려면
rostopic list