ForceSuccess의 Failure→Success 변환 규칙 (ForceSuccess’s Failure→Success Conversion Rule)
1. 개요
ForceSuccess 데코레이터의 핵심 변환 규칙은 자식 노드가 FAILURE를 반환할 때 이를 SUCCESS로 변환하는 것이다. 이 단방향 변환은 자식 행동의 실패를 의도적으로 은폐하여, 실패가 상위 제어 흐름에 전파되지 않도록 차단한다. 본 절에서는 이 변환 규칙의 정형적 정의, Sequence에서의 효과, 안전성 고려 사항을 상세히 다룬다.
2. 변환 규칙의 정형적 정의
2.1 FAILURE→SUCCESS 변환
f_{\text{ForceSuccess}}(\text{FAILURE}) = \text{SUCCESS}
이 변환에 의해, 자식이 FAILURE를 반환하더라도 ForceSuccess의 부모 노드는 SUCCESS를 수신한다. 부모 노드의 관점에서 자식의 실패는 보이지 않는다.
Inverter와의 차이
| 입력 | Inverter 출력 | ForceSuccess 출력 |
|---|---|---|
| SUCCESS | FAILURE | SUCCESS |
| FAILURE | SUCCESS | SUCCESS |
Inverter는 SUCCESS도 FAILURE로 변환하지만, ForceSuccess는 SUCCESS를 그대로 유지한다. 즉, ForceSuccess는 비대칭(asymmetric) 변환이다.
Sequence에서의 효과
ForceSuccess 없이
<Sequence>
<Action ID="Step1"/>
<Action ID="Step2"/> <!-- FAILURE 반환 시 -->
<Action ID="Step3"/> <!-- 실행되지 않음 -->
</Sequence>
Step2가 FAILURE → Sequence가 FAILURE → Step3는 실행되지 않음.
ForceSuccess 적용
<Sequence>
<Action ID="Step1"/>
<ForceSuccess>
<Action ID="Step2"/> <!-- FAILURE 반환해도 -->
</ForceSuccess>
<Action ID="Step3"/> <!-- 실행됨 -->
</Sequence>
Step2가 FAILURE → ForceSuccess가 SUCCESS → Sequence가 Step3로 진행.
정보 손실의 함의
FAILURE→SUCCESS 변환은 자식의 실패 정보를 소실시킨다. 이로 인한 영향은 다음과 같다.
| 측면 | 영향 |
|---|---|
| 상위 제어 흐름 | 자식의 실패를 인지하지 못함 |
| 디버깅 | 실패 원인 추적이 어려움 |
| 로깅 | 별도의 로깅 없이는 실패 발생 사실이 기록되지 않음 |
| 안전성 | 안전 관련 실패가 은폐될 위험 |
로깅을 결합한 안전한 사용
실패 정보 손실을 보완하기 위해, ForceSuccess 내부에서 자식의 실패를 로깅한다.
class ForceSuccessWithLog : public BT::DecoratorNode
{
BT::NodeStatus tick() override
{
auto status = child_node_->executeTick();
if (status == BT::NodeStatus::FAILURE)
{
RCLCPP_WARN(node_->get_logger(),
"[%s] Child '%s' returned FAILURE (forced to SUCCESS)",
name().c_str(), child()->name().c_str());
}
if (status == BT::NodeStatus::RUNNING)
{
return BT::NodeStatus::RUNNING;
}
return BT::NodeStatus::SUCCESS;
}
};
적용 기준
ForceSuccess의 FAILURE→SUCCESS 변환을 적용하여도 안전한 경우:
| 적합 | 부적합 |
|---|---|
| 로깅/알림 전송 실패 | 안전 장치 활성화 실패 |
| 보조 센서 초기화 실패 | 주 센서 초기화 실패 |
| 선택적 최적화 단계 실패 | 필수 처리 단계 실패 |
| 통계 수집 실패 | 데이터 저장 실패 |
복수 ForceSuccess의 결합
<Sequence>
<ForceSuccess><Action ID="OptionalA"/></ForceSuccess>
<ForceSuccess><Action ID="OptionalB"/></ForceSuccess>
<Action ID="RequiredC"/>
</Sequence>
OptionalA와 OptionalB의 실패와 관계없이 RequiredC가 항상 실행된다.
설계 시 주의 사항
과도한 사용 지양
ForceSuccess를 남용하면 모든 실패가 무시되어, 시스템이 비정상 상태에서도 정상적으로 동작하는 것처럼 보이는 위험이 있다. 필수적인 경우에만 제한적으로 사용하여야 한다.
코드 리뷰 시 명시적 확인
ForceSuccess가 적용된 모든 위치에 대해, 해당 행동의 실패가 안전에 영향을 미치지 않는지를 코드 리뷰에서 명시적으로 확인하여야 한다.
참고 문헌
- 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 | 초안 작성 |