DecoratorNode 기반 클래스의 인터페이스 (Interface of the DecoratorNode Base Class)
1. 개요
BT::DecoratorNode는 BehaviorTree.CPP에서 모든 데코레이터 노드의 기반이 되는 추상 클래스이다. 이 클래스는 단일 자식 관리, halt 전파, 기본 tick 프레임워크 등의 공통 기능을 제공하며, 사용자 정의 데코레이터는 이 클래스를 상속하여 tick() 메서드를 구현한다.
2. 클래스 선언
namespace BT
{
class DecoratorNode : public TreeNode
{
public:
DecoratorNode(const std::string& name,
const NodeConfiguration& config);
virtual ~DecoratorNode() override = default;
// 자식 노드 설정 (팩토리에 의해 호출)
void setChild(TreeNode* child);
// 자식 접근자
const TreeNode* child() const;
TreeNode* child();
// halt: 자식 halt 후 자신을 IDLE로 전환
virtual void halt() override;
// 노드 유형 반환
NodeType type() const override
{
return NodeType::DECORATOR;
}
protected:
// 자식이 RUNNING이면 halt 호출
void haltChild();
TreeNode* child_node_;
};
}
3. 주요 메서드 상세
3.1 setChild()
void setChild(TreeNode* child);
데코레이터의 자식 노드를 설정한다. BehaviorTreeFactory가 XML을 파싱할 때 자동으로 호출되며, 사용자가 직접 호출하는 경우는 드물다.
3.2 child()
TreeNode* child();
const TreeNode* child() const;
자식 노드에 대한 포인터를 반환한다. tick() 메서드 내부에서 child_node_를 직접 접근하는 것이 일반적이나, 이 접근자를 통해서도 가능하다.
3.3 halt()
virtual void halt() override;
기본 구현:
haltChild()호출하여 자식의 실행을 중단- 자신의 상태를
IDLE로 설정
사용자 정의 데코레이터에서 오버라이드할 때는, 자신의 내부 상태를 초기화한 후 기반 클래스의 halt()를 호출한다.
void MyDecorator::halt() override
{
my_counter_ = 0; // 내부 상태 초기화
DecoratorNode::halt(); // 기반 클래스 호출
}
3.4 haltChild()
void haltChild();
자식이 RUNNING 상태인 경우에만 자식의 halt() 메서드를 호출하고, 자식의 상태를 IDLE로 설정한다. 자식이 이미 SUCCESS, FAILURE, 또는 IDLE 상태이면 아무 동작도 수행하지 않는다.
4. tick()의 구현 규약
4.1 필수 호출: executeTick()
자식을 tick할 때는 반드시 child_node_->executeTick()을 사용한다.
// 올바름
auto status = child_node_->executeTick();
// 부적절 (상태 관리 로직 누락)
auto status = child_node_->tick();
executeTick()은 tick()을 호출하기 전에 노드의 상태 전이 로직(IDLE→RUNNING 등)을 처리한다.
4.2 setStatus() 호출
tick() 메서드 시작 시 setStatus(NodeStatus::RUNNING)을 호출하여 데코레이터의 상태를 RUNNING으로 설정한다.
BT::NodeStatus tick() override
{
setStatus(BT::NodeStatus::RUNNING);
// ...
}
5. providedPorts()의 정의
입력/출력 포트가 필요한 데코레이터는 정적 providedPorts() 메서드를 정의한다.
static BT::PortsList providedPorts()
{
return {
BT::InputPort<int>("max_count", 5, "최대 횟수"),
BT::InputPort<double>("timeout_sec", 10.0, "타임아웃")
};
}
6. 설계 시 고려 사항
6.1 단일 자식 보장
DecoratorNode는 단일 child_node_ 포인터만 유지하므로, 복수의 자식을 설정하면 이전 자식이 대체된다. XML 파서가 이를 강제하므로, 런타임에서는 이 문제가 발생하지 않는다.
6.2 가상 소멸자
DecoratorNode는 가상 소멸자를 가지므로, 파생 클래스에서 동적 할당된 리소스를 안전하게 해제할 수 있다.
7. 참고 문헌
- BehaviorTree.CPP 공식 문서. https://www.behaviortree.dev/
- BehaviorTree.CPP 소스 코드. https://github.com/BehaviorTree/BehaviorTree.CPP
| 버전 | 날짜 | 변경 사항 |
|---|---|---|
| v0.1 | 2026-04-05 | 초안 작성 |