行为树的基本概念和C++库

2023-09-21 08:56:58

一 说明

        行为计算机科学机器人技术控制系统视频游戏中使用的计划执行的数学模型。它们以模块化方式描述一组有限任务之间的切换。他们的优势来自于他们能够创建由简单任务组成的非常复杂的任务,而不用担心简单任务是如何实现的。行为树与分层状​​态机有一些相似之处关键区别在于行为的主要构建块是任务而不是状态。它易于人类理解,使得行为树不易出错,并且在游戏开发者社区中非常受欢迎。行为树已被证明可以推广其他几种控制架构。[1] [2]

        对双臂机器人的搜索和抓取计划进行行为树建模。

二 背景概述

        基于行为的控制结构最初由 Rodney Brooks 在其题为“移动机器人的鲁棒分层控制系统”的论文中提出。在最初的提案中,一系列行为可以相互替代,后来该方法在行为的树状组织中得到了扩展和概括,并在游戏行业中得到了广泛应用[需要引用]作为对行为进行建模强大工具非玩家角色(NPC)的行为。[3] [4] [5] [6]它们已广泛应用于HaloBioshockSpore 等备受瞩目的视频游戏中。最近的工作提出行为树作为无人机、复杂机器人、机器人操纵和多机器人系统的多任务控制框架。[7] [8] [9] [10] [11] [12] 行为树现已达到游戏 AI 教科书、[13] [14]以及Unity(游戏)等通用游戏环境的成熟度。引擎)虚幻引擎(请参阅下面的链接)。

        行为树因其开发范式而变得流行:只需对 NPC 的动作进行编程,然后设计一个树结构(通常通过拖放)即可创建复杂的行为,叶节点是动作,其内部节点决定 NPC 的决策。行为树在视觉上直观且易于设计、测试和调试,并且比其他行为创建方法提供更多的模块化性、可扩展性和可重用性。

        多年来,行为树的多样化实现在效率和能力上不断提高,以满足行业的需求,直到演变为事件驱动的行为树。[15] [5]事件驱动的行为树通过改变树内部处理其执行的方式以及引入一种可以对事件做出反应并中止正在运行的节点的新型节点,解决了经典行为树的一些可扩展性问题。如今,事件驱动行为树的概念已成为标准并在大多数实现中使用,尽管为了简单起见它们仍被称为“行为树”。

三 关键概念 

        行为树以图形方式表示为有向,其中节点被分类为根、控制流节点或执行节点(任务)。对于每对连接的节点,传出节点称为父节点,传入节点称为子节点。根没有父节点且只有一个子节点,控制流节点有一个父节点和至少一个子节点,而执行节点有一个父节点且没有子节点。从图形上看,控制流节点的子节点放置在其下方,从左到右排序。[16]

        行为树的执行从根部开始,根部以一定的频率向其子节点发送刻度。勾号是允许执行子进程的启用信号。当行为树中的某个节点被允许执行时,如果执行尚未完成,则向父节点返回运行状态如果达到目标,则返回成功;否则返回失败

3.1 控制流节点 

        控制流节点用于控制其组成的子任务。控制流节点可以是选择器(回退)节点或序列节点。他们依次运行每个子任务。当一个子任务完成并返回其状态(成功或失败)时,控制流节点决定是否执行下一个子任务。

        选择器(后备)节点 

图 I. N 个任务的后备组合的图形表示。

        回退节点用于查找并执行第一个未失败的子节点。当回退节点的一个子节点返回成功或正在运行时,后备节点将返回成功或立即运行的状态代码(参见图 I 和下面的伪代码)。孩子们按照重要性顺序从左到右打勾。

在伪代码中,后备组合的算法是:

for i from 1 to n do
     childstatus ← Tick(child(i))
     if childstatus = running
        return running
     else if childstatus = success
         return success
 end
 return failure

序列节点 

图二。N 个任务的序列组合的图形表示。。

        序列节点用于查找并执行第一个尚未成功的子节点。当序列节点的一个子节点返回失败或运行时,序列节点将立即返回失败或运行的状态代码(参见图 II 和下面的伪代码)。子项按从左到右的顺序勾选。

在伪代码中,序列组合的算法是:

for i from 1 to n do
2     childstatus ← Tick(child(i))
3     if childstatus = running
4         return running
5     else if childstatus = failure
6         return failure
7 end
8 return success

3.2 数学状态空间定义[编辑]

为了将控制理论工具应用于行为树的分析,可以将它们定义为三元组。[17]

在这里 i \in \mathbb{N},是行为树的索引 f_i: \mathbb{R}^n \rightarrow \mathbb{R}^n;是一个向量域到向量的

