添加 TreeNodesModel

使用Groot打开行为树文件,有时会报警一大堆:不识别某Action,这是因为xml文件必须具备 TreeNodesModel才能让Groot识别。显然xml的作者不太会用行为树。

此外它还需要:节点类型,端口的名称和类型(输入/输出)。我们不需要手动去添加,工作了太大了。行为树提供了函数来生成:

1
2
3
4
5
BT::BehaviorTreeFactory factory;  
// register here your user-defined Nodes

std::string xml_models = BT::writeTreeNodesModelXML(factory);
cout << xml_models <<endl;

可以将 XML 保存到文件中,然后点击 Groot2 中的导入模型按钮。或者手动将输出的 xml_models直接添加到 .xml文件中。

也就是需要先定义Node,然后注册。才能调用writeTreeNodesModelXML,否则不识别Action的名称。当然也必须在 createTreeFromFile之后。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include "behaviortree_cpp_v3/action_node.h"
#include "behaviortree_cpp_v3/xml_parsing.h"
#include "behaviortree_cpp_v3/bt_factory.h"
#include "behaviortree_cpp_v3/behavior_tree.h"

using namespace std;
using namespace BT;

class MyClass : public BT::SyncActionNode
{
public:
MyClass(const std::string& name, [[maybe_unused]] const BT::NodeConfiguration& config):
BT::SyncActionNode(name, {})
{
}
~MyClass()
{
}
static BT::PortsList providedPorts()
{
return {BT::InputPort<string>("input_code","NULL_ERROR","error code "),
BT::InputPort<string>("input_action","NULL_ACTION","input action ")};
}
BT::NodeStatus tick()
{
return BT::NodeStatus::SUCCESS;
}
};

int main([[maybe_unused]] int argc, [[maybe_unused]] char ** argv)
{
BT::BehaviorTreeFactory factory;
factory.registerNodeType<MyClass>("ClassName");

auto tree = factory.createTreeFromFile("/home/user/bt.xml");

std::string xmlmodels = BT::writeTreeNodesModelXML(factory);
cout << endl << xmlmodels << endl;

return 0;
}