BehaviorTree.CPP行为树学习:subtree 和 loggers

子树和日志记录器

Composition of Behaviors with Subtree

【带有子树的行为树】

原英文网站:Tutorial 5: Subtrees and Loggers - BehaviorTree.CPP

We can build large scale behavior composing together smaller and reusable behaviors into larger ones.

In other words, we want to create hierarchical behavior trees.

This can be achieved easily defining multiple trees in the XML including one into the other.

【我们可以构建大规模行为树,将较小的可重用行为组合成较大的行为。

换句话说,我们想要创建层次化的行为树。

这可以很容易地在XML中定义多个树,一个树包含另一个树。】

CrossDoor behavior

【穿过门行为树】

This example is inspired by a popular article about behavior trees.

【‎此示例的灵感来自一‎‎篇关于行为树‎‎的流行文章。‎】

It is also the first practical example that uses and .Decorators Fallback

【Decorator 和 Fallback 是第一个使用子树的实际示例。】

<root main_tree_to_execute = "MainTree">

    <BehaviorTree ID="DoorClosed">
        <Sequence name="door_closed_sequence">
            <Inverter>
                <IsDoorOpen/>
            </Inverter>
            <RetryUntilSuccessful num_attempts="4">
                <OpenDoor/>
            </RetryUntilSuccessful>
            <PassThroughDoor/>
        </Sequence>
    </BehaviorTree>

    <BehaviorTree ID="MainTree">
        <Fallback name="root_Fallback">
            <Sequence name="door_open_sequence">
                <IsDoorOpen/>
                <PassThroughDoor/>
            </Sequence>
            <SubTree ID="DoorClosed"/>
            <PassThroughWindow/>
        </Fallback>
    </BehaviorTree>

</root>

 

For readability, our custom nodes are registered with the one-liner:

【‎为了便于阅读,我们的自定义节点使用下面代码进行注册:‎】

CrossDoor::RegisterNodes(factory);

Default nodes provided by the BT library such as Fallback are already registered by the BehaviorTreeFactory.

【BT库提供的默认节点(如Fallback)已由BehaviorTreeFactory注册。】

It may be noticed that we encapsulated a quite complex branch of the tree, the one to execute when the door is closed, into a separate tree called DoorClosed.

【我们将 “关门”这个复杂的部分单独封装成一个子树,它将在门关闭时执行,它被单独的成为“DoorClosed.”(子树)】

The desired behavior is:

  • If the door is open, .PassThroughDoor
  • If the door is closed, try up to 4 times to and, then, .OpenDoorPassThroughDoor
  • If it was not possible to open the closed door, .PassThroughWindow

【期望的行为是

  • 如果门是开着的,穿过门
  • 如果门是关闭,最多尝试4次,然后尝试.开门并穿过门
  • 如果无法打关闭的门,则从窗户进去】

 

Loggers

【日志】

On the C++ side we don't need to do anything to build reusable subtrees.

【在C++中,我们不想做任何事情去构建重复的子树】

Therefore we take this opportunity to introduce another neat feature of BehaviorTree.CPP : Loggers.

【因此,我们借此机会介绍行为树的另外一个简洁的特性:日志记录器】

A Logger is a mechanism to display, record and/or publish any state change in the tree.

【日志记录器是一种在显示、记录任何状态改变的工具机制】

int main()
{
    using namespace BT;
    BehaviorTreeFactory factory;

    // register all the actions into the factory
    // We don't show how these actions are implemented, since most of the 
    // times they just print a message on screen and return SUCCESS.
    // See the code on Github for more details.
    factory.registerSimpleCondition("IsDoorOpen", std::bind(IsDoorOpen));
    factory.registerSimpleAction("PassThroughDoor", std::bind(PassThroughDoor));
    factory.registerSimpleAction("PassThroughWindow", std::bind(PassThroughWindow));
    factory.registerSimpleAction("OpenDoor", std::bind(OpenDoor));
    factory.registerSimpleAction("CloseDoor", std::bind(CloseDoor));
    factory.registerSimpleCondition("IsDoorLocked", std::bind(IsDoorLocked));
    factory.registerSimpleAction("UnlockDoor", std::bind(UnlockDoor));

    // Load from text or file...
    auto tree = factory.createTreeFromText(xml_text);

    // This logger prints state changes on console
    StdCoutLogger logger_cout(tree);

    // This logger saves state changes on file
    FileLogger logger_file(tree, "bt_trace.fbl");

    // This logger stores the execution time of each node
    MinitraceLogger logger_minitrace(tree, "bt_trace.json");

#ifdef ZMQ_FOUND
    // This logger publish status changes using ZeroMQ. Used by Groot
    PublisherZMQ publisher_zmq(tree);
#endif

    printTreeRecursively(tree.rootNode());

    //while (1)
    {
        NodeStatus status = NodeStatus::RUNNING;
        // Keep on ticking until you get either a SUCCESS or FAILURE state
        while( status == NodeStatus::RUNNING)
        {
            status = tree.tickRoot();
            // IMPORTANT: you must always add some sleep if you call tickRoot()
            // in a loop, to avoid using 100% of your CPU (busy loop).
            // The method Tree::sleep() is recommended, because it can be
            // interrupted by an internal event inside the tree.
            tree.sleep( milliseconds(10) );
        }
        if( LOOP )
        {
            std::this_thread::sleep_for( milliseconds(1000) );
        }
    }
    return 0;
}

 

【说明】

BehaviorTree.CPP行为树学习系列是翻译自源英文网站,由于个人知识能力水平有限,如有错误的地方,请在评论区留言,会不断修改和完善的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值