1292.62 데코레이터 노드의 동작 원리
1. 데코레이터 노드의 정의
데코레이터 노드(Decorator Node)는 행동 트리(Behavior Tree)의 노드 유형 중 하나로, 정확히 하나의 자식 노드를 가지며, 자식 노드의 반환 상태를 변환(transform)하거나 자식 노드의 실행 방식을 수정(modify)하는 역할을 수행한다. 데코레이터 노드는 소프트웨어 공학의 데코레이터 패턴(Decorator Pattern)에서 착안한 것으로, 자식 노드의 기본 기능을 변경하지 않으면서 추가적인 행동을 부여한다 (Colledanchise & Ögren, Behavior Trees in Robotics and AI: An Introduction, 2018).
2. 구조적 특성
데코레이터 노드는 다음의 구조적 특성을 가진다.
| 특성 | 설명 |
|---|---|
| 자식 수 | 정확히 1개 |
| 위치 | 내부 노드 (리프가 아님) |
| tick 전파 | 자식에게 tick을 전달하고 반환 상태를 가공 |
Decorator [D1]
└─ Child [C1] ← 단일 자식
제어 흐름 노드(Sequence, Fallback, Parallel 등)가 복수의 자식 간의 실행 순서와 조건을 관리하는 반면, 데코레이터 노드는 단일 자식의 실행과 반환 상태를 수정한다. 이 단일 자식 제약은 데코레이터 노드의 역할을 자식 노드에 대한 단항 연산(unary operation)으로 한정한다.
3. 동작 메커니즘
데코레이터 노드가 tick을 수신하면, 일반적으로 다음의 절차를 따른다.
function DecoratorNode.tick():
child_status = child.tick() // 자식에 tick 전달
return transform(child_status) // 반환 상태 변환
그러나 모든 데코레이터가 이 단순한 패턴을 따르는 것은 아니다. 일부 데코레이터는 자식에게 tick을 전달하지 않고 자체적으로 반환 상태를 결정하거나(Delay), 자식의 반환 상태에 관계없이 반복적으로 tick을 전달한다(Repeat). 데코레이터 노드의 동작은 크게 두 가지 범주로 분류된다 (Faconti, BehaviorTree.CPP Documentation, 2024).
3.1 반환 상태 변환
자식 노드의 반환 상태를 다른 상태로 변환하는 데코레이터이다. 자식 노드의 실행 자체는 수정하지 않으며, 자식이 반환한 상태만을 가공한다.
| 데코레이터 | 변환 규칙 |
|---|---|
| Inverter | Success → Failure, Failure → Success |
| ForceSuccess | 모든 상태 → Success |
| ForceFailure | 모든 상태 → Failure |
3.2 실행 흐름 수정
자식 노드의 실행 방식 자체를 수정하는 데코레이터이다. 자식 노드에 tick을 전달하는 횟수, 시점, 조건 등을 제어한다.
| 데코레이터 | 실행 수정 방식 |
|---|---|
| Repeat | 자식을 지정된 횟수만큼 반복 실행 |
| Retry | 자식이 실패하면 지정된 횟수만큼 재시도 |
| Timeout | 자식의 실행 시간을 제한 |
| Delay | 지정된 시간만큼 대기 후 자식에 tick 전달 |
| RunOnce | 자식을 한 번만 실행하고 이후 tick을 무시 |
4. Halt 전파
데코레이터 노드가 halt 요청을 수신하면, 자식 노드가 Running 상태인 경우 자식에게 halt를 전파한다.
function DecoratorNode.halt():
if child.status == Running:
child.halt()
reset_internal_state()
set_status(Idle)
데코레이터 노드의 내부 상태(반복 카운터, 타이머 등)도 halt 시 초기화된다 (Faconti, 2024).
5. 데코레이터의 합성
데코레이터 노드는 중첩(nesting)하여 합성할 수 있다. 여러 데코레이터를 연쇄적으로 적용하면, 각 데코레이터의 효과가 순차적으로 적용된다.
Retry [3회]
└─ Timeout [5초]
└─ Action [A1: 서버 연결]
이 구조에서 A1의 실행에 5초 시간 제한이 적용되고, 실패 시 최대 3회 재시도된다. 데코레이터의 적용 순서는 트리 구조에 의해 결정되며, 외부 데코레이터가 내부 데코레이터의 결과에 대해 작용한다.
6. 제어 흐름 노드와의 비교
| 속성 | 데코레이터 노드 | 제어 흐름 노드 |
|---|---|---|
| 자식 수 | 1개 | 복수 |
| 역할 | 단일 자식의 행동/상태 수정 | 복수 자식의 실행 순서 관리 |
| 연산 유형 | 단항 연산 | 다항 연산 |
| 조합 방식 | 수직적 중첩 | 수평적 배치 |
데코레이터 노드는 기존 자식 노드의 의미론을 수정하지 않으면서, 재시도, 시간 제한, 상태 반전 등의 정책을 선언적으로 추가하는 수단이다. 이를 통해 자식 노드의 구현을 변경하지 않고도 행동의 실행 정책을 유연하게 조정할 수 있다 (Colledanchise & Ögren, 2018).
7. BehaviorTree.CPP에서의 분류
BehaviorTree.CPP 라이브러리에서 제공하는 주요 데코레이터 노드는 다음과 같다.
| 데코레이터 | 기능 요약 |
|---|---|
| Inverter | 자식의 Success/Failure를 반전 |
| ForceSuccess | 자식의 결과를 항상 Success로 변환 |
| ForceFailure | 자식의 결과를 항상 Failure로 변환 |
| Repeat | 자식을 지정 횟수만큼 반복 |
| Retry | 실패 시 지정 횟수만큼 재시도 |
| Timeout | 시간 초과 시 Failure 반환 |
| Delay | 지정 시간 대기 후 자식 실행 |
| RunOnce | 자식을 최초 1회만 실행 |
| KeepRunningUntilFailure | 자식이 Failure를 반환할 때까지 Running 유지 |
이 데코레이터 노드들은 행동 트리의 표현력을 확장하며, 기본적인 제어 흐름 노드만으로는 구현하기 어려운 실행 정책을 간결하게 표현할 수 있게 한다 (Faconti, 2024).
8. 로봇 공학에서의 활용
8.1 재시도 정책
로봇의 행동이 일시적 요인에 의해 실패할 수 있는 경우, Retry 데코레이터를 통해 자동 재시도 정책을 적용한다. 센서 읽기 실패, 통신 시간 초과, 매니퓰레이션 실패 등의 일시적 실패에 대한 복원력(resilience)을 제공한다.
8.2 시간 제한
비동기 액션 노드의 실행 시간을 제한하기 위해 Timeout 데코레이터가 활용된다. 경로 추종, 물체 탐색 등의 행동에 시간 제한을 설정하여, 무한 대기를 방지하고 대안 행동으로의 전환을 유도한다.
8.3 논리 반전
Inverter 데코레이터는 조건 노드의 논리를 반전시켜, “~이 아닌 경우“와 같은 부정 조건을 간결하게 표현한다. 이를 통해 별도의 부정 조건 노드를 구현하지 않고도 기존 조건 노드를 재활용할 수 있다.
참고 문헌
- Colledanchise, M. & Ögren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
- Faconti, D. (2024). BehaviorTree.CPP Documentation. https://www.behaviortree.dev/