1293.78 Tick 단위 Halt 이벤트 로그

1. Halt 이벤트 로그의 정의

Halt 이벤트 로그란, Tick 실행 중에 노드에 대해 halt() 또는 onHalted()가 호출된 사건을 기록한 것이다. Halt 이벤트는 실행 중인 작업의 중단을 나타내며, 조기 종료, Reactive 노드의 조건 변화, 외부 트리 종료 등에 의해 발생한다. Halt 이벤트의 로깅은 작업 취소의 원인 추적, 자원 정리의 검증, 비정상적 중단의 진단에 필수적이다(Colledanchise & Ogren, 2018).

2. Halt 이벤트의 발생 시점

Halt 이벤트는 다음의 상황에서 발생한다.

발생 상황Halt 대상트리거
Sequence 조기 종료RUNNING 상태의 후속 자식선행 자식 FAILURE
Fallback 조기 종료RUNNING 상태의 후속 자식선행 자식 SUCCESS
ReactiveSequence 조건 변화RUNNING 상태의 액션 자식조건 자식 FAILURE
ReactiveFallback 조건 변화RUNNING 상태의 액션 자식상위 대안 SUCCESS
데코레이터 타임아웃RUNNING 상태의 자식Timeout 초과
트리 종료모든 RUNNING 노드haltTree() 호출

3. Halt 이벤트 로그의 구성 요소

struct HaltLogEntry {
    int tick_id;                           // Tick 순번
    std::chrono::steady_clock::time_point timestamp;  // 시각
    std::string halted_node_name;          // Halt된 노드 이름
    std::string halted_node_type;          // 노드 유형
    BT::NodeStatus status_before_halt;     // Halt 전 상태 (RUNNING)
    std::string trigger_node_name;         // Halt를 유발한 노드
    std::string trigger_reason;            // Halt 원인
    std::chrono::microseconds running_duration;  // RUNNING 유지 시간
};

4. Halt 이벤트의 캡처

4.1 StatusChangeLogger를 통한 캡처

Halt 이벤트는 상태 전이(RUNNING → IDLE)로 나타나므로, StatusChangeLogger에서 캡처할 수 있다.

void callback(BT::Duration timestamp,
              const BT::TreeNode& node,
              BT::NodeStatus prev_status,
              BT::NodeStatus status) override {
    if (prev_status == BT::NodeStatus::RUNNING && 
        status == BT::NodeStatus::IDLE) {
        // Halt 이벤트 감지
        HaltLogEntry entry;
        entry.timestamp = std::chrono::steady_clock::now();
        entry.halted_node_name = node.name();
        entry.status_before_halt = prev_status;
        entry.tick_id = current_tick_;
        
        halt_log_.push_back(entry);
        
        RCLCPP_INFO(logger_, 
            "[Tick %d] HALT: %s (was RUNNING)",
            current_tick_, node.name().c_str());
    }
}

4.2 onHalted 내부 로깅

StatefulActionNodeonHalted() 메서드 내에서 자원 정리의 상세 내용을 기록한다.

void onHalted() override {
    RCLCPP_INFO(node_->get_logger(), 
        "NavigateToGoal halted: canceling action goal");
    
    if (goal_handle_) {
        action_client_->async_cancel_goal(goal_handle_);
        RCLCPP_INFO(node_->get_logger(), 
            "Goal cancel request sent for goal_id: %s",
            rclcpp_action::to_string(goal_handle_->get_goal_id()).c_str());
    }
}

5. Halt 전파 체인 로그

Halt가 깊이 우선 순서로 전파될 때, 전파 체인 전체를 기록하면 Halt의 영향 범위를 파악할 수 있다.

Tick #200: Halt 전파 체인
  트리거: IsBatteryAbove → FAILURE (ReactiveSequence에서)
  ├─ Halt: NavigateSubtree (서브트리)
  │   ├─ Halt: ComputePath (RUNNING → IDLE)
  │   └─ Halt: FollowPath (RUNNING → IDLE)
  └─ Halt 전파 완료 (2개 노드 중단)

6. Halt 빈도 분석

Halt 이벤트 로그를 집계하면 각 노드의 Halt 빈도를 분석할 수 있다.

f_{halt}(n) = \frac{N_{halt}(n)}{N_{running}(n)}

여기서 N_{halt}(n)은 노드 n이 Halt된 횟수, N_{running}(n)은 노드가 RUNNING 상태로 진입한 횟수이다. Halt 비율이 높은 노드는 작업이 빈번히 중단되는 것을 나타내며, 다음의 원인을 의심할 수 있다.

  • Reactive 노드의 조건이 불안정하게 진동하는 경우
  • 액션 서버가 빈번히 실패하여 재시도가 발생하는 경우
  • 트리 설계에서 불필요한 작업 취소가 포함된 경우

7. Halt 로그와 자원 정리 검증

Halt 이벤트 로그와 자원 상태를 대조하여, Halt 시 자원 정리가 정상적으로 수행되었는지 검증한다.

검증 항목:
  ✓ ROS2 액션 목표 취소 요청 전송 확인
  ✓ 외부 스레드 종료 확인
  ✓ 소켓/파일 핸들 해제 확인
  ✓ 하드웨어 장치 안전 상태 전환 확인

8. 비정상 Halt 패턴의 검출

비정상 패턴설명잠재적 문제
동일 노드 연속 Halt매 Tick마다 Halt 발생조건 진동, 히스테리시스 부재
Halt 후 즉시 재시작RUNNING → IDLE → RUNNING비효율적 작업 재시작
Halt 없이 IDLE 전이RUNNING → IDLE (Halt 미호출)구현 오류
긴 RUNNING 후 Halt수백 Tick RUNNING 후 중단장시간 작업의 낭비

이러한 비정상 패턴의 자동 검출을 통해 트리 설계의 문제를 조기에 식별할 수 있다.


참고 문헌

  • 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/