데코레이터 노드의 디버깅 기법 (Debugging Techniques for Decorator Nodes)
1. 개요
데코레이터 노드의 디버깅은 데코레이터의 상태 변환, 카운터 동작, 타이밍 동작, halt 전파 등이 기대대로 수행되는지를 추적하고 확인하는 과정이다. 데코레이터는 자식의 동작을 수정하므로, 행동 트리의 전체 흐름에서 데코레이터의 영향을 정확히 파악하는 것이 중요하다.
2. 디버깅 기법
2.1 Groot2를 활용한 시각적 디버깅
Groot2에서 각 데코레이터 노드의 실시간 상태(IDLE, RUNNING, SUCCESS, FAILURE)를 색상으로 확인한다. 데코레이터가 자식의 상태를 어떻게 변환하는지를 시각적으로 추적한다.
2.2 TreeObserver를 활용한 통계 수집
BT::TreeObserver observer(tree);
tree.tickWhileRunning();
auto stats = observer.getStatistics("MyRetryNode");
std::cout << "SUCCESS: " << stats.success_count
<< " FAILURE: " << stats.failure_count << std::endl;
2.3 로깅 데코레이터 삽입
디버깅이 필요한 데코레이터 주변에 로깅 데코레이터를 삽입한다.
<Log>
<RetryNode num_attempts="3">
<Log>
<Action ID="ConnectToSensor"/>
</Log>
</RetryNode>
</Log>
외부 Log는 Retry의 최종 결과를, 내부 Log는 각 재시도의 결과를 기록한다.
2.4 FileLogger2를 활용한 로그 파일 분석
BT::FileLogger2 logger(tree, "debug_trace.btlog");
기록된 로그를 Groot2에서 재생하여 데코레이터의 동작을 단계별로 분석한다.
3. 일반적 디버깅 시나리오
3.1 Retry가 즉시 종료
증상: Retry가 한 번도 재시도하지 않고 바로 성공/실패.
원인: 자식이 FAILURE가 아닌 SUCCESS를 반환.
해결: 자식의 실제 반환 상태를 로깅으로 확인.
3.2 Timeout이 너무 빨리 만료
증상: 자식이 충분히 빠르게 실행되는데도 Timeout이 발생.
원인: msec 단위/초 단위 혼동, 시뮬레이션 시간 불일치.
해결: 타이밍 로그로 실제 경과 시간 확인.
3.3 Repeat가 무한 반복
증상: Repeat가 종료되지 않음.
원인: num_cycles=-1 설정, ForceSuccess에 의해 FAILURE가 차단됨.
해결: num_cycles 값 확인, ForceSuccess 제거 후 테스트.
4. 참고 문헌
- BehaviorTree.CPP 공식 문서. https://www.behaviortree.dev/
- Groot2 공식 문서. https://www.behaviortree.dev/groot
| 버전 | 날짜 | 변경 사항 |
|---|---|---|
| v0.1 | 2026-04-05 | 초안 작성 |