1291.46 행동 트리의 재사용성 원칙

1. 재사용성의 정의와 의의

재사용성(reusability)이란, 하나의 소프트웨어 구성 요소가 원래 개발된 맥락을 넘어서 다른 맥락에서도 수정 없이 또는 최소한의 수정으로 활용될 수 있는 속성을 의미한다. 소프트웨어 공학에서 재사용성은 개발 비용의 절감, 품질의 향상, 그리고 시스템 신뢰성의 증가를 위한 핵심 설계 목표로 인정되어 왔다(Krueger, 1992).

행동 트리(Behavior Tree, BT)에서의 재사용성은, 한 번 설계·구현·검증된 노드 또는 서브트리가 다른 행동 트리, 다른 임무, 또는 다른 로봇 플랫폼에서 변경 없이 재활용될 수 있는 구조적 속성을 의미한다. 이 속성은 행동 트리의 모듈성으로부터 자연스럽게 파생되며, 대규모 로봇 시스템의 개발 효율성을 결정하는 핵심 요인이다.

2. 재사용성을 가능케 하는 구조적 기반

2.1 통일된 인터페이스에 의한 상호 교환 가능성

행동 트리의 모든 노드는 동일한 인터페이스를 준수한다. 임의의 노드 또는 서브트리는 Tick을 입력으로 수신하고, Success, Failure, Running 중 하나의 반환 상태를 출력한다.

\text{Node}: \text{Tick} \rightarrow \{\text{Success}, \text{Failure}, \text{Running}\}

이 통일된 인터페이스에 의하여, 하나의 노드가 트리 내의 임의의 위치에 삽입될 수 있다. 부모 노드는 자식 노드의 구체적 유형이나 내부 구현에 무관하게 동일한 규칙으로 자식을 관리하므로, 노드의 **상호 교환 가능성(interchangeability)**이 보장된다. 이는 하드웨어 시스템에서 표준화된 인터페이스(예: USB, PCI Express)가 장치의 호환성과 재사용성을 보장하는 원리와 구조적으로 동일하다.

2.2 문맥 독립적 노드 설계

재사용 가능한 노드란, 자신이 배치된 트리의 구조나 위치에 의존하지 않는 노드를 의미한다. 행동 트리의 노드는 원칙적으로 **문맥 독립적(context-independent)**으로 설계된다. 하나의 액션 노드 “MoveToPosition“은 내비게이션 서브트리에서도, 탐사 서브트리에서도, 충전소 복귀 서브트리에서도 동일하게 동작한다. 노드의 동작은 자신의 입력 매개변수와 블랙보드에서 참조하는 데이터에 의하여만 결정되며, 부모 노드의 유형이나 형제 노드의 구성에 의존하지 않는다.

이와 대조적으로, 유한 상태 머신의 상태는 본질적으로 문맥 의존적이다. 하나의 상태는 해당 상태로의 진입을 허용하는 전이 규칙과, 해당 상태로부터의 전이 규칙에 의하여 정의되므로, 동일한 행동을 수행하는 상태라 하더라도 다른 상태 머신에서 재사용하려면 전이 규칙을 재정의하여야 한다.

2.3 매개변수화에 의한 일반화

재사용성을 극대화하기 위하여, 행동 트리의 노드는 **매개변수화(parameterization)**를 통하여 일반화된다. 노드의 동작에 필요한 구체적 값(목표 좌표, 속도 제한, 시간 제한 등)을 하드코딩하지 않고, 블랙보드 포트(blackboard port)를 통하여 외부에서 주입받는다.

BehaviorTree.CPP 4.x에서는 노드의 입력·출력 포트를 정적으로 선언하여, 노드가 요구하는 매개변수와 생성하는 출력을 명시적으로 정의한다.

class MoveToPosition : public BT::StatefulActionNode {
public:
    static BT::PortsList providedPorts() {
        return {
            BT::InputPort<geometry_msgs::msg::PoseStamped>("target_pose"),
            BT::InputPort<double>("speed_limit", 1.0, "최대 속도 제한"),
            BT::OutputPort<bool>("goal_reached")
        };
    }
    // ...
};

이 설계에서 MoveToPosition 노드는 목표 위치와 속도 제한을 외부로부터 주입받으므로, 특정 임무에 종속되지 않는다. 동일한 노드가 “웨이포인트 순찰”, “충전소 이동”, “대피 경로 추종” 등 다양한 임무에서 재사용될 수 있다.

