域随机化¶
本页仅描述仓库中已注册任务的域随机化现状。所有结论都来自代码;不从设计意图推断任何内容。
当前存在两条 DR 声明路径:
Manager-Based(Compatible)任务:reset / interval 随机化通过 owner YAML 中的 Hydra
events:manager term 声明;reset 生命周期的 event 在 reset 时采样,interval 生命周期的 event 在 step 之间施加扰动。例如src/unilab/conf/ppo/task/go1_joystick_flat/base.yaml的events:段。任务级 provider 路径:自定义任务(包括托管在外部仓库中的任务)可以通过
DomainRandomizationProvider+DomainRandomizationManager声明env.domain_rand.*配置。当前仓库内没有任务使用该路径。
legacy provider 路径的统一入口点位于 NpEnv._init_domain_randomization() 和 DomainRandomizationManager:
init 路径:task provider 产生一个
InitRandomizationPlan;manager 在 env 初始化期间调用后端的apply_init_randomization(...)reset 路径:task provider 产生一个
ResetPlan;manager 验证能力,然后调用后端的set_state(..., randomization=...)interval 路径:task provider 产生一个
IntervalRandomizationPlan;manager 在 step 之前按需调用后端的apply_interval_randomization(...)
这三条路径对应三个生命周期类别:
init 生命周期 DR:改变模型 identity 或模型几何的项;只能在 env/backend 初始化和 materialization 期间生效,例如通过模型变体进行的物体
geom_size缩放。reset 生命周期 DR:不改变模型 identity,只在同一模型内改变参数或 reset 状态的项,例如
base_mass_delta、base_com_offset、gravity、kp、kd。interval 生命周期 DR:step 之间的外部扰动,例如 push。
状态结论¶
Manager-Based 任务不注册 DR provider;它们的 reset/interval 随机化是 owner YAML 中的
events:manager term,由 manager 生命周期统一执行。走 provider 路径的自定义任务则经过DomainRandomizationManager统一入口。provider 路径的 owner 定义
domain_rand配置 dataclass、DomainRandomizationProvider和ResetPlan;Manager-Based owner 则通过 Hydra command/event term 声明 reset 行为。G1 motion reset 扰动归MotionCommandCfg所有,WBT 另加EventTermCfgreset 与 interval term。今天所”统一”的主要是入口点和执行流程,而不是每一个随机化项本身。legacy 路径的共享辅助函数
build_common_reset_randomization()目前生成base_mass_delta、base_com_offset、gravity、kp、kd。ResetRandomizationPayload已经可以表达gravity、body_iquat、body_inertia、kp、kd,并且MuJoCoBackend已声明支持。这些是否实际被使用,仍取决于 task provider 是否对它们进行采样和 dispatch。MotrixBackend目前支持base_mass_delta、base_com_offset、kp、kd和 interval push;并且它要求在初始化期间所有模型 actuator 都是 position actuator。geom_size不是 reset 生命周期字段;物体 geom 缩放由 init 生命周期的模型 materialization 处理。
统一性评估表¶
Task |
声明路径 |
结构化形式? |
reset 形式 |
interval 形式 |
Code |
|---|---|---|---|---|---|
|
Hydra |
是:owner YAML 声明 reset/interval event |
root-state reset + base mass/COM + |
|
|
|
Hydra |
是:owner YAML 声明 reset event |
root-state reset + |
无 |
|
|
Hydra |
是:Hydra |
root-state reset + 经 |
无 |
|
|
Hydra |
是:与 |
root-state reset + 经 |
无 |
|
|
Hydra command term |
是:Hydra |
motion frame、root pose/velocity 与 joint-position 采样 |
无 |
|
|
Hydra |
是:同一 motion command + Hydra |
motion reset 加 mass/COM/PD/friction/encoder-bias event |
interval velocity kick |
|
|
Hydra |
是:Hydra |
entity 范围的手/球 reset |
无 |
|
|
Hydra |
是:复用 rotation reset event + |
带噪声的手部 reset + grasp 收集 |
无 |
|
各任务域随机化清单¶
Task |
当前已实现的 reset 域随机化 |
当前已实现的 interval 域随机化 |
默认状态 |
|---|---|---|---|
|
经 |
|
上述 event term 全部在 |
|
经 |
无 |
event term 在 |
|
经 |
无 |
mujoco owner 默认启用 kp/kd;motrix/mjwarp owner 默认禁用 |
|
与 |
无 |
与 |
|
Motion-command frame 采样;root 位姿扰动 |
无 |
base owner 中 |
|
同一 motion reset 加 base mass、base COM、PD gain、足端摩擦和 encoder-bias event term |
|
WBT owner 显式启用上述全部 event term;能力不支持时直接报错,不回退 |
|
entity 范围的手/球 reset;显式配置 grasp cache 时进行采样,否则以 |
无 |
owner YAML 显式选择 home pose 与零 reset 噪声;配置的 cache 缺失或格式错误时 fail-closed |
|
复用 rotation reset 并设置 |
无 |
生成 5 万行 Allegro grasp cache,成功保存后抛出 |
当前统一 DR 的能力与边界¶
1. legacy provider 入口是统一的¶
legacy provider 路径的统一入口点由 NpEnv 和 DomainRandomizationManager 保证:
任务只需注册一个 provider
manager 统一执行能力验证
后端统一负责实际施加随机化 payload
因此从执行路径的角度看,provider 路径的任务是统一的;Manager-Based 任务则由 manager 生命周期统一执行 owner YAML 声明的 events: term。
2. 共享辅助函数仍然较窄¶
legacy 路径的 dr_utils.py 构造并校验通用 reset payload:
reset common payload:
base_mass_delta、base_com_offset、gravity、kp、kd
这意味着:
provider 路径的任务直接在各自的 provider 内部采样 task 专属状态
G1MotionTracking的 pose / velocity / joint 噪声由其 manager command 所有Allegro 的 grasp / 物体初始状态采样完全是 task 专属逻辑
geom_size缩放是 init 生命周期的模型 materialization,不属于 reset common payload
所以今天的”统一性”更多是关于 contract 和调用约定,而不是”所有任务共享同一套随机化项 schema”。
3. 后端能力已经超出任务当前使用的范围¶
ResetRandomizationPayload 现在包含:
base_mass_deltabase_com_offsetgravitybody_iquatbody_inertiakpkd
当前的后端能力:
MuJoCoBackend:支持上述 7 个 reset 项,外加 interval push、interval body velocity delta(线速度与世界系角速度)和 interval body force/torqueMotrixBackend:支持base_mass_delta、base_com_offset、kp、kd,外加 interval push;要求在初始化期间 actuator 全部为 position actuator
说明:
当前的
IntervalRandomizationPlan支持push_perturbation_limit、body_linear_velocity_delta、body_angular_velocity_delta、body_force和body_torque;其中body_force/body_torque表达热路径上的直接外力/力矩扰动,而不暴露后端私有的xfrc_applied细节。当前 MuJoCo 后端的 interval push 和 interval body force 都通过
xfrc_applieddispatch。Motrix 后端目前仍不支持直接 body-force 扰动,因此这类 owner 配置必须继续显式禁用。
但在任务侧,当前的现实是:并非每个 provider 都构造这些字段。后端 contract 是能力边界;task 配置和 provider 是否 dispatch 一个 payload,才决定了某个任务是否实际启用对应的 DR 项。
Reset gravity 用法¶
gravity 是一个 reset 生命周期 DR:在每次 reset 时,会按 env 子集采样一个完整的 MuJoCo gravity 向量 (gx, gy, gz),并通过 ResetRandomizationPayload.gravity dispatch 到后端。该向量同时表达方向和大小:
方向:由
(gx, gy, gz)的方向决定。大小:由向量范数
sqrt(gx^2 + gy^2 + gz^2)决定。生命周期:仅在 reset 时采样和写入;env 会保留该重力,直到下一次 reset 重新采样。
后端:当前在 UniLab 中,只有 MuJoCo 后端声明支持该 reset 项;Motrix 后端不支持。一些任务按能力过滤并跳过它;另一些任务在 validate 阶段抛出错误。
配置入口位于 provider 路径任务 owner 的 env.domain_rand 下;Manager-Based 任务没有 env.domain_rand:
env:
domain_rand:
randomize_gravity: true
gravity_range:
- [-0.2, -0.2, -10.5]
- [0.2, 0.2, -8.5]
字段语义:
randomize_gravity:是否启用 gravity reset DR;默认为false。gravity_range:一个形状为(2, 3)的逐维采样范围;第一行和第二行给出每个分量的上界和下界。在每次 reset 时,每个维度在
[min(row0, row1), max(row0, row1)]内均匀采样。方向不会自动归一化,重力范数也不固定。
如果你只想随机化大小而保持竖直向下的方向,只开放 z 分量;如果想同时随机化方向和大小,开放 x/y/z。在 provider 路径的任务 owner 上,可通过 CLI 以 env.domain_rand.randomize_gravity=true 与 env.domain_rand.gravity_range=[...] override 启用。
说明:
gravity_range必须可转换为(2, 3)数组;否则 reset 在构造 payload 时会抛出错误。该项不调用
mj_setConst;MuJoCo step / forward 直接读取mjModel.opt.gravity。不要在 Motrix 后端下启用该项;当前 Motrix 能力不包含
gravity。如果你当前的环境仍安装了不包含
gravity字段的mujoco-uni-runtime包,MuJoCo reset 会抛出 unsupported field;你需要使用包含该字段的mujoco-uni-runtime构建/发布版本。在训练期间,建议从较小的倾斜范围开始;否则在早期采样到过大的水平重力,可能会使任务退化为不可学习。
Interval push 用法¶
Manager-Based 任务通过 env.events.push_robot term 配置周期推扰。例如,
src/unilab/conf/ppo/task/go1_joystick_flat/base.yaml 使用
push_by_setting_velocity,间隔为 15 秒,并按轴声明速度范围。
uv run train --algo ppo --task go1_joystick_flat --sim mujoco \
'env.events.push_robot.interval_range_s=[10.0,10.0]'
geom_size 生命周期边界¶
geom_size 明确不属于 ResetRandomizationPayload,并且不得在热路径上通过 BatchEnvPool.reset(..., randomization=...) 修改。
原因在于 geom_size 会改变模型几何和模型 identity;正确的生命周期是:
task provider 在
build_init_randomization_plan(...)中生成模型变体以及 env 到模型的分配。MuJoCo 后端在冷路径上使用
MjSpec修改 geom size,并编译 scale 专属的MjModel。后端使用长度为
num_envs的模型序列构造BatchEnvPool。
reset 阶段只在同一模型 identity 内执行状态和参数扰动;它不处理
geom_size。
这条边界存在的目的是遵循冷路径 asset/model-metadata 访问原则:step()、reset() 和热路径 DR 不解析 XML、不读取 asset,也不在运行时基于 asset 元数据进行分支。
相关任务¶
G1 Motion Tracking:开启 DR 前先确认 motion 资产和 replay。
Go2 Rough Terrain:常见的是 mass、COM、friction、push。
有关配置示例,请参阅 配置。有关开发者 provider 接口和后端能力边界,请参阅 编写 Provider 和 Domain Randomization Contract。