조건 노드의 디버깅 기법 (Condition Node Debugging Techniques)
1. 개요
조건 노드의 디버깅은 조건 평가의 결과가 기대와 다른 경우, 그 원인을 체계적으로 추적하고 식별하는 과정이다. 행동 트리에서 조건 노드의 잘못된 평가는 전체 행동 흐름에 영향을 미치므로, 효과적인 디버깅 기법의 활용이 필수적이다. 본 절에서는 로깅, 시각화, 입력 추적, 단계별 실행 등의 디버깅 기법을 다룬다.
2. 디버깅 기법의 분류
| 기법 | 설명 | 도구 |
|---|---|---|
| 조건 평가 결과 로깅 | 각 tick에서의 반환 상태 기록 | ROS2 로거, BT 로거 |
| 입력 값 추적 | 블랙보드/토픽 입력 값 기록 | 커스텀 로깅 |
| 행동 트리 시각화 | 트리의 실시간 상태 표시 | Groot, rqt 플러그인 |
| 단계별 실행 | tick을 수동으로 제어 | 디버그 모드 |
| 로그 파일 분석 | 기록된 로그의 사후 분석 | BT 로그 파일 |
3. BehaviorTree.CPP의 내장 로깅
3.1 TreeObserver 활용
BehaviorTree.CPP 4.x에서는 TreeObserver를 등록하여 모든 노드의 상태 전환을 감시할 수 있다.
BT::TreeObserver observer(tree);
// 노드 상태 변경 콜백
observer.enableTransitionToIdle(false);
tree.tickWhileRunning();
// 특정 노드의 통계 조회
auto stats = observer.getStatistics("IsObstacleDetected");
std::cout << "SUCCESS 횟수: " << stats.success_count << std::endl;
std::cout << "FAILURE 횟수: " << stats.failure_count << std::endl;
3.2 FileLogger2를 통한 로그 파일 생성
BT::FileLogger2 logger(tree, "bt_trace.btlog");
tree.tickWhileRunning();
// 로그 파일은 Groot2에서 재생하여 시각적으로 분석 가능
4. ROS2 로거를 활용한 조건 디버깅
4.1 tick() 메서드 내 로깅
BT::NodeStatus tick() override
{
auto msg = getLastMessage();
if (!msg)
{
RCLCPP_DEBUG(node_->get_logger(),
"[%s] No message received → FAILURE", name().c_str());
return BT::NodeStatus::FAILURE;
}
double value = extractValue(msg);
double threshold;
getInput("threshold", threshold);
bool result = (value > threshold);
RCLCPP_DEBUG(node_->get_logger(),
"[%s] value=%.3f, threshold=%.3f → %s",
name().c_str(), value, threshold,
result ? "SUCCESS" : "FAILURE");
return result ? BT::NodeStatus::SUCCESS
: BT::NodeStatus::FAILURE;
}
ROS2의 로그 수준을 DEBUG로 설정하면 상세한 조건 평가 과정을 확인할 수 있다.
ros2 run my_package my_node --ros-args --log-level debug
5. Groot2를 활용한 시각적 디버깅
Groot2는 BehaviorTree.CPP의 공식 시각화 도구로, 행동 트리의 실시간 상태를 그래픽으로 표시한다.
5.1 실시간 모니터링
// ZMQ 퍼블리셔 설정 (Groot2와의 통신)
BT::PublisherZMQ publisher(tree, 25, 1666, 1667);
tree.tickWhileRunning();
Groot2에서 각 노드의 현재 상태(SUCCESS/FAILURE/RUNNING/IDLE)가 색상으로 표시되며, 조건 노드의 상태 변화를 실시간으로 관찰할 수 있다.
5.2 로그 파일 재생
FileLogger2로 기록된 로그 파일을 Groot2에서 재생하여, 과거 시점의 조건 평가 과정을 단계별로 분석할 수 있다.
6. 일반적인 디버깅 시나리오
6.1 시나리오 1: 조건이 항상 FAILURE를 반환
가능한 원인:
- 토픽 메시지가 수신되지 않음 (QoS 불일치, 토픽 이름 오류)
- 임계값이 도달 불가능한 값으로 설정됨
- 블랙보드 키 이름 오류
디버깅 절차:
ros2 topic echo명령으로 토픽 발행 확인ros2 topic info명령으로 QoS 호환성 확인- 조건 노드 내부에 로깅을 추가하여 메시지 수신 여부 확인
- 블랙보드 값이 올바르게 설정되었는지 확인
6.2 시나리오 2: 조건이 예상과 다른 시점에서 전환
가능한 원인:
- 센서 잡음에 의한 조건 진동
- 타임스탬프 동기화 문제
- 히스테리시스 미적용
디버깅 절차:
- 조건 입력 값을 시계열로 로깅하여 변동 패턴 분석
- 메시지 타임스탬프와 현재 시각의 차이 확인
- 히스테리시스 대역의 적절성 검토
6.3 시나리오 3: 조건 노드가 행동 트리 성능을 저하
가능한 원인:
- 서비스 호출의 차단 지연
- 대용량 메시지 처리
- 캐싱 미적용
디버깅 절차:
tick()메서드의 실행 시간 측정- 서비스 응답 시간 확인
- 캐싱 전략 적용 검토
7. 설계 시 고려 사항
7.1 프로덕션 환경에서의 로깅 수준
디버그 로깅은 개발 및 테스트 단계에서만 활성화하고, 프로덕션 환경에서는 WARN 수준 이상만 활성화하여 로깅 오버헤드를 최소화한다.
7.2 로그 데이터의 분량
매 tick마다 모든 조건 노드의 입출력을 로깅하면 대량의 로그 데이터가 생성된다. 디스크 공간과 I/O 부하를 고려하여 로깅 범위를 제한하거나, 조건부 로깅(상태 전환 시에만 로깅)을 적용한다.
8. 참고 문헌
- Colledanchise, M., & Ogren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
- BehaviorTree.CPP 공식 문서. https://www.behaviortree.dev/
- Groot2 공식 문서. https://www.behaviortree.dev/groot
| 버전 | 날짜 | 변경 사항 |
|---|---|---|
| v0.1 | 2026-04-04 | 초안 작성 |