본문 바로가기

쓰기

ROS(Robot Operating System) 개념과 활용
2015.07.26 22:50

ROS(Robot Operating System) 개념과 활용 - 5. 바닥부터 node 작성하기

조회 수 33278
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

 지금까지는 기존에 있던 패키지 노드를 수정하여 사용해 왔습니다. 이번에는 노드를 아예 처음부터 새로 작성하는 법에 대해 알아보겠습니다. 또한 노드 내부에서 사용되는 ROS의 기본 구조에 대해서도 간략히 짚고 넘어가도록 하겠습니다. 노드 작성법을 간단히 요약하면 [디렉토리 생성 -> 소스 작성 -> 설정 파일 작성 -> 빌드]입니다. 각 과정을 순서대로 하나씩 설명드리도록 하겠습니다.


1. 디렉토리 생성

$ cd ~/catkin_ws/src                         -> catkin workspace source 디렉토리로 이동

$ catkin_create_pkg nodetest           -> nodetest 패키지 생성


패키지를 생성하면 패키지 디렉토리 아래에 CMakeLists.txt와 package.xml 파일이 생성됩니다. 이 두 파일이 빌드에 관련된 설정 정보를 가지고 있습니다.


2. Publisher 노드 작성

 우선 publisher 노드를 작성하도록 해 보겠습니다. 실제로는 한 노드가 publisher와 subscriber로서 모두 작동할 수 있지만 이번에는 각각을 별개의 노드로 만들어 보겠습니다. 이번에 만들 publisher는 0.2초마다 0부터 1씩 증가하는 값을 ASCII로 메시지를 통해 전달하는 노드입니다.


~/catkin_ws/src/nodetest 경로에서

$ mkdir src                                         -> src 디렉토리 생성

$ cd src                                               -> src 디렉토리로 이동

$ gedit nodetest_publisher.cpp          -> nodetest_publisher 소스 파일 생성


경로나 소스 파일 생성은 우분투 내장 파일 관리자인 nautilus를 사용해도 됩니다.


nodetest.png

Publisher 노드와 subscriber 노드 작성 예시


 ROS는 기본적으로 python으로 동작하지만 roscpp 라이브러리를 통해 C++로 소스를 작성할 수 있습니다. 별도의 언급이 없는 한 C++을 사용하는 것을 기준으로 하겠습니다. 메시지의 형식은 사전 정의되어 있으며 std_msgs와 common_msgs, 그리고 사용자 정의 메시지가 있습니다. std_msgs 패키지에는 bool, char, float, int, string 등의 일반적으로 사용되는 자료형이 들어 있습니다. common_msgs 패키지에는 로봇의 구성부와 관련 패키지에서 주로 쓰이는 자료형이 포함되어 있습니다. common_msgs 패키지에는 actionlib_msgs, diagnostic_msgs, geometry_msgs, nav_msgs, sensor_msgs가 포함되어 있습니다. 이 중 geometry_msgs에는 동역학적 데이터인 Accel, Inertia, Quaternion, Transform, Twist, Vector, Wrench 등이 포함되어 있으며, sensor_msgs에는 여러 가지 센서 측정값에 관련된 데이터인 CompressedImage, FluidPressure, Imu, JointState, LaserScan, MagneticField, Range, RelativeHumidity, Temperature 등이 포함되어 있습니다. 이런 식으로 다양한 자료형을 사전 정의해 놓는 이유는 데이터를 표준화하여 서로 다른 패키지간의 정보 전달과 사용을 원활하게 하기 위해서입니다. 사용자의 필요에 따라 사전 정의된 메시지 형식 말고도 직접 메시지 형식을 만들어 사용하는 것도 가능합니다.


 소스 내에서 실제로 publisher 선언을 하는 부분은 ros::Nodehandle 클래스의 advertise()를 이용합니다. advertise()가 호출되면 마스터가 해당 토픽의 메시지를 subscribe하고자 하는 노드에게 그 토픽으로 publish하고자 하는 노드가 있음을 전달합니다. 그 이후에 publisher와 subscriber가 직접 연결됩니다. advertise()는 해당 토픽으로 publish 가능한 객체인 ros::Publisher 클래스를 반환하며 그 객체의 publish()를 이용하여 원하는 메시지를 발행할 수 있습니다. advertise()는 함수 오버로딩이 되어 있으며 가장 간단한 형태는 매개변수로 토픽명과 queue size를 가집니다. Queue size는 발행하는 메시지를 몇 개까지 저장해 둘 것인지 정하는 값입니다. 위에 제가 작성한 예제 소스에서는 advertise()를 이용해 i_am_the_publisher라는 ros::Publisher 객체를 생성하고, 그 객체의 publish()를 이용해 std_msgs::Int32 자료형의 testmsg 객체가 가진 data 값을 메시지로 발행하고 있습니다.


 그 외에 publisher 노드 소스에 포함된 내용들은 ROS 관련 의존 요소 포함, 노드 초기화, 루프문으로 구성되어 있습니다. ROS 관련 헤더인 ros.h와 표준 자료형 메시지 패키지인 std_msgs/Int32.h 헤더를 포함시켰습니다. 그 다음 ros::init()을 이용하여 ROS를 초기화하고 노드 이름을 지정합니다. init()을 사용할 때 인자로 argc와 argv가 들어가는데 이 부분은 그냥 이렇게 쓰면 된다고 기억하시고 자세한 것은 차후에 다루도록 하겠습니다. 그리고 노드명 매개변수에는 "name_of_pub_node"라는 노드 이름을 인자로 주었습니다. 나중에 rqt_graph에서 노드와 메시지를 확인할 때 지금 지정한 이름이 뜨게 됩니다. loop_rate()를 이용해 루프가 5Hz로 실행되도록 하였고, 루프가 한 번씩 돌 때마다 count값이 0부터 1씩 증가하도록 하였습니다. 루프 내부에서 testmsg 메시지 객체의 data 값에 count 값을 대입해 주므로 data 값도 0부터 1씩 증가하고, 이 값이 publish됩니다. ROS_INFO()를 이용하면 노드가 돌아가는 터미널 창에 printf처럼 무언가를 출력할 수 있습니다. 여기서는 testmsg 객체의 data 값을 출력하도록 하였는데, 포맷 스트링을 %c로 주어서 data 값이 ASCII로 출력되도록 하였습니다.


