784 字
4 分钟
Decorators (一) - Inverter
一、Inverter 节点核心解析
1. 功能定义
Inverter(逆变器 / 取反器)属于装饰器节点,仅能包含一个子节点,其执行逻辑严格遵循以下规则:
- 子节点返回 FAILURE → Inverter 返回 SUCCESS
- 子节点返回 SUCCESS → Inverter 返回 FAILURE
- 子节点返回 RUNNING → Inverter 也返回 RUNNING(运行中状态不做取反)
通俗理解:Inverter 等价于逻辑非(NOT)运算符,只改变子节点最终的成功 / 失败状态,不干扰运行中的中间状态。
2. 适用场景
当现有节点的判定逻辑与业务需求相反时,无需重新编写节点,直接用 Inverter 包装即可快速适配。
示例:
- 自定义节点
CheckObstacle:检测到障碍物返回 SUCCESS,无障碍物返回 FAILURE。 - 业务需求:无障碍物时执行后续动作 → 用 Inverter 包装
CheckObstacle,将结果取反。
二、ROS2 + BehaviorTree4.x 实战示例
基于 ROS2 Humble + BehaviorTree4.x 实现 Inverter 节点的使用,包含完整代码与解析。
1. 完整代码示例
#include "behaviortree_cpp/bt_factory.h"#include "rclcpp/rclcpp.hpp"
// 自定义测试节点:固定返回 SUCCESSclass SuccessNode : public BT::SyncActionNode{public: SuccessNode(const std::string& name) : BT::SyncActionNode(name, {}) {}
BT::NodeStatus tick() override { RCLCPP_INFO(rclcpp::get_logger("SuccessNode"), "执行SuccessNode,返回SUCCESS"); return BT::NodeStatus::SUCCESS; }};
// 自定义测试节点:固定返回 FAILUREclass FailureNode : public BT::SyncActionNode{public: FailureNode(const std::string& name) : BT::SyncActionNode(name, {}) {}
BT::NodeStatus tick() override { RCLCPP_INFO(rclcpp::get_logger("FailureNode"), "执行FailureNode,返回FAILURE"); return BT::NodeStatus::FAILURE; }};
int main(int argc, char** argv){ // 初始化 ROS2 节点 rclcpp::init(argc, argv); auto node = rclcpp::Node::make_shared("inverter_example_node");
// 1. 创建行为树工厂 BT::BehaviorTreeFactory factory;
// 2. 注册自定义节点 factory.registerNodeType<SuccessNode>("SuccessNode"); factory.registerNodeType<FailureNode>("FailureNode");
// 3. 定义行为树结构(使用 Inverter 装饰器) std::string xml_text = R"( <root BTCPP_format="4"> <BehaviorTree ID="InverterExample"> <Sequence> <!-- 测试1:Inverter 包裹 SuccessNode,预期返回 FAILURE --> <Inverter> <SuccessNode/> </Inverter> <!-- 测试2:Inverter 包裹 FailureNode,预期返回 SUCCESS --> <Inverter> <FailureNode/> </Inverter> </Sequence> </BehaviorTree> </root> )";
// 4. 创建行为树 auto tree = factory.createTreeFromText(xml_text);
// 5. 执行行为树 RCLCPP_INFO(node->get_logger(), "开始执行行为树..."); BT::NodeStatus status = tree.tickWhileRunning();
// 6. 输出最终结果 RCLCPP_INFO(node->get_logger(), "行为树执行完成,最终状态:%s", BT::toStr(status).c_str());
rclcpp::shutdown(); return 0;}2. 代码核心解释
| 代码模块 | 功能说明 |
|---|---|
自定义节点 SuccessNode / FailureNode | 分别固定返回 SUCCESS 和 FAILURE, 用于验证 Inverter 的取反效果 |
| 行为树 XML 结构 | 用 Sequence 顺序节点串联两个 Inverter 测试用例,直观展示取反逻辑 |
tree.tickWhileRunning() | 持续执行行为树,直到无节点处于 RUNNING 状态 |
3. 预期输出
运行代码后终端输出如下(核心关注 Inverter 对单个节点的取反效果):
[INFO] [SuccessNode]: 执行SuccessNode,返回SUCCESS[INFO] [FailureNode]: 执行FailureNode,返回FAILURE[INFO] [inverter_example_node]: 行为树执行完成,最终状态:FAILURE注:Sequence 节点的执行逻辑是所有子节点成功才返回 SUCCESS,第一个 Inverter 返回 FAILURE,因此最终 Sequence 状态为 FAILURE。
三、ROS2 中 XML 文件单独定义 Inverter
ROS2 行为树开发中,常通过 XML 文件解耦逻辑与代码,以下是 Inverter 的 XML 示例:
<root BTCPP_format="4"> <BehaviorTree ID="InverterTest"> <!-- 对障碍物检测节点取反,实现“无障碍物”判定逻辑 --> <Inverter name="InvertObstacleCheck"> <CheckObstacle/> <!-- 自定义障碍物检测节点 --> </Inverter> </BehaviorTree></root> 分享
如果这篇文章对你有帮助,欢迎分享给更多人!
Decorators (一) - Inverter
https://github.com/qingfeng3374-lab 部分信息可能已经过时









