跳转至

域随机化

本页介绍 LAV2 仿真栈内部的域随机化。这里关注的是载具内在参数的随机化,也就是在同一个任务定义下,让不同环境实例持有不同但仍然物理合理的载具参数、执行器响应和控制器配置。

在 LAV2 中,这类随机化更贴近平台模型本身。讨论的核心不在于任务目标如何变化,而在于同一类载具在仿真中可以呈现出哪些合理的参数差异。如需了解这套做法在迁移链路中的作用,可继续阅读 Real2Sim;本页则专门说明其在仿真内部的表达与执行方式。

flowchart TD
  A[标称平台定义] --> B[VehicleParams]
  B --> C[控制器侧参数]
  B --> D[执行器与动力学侧参数]
  C --> E[Array API 控制器]
  D --> F[Mixer 与 RotorDynamics]
  E --> G[任务后端随机化入口]
  F --> G
  G --> H[按环境实例采样后的运行时状态]
  H --> I[并行训练环境]

设计边界

LAV2 将平台的标称描述集中保留在 VehicleParams 中。域随机化建立在这份标称模型之上,运行时只对其中被允许的参数子集施加扰动。这样一来,仓库始终保留一个统一的质量、惯量、执行器常数、时序假设和 PX4 对齐参数来源,而训练后端只负责在执行阶段生成不同的参数样本。

当前实现遵循一套比较一致的模式:共享组件拥有自己的标称参数并提供类型明确的随机化接口,任务后端只负责决定这些接口何时被调用。这样可以让随机化贴近真正消费参数的模型,而不是在任务代码中再维护一套平行定义。

因此,LAV2 把域随机化视为仿真组件自身的性质,而不是任务层单独施加的一层“外部噪声”。真正关键的问题不在于某个任务能否注入随机性,而在于被扰动的控制器或动力学模块在参数变化之后,是否仍然能够保持清晰、稳定并可复用的接口。这也是为什么当前实现主要围绕控制器、mixer 和旋翼动力学展开,而没有完全隐藏在任务代码内部。

参数作用面

第一类参数作用面在控制器侧。批量 FlightController 通过 FlightController.randomize 支持在重置时重采样每个环境实例上的 PID 增益和控制器限幅。从建模意义上说,这和动力学参数随机化并不相同。它改变的是同一组目标与状态信号如何被解释成控制指令,因此更接近“内环控制配置存在偏差”的不确定性,而不仅仅是“平台物理参数存在偏差”。

第二类参数作用面在执行器分配与推力映射路径上。Mixer 提供了 Mixer.randomize,可以扰动控制分配和归一化节流解释所依赖的参数。由于 mixer 会在采样后重建分配矩阵和与推力相关的缓存量,这种变化不只是简单地在输出端乘一个系数,而是直接改变了期望 wrench 被映射为旋翼命令的方式。

第三类参数作用面在旋翼动力学本体。RotorDynamics 通过 RotorDynamics.randomize 支持扰动推力与扭矩系数、速率限制、电机转动惯量以及升速和降速时间常数。这一点与某些只对最终推力做乘性扰动的简化方法有本质区别。在 LAV2 中,被随机化的不只是“最后输出多大力”,还包括执行器本身如何响应输入命令,而这通常更贴近真实推进链路在仿真到实物迁移中暴露出的误差来源。

第四类参数作用面是 AerodynamicEffects。阻力、地效、壁效和给定外力均可通过 AerodynamicEffects.randomize 按环境实例采样。气动系数范围描述物理模型参数,效应强度范围则描述某项已启用气动效应的作用强弱。

Isaac Lab 地面任务还会在 reset 时随机化部分执行器响应、接触、质量和惯量属性。任务配置是支持范围的入口,共享地面执行器适配器负责自身的运行时参数。

这些参数面共同构成了 LAV2 当前已经落地的载具内在参数随机化范围。质心偏移和非 Isaac 地面后端仍未被统一成同一层运行时机制。

运行时拓扑

LAV2 的运行时拓扑是有意分层的。标称车辆定义仍然集中保留,采样值则由真正消费它们的控制器或动力学组件负责。正是这种分工,让仓库既可以维持统一的平台词汇,又能让不同环境实例在 episode 边界拥有彼此不同的参数样本。

flowchart LR
  A[VehicleParams] --> B[FlightController]
  A --> C[Mixer]
  A --> D[RotorDynamics]
  B --> E[动作项]
  C --> E
  D --> E
  E --> F[事件项或动作项]
  F --> G[控制器随机化]
  F --> H[Mixer 随机化]
  F --> I[旋翼随机化]
  G --> J[按环境实例存储的并行张量]
  H --> J
  I --> J

这里最重要的一点是,编排层并不会重新发明一套参数语言。后端提供生命周期入口,控制器和动力学模块负责定义每个采样参数的含义。这种分离让任务代码保持较薄,同时避免把任务语义与组件内部的参数管理耦合在一起。

当前已经接入的主要入口是重置阶段的随机化,这适合表达“同一轮任务中平台参数固定、不同轮次之间参数变化”的问题设定。与此同时,更复杂的任务同样可能需要时变随机化,例如电机故障下的容错控制、模型摄动下的自适应控制,或者其它在任务执行过程中逐步改变平台条件的场景。在这种情况下,随机化入口就不应局限于重置事件,而可以进一步接入动作项或其它更高频的运行时更新路径。

后端接入

LAV2 中面向训练的后端都遵循这套总体逻辑,而主要入口首先是事件项。在 Isaac Lab 路径中,lav2.tasks.isaaclab.locomotion.aerial.base.mdp.events 提供了显式的事件辅助函数,它们会找到对应的动作项,再取出挂在其上的运行时组件,最后调用组件自己的随机化接口。默认接线则在 lav2.tasks.isaaclab.locomotion.aerial.base.base_env_cfg 中完成,其中重置事件给出了控制器、mixer 和 rotor 扰动的实际参数范围。

地面任务通过 Isaac Lab 环境配置和 reset 接入随机化。任务配置位于 lav2/tasks/isaaclab/locomotion/ground/,共享执行器接口见 GroundDriveActuatorAdapter。

mjlab 路径与之高度相似。lav2.tasks.mjlab.locomotion.aerial.base.mdp.events 提供了同类事件层封装,而 lav2.tasks.mjlab.locomotion.aerial.base.base_env_cfg 则把这些事件组装进 manager-based 环境配置。这样的结构相似性很有价值,因为即使底层环境框架不同,开发者仍然可以用同一套心智模型去理解域随机化的注入路径。

Genesis Forge 使用自身的生命周期接入方式,但底层随机化对象保持一致:控制器、mixer、rotor 与气动模块提供共享的接口面。

把这几条路径放在一起看,设计意图其实是清晰的。LAV2 不希望把域随机化做成某个后端特有的技巧,而是希望由后端决定注入位置、由共享控制与动力学组件定义随机化语义。正因为如此,这套实现才更容易在 Isaac Lab、mjlab 和未来后端之间迁移。

气动域随机化

气动域随机化默认不启用。应先在 AerodynamicEffectsCfg 中打开相应能力,再注册调用 AerodynamicEffects.randomize 的 reset 入口。基础任务配置中没有预置该入口,因此现有任务的默认物理保持不变。

下面的配置让 60% 的 episode 精确地没有壁效,其余 episode 使用较弱的随机壁效:

randomization: AerodynamicRandomization = {
    "effect_probabilities": {"wall_effect": 0.4},
    "effect_scale_ranges": {"wall_effect": (0.1, 0.5)},
    "parameter_ranges": {
        "wall_effect_a1": (0.10, 0.21),
        "wall_effect_b1": (0.25, 0.45),
        "wall_effect_a2": (0.02, 0.06),
        "wall_effect_b2": (0.45, 0.65),
    },
}

支持的系数和效应名称由 AerodynamicRandomization 定义。概率用于选择某项效应是否出现,参数范围用于扰动物理模型,效应强度范围用于调节已启用效应的作用大小。范围应保持物理有效且非负,壁面模型的指数底数应位于 (0, 1]。

各后端的 reset 接入均使用同一个 AerodynamicRandomization 配置结构。

是否将采样后的气动参数作为观测,属于任务设计选择。当前壁面模型使用解析平面;有限表面和基于几何的遮罩仍属于场景层工作。在几何和机体专属系数得到验证之前,应保持壁效随机化较弱。

建模含义

当前实现已经比最简单的“在推力输出后乘一个噪声系数”更接近真实系统建模。一旦执行器时间常数、推力系数、限幅和控制器增益都可以在不同环境实例之间独立变化,策略面对的就不再是一套被冻结的内环与执行器,而是一族在物理和控制意义上都彼此相近、但又存在差异的闭环系统。

不过,也需要明确它仍然不是一套完全通用的域随机化引擎。仓库目前还没有为所有参数类别统一抽象出 scale、add、abs 这样的操作模型,也没有提供一套能够跨机体、执行器和控制器对象统一选取目标的参数语言。这些都是自然的后续开发方向,可以逐步把当前已经可用的随机化层推进成更完整的通用框架。

同时,控制器侧不确定性和动力学侧不确定性在概念上必须保持区分。控制器增益随机化主要对应内环配置漂移,mixer 与 rotor 参数随机化主要对应执行器和被控对象失配。二者可以同时使用,但它们回答的是不同类型的失效模式,因此无论在代码还是文档中,都不应被混成同一个概念。

后续扩展

最自然的扩展方向,是把新的 Isaac 地面参数面移植成跨后端机制。质量、质心偏移和履带侧执行器参数仍需要在 Isaac Lab、mjlab 与 Genesis Forge 之间形成统一的运行时模式。

另一个重要方向是统一采样参数的可观测性。地面动作项已经暴露自身样本,但整个系统还没有提供跨组件的统一参数记录,用于日志、回放或有条件地暴露给策略。

这些方向建立在现有结构之上继续展开。现阶段的设计已经建立了比较清晰的所有权关系:标称参数保持集中,运行时组件拥有采样后的执行状态,任务后端通过事件项或动作项触发随机化。

气动不确定性遵循相同的所有权原则,各物理项分别描述。对角阻力系数、地效系数 \(\kappa_g\) 与壁面效应系数 \((a_1,b_1,a_2,b_2)\) 对应不同机制,适合独立采样。表面平面及距离属于环境状态。地效和壁面参数都具有经验性并依赖具体机体,因此合理的随机范围可先来自系统辨识,再叠加有界不确定性;这些系数通常在单个 episode 内保持固定,而刻意设置的时变外力或运动表面属于场景动力学。固定线性机体阻力、随旋翼转速变化的桨叶阻力和相对空速二次阻力属于不同模型族,系数单位也不同,适合分别配置。下洗系数可与对应机型的辨识结果和多机尾流模型一并引入。

相关页面

API 交叉引用