行为树保姆级教程(以机器人的任务规划为例

行为树

目录

  • 什么是行为树(behavior tree)?
  • 行为树的相关术语
    • 行为节点和控制节点
    • 不同类型的控制结点:
      • 顺序节点
      • 选择节点
      • 并行节点
      • 装饰结点
  • 机器人的例子:物体搜索
    • 1:如果只存在一个地点A,那么行为树很简单,到A处,找到物体。如下图所示:
    • 2:接下来我们使用一个条件结点,用来判断机器人是否找到了物体(具体实现可以通过相机拍摄照片,然后进行图像识别)。
    • 3:我们的机器人工作的环境可能包含了多个地点,我们期望它可以尝试到所有已知的地点搜寻物体,在搜寻到物体后结束搜索。这可以通过添加一个选择结点作为根节点来实现,如下图所示:
    • 4:如果我们期望机器人可以同时搜寻多个不同的物体(比如苹果和橘子),可以通过添加并行结点实现。
  • 装饰器(decorator)和黑板(blackboard)
  • 行为树和有限状态机的比较
    • 1:以机器人捡起一个物体的任务为例,这需要机器人先移动到物体附近,然后夹起物体,最后再移动回机器人原来所处的位置。我们分别用行为树和状态机实现它们,如下图所示:
    • 2:如果我们想要进一步修改行为,比如检测夹子是否处于可以抓起物体的位置,然后再夹紧夹子。对于行为树,我们只需要插入一个子树就能完成期望的修改。但对于状态机,我们需要重写多个转换操作。也就是说行为树更便于进行组合(modularity)和模块化。下图给出了修改后的行为树和状态机图示:
    • 3:对于反应式行为,比如机器人低电量时需要马上回到电源处,即使它还在执行某个任务的过程中。如果使用行为树来实现,这会非常麻烦,我们需要在任意任务的子树中支持充电行为。但对于状态机来说,实现起来就很简单,只需要从所有其它动作连线到充电动作即可。
    • 状态机和行为树联合使用

参考原文:https://robohub.org/introduction-to-behavior-trees/

参考翻译:https://zhuanlan.zhihu.com/p/463182588

什么是行为树(behavior tree)?

行为树(behavior tree)是用来实现非人工角色复杂行为的工具,它具有下面这些特征:

  1. 行为树是树: 执行时从根结点开始按照指定的顺序遍历,直到到达终结状态
  2. **叶子结点都是可执行的行为:**叶子结点会进行具体的操作,可以是一个简单的检测操作,也可以是一个更复杂的操作,结点会返回状态信息(成功,失败,运行中)。
  3. 内部结点控制树的遍历:内部结点会根据孩子结点返回的状态信息,按照特定的规则确定下一个执行的结点。

在这里插入图片描述

行为树的相关术语

行为节点和控制节点

下图给出了行为树的不同结点类型及其对应的图示:

  1. tick:行为树从根节点开始按照预定义的顺序遍历各个节点并执行他们的行为的过程称为一次tick,会返回成功(success)失败(failure)运行中(running) 的状态信息给它的父结点。
  2. 行为结点(execution node):行为树的叶子结点,可以是动作结点(action node)或条件结点(condition node)。对于条件结点(condition node)会在一次tick后立马返回成功或失败的状态信息。对于动作结点(action node)则可以跨越多个tick执行,直到到达它的终结状态。一般来说,条件结点用于简单的判断(比如钳子是否打开?),动作结点用于表示复杂的行为(比如打开房门)。
  3. 控制结点(control node):控制结点是行为树的内部结点,它们定义了遍历其孩子结点的方式。控制结点的孩子可以是行为结点,也可以是控制结点顺序(Sequence)备选(Fallback)并行(Parallel)这3种类型的控制结点可以有任意数量的孩子结点,它们的区别在于对其孩子结点的处理方式。而装饰(Decorator)结点只能有一个孩子结点,用来对孩子结点的行为进行自定义修改。

不同类型的控制结点:

顺序节点

按顺序执行孩子结点直到其中一个孩子结点返回失败状态或所有孩子结点返回成功状态。

在这里插入图片描述

选择节点

按顺序执行孩子结点直到其中一个孩子结点返回成功状态或所有孩子结点返回失败状态。一般用来实现角色的选择行为。

并行节点

“并行执行”所有孩子结点。直到至少M个孩子(M的值在1到N之间)结点返回成功状态或所有孩子结点返回失败状态。

在这里插入图片描述

装饰结点

装饰结点:以自定义的方式修改孩子结点的行为。比如Invert类型的装饰结点,可以反转其孩子结点返回的状态信息。为了方便他人理解,应该尽可能使用比较常见的装饰结点。

机器人的例子:物体搜索

接下来我们通过一个机器人搜索物体的例子来理解行为树的执行过程。

在这里插入图片描述

1:如果只存在一个地点A,那么行为树很简单,到A处,找到物体。如下图所示:

上图中我们使用了一控制结点表示到A处这一动作。在机器人还没有移动到A处前,这一动作结点会返回运行中(running)状态。

2:接下来我们使用一个条件结点,用来判断机器人是否找到了物体(具体实现可以通过相机拍摄照片,然后进行图像识别)。

行为树的一个很常用的设计规则就是使用显式成功条件(explicit success condition)。简单来说,就是在执行动作前总是先进行条件检测。比如,先检测机器人是否已经在A处,如果在就不执行去A处的动作,直接返回成功状态。如下图所示:

3:我们的机器人工作的环境可能包含了多个地点,我们期望它可以尝试到所有已知的地点搜寻物体,在搜寻到物体后结束搜索。这可以通过添加一个选择结点作为根节点来实现,如下图所示:

在这里插入图片描述

我们可以使用选择结点(fallback node)定义角色的反应行为。当一种反应行为无法工作后,自动尝试下一种。

4:如果我们期望机器人可以同时搜寻多个不同的物体(比如苹果和橘子),可以通过添加并行结点实现。

下图给出了在多个地点,同时搜寻苹果和橘子的行为树图示:

我们可以使用并行结点组合多个动作,比如:让机器人原地打转直到连续5个tick识别到一个人为止。

装饰器(decorator)和黑板(blackboard)

📌装饰器(decorator)

我们可以使用装饰器结点(decorator node)来对行为树进行优化。考虑上面的在多个地点搜寻物体的行为树,如果地点数目达到20个以上,整个行为树看上去就会变得非常庞大,也为我们进一步添加新的结点带来麻烦。

下面是避免这些麻烦的常用方法:

  • 引入装饰器结点(decorator node) 相较于每增加一个搜寻地点就复制一份完全相同的子树,我们可以定义一个规则为Repeat的装饰器结点,用来重复执行它的孩子结点,完成搜寻多个地点。
  • 在每一次迭代更新目标位置**:** 使用一个队列存储所有待搜寻地点,每次迭代从队列中取出一个地点进行搜寻,当队列为空时,所有地点都被搜寻完毕。

📌黑板(blackboard)

为了存储可以被多个结点访问的共享信息(比如上面提到的存储有所有待搜寻地点的队列),我们引入黑板(blackboard)的概念。黑板是一块可以被结点读写的公共存储区。

针对我们的例子,我们为行为树添加一个Repeat装饰器结点和一个GetLoc的动作结点,用来在每一次迭代读取新的搜寻地址,如下图所示:

我们也可以利用黑板(blackboard)实现其它一些任务。比如:在找到苹果或橘子后在黑板上记录下它们的位置信息,然后在添加的Speak动作结点中读取它们,让机器人说出在哪里找到了苹果或橘子。还有对于找到的物体不同,后续结点可以根据黑板记录的信息采取不同的处理规则。

行为树和有限状态机的比较

读者可能想了解行为树和有限状态机哪个更好。下面这些观点可以供大家参考:

  • 理论上,行为树和状态机具有相同的表达能力,可以实现相同的功能。
  • 行为树更好还是状态机更好主要看所要定义的行为是更偏向模块化,还是更偏向反应式。一般来说,行为树更方便进行组合和修改,状态机更方便进行反应式动作设计。
1:以机器人捡起一个物体的任务为例,这需要机器人先移动到物体附近,然后夹起物体,最后再移动回机器人原来所处的位置。我们分别用行为树和状态机实现它们,如下图所示:

在这里插入图片描述

​ 左侧为行为树实现,右侧为状态机实现

2:如果我们想要进一步修改行为,比如检测夹子是否处于可以抓起物体的位置,然后再夹紧夹子。对于行为树,我们只需要插入一个子树就能完成期望的修改。但对于状态机,我们需要重写多个转换操作。也就是说行为树更便于进行组合(modularity)和模块化。下图给出了修改后的行为树和状态机图示:

在这里插入图片描述

修改后的行为树和状态机

3:对于反应式行为,比如机器人低电量时需要马上回到电源处,即使它还在执行某个任务的过程中。如果使用行为树来实现,这会非常麻烦,我们需要在任意任务的子树中支持充电行为。但对于状态机来说,实现起来就很简单,只需要从所有其它动作连线到充电动作即可。

在这里插入图片描述

​ 有限状态机可以在任意两个结点添加转换方便地实现反应式行为​

更进一步,通过对状态分层(也就是层次状态机,HFSM),建立超级状态Nominal,我们可以简化状态间的转换实现

状态机和行为树联合使用

行为树更好还是状态机更好需要看具体要解决的问题,个人认为有限状态机更方便管理高优先级的操作行为(比如机器人处于正常状态还是充电状态),行为树更适合定义复杂的行为,比如处理错误恢复等等。实践中,混合使用两者可能会是更好的选择。下图给出了混合使用行为树和状态机定义我们例子中的机器人行为的图示:

​ 高优先级行为使用状态机,复杂行为使用行为树实现​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/222440.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS第二天导读

1,Emmet语法 Emmet语法的前身是Zen coding,它使用缩写,来提高html / css 的编写速度,Vscode内部已经集成该语法 1.1,快速生成HTML结构语法 1.想要快速生成多个相同标签,加上*就可以了,比如 d…

物流实时数仓:数仓搭建(DWD)一

系列文章目录 物流实时数仓:采集通道搭建 物流实时数仓:数仓搭建 物流实时数仓:数仓搭建(DIM) 物流实时数仓:数仓搭建(DWD)一 文章目录 系列文章目录前言一、文件编写1.目录创建2.b…

iPhone 16 的电池供应可能来自印度

据英国《金融时报》报道,据报道,苹果已通知其供应链,包括中国德赛公司和台湾新普科技等电池供应商,其倾向于将 iPhone 16 的电池供应转移到印度。苹果鼓励供应商将现有产能迁往印度,以扩大该地区的生产规模。 鉴于电池…

Redis高级特性解析:持久化、主从复制与哨兵机制全面探讨

Redis持久化 RDB快照(snapshot) 在默认情况下, Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中。 你可以对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动保存…

Java使用Microsoft Entra微软 SSO 认证接入

1. Microsoft Entra Microsoft Entra ID 是基于云的标识和访问管理服务,可帮助员工访问外部资源。 示例资源包括 Microsoft 365、Azure 门户以及成千上万的其他 SaaS 应用程序。 Microsoft Entra ID 还可帮助他们访问你的企业 Intranet 上的应用等内部资源&#x…

2019年第八届数学建模国际赛小美赛B题数据中心冷出风口的设计解题全过程文档及程序

2019年第八届数学建模国际赛小美赛 B题 数据中心冷出风口的设计 原题再现: 这是数据中心空调设计面临的一个问题。在一些数据中心,计算机机柜是开放的,在一个房间里排列成三到四排。冷却后的空气通过主管进入房间,并分为三到四个…

【华为数据之道学习笔记】5-2华为数据湖的特点

华为数据湖是逻辑上对内外部的结构化、非结构化的原始数据的逻辑汇聚。数据入湖要遵从6项入湖标准,基于6项标准保证入湖的质量,同时面向不同的消费场景提供两种入湖方式,满足数据消费的要求。经过近两年的数据湖建设,目前已经完成…

0-50KHz频率响应模拟量高速信号隔离变送器

0-50KHz频率响应模拟量高速信号隔离变送器 型号:JSD TA-2322F系列 高速响应时间,频率响应时间快 特点: ◆小体积,低成本,标准 DIN35mm 导轨安装方式 ◆六端隔离(输入、输出、工作电源和通道间相互隔离) ◆高速信号采集 (-3dB,Min≤ 3.5 uS,订…

谷歌上架或更新被拒审的可能原因有哪些?

众所周知,在Google play应用商店上架或更新应用时,开发者需要遵守谷歌的相关规定和政策,否则可能会导致审核不通过,甚至永久封号。 很多开发者在提交应用到谷歌Play商店或进行应用更新时,即便了解了Google Play商店的…

unity 双摇杆控制教程(方向和旋转)

使用工具: unity 2021.2.8f1c1 visual studio 2022 插件: Joystick Pack 准备工作: 1.新建一个plane(作为地面),一个胶囊体(作为玩家),并在胶囊体上添加刚体组件&am…

java实现冒泡排序及其动图演示

冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。重复这个过程直到整个数列都是按照从小到大的顺序排列。 具体步骤如下: 比较相邻的两个元素,如果前…

hive聚合函数之排序

1 全局排序(Order By) Order By:全局排序,只有一个Reduce。 (1).使用Order By子句排序 asc(ascend):升序(默认) desc(descend)&#…

分布式解决方案与实战

分布式多线程性能调优 使用多线程优化接口 //下单业务public Object order( long userId){long start System.currentTimeMillis();//方法的开始时间戳&#xff08;ms&#xff09;JSONObject orderInfo remoteService.createOrder(userId);Callable<JSONObject> calla…

C++笔记之system()用于在Qt中执行系统命令的习惯

C笔记之system()用于在Qt中执行系统命令的习惯 参考博文&#xff1a;qt-C笔记之std::tostring()、.toStdString()、.toLocal8Bit().constData()的使用场景 code review! 文章目录 C笔记之system()用于在Qt中执行系统命令的习惯一.一般我用的int system( const char *command…

HarmonyOS学习0基础版

1.安装并配置DevEco 访问 HUAWEI开发者官网 找到 DevEco点击下载,我这里以windows版为例 点击下载并安装 (安装时直接点击下一步下一步,然后运行安装好的DevEco) 注意&#xff1a;第一次安装没有开发环境的时候&#xff0c;这里点击Do not import settings&#xff0c;进入软…

modelbox线程爆满宕机bug

序 该bug的解决需要特别感谢张同学。有了大佬的帮助&#xff0c;这个bug才得以解决。 问题现象 modelbox可以进行模型推理&#xff0c;但压测一段时间后&#xff0c;modelbox会宕机&#xff0c;并发生段错误。 “libgomp: Thread creation failed: Resource temporarily una…

MacOS多屏状态栏位置不固定,程序坞不小心跑到副屏

目录 方式一&#xff1a;通过系统设置方式二&#xff1a;鼠标切换 MacOS多屏状态栏位置不固定&#xff0c;程序坞不小心跑到副屏 方式一&#xff1a;通过系统设置 先切换到左边 再切换到底部 就能回到主屏了 方式二&#xff1a;鼠标切换 我的两个屏幕放置位置如下 鼠标在…

实验03:OSPF配置网络实验

1.实验目的&#xff1a; 本实验的主要目的是了解OSPF协议的基本概念、OSPF网络的配置及验证&#xff0c;通过实验来掌握OSPF协议的工作原理、配置方法、路由表的生成过程等。 2.实验内容&#xff1a; 设计一个拓扑结构&#xff0c;并在网络设备上进行配置&#xff1b;配置OS…

架构简洁之道有感,谈谈软件组件聚合的张力

配图由腾讯混元助手生成 这篇文章介绍了软件架构设计中组件设计思想&#xff0c;围绕“组件间聚合的张力”这个有意思的角度&#xff0c;介绍了概念&#xff0c;并且结合架构设计示例对这个概念进行了进一步阐述。 组件聚合&#xff1f;张力&#xff1f;这标题&#xff0c;有种…

Matlab绘图添加背景色,动态添加背景

Matlab绘图添加背景色&#xff0c;动态添加背景 有没有小伙伴想过绘制这种有背景的曲线图呢&#xff1f;因为矩形是背景&#xff0c;所以要先绘制&#xff0c;然后再绘制曲线&#xff0c;因此&#xff0c;最先想到的思路可能是&#xff1a;先绘制三个背景矩形&#xff0c;然后填…