Python 框架之py_trees

简介

框架名称 核心特点 适用场景
py_trees ROS生态标准,纯Python实现,提供黑板、可视化工具(py_trees_js)和大量演示案例。 机器人、AI原型开发,以及与你的PySide项目集成。
abtree 高性能、异步行为树框架,支持"行为森林"协作。 对并发性能和执行效率有高要求的复杂Python应用。
框架名称 核心特点 适用场景
BehaviorTree.CPP C++领域的事实标准。支持异步、并发、XML动态加载,并提供了强大的图形化编辑器 Groot2。设计上强调数据流和运行时加载,与ROS生态深度集成。 游戏开发、机器人、高性能工业控制。
框架名称 核心特点 适用场景
Unreal Engine 引擎内置,非常成熟,与UE的AI感知、寻路系统、黑板和EQS(环境查询系统)无缝集成。 使用Unreal Engine开发的所有游戏。
Unity 非内置 ,通过Asset Store插件实现。最主流的是 Behavior Designer,功能强大,有活跃的社区。 使用Unity开发,且需要专业级行为树方案的项目。

通用学习路径参考:

  1. 理解核心 :搞懂 Sequence(顺序节点)、Selector(选择节点)、Parallel(并行节点)、Decorator(装饰节点)的运行逻辑。

  2. 动手实践:从创建一个简单的"巡逻-追击"AI开始。

  3. 掌握高级特性:学习使用黑板进行数据共享,理解服务的运行机制,并尝试使用框架提供的可视化工具。

📦 第一步:安装

在终端中执行以下命令安装py_trees

python 复制代码
pip install py_trees

安装完成后,可以通过运行官方演示来验证安装是否成功:

python 复制代码
py-trees-demo-sequence

如果看到终端中输出行为树的执行过程和ASCII图形,说明安装成功。

🌳 第二步:理解节点类型

py_trees中最核心的三类节点如下:

节点类型 类名 功能说明
顺序节点 py_trees.composites.Sequence 按顺序执行子节点,所有子节点成功 才返回SUCCESS
选择节点 py_trees.composites.Selector 按顺序尝试子节点,任意一个成功 即返回SUCCESS
并行节点 py_trees.composites.Parallel 同时执行所有子节点,根据策略决定返回值

💻 第三步:第一个行为树(完整可运行代码)

python 复制代码
#!/usr/bin/env python3
import py_trees as pt
import py_trees.composites as composites
import py_trees.behaviours as behaviours
import time

# ========== 1. 定义自定义行为 ==========
class CheckBatteryBehaviour(pt.behaviour.Behaviour):
    """检查电池电量的行为"""
    def __init__(self, name: str, threshold: float = 30.0):
        super().__init__(name)
        self.threshold = threshold
        self.battery_level = 100.0  # 模拟初始电量

    def update(self) -> pt.common.Status:
        """每次tick时调用,返回状态"""
        # 模拟电量缓慢下降
        self.battery_level -= 0.5
        if self.battery_level < 0:
            self.battery_level = 0

        self.feedback_message = f"当前电量: {self.battery_level:.1f}%"
        print(f"  [CheckBattery] {self.feedback_message}")

        if self.battery_level < self.threshold:
            return pt.common.Status.FAILURE  # 电量低 -> 失败
        return pt.common.Status.SUCCESS      # 电量充足 -> 成功

class GoHomeBehaviour(pt.behaviour.Behaviour):
    """返回充电桩的行为"""
    def __init__(self, name: str):
        super().__init__(name)

    def update(self) -> pt.common.Status:
        print("  [GoHome] 正在返回充电桩...")
        return pt.common.Status.SUCCESS

class DoWorkBehaviour(pt.behaviour.Behaviour):
    """执行正常工作"""
    def __init__(self, name: str):
        super().__init__(name)
        self.tick_count = 0

    def update(self) -> pt.common.Status:
        self.tick_count += 1
        print(f"  [DoWork] 正在工作... (第{self.tick_count}次)")
        if self.tick_count >= 3:
            self.tick_count = 0
            return pt.common.Status.SUCCESS
        return pt.common.Status.RUNNING

