2、行为树基础:行为树的核心概念、节点类型(控制节点、执行节点、装饰节点)与树结构
行为树(Behavior Tree,BT)是一种用于构建复杂、模块化、可复用决策逻辑的树形结构,最早广泛应用于游戏AI(如《光环》系列),近年来在机器人控制、自动驾驶、仿真系统等领域成为主流方案。与有限状态机(FSM)相比,行为树通过层级化的节点组合,将“决策”与“执行”解耦,使开发者能够以搭积木的方式快速构建、调试和扩展智能体的行为逻辑。在ROS2中,行为树通常通过BehaviorTree.CPP库实现,并与ROS2的动作(Action)、话题(Topic)和服务(Service)无缝集成。本章将系统讲解行为树的核心概念、节点类型与树结构,为后续章节中集成AI识别条件、任务状态管理和失败回退打下坚实基础。
上图展示了行为树的基本拓扑结构:根节点位于最顶层,向下连接控制节点(选择、序列、并行),控制节点再连接装饰节点和执行节点(动作、条件)。这种层级结构使得行为树天然具备“自顶向下决策、自底向上反馈”的特性。下面我们将深入剖析每个组成部分。
2.1 核心概念:状态、Tick与黑板
行为树的运行机制建立在三个核心概念之上:节点状态(Node Status)、Tick(心跳/触发)和黑板(Blackboard)。
- 节点状态:每个节点在执行后必须返回三种状态之一——
SUCCESS(成功)、FAILURE(失败)、RUNNING(运行中)。RUNNING状态是行为树区别于传统决策树的关键,它允许动作节点跨多个周期持续执行(如机器人移动、机械臂抓取),而不会阻塞整棵树的运行。 - Tick:行为树以固定频率(如10Hz或30Hz)从根节点开始,向下“打拍子”触发子节点执行。每个节点收到Tick后执行自身逻辑,并将状态返回给父节点。父节点根据子节点的返回状态决定是否继续Tick其他子节点。
- 黑板:黑板是一个共享的数据存储区,类似于全局变量池。树中的任何节点都可以读写黑板上的键值对,用于传递数据(如目标位置、传感器读数、AI识别结果)。在ROS2中,黑板通常与
Blackboard::Ptr绑定,支持类型安全的读写操作。
2.2 节点类型详解:控制节点、执行节点与装饰节点
行为树的节点分为三大类,每类节点承担不同的职责。下表总结了它们的核心特征与典型应用场景:
| 节点类型 | 子节点数量 | 核心逻辑 | 返回状态规则 | 典型应用 |
|---|---|---|---|---|
| 选择节点(Fallback/Selector) | 多个 | 从左到右依次Tick子节点,遇到第一个SUCCESS则返回SUCCESS;若所有子节点均FAILURE,则返回FAILURE | 任一子节点SUCCESS → SUCCESS;全部FAILURE → FAILURE | 备选方案选择(如先尝试视觉定位,失败则用激光定位) |
| 序列节点(Sequence) | 多个 | 从左到右依次Tick子节点,遇到第一个FAILURE则返回FAILURE;若所有子节点均SUCCESS,则返回SUCCESS | 任一子节点FAILURE → FAILURE;全部SUCCESS → SUCCESS | 顺序任务执行(如先导航到目标,再执行抓取) |
| 并行节点(Parallel) | 多个 | 同时Tick所有子节点,根据成功/失败阈值决定返回状态 | 成功数≥阈值 → SUCCESS;失败数>允许值 → FAILURE | 多传感器融合、同步动作(如边移动边避障) |
| 装饰节点(Decorator) | 1个 | 包裹单个子节点,修改其行为或状态(如取反、重试、限时) | 由具体装饰逻辑决定 | 条件反转、失败重试、超时控制 |
| 动作节点(Action) | 0个 | 执行具体操作(如发布速度指令、调用服务),可返回RUNNING | 执行结果决定 | 机器人移动、机械臂控制、播放语音 |
| 条件节点(Condition) | 0个 | 检查某个条件是否成立(如检测到障碍物、AI识别到目标),不修改世界状态 | 条件成立 → SUCCESS;否则 → FAILURE | 传感器阈值判断、AI识别结果检查 |
2.2.1 控制节点:决策的骨架
控制节点是行为树的“决策中枢”,它们不执行具体动作,而是决定子节点的执行顺序和逻辑。选择节点(Fallback)用于“备选”场景,例如:选择[视觉定位, 激光定位, 航迹推算]——如果视觉定位失败,则尝试激光定位,再失败则使用航迹推算。序列节点(Sequence)用于“必须全部成功”的场景,例如:序列[检查电量, 导航到目标点, 执行抓取]——任何一步失败,整个序列即失败。并行节点(Parallel)则用于需要同时满足多个条件的场景,例如:并行[避障, 朝向目标, 接近目标],只有当所有子节点都成功时才返回SUCCESS。
2.2.2 执行节点:动作与条件
执行节点是行为树的“手脚”,包括动作节点和条件节点。动作节点会改变系统状态或与外部世界交互,例如发布cmd_vel话题控制机器人移动、调用nav_to_pose动作服务。动作节点可以返回RUNNING状态,表示任务仍在执行中。条件节点则只做“检查”,不产生副作用,例如检查laser_scan话题中最近障碍物的距离是否小于0.5米,或检查AI识别结果中是否包含“person”类别。条件节点通常返回SUCCESS或FAILURE,不会返回RUNNING。
2.2.3 装饰节点:行为的“修饰器”
装饰节点是行为树的“魔法师”,它们包裹一个子节点,并修改其行为。常见的装饰节点包括:
- 取反节点(Inverter):将子节点的SUCCESS变为FAILURE,FAILURE变为SUCCESS。例如:
取反[检测到障碍物]——当没有障碍物时返回SUCCESS。 - 重试节点(Retry):当子节点返回FAILURE时,重试指定次数。例如:
重试(3次)[尝试连接WiFi]——最多尝试3次。 - 限时节点(Timeout):给子节点设置执行时限,超时则返回FAILURE。例如:
限时(5秒)[等待用户语音输入]——5秒内没有语音输入则失败。 - 重复节点(Repeat):重复执行子节点指定次数或无限次,直到子节点返回FAILURE。
Retry节点包裹“AI目标检测”动作,当检测失败时自动重试,避免因单帧误检导致整个任务失败。但要注意设置合理的重试次数和间隔,防止无限循环消耗计算资源。
2.3 树结构设计:从根到叶的层次化组织
一棵完整的行为树通常包含以下层次:
- 根节点(Root):树的入口,只有一个子节点,负责启动整棵树的Tick。
- 顶层控制节点:通常是选择节点或序列节点,定义任务的主流程。例如,一个巡检机器人的顶层可以是
选择[执行巡检任务, 执行充电任务, 执行待机任务]。 - 中层控制节点:将复杂任务分解为子任务。例如,“执行巡检任务”可以分解为
序列[导航到巡检点, 执行拍照, 执行AI分析]。 - 底层执行节点:具体的动作和条件节点,直接与ROS2接口交互。
这种层次化设计带来了三大优势:模块化(每个子树可独立测试和复用)、可读性(树形结构直观展示决策逻辑)、可扩展性(新增功能只需添加子树,无需修改现有逻辑)。
2.4 案例拆解:室内巡检机器人的行为树设计
下面通过一个室内巡检机器人的案例,展示如何将上述概念应用于实际工程。假设机器人需要完成以下任务:在走廊中巡逻,遇到障碍物时避让,检测到异常温度时报警,电量低于20%时自动充电。
初始现象与目标:机器人频繁卡在障碍物前,且无法自主处理低电量情况。目标是通过行为树重构决策逻辑,实现自主避障、异常检测和充电管理。
关键输入数据:
- 激光雷达话题:
/scan(距离数据) - 温度传感器话题:
/temperature(浮点值) - 电池电量话题:
/battery(百分比) - AI视觉识别话题:
/ai_detections(目标类别和置信度)
行为树设计:
根节点
└── 选择节点(主循环)
├── 序列节点(充电任务)
│ ├── 条件节点:电量 < 20%?
│ ├── 动作节点:导航到充电桩
│ └── 动作节点:执行充电
├── 序列节点(巡检任务)
│ ├── 条件节点:AI识别到异常目标?
│ ├── 动作节点:导航到目标位置
│ ├── 动作节点:执行拍照
│ └── 动作节点:发布报警
└── 序列节点(常规巡逻)
├── 装饰节点:重试(3次)[避障导航]
│ └── 序列节点
│ ├── 条件节点:前方有障碍物?
│ ├── 动作节点:避障转向
│ └── 动作节点:前进
└── 动作节点:沿走廊巡逻
分析判断过程:顶层选择节点优先处理充电任务(电量不足时),其次是巡检任务(AI识别到异常时),最后才是常规巡逻。在常规巡逻中,使用Retry装饰节点包裹避障导航逻辑,当连续3次避障失败时,放弃该方向并重新规划路径。
实际操作步骤:
- 在ROS2中创建行为树XML文件,定义上述节点结构。
- 使用BehaviorTree.CPP库加载XML,并注册自定义的动作节点和条件节点(如
CheckBattery、NavigateToPose)。 - 将AI识别结果写入黑板键
ai_detections,条件节点AI异常检测读取该键并判断是否包含“fire”或“smoke”类别。 - 设置Tick频率为10Hz,运行行为树。
结果对比:重构前,机器人遇到障碍物时直接停止,等待人工干预;重构后,机器人能够自主避障、自动充电,并在AI识别到异常时主动报警。任务完成率从65%提升至92%,人工干预次数减少80%。
风险与代价:行为树增加了系统复杂度,调试时需要同时关注树结构和节点状态。此外,Retry节点可能导致重复尝试消耗时间,需合理设置重试次数。
复盘经验:行为树设计应遵循“先条件后动作”的原则,将条件节点放在序列的前端,避免无效动作执行。同时,善用装饰节点处理异常情况,但不要过度嵌套,以免降低可读性。
2.5 常见误区与总结复盘
在实际使用中,初学者常犯以下错误:
RUNNING,否则行为树会认为动作瞬间完成,导致后续节点在错误时机执行。例如,导航动作需要持续数秒,若返回SUCCESS,则后续拍照动作会在机器人尚未到达目标时执行。
ai/detections、nav/target_pose。