KeepRunningUntilFailure 데코레이터의 동작 (Operation of the KeepRunningUntilFailure Decorator)

KeepRunningUntilFailure 데코레이터의 동작 (Operation of the KeepRunningUntilFailure Decorator)

1. 개요

KeepRunningUntilFailure 데코레이터는 자식 노드가 FAILURE를 반환할 때까지 실행을 지속하는 실행 제어 데코레이터이다. 자식이 SUCCESS를 반환하면 이를 RUNNING으로 변환하여 다음 tick에서 자식을 다시 실행하고, FAILURE를 반환하면 그대로 FAILURE를 전달하여 반복을 종료한다. 이는 특정 조건이 거짓이 될 때까지 행동을 지속하는 “do-until” 패턴을 구현한다.

2. 동작 규칙

2.1 상태 변환 테이블

자식 반환KeepRunningUntilFailure 반환다음 tick 동작
SUCCESSRUNNING자식 재실행
FAILUREFAILURE종료
RUNNINGRUNNING자식 계속 실행

2.2 수학적 표현

f_{\text{KRUF}}(s) = \begin{cases} \text{RUNNING} & \text{if } s = \text{SUCCESS} \\ \text{FAILURE} & \text{if } s = \text{FAILURE} \\ \text{RUNNING} & \text{if } s = \text{RUNNING} \end{cases}

핵심 변환은 SUCCESS→RUNNING이다. 이에 의해 자식의 “성공적 완료” 후에도 실행이 계속된다.

구현

class KeepRunningUntilFailure : public BT::DecoratorNode
{
    BT::NodeStatus tick() override
    {
        setStatus(BT::NodeStatus::RUNNING);
        auto child_status = child_node_->executeTick();

        if (child_status == BT::NodeStatus::FAILURE)
        {
            return BT::NodeStatus::FAILURE;
        }
        return BT::NodeStatus::RUNNING;
    }
};

이 구현은 매우 간단하다. 자식이 FAILURE를 반환하는 경우에만 FAILURE를 전달하고, 그 외의 모든 경우에 RUNNING을 반환한다.

Repeat(-1)과의 비교

특성KeepRunningUntilFailureRepeat(num_cycles=-1)
SUCCESS 처리RUNNING 반환 (재실행)RUNNING 반환 (재실행)
FAILURE 처리FAILURE 반환 (종료)FAILURE 반환 (종료)
RUNNING 처리RUNNING 반환RUNNING 반환
내부 상태무상태카운터 유지
종료 조건FAILURE만FAILURE 또는 카운터 도달

KeepRunningUntilFailure는 무한 반복의 Repeat(-1)과 동일한 동작을 하며, 카운터 관리가 없으므로 더 경량이다.

활용 사례

지속적 센서 감시

<KeepRunningUntilFailure>
    <Sequence>
        <Action ID="ReadSensorData"/>
        <Action ID="PublishProcessedData"/>
    </Sequence>
</KeepRunningUntilFailure>

센서 데이터 읽기와 처리를 지속적으로 반복하다가, 센서 오류로 FAILURE가 반환되면 종료한다.

드론 호버링 유지

<KeepRunningUntilFailure>
    <Action ID="MaintainHover"/>
</KeepRunningUntilFailure>

호버링을 지속하다가 외부 명령에 의해 FAILURE가 반환되면 종료한다.

이벤트 폴링

<KeepRunningUntilFailure>
    <Fallback>
        <Sequence>
            <Condition ID="IsEventDetected"/>
            <ForceFailure>
                <Action ID="HandleEvent"/>
            </ForceFailure>
        </Sequence>
        <ForceSuccess><Action ID="Sleep" ms="100"/></ForceSuccess>
    </Fallback>
</KeepRunningUntilFailure>

이벤트가 감지되면 처리하고 종료하며, 이벤트가 없으면 100ms 대기 후 재확인한다.

설계 시 고려 사항

종료 메커니즘 보장

KeepRunningUntilFailure는 자식이 FAILURE를 반환하지 않는 한 영원히 RUNNING을 반환한다. 반드시 자식이 FAILURE를 반환할 수 있는 경로가 존재하여야 하며, 그렇지 않으면 ReactiveSequence와 외부 조건 또는 Timeout을 통해 종료를 보장하여야 한다.

ForceSuccess로 감싼 자식은 사용 불가

ForceSuccess로 감싼 자식은 절대로 FAILURE를 반환하지 않으므로, KeepRunningUntilFailure가 영원히 종료되지 않는다. 이는 설계 오류이다.

참고 문헌

  • 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초안 작성