背景
当前 env 设计与 RL 强耦合:ArrayEnv 的 ArrayEnvState(obs/reward/terminated/truncated 整包)、auto-reset、truncation 全部固化在唯一的环境基类里。非 RL 使用方(纯仿真查看、数据采集、teleop)要么继承 DirectEnv/ManagerEnv 被迫接受整套 MDP 契约,要么绕过 core 手工拼装(scripts/view.py 的 robot 路径直接用 motrixsim.RenderApp)。
对照 IsaacLab 的分层(ManagerBasedEnv → ManagerBasedRLEnv,DirectRLEnv 平行,纯仿真层在 env 体系之外),可以抽出一层与 RL 无关的任务环境。
已验证事实:ManagerEnv 在 rewards = {}、terminations = {} 下可正常构造、编译、step(codegen 空组退化优雅,实测 g1-walk-flat reward 恒 0、terminated 恒 False)——能力层不缺,缺的是类与契约切分。
设计
1. SimApp:纯仿真门面(RL-free,无 obs/action)
- 位置
motrix_env_core/sim/app.py,只 import sim.backend/sim.registry/config
- 定位:仿真应用外壳,统一物理、渲染与窗口生命周期
__init__(scene, sim=SimCfg(), num_envs=1, backend=None, render_spacing=1.0, render=None);render 传入时立即 open
open(config):创建/替换 renderer(关旧开新,不重建 backend);render() 呈现一帧;close() 幂等,先关窗口
step(substeps=1) 转发 SimBackend.step;run(substeps=1, fps=60) 应用循环直至窗口关闭
- 不暴露
capture(headless 录制第一版不进)
- 配套契约改动:
SimRenderer 增加 is_closed 抽象 property;SimBackend 增加 dt property
view.py 的 robot 查看路径迁移为第一个使用方
2. ManagerBasedEnv:非 RL 任务环境(对位 IsaacLab ManagerBasedEnv)
step(action) -> NpObs:apply_action → physics → read → observe kernel,无 episode
reset(env_ids=None) -> NpObs:走 SimResetRuntime,并触发 commands 的 reset_env hooks
- 无 reward/done/episode_steps/truncation/auto-reset(episode 语义全归 RL 层)
- 满足
ABEnv(obs/action space),不继承 ArrayRLEnv
- 构造期校验
rewards == {} and terminations == {},报错指明 reward/termination 属于 ManagerRLEnv 工作流
- 不做
reset_to(state)(无使用方,scene state 格式未定义;将来以 mimic/回放任务驱动)
3. ManagerRuntime:共享内核(内部,不是 env)
- 承载现
ManagerEnv 中与生命周期无关的 ~80%:term 装配、term-query 合并编译、read program、metrics、kernel 构建、SimResetRuntime、读写刷新
- 无公开
step/reset,只有下划线原语(_apply_actions/_advance_physics/_refresh_reads/_evaluate/_observe/_reset_rows)
- 两个 env 外壳平行组合(不采用 IsaacLab 的继承式切分:
ArrayEnv 模板方法与 base 的 step/reset/apply_action 同名不同签名,MRO 遮蔽会静默丢失 auto-reset 生命周期)
SwapObsBuffer 改为 runtime 内部持有「obs 页 + 可选 evaluate 输出页」;codegen/缓存/fingerprint 不动
4. RL 层改名(语义显性化)
| 旧 |
新 |
理由 |
ArrayEnv |
ArrayRLEnv |
拥有的全是 MDP 语义;继承它 = 接受 RL 契约 |
DirectEnv / DirectEnvCfg |
DirectRLEnv / DirectRLEnvCfg |
对齐 IsaacLab 与家族命名一致性 |
ManagerEnv |
ManagerRLEnv |
manager 工作流 RL 外壳,内核来自 ManagerRuntime |
ArrayEnvState 不改名(step 契约数据类,语义仍准确)
- 模块路径
array/、direct/、numba/manager/ 不动(package 表达工作流,类表达契约)
- 不留旧名别名(引用一次迁干净)
最终家族:
SimApp 纯仿真(无 obs/action)
ManagerBasedEnv obs/action 任务层(无 reward/done/episode)
── RL 层 ──
ArrayRLEnv NumPy 前端 MDP 生命周期模板
DirectRLEnv(ArrayRLEnv) 直接工作流
ManagerRLEnv(..., ArrayRLEnv) manager 工作流
迁移批次
- core:
ManagerRuntime 抽取 + ManagerBasedEnv/ManagerRLEnv 定义 + 三个改名(同一语义动作一批完成)+ SimApp/SimRenderer.is_closed/SimBackend.dt
- motrix_envs:所有
ManagerEnv→ManagerRLEnv、DirectEnv→DirectRLEnv 子类迁移
- registry 前端推断 / motrix_rl isinstance / scripts / bench 迁移;
view.py robot 路径接 SimApp
- docs(含 AGENTS.md 运行时基类段落)
每批全量 pytest;批次 2 后跑 direct 系与 manager 系训练 smoke 各一。
验收标准
- 现有全部 env 改名迁移后
step/reset/metrics 输出逐位一致(测试套件 + 训练 smoke)
ManagerBasedEnv + 空 rewards/terminations 配置可注册使用,数据采集/view 可直接驱动,全程无 reward/done 概念出现
motrix_rl、TorchEnv、deploy 链路不受影响
- 改名无残留引用(grep 扫描验收)
波及面
ManagerEnv 约 154 处引用 / 约 45 文件(core 14 + envs 10 + 测试 8 + docs 15 + bench/AGENTS 等)
DirectEnv/DirectEnvCfg 约 176 + 66 处引用(集中在 motrix_envs/basic/)
ArrayEnv 约 240 处(含 ArrayEnvState,后者不改名)
决策记录
ManagerBasedEnv.step 返回 NpObs(非 IsaacLab 的 (obs, extras) 元组)
- episode 管理全归 RL 层(base 无 truncation/episode_steps)
- RL 类改名
ManagerRLEnv,不留 ManagerEnv 别名
- 共享内核用组合(
ManagerRuntime),不用继承(避免 step/reset/apply_action MRO 遮蔽)
DirectEnv 一并改名 DirectRLEnv(家族一致性)
- base
reset 触发 command reset_env hooks(显式复位语义自洽,与 RL auto-reset 同入口)
- 第一版不做
reset_to、不做 headless capture API
背景
当前 env 设计与 RL 强耦合:
ArrayEnv的ArrayEnvState(obs/reward/terminated/truncated 整包)、auto-reset、truncation 全部固化在唯一的环境基类里。非 RL 使用方(纯仿真查看、数据采集、teleop)要么继承DirectEnv/ManagerEnv被迫接受整套 MDP 契约,要么绕过 core 手工拼装(scripts/view.py的 robot 路径直接用motrixsim.RenderApp)。对照 IsaacLab 的分层(
ManagerBasedEnv→ManagerBasedRLEnv,DirectRLEnv平行,纯仿真层在 env 体系之外),可以抽出一层与 RL 无关的任务环境。已验证事实:
ManagerEnv在rewards = {}、terminations = {}下可正常构造、编译、step(codegen 空组退化优雅,实测g1-walk-flatreward 恒 0、terminated 恒 False)——能力层不缺,缺的是类与契约切分。设计
1. SimApp:纯仿真门面(RL-free,无 obs/action)
motrix_env_core/sim/app.py,只 importsim.backend/sim.registry/config__init__(scene, sim=SimCfg(), num_envs=1, backend=None, render_spacing=1.0, render=None);render传入时立即openopen(config):创建/替换 renderer(关旧开新,不重建 backend);render()呈现一帧;close()幂等,先关窗口step(substeps=1)转发SimBackend.step;run(substeps=1, fps=60)应用循环直至窗口关闭capture(headless 录制第一版不进)SimRenderer增加is_closed抽象 property;SimBackend增加dtpropertyview.py的 robot 查看路径迁移为第一个使用方2. ManagerBasedEnv:非 RL 任务环境(对位 IsaacLab
ManagerBasedEnv)step(action) -> NpObs:apply_action → physics → read → observe kernel,无 episodereset(env_ids=None) -> NpObs:走SimResetRuntime,并触发 commands 的reset_envhooksABEnv(obs/action space),不继承ArrayRLEnvrewards == {} and terminations == {},报错指明 reward/termination 属于ManagerRLEnv工作流reset_to(state)(无使用方,scene state 格式未定义;将来以 mimic/回放任务驱动)3. ManagerRuntime:共享内核(内部,不是 env)
ManagerEnv中与生命周期无关的 ~80%:term 装配、term-query 合并编译、read program、metrics、kernel 构建、SimResetRuntime、读写刷新step/reset,只有下划线原语(_apply_actions/_advance_physics/_refresh_reads/_evaluate/_observe/_reset_rows)ArrayEnv模板方法与 base 的step/reset/apply_action同名不同签名,MRO 遮蔽会静默丢失 auto-reset 生命周期)SwapObsBuffer改为 runtime 内部持有「obs 页 + 可选 evaluate 输出页」;codegen/缓存/fingerprint 不动4. RL 层改名(语义显性化)
ArrayEnvArrayRLEnvDirectEnv/DirectEnvCfgDirectRLEnv/DirectRLEnvCfgManagerEnvManagerRLEnvManagerRuntimeArrayEnvState不改名(step 契约数据类,语义仍准确)array/、direct/、numba/manager/不动(package 表达工作流,类表达契约)最终家族:
迁移批次
ManagerRuntime抽取 +ManagerBasedEnv/ManagerRLEnv定义 + 三个改名(同一语义动作一批完成)+SimApp/SimRenderer.is_closed/SimBackend.dtManagerEnv→ManagerRLEnv、DirectEnv→DirectRLEnv子类迁移view.pyrobot 路径接SimApp每批全量 pytest;批次 2 后跑 direct 系与 manager 系训练 smoke 各一。
验收标准
step/reset/metrics输出逐位一致(测试套件 + 训练 smoke)ManagerBasedEnv+ 空 rewards/terminations 配置可注册使用,数据采集/view 可直接驱动,全程无 reward/done 概念出现motrix_rl、TorchEnv、deploy 链路不受影响波及面
ManagerEnv约 154 处引用 / 约 45 文件(core 14 + envs 10 + 测试 8 + docs 15 + bench/AGENTS 等)DirectEnv/DirectEnvCfg约 176 + 66 处引用(集中在motrix_envs/basic/)ArrayEnv约 240 处(含ArrayEnvState,后者不改名)决策记录
ManagerBasedEnv.step返回NpObs(非 IsaacLab 的(obs, extras)元组)ManagerRLEnv,不留ManagerEnv别名ManagerRuntime),不用继承(避免step/reset/apply_actionMRO 遮蔽)DirectEnv一并改名DirectRLEnv(家族一致性)reset触发 commandreset_envhooks(显式复位语义自洽,与 RL auto-reset 同入口)reset_to、不做 headless capture API