mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
1003 字
5 分钟
Decorators (二) - ForceSuccess & ForceFailure

一、ForceSuccess & ForceFailure 核心解析#

这两个节点同样是装饰器节点(仅包含一个子节点),核心逻辑比 Inverter 更简单:强制修改子节点的最终返回状态,具体规则如下:

节点类型核心功能
ForceSuccess执行子节点一次,无论子节点返回 FAILURE/SUCCESS
最终都返回 SUCCESS;若子节点返回 RUNNING
则自身也返回 RUNNING
ForceFailure执行子节点一次,无论子节点返回 FAILURE/SUCCESS
最终都返回 FAILURE;若子节点返回 RUNNING
则自身也返回 RUNNING

适用场景#

  • ForceSuccess:即使某个子节点执行失败,也不想让整个分支中断(比如“尝试发送消息失败,但不影响后续逻辑”)。
  • ForceFailure:即使某个子节点执行成功,也需要强制让分支判定为失败(比如“检测到目标但权限不足,强制终止任务”)。

二、ROS2 + BehaviorTree4.x 实战示例#

下面基于你熟悉的代码结构,展示这两个节点的使用(兼容 ROS2 Humble + BehaviorTree4.x)。

1. 完整代码示例#

#include "behaviortree_cpp/bt_factory.h"
#include "rclcpp/rclcpp.hpp"
// 自定义测试节点:可通过参数控制返回状态
class ControllableNode : public BT::SyncActionNode
{
public:
// 构造函数:接收节点名称 + 参数(返回SUCCESS/FAILURE)
ControllableNode(const std::string& name, const BT::NodeConfig& config)
: BT::SyncActionNode(name, config) {}
// 定义输入参数(控制返回状态)
static BT::PortsList providedPorts()
{
return { BT::InputPort<std::string>("return_status", "SUCCESS or FAILURE") };
}
// 核心执行逻辑:根据参数返回指定状态
BT::NodeStatus tick() override
{
std::string status_str;
// 获取输入参数
if (!getInput("return_status", status_str)) {
RCLCPP_ERROR(rclcpp::get_logger("ControllableNode"), "未设置return_status参数");
return BT::NodeStatus::FAILURE;
}
// 根据参数返回状态
if (status_str == "SUCCESS") {
RCLCPP_INFO(rclcpp::get_logger("ControllableNode"), "执行ControllableNode,返回SUCCESS");
return BT::NodeStatus::SUCCESS;
} else if (status_str == "FAILURE") {
RCLCPP_INFO(rclcpp::get_logger("ControllableNode"), "执行ControllableNode,返回FAILURE");
return BT::NodeStatus::FAILURE;
} else {
RCLCPP_WARN(rclcpp::get_logger("ControllableNode"), "参数无效,默认返回FAILURE");
return BT::NodeStatus::FAILURE;
}
}
};
int main(int argc, char** argv)
{
// 初始化ROS2节点
rclcpp::init(argc, argv);
auto node = rclcpp::Node::make_shared("force_nodes_example_node");
// 1. 创建行为树工厂
BT::BehaviorTreeFactory factory;
// 2. 注册自定义节点
factory.registerNodeType<ControllableNode>("ControllableNode");
// 3. 定义行为树结构:测试ForceSuccess和ForceFailure
std::string xml_text = R"(
<root BTCPP_format="4">
<BehaviorTree ID="ForceNodesExample">
<Sequence>
<!-- 测试1:ForceSuccess包裹返回FAILURE的节点 → 最终返回SUCCESS -->
<ForceSuccess>
<ControllableNode return_status="FAILURE"/>
</ForceSuccess>
<!-- 测试2:ForceFailure包裹返回SUCCESS的节点 → 最终返回FAILURE -->
<ForceFailure>
<ControllableNode return_status="SUCCESS"/>
</ForceFailure>
<!-- 测试3:ForceSuccess包裹返回SUCCESS的节点 → 仍返回SUCCESS -->
<ForceSuccess>
<ControllableNode return_status="SUCCESS"/>
</ForceSuccess>
</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. 代码核心解释#

  • ControllableNode:可通过输入参数 return_status 控制返回 SUCCESSFAILURE,比固定返回的节点更灵活,能全面测试 Force 系列节点的效果。
  • 行为树结构:用 Sequence 串联 3 个测试用例:
    • ForceSuccess + 返回 FAILURE 的子节点 → 最终返回 SUCCESS
    • ForceFailure + 返回 SUCCESS 的子节点 → 最终返回 FAILURE
    • ForceSuccess + 返回 SUCCESS 的子节点 → 仍返回 SUCCESS(验证“强制成功”对成功状态无影响)
  • 参数传递:通过 XML 属性 return_status="FAILURE" 给自定义节点传参,这是 ROS2 行为树中传递参数的标准方式。

3. 预期输出#

运行代码后终端输出如下(重点看 Force 节点对结果的覆盖效果):

[INFO] [ControllableNode]: 执行ControllableNode,返回FAILURE
[INFO] [ControllableNode]: 执行ControllableNode,返回SUCCESS
[INFO] [ControllableNode]: 执行ControllableNode,返回SUCCESS
[INFO] [force_nodes_example_node]: 行为树执行完成,最终状态:FAILURE

注:Sequence 节点第二个子节点(ForceFailure)返回 FAILURE,因此整个 Sequence 最终状态为 FAILURE,符合预期。

三、XML 文件单独定义(ROS2 常用方式)#

force_nodes_example.xml
<root BTCPP_format="4">
<BehaviorTree ID="ForceNodesTest">
<!-- 场景1:即使传感器检测失败,也强制判定为成功,继续执行后续逻辑 -->
<ForceSuccess name="ForceSensorSuccess">
<SensorCheck/> <!-- 自定义传感器检测节点 -->
</ForceSuccess>
<!-- 场景2:即使任务执行成功,也强制判定为失败,终止当前分支 -->
<ForceFailure name="ForceTaskFailure">
<TaskExecute/> <!-- 自定义任务执行节点 -->
</ForceFailure>
</BehaviorTree>
</root>
分享

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

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

部分信息可能已经过时

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