Repeat의 반복 카운터 관리 (Repeat's Repetition Counter Management)

Repeat의 반복 카운터 관리 (Repeat’s Repetition Counter Management)

1. 개요

Repeat 데코레이터의 반복 카운터 관리는 자식 노드의 성공적 실행 횟수를 추적하고, 지정된 반복 횟수에 도달하였는지를 판정하는 내부 상태 관리 메커니즘이다. 카운터의 초기화, 증가, 리셋 시점의 올바른 관리는 Repeat 데코레이터의 정확한 동작을 보장하는 핵심 요소이다.

2. 카운터의 생명주기

2.1 초기화

반복 카운터 k는 Repeat 데코레이터가 최초로 tick되는 시점에서 0으로 초기화된다.

k_0 = 0

증가

자식 노드가 SUCCESS를 반환할 때마다 카운터가 1 증가한다.

k_{t+1} = k_t + 1 \quad \text{if } s_{\text{child}}(t) = \text{SUCCESS}

자식이 RUNNING을 반환하는 동안에는 카운터가 변하지 않는다.

2.2 리셋

카운터가 리셋되는 시점은 다음과 같다.

시점조건리셋 후 상태
반복 완료k = Nk \leftarrow 0, Repeat=SUCCESS
자식 FAILURE자식이 FAILURE 반환k \leftarrow 0, Repeat=FAILURE
halt() 호출외부에서 haltk \leftarrow 0, 상태=IDLE

3. 카운터 상태와 Repeat 반환의 관계

k=0, Child tick → RUNNING → Repeat=RUNNING
k=0, Child tick → SUCCESS → k=1, Repeat=RUNNING
k=1, Child tick → RUNNING → Repeat=RUNNING
k=1, Child tick → SUCCESS → k=2, Repeat=RUNNING
...
k=N-1, Child tick → SUCCESS → k=N, Repeat=SUCCESS

4. halt() 시의 카운터 초기화

Repeat가 외부에서 halt될 때(예: ReactiveSequence의 조건 실패에 의한 halt), 카운터를 반드시 0으로 리셋하여야 한다. 리셋하지 않으면 다음 실행에서 이전 반복 회차의 잔여 카운터가 남아 지정된 횟수보다 적게 반복할 수 있다.

void halt() override
{
    repeat_count_ = 0;  // 필수 초기화
    DecoratorNode::halt();
}

4.1 halt 누락에 의한 오류 시나리오

[시행 1] k=0→1→2 (3번 중 2번 완료 시 halt)
[시행 2] k=2→3 (1번만 추가 실행 후 완료 → 실제로 1번만 반복!)

halt 시 카운터를 초기화하지 않으면, 두 번째 시행에서 이전의 카운터 값(k=2)이 남아 1회만 반복하고 완료된다.

5. 동적 반복 횟수 변경

블랙보드를 통해 num_cycles 값이 동적으로 변경되는 경우, 변경된 값이 현재 진행 중인 반복에 즉시 반영되는지는 구현에 따라 다르다.

5.1 BehaviorTree.CPP의 동작

BehaviorTree.CPP에서는 num_cycles 입력 포트를 매 tick마다 읽으므로, 반복 중에도 변경된 값이 반영된다. 이는 유연성을 제공하나, 예기치 않은 동작을 초래할 수 있으므로 주의가 필요하다.

<Repeat num_cycles="{dynamic_count}">
    <Action ID="Task"/>
</Repeat>

dynamic_count가 5에서 3으로 변경되면, 현재 카운터가 3 이상이면 즉시 반복이 완료된다.

6. 카운터 값의 외부 조회

디버깅 목적으로 현재 반복 카운터 값을 블랙보드에 기록하여 외부에서 조회할 수 있도록 한다.

BT::NodeStatus tick() override
{
    // ... (반복 로직)
    setOutput("current_count", repeat_count_);
    // ...
}
<Repeat num_cycles="10"
        current_count="{patrol_progress}">
    <Action ID="PatrolWaypoint"/>
</Repeat>

patrol_progress 블랙보드 키를 통해 현재 반복 진행 상태를 다른 노드에서 참조할 수 있다.

7. 설계 시 고려 사항

7.1 카운터의 정수형 정밀도

반복 횟수가 매우 큰 경우(예: 수만 회), 정수형 카운터의 오버플로우를 고려하여야 한다. int 타입의 최대값(2^{31} - 1 \approx 2.1 \times 10^9)은 대부분의 실용적 반복에 충분하다.

7.2 카운터와 자식 상태의 일관성

카운터 증가와 자식의 상태 전이가 원자적으로 이루어져야 한다. 단일 스레드 tick 환경에서는 이 일관성이 자연스럽게 보장된다.

8. 참고 문헌

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