f_i: \mathbb{R}^n \rightarrow \mathbb{R}^n 是表示常差分方程右侧的向量场,

\Delta t 是时间步长并且

r_i: \mathbb{R}^n \rightarrow \{R_i,S_i,F_i\} 是返回状态,可以等于 Running R_{i},成功S_{i},或失败 F_{i}。

注意:任务是一个没有父级也没有子级的退化行为树

3.3 行为树执行

        行为树的执行由以下标准常差分方程描述:

        {\displaystyle x_{k+1}(t_{k+1})=f_{i}(x_{k}(t_{k}))}

        t_{k+1}=t_{k}+\Delta t

        在这里

        k\in \mathbb{N} 表示离散时间,并且  

        x \in \mathbb{R}^n是由行为树建模的系统的状态空间。

3.4 序列组成

        两个行为树 T_{i}T_{j}可以组成更复杂的行为树T_{0} ;使用序列运算符 T_0=\mbox{sequence}(T_i,T_j).

然后返回状态r_{0} 和向量场f_{0}关联于T_{0}被定义(对于{\displaystyle {\mathcal {S}}_{1}}^{[definition\; needed]})如下:

 {\displaystyle r_{0}(x_{k})={\begin{cases}r_{j}(x_{k})&{\text{ if }}x_{k}\in {\mathcal {S}}_{1}\\r_{i}(x_{k})&{\text{ otherwise }}.\end{cases}}}

{\displaystyle f_{0}(x_{k})={\begin{cases}f_{j}(x_{k})&{\text{ if }}x_{k}\in {\mathcal {S}}_{1}\\f_{i}(x_{k})&{\text{ otherwise }}.\end{cases}}}

 

四 C++行为树的实施

4.1 关于此库

        此C++库提供了一个创建行为树的框架。 它的设计灵活、易于使用且快速。

        即使我们的主要用例是机器人技术,您也可以使用此库为游戏构建 AI,或替换应用程序中的有限状态机。

        与其他实现相比,BehaviorTree.CPP具有许多有趣的功能:

  • 它使异步操作(即非阻塞例程)成为一等公民。
  • 树是在运行时使用解释语言(基于 XML)创建的。
  • 它包括一个日志记录/分析基础结构,允许用户 可视化、记录、重放和分析状态转换。
  • 您可以静态链接自定义树节点或将它们转换为插件 在运行时加载。

4.2 行为树描述

        行为树(BT)是一种构建不同之间切换的方法 自主代理中的任务,例如计算机游戏中的机器人或虚拟实体。

        BT是创建模块化和反应式复杂系统的一种非常有效的方法。 这些特性在许多应用中至关重要,这导致了传播 从计算机游戏编程到人工智能和机器人的许多分支的BT。

        如果您已经熟悉有限状态机 (FSM),您将 轻松掌握大多数概念,但希望您会发现 BT 更具表现力,更容易推理。

        将树的节点视为一组构建基块。 这些块是用C++实现的,并且是“可组合的”:换句话说,它们可以是 “组装”以构建行为。

        在上图中,您可以看到我们以简单的顺序排列这些操作; 操作将按从左到右的顺序执行。要了解更多信息,请访问BT简介页面。

4.3 行为树的主要优点

  • 它们本质上是分层的:我们可以组合复杂的行为,包括将整棵树作为更大树的子分支。 例如,行为“获取啤酒”可能会重用树 “抓住对象”。

  • 它们的图形表示具有语义意义:更容易 “阅读”BT并了解相应的工作流程。 相比之下,FSM中的状态转换更难理解 无论是在文本还是图形表示中。

  • 它们更具表现力:即用型控制节点和装饰器节点 使表达更复杂的控制流成为可能。用户可以扩展 “词汇”与他/她自己的自定义节点。

五 为什么我们需要行为树(或FSM)

        许多软件系统,机器人技术是一个值得注意的例子,本质上是 复杂。

        管理复杂性、异构性和可扩展性的常用方法是 使用基于组件的软件工程的概念。

        任何现有的机器人中间件都非正式或正式地采用了这种方法, 是ROS,YARPSmartSoft的一些值得注意的例子。

        一个“好”的软件架构应该具有以下特征:

  • 模块性。
  • 组件的可重用性。
  • 可组合性。
  • 良好的关注点分离。

        如果我们从一开始就不牢记这些概念,我们就会创造 紧密耦合且可重用性较低的软件。

通常,软件系统的业务逻辑被“传播”到许多 组件,对开发人员来说很难 推理它并调试错误