3. Subscriber 노드 작성

 이번에는 전달받은 메시지 데이터를 decimal 값으로 터미널에 출력하는 노드를 작성해 보겠습니다.


~/catkin_ws/src/nodetest/src 경로에서

$ gedit nodetest_subscriber.cpp       -> nodetest_subscriber 소스 파일 생성


Publisher의 advertise()와 같이 subscriber도 ros::Nodehandle 클래스의 subscribe()를 이용해 구독자 선언을 해야 합니다. subscribe()는 세 가지 파라미터로 토픽명, 받은 메시지를 저장할 큐 사이즈, 그리고 callback 함수를 가집니다. subscribe()는 메시지를 받아서 callback 함수에 전달합니다. 즉 callback 함수에서 받은 메시지를 이용해 무엇을 할 것인지 처리하도록 할 수가 있습니다. subscriber()는 ros::Subscriber 객체를 반환합니다. subscriber() 호출 후에는 ros::spin() 함수를 이용하여 반복 구독을 수행하고 callback을 지속적으로 요청합니다. Publisher의 경우엔 사용자가 주기를 지정해서 정해진 시간 간격으로 메시지를 보냈지만, subscriber는 메시지가 오는 즉시 callback을 요청하고 바로 그 다음 메시지를 기다립니다. 노드를 작성하는 전체적인 절차는 발행자 노드와 비슷합니다. 의존 요소와 ROS 관련 헤더를 포함시키고, callback 함수를 정의한 다음, 노드 초기화를 하고 spin()을 이용해 callback 요청과 반복을 수행하는 것입니다. 위의 예시에서는 'name_of_topic'이라는 토픽을 가진 메시지를 10진수 정수형으로 터미널에 출력하는 노드를 작성하였습니다.


4. 설정 파일 작성

 처음에 패키지를 생성했을 때 만들어진 package.xml과 CMakeLists.txt 파일을 수정하여 빌드 관련 내용들을 수정해 보겠습니다. 이 파일들을 열면 주석이 대부분을 차지하고 있으며 어떤 식으로 각각의 파일을 수정해야 하는지에 대해 안내되어 있습니다. package.xml 파일에는 패키지 자체에 관련된 정보가 기입되어 있습니다. 패키지 이름, 버전, 간략한 설명, 작성자 연락처, 라이선스, 빌드 tool 의존성 등에 대한 정보가 들어 있습니다. ROS는 오픈소스를 지향하기 때문에 이러한 정해진 형식이 공유 과정에 있어 중요합니다. 이를 통해 패키지 간의 호환성 확보와 간편한 적용이 가능해집니다.


