1296.5 액션 노드의 분류 체계

1. 실행 모델에 의한 분류

BehaviorTree.CPP 라이브러리(버전 4.x)는 액션 노드를 실행 모델에 따라 네 가지 범주로 분류한다. 각 범주는 BT::ActionNodeBase를 기반으로 하는 별도의 기반 클래스를 제공하며, 개발자는 행동의 특성에 맞는 기반 클래스를 선택하여 상속한다.

1.1 SyncActionNode (동기 액션 노드)

단일 Tick 내에서 즉시 완료되는 행동을 위한 노드이다. tick() 메서드가 호출되면 SUCCESS 또는 FAILURE를 즉시 반환한다. RUNNING을 반환할 수 없다.

적합한 행동: 블랙보드 값 설정, 로그 출력, 단순 계산, ROS2 토픽 단일 발행, 경량 서비스 호출

1.2 StatefulActionNode (상태 기반 비동기 액션 노드)

다수의 Tick에 걸쳐 실행되는 비동기 행동을 위한 노드이다. onStart(), onRunning(), onHalted()의 세 가지 콜백으로 행동의 생명주기를 관리한다.

적합한 행동: ROS2 액션 호출, 경로 추종, 타임아웃 대기, 센서 데이터 수집 대기

1.3 ThreadedAction (스레드 기반 액션 노드)

tick() 메서드를 별도의 스레드에서 실행하는 노드이다. tick() 내부에서 차단(blocking) 호출이 가능하며, 라이브러리가 스레드 관리를 담당한다.

적합한 행동: 라이브러리 내부에서 차단 호출이 불가피한 경우, 레거시 코드 래핑

1.4 CoroActionNode (코루틴 액션 노드)

C++ 코루틴을 활용하여 협력적(cooperative) 비동기 실행을 구현하는 노드이다. tick() 내부에서 setStatusRunningAndYield()를 호출하여 RUNNING을 반환하고, 다음 Tick에서 중단 지점부터 실행을 재개한다.

적합한 행동: 다단계 행동을 순차적 코드로 구현하려는 경우

2. 분류 기준의 비교

기준SyncActionNodeStatefulActionNodeThreadedActionCoroActionNode
RUNNING 반환불가가능가능가능
실행 스레드메인 스레드메인 스레드별도 스레드메인 스레드
차단 호출불가불가가능불가
콜백 분리tick() 단일onStart/onRunning/onHaltedtick() 단일tick() 단일
Halt 처리불필요onHalted()halt() 오버라이드자동 (코루틴 파괴)
스레드 안전성고려 불필요고려 불필요필수 고려고려 불필요
권장 여부 (4.x)권장권장제한적 사용권장

3. 기능적 역할에 의한 분류

실행 모델과 별개로, 액션 노드를 기능적 역할에 따라 분류할 수 있다.

3.1 이동(Navigation) 액션

로봇의 위치를 변경하는 행동이다. 목표 위치로의 항법, 경로 추종, 회전, 후진 등이 포함된다.

3.2 조작(Manipulation) 액션

로봇의 매니퓰레이터를 구동하는 행동이다. 관절 이동, 엔드 이펙터 제어, 물체 파지 및 배치 등이 포함된다.

3.3 인식(Perception) 액션

센서 데이터를 수집하거나 처리하는 행동이다. 이미지 촬영, 포인트 클라우드 처리, 물체 인식 등이 포함된다.

3.4 통신(Communication) 액션

외부 시스템과의 데이터 교환 행동이다. ROS2 토픽 발행/구독, 서비스 호출, 상태 보고 등이 포함된다.

3.5 내부(Internal) 액션

블랙보드 값 조작, 로그 기록, 타이머 관리 등의 내부 상태 관리 행동이다.

4. 분류 선택 지침

개발자가 새로운 액션 노드를 구현할 때의 기반 클래스 선택 지침을 정리한다.

행동이 단일 Tick 내에 완료되는가?
├── 예 → SyncActionNode
└── 아니오 → 행동이 차단(blocking) 호출을 포함하는가?
    ├── 예 → ThreadedAction (단, 가능하면 비동기로 전환)
    └── 아니오 → 다단계 순차 행동을 단일 함수로 작성하고 싶은가?
        ├── 예 → CoroActionNode
        └── 아니오 → StatefulActionNode

대부분의 로봇공학 응용에서 StatefulActionNode가 가장 적합한 선택이다. ROS2 액션 서버와의 연동은 비동기 모델이 자연스럽게 대응되며, onStart()에서 목표를 전송하고 onRunning()에서 결과를 폴링하며 onHalted()에서 취소를 요청하는 패턴이 ROS2 액션의 생명주기와 정확히 일치한다.

SyncActionNode는 블랙보드 조작, 로그 출력, 단일 토픽 발행 등의 경량 작업에 적합하다. ThreadedAction은 레거시 라이브러리의 차단 API를 래핑하는 특수한 경우에만 사용하며, 새로운 구현에서는 가급적 StatefulActionNodeCoroActionNode로 대체하는 것이 권장된다.

5. 버전별 차이

BehaviorTree.CPP 3.x에서 4.x로의 전환에서 액션 노드 분류 체계에 변화가 있었다.

3.x 명칭4.x 명칭변경 사항
SyncActionNodeSyncActionNode변경 없음
AsyncActionNode(제거)StatefulActionNode로 대체
CoroActionNodeCoroActionNodeAPI 안정화
-StatefulActionNode4.x에서 새로 도입
-ThreadedAction3.x AsyncActionNode의 스레드 모델 계승

4.x에서 도입된 StatefulActionNode는 3.x의 AsyncActionNode가 제공하던 비동기 실행 모델을 콜백 기반의 더 명확한 인터페이스로 재설계한 것이다. 3.x에서 4.x로의 마이그레이션 시 AsyncActionNodeStatefulActionNode로 전환하는 것이 권장된다.