3. 재사용의 수준과 범위

3.1 노드 수준의 재사용

가장 기본적인 재사용 수준은 개별 노드의 재사용이다. 범용적인 액션 노드와 조건 노드를 **노드 라이브러리(node library)**로 구축하여, 다양한 행동 트리에서 공유한다.

노드 유형재사용 범위예시
범용 조건 노드프로젝트 전체IsBatteryAbove, IsPathClear
범용 액션 노드프로젝트 전체MoveToPosition, Wait, Log
플랫폼 특화 노드동일 플랫폼 내ArmGrasp, DroneHover
임무 특화 노드동일 임무 내CheckMissionComplete

BehaviorTree.CPP의 BehaviorTreeFactory는 노드를 이름으로 등록하고, XML에서 이름으로 참조하는 팩토리 패턴(factory pattern)을 구현한다. 이 메커니즘에 의하여, 노드의 C++ 구현과 행동 트리의 XML 정의가 분리되며, 동일한 노드 구현이 다수의 XML 행동 트리에서 재사용된다.

BT::BehaviorTreeFactory factory;
factory.registerNodeType<MoveToPosition>("MoveToPosition");
factory.registerNodeType<IsBatteryAbove>("IsBatteryAbove");

등록된 노드는 XML에서 다음과 같이 반복적으로 참조된다.

<Sequence>
    <IsBatteryAbove threshold="0.3" />
    <MoveToPosition target_pose="{waypoint_1}" />
</Sequence>

3.2 서브트리 수준의 재사용

복합적인 행동 패턴은 **서브트리(subtree)**로 캡슐화되어 재사용된다. 서브트리는 단일 노드와 동일한 인터페이스를 제공하므로, 부모 트리의 관점에서 서브트리와 단일 노드는 구별되지 않는다.

이동 로봇의 “장애물 감지 시 정지 후 재경로” 행동을 서브트리로 정의한 경우, 이 서브트리는 실내 순찰 임무, 배송 임무, 탐사 임무 등 장애물 대응이 필요한 모든 상위 트리에서 재사용될 수 있다.

BehaviorTree.CPP에서는 XML 파일 내에서 서브트리를 정의하고, <SubTree> 태그를 통하여 참조한다.

<BehaviorTree ID="ObstacleResponse">
    <ReactiveSequence>
        <Condition ID="IsObstacleDetected" />
        <Action ID="StopMotion" />
        <Action ID="ComputeAlternativePath" />
        <Action ID="FollowAlternativePath" />
    </ReactiveSequence>
</BehaviorTree>

<!-- 다른 트리에서 재사용 -->
<BehaviorTree ID="PatrolMission">
    <Sequence>
        <SubTree ID="ObstacleResponse" />
        <Action ID="MoveToNextWaypoint" />
    </Sequence>
</BehaviorTree>

3.3 프로젝트 간 재사용

행동 트리의 재사용성은 단일 프로젝트를 넘어서 프로젝트 간(cross-project) 재사용으로 확장된다. 범용적인 노드와 서브트리를 ROS2 패키지로 배포함으로써, 서로 다른 로봇 프로젝트에서 공유할 수 있다.

Nav2는 이 원칙의 대표적 구현 사례이다. Nav2는 NavigateToPose, ComputePathToPose, FollowPath, Wait, Spin, BackUp 등의 범용 액션 노드와 IsPathValid, GoalUpdated, IsBatteryLow 등의 범용 조건 노드를 ROS2 패키지로 제공한다. 이 노드들은 특정 로봇 플랫폼에 종속되지 않으며, 적절한 ROS2 인터페이스를 구현하는 모든 로봇에서 재사용될 수 있다.

4. 재사용성과 상태 머신의 비교

유한 상태 머신에서 재사용이 어려운 근본적 원인을 행동 트리와 비교하여 분석하면 다음과 같다.

측면유한 상태 머신행동 트리
노드/상태의 인터페이스전이 규칙에 의해 정의통일된 반환 상태 인터페이스
문맥 의존성전이 규칙이 문맥을 형성노드가 문맥 독립적
재사용 시 필요한 수정전이 규칙 전체 재정의수정 불필요 (포트 연결만 변경)
재사용 단위개별 상태 재사용 곤란노드·서브트리 단위 재사용
매개변수화 지원표준적 방법 부재블랙보드 포트 기반 일반화