package-xml.png

package.xml 작성 예시. 파란 텍스트는 전부 주석입니다.


 CMakeLists.txt 파일에는 패키지 빌드와 catkin에 관련된 설정 정보가 포함되어 있습니다. catkin 버전, file include 경로, 노드 리스트, 라이브러리 의존성 등이 작성되어 있습니다. 아래의 예시에서는 순서대로 cmake 버전, 프로젝트 이름, 의존 패키지 목록, 포함 디렉토리, 노드 추가 순으로 작성하였습니다. 노드 추가는 앞에서 작성한 publisher와 subscriber 노드를 각각 추가하였습니다. add_executable은 노드를 rosrun이나 roslaunch를 이용해 실제로 실행시킬 때 사용하는 실행 파일의 이름과 소스 파일을 지정합니다. 실행 파일 이름은 각각 pub_node와 sub_node로 지정하였습니다. target_link_libraries와 add_dependencies는 기본적인 내용대로 작성하였습니다.


 package.xml과 CMakeLists.txt 파일을 모두 작성하고 난 다음에는 $ cm 또는 ~catkin_ws/src 경로에서 $ catkin_make를 통해 작성한 노드를 build합니다. 빌드가 끝나면 ~catkin_ws/devel/lib/nodetest 경로에 pub_node와 sub_node 두 실행 파일이 생성된 것을 확인하실 수 있습니다.


build.png

CMakeLists.txt 작성 예시와 빌드를 수행한 결과



executables.png

생성된 실행 파일


 빌드가 성공적으로 끝나면 노드를 실행시켜 정상 작동하는지 확인합니다.

$ roscore                                      -> ROS master node 실행

$ rosrun nodetest pub_node       -> publisher node 실행

$ rosrun nodetest sub_node        -> subscriber node 실행

$ rosrun rqt_graph rqt_graph      -> rqt_graph node 실행(노드 관계 도식화)


