Node 상속

기능이 늘어나면 노드 코드는 어디에 두어야 할까?

함수만 쓰면

콜백마다 global이 늘어납니다

타이머, 퍼블리셔, 카운터처럼 노드가 쥐고 있어야 할 것이 늘어납니다. 함수로만 짜면 콜백 함수들이 그 값을 나눠 쓰려고 전역 변수에 기대게 됩니다. 노드가 둘만 되어도 서로 섞입니다.

on_timer는 예시로 붙인 콜백 이름입니다. 콜백은 3편, 타이머는 4편에서 봅니다.

상속

Node를 물려받은 내 클래스

class HelloNode(Node):라고 쓰면 HelloNode가 rclpy의 Node를 상속(inheritance)합니다. 퍼블리셔 만들기, 타이머 만들기, 로그 남기기 같은 기능은 그대로 물려받고, 내 값과 콜백만 더하면 됩니다.

생성자

super()에서 이름을 정합니다

생성자 __init__의 첫 줄은 super().__init__('hello')입니다. 부모인 Node를 먼저 준비시키면서 노드 이름을 넘깁니다. 그다음부터 self는 노드 자신이라서, self.get_logger()처럼 물려받은 기능을 바로 씁니다.

self

값은 모두 self에 담습니다

노드가 쥐고 있어야 할 값과 부품은 self.count, self.timer처럼 노드 자신에 붙여 둡니다. 콜백 메서드는 self로 그 값을 읽고 바꿉니다. 전역 변수가 필요 없고, 같은 클래스로 노드를 여러 개 만들어도 값이 섞이지 않습니다.

main은 짧게

만들고, 돌리고, 끄기만

일은 모두 클래스 안에 있으니 main은 다섯 줄이면 됩니다. 1편의 세 단계 사이에 rclpy.spin(node)가 끼어 노드를 계속 살려 둡니다. 공식 튜토리얼의 talker, listener도 모두 이 모양입니다.

args=None은 실행할 때 붙인 ROS 인자를 rclpy에 넘기는 자리입니다.

앞으로의 틀

이 틀에 부품을 끼워 갑니다

생성자에서 부품을 만들고, 일이 생기면 불릴 콜백을 메서드로 둡니다. 이 강의 나머지 편은 이 틀에 타이머, 퍼블리셔, 서브스크라이버를 하나씩 끼우는 과정입니다.

callback은 자리를 보이려고 붙인 이름입니다. 실제로는 self.timer = self.create_timer(...)처럼 받아 둡니다.

다음 편

main의 rclpy.spin(node)는 무엇을 돌리고 있을까요?

3편spin은 무엇을 돌릴까? 6강 목록