유한 상태 머신에서 하나의 상태를 다른 상태 머신에서 재사용하려면, 해당 상태를 포함하는 전이 규칙을 새로운 상태 머신의 맥락에 맞추어 전면 재정의하여야 한다. 이는 상태의 “재구현(reimplementation)“에 해당하며, 진정한 의미의 재사용이 아니다.

5. 재사용성을 저해하는 요인과 대응

5.1 전역 블랙보드 의존

노드가 특정 이름의 블랙보드 키에 직접 의존하면, 해당 키 이름을 사용하지 않는 다른 트리에서는 재사용이 불가능해진다. 이를 방지하기 위하여, 노드는 블랙보드 포트를 통하여 키 이름을 외부에서 매핑(remapping)받아야 한다.

<!-- 키 이름 매핑을 통한 재사용 -->
<SubTree ID="NavigateToGoal"
         target="{patrol_waypoint}" />

<SubTree ID="NavigateToGoal"
         target="{charging_station_pose}" />

위 예시에서 동일한 NavigateToGoal 서브트리가 순찰 웨이포인트와 충전소 위치라는 서로 다른 데이터에 연결되어 재사용된다.

5.2 플랫폼 특화 의존성

노드가 특정 로봇 하드웨어나 센서에 직접 의존하면, 다른 플랫폼에서의 재사용이 제한된다. 이를 완화하기 위하여, 하드웨어 추상화 계층(Hardware Abstraction Layer, HAL)과 ROS2 인터페이스를 통한 간접적 하드웨어 접근이 권장된다. 액션 노드는 ROS2 액션 클라이언트를 통하여 하드웨어를 제어하되, 구체적인 하드웨어 드라이버와의 결합은 ROS2 액션 서버 측에서 처리한다.

5.3 과도한 일반화의 위험

재사용성을 극대화하기 위하여 노드를 지나치게 일반화하면, 노드의 매개변수가 과도하게 많아져 사용의 복잡도가 증가할 수 있다. 적절한 재사용 수준은 해당 노드가 실제로 사용되는 맥락의 다양성에 의하여 결정되어야 하며, 예측되지 않는 미래의 재사용을 위한 과잉 설계(over-engineering)는 지양하여야 한다.

6. 재사용성의 검증

재사용 가능한 노드와 서브트리는 **문맥 독립적 단위 테스트(context-independent unit testing)**를 통하여 검증되어야 한다. 노드가 특정 트리 구조에 종속되지 않고 정확하게 동작함을 보이기 위하여, 개별 노드를 격리된 환경에서 테스트한다.

BehaviorTree.CPP에서는 테스트 전용 트리를 구성하여 개별 노드의 동작을 검증할 수 있다.

// 단위 테스트: MoveToPosition 노드의 독립 검증
BT::BehaviorTreeFactory factory;
factory.registerNodeType<MoveToPosition>("MoveToPosition");

auto tree = factory.createTreeFromText(R"(
    <root BTCPP_format="4">
        <BehaviorTree ID="TestTree">
            <MoveToPosition target_pose="{test_pose}" />
        </BehaviorTree>
    </root>
)");

이러한 테스트가 통과한 노드는, 어떤 트리에 삽입되더라도 동일한 동작을 보장하므로, 재사용의 신뢰성이 확보된다.

7. 참고 문헌

  • Colledanchise, M., & Ögren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
  • Colledanchise, M., & Ögren, P. (2017). “How Behavior Trees Modularize Hybrid Control Systems and Generalize Sequential Behavior Compositions, the Subsumption Architecture, and Decision Trees.” IEEE Transactions on Robotics, 33(2), 372–389.
  • Faconti, D. (2022). BehaviorTree.CPP 4.x Documentation. https://www.behaviortree.dev/
  • Iovino, M., Scukins, E., Styrud, J., Ögren, P., & Smith, C. (2022). “A Survey of Behavior Trees in Robotics and AI.” Robotics and Autonomous Systems, 154, 104096.
  • Krueger, C. W. (1992). “Software Reuse.” ACM Computing Surveys, 24(2), 131–183.
  • Macenski, S., Martín, F., White, R., & Clavero, J. G. (2020). “The Marathon 2: A Navigation System.” Proceedings of the IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS), 2718–2725.

버전: 2026-03-31