BehaviorTree.CPP 项目教程:使用 Groot2 可视化行为树

BehaviorTree.CPP 项目教程:使用 Groot2 可视化行为树

BehaviorTree.CPP Behavior Trees Library in C++. Batteries included. BehaviorTree.CPP 项目地址: https://gitcode.com/gh_mirrors/be/BehaviorTree.CPP

概述

本教程将介绍如何在 BehaviorTree.CPP 项目中集成 Groot2 可视化工具,展示如何创建自定义节点类型、生成节点模型、连接 Groot2 实时监控,以及记录行为树执行日志。

核心概念

Groot2 简介

Groot2 是 BehaviorTree.CPP 的官方可视化工具,它提供了以下功能:

  • 图形化编辑行为树
  • 实时监控行为树执行状态
  • 回放行为树执行日志
  • 调试和分析行为树

自定义数据类型可视化

BehaviorTree.CPP 允许开发者定义自己的数据类型,并通过 Groot2 可视化这些数据。本教程中的 Position2D 结构体就是一个自定义数据类型的例子。

实现步骤

1. 定义自定义数据类型

首先定义一个需要在 Groot2 中可视化的自定义结构体:

struct Position2D {
  double x;
  double y;
};

然后使用 BT_JSON_CONVERTER 宏生成 JSON 转换代码:

BT_JSON_CONVERTER(Position2D, pos) {
  add_field("x", &pos.x);
  add_field("y", &pos.y);
}

2. 创建自定义节点

创建一个更新位置信息的同步动作节点:

class UpdatePosition : public BT::SyncActionNode {
public:
  UpdatePosition(const std::string& name, const BT::NodeConfig& config)
    : BT::SyncActionNode(name, config) {}

  BT::NodeStatus tick() override {
    _pos.x += 0.2;
    _pos.y += 0.1;
    setOutput("pos", _pos);
    return BT::NodeStatus::SUCCESS;
  }

  static BT::PortsList providedPorts() {
    return { BT::OutputPort<Position2D>("pos") };
  }

private:
  Position2D _pos = { 0, 0 };
};

3. 定义行为树结构

使用 XML 格式定义行为树结构:

<root BTCPP_format="4">
  <BehaviorTree ID="MainTree">
    <Sequence>
      <Script code="door_open:=false" />
      <UpdatePosition pos="{pos_2D}" />
      <Fallback>
        <Inverter>
          <IsDoorClosed/>
        </Inverter>
        <SubTree ID="DoorClosed" _autoremap="true" door_open="{door_open}"/>
      </Fallback>
      <PassThroughDoor/>
    </Sequence>
  </BehaviorTree>

  <BehaviorTree ID="DoorClosed">
    <Fallback name="tryOpen" _onSuccess="door_open:=true">
      <OpenDoor/>
        <RetryUntilSuccessful num_attempts="5">
          <PickLock/>
        </RetryUntilSuccessful>
      <SmashDoor/>
    </Fallback>
  </BehaviorTree>
</root>

4. 主程序实现

在主程序中完成以下操作:

  1. 注册节点类型
  2. 生成节点模型 XML
  3. 注册行为树
  4. 注册自定义数据类型
  5. 创建行为树实例
  6. 连接 Groot2 发布者
  7. 设置日志记录器
int main() {
  BT::BehaviorTreeFactory factory;
  
  // 注册节点
  CrossDoor cross_door;
  cross_door.registerNodes(factory);
  factory.registerNodeType<UpdatePosition>("UpdatePosition");

  // 生成节点模型XML
  const std::string xml_models = BT::writeTreeNodesModelXML(factory);
  
  // 注册行为树
  factory.registerBehaviorTreeFromText(xml_text);
  
  // 注册自定义数据类型
  BT::RegisterJsonDefinition<Position2D>();
  
  // 创建行为树
  auto tree = factory.createTree("MainTree");
  
  // 连接Groot2发布者
  const unsigned port = 1667;
  BT::Groot2Publisher publisher(tree, port);
  
  // 设置日志记录器
  BT::FileLogger2 logger2(tree, "t11_groot_howto.btlog");
  BT::MinitraceLogger minilog(tree, "minitrace.json");
  
  // 运行行为树
  while(1) {
    tree.tickWhileRunning();
    std::this_thread::sleep_for(std::chrono::milliseconds(2000));
  }
  
  return 0;
}

关键点解析

节点模型生成

writeTreeNodesModelXML(factory) 方法会自动生成所有已注册节点的模型描述,这是 Groot2 能够正确显示和编辑这些节点的关键。

Groot2 连接

Groot2Publisher 类负责与 Groot2 建立连接,它会在指定端口(默认为1667)监听 Groot2 的连接请求,并提供以下功能:

  • 发送行为树结构
  • 实时更新节点状态
  • 支持远程控制

日志记录

BehaviorTree.CPP 提供了多种日志记录方式:

  1. FileLogger2:生成轻量级的二进制日志,可直接在 Groot2 中回放
  2. MinitraceLogger:生成 JSON 格式的日志,适合其他分析工具使用

实际应用建议

  1. 调试技巧:在开发过程中保持 Groot2 连接,可以实时观察行为树的执行状态和变量变化
  2. 性能考虑:生产环境中可以关闭 Groot2 连接以减少开销
  3. 日志分析:结合 Groot2 的回放功能,可以分析行为树的历史执行情况
  4. 自定义可视化:对于复杂数据类型,可以扩展 JSON 转换逻辑以支持更丰富的可视化效果

总结

本教程展示了如何在 BehaviorTree.CPP 项目中集成 Groot2 可视化工具,从自定义数据类型定义、节点创建、行为树设计到最终的可视化监控和日志记录。这种集成大大提高了行为树的开发效率和调试能力,是 BehaviorTree.CPP 项目开发中不可或缺的工具链组成部分。

BehaviorTree.CPP Behavior Trees Library in C++. Batteries included. BehaviorTree.CPP 项目地址: https://gitcode.com/gh_mirrors/be/BehaviorTree.CPP

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晏惠娣Elijah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值