BT9:各种调试工具介绍

大家好,欢迎大家关注我的知乎专栏慢慢悠悠小马车


1、Groot

Groot是与BehaviorTree.CPP搭配使用的工具,分为Editor、Monitor、Log Replay 3种模式,具有行为树编辑、状态监控、历史log回放等功能。

BT9:各种调试工具介绍_第1张图片

GitHub - BehaviorTree/Groot: Graphical Editor to create BehaviorTrees. Compliant with BehaviorTree.CPPGraphical Editor to create BehaviorTrees. Compliant with BehaviorTree.CPP - GitHub - BehaviorTree/Groot: Graphical Editor to create BehaviorTrees. Compliant with BehaviorTree.CPPhttps://github.com/BehaviorTree/Groot

入门使用指引https://navigation.ros.org/tutorials/docs/using_groot.html#groot-introduction%C2%A0在Groot中可以图形化的方式创建节点(node),为节点添加输入输出端口(port),可以像Visio一样拖动、连接节点,从而构造行为树,而无需在意节点代码是否完成。将树保存、导出为xml文件,可以被BehaviorTree.CPP的接口读入并解析。这样就可以避免开发者自行编写xml文件的复杂局面。

如BehaviorTree.CPP/examples/t03_generic_ports.cpp中这样定义了一棵行为树:


     
        
            
            
            
            
        
     

在Groot中依此创建,如图所示:

BT9:各种调试工具介绍_第2张图片

将其保存为xml文件,如下所示。和上段代码的区别在于缺失了blackboard entry的指定,增加了node的类型。其实这2段代码都可以被Groot加载和解析。



    
    
        
            
            
            
            
        
    
    
    
        
            
        
        
            Simply print the target on console...
        
    
    

 2、StdCoutLogger

作用:在终端打印行为树中的节点执行状态变化。

代码仅需在加载tree后添加StdCoutLogger类的1个实例(且只能有1个实例),运行效果如下:

BT9:各种调试工具介绍_第3张图片

BehaviorTree.CPP/examples/t05_crossdoor.cpp中也有本文各工具的使用示例。

3、FileLogger

作用:行为树中的节点执行状态变化保存在文件中(必须是*.fbl格式文件),可以通过Groot打开并回放执行过程。

代码仅需在加载tree后添加FileLogger类的1个实例,运行效果如下:

BT9:各种调试工具介绍_第4张图片

Groot选择Log Replay模式后加载bt_trace.fbl,如下。当选中左侧的节点时,右侧会通过线条的颜色来表示执行的状态(绿色-SUCCESS,橙色-RUNNING,青色-未执行)。

BT9:各种调试工具介绍_第5张图片

 4、MinitraceLogger

作用:保存节点的执行时序。

代码仅需在加载tree后添加FileLogger类的1个实例(且只能有1个实例),运行效果如下:

 生成的json文件内容如下:

BT9:各种调试工具介绍_第6张图片

5、PublisherZMQ

作用:在节点执行的同时发布其状态变化,在Groot中实时观察。

代码仅需在加载tree后添加PublisherZMQ类的1个实例(且只能有1个实例)。

Groot需要选择Monitor模式,并设置下列输入。如果行为树与Groot都在同一台机器运行的话,就自发自收,Server IP可以设置为“127.0.0.1”,Publisher Port设置为“1666”,Server Port设置为“1667”。

Groot会自动获得树的结构,无需用户手动加载,但是它会自动展开1棵树中的所有子树,使得界面内容非常密集,因此复杂的树并不方便观察。

BT9:各种调试工具介绍_第7张图片

6、printTreeRecursively()内置函数

作用:层级打印树结构,默认打印在终端。

该函数定义在BehaviorTree.CPP/include/behaviortree_cpp_v3/behavior_tree.h中,声明和运行效果如下。

void printTreeRecursively(const TreeNode* root_node);

BT9:各种调试工具介绍_第8张图片

7、debugMessage()内置函数

打印不同的树之间的端口(port)映射关系,也可以反映出port是否被设置值。

该函数定义在BehaviorTree.CPP/include/behaviortree_cpp_v3/blackboard.h中。BehaviorTree.CPP/examples/t06_subtree_port_remapping.cpp有代码示例。

void Blackboard::debugMessage() const {
  for (const auto& entry_it : storage_) {
    auto port_type = entry_it.second.port_info.type();
    if (!port_type) {
      port_type = &(entry_it.second.value.type());
    }
    std::cout << entry_it.first << " (" << demangle(port_type) << ") -> ";

    if (auto parent = parent_bb_.lock()) {
      auto remapping_it = internal_to_external_.find(entry_it.first);
      // if条件满足,说明有port外部映射
      if (remapping_it != internal_to_external_.end()) {
        std::cout << "remapped to parent [" << remapping_it->second << "]"
                  << std::endl;
        continue;
      }
    }
    // 若此处打印,而不是在上面continue处返回,说明没有外部映射
    // empty表明该port没有值(从未被设置值),无法读取,读取会抛出异常
    // full表明该port有值,可以被读取
    std::cout << ((entry_it.second.value.empty()) ? "empty" : "full")
              << std::endl;
  }
}

你可能感兴趣的:(行为树,行为树,机器人,状态机,决策,自动驾驶)