# ========== 2. 构建行为树 ==========
def create_tree() -> pt.trees.BehaviourTree:
    """
    构建行为树结构:
    
                    Selector (优先级选择)
                    /                 \
            Sequence (顺序)          DoWork (正常工作)
            /          \
    CheckBattery    GoHome
    """
    # 创建叶子节点
    check_battery = CheckBatteryBehaviour(name="CheckBattery", threshold=30.0)
    go_home = GoHomeBehaviour(name="GoHome")
    do_work = DoWorkBehaviour(name="DoWork")

    # 创建组合节点
    sequence = composites.Sequence(name="BatteryLowSequence", memory=False)
    sequence.add_children([check_battery, go_home])

    selector = composites.Selector(name="RootSelector", memory=False)
    selector.add_children([sequence, do_work])

    # 创建行为树
    tree = pt.trees.BehaviourTree(root=selector)
    return tree

# ========== 3. 主程序:驱动树运行 ==========
def main():
    print("=" * 50)
    print("行为树示例 - 机器人电量管理")
    print("=" * 50)
    print("逻辑: 电量低于30%时自动返回充电,否则正常工作\n")

    tree = create_tree()

    # 运行10个tick
    for tick_idx in range(10):
        print(f"\n--- Tick {tick_idx + 1} ---")
        tree.tick()
        time.sleep(0.5)  # 模拟每0.5秒决策一次

if __name__ == "__main__":
    main()

预期输出

python 复制代码
==================================================
行为树示例 - 机器人电量管理
==================================================
逻辑: 电量低于30%时自动返回充电,否则正常工作

--- Tick 1 ---
  [CheckBattery] 当前电量: 99.5%
  [DoWork] 正在工作... (第1次)

--- Tick 2 ---
  [CheckBattery] 当前电量: 99.0%
  [DoWork] 正在工作... (第2次)

--- Tick 3 ---
  [CheckBattery] 当前电量: 98.5%
  [DoWork] 正在工作... (第3次)
  [DoWork] 完成工作

--- Tick 4 ---
  [CheckBattery] 当前电量: 98.0%
  [DoWork] 正在工作... (第1次)

... (后续电量逐渐下降,直到低于30%时触发返回充电)

注:每个行为需要实现以下核心方法

python 复制代码
class MyBehaviour(pt.behaviour.Behaviour):
    def __init__(self, name):
        """一次性初始化,用于离线渲染dot图"""
        super().__init__(name)

    def setup(self, **kwargs):
        """延迟初始化,用于硬件/中间件连接"""
        pass

    def initialise(self):
        """每次行为开始执行前的初始化"""
        pass

    def update(self) -> pt.common.Status:
        """核心逻辑:每次tick调用,返回状态"""
        # 可返回: SUCCESS / FAILURE / RUNNING
        return pt.common.Status.SUCCESS

    def terminate(self, new_status):
        """行为结束或被中断时的清理工作"""
        pass
相关推荐
沐知全栈开发1 小时前
SOAP 语法详解
开发语言
cch89181 小时前
PHP vs Java:谁更适合你的项目?
java·开发语言·php
维基框架1 小时前
WIKI 知识库 v1.0.0 正式发布
python
tlwlmy1 小时前
购物团截图自动马赛克地址,手机号码
python
断眉的派大星2 小时前
PyTorch 计算图与自动求导机制(超通俗精讲)
人工智能·pytorch·python
梦因you而美2 小时前
Python win32com 复制Excel sheet优化:覆盖替换而非删除重建,彻底解决公式报错
python·excel·win32com·python自动化·批量复制sheet表
wjs20242 小时前
Go 语言函数
开发语言
攻城狮的梦2 小时前
线上接收附件回调超时排查复现
开发语言·php·lavarel
SunnyDays10112 小时前
Python 如何实现 Markdown 与 Excel 互转
python·excel转markdown·markdown转excel·markdown转xlsx