조건 노드 설계의 모범 사례 (Best Practices for Condition Node Design)

조건 노드 설계의 모범 사례 (Best Practices for Condition Node Design)

1. 개요

조건 노드 설계의 모범 사례는 조건 노드를 올바르고, 효율적이며, 유지보수 가능하게 구현하기 위한 지침을 정리한 것이다. 이 지침들은 행동 트리의 이론적 원칙, BehaviorTree.CPP의 프레임워크 규약, 로봇 시스템의 안전 요구를 종합하여 도출된 것으로, 조건 노드 설계 시 준수하여야 할 핵심 원칙과 실무적 권장 사항을 다룬다.

2. 핵심 설계 원칙의 준수

2.1 즉시 반환 원칙

조건 노드는 항상 SUCCESS 또는 FAILURE를 즉시 반환하여야 한다. RUNNING 상태를 반환하여서는 안 되며, 차단(blocking) 호출을 포함하여서도 안 된다.

// 올바른 구현
BT::NodeStatus tick() override
{
    if (checkCondition())
        return BT::NodeStatus::SUCCESS;
    return BT::NodeStatus::FAILURE;
}

2.2 부작용 금지 원칙

조건 노드는 외부 상태를 변경하여서는 안 된다. 토픽 발행, 서비스 호출(상태 변경형), 파일 쓰기 등의 부작용을 포함하지 않아야 한다.

2.3 단일 책임 원칙

하나의 조건 노드는 하나의 조건만을 평가하여야 한다. 복수의 관련 없는 조건을 단일 노드에서 평가하면 재사용성이 떨어지고 테스트가 어려워진다.

2.4 실패 안전 원칙

데이터가 부재하거나 유효하지 않은 경우, 보수적으로 FAILURE를 반환한다. 특히 안전 관련 조건에서는 “모르면 위험으로 간주“하는 정책을 적용한다.

3. 명명 규약

3.1 조건 노드 이름

조건 노드의 이름은 질문 형식으로, Is, Has, Are, Can 등의 접두어를 사용한다.

권장 이름비권장 이름
IsBatteryAboveCheckBattery
IsObstacleDetectedObstacleDetector
HasTimeoutElapsedTimeout
IsPathValidValidatePath
AreAllSensorsReadySensorCheck

이름만으로 노드가 무엇을 판정하는지를 명확히 알 수 있어야 한다.

3.2 SUCCESS의 의미론적 일관성

조건 노드의 SUCCESS가 의미하는 바가 직관적이어야 한다. IsObstacleDetectedSUCCESS를 반환하면 장애물이 감지된 것이고, IsPathClearSUCCESS를 반환하면 경로가 비어 있는 것이다. 이중 부정을 피하여야 한다.

4. 입력 포트 설계

4.1 의미 있는 기본값 설정

static BT::PortsList providedPorts()
{
    return {
        BT::InputPort<double>("min_percentage", 0.2,
            "최소 요구 잔량 비율 (0.0~1.0)")  // 기본값 20%
    };
}

4.2 단위 명시

포트 설명에 물리량의 단위를 명시한다.

BT::InputPort<double>("max_speed", 2.0, "최대 허용 속도 (m/s)")
BT::InputPort<double>("max_angle", 0.5236, "최대 허용 각도 (rad)")
BT::InputPort<double>("timeout", 5.0, "타임아웃 (초)")

4.3 토픽 이름의 매개변수화

토픽 이름을 입력 포트로 받아 XML에서 설정할 수 있도록 한다.

5. 데이터 유효성 검증

5.1 입력 데이터 검증 체크리스트

검증 항목방법
메시지 수신 여부msg != nullptr
수치 유효성std::isfinite()
배열 비어 있음!msg->ranges.empty()
범위 내 값range >= range_min && range <= range_max
센서 존재msg->present == true
공분산 유효성covariance[0] >= 0

6. 성능 최적화

6.1 비용 기반 캐싱

계산 비용이 높은 조건에만 캐싱을 적용한다. 블랙보드 값 비교와 같이 가벼운 조건에는 캐싱이 불필요하다.

6.2 뮤텍스 잠금 범위 최소화

토픽 콜백과 tick 스레드 사이의 뮤텍스 잠금 구간을 최소화하여 성능 영향을 줄인다.

6.3 불필요한 계산 회피

조건 평가에 필요하지 않은 데이터 처리를 포함하지 않는다.

7. 테스트 가능성

7.1 의존성 주입

ROS2 노드, 시간 소스 등의 외부 의존성을 생성자 매개변수로 주입받아 테스트 시 모의 객체로 대체할 수 있도록 한다.

7.2 순수 평가 로직 분리

토픽 구독과 조건 평가 로직을 분리하여, 평가 로직만을 독립적으로 테스트할 수 있도록 한다.

8. 문서화

8.1 포트 설명의 완전성

모든 입력 포트에 설명, 타입, 기본값, 단위를 명시한다.

8.2 SUCCESS/FAILURE의 의미 문서화

노드의 반환 상태가 각각 무엇을 의미하는지를 명확히 문서화한다.

9. 참고 문헌

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