`rqt-graph.jpg

노드 실행 결과


 위 스크린샷에서 왼쪽의 publisher 노드는 0부터 1씩 증가하는 값을 ASCII로 발행하고, 오른쪽의 subscriber 노드는 그 값을 10진수로 표현하고 있습니다. INFO 옆의 시간을 보면 메시지 발행과 구독이 0.2초마다 이루어지는 것을 확인할 수 있습니다. rqt_graph를 통해 노드를 작성할 때 정했던 노드명인 'name_of_pub_node'와 'name_of_sub_node', 토픽명 'name_of_topic', 그리고 노드와 메시지의 전달 관계를 그림으로 확인할 수 있습니다.


 지금까지 간단한 노드 작성 예시를 통해 어떤 식으로 노드를 작성하고 관련 설정 파일을 만드는지 알아보았습니다. 다음에는 ROS의 모니터링 도구인 rqt를 이용해 메시지 데이터를 기록하고 표시하는 방법에 대해 정리하도록 하겠습니다.


  1. ROS(Robot Operating System) 개념과 활용 - 11. rosserial 알아보기

    ROS가 적용되는 시스템에선 연산을 위한 상위 제어기와 하드웨어 제어를 위한 하위 제어기가 각각의 역할을 수행하는 경우가 많습니다. 상위 제어기는 보통 PC나 OBC(One Board Computer)를 사용하게 되는데, 하위 제어기와 통신할 때 가장 흔하게 사용되는 ...
    Date2016.03.28 CategoryROS(Robot Operating System) 개념과 활용 By박정현 Views7544
    Read More
  2. ROS(Robot Operating System) 개념과 활용 - 10. CMakeLists.txt 파헤치기

    CMakeLists.txt는 빌드 설정에 관련된 매우 중요한 파일이지만 주석의 압박과 익숙하지 않은 사용법 때문에 매번 대충 작성했던 경험이 있습니다. 관련 가이드를 찾아 보니 생각보다 간단한 규칙으로 되어 있어서 다른 내용을 진행하기 전에 미리 짚고 넘어가...
    Date2016.03.05 CategoryROS(Robot Operating System) 개념과 활용 By박정현 Views8442
    Read More
  3. ROS(Robot Operating System) 개념과 활용 - 9. Dynamic reconfigure를 이용한 실시간 node parameter 업데이트

    오랜만의 ROS 강좌 업데이트입니다. 거의 반년 전 쯤에 해 보았던 내용이지만 이런 저런 바쁜 일들에 밀려 이제서야 업데이트를 하게 되었습니다. 본 코너인 ROS 개념과 활용에서는 나머지 기본적인 내용들을 다루고 최종적으로 간단한 제어 예제까지 수행할 ...
    Date2016.02.24 CategoryROS(Robot Operating System) 개념과 활용 By박정현 Views3858
    Read More
  4. 밸런싱 로봇 만들기 - 2. I2C로 IMU(MPU 6050)와 통신하기

    이번 포스팅은 밸런싱 로봇에서 사용하는 유일한 센서인 IMU(Inertial Measurement Unit) - MPU6050과의 통신에 대한 것입니다. 준비물 : 앞의 포스팅에서 만든 하드웨어, 컴퓨터와 UART통신을 하기 위한 UART통신모듈(테스트용), CodeVision AVR 센서와 통신...
    Date2015.08.16 Category밸런싱 로봇 By한종인 Views4093
    Read More
  5. ROS(Robot Operating System) 개념과 활용 - 8. roslaunch 사용과 launch 파일 작성하기

    저번에 USB 카메라를 이용하면서 usb_cam-test.launch 파일을 실행시켜 보았습니다. usb_cam-test.launch 파일을 실행시키면 USB 카메라와 직접적으로 상호작용하는 '/usb_cam' 노드와 '/usb_cam/image_raw' 토픽을 받아 화면에 출력하는 '/image_view' 노드...
    Date2015.08.13 CategoryROS(Robot Operating System) 개념과 활용 By박정현 Views17590
    Read More
  6. ROS(Robot Operating System) 개념과 활용 - 7. USB 카메라 사용하기

    ROS는 여러 가지 이미지 관련 패키지를 제공하고 있습니다. 특히 OpenCV 연동 기능을 제공하기 때문에 다양한 영상 처리 알고리즘을 적용할 수 있다는 장점이 있습니다. 이미지와 영상을 얻기 위해서는 이미지를 얻는 센서가 필요한데, ROS가 주로 PC나 SBC ...
    Date2015.08.09 CategoryROS(Robot Operating System) 개념과 활용 By박정현 Views6788
    Read More
  7. ROS(Robot Operating System) 개념과 활용 - 6. rqt를 이용한 데이터 모니터링

    ROS는 로봇으로부터 얻을 수 있는 데이터를 쉽게 확인하고 관리할 수 있도록 rqt라고 하는 모니터링 도구를 제공합니다. rqt는 GUI 개발에 쓰이는 Qt framework 기반의 ROS software framework입니다. rqt는 우리가 지금까지 노드간 관계를 확인할 때 써 오던...
    Date2015.08.08 CategoryROS(Robot Operating System) 개념과 활용 By박정현 Views7066
    Read More
  8. ROS(Robot Operating System) 개념과 활용 - 5. 바닥부터 node 작성하기

    지금까지는 기존에 있던 패키지 노드를 수정하여 사용해 왔습니다. 이번에는 노드를 아예 처음부터 새로 작성하는 법에 대해 알아보겠습니다. 또한 노드 내부에서 사용되는 ROS의 기본 구조에 대해서도 간략히 짚고 넘어가도록 하겠습니다. 노드 작성법을 간...
    Date2015.07.26 CategoryROS(Robot Operating System) 개념과 활용 By박정현 Views33278
    Read More
  9. ROS(Robot Operating System) 개념과 활용 - 4. ROS node를 이용하여 direct serial 통신하기

    ROS 노드들은 TCP/IP 프로토콜의 메시지 통신을 기반으로 데이터를 주고 받습니다. 하지만 대다수의 센서들과 MCU의 통신은 일반적인 serial 프로토콜을 이용해 통신을 하는 경우가 많습니다. 여러 용도로 편리하게 사용되는 UART 통신 또한 그러한 방식입니...
    Date2015.07.07 CategoryROS(Robot Operating System) 개념과 활용 By박정현 Views10415
    Read More
  10. 밸런싱 로봇 만들기 - 1. 하드웨어 구성

    안녕하세요? 오늘부터 "밸런싱로봇 만들기"를 포스팅할 P.M.한종인 입니다. 밸런싱 로봇 하드웨어를 제작하기 위해서는 다음과 같은 몇 가지 준비물이 필요합니다. 준비물 : 부품, 회로도, 인두, 땜납, 테프론 래핑 와이어(얇은 배선용 전선), 일반전선, 멀티...
    Date2015.07.03 Category밸런싱 로봇 By한종인 Views2694
    Read More
Board Pagination Prev 1 2 Next
/ 2