Delay의 지연 중 Running 반환 (Delay's Running Return During Delay Period)

Delay의 지연 중 Running 반환 (Delay’s Running Return During Delay Period)

1. 개요

Delay 데코레이터는 지연 시간 동안 RUNNING 상태를 반환하여, 부모 노드에게 아직 행동이 진행 중임을 알린다. 이 RUNNING 반환은 자식 노드가 실행 중인 것이 아니라, 데코레이터 자체가 지연 대기 중임을 나타낸다. 지연 동안 자식 노드는 tick되지 않으며, 지연이 완료된 후에야 자식의 실행이 시작된다.

2. RUNNING 반환의 메커니즘

2.1 지연 중 tick 흐름

Tick 1: Delay 진입 → 타이머 시작 → 자식 tick 안 함 → RUNNING 반환
Tick 2: 경과 시간 확인 → 미완료 → 자식 tick 안 함 → RUNNING 반환
Tick 3: 경과 시간 확인 → 미완료 → 자식 tick 안 함 → RUNNING 반환
...
Tick N: 경과 시간 확인 → 완료 → 자식 tick 시작

2.2 코드 수준

BT::NodeStatus tick() override
{
    if (status() == BT::NodeStatus::IDLE)
    {
        start_time_ = std::chrono::steady_clock::now();
        setStatus(BT::NodeStatus::RUNNING);
    }

    auto elapsed = std::chrono::steady_clock::now() - start_time_;
    if (elapsed < delay_duration_)
    {
        // 지연 중: 자식을 tick하지 않고 RUNNING 반환
        return BT::NodeStatus::RUNNING;
    }

    // 지연 완료: 자식 tick
    return child_node_->executeTick();
}

3. RUNNING 반환의 효과

3.1 부모 노드에 대한 영향

부모 노드(Sequence, Fallback 등)는 Delay의 RUNNING을 수신하면 다음 자식으로 진행하지 않고, 다음 tick에서 Delay를 다시 tick한다. 이는 행동 트리의 표준 RUNNING 전파 메커니즘에 의한 것이다.

3.2 ReactiveSequence에서의 동작

ReactiveSequence 내에서 Delay가 RUNNING을 반환하면, 매 tick마다 Delay 앞의 조건 노드가 재평가된다.

<ReactiveSequence>
    <Condition ID="IsNotEmergencyStopped"/>
    <Delay delay_msec="5000">
        <Action ID="StartTask"/>
    </Delay>
</ReactiveSequence>

5초 지연 중에도 비상 정지 조건이 매 tick마다 확인된다. 비상 정지가 활성화되면 Delay가 halt되어 지연과 후속 행동이 모두 취소된다.

4. Delay의 RUNNING과 자식의 RUNNING의 구분

Delay의 tick 흐름에서 두 가지 RUNNING 상태가 존재한다.

시점RUNNING의 원인자식 상태
지연 중Delay 자체의 대기IDLE (tick되지 않음)
지연 후자식의 비동기 실행RUNNING

부모 노드의 관점에서 두 RUNNING은 구분되지 않으며, 동일한 방식으로 처리된다.

5. halt 시의 RUNNING 처리

Delay가 RUNNING 상태에서 halt되면:

  1. 지연 중에 halt된 경우: 타이머가 리셋되고, 자식은 tick된 적이 없으므로 자식의 halt는 불필요하다.
  2. 자식 실행 중에 halt된 경우: 타이머가 리셋되고, 자식의 halt()가 호출된다.
void halt() override
{
    // 자식이 RUNNING이면 halt
    haltChild();
    // 상태를 IDLE로 전환
    DecoratorNode::halt();
}

6. 설계 시 고려 사항

6.1 지연 중 자원 소모

Delay의 RUNNING 반환은 행동 트리의 tick 루프를 점유한다. tick 주기마다 시간 비교 연산이 수행되지만, 이 비용은 무시할 수 있을 정도로 작다.

6.2 시뮬레이션 시간과의 호환

BehaviorTree.CPP의 Delay는 std::chrono::steady_clock을 사용하므로 시뮬레이션 시간과 독립적이다. 시뮬레이션 환경에서 정확한 지연이 필요하면 ROS2 시간을 사용하는 사용자 정의 Delay를 구현하여야 한다.

7. 참고 문헌

  • Colledanchise, M., & Ogren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
  • BehaviorTree.CPP 공식 문서. https://www.behaviortree.dev/

버전날짜변경 사항
v0.12026-04-04초안 작성