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과의 차이
| 특성 | Delay | Timeout |
|---|---|---|
| 시간 경과 전 | 자식을 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.1 | 2026-04-04 | 초안 작성 |