ForceSuccess의 Failure→Success 변환 규칙 (ForceSuccess's Failure→Success Conversion Rule)

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 출력
SUCCESSFAILURESUCCESS
FAILURESUCCESSSUCCESS

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>

OptionalAOptionalB의 실패와 관계없이 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.12026-04-04초안 작성