1293.79 Tick 실행 흐름의 시각화

1. 실행 흐름 시각화의 목적

행동 트리의 Tick 실행 흐름 시각화란, Tick 전파 경로, 노드 상태, 반환 값 등의 실행 정보를 그래픽 형태로 표현하는 것이다. 시각화는 복잡한 트리의 동작을 직관적으로 이해하고, 비정상적 실행 경로나 성능 병목을 신속히 식별하기 위한 핵심적 도구이다. BehaviorTree.CPP 생태계에서는 Groot2가 표준 시각화 도구로 사용된다(Faconti, 2022).

2. Groot2를 이용한 시각화

2.1 실시간 시각화

Groot2는 ZeroMQ 기반의 퍼블리셔를 통해 실행 중인 행동 트리의 상태를 실시간으로 수신하고 시각화한다.

// ZMQ 퍼블리셔 연결
BT::PublisherZMQ publisher(tree, 25, 1666, 1667);

// 또는 Groot2Monitor 사용 (BT.CPP v4)
BT::Groot2Publisher groot_publisher(tree, 1667);

Groot2는 트리 구조를 그래프로 표시하고, 각 노드의 현재 상태를 색상으로 구분한다.

노드 상태색상의미
IDLE회색비활성
RUNNING주황색실행 중
SUCCESS녹색성공
FAILURE적색실패

2.2 로그 재생(Replay)

FileLogger2로 기록된 로그 파일을 Groot2에서 재생하여, 과거의 Tick 실행 흐름을 시각적으로 분석할 수 있다. 재생 시 Tick 단위로 전진/후진하며 각 시점의 트리 상태를 확인한다.

// 로그 기록
BT::FileLogger2 file_logger(tree, "execution_log.btlog");

// Groot2에서 "execution_log.btlog" 파일 열기로 재생

3. Chrome Tracing 시각화

MinitraceLogger를 사용하면 Chrome Tracing 형식의 JSON 파일을 생성하여, 각 노드의 실행 시간을 타임라인으로 시각화할 수 있다.

BT::MinitraceLogger minitrace(tree, "trace.json");

// 트리 실행 후
// 크롬 브라우저에서 chrome://tracing 접속
// trace.json 파일 로드

Chrome Tracing 시각화는 각 노드의 실행이 시간축 위에 막대로 표시되어, 노드 간의 시간적 관계와 실행 시간 분포를 직관적으로 파악할 수 있다.

4. 텍스트 기반 시각화

그래픽 도구가 없는 환경(원격 서버, 임베디드 시스템 등)에서는 텍스트 기반으로 트리 상태를 시각화한다.

void printTreeStatus(const BT::Tree& tree) {
    std::function<void(const BT::TreeNode*, int)> printNode;
    printNode = [&](const%20BT::TreeNode*%20node,%20int%20depth) {
        std::string indent(depth * 2, ' ');
        std::string status_str = BT::toStr(node->status());
        char marker = ' ';
        if (node->status() == BT::NodeStatus::RUNNING) marker = '>';
        if (node->status() == BT::NodeStatus::SUCCESS) marker = '+';
        if (node->status() == BT::NodeStatus::FAILURE) marker = 'x';
        
        printf("%s%c %s [%s]\n", 
               indent.c_str(), marker, 
               node->name().c_str(), 
               status_str.c_str());
        
        if (auto control = dynamic_cast<const BT::ControlNode*>(node)) {
            for (size_t i = 0; i < control->childrenCount(); ++i) {
                printNode(control->child(i), depth + 1);
            }
        }
    };
    
    printNode(tree.rootNode(), 0);
}

출력 예시:

> MainSequence [RUNNING]
  + IsBatteryAbove [SUCCESS]
  + IsLocalized [SUCCESS]
  > NavigateToGoal [RUNNING]
    RecoveryFallback [IDLE]
      ComputePath [IDLE]
      ClearCostmap [IDLE]

5. ROS2 토픽을 통한 시각화 데이터 발행

트리 상태를 ROS2 토픽으로 발행하여, RViz2나 사용자 정의 시각화 도구에서 수신할 수 있다.

void publishTreeState() {
    auto msg = bt_interfaces::msg::TreeState();
    msg.header.stamp = node_->now();
    msg.tick_number = tick_count_;
    
    for (const auto& node : tree_.nodes()) {
        bt_interfaces::msg::NodeState ns;
        ns.name = node->name();
        ns.status = statusToString(node->status());
        ns.type = node->registrationName();
        msg.nodes.push_back(ns);
    }
    
    tree_state_pub_->publish(msg);
}

6. Tick 전파 경로의 시각화

단일 Tick에서의 전파 경로를 화살표나 하이라이트로 표시하면, Tick이 트리를 어떻게 순회했는지를 시각적으로 추적할 수 있다.

Tick #142 전파 경로:
  Root ──→ Sequence ──→ Condition_A ──→ Condition_B ──→ Action_1
                                                          ↑
                                                    RUNNING (멈춤)

이 시각화는 어떤 노드에서 Tick 전파가 멈추었는지, 어떤 분기가 선택되었는지를 즉시 파악할 수 있게 한다.

7. 시각화 도구의 비교

도구실시간재생시간 프로파일링환경 요구
Groot2지원지원제한적GUI 환경
Chrome Tracing미지원지원상세브라우저
텍스트 출력지원제한적미지원터미널
ROS2 토픽 + RViz2지원미지원미지원ROS2 환경

8. 시각화의 성능 영향

시각화 데이터의 생성과 전송은 Tick 실행 시간에 영향을 미칠 수 있다. ZMQ 퍼블리싱은 통상 수백 마이크로초의 오버헤드를 가지며, 파일 로깅은 이보다 적은 오버헤드를 가진다. 성능에 민감한 운영 환경에서는 시각화를 비활성화하거나 샘플링 간격을 조정하여 오버헤드를 줄인다.


참고 문헌

  • Colledanchise, M., & Ogren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
  • Faconti, D. (2022). BehaviorTree.CPP documentation and API reference. https://www.behaviortree.dev/