为了实现关注点的强分离,最好集中 单个位置中的业务逻辑。

        有限状态机是专门为这个目标而创建的,但在 近年来,行为树越来越受欢迎,尤其是在游戏行业。

更多推荐

React面试题总结(一)

1、redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的实现原理是什么?1、Redux-thunk这个中间件支持异步操作2、执行异步的操作首先需要下载一个thunk,通过thunk来进行异步的一个操作,支持异步操作,可以使用dispatch和getState来进行数据的获取或状态3、Redux是一个

【C++】STL—— unordered_map的介绍和使用、 unordered_map的构造函数和迭代器、 unordered_map的增删查改函数

文章目录1.unordered_map的介绍2.unordered_map的使用2.1unordered_map的构造函数2.2unordered_map的迭代器2.3unordered_map的容量和访问函数2.4unordered_map的增删查改函数1.unordered_map的介绍unordered_map的

【Java 基础篇】Java多线程编程详解:线程创建、同步、线程池与性能优化

Java是一门强大的编程语言,其中最引人注目的特性之一是多线程支持。多线程允许我们在同一程序中同时执行多个任务,这大大提高了应用程序的性能和响应能力。本文将深入介绍Java线程的基础知识,无论您是初学者还是有一些经验的开发人员,都将从中获益。什么是线程?在计算机科学领域,线程是指在一个进程内部执行的独立单元。一个进程可

多线程设计模式【线程安全、 Future 设计模式、Master-Worker 设计模式 】(一)-全面详解(学习总结---从入门到深化)

目录SingleThreadExecution设计模式线程安全Future设计模式Master-Worker设计模式生产者消费者设计模式定义不可变对象的策略SingleThreadExecution设计模式机场过安检SingleThreadExecution模式是指在同一时刻只能有一个线程去访问共享资源,就像独木桥一样

runc和docker

在Docker中,runc是一个轻量级的运行时工具,用于创建和运行容器。它是OpenContainerInitiative(OCI)的一部分,负责管理和执行容器中的进程。runc负责创建和管理Linux命名空间、控制组(cgroups)和文件系统挂载等功能,以便隔离容器中的进程、资源和文件系统。它还提供了容器的生命周期

在项目中,关于前端实现数据可视化的技术选择

前言在项目中,数据可视化以图表、报表类型为主。需求背景技术框架是Vue2.x版本,组件库是AntDesignofVue能够支撑足够多的图表类型开发图表大小/位置能够随意变动图表样式需要支持丰富多样的用户配置强大、开放的图表语法支持复杂的数据可视化场景兼顾电脑端和手机端、同时兼顾开发周期和后期维护版本稳定、社区活跃,方便

【数据结构】二叉树

树的概念及结构树的概念树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。有一个特殊的结点,称为根结点,根节点没有前驱结点(上图中的A结点就是根节点)除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、

SpringCLoud——RabbitMQ的消息模型

WorkQueue工作队列他的主要作用就是增加消费者的个数,可以提高消息处理速度,避免队列消息堆积。案例实现一个队列绑定多个消费者首先修改一下之前的发送消息的代码,让他循环发送50次,但是不要一次性发完:@TestvoidLoopSend()throwsInterruptedException{StringqueueN

计算机网络知识补充(1)

计算机网络:是一个将分散的,具有独立功能的计算机系统,通过通信设备和线路进行连接起来,由功能完善的软件实现资源共享和信息共享的系统,计算机网络是互连的,自治的计算机集合互连:通过通信链路来进行互联互通自治:没有主从关系1)电路交换:电路交换是一种通信方式,它是通过建立点对点的电路连接来传输数据的,在电路交换中,如果两个

同为科技(TOWE)工业用插头插座及配电箱产品选型推荐

工业用插头插座及配电箱产品是专用于工业环境中的电源连接和电气设备控制,与普通家用插头插座相比,通常具有更高的功率和电流容量,并且设计上考虑了耐用性、安全性和适应各种环境条件的能力。工业用插头插座产品类型多样,包括插头插座、工业连接器、防水配电箱等,满足户内外工业用电的各种需求,适用于工业、建筑、船舶、交通、能源、通信等

【linux基础(八)】计算机体系结构--冯诺依曼系统&操作系统的再理解

💓博主CSDN主页:杭电码农-NEO💓⏩专栏分类:Linux从入门到精通⏪🚚代码仓库:NEO的学习日记🚚🌹关注我🫵带你学更多操作系统知识🔝🔝计算机体系结构1.前言2.冯诺依曼系统介绍3.为什么冯诺依曼系统如此流行?4.对硬件系统的再理解5.校长对学生的管理6.操作系统对硬件的管理7.总结1.前言为了更好

热文推荐