본문 바로가기

IT/ROS

[ROS] 4. 퍼블리셔-서브스크라이버 메시지 통신

반응형

☞ 메인보드 : Jetson Nano Developer Kit

운영 체제 : Ubuntu 18.04 - JetPack 4.3

☞ ROS 버전 : Melodic

☞ 언어 : C++

 

 

 

<이전 포스트>

 

3. ROS Melodic 설치

메인보드 : Jetson Nano Deverloper Kit 이미지 파일 버전 : JetPack 4.3 ROS 버전 : Ubuntu 18.04 LTS bionic > ROS Melodic <이전 포스트> 2. Jetson Nano 보드에 Ubuntu 18.04 설치 및 환경설정 메인보드 : Jet..

95mkr.tistory.com

 

 

 

 

 


목차

1. 패키지 생성

2. 퍼블리셔 코드 작성 [talker.cpp]

3. 서브스크라이버 코드 작성 [listener.cpp]

4. XML, CMAKE 파일 작성

 

 

 


 

 

 

① 패키지 생성

 

cs
catkin_create_pkg pub_sub_msg_pkg std_msgs roscpp message_generation actionlib actionlib_msgs
cm
roscd pub_sub_msg_pkg/src

 

패키지를 생성하는 catkin_create_pkg 명령어를 사용하여 pub_sub_msg_pkg란 패키지와 이 패키지에 사용될 의존성을 붙일 것이다.

talker.cpp 와 listener.cpp  두 파일을 작성하는데 C++ 언어를 사용하므로 roscpp을 추가하고 int, float과 같은 데이터 타입을 제공하는 std_msgs도 추가한다. 만약 python으로 코드를 작성한다면 위와 같은 이유로 rospy를 의존성으로 입력해야한다.

 

패키지 생성을 마치면 cm(= cd catkin_ws && catkin_make) 명령어로 빈 패키지를 catkin_make 빌드하자.

 

 

 

 

빌드를 마치면 pub_sub_msg_pkg/src 디렉터리로 이동하고 퍼블리셔 코드를 작성하자.

 

 

 


퍼블리셔 코드 작성 [talker.cpp]

 

[편집기] talker.cpp

 

pub_sub_msg_pkg/src 디렉터리에서 퍼블리셔, 서브스크라이버 코드를 차례대로 작성한다. 선호하는 편집기나 개발환경에서 작업하자.

 

 

#include "ros/ros.h"
#include "std_msgs/Int32.h"
#include <iostream>

int main(int argc, char **argv){

  ros::init(argc, argv, "talker");
	
  ros::NodeHandle n;
  ros::Publisher pub = n.advertise<std_msgs::Int32>("/numbers", 10);
    
  ros::Rate loop_rate(10);
    
  int count = 0;   
  while(ros::ok()){    
    
    std_msgs::Int32 msg;
    
    msg.data = count;
        
    ROS_INFO("%d", msg.data);
        
    pub.publish(msg);
        
    ros::spinOnce();
        
    loop_rate.sleep();
    ++count;
  }
  
  return 0;
}

 

 

 

 

 

 


서브스크라이버 코드 작성 [listener.cpp]

 

[편집기] listener.cpp

 

마찬가지로 src 디렉터리에 다음 코드를 작성하자.

 

 

#include "ros/ros.h"
#include "std_msgs/Int32.h"
#include <iostream>


void numberCallback(const std_msgs::Int32::ConstPtr& msg){
   ROS_INFO("Recieved: [%d]", msg->data);
}

int main(int argc, char **argv){

   ros::init(argc, argv, "listener");
   
   ros::NodeHandle n;
   ros::Subscriber sub = n.subscribe("/numbers", 10, numberCallback);
   
   ros::spin();
   
   return 0;
}

 

 

 

 

 


XML, CMAKE 파일 작성

 

노드 코드를 모두 작성했으면 코드에 맞게 package.xml과 CMakeLists.txt를 수정한다.

alias 명령어로 .bashrc 에 등록한 cs(= cd  ~/catkin_ws/src)로 이동한 후에 pub_sub_msg_pkg 디렉터리로 이동하면 package.xml과 CMakeLists.txt의 존재를 확인할 수 있을 것이다.

 

[편집기] package.xml

 

xml 파일은 수정할 필요가 없으나 주석이 너무 많아서 주석들을 모두 제거했다. 주석을 지우고 말고는 본인이 편한대로 하기 바란다.

(nano 편집기는 Ctrl+k 로 한 줄씩 지울 수 있다. )

 

 

이 xml 파일에서는 빌드 도구가 catkin이라는 점과 패키지 의존성으로 roscpp와 std_msgs를 썼다는 점을 알 수 있다.

 

[편집기] CMakeLists.txt

 

 

 

cmake 버전과 패키지 이름, 패키지를 만들때 입력한 의존성(roscpp std_msgs)과 talker 코드, listener 코드의 실행파일 생성을 위한 내용을 CMakeLists.txt에 적어 놓아야한다. [catkin_package의 내용은 주석 처리 되어도 상관없으나 꼭 포함해야지만 에러가 발생하지 않는다.]

 

해당 명령어에는 순서가 있으니 위 순서를 참고하여 작성하기 바란다. 

 

 

위 작업을 완료하면

 

cm pub_sub_msg_pkg

 

입력해주고 빌드한다. [cm = cd catkin_ws && catkin_make] 

.bashrc 파일에 alias 명령을 사용하면 다양한 나만의 명령어를 만들 수 있으니 참고바란다. 

 

 

talker와 listener의 빌드가 완료되면 이러한 메시지로 출력될 것이다.

 

 

 

위 작업까지 오류 없이 완료하면 새 터미널을 3개 열고 아래의 세 명령어를 각각 쳐주기 바란다.

 

roscore

rosrun pub_sub_msg_pkg talker

rosrun pub_sub_msg_pkg listener

 

 

순서대로 listener -  talker - roscore 이미지다.

roscore로 ros 실행 준비를 하고, rosrun 명령어로 talker와 listener를 차례대로 실행해준다.

퍼블리셔인 talker는 ++count로 number를 늘려가며 numer 값을 출력하고 있으며 /number 토픽을 통해 서브스크라이버인 listener에 number의 값을 INT32의 데이터 타입으로 수신하고 있다.

 

 

이러한 과정은 rqt graph 명령어를 사용하면 마인드맵 형식으로 볼 수 있다.

실행중인 노드의 상관관계를 보여준다.

 

rqt_graph

 

입력하면

원은 노드이며, 화살표 방향으로 퍼블리셔와 서브스크라이버의 관계를 알 수 있다. 화살표 위에 있는 /numbers는 어떠한 토픽으로 메시지를 송수신하고 있는지 알 수 있다.

 

 

 

참고 ☞ 렌틴 조셉 - ROS 로보틱스 프로그래밍

반응형