mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
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"
// 自定义测试节点:固定返回 SUCCESS
class 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;
}
};
// 自定义测试节点:固定返回 FAILURE
class 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分别固定返回 SUCCESSFAILURE
用于验证 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 示例:

inverter_example.xml
<root BTCPP_format="4">
<BehaviorTree ID="InverterTest">
<!-- 对障碍物检测节点取反,实现“无障碍物”判定逻辑 -->
<Inverter name="InvertObstacleCheck">
<CheckObstacle/> <!-- 自定义障碍物检测节点 -->
</Inverter>
</BehaviorTree>
</root>
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Decorators (一) - Inverter
https://github.com/qingfeng3374-lab
作者
suilli
发布于
2026-01-15
许可协议
Apache 2.0

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00