【免费下载链接】flybody
MuJoCo fruit fly body model and locomotion RL tasks
flybody 是一个为 MuJoCo 物理模拟器打造的果蝇(Drosophila melanogaster)全身模型与运动强化学习任务库。其中最硬核的任务是视觉引导飞行(vision-guided flight):果蝇仅靠头部两只32×32 像素的"眼睛"相机和惯性传感器,学习在随机生成的丘陵或蜿蜒沟壑上方保持目标高度与速度飞行。本文将带你拆解这个任务的完整机制:眼睛相机如何定义、奖励函数如何设计、单一标量动作如何控制 218Hz 的翅膀拍频,以及如何用 Ray 分布式训练。
🦟 flybody 是什么:一只可以"活过来"的仿真果蝇
flybody 由 Google DeepMind 与 HHMI Jeline 研究院合作开发,其模型包含头部、胸部、腹部、6 条腿、翅膀、平衡棒与口器等解剖学细节(见 flybody/fruitfly/assets/fruitfly.xml)。模型支持:
- 飞行模式:翅膀使用力控执行器 + 椭圆流体模型(
fluidshape='ellipsoid')模拟空气动力,物理步长仅5e-5秒; - 行走模式:腿足带摩擦与粘附执行器,可在球面上行走;
- 任务抽象:所有任务基于 dm_control 的
composer.Task,观察量(observables)以传感器方式声明。
任务工厂集中在 flybody/fly_envs.py,视觉飞行任务由vision_guided_flight()函数一行创建:
from flybody.fly_envs import vision_guided_flight env = vision_guided_flight(bumps_or_trench='trench') # 或 'bumps'👁️ 32×32"眼睛"相机:视觉输入的真相
视觉任务的核心观察量是两只眼睛。相机在果蝇模型的 XML 中定义,位于头部两侧(flybody/fruitfly/assets/fruitfly.xml):
<camera name="eye_right" fovy="140" pos="0.0219 0.0131 0" quat="0.474 0.688 -0.344 -0.429"/> <camera name="eye_left" fovy="140" pos="-0.0219 0.0131 0" quat="0.474 0.688 0.344 0.429"/>关键参数由任务构造函数控制(见 flybody/tasks/vision_flight.py):
| 参数 | 默认值 | 含义 |
|---|---|---|
eye_camera_size | 32 | 每只眼睛的分辨率(32×32 像素) |
eye_camera_fovy | 150° | 眼睛垂直视场角(宽视角,类似昆虫复眼) |
target_height_range | (0.5, 0.8) | 随机目标飞行高度(米) |
target_speed_range | (20, 40) | 随机目标速度(cm/s) |
在 flybody/fruitfly/fruitfly.py 中,left_eye与right_eye被实现为observable.MJCFCamera观察量——每次env.step()时直接从仿真场景渲染 32×32 的 RGB 图像,作为策略网络的输入。分辨率极低是刻意设计:真实果蝇单眼的光感受器数量与之相当,这也是任务难度来源之一。
一个有趣的细节:视觉任务会移除场景中所有光源(vision_flight.py中对light节点的清空循环),并调小znear/zfar/force等渲染参数(见 flybody/tasks/base.py 的注释:"对视觉引导飞行任务至关重要"),迫使果蝇只能依靠地形本身的光照与轮廓来判断障碍。
🏔️ 两种地形:bumps 与 trench
vision_guided_flight()支持两种可随机再生的竞技场(见 flybody/tasks/arenas/hills.py):
bumps(丘陵):SineBumps生成碗状地形 + 正弦波状隆起,波长 10~15m、振幅 0.5~1.0m 每回合随机采样,果蝇需要"看"前方地形起伏来维持高度;trench(沟壑):SineTrench在碗状地形上开出一条蜿蜒的正弦形沟渠,果蝇需要沿沟中线飞行,且地形参数经过约束(width = 2*amplitude + 0.604*width_factor,0.604 正是果蝇翅展),杜绝直线穿越的平凡解。
每个回合开始时,目标高度与目标速度随机重采样,并通过task_input观察量(目标高度 + 目标速度,2 个标量)告诉策略"这轮飞多高、多快"。
📐 奖励与动作:七个因子 × 一个标量
奖励函数:7 个因子的几何平均
get_reward_factors()(flybody/tasks/vision_flight.py)返回 7 项容忍度(tolerance)奖励因子,总奖励为其乘积:
- height:相对地形的当前高度逼近随机目标高度(容差 ±0.15m);
- x_speed:世界系 x 方向速度不低于目标速度;
- speed:合速度模长逼近目标速度;
- side_speed:自身坐标系下横向速度为 0(不许侧滑);
- world_zaxis:机体竖直轴对齐目标姿态(果蝇飞行时身体前倾 47.5°,来自真实飞行数据);
- center_of_trench:trench 任务中保持贴近沟渠中心线;
- retract_legs:飞行时保持腿部收拢(向折叠参考角度看齐)。
此外,触碰地面直接终止回合(floor_contacts_fatal=True),坠机是最快的失败方式。
动作空间:一个数字控制拍翅频率
整个策略只输出1 个标量动作a ∈ [-1, 1],其余"动作"由拍翅模式发生器(WingBeatPatternGenerator, WBPG)自动生成。before_step中的控制律(flybody/tasks/vision_flight.py):
ctrl_freq = base_freq * (1 + rel_range * a) # base_freq = 218 Hz即动作将基础拍频 218Hz 上下调节 ±5%。WBPG 根据拍频查表/生成翅膀位置指令,再转换为力控制驱动 6 个翅膀关节(左/右 × yaw/roll/pitch)。这意味着策略的全部自由度只有"扇翅膀快一点还是慢一点"——俯仰、偏航姿态全部涌现自翅膀流体力学与机体耦合,这正是该任务对生物启发控制研究的价值所在。
观察量清单
策略每步(控制步长 2e-4s,单回合上限 0.4s)看到:
- 左右眼 32×32 RGB 图像(各 3072 维);
- 前庭传感器:陀螺仪、加速度计、测速计、世界 z 轴;
- 本体感觉:关节位置/速度、执行器激活状态;
task_input:目标高度 + 目标速度。
🚀 快速上手:5 分钟跑通视觉飞行环境
# 1. 克隆仓库并安装(含 ML 依赖) git clone https://gitcode.com/gh_mirrors/fl/flybody cd flybody conda create --name flybody -c conda-forge python=3.10 pip conda activate flybody pip install -e .[tf] # 训练再装 .[ray] export MUJOCO_GL=eglimport numpy as np from flybody.fly_envs import vision_guided_flight env = vision_guided_flight(bumps_or_trench='bumps') timestep = env.reset() # 随机策略飞一会儿(预期很快坠地) for _ in range(50): action = np.random.uniform(-1, 1) timestep = env.step(action) if timestep.last(): break # 看一眼"果蝇的视角" print('双眼输入:', timestep.observation['walker/left_eye'].shape) # (32, 32, 3)想直观查看三类任务环境的运行效果,官方示例 notebook 是 docs/fly-env-examples.ipynb(飞行模仿 / 行走模仿 / 视觉引导飞行)。
🖥️ 分布式训练:Ray + DMPO
真正教会果蝇飞的是强化学习。flybody/train_dmpo_ray.py 提供了基于Ray的分布式DMPO(Deep Memory Policy Optimization)训练脚本:
python flybody/train_dmpo_ray.py --test # 轻量模式:单 actor,每 10 秒打印统计 python flybody/train_dmpo_ray.py # 全量模式:32 actors + 独立 learner默认配置 32 个并行 actor、batch size 256、replay buffer 上限 400 万样本。脚本本身任务无关——把environment_factory里的walk_on_ball()换成vision_guided_flight(...)即可训练视觉任务。DMPO 的分布式实现(Learner / ReplayServer / EnvironmentLoop)位于 flybody/agents/ray_distributed_dmpo.py。
🧠 进阶技巧:控制器复用(Controller Reuse)
官方还有一个值得学习的两阶段方案(docs/controller-reuse-vision-flight.ipynb):
- 先学技能:用飞行模仿任务(
flight_imitation)训练低层飞行控制器,学会"如何飞"; - 冻结复用:在视觉任务中加载并冻结低层控制器权重,只训练一个高层策略——高层网络吃双眼图像,输出 1 个拍频标量"驾驶"冻结的低层控制器完成导航。
这种"技能库 + 高层决策"的分层架构,避免了从零学习飞行的巨大样本量开销,也是该工作发表在 Nature 论文中的核心方法论之一。
📂 关键文件导航
| 文件 | 说明 |
|---|---|
| flybody/tasks/vision_flight.py | 视觉飞行任务类VisionFlightImitationWBPG:奖励、终止、眼睛观察量 |
| flybody/fly_envs.py | vision_guided_flight()环境工厂(bumps / trench) |
| flybody/fruitfly/fruitfly.py | 果蝇 walker 与left_eye/right_eye相机观察量 |
| flybody/fruitfly/assets/fruitfly.xml | 果蝇 MuJoCo 模型与双眼相机定义 |
| flybody/tasks/arenas/hills.py | SineBumps/SineTrench随机地形生成 |
| flybody/tasks/pattern_generators.py | 拍翅模式发生器 WBPG |
| flybody/train_dmpo_ray.py | Ray 分布式 DMPO 训练入口 |
| docs/fly-env-examples.ipynb | 三类 RL 任务环境演示 notebook |
| docs/controller-reuse-vision-flight.ipynb | 控制器复用视觉导航示例 |
总结:为什么这个任务值得研究
flybody 的视觉引导飞行任务把生物约束压到了极致:32×32 的低分辨率双眼、一个标量动作、0.4 秒的回合、坠地即死。在这种信息带宽下,策略必须学会从像素流中提取地形高度与走向,并用拍翅频率这一单一操纵面完成六自由度飞行——这正是果蝇神经系统真正做的事。对 RL 研究者而言,它是检验"感知-运动耦合"与分层控制的绝佳基准;对仿真爱好者,一行vision_guided_flight()就能启动这个任务。
【免费下载链接】flybody
MuJoCo fruit fly body model and locomotion RL tasks
相关推荐
PX4-Autopilot 飞行指南:从首飞准备、手动飞行到自主任务全流程实战
PX4 Autopilot 飞行指南:从首飞准备、手动飞行到自主任务全流程实战 本篇技术指南以 PX4 Autopilot 官方文档「Flying(飞行)」章节
无人机嵌入式机器人智能硬件如何用代码画一只会飞的果蝇?DesktopFly程序化3D建模与三足步态动画实战
如何用代码画一只会飞的果蝇?DesktopFly程序化3D建模与三足步态动画实战 DesktopFly 是一个 macOS 桌面 3D 果蝇宠物,它的身体完全由
PX4 飞行任务(Flight Task)框架实战指南:架构原理与自定义飞行任务开发
PX4 飞行任务(Flight Task)框架实战指南:架构原理与自定义飞行任务开发 飞行任务(Flight Task)是 PX4 飞行模式(Flight Mo
无人机嵌入式机器人智能硬件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考