.. Cover Letter

공부#Robotics#자율주행/(ROS2) 기초

(ROS2 기초)9. Python과 C++ 패키지 설계부터 토픽, 서비스, 액션, 파라미터로 코딩하기 (문제 파트)

BrainKimDu 2023. 5. 12. 18:18

참고도서 1. ROS 2로 시작하는 로봇 프로그래밍. 표윤석 .  루비페이퍼 . 2021 
참고도서 2. ROS2 혼자공부하는 로봇SW 직접 만들고 코딩하자 . 민형기 .  잇플 . 2022
참고자료 1. PinkWink(민형기)님의 ROS2 강의자료
참고자료 2. ROS2 humble documeation

ROS2를 복습하는 김에 제대로 다시 한 번 정리하고 넘어가고 싶어서 이 시리즈를 작성합니다. 
이 글은 Turtlebot3 패키지를 제대로 이해하고, 다양한 센서를 부착하면서 활용하는 것을 목표로 합니다.
또한 글이 끝날 때 ROS와 관련된 문제를 하나 만들어서 직접 풀어보도록 합니다.
이번 시간은 호흡이 엄청 길어질 예정입니다.  이번 글은 표윤석 님의 ROS2로 시작하는 로봇 프로그래밍의 내용을 주로 참고하여 작성됩니다.


ROS2 패키지 설계하기 문제

ROS를 활용해서 로봇을 프로그래밍할 때는 프로세스를 목적별로 나누어 노드 단위의 프로그램으로 작성하고 노드와 노드 간의 데이터 통신을 고려하여 설계를 해야합니다. 앞서 배운 토픽, 서비스, 액션을 사용하게 됩니다. 
표윤석님의 책에서는 계산기를 ROS상에서 구현해보는 것으로 접근을 하고 있습니다.  이번 시간에는 이  패키지를 뜯어보면서 python에서 ROS2 패키지를 어떻게 설계하게 되는지를 알아봅시다.
 
그러면 설계의 첫 번째 단계인 고객의 요구사항을 수용하는 방향으로 가도록합시다.
요구사항 : 계산기를 만들려고 합니다. argument노드는 현재 시간과 변수 a, b를 topic으로 발행합니다. 그러면 calculator노드는 operator노드에게 연산자를 보내면 argument노드의 a와 b와 carculator에서 받은 연산자의 결과를 calculator에게 보냅니다. 
그러면 calculator노드는 이 결과값을 checker노드에게 전달하고 checker노드는 이 연산 결과값을 누적합니다. 그러다가 연산의 결과값이 목표치에 도달했을 때 이 결과값을 calculator 노드에게 보냅니다. 이 과정에서 피드백으로 연산식을 보내게 됩니다.
문제가 글로 표현하려니 조금 이상하니까 그림을 그려봅시다.

대충 이런 느낌으로 이해를 해봅시다. 
 
간단하게 이 문제를 로봇이라 생각을 해봅시다.
A노드는 camera 라고 할 때 현재 시간의 전방(a)와 후방(b)의 영상정보를 topic으로 발행하고 있는 상태입니다.
그러면 B노드는 이 영상정보를 계속 받고 있지만, 차선인식(segmentation)을 해야할지 사람을 탐지(object detection)을 해야할지 아직 정해지지 않았습니다. main에서 지금 영상에서 사람을 탐지한 결과를 달라고 요청을 합니다. 그러면 B노드는 사람을 탐지한 결과를 main노드에게 보내주고 main은 이 정보를 C노드에 보냅니다.
C노드는 데이터 베이스 역할을 하고 있습니다. 저장이 완료될 경우 이를 main노드에게 알립니다. 용량의 제한이 있기 때문에 임계값이상으로 쌓이는 경우 main에게 이를 알리게 됩니다.
이렇게 설명하면 조금 편하군요... 
 
그러면 저희는 살짝 변형을 해서 로봇의 카메라 예제라 생각하고 접근을 하도록 합시다. 
우선 문제를 보면서 어떻게 노드를 분할해야할지 알아봅시다. 이미 노드가 분할되어 있지만 어떠한 이유로 분할이 되었나에 초점을 맞춰봅시다.
A노드는 camera 라고 할 때 현재 시간의 전방(a)와 후방(b)의 영상정보를 topic으로 발행하고 있는 상태입니다.
A노드는 camera 라고 이름을 짓고, 하는 일만 본다면 camera에서 얻은 영상정보를 topic으로 발행하고 있는 상태입니다. 그 외의 일은 맡고 있지 않습니다. 이게 하나의 노드 단위입니다. 카메라 역할에만 충실한 상태이기 때문이죠.
그러면 B노드는 이 영상정보를 계속 받고 있지만, 차선인식(segmentation)을 해야할지 사람을 탐지(object detection)을 해야할지 아직 정해지지 않았습니다. main에서 지금 영상에서 사람을 탐지한 결과를 달라고 요청을 합니다. 그러면 B노드는 사람을 탐지한 결과를 main노드에게 보내주고 main은 이 정보를 C노드에 보냅니다.
B노드는 image_processing 라고 이름을 짓고, 하는 일은 image processing에 관련된 일만 진행합니다. 사실 토픽이 맞을지 service가 맞을지는 애매합니다. 사실 로봇에서는 차선인식을 하고 topic으로 발행하고, 사람을 탐지하고 topic으로 발행해주어야 하기 때문에 2개의 노드가 되고 각각 토픽을 발행하는 상황이여야 좋습니다. 
그러나 이 문제는 패키지 설계의 이해를 돕기 위함이니 그렇다 생각하고 넘어가도록 하겠습니다.

 
C노드는 데이터 베이스 역할을 하고 있습니다. 저장이 완료될 경우 이를 main노드에게 알립니다. 용량의 제한이 있기 때문에 임계값이상으로 쌓이는 경우 main에게 이를 알리게 됩니다.
C노드는 database로 이름을 짓고 데이터를 저장하는 역할을 하는 노드입니다. 실제 로봇에서는 인터넷과 통신을 하면서 서버로 정보를 보내게 될 것입니다. 
 
 
그러면 설계의 첫 번째 단계인 고객의 요구사항을 수용하는 방향으로 가도록합시다.
요구사항 : 계산기를 만들려고 합니다. A노드는 현재 시간과 변수 a, b를 topic으로 발행합니다. 그러면 main 노드는 이를 B노드에게 연산자를 보내면 A노드의 a와 b와 main에서 받은 연산자의 결과를 main에게 보냅니다. 
그러면 main노드는 이 결과값을 C노드에게 전달하고 C노드는 이 연산 결과값을 누적합니다. 그러다가 연산의 결과값이 목표치에 도달했을 때 이 결과값을 main 노드에게 보냅니다. 이 과정에서 피드백으로 연산식을 보내게 됩니다.
여튼 다시 이 부분으로 돌아와서

이제 이 패키지들을 삭제해주어도 좋습니다. 삭제하고 표윤석님의 코드를 가져오도록 합시다. 삭제하게 되는 경우 ros_study 부분에 있는 src폴더를 제외하고는 삭제를 해주시는 것이 좋습니다.
 
 
참고로 이 코드의 저작권은 오픈로보틱스 카페 및 표윤석님에게 있습니다. 
https://cafe.naver.com/openrt

오픈소스 소프트웨어 & 하드웨어: 로... : 네이버 카페

오픈소스 소프트웨어/하드웨어로 만드는 로봇 기술 공유 카페 (ROS,ARM,AVR,mbed,라즈베리파이,아두이노)

cafe.naver.com

(저는 블로그 수익창출 활동을 하고 있지 않으며, 이는 개인포토폴리오용 블로그입니다.  문제가 된다면 삭제하겠습니다.)
표윤석님의 코드를 내려받아서 패키지를 뜯어보는 방식으로 진행을 하도록 하겠습니다. 

git clone https://github.com/robotpilot/ros2-seminar-examples.git

여기서 우리가 사용할 패키지는 topic service action rclpy example 패키지입니다. 이 패키지와 interface  패키지를 제외하고는 빌드에 오랜 시간이 걸리니 삭제하도록 합시다.

이렇게 만든 후에 진행을 하도록 하겠습니다. 우선 colcon build를 하며 버전 충돌이 없는지 확인합니다.

딱히 문제는 없습니다. 나중에 주행로봇을 하게될 경우, 다른 사람의 패키지를 들고 올 때 rosdep을 사용하여 의존성을 해결할 수 있습니다, 이건 나중 이야기입니다. 혹시 모르니 ros_study 폴더 에서 rosdep으로 의존성을 체크하도록 합시다.

rosdep install --from-paths src --ignore-src -r -y

문제가 없다면 다음처럼 나올 것이고, 문제가 있다면 알아서 다운로드를 시작할 것입니다. 이제 humble 환경을 불러오고 빌드 후에 진행을 해보도록 합시다.
 
먼저 A노드를 실행해서 변수를 보내도록 합시다. 그 전에 꼭 패키지 환경을 불러올 수 있도록 합니다. 

다음처럼 분명히 패키지를 찾을 수 있는데, 찾지 못한다면 패키지 환경을 불러오지 않은 것입니다.

ros2 run topic_service_action_rclpy_example calculator

이 노드는 일종의 main 노드 같은 느낌입니다. 이 노드는 토픽 구독, 서비스 서버, 액션 서버 역할을 수행합니다. 그러면 topic을 발행하는 역할을 하는 노드를 실행시킵시다. argument노드입니다. 

ros2 run topic_service_action_rclpy_example argument

토픽을 발행하면 calculator 노드에서 토픽이 발견되었음을 알리고 argument는 변수 a, b를 topic의 형태로 발행합니다. 이 상태로 서비스 클라이언트를 실행합니다.

ros2 run topic_service_action_rclpy_example operator

다음처럼 계산결과를 리턴합니다. 이 때 연산자와 결과값이 calculator에서 표시됩니다.

그 다음에는 액션 노드를 실행합시다 checker입니다.

ros2 run topic_service_action_rclpy_example checker

누적된 연산 결과값이 전달받은 액션 목푯값보다 커지면 결괏값으로 누적된 연산 결괏값과 진행된 연산식 모두를 보냅니다.
다음처럼 파라미터를 변경해서 누적되는 한계치를 조절할 수 있습니다.

ros2 run topic_service_action_rclpy_example checker -g 100

 
다음은 런치파일입니다. 

ros2 launch topic_service_action_rclpy_example arithmetic.launch.py

이를 한 번에 실행하는 방법으로 launch 파일에 대한 이야기는 패키지 설계 파트가 마무리된 후에 진행하도록 하겠습니다.
 
이 문제를 풀어낼 예정입니다. 내일 일정으로 인해 오늘은 패키지가 어떻게 동작하는지만 살펴봤습니다. 이제 이 코드를 C++의 입장으로 혹은 Python의 입장으로 하나씩 뜯어볼 예정입니다.  그렇게 하면서 작업공간을 별도로 만들어서 작업을 따라 진행하도록 하겠습니다.
 
다음 글은 파이썬에 대한 설명이고, 그 다음 글은 C++에 대한 설명입니다. 아마 이번 주말은 바빠서 글을 못올릴 것 같고, 월요일 화요일 쯤 글이 올라갈 것으로 생각됩니다.
그리고 그 다음주 까지 휴가입니다.



어.. 이 글 이후로 더 이상 연재는 없을 것입니다.

-2023 12 27