Delay 데코레이터의 동작 (Operation of the Delay Decorator)

Delay 데코레이터의 동작 (Operation of the Delay Decorator)

1. 개요

Delay 데코레이터는 자식 노드의 실행을 지정된 시간만큼 지연시키는 시간 제어 데코레이터이다. 지연 시간 동안 RUNNING을 반환하며, 지연이 완료된 후에 자식 노드를 tick한다. 행동 사이의 안정화 시간 확보, 모터 제어의 순차적 실행, 네트워크 요청 간 간격 설정 등에 활용된다.

2. 동작 규칙

2.1 상태 전이

단계시간 조건동작Delay 반환
지연 중t - t_0 < T_d자식을 tick하지 않음RUNNING
지연 완료t - t_0 \geq T_d자식을 tick자식의 상태

여기서 T_d는 지연 시간, t_0는 타이머 시작 시점이다.

2.2 수학적 표현

f_{\text{Delay}}(t) = \begin{cases} \text{RUNNING} & \text{if } (t - t_0) < T_d \\ \text{child.tick()} & \text{if } (t - t_0) \geq T_d \end{cases}

구현

class DelayNode : public BT::DecoratorNode
{
    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_)
        {
            return BT::NodeStatus::RUNNING;
        }

        return child_node_->executeTick();
    }

    void halt() override
    {
        // 타이머 리셋
        DecoratorNode::halt();
    }

    std::chrono::steady_clock::time_point start_time_;
    std::chrono::milliseconds delay_duration_;
};

XML에서의 사용

<Delay delay_msec="2000">
    <Action ID="StartMotor"/>
</Delay>

2초 대기 후 모터를 시작한다.

시간적 동작 흐름 (delay_msec=2000, tick 주기 100ms)

Tick 1:   elapsed=0ms      → RUNNING (지연 중)
Tick 2:   elapsed=100ms    → RUNNING
...
Tick 20:  elapsed=1900ms   → RUNNING
Tick 21:  elapsed=2000ms   → 자식 tick 시작 → RUNNING (자식 실행 중)
Tick 22:  elapsed=2100ms   → 자식 tick → SUCCESS
→ Delay = SUCCESS

Timeout과의 차이

특성DelayTimeout
시간 경과 전자식을 tick하지 않음자식을 tick함
시간 경과 후자식을 tick 시작자식을 halt하고 FAILURE
역할실행 지연실행 시간 제한
RUNNING 반환 시점지연 중자식이 RUNNING 중

활용 사례

모터 방향 전환 대기

<Sequence>
    <Action ID="StopMotor"/>
    <Delay delay_msec="500">
        <Action ID="ReverseMotor"/>
    </Delay>
</Sequence>

모터 정지 후 500ms 대기 후 역회전한다. 모터의 기계적 감속 시간을 확보한다.

Retry 사이 대기

<RetryNode num_attempts="3">
    <Delay delay_msec="1000">
        <Action ID="ConnectToServer"/>
    </Delay>
</RetryNode>

서버 연결 재시도 사이에 1초 간격을 둔다.

시스템 시작 후 안정화 대기

<Sequence>
    <Action ID="PowerOnSensors"/>
    <Delay delay_msec="3000">
        <Action ID="CalibrateSensors"/>
    </Delay>
</Sequence>

센서 전원 투입 후 3초 대기하여 센서가 안정화된 후 캘리브레이션을 수행한다.

드론 이륙 후 호버링 안정화

<Sequence>
    <Action ID="Takeoff"/>
    <Delay delay_msec="5000">
        <Action ID="StartMission"/>
    </Delay>
</Sequence>

이륙 후 5초 대기하여 호버링이 안정화된 후 임무를 시작한다.

설계 시 고려 사항

지연 중 halt의 처리

지연 중에 외부에서 halt가 호출되면, 지연 타이머가 리셋되어 다음 실행에서 처음부터 지연이 시작된다.

지연 중 조건 변화

ReactiveSequence 내에서 Delay를 사용하면, 지연 중에도 조건 노드가 재평가된다. 조건이 실패하면 Delay가 halt되어 지연이 취소된다.

정밀도

Delay의 정밀도는 행동 트리의 tick 주기에 의해 제한된다. tick 주기가 100ms이면, 실제 지연은 지정 시간 ±100ms의 범위에 있을 수 있다.

참고 문헌

  • 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초안 작성