타이머 콜백
0.5초마다 일하려면 while과 sleep을 쓰면 될까?
while은 곤란
직접 돌리면 spin이 못 돕니다
main에서 while True:와 time.sleep()으로 직접 돌리면, 프로그램이 그 안에 갇혀 rclpy.spin()에 닿지 못합니다. 그러면 메시지가 와도 콜백을 불러 줄 실행기가 돌지 않습니다.
work는 예시로 붙인 메서드 이름입니다.
create_timer
주기와 콜백을 맡겨 둡니다
노드의 create_timer(주기, 콜백)은 타이머를 만들어 실행기에 맡깁니다. 주기는 초 단위입니다. 이 줄은 기다리지 않고 바로 다음 줄로 넘어가고, 콜백은 spin이 돌 때 불립니다.
만든 타이머는 self.timer처럼 노드에 붙여 둡니다. 멈추려면 self.timer.cancel()을 부릅니다.
시간 축
0.5초마다 실행기가 불러 줍니다
타이머 시각이 될 때마다 실행기가 timer_callback을 부릅니다. 콜백이 끝나면 다시 기다립니다. 첫 호출은 타이머를 만든 즉시가 아니라 한 주기가 지난 뒤입니다.
전체 코드
숫자를 세는 Counter 노드
생성자에서 카운터와 타이머를 만들고, 콜백에서 숫자를 로그로 남긴 뒤 하나 올립니다. 숫자는 self.i에 있으니 콜백이 불릴 때마다 이어서 셉니다.
맨 위 import 두 줄은 1편과 같고, main은 2편과 같되 HelloNode() 자리에 Counter()를 씁니다.
따라 하기
이번에는 계속 살아 있습니다
setup.py에 counter 명령을 더하고 빌드한 뒤 ros2 run my_package counter를 실행합니다. 0.5초마다 한 줄씩 찍힙니다. 다른 터미널의 ros2 node list에도 /counter가 계속 보입니다.
실제 출력의 시각 부분은 줄였습니다. 끝낼 때는 Ctrl+C를 누릅니다.
콜백은 짧게
콜백이 길면 박자가 밀립니다
콜백이 주기보다 오래 걸리면 다음 호출이 늦어집니다. 실행기는 콜백을 하나씩 부르니(3편), 앞 콜백이 끝나야 다음 타이머 콜백도 불립니다. 콜백 안에서는 짧은 일만 합니다.
그림의 0.8초는 예시입니다.
다음 편