1294.51 Fallback, FallbackWithMemory, ReactiveFallback의 비교
1. 세 가지 Fallback 변형의 개관
BehaviorTree.CPP v4에서 제공하는 두 가지 Fallback 변형—FallbackWithMemory(기본 <Fallback>)와 ReactiveFallback(<ReactiveFallback>)—은 모두 자식 노드를 왼쪽에서 오른쪽으로 순차적으로 평가하며 OR 의미론을 따른다는 공통점을 가진다. 그러나 RUNNING 상태 이후의 재진입 동작, 우선순위 재검사 여부, Halt 처리 방식에서 본질적인 차이를 보인다(Colledanchise & Ogren, 2018).
2. 핵심 특성 비교
2.1 재진입 동작
| 특성 | FallbackWithMemory | ReactiveFallback |
| Tick 시작 위치 | 마지막 RUNNING 자식 인덱스 | 항상 인덱스 0 |
| 상태 변수 | current_child_idx 유지 | 상태 변수 없음 |
| FAILURE 자식 재평가 | 건너뜀 | 매 Tick 재평가 |
| 메모리 유무 | 있음 (Stateful) | 없음 (Stateless) |
2.2 우선순위 감시 능력
| 특성 | FallbackWithMemory | ReactiveFallback |
| 우선 대안 가용성 변화 감지 | 불가 | 가능 |
| 동적 대안 전환 | 부적합 | 적합 |
| 조건 변화 반응 | 대안 시도 완료 후에만 반응 | 즉시 반응 |
2.3 Halt 동작
| 특성 | FallbackWithMemory | ReactiveFallback |
| 앞쪽 자식 SUCCESS 시 Halt | 해당 없음 (재평가 없음) | 즉시 Halt |
| 자체 SUCCESS 시 Halt | Halt 수행 | Halt 수행 |
| Halt 후 인덱스 초기화 | current_child_idx ← 0 | 상태 없으므로 불필요 |
3. Tick 비용 비교
3.1 Tick당 노드 방문 수
자식 배열이 [C_0, C_1, ..., C_{k-1}, A_k]이고 A_k가 RUNNING 상태인 경우:
| 변형 | Tick당 방문 노드 수 |
| FallbackWithMemory | 1 (A_k만 방문) |
| ReactiveFallback | k + 1 (모든 자식 방문) |
3.2 총 노드 방문 수 (M Tick 동안 RUNNING 유지)
| 변형 | 초기 평가 | RUNNING 유지 기간 | 총 방문 수 |
| FallbackWithMemory | k + 1 | (M - 1) \times 1 | k + M |
| ReactiveFallback | k + 1 | (M - 1) \times (k + 1) | (k + 1) \times M |
4. 안전성 및 효율성 비교
4.1 시나리오: 주 서비스 복구 감지
<Fallback변형>
<Condition ID="IsPrimaryServiceOnline"/>
<Action ID="UseBackupService"/>
</Fallback변형>
FallbackWithMemory:
Tick 1: Primary→F, Backup→R (idx=1)
Tick 2: Backup→R (Primary 건너뜀)
...
Tick N: Backup→R (Primary 복구됐지만 미감지)
Tick N+1: Backup→S (백업 완료)
→ SUCCESS
ReactiveFallback:
Tick 1: Primary→F, Backup→R
Tick 2: Primary→F, Backup→R
Tick K: Primary→S (주 서비스 복구 즉시 감지)
Backup→Halt
→ SUCCESS
ReactiveFallback은 주 서비스가 복구되는 즉시 백업 서비스를 중단하고 전환한다.
5. 의미론적 비교
5.1 논리적 해석
- FallbackWithMemory: “대안을 순서대로 시도한다” — 각 대안의 실패는 한 번만 확인된다.
- ReactiveFallback: “가용한 최선의 대안을 사용한다” — 더 나은 대안의 가용성이 지속적으로 확인된다.
5.2 시간적 해석
- FallbackWithMemory: 순차적 시도(sequential try) — 대안 i의 실패는 대안 i+1의 시도 전제 조건이며, 이후 재확인되지 않는다.
- ReactiveFallback: 동적 선택(dynamic selection) — 모든 앞쪽 대안의 실패 상태가 뒤쪽 대안의 실행 중에도 지속적으로 재확인된다.
6. Sequence 변형과의 대칭적 관계
| Sequence 변형 | Fallback 변형 | 공통 특성 |
| SequenceWithMemory | FallbackWithMemory | 메모리 기반, 재진입 |
| ReactiveSequence | ReactiveFallback | 무상태, 매 Tick 재평가 |
각 쌍에서 SUCCESS와 FAILURE의 역할만 교환되며, 알고리즘 구조, 비용 특성, 사용 패턴이 모두 대칭적이다.
7. 설계 지침
7.1 FallbackWithMemory 사용이 적합한 경우
- 대안의 시도가 비용이 높아 재시도를 피해야 하는 경우
- 부수 효과가 있는 액션이 앞쪽에 위치하는 경우
- 우선순위 재검사가 필요하지 않은 경우
<Fallback>
<Action ID="TryExpensiveMethod"/>
<Action ID="TryMediumMethod"/>
<Action ID="TryCheapMethod"/>
</Fallback>
7.2 ReactiveFallback 사용이 적합한 경우
- 앞쪽 노드가 부수 효과 없는 조건이며, 우선순위 감시가 필요한 경우
- 더 나은 대안이 가용해지면 즉시 전환해야 하는 경우
- 목표 달성 상태를 지속적으로 확인해야 하는 경우
<ReactiveFallback>
<Condition ID="IsGoalAchieved"/>
<Action ID="AchieveGoal"/>
</ReactiveFallback>
8. 종합 비교표
| 비교 항목 | FallbackWithMemory | ReactiveFallback |
| 재진입 방식 | 기억된 인덱스부터 재개 | 항상 처음부터 시작 |
| 상태 변수 | current_child_idx | 없음 |
| FAILURE 자식 처리 | 건너뜀 | 재평가 |
| 우선순위 재검사 | 불가 | 가능 |
| Tick당 비용 | O(1) (RUNNING 시) | O(k+1) |
| 동적 대안 전환 | 부적합 | 적합 |
| 부수 효과 안전성 | 안전 (재실행 없음) | 위험 (앞쪽 액션 재실행) |
| 전형적 앞쪽 노드 | 액션 또는 조건 | 조건만 권장 |
| BT.CPP v4 태그 | <Fallback> | <ReactiveFallback> |
| 사용 패턴 | 순차적 대안 시도 | 우선순위 감시 하의 대안 선택 |
참고 문헌
- 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/