diff --git a/AGENTS.md b/AGENTS.md index 4ca2f4c3..a9e246d5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,12 +9,13 @@ MotrixLab 是构建在 MotrixSim 仿真后端之上的强化学习框架,提 ## Workspace 结构 -项目使用 UV workspace,包含十二个 package: +项目使用 UV workspace,包含以下 package: -- `motrix_env_core`:backend 无关的环境框架(不依赖任何 simulator) +- `motrix_env_core`:backend 无关的环境框架,拥有 robot registry 与 `motrix_env_core.robots` entry-point discovery(不依赖任何 simulator 或 `motrix_robots`) - `motrix_env_motrixsim`:MotrixSim 仿真后端(SimBackend、scene compiler、renderer、torch frontend) - `motrix_env_mujoco`:仅用于编译的 MuJoCo scene 后端 -- `motrix_envs`:内置环境、机器人模型与任务资产 +- `motrix_robots`:仿真 `RobotCfg`、模型自有关键姿态及模型 MJCF/URDF、mesh 与模型纹理资产,仅依赖 core;模型定义模块与 `assets/` 位于 package 根目录,任务场景、地面与 terrain 资产属于 `motrix_envs`。根 package 以显式 `__all__` 提供模型类和类型化 humanoid/quadruped helper 的公共 API;框架内部从定义模块导入。注册回调由首次 robot registry 查询惰性调用;导入 package 或模型类不触发 discovery、注册、资产扫描或读取,也不加载 simulator 或训练环境 +- `motrix_envs`:内置环境与任务资产 - `motrix_rl`:RL 控制平面、训练编排与稳定 contracts(runner、run/checkpoint、backend 选择、`motrix_rl.frameworks` discovery、provider/trainer 接口) - `motrix_rl_builtin`:内置 Motrix FastSAC provider 插件 - `motrix_rl_skrl`:SKRL PPO provider 插件(Torch 必需,额外 JAX runtime 可选) @@ -99,7 +100,7 @@ Python 方法,由 manager 运行时契约定义(`wiki/design/manager/runtime ### 版本与依赖一致性 -- 所有 workspace package(见上文 Workspace 结构,共十二个)的 `pyproject.toml` 中 `version` 字段必须保持一致。 +- 所有 workspace package(见上文 Workspace 结构)的 `pyproject.toml` 中 `version` 字段必须保持一致。 - MotrixSim 相关依赖版本必须在使用该依赖的 workspace package 之间保持一致。 - 关键第三方依赖使用精确版本锁定(`===`);新增或升级依赖时同步更新 `uv.lock`。 diff --git a/README.md b/README.md index d86b4ea0..209dced4 100644 --- a/README.md +++ b/README.md @@ -161,11 +161,20 @@ Seven reusable robot models are registered out of the box and can be combined in python scripts/view.py robot=go2 ``` +Use the public configuration API to compose a model directly: + +```python +from motrix_robots import Microduck, UnitreeGo2Robot + +microduck = Microduck() +go2 = UnitreeGo2Robot() +``` + See [Supported Robots](https://motrixlab.readthedocs.io/en/latest/user_guide/robots.html) for configuration details and how to add your own model. ## 🏗️ What's Inside -MotrixLab is a [uv](https://docs.astral.sh/uv/) workspace of twelve packages: +MotrixLab is a [uv](https://docs.astral.sh/uv/) workspace with the following packages: | Package | PyPI name | Description | | --- | --- | --- | @@ -173,10 +182,11 @@ MotrixLab is a [uv](https://docs.astral.sh/uv/) workspace of twelve packages: | **motrix_deploy_mujoco** | `motrix-deploy-mujoco` | MuJoCo deployment backend plugin | | **motrix_deploy_unitree** | `motrix-deploy-unitree` | Unitree SDK2 DDS hardware backend plugin | | **motrix_deploy_tasks** | `motrix-deploy-tasks` | Versioned deployment tasks and executable bootstrap | -| **motrix_env_core** | `motrix-env-core` | Backend-agnostic environment framework, configuration, registry, lifecycle, and rendering | +| **motrix_env_core** | `motrix-env-core` | Backend-agnostic environment framework, configuration, registry, robot entry-point discovery, lifecycle, and rendering | | **motrix_env_motrixsim** | `motrix-env-motrixsim` | Live MotrixSim backend, renderer, and Torch frontend | | **motrix_env_mujoco** | `motrix-env-mujoco` | Compile-only MuJoCo scene backend | -| **motrix_envs** | `motrix-envs` | Built-in environments, robot models, data, and deployment-profile compilers | +| **motrix_robots** | `motrix-robots` | Simulation robot configs, model-owned poses, and model MJCF/URDF, meshes, and model textures; core-only dependency | +| **motrix_envs** | `motrix-envs` | Built-in environments, task assets, data, and deployment-profile compilers | | **motrix_rl** | `motrix-rl` | RL control plane, provider/trainer contracts, run/checkpoint handling, and discovery | | **motrix_rl_builtin** | `motrix-rl-builtin` | Built-in Motrix FastSAC provider | | **motrix_rl_skrl** | `motrix-rl-skrl` | Required SKRL PPO Torch provider; optional JAX extra | diff --git a/README.zh-CN.md b/README.zh-CN.md index 9dcc0bab..2136856b 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -161,11 +161,20 @@ python scripts/view.py env=go2-walk-rough python scripts/view.py robot=go2 ``` +通过公共配置 API 直接构造模型,用于场景组合: + +```python +from motrix_robots import Microduck, UnitreeGo2Robot + +microduck = Microduck() +go2 = UnitreeGo2Robot() +``` + 机器人配置细节与自定义新模型的方法见[支持的机器人](https://motrixlab.readthedocs.io/zh-cn/latest/user_guide/robots.html)。 ## 🏗️ 项目组成 -MotrixLab 是一个由十二个 package 组成的 [uv](https://docs.astral.sh/uv/) workspace: +MotrixLab 是一个 [uv](https://docs.astral.sh/uv/) workspace,包含以下 package: | Package | PyPI 名称 | 说明 | | --- | --- | --- | @@ -173,10 +182,11 @@ MotrixLab 是一个由十二个 package 组成的 [uv](https://docs.astral.sh/uv | **motrix_deploy_mujoco** | `motrix-deploy-mujoco` | MuJoCo 部署 backend plugin | | **motrix_deploy_unitree** | `motrix-deploy-unitree` | Unitree SDK2 DDS 硬件 backend plugin | | **motrix_deploy_tasks** | `motrix-deploy-tasks` | 带版本的部署任务与可执行入口 bootstrap | -| **motrix_env_core** | `motrix-env-core` | backend 无关的环境框架、配置、registry、生命周期与渲染 | +| **motrix_env_core** | `motrix-env-core` | backend 无关的环境框架、配置、registry、robot entry-point discovery、生命周期与渲染 | | **motrix_env_motrixsim** | `motrix-env-motrixsim` | MotrixSim 实时仿真 backend、renderer 与 Torch frontend | | **motrix_env_mujoco** | `motrix-env-mujoco` | 仅负责编译场景的 MuJoCo backend | -| **motrix_envs** | `motrix-envs` | 内置环境、机器人模型、数据及部署 profile 编译实现 | +| **motrix_robots** | `motrix-robots` | 仿真机器人配置、模型自有姿态及 模型 MJCF/URDF、mesh 与模型纹理资产;仅依赖 core | +| **motrix_envs** | `motrix-envs` | 内置环境、任务资产、数据及部署 profile 编译实现 | | **motrix_rl** | `motrix-rl` | RL 控制平面、provider/trainer contract、run/checkpoint 管理与 discovery | | **motrix_rl_builtin** | `motrix-rl-builtin` | 内置 Motrix FastSAC provider | | **motrix_rl_skrl** | `motrix-rl-skrl` | 必需的 SKRL PPO Torch provider;可选 JAX extra | diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index b54558dd..5b380f65 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -17,10 +17,10 @@ separately downloaded optional asset. | Franka Emika Panda MJCF and meshes | `motrix_envs/src/motrix_envs/manipulation/franka_lift_cube/xmls/`; `motrix_envs/src/motrix_envs/manipulation/franka_open_cabinet/xmls/` | [frankarobotics/franka_ros](https://github.com/frankarobotics/franka_ros/tree/develop/franka_description), see each directory README | The public source repository declares Apache-2.0; local model licenses are present. Record the exact imported revision and preserve attribution for all derived meshes | | Shadow Hand E3M5 description | `motrix_envs/src/motrix_envs/manipulation/shadow_hand/xmls/` | Record the exact upstream source and revision before release | A local Apache-2.0 file is present; upstream provenance still needs to be recorded | | RM65 descriptions and meshes | `motrix_envs/src/motrix_envs/manipulation/rm65_open_cabinet/xmls/`; `motrix_envs/src/motrix_envs/common/rm65/` | Record the exact upstream source and revision before release | A local Apache-2.0 file is present for the cabinet scene; verify every shared mesh | -| Unitree G1, Go1 and Go2 assets | `motrix_envs/src/motrix_envs/robot/assets/`; `motrix_envs/src/motrix_envs/locomotion/go1/` | Record the exact Unitree source and model terms | Release approval required from the rights holder; trademarks and model terms are separate from the code license | -| ANYmal-C assets | `motrix_envs/src/motrix_envs/robot/assets/anymal_c/`; `motrix_envs/src/motrix_envs/locomotion/anymal_c/` | Record the exact upstream source and model terms | Release approval and attribution required | -| Booster K1 assets | `motrix_envs/src/motrix_envs/robot/assets/k1/` | [BoosterRobotics/booster_assets K1 model](https://github.com/BoosterRobotics/booster_assets/blob/main/robots/K1/K1_22dof.xml) | The public repository declares BSD-3-Clause and the local XML identifies this source. Record the exact imported revision and confirm that the derived XML and meshes may be redistributed | -| Dex-EVT assets | `motrix_envs/src/motrix_envs/robot/assets/dex_evt/` | Record the exact upstream source and model terms | No public provenance or redistribution permission is documented in this checkout; release approval and attribution are required | +| Unitree G1, Go1 and Go2 assets | `motrix_robots/src/motrix_robots/assets/g1/`; `motrix_robots/src/motrix_robots/assets/go1/`; `motrix_robots/src/motrix_robots/assets/go2/` | Record the exact Unitree source and model terms | Release approval required from the rights holder; trademarks and model terms are separate from the code license | +| ANYmal-C assets | `motrix_robots/src/motrix_robots/assets/anymal_c/`; `motrix_envs/src/motrix_envs/locomotion/anymal_c/` | Record the exact upstream source and model terms | Release approval and attribution required | +| Booster K1 assets | `motrix_robots/src/motrix_robots/assets/k1/` | [BoosterRobotics/booster_assets K1 model](https://github.com/BoosterRobotics/booster_assets/blob/main/robots/K1/K1_22dof.xml) | The public repository declares BSD-3-Clause and the local XML identifies this source. Record the exact imported revision and confirm that the derived XML and meshes may be redistributed | +| Dex-EVT assets | `motrix_robots/src/motrix_robots/assets/dex_evt/` | Record the exact upstream source and model terms | No public provenance or redistribution permission is documented in this checkout; release approval and attribution are required | | LAFAN1 input data and converter | `motrix_envs/src/motrix_envs/motion/converters/`; downloaded inputs are not part of the repository | [LAFAN1 Retargeting Dataset](https://huggingface.co/datasets/lvhaidong/LAFAN1_Retargeting_Dataset) | CC BY-NC-ND 4.0 is documented by the user guide; retain attribution and state the non-commercial/no-derivatives limits before redistributing any converted output | | Bundled whole-body-tracking motion clips | `motrix_envs/src/motrix_envs/locomotion/wbt/assets/motion/` | Record the source, revision, author, and terms for each `*.npz` clip | Provenance and redistribution permission are not yet documented for every clip; do not publish until cleared | | Documentation videos, posters and benchmark figures | `docs/source/_static/` | Record whether each item is original, generated, or derived from a third-party asset | Verify the rights for the source material and the resulting media independently; retain attribution where required | diff --git a/bench/bench_physics.py b/bench/bench_physics.py index d6d01f37..d1028dbc 100644 --- a/bench/bench_physics.py +++ b/bench/bench_physics.py @@ -40,7 +40,6 @@ import numpy as np from report import render_table -import motrix_envs # noqa: F401 registers robots and scene assets from motrix_env_core import registry from motrix_env_core.base import SimCfg from motrix_env_motrixsim.compiler import MotrixSimSceneCompiler diff --git a/docs/scripts/generate_robot_docs.py b/docs/scripts/generate_robot_docs.py index 40993056..7be0995f 100644 --- a/docs/scripts/generate_robot_docs.py +++ b/docs/scripts/generate_robot_docs.py @@ -12,7 +12,6 @@ import motrixsim as mtx from motrixsim.render import RenderApp, RenderSettings -import motrix_envs # noqa: F401 registers built-in robots from motrix_env_core import registry from motrix_env_core.config.scene import MjcfFileCfg, SystemCameraCfg, UrdfFileCfg from motrix_env_motrixsim.compiler import build_scene_model diff --git a/docs/source/en/user_guide/envs/humanoid_velocity_tracking/adding_robot.md b/docs/source/en/user_guide/envs/humanoid_velocity_tracking/adding_robot.md index 78201758..963483e5 100644 --- a/docs/source/en/user_guide/envs/humanoid_velocity_tracking/adding_robot.md +++ b/docs/source/en/user_guide/envs/humanoid_velocity_tracking/adding_robot.md @@ -38,13 +38,12 @@ nested config overrides, field details, and tuning guidance. Use the following layout: ```text -motrix_envs/src/motrix_envs/ -├── robot/ -│ ├── .py # RobotCfg, including its default key pose -│ └── assets// # Reusable robot assets -└── locomotion/ - └── humanoid/ - └── .py # Flat/terrain configs and environment registration +motrix_robots/src/motrix_robots/ +├── .py # RobotCfg and default key pose +└── assets// # Reusable robot assets + +motrix_envs/src/motrix_envs/locomotion/humanoid/ +└── .py # Flat/terrain configs and environment registration configs/task/ ├── -walk-flat/ diff --git a/docs/source/en/user_guide/envs/quadruped_velocity_tracking/adding_robot.md b/docs/source/en/user_guide/envs/quadruped_velocity_tracking/adding_robot.md index 07e1be85..2f179165 100644 --- a/docs/source/en/user_guide/envs/quadruped_velocity_tracking/adding_robot.md +++ b/docs/source/en/user_guide/envs/quadruped_velocity_tracking/adding_robot.md @@ -8,13 +8,12 @@ construction, diagonal-trot rewards, reset, and termination. Use the following layout: ```text -motrix_envs/src/motrix_envs/ -├── robot/ -│ ├── .py # QuadrupedRobotCfg and default key pose -│ └── assets// # Robot assets reusable across tasks -└── locomotion/ - └── quadruped/ - └── .py # Flat/rough configs and environment registration +motrix_robots/src/motrix_robots/ +├── .py # QuadrupedRobotCfg and default key pose +└── assets// # Robot assets reusable across tasks + +motrix_envs/src/motrix_envs/locomotion/quadruped/ +└── .py # Flat/rough configs and environment registration configs/task/ ├── -walk-flat/ @@ -43,7 +42,7 @@ foot in front-left, front-right, rear-left, rear-right order: ```python from motrix_env_core.config import configclass from motrix_env_core.config.scene import KeyPoseCfg, MjcfFileCfg -from motrix_envs.robot import QuadrupedLegCfg, QuadrupedLegsCfg, QuadrupedRobotCfg +from motrix_robots import QuadrupedLegCfg, QuadrupedLegsCfg, QuadrupedRobotCfg @configclass(kw_only=True) diff --git a/docs/source/en/user_guide/robots.md b/docs/source/en/user_guide/robots.md index b6eea17b..32d19890 100644 --- a/docs/source/en/user_guide/robots.md +++ b/docs/source/en/user_guide/robots.md @@ -1,7 +1,6 @@ # Supported Robots -MotrixLab exposes reusable robot models through the robot registry. A registered robot has a public `RobotCfg` and can -be composed into different scenes and tasks. The table below is generated directly from the registry and robot configs. +`motrix_robots` provides reusable robot models that you can preview independently or use in tasks from `motrix_envs`. ## Built-in robots @@ -20,6 +19,38 @@ be composed into different scenes and tasks. The table below is generated direct +## Preview a robot + +Use `view.py` to inspect a registered robot in its default pose without creating an RL environment: + +```bash +python scripts/view.py robot=go2 +``` + +Robot view mode builds a static standard scene. It does not sample actions or run a physics rollout. + +## Python API + +Import reusable configurations directly from `motrix_robots`: + +```python +from motrix_robots import Microduck, UnitreeGo2Robot + +microduck = Microduck() +go2 = UnitreeGo2Robot(prefix="robot_") +``` + +You can also select a robot by its registry name and place it in a standard scene: + +```python +from motrix_env_core import registry +from motrix_envs.config.scene import StandardSceneCfg, StandardSceneObjsCfg + +print(registry.list_registered_robots()) +robot = registry.make_robot_config("go2") +scene = StandardSceneCfg(objs=StandardSceneObjsCfg(robot=robot)) +``` + ## Define a new robot A reusable robot should be defined as a `RobotCfg` that describes only the robot model and how it is instantiated. @@ -31,7 +62,7 @@ markers, and task-created sensors belong to `SceneCfg` or the task configuration Use the following layout for a built-in robot: ```text -motrix_envs/src/motrix_envs/robot/ +motrix_robots/src/motrix_robots/ ├── my_robot.py └── assets/my_robot/ ├── my_robot.xml # or my_robot.urdf @@ -45,7 +76,7 @@ Import `ActuatorCfg`, `PositionActuatorCfg`, and `MotorActuatorCfg` from `motrix ### 2. Declare the `RobotCfg` -Define the configuration in `robot/my_robot.py` with `@configclass(kw_only=True)`. This is a minimal MJCF example: +Define the configuration in `motrix_robots/src/motrix_robots/my_robot.py` with `@configclass(kw_only=True)`. This is a minimal MJCF example: ```python from pathlib import Path @@ -88,7 +119,7 @@ robot joint poses here; ground names, task sensor names, and other scene semanti A humanoid robot should inherit `HumanoidRobotCfg` and define its left and right foot links: ```python -from motrix_envs.robot import HumanoidRobotCfg +from motrix_robots import HumanoidRobotCfg @configclass(kw_only=True) @@ -138,18 +169,28 @@ Set `inherit_joint_range=True` to use imported joint limits as the control range ### 3. Register the robot -Import and register a built-in robot in `motrix_envs/robot/__init__.py`: +Register a built-in robot inside the `register()` callback in +`motrix_robots/src/motrix_robots/registration.py`. Import the new class from its defining module +and add its registration to the callback: ```python from motrix_env_core import registry -from motrix_envs.robot.my_robot import MyRobot +from motrix_robots.my_robot import MyRobot -registry.robotcfg("my-robot")(MyRobot) + +def register() -> None: + # Keep the other built-in model registrations here. + registry.robotcfg("my-robot")(MyRobot) ``` -Also add `MyRobot` to that module's `__all__`. The registry name is the stable ID used by the CLI and -`registry.make_robot_config()`. The class must be constructible without arguments; alternatively, register a typed -zero-argument factory. +Installed robot packages are discovered automatically; no manual registration import is needed. +For a separate package, define the same `register()` callback using your own model import and declare it in that +package's `pyproject.toml`: + +```toml +[project.entry-points."motrix_env_core.robots"] +my_robot = "my_robot_package.registration:register" +``` ### 4. Validate @@ -172,32 +213,3 @@ To include the robot in the generated table above, add its type and screenshot p python docs/scripts/generate_robot_docs.py --screenshots my-robot python docs/scripts/generate_robot_docs.py --check ``` - -## Preview a robot - -Use `view.py` to inspect a registered robot in its default pose without creating an RL environment: - -```bash -python scripts/view.py robot=go2 -``` - -Robot view mode builds a static standard scene. It does not sample actions or run a physics rollout. - -## Python API - -Importing `motrix_envs` registers the built-in robots. You can inspect the registry, create a fresh config, and compose -it into a standard scene: - -```python -import motrix_envs # noqa: F401 registers built-in robots -from motrix_env_core import registry -from motrix_envs.config.scene import StandardSceneCfg, StandardSceneObjsCfg - -print(registry.list_registered_robots()) - -robot = registry.make_robot_config("go2") -scene = StandardSceneCfg(objs=StandardSceneObjsCfg(robot=robot)) -``` - -`make_robot_config()` returns a new validated config on every call, so callers can safely customize placement, naming -prefixes, or other instance-level fields. diff --git a/docs/source/en/user_guide/tutorial/basic_frame.md b/docs/source/en/user_guide/tutorial/basic_frame.md index 291cdaa3..bd2f3f35 100644 --- a/docs/source/en/user_guide/tutorial/basic_frame.md +++ b/docs/source/en/user_guide/tutorial/basic_frame.md @@ -34,14 +34,15 @@ With this loop in mind, every MotrixLab package has a place in the figure. ## Which part of the loop each package covers -MotrixLab is a UV workspace of twelve packages. The packages are grouped by ownership rather than treated as one monolithic runtime: +MotrixLab is a UV workspace. The packages are grouped by ownership rather than treated as one monolithic runtime: | Package | Loop stage | Responsibility | | --- | --- | --- | | `motrix_env_core` | Policy–environment interaction | Backend-agnostic environment framework: `EnvCfg`, registry, frontends, lifecycle | | `motrix_env_motrixsim` | Policy–environment interaction | MotrixSim `SimBackend`, renderer, and Torch frontend | | `motrix_env_mujoco` | Scene compilation | Compile-only MuJoCo scene backend | -| `motrix_envs` | Policy–environment interaction | Built-in environments, robot models, and task assets | +| `motrix_robots` | Simulation models | Robot models, default poses, and model assets | +| `motrix_envs` | Policy–environment interaction | Built-in environments and task assets | | `motrix_rl` | Policy training and updates | RL control plane, provider/trainer contracts, run/checkpoint handling, and discovery | | `motrix_rl_builtin` | Policy training and updates | Built-in Motrix FastSAC provider | | `motrix_rl_skrl` | Policy training and updates | SKRL PPO provider for Torch (required) and optional JAX extra | diff --git a/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking/adding_robot.md b/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking/adding_robot.md index e0ffcf8e..4b989391 100644 --- a/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking/adding_robot.md +++ b/docs/source/zh_CN/user_guide/envs/humanoid_velocity_tracking/adding_robot.md @@ -38,13 +38,12 @@ def make_robot_walk_flat_cfg() -> HumanoidVelocityTrackingEnvCfg: 推荐将文件放在以下位置: ```text -motrix_envs/src/motrix_envs/ -├── robot/ -│ ├── .py # RobotCfg,包含默认 key pose -│ └── assets// # 可跨任务复用的机器人资产 -└── locomotion/ - └── humanoid/ - └── .py # 平地/地形配置与环境注册 +motrix_robots/src/motrix_robots/ +├── .py # RobotCfg 与默认关键姿态 +└── assets// # 可跨任务复用的机器人资产 + +motrix_envs/src/motrix_envs/locomotion/humanoid/ +└── .py # 平地/地形配置与环境注册 configs/task/ ├── -walk-flat/ diff --git a/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking/adding_robot.md b/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking/adding_robot.md index 0be7cb09..6fe876f8 100644 --- a/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking/adding_robot.md +++ b/docs/source/zh_CN/user_guide/envs/quadruped_velocity_tracking/adding_robot.md @@ -7,13 +7,12 @@ 推荐使用以下目录布局: ```text -motrix_envs/src/motrix_envs/ -├── robot/ -│ ├── .py # QuadrupedRobotCfg 与默认关键姿态 -│ └── assets// # 可跨任务复用的机器人资产 -└── locomotion/ - └── quadruped/ - └── .py # 平地/粗糙地形配置与环境注册 +motrix_robots/src/motrix_robots/ +├── .py # QuadrupedRobotCfg 与默认关键姿态 +└── assets// # 可跨任务复用的机器人资产 + +motrix_envs/src/motrix_envs/locomotion/quadruped/ +└── .py # 平地/粗糙地形配置与环境注册 configs/task/ ├── -walk-flat/ @@ -41,7 +40,7 @@ robot = registry.make_robot_config("go2") ```python from motrix_env_core.config import configclass from motrix_env_core.config.scene import KeyPoseCfg, MjcfFileCfg -from motrix_envs.robot import QuadrupedLegCfg, QuadrupedLegsCfg, QuadrupedRobotCfg +from motrix_robots import QuadrupedLegCfg, QuadrupedLegsCfg, QuadrupedRobotCfg @configclass(kw_only=True) diff --git a/docs/source/zh_CN/user_guide/robots.md b/docs/source/zh_CN/user_guide/robots.md index e7867891..0c1910fd 100644 --- a/docs/source/zh_CN/user_guide/robots.md +++ b/docs/source/zh_CN/user_guide/robots.md @@ -1,7 +1,6 @@ # 支持的机器人 -MotrixLab 通过 robot registry 暴露可复用的机器人模型。注册后的 robot 具有公共 `RobotCfg`,可以组合到不同的 -scene 和 task 中。下表直接根据 registry 和 robot 配置生成。 +`motrix_robots` 提供可复用的机器人模型,可以独立预览,也可以用于 `motrix_envs` 中的任务。 ## 内置机器人 @@ -20,6 +19,38 @@ scene 和 task 中。下表直接根据 registry 和 robot 配置生成。 +## 独立预览 + +使用 `view.py` 可以在默认姿态下查看已注册 robot,无需创建 RL environment: + +```bash +python scripts/view.py robot=go2 +``` + +robot 模式会构建一个静态标准场景,不采样 action,也不执行 physics rollout。 + +## Python API + +从 `motrix_robots` 直接导入可复用配置: + +```python +from motrix_robots import Microduck, UnitreeGo2Robot + +microduck = Microduck() +go2 = UnitreeGo2Robot(prefix="robot_") +``` + +也可以按 registry 名称选择机器人,并放入标准场景: + +```python +from motrix_env_core import registry +from motrix_envs.config.scene import StandardSceneCfg, StandardSceneObjsCfg + +print(registry.list_registered_robots()) +robot = registry.make_robot_config("go2") +scene = StandardSceneCfg(objs=StandardSceneObjsCfg(robot=robot)) +``` + ## 定义新机器人 新的可复用机器人应定义为 `RobotCfg`,只描述机器人本体及其实例化方式。机器人资产、执行器、仿真所需的 site 和通用 @@ -30,7 +61,7 @@ scene 和 task 中。下表直接根据 registry 和 robot 配置生成。 内置机器人推荐使用以下目录结构: ```text -motrix_envs/src/motrix_envs/robot/ +motrix_robots/src/motrix_robots/ ├── my_robot.py └── assets/my_robot/ ├── my_robot.xml # 或 my_robot.urdf @@ -44,7 +75,7 @@ MJCF 和 URDF 的执行器均通过机器人实例继承的 `BodyCfg.actuators` ### 2. 声明 `RobotCfg` -在 `robot/my_robot.py` 中使用 `@configclass(kw_only=True)` 定义配置类。下面是一份最小的 MJCF 示例: +在 `motrix_robots/src/motrix_robots/my_robot.py` 中使用 `@configclass(kw_only=True)` 定义配置类。下面是一份最小的 MJCF 示例: ```python from pathlib import Path @@ -87,7 +118,7 @@ class MyRobot(RobotCfg): 人形机器人应继承 `HumanoidRobotCfg`,并定义左右脚 link: ```python -from motrix_envs.robot import HumanoidRobotCfg +from motrix_robots import HumanoidRobotCfg @configclass(kw_only=True) @@ -136,17 +167,27 @@ robot = RobotCfg( ### 3. 注册机器人 -内置机器人在 `motrix_envs/robot/__init__.py` 中导入并注册: +内置机器人在 `motrix_robots/src/motrix_robots/registration.py` 的 `register()` 回调中注册。 +从新类的定义模块导入,并将注册语句加入回调: ```python from motrix_env_core import registry -from motrix_envs.robot.my_robot import MyRobot +from motrix_robots.my_robot import MyRobot -registry.robotcfg("my-robot")(MyRobot) + +def register() -> None: + # 保留其他内置模型的注册语句。 + registry.robotcfg("my-robot")(MyRobot) ``` -同时将 `MyRobot` 加入该模块的 `__all__`。注册名称是命令行和 `registry.make_robot_config()` 使用的稳定 ID;配置类必须能 -无参数构造,或者改用带明确返回类型的零参数 factory 注册。 +已安装的机器人 package 会自动发现,无需手动导入注册模块。 +若使用独立 package,在自己的注册模块中采用同样的 `register()` 回调并导入自己的模型,再在该 package 的 +`pyproject.toml` 中声明: + +```toml +[project.entry-points."motrix_env_core.robots"] +my_robot = "my_robot_package.registration:register" +``` ### 4. 验证 @@ -168,31 +209,3 @@ python -m pytest motrix_envs/tests/test_robot_cfg.py -q python docs/scripts/generate_robot_docs.py --screenshots my-robot python docs/scripts/generate_robot_docs.py --check ``` - -## 独立预览 - -使用 `view.py` 可以在默认姿态下查看已注册 robot,无需创建 RL environment: - -```bash -python scripts/view.py robot=go2 -``` - -robot 模式会构建一个静态标准场景,不采样 action,也不执行 physics rollout。 - -## Python API - -导入 `motrix_envs` 会注册所有内置 robot。随后可以查看 registry、创建新的配置实例并组合到标准 scene 中: - -```python -import motrix_envs # noqa: F401 registers built-in robots -from motrix_env_core import registry -from motrix_envs.config.scene import StandardSceneCfg, StandardSceneObjsCfg - -print(registry.list_registered_robots()) - -robot = registry.make_robot_config("go2") -scene = StandardSceneCfg(objs=StandardSceneObjsCfg(robot=robot)) -``` - -`make_robot_config()` 每次调用都会返回一个经过校验的新配置,因此调用方可以安全地修改位置、名称前后缀或其他 -实例级字段。 diff --git a/docs/source/zh_CN/user_guide/tutorial/basic_frame.md b/docs/source/zh_CN/user_guide/tutorial/basic_frame.md index 2f891fd7..55f94f04 100644 --- a/docs/source/zh_CN/user_guide/tutorial/basic_frame.md +++ b/docs/source/zh_CN/user_guide/tutorial/basic_frame.md @@ -29,14 +29,15 @@ MotrixLab 将环境实现、仿真后端、训练方法、配置和命令行编 ## MotrixLab package 与流程的对应 -MotrixLab 是一个由十二个 package 组成的 UV workspace。下面按所有权而不是按单一整体运行时划分这些 package: +MotrixLab 是一个 UV workspace。下面按所有权而不是按单一整体运行时划分这些 package: | Package | 流程环节 | 职责 | | --- | --- | --- | | `motrix_env_core` | 策略与环境的交互 | backend 无关的环境框架:`EnvCfg`、registry、环境前端与生命周期 | | `motrix_env_motrixsim` | 策略与环境的交互 | MotrixSim `SimBackend`、renderer 与 Torch frontend | | `motrix_env_mujoco` | 场景编译 | 仅负责编译场景的 MuJoCo backend | -| `motrix_envs` | 策略与环境的交互 | 内置环境、机器人模型与任务资产 | +| `motrix_robots` | 仿真模型 | 机器人模型、默认姿态与模型资产 | +| `motrix_envs` | 策略与环境的交互 | 内置环境与任务资产 | | `motrix_rl` | 策略的训练与更新 | RL 控制平面、provider/trainer contract、run/checkpoint 管理与 discovery | | `motrix_rl_builtin` | 策略的训练与更新 | 内置 Motrix FastSAC provider | | `motrix_rl_skrl` | 策略的训练与更新 | SKRL PPO Torch provider(必需)及可选 JAX extra | diff --git a/motrix_env_core/src/motrix_env_core/registry.py b/motrix_env_core/src/motrix_env_core/registry.py index 54f18311..0ed50c63 100644 --- a/motrix_env_core/src/motrix_env_core/registry.py +++ b/motrix_env_core/src/motrix_env_core/registry.py @@ -5,6 +5,7 @@ import inspect from collections.abc import Callable from dataclasses import dataclass, field +from importlib.metadata import EntryPoint, entry_points from typing import Any, get_type_hints from motrix_env_core.base import ABEnv, EnvCfg @@ -98,7 +99,41 @@ class RobotMeta: robot_cfg_factory: RobotCfgFactory +ROBOT_ENTRY_POINT_GROUP = "motrix_env_core.robots" + _robots: dict[str, RobotMeta] = {} +_robots_discovered = False +_robots_discovering = False +_robot_entry_points: tuple[EntryPoint, ...] | None = None +_completed_robot_entry_points = 0 + + +def _discover_robots() -> None: + """Invoke installed robot registration callbacks on the first query. + + Completed callbacks are not repeated if a later entry point fails. Failed + loads/callbacks propagate and are retried on the next query; any registration + side effects of a failed callback remain. Reentrant queries see the registry + as populated so far, without starting another discovery pass. + """ + global _robots_discovered, _robots_discovering, _robot_entry_points, _completed_robot_entry_points + if _robots_discovered or _robots_discovering: + return + _robots_discovering = True + try: + if _robot_entry_points is None: + _robot_entry_points = tuple( + sorted(entry_points(group=ROBOT_ENTRY_POINT_GROUP), key=lambda ep: (ep.name, ep.value)) + ) + for entry_point in _robot_entry_points[_completed_robot_entry_points:]: + register = entry_point.load() + if not callable(register): + raise TypeError(f"Robot entry point {entry_point.name!r} must load a callable") + register() + _completed_robot_entry_points += 1 + _robots_discovered = True + finally: + _robots_discovering = False def _get_env_meta(name: str) -> EnvMeta: @@ -232,7 +267,8 @@ def decorator(provider: Any) -> Any: def make_robot_config(name: str) -> RobotCfg: - """Create and validate a fresh config for a registered robot.""" + """Discover installed robot plugins, then create and validate a fresh config.""" + _discover_robots() if name not in _robots: raise ValueError(f"Robot '{name}' is not registered.") @@ -247,7 +283,8 @@ def make_robot_config(name: str) -> RobotCfg: def list_registered_robots() -> dict[str, dict[str, Any]]: - """List registered robot configs.""" + """Discover installed robot plugins and list their registered configs.""" + _discover_robots() return { name: { "config_class": meta.robot_cfg_cls.__name__, diff --git a/motrix_env_core/tests/test_registry.py b/motrix_env_core/tests/test_registry.py index ae61ff3e..45e6166d 100644 --- a/motrix_env_core/tests/test_registry.py +++ b/motrix_env_core/tests/test_registry.py @@ -88,13 +88,20 @@ def compile_reads(self, queries) -> PhysicsReadProgram: @pytest.fixture(autouse=True) -def _restore_global_registry(): +def _restore_global_registry(monkeypatch): """Drop any envs/robots a test registers so they do not leak across tests. Several tests below register throwaway env/robot configs into the module-level registry. Without cleanup they leak into later tests (e.g. the robot-docs suite asserts the registered robot set matches its metadata) and into whole-repo runs. """ + # Core unit tests must not depend on installed robot distributions. + monkeypatch.setattr(registry, "entry_points", lambda *, group: ()) + monkeypatch.setattr(registry, "_robots", {}) + monkeypatch.setattr(registry, "_robots_discovered", False) + monkeypatch.setattr(registry, "_robots_discovering", False) + monkeypatch.setattr(registry, "_robot_entry_points", None) + monkeypatch.setattr(registry, "_completed_robot_entry_points", 0) envs_before = set(registry._envs) robots_before = set(registry._robots) yield diff --git a/motrix_env_core/tests/test_robot_discovery.py b/motrix_env_core/tests/test_robot_discovery.py new file mode 100644 index 00000000..152d9f35 --- /dev/null +++ b/motrix_env_core/tests/test_robot_discovery.py @@ -0,0 +1,203 @@ +# Copyright Motphys Technology Co., Ltd. 2025, 2026 +# SPDX-License-Identifier: Apache-2.0 + +from dataclasses import dataclass + +import pytest + +from motrix_env_core import registry +from motrix_env_core.config import configclass +from motrix_env_core.config.scene import MjcfFileCfg, RobotCfg + + +@dataclass +class FakeEntryPoint: + name: str + value: str + callback: object + loads: int = 0 + load_error: Exception | None = None + + def load(self): + self.loads += 1 + if self.load_error is not None: + raise self.load_error + return self.callback + + +@pytest.fixture(autouse=True) +def isolated_robot_registry(monkeypatch): + monkeypatch.setattr(registry, "_robots", {}) + monkeypatch.setattr(registry, "_robots_discovered", False) + monkeypatch.setattr(registry, "_robots_discovering", False) + monkeypatch.setattr(registry, "_robot_entry_points", None) + monkeypatch.setattr(registry, "_completed_robot_entry_points", 0) + monkeypatch.setattr(registry, "entry_points", lambda *, group: ()) + + +@pytest.fixture +def robot_type(tmp_path): + @configclass(kw_only=True) + class CustomRobotCfg(RobotCfg): + model: MjcfFileCfg = MjcfFileCfg(file=tmp_path / "robot.xml") + base_link_name: str = "base" + + def validate(self, path="robot"): + self.validated_path = path + + return CustomRobotCfg + + +@pytest.mark.parametrize("query", ["make", "list"]) +def test_plugins_are_lazy_sorted_and_discovered_once(monkeypatch, robot_type, query): + calls = [] + metadata_queries = [] + + def register_a(): + calls.append("a") + registry.register_robot_config("plugin-a", robot_type) + + def register_b(): + calls.append("b") + registry.register_robot_config("plugin-b", robot_type) + + a = FakeEntryPoint("a", "a:register", register_a) + b = FakeEntryPoint("b", "b:register", register_b) + + def entry_points(*, group): + metadata_queries.append(group) + return [b, a] + + monkeypatch.setattr(registry, "entry_points", entry_points) + registry.register_robot_config("manual", robot_type) + assert not metadata_queries + if query == "make": + registry.make_robot_config("plugin-a") + else: + registry.list_registered_robots() + first = registry.make_robot_config("plugin-a") + second = registry.make_robot_config("plugin-a") + assert first is not second + assert first.validated_path == "robot" + assert registry.list_registered_robots() == { + name: {"config_class": "CustomRobotCfg"} for name in ("manual", "plugin-a", "plugin-b") + } + assert metadata_queries == [registry.ROBOT_ENTRY_POINT_GROUP] + assert calls == ["a", "b"] + assert a.loads == b.loads == 1 + + +def test_no_plugins_supports_manual_registration_and_unknown_errors(robot_type): + assert registry.list_registered_robots() == {} + registry.register_robot_config("manual", robot_type) + assert isinstance(registry.make_robot_config("manual"), robot_type) + with pytest.raises(ValueError, match="already registered"): + registry.register_robot_config("manual", robot_type) + with pytest.raises(ValueError, match="not registered"): + registry.make_robot_config("unknown") + + +def test_discovered_factory_preserves_validation_and_return_type_checks(monkeypatch, robot_type): + class InvalidRobotCfg(robot_type): + def validate(self, path="robot"): + raise ValueError("invalid robot") + + def register(): + registry.register_robot_config("wrong-result", lambda: object(), cfg_type=robot_type) + registry.register_robot_config("invalid", InvalidRobotCfg) + + monkeypatch.setattr( + registry, "entry_points", lambda *, group: [FakeEntryPoint("custom", "custom:register", register)] + ) + with pytest.raises(TypeError, match="config factory must return CustomRobotCfg"): + registry.make_robot_config("wrong-result") + with pytest.raises(ValueError): + registry.make_robot_config("invalid") + + +@pytest.mark.parametrize("failure", ["load", "noncallable", "callback"]) +def test_plugin_errors_propagate_and_are_retried(monkeypatch, failure): + error = RuntimeError("plugin failed") + + def fail(): + raise error + + ep = FakeEntryPoint("broken", "broken:register", fail) + if failure == "load": + ep.load_error = error + elif failure == "noncallable": + ep.callback = object() + monkeypatch.setattr(registry, "entry_points", lambda *, group: [ep]) + for _ in range(2): + if failure == "noncallable": + with pytest.raises(TypeError, match="Robot entry point 'broken' must load a callable"): + registry.list_registered_robots() + else: + with pytest.raises(RuntimeError) as caught: + registry.list_registered_robots() + assert caught.value is error + assert not registry._robots_discovered + assert not registry._robots_discovering + assert ep.loads == 2 + + +def test_retry_does_not_repeat_completed_callbacks(monkeypatch, robot_type): + def register_first(): + registry.register_robot_config("first", robot_type) + + def fail(): + raise RuntimeError("try again") + + first = FakeEntryPoint("a", "a:register", register_first) + second = FakeEntryPoint("b", "b:register", fail) + monkeypatch.setattr(registry, "entry_points", lambda *, group: [first, second]) + with pytest.raises(RuntimeError, match="try again"): + registry.list_registered_robots() + second.callback = lambda: registry.register_robot_config("second", robot_type) + assert set(registry.list_registered_robots()) == {"first", "second"} + assert first.loads == 1 + assert second.loads == 2 + + +def test_failed_callback_registration_side_effects_are_not_rolled_back(monkeypatch, robot_type): + def fail_after_registering(): + registry.register_robot_config("partial", robot_type) + raise RuntimeError("partial registration") + + ep = FakeEntryPoint("partial", "partial:register", fail_after_registering) + monkeypatch.setattr(registry, "entry_points", lambda *, group: [ep]) + with pytest.raises(RuntimeError, match="partial registration"): + registry.list_registered_robots() + assert "partial" in registry._robots + # Plugins own recovery from partial registration; the registry is not transactional. + with pytest.raises(ValueError, match="already registered"): + registry.list_registered_robots() + + +def test_identical_entry_point_declarations_are_not_silently_skipped(monkeypatch, robot_type): + def register(): + registry.register_robot_config("duplicate", robot_type) + + first = FakeEntryPoint("same", "same:register", register) + second = FakeEntryPoint("same", "same:register", register) + monkeypatch.setattr(registry, "entry_points", lambda *, group: [first, second]) + with pytest.raises(ValueError, match="already registered"): + registry.list_registered_robots() + assert first.loads == second.loads == 1 + + +def test_registration_callback_can_reenter_queries(monkeypatch, robot_type): + calls = [] + + def register(): + calls.append("register") + assert registry.list_registered_robots() == {} + registry.register_robot_config("recursive", robot_type) + assert isinstance(registry.make_robot_config("recursive"), robot_type) + assert "recursive" in registry.list_registered_robots() + + ep = FakeEntryPoint("recursive", "recursive:register", register) + monkeypatch.setattr(registry, "entry_points", lambda *, group: [ep]) + assert "recursive" in registry.list_registered_robots() + assert calls == ["register"] + assert ep.loads == 1 diff --git a/motrix_envs/pyproject.toml b/motrix_envs/pyproject.toml index b26b0b51..2a75a2e4 100644 --- a/motrix_envs/pyproject.toml +++ b/motrix_envs/pyproject.toml @@ -14,6 +14,7 @@ dependencies = [ "gymnasium==1.1.1", "motrix-env-core[numba,video]", "motrix-env-motrixsim", + "motrix-robots", "numpy>=1.26", "omegaconf>=2.3,<2.4", ] diff --git a/motrix_envs/src/motrix_envs/__init__.py b/motrix_envs/src/motrix_envs/__init__.py index a8919bf2..3deeefd6 100644 --- a/motrix_envs/src/motrix_envs/__init__.py +++ b/motrix_envs/src/motrix_envs/__init__.py @@ -14,7 +14,7 @@ def register() -> None: return _registered = True try: - from motrix_envs import basic, locomotion, manipulation, robot # noqa: F401 + from motrix_envs import basic, locomotion, manipulation # noqa: F401 except Exception: _registered = False raise diff --git a/motrix_envs/src/motrix_envs/deploy/go2_walk.py b/motrix_envs/src/motrix_envs/deploy/go2_walk.py index cfafb4b3..f2733dd7 100644 --- a/motrix_envs/src/motrix_envs/deploy/go2_walk.py +++ b/motrix_envs/src/motrix_envs/deploy/go2_walk.py @@ -4,13 +4,13 @@ """Compile Go2 walking environments into their deployment artifact contract.""" import numpy as np +from motrix_robots.unitree import UnitreeGo2Robot from motrix_deploy.artifact import ControlSpec, TaskSpec from motrix_deploy.profile import DeploymentProfile, register_profile_compiler from motrix_env_core import registry from motrix_envs.deploy.robot import build_robot_model, build_robot_spec, read_position_servo_gains from motrix_envs.locomotion.quadruped.cfg import QuadrupedWalkEnvCfg -from motrix_envs.robot import UnitreeGo2Robot GO2_TASK_NAME = "go2_walk/v1" GO2_COMMAND_SCALES = { diff --git a/motrix_envs/src/motrix_envs/locomotion/anymal_c/cfg.py b/motrix_envs/src/motrix_envs/locomotion/anymal_c/cfg.py index 173e2371..d743c0b6 100644 --- a/motrix_envs/src/motrix_envs/locomotion/anymal_c/cfg.py +++ b/motrix_envs/src/motrix_envs/locomotion/anymal_c/cfg.py @@ -3,10 +3,12 @@ import os +from motrix_robots.anymal import AnymalC + from motrix_env_core import registry from motrix_env_core.base import SimCfg from motrix_env_core.config import configclass -from motrix_env_core.config.scene import SceneCfg +from motrix_env_core.config.scene import SceneCfg, SceneObjsCfg from motrix_env_core.direct.env import DirectEnvCfg model_file = os.path.dirname(__file__) + "/xmls/scene.xml" @@ -103,7 +105,7 @@ class AnymalCEnvCfg(DirectEnvCfg): zh_CN: 控制 ANYmal-C 在平地上朝目标位置导航。 """ - scene: SceneCfg = SceneCfg(file=model_file) + scene: SceneCfg = SceneCfg(file=model_file, objs=SceneObjsCfg(robot=AnymalC())) reset_noise_scale: float = 0.01 max_episode_seconds: float = 7.0 sim: SimCfg = SimCfg(dt=0.01) diff --git a/motrix_envs/src/motrix_envs/locomotion/anymal_c/xmls/scene.xml b/motrix_envs/src/motrix_envs/locomotion/anymal_c/xmls/scene.xml index 78be5ee1..19eec6c2 100644 --- a/motrix_envs/src/motrix_envs/locomotion/anymal_c/xmls/scene.xml +++ b/motrix_envs/src/motrix_envs/locomotion/anymal_c/xmls/scene.xml @@ -1,5 +1,4 @@ - diff --git a/motrix_envs/src/motrix_envs/locomotion/ball_balance/microduck.py b/motrix_envs/src/motrix_envs/locomotion/ball_balance/microduck.py index dc30618b..b218a87b 100644 --- a/motrix_envs/src/motrix_envs/locomotion/ball_balance/microduck.py +++ b/motrix_envs/src/motrix_envs/locomotion/ball_balance/microduck.py @@ -5,6 +5,7 @@ from pathlib import Path +from motrix_robots.microduck import Microduck from omegaconf import MISSING from motrix_env_core import registry @@ -80,7 +81,6 @@ UndesiredContactsRewardCfg, ) from motrix_envs.locomotion.wbt.mdp.terminations import BadDofPositionTerminationCfg -from motrix_envs.robot import Microduck _BALL_ASSET_DIR = Path(__file__).parent / "assets" _BALL_RADIUS = 0.14 diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/cfg.py b/motrix_envs/src/motrix_envs/locomotion/go1/cfg.py index 2851f575..78049113 100644 --- a/motrix_envs/src/motrix_envs/locomotion/go1/cfg.py +++ b/motrix_envs/src/motrix_envs/locomotion/go1/cfg.py @@ -1,12 +1,14 @@ # Copyright Motphys Technology Co., Ltd. 2025, 2026 # SPDX-License-Identifier: Apache-2.0 -import os +from pathlib import Path + +from motrix_robots.unitree import UNITREE_GO1_ASSET_DIR, UnitreeGo1Robot from motrix_env_core import registry from motrix_env_core.base import SimCfg from motrix_env_core.config import configclass -from motrix_env_core.config.scene import SceneCfg +from motrix_env_core.config.scene import MjcfFileCfg, SceneCfg, SceneObjsCfg from motrix_env_core.direct.env import DirectEnvCfg @@ -135,7 +137,12 @@ class Go1WalkDirectStairsEnvCfg(Go1TerrainWalkDirectEnvCfg): """ render_spacing: float = 0.0 - scene: SceneCfg = SceneCfg(file=os.path.dirname(__file__) + "/xmls/scene_stairs_terrain.xml") + scene: SceneCfg = SceneCfg( + file=Path(__file__).parent / "xmls" / "scene_stairs_terrain.xml", + objs=SceneObjsCfg( + robot=UnitreeGo1Robot(model=MjcfFileCfg(file=UNITREE_GO1_ASSET_DIR / "go1_motor_actuator.xml")) + ), + ) # Pinned to the scene's geom inventory (single hfield "floor"): the legacy # env matched ground/foot geoms by substring over exactly these names. # Foot contact-force sensors follow Sensor.feet order. diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/materials.xml b/motrix_envs/src/motrix_envs/locomotion/go1/xmls/materials.xml index 426352f7..f4f86e47 100644 --- a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/materials.xml +++ b/motrix_envs/src/motrix_envs/locomotion/go1/xmls/materials.xml @@ -4,4 +4,4 @@ - \ No newline at end of file + diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/scene_rough_terrain.xml b/motrix_envs/src/motrix_envs/locomotion/go1/xmls/scene_rough_terrain.xml index 3891ee6a..63e6ec96 100644 --- a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/scene_rough_terrain.xml +++ b/motrix_envs/src/motrix_envs/locomotion/go1/xmls/scene_rough_terrain.xml @@ -1,5 +1,4 @@ - @@ -24,4 +23,4 @@ - \ No newline at end of file + diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/scene_stairs_terrain.xml b/motrix_envs/src/motrix_envs/locomotion/go1/xmls/scene_stairs_terrain.xml index fe97800f..3912409d 100644 --- a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/scene_stairs_terrain.xml +++ b/motrix_envs/src/motrix_envs/locomotion/go1/xmls/scene_stairs_terrain.xml @@ -1,6 +1,8 @@ - + @@ -29,4 +31,4 @@ - \ No newline at end of file + diff --git a/motrix_envs/src/motrix_envs/locomotion/humanoid/cfg.py b/motrix_envs/src/motrix_envs/locomotion/humanoid/cfg.py index 542cad2c..95ec53bc 100644 --- a/motrix_envs/src/motrix_envs/locomotion/humanoid/cfg.py +++ b/motrix_envs/src/motrix_envs/locomotion/humanoid/cfg.py @@ -12,6 +12,8 @@ data those terms consume. No environment subclass is needed. """ +from motrix_robots.humanoid import HumanoidRobotCfg + from motrix_env_core.base import SimCfg from motrix_env_core.config import configclass from motrix_env_core.config.scene import ( @@ -71,7 +73,6 @@ PenaltyOrientationRewardCfg, PoseRewardCfg, ) -from motrix_envs.robot import HumanoidRobotCfg @configclass diff --git a/motrix_envs/src/motrix_envs/locomotion/humanoid/dex_evt.py b/motrix_envs/src/motrix_envs/locomotion/humanoid/dex_evt.py index 5470921e..fad7bd4b 100644 --- a/motrix_envs/src/motrix_envs/locomotion/humanoid/dex_evt.py +++ b/motrix_envs/src/motrix_envs/locomotion/humanoid/dex_evt.py @@ -5,6 +5,8 @@ from dataclasses import replace +from motrix_robots.dex_evt import DexEvt + from motrix_env_core import registry from motrix_env_core.base import SimCfg from motrix_env_core.config.scene import FlatTerrainCfg, HFieldTerrainCfg @@ -26,7 +28,6 @@ PenaltyCloseFeetXyRewardCfg, PoseRewardCfg, ) -from motrix_envs.robot import DexEvt # Pinned Dex-EVT termination collision inventory, owned by the Dex-EVT walk task. _DEX_EVT_TERMINATION_GEOMS = ( diff --git a/motrix_envs/src/motrix_envs/locomotion/humanoid/g1.py b/motrix_envs/src/motrix_envs/locomotion/humanoid/g1.py index 7bdbc5b1..7b656d52 100644 --- a/motrix_envs/src/motrix_envs/locomotion/humanoid/g1.py +++ b/motrix_envs/src/motrix_envs/locomotion/humanoid/g1.py @@ -5,6 +5,8 @@ from dataclasses import replace +from motrix_robots.unitree import UnitreeG129Dof + from motrix_env_core import registry from motrix_env_core.base import SimCfg from motrix_env_core.config.scene import HFieldTerrainCfg, SystemCameraCfg @@ -29,7 +31,6 @@ PenaltyCloseFeetXyRewardCfg, PoseRewardCfg, ) -from motrix_envs.robot import UnitreeG129Dof # Pinned G1 termination collision inventory, owned by the G1 walk task. _G1_TERMINATION_GEOMS = ( diff --git a/motrix_envs/src/motrix_envs/locomotion/humanoid/k1.py b/motrix_envs/src/motrix_envs/locomotion/humanoid/k1.py index f4adca6d..f32d1141 100644 --- a/motrix_envs/src/motrix_envs/locomotion/humanoid/k1.py +++ b/motrix_envs/src/motrix_envs/locomotion/humanoid/k1.py @@ -5,6 +5,8 @@ from dataclasses import replace +from motrix_robots.booster import BoosterK1 + from motrix_env_core import registry from motrix_env_core.base import SimCfg from motrix_env_core.config.scene import HFieldTerrainCfg @@ -26,7 +28,6 @@ PenaltyCloseFeetXyRewardCfg, PoseRewardCfg, ) -from motrix_envs.robot import BoosterK1 def _make_k1_robot() -> BoosterK1: diff --git a/motrix_envs/src/motrix_envs/locomotion/humanoid/microduck.py b/motrix_envs/src/motrix_envs/locomotion/humanoid/microduck.py index 606c7702..b6ee8d88 100644 --- a/motrix_envs/src/motrix_envs/locomotion/humanoid/microduck.py +++ b/motrix_envs/src/motrix_envs/locomotion/humanoid/microduck.py @@ -5,6 +5,8 @@ from dataclasses import replace +from motrix_robots.microduck import Microduck + from motrix_env_core import registry from motrix_env_core.base import SimCfg from motrix_env_core.config.scene import HFieldTerrainCfg, SystemCameraCfg @@ -28,7 +30,6 @@ PenaltyCloseFeetXyRewardCfg, PoseRewardCfg, ) -from motrix_envs.robot import Microduck def _make_microduck_robot() -> Microduck: diff --git a/motrix_envs/src/motrix_envs/locomotion/quadruped/anymalc.py b/motrix_envs/src/motrix_envs/locomotion/quadruped/anymalc.py index f74ec16e..69736c47 100644 --- a/motrix_envs/src/motrix_envs/locomotion/quadruped/anymalc.py +++ b/motrix_envs/src/motrix_envs/locomotion/quadruped/anymalc.py @@ -9,6 +9,8 @@ into the robot file. """ +from motrix_robots.anymal import AnymalC + from motrix_env_core import registry from motrix_env_core.config import configclass from motrix_env_core.config.scene import ( @@ -30,7 +32,6 @@ Sensor, ) from motrix_envs.locomotion.quadruped.walk_np import QuadrupedWalkTask -from motrix_envs.robot import AnymalC @configclass diff --git a/motrix_envs/src/motrix_envs/locomotion/quadruped/cfg.py b/motrix_envs/src/motrix_envs/locomotion/quadruped/cfg.py index 69957406..aff1ee44 100644 --- a/motrix_envs/src/motrix_envs/locomotion/quadruped/cfg.py +++ b/motrix_envs/src/motrix_envs/locomotion/quadruped/cfg.py @@ -6,6 +6,7 @@ from dataclasses import replace import numpy as np +from motrix_robots.quadruped import QuadrupedRobotCfg from numpy.typing import NDArray from omegaconf import MISSING @@ -20,7 +21,6 @@ ) from motrix_env_core.direct.env import DirectEnvCfg from motrix_envs.config.scene import StandardSceneAssetsCfg, StandardSceneCfg -from motrix_envs.robot import QuadrupedRobotCfg def _contact_sensor(geom_name: str | None) -> ContactSensorCfg: diff --git a/motrix_envs/src/motrix_envs/locomotion/quadruped/go1.py b/motrix_envs/src/motrix_envs/locomotion/quadruped/go1.py index 16df4c51..c41e9845 100644 --- a/motrix_envs/src/motrix_envs/locomotion/quadruped/go1.py +++ b/motrix_envs/src/motrix_envs/locomotion/quadruped/go1.py @@ -3,6 +3,8 @@ """Go1 flat- and rough-terrain walk configuration and environment registration.""" +from motrix_robots.unitree import UnitreeGo1Robot + from motrix_env_core import registry from motrix_env_core.config import configclass from motrix_env_core.config.scene import FlatTerrainCfg, HFieldTerrainCfg @@ -16,7 +18,6 @@ RewardScales, ) from motrix_envs.locomotion.quadruped.walk_np import QuadrupedWalkTask -from motrix_envs.robot import UnitreeGo1Robot @registry.envcfg("go1-walk-flat") diff --git a/motrix_envs/src/motrix_envs/locomotion/quadruped/go2.py b/motrix_envs/src/motrix_envs/locomotion/quadruped/go2.py index 6f6d23ab..0d5c3ad4 100644 --- a/motrix_envs/src/motrix_envs/locomotion/quadruped/go2.py +++ b/motrix_envs/src/motrix_envs/locomotion/quadruped/go2.py @@ -6,6 +6,7 @@ from dataclasses import replace import numpy as np +from motrix_robots.unitree import UnitreeGo2Robot from motrix_env_core import registry from motrix_env_core.config import configclass @@ -22,7 +23,6 @@ VelocityCommandCfg, ) from motrix_envs.locomotion.quadruped.walk_np import QuadrupedWalkTask -from motrix_envs.robot import UnitreeGo2Robot @registry.envcfg("go2-walk-flat") diff --git a/motrix_envs/src/motrix_envs/locomotion/quadruped/walk_np.py b/motrix_envs/src/motrix_envs/locomotion/quadruped/walk_np.py index 45d05236..31c4dcbf 100644 --- a/motrix_envs/src/motrix_envs/locomotion/quadruped/walk_np.py +++ b/motrix_envs/src/motrix_envs/locomotion/quadruped/walk_np.py @@ -5,6 +5,7 @@ import gymnasium as gym import numpy as np +from motrix_robots.quadruped import QuadrupedRobotCfg from motrix_env_core.array.env import ArrayEnvState, NpObs from motrix_env_core.base import ObsSpace @@ -40,7 +41,6 @@ ) from motrix_envs.locomotion.quadruped.cfg import QuadrupedWalkEnvCfg from motrix_envs.locomotion.quadruped.velocity_command import RandomPlanarVelocityBinding -from motrix_envs.robot import QuadrupedRobotCfg def _sim_data_queries(cfg: QuadrupedWalkEnvCfg): diff --git a/motrix_envs/src/motrix_envs/locomotion/wbt/dex_evt.py b/motrix_envs/src/motrix_envs/locomotion/wbt/dex_evt.py index 08c470dc..1102f9ca 100644 --- a/motrix_envs/src/motrix_envs/locomotion/wbt/dex_evt.py +++ b/motrix_envs/src/motrix_envs/locomotion/wbt/dex_evt.py @@ -6,6 +6,8 @@ from dataclasses import InitVar from pathlib import Path +from motrix_robots.dex_evt import DexEvt + from motrix_env_core import registry from motrix_env_core.base import EnvCfg, SimCfg from motrix_env_core.config import configclass @@ -27,7 +29,6 @@ from motrix_envs.locomotion.wbt.mdp.terminations import ( BadBodyZTerminationCfg, ) -from motrix_envs.robot import DexEvt _MOTION_DIR = Path(__file__).parent / "assets" / "motion" / "dex_evt" _DEX_EVT_TRACKED_BODY_NAMES = ( diff --git a/motrix_envs/src/motrix_envs/locomotion/wbt/g1/backflip.py b/motrix_envs/src/motrix_envs/locomotion/wbt/g1/backflip.py index 3bfe7e66..873dd94a 100644 --- a/motrix_envs/src/motrix_envs/locomotion/wbt/g1/backflip.py +++ b/motrix_envs/src/motrix_envs/locomotion/wbt/g1/backflip.py @@ -3,6 +3,8 @@ """G1 backflip tracking task.""" +from motrix_robots.unitree import UnitreeG129Dof + from motrix_env_core import registry from motrix_env_core.base import EnvCfg, SimCfg from motrix_env_core.config import configclass @@ -25,7 +27,6 @@ BadRefOrientationTerminationCfg, BadRefZTerminationCfg, ) -from motrix_envs.robot import UnitreeG129Dof from .common import MOTION_DIR, G1WbtEnvCfg diff --git a/motrix_envs/src/motrix_envs/locomotion/wbt/g1/common.py b/motrix_envs/src/motrix_envs/locomotion/wbt/g1/common.py index c07d56fe..662df59c 100644 --- a/motrix_envs/src/motrix_envs/locomotion/wbt/g1/common.py +++ b/motrix_envs/src/motrix_envs/locomotion/wbt/g1/common.py @@ -6,6 +6,8 @@ from dataclasses import InitVar from pathlib import Path +from motrix_robots.unitree import UnitreeG129Dof + from motrix_env_core.base import SimCfg from motrix_env_core.config import configclass from motrix_env_core.config.scene import SystemCameraCfg @@ -15,7 +17,6 @@ from motrix_envs.locomotion.wbt.cfg import CommandsCfg, RewardsCfg, TerminationsCfg, WbtEnvCfg from motrix_envs.locomotion.wbt.mdp.command import WbtMotionCommandCfg from motrix_envs.locomotion.wbt.mdp.terminations import BadBodyZTerminationCfg -from motrix_envs.robot import UnitreeG129Dof MOTION_DIR = Path(__file__).resolve().parent.parent / "assets" / "motion" / "g1" G1_TRACKED_BODY_NAMES = ( diff --git a/motrix_envs/src/motrix_envs/locomotion/wbt/k1.py b/motrix_envs/src/motrix_envs/locomotion/wbt/k1.py index 26b7ea44..fe6cfbca 100644 --- a/motrix_envs/src/motrix_envs/locomotion/wbt/k1.py +++ b/motrix_envs/src/motrix_envs/locomotion/wbt/k1.py @@ -6,6 +6,8 @@ from dataclasses import InitVar from pathlib import Path +from motrix_robots.booster import BoosterK1 + from motrix_env_core import registry from motrix_env_core.base import EnvCfg, SimCfg from motrix_env_core.config import configclass @@ -24,7 +26,6 @@ from motrix_envs.locomotion.wbt.mdp.terminations import ( BadBodyZTerminationCfg, ) -from motrix_envs.robot import BoosterK1 _MOTION_DIR = Path(__file__).parent / "assets" / "motion" / "k1" _K1_TRACKED_BODY_NAMES = ( diff --git a/motrix_envs/src/motrix_envs/motion/converters/lafan_converter.py b/motrix_envs/src/motrix_envs/motion/converters/lafan_converter.py index 29b219e6..45aafdcf 100644 --- a/motrix_envs/src/motrix_envs/motion/converters/lafan_converter.py +++ b/motrix_envs/src/motrix_envs/motion/converters/lafan_converter.py @@ -32,10 +32,10 @@ import motrixsim as mtx import numpy as np +from motrix_robots.unitree import UNITREE_G1_ASSET_DIR from motrix_env_core.math import quaternion from motrix_envs.motion.schema import SCHEMA_VERSION -from motrix_envs.robot.unitree import UNITREE_G1_ASSET_DIR # G1 joint order as stored in the CSV columns (dataset meta_data/info.json). G1_CSV_JOINT_ORDER = ( @@ -76,10 +76,10 @@ def _default_model_file(robot: str) -> Path: - """Locate the MotrixSim scene xml shipped with the requested robot package.""" + """Locate the robot-only MJCF used for forward kinematics.""" if robot != "g1": raise ValueError(f"LAFAN converter only supports robot 'g1', got {robot!r}") - return UNITREE_G1_ASSET_DIR / "scene_g1_29dof.xml" + return UNITREE_G1_ASSET_DIR / "g1_29dof.xml" def _normalize(q: np.ndarray) -> np.ndarray: diff --git a/motrix_envs/src/motrix_envs/robot/__init__.py b/motrix_envs/src/motrix_envs/robot/__init__.py deleted file mode 100644 index 6419b86d..00000000 --- a/motrix_envs/src/motrix_envs/robot/__init__.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright Motphys Technology Co., Ltd. 2025, 2026 -# SPDX-License-Identifier: Apache-2.0 - -from motrix_env_core import registry -from motrix_envs.robot.anymal import AnymalC -from motrix_envs.robot.booster import BoosterK1 -from motrix_envs.robot.dex_evt import DexEvt -from motrix_envs.robot.humanoid import HumanoidRobotCfg -from motrix_envs.robot.microduck import Microduck -from motrix_envs.robot.quadruped import QuadrupedLegCfg, QuadrupedLegsCfg, QuadrupedRobotCfg -from motrix_envs.robot.unitree import ( - UnitreeG129Dof, - UnitreeGo1Robot, - UnitreeGo2Robot, -) - -registry.robotcfg("anymal_c")(AnymalC) -registry.robotcfg("dex-evt")(DexEvt) -registry.robotcfg("g1-29dof")(UnitreeG129Dof) -registry.robotcfg("go1")(UnitreeGo1Robot) -registry.robotcfg("go2")(UnitreeGo2Robot) -registry.robotcfg("k1")(BoosterK1) -registry.robotcfg("microduck")(Microduck) - -__all__ = [ - "AnymalC", - "BoosterK1", - "DexEvt", - "HumanoidRobotCfg", - "Microduck", - "QuadrupedLegCfg", - "QuadrupedLegsCfg", - "QuadrupedRobotCfg", - "UnitreeG129Dof", - "UnitreeGo1Robot", - "UnitreeGo2Robot", -] diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/scene_dex_evt.xml b/motrix_envs/src/motrix_envs/robot/assets/dex_evt/scene_dex_evt.xml deleted file mode 100644 index 7c03b2d0..00000000 --- a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/scene_dex_evt.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - \ No newline at end of file diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/scene_g1_29dof.xml b/motrix_envs/src/motrix_envs/robot/assets/g1/scene_g1_29dof.xml deleted file mode 100644 index d44a4db1..00000000 --- a/motrix_envs/src/motrix_envs/robot/assets/g1/scene_g1_29dof.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - \ No newline at end of file diff --git a/motrix_envs/tests/test_deploy_profile.py b/motrix_envs/tests/test_deploy_profile.py index 50621c28..0470ef9d 100644 --- a/motrix_envs/tests/test_deploy_profile.py +++ b/motrix_envs/tests/test_deploy_profile.py @@ -7,6 +7,7 @@ import numpy as np import pytest +from motrix_robots.unitree import UnitreeGo2Robot from motrix_env_core import registry from motrix_envs.deploy import build_deployment_profile, registered_profile_compilers @@ -15,7 +16,6 @@ build_robot_spec, resolve_joint_actuators_in_canonical_order, ) -from motrix_envs.robot import UnitreeGo2Robot @dataclass diff --git a/motrix_envs/tests/test_lafan_converter.py b/motrix_envs/tests/test_lafan_converter.py index a45a9339..811cf408 100644 --- a/motrix_envs/tests/test_lafan_converter.py +++ b/motrix_envs/tests/test_lafan_converter.py @@ -3,14 +3,14 @@ import motrixsim as mtx import numpy as np +from motrix_robots.unitree import UNITREE_G1_ASSET_DIR from motrix_envs.motion import MotrixMotion from motrix_envs.motion.converters.lafan_converter import G1_CSV_JOINT_ORDER, convert_lafan -from motrix_envs.robot.unitree import UNITREE_G1_ASSET_DIR # G1 pelvis rest height (~0.79 m); keeps the synthetic root above ground. _ROOT_Z = 0.793 -_G1_MODEL_FILE = UNITREE_G1_ASSET_DIR / "scene_g1_29dof.xml" +_G1_MODEL_FILE = UNITREE_G1_ASSET_DIR / "g1_29dof.xml" def _write_synthetic_csv(path, num_frames=12): diff --git a/motrix_envs/tests/test_robot_cfg.py b/motrix_envs/tests/test_robot_cfg.py index 64d7d99d..2cb75c9b 100644 --- a/motrix_envs/tests/test_robot_cfg.py +++ b/motrix_envs/tests/test_robot_cfg.py @@ -7,6 +7,20 @@ import motrixsim as mtx import pytest +from motrix_robots.anymal import ANYMAL_C_ASSET_DIR, AnymalC +from motrix_robots.booster import BOOSTER_K1_ASSET_DIR, BoosterK1 +from motrix_robots.dex_evt import DEX_EVT_ASSET_DIR, DexEvt +from motrix_robots.humanoid import HumanoidRobotCfg +from motrix_robots.microduck import MICRODUCK_ASSET_DIR, Microduck +from motrix_robots.quadruped import QuadrupedLegCfg, QuadrupedRobotCfg +from motrix_robots.unitree import ( + UNITREE_G1_ASSET_DIR, + UNITREE_GO1_ASSET_DIR, + UNITREE_GO2_ASSET_DIR, + UnitreeG129Dof, + UnitreeGo1Robot, + UnitreeGo2Robot, +) from motrix_env_core import registry from motrix_env_core.config import configclass @@ -22,23 +36,6 @@ from motrix_env_motrixsim.compiler import build_scene_model from motrix_envs.config.scene import StandardSceneObjsCfg from motrix_envs.locomotion.quadruped.cfg import QuadrupedSceneCfg -from motrix_envs.robot import ( - AnymalC, - BoosterK1, - DexEvt, - HumanoidRobotCfg, - Microduck, - QuadrupedLegCfg, - QuadrupedRobotCfg, - UnitreeG129Dof, - UnitreeGo1Robot, - UnitreeGo2Robot, -) -from motrix_envs.robot.anymal import ANYMAL_C_ASSET_DIR -from motrix_envs.robot.booster import BOOSTER_K1_ASSET_DIR -from motrix_envs.robot.dex_evt import DEX_EVT_ASSET_DIR -from motrix_envs.robot.microduck import MICRODUCK_ASSET_DIR -from motrix_envs.robot.unitree import UNITREE_G1_ASSET_DIR, UNITREE_GO1_ASSET_DIR, UNITREE_GO2_ASSET_DIR @configclass diff --git a/motrix_robots/README.md b/motrix_robots/README.md new file mode 100644 index 00000000..30edb7a6 --- /dev/null +++ b/motrix_robots/README.md @@ -0,0 +1,79 @@ +# Motrix Robot Models + +`motrix-robots` provides reusable robot configurations, default poses, and model +assets for simulation. + +## Simulation configuration + +```python +from motrix_robots import Microduck, UnitreeGo2Robot +from motrix_env_core.config.scene.base import RobotCfg + +microduck = Microduck() +robot = UnitreeGo2Robot(prefix="robot_") +robot.validate("robot") +assert isinstance(robot, RobotCfg) +assert robot.resolved_base_link_name == "robot_base" +``` + +Use `key_pose` for named joint poses and `init_key_pose` to select the initial pose. +Resolve prefixed model names with `robot.resolve_name(name)`. Tasks supply the scene +and choose their sensors. + +## Selecting built-in models by ID + +Installed robot packages are discovered automatically. Select a built-in model +by its registered ID: + +```python +from motrix_env_core.registry import make_robot_config + +robot = make_robot_config("go2") +``` + +The IDs are `anymal_c`, `g1-29dof`, `go1`, `go2`, `k1`, `dex-evt`, and `microduck`. + +## Programmatic actuator overrides + +`BodyCfg` (and therefore `RobotCfg`) owns format-neutral `actuators` for both MJCF +and URDF models. `None` preserves imported actuators; a dictionary replaces the +entire model instance's actuator set; `{}` removes all of them. Keys supply actuator +names, so `ActuatorCfg` does not duplicate a `name` field. Override joint names are +model-local, before prefix/suffix decoration. Other instances and source asset +files are not modified. + +```python +from motrix_env_core.config.scene.actuator import MotorActuatorCfg + +robot = UnitreeGo2Robot( + actuators={ + "FL_hip_motor": MotorActuatorCfg(joint_name="FL_hip_joint", force_range=(-20.0, 20.0)), + # Declare the other controlled joints here: this replaces, not appends. + }, +) +``` + +`MotorActuatorCfg` declares unit-transmission direct effort. `PositionActuatorCfg` +declares a native position servo using `kp`, absolute damping `kv`, and optional +control/force ranges. Actuator order follows dictionary insertion order. +Replacement resets keyframe actuator controls/activations while retaining joint +poses and velocities. Dex-EVT declares its drives on the robot instance. + +## Model modules and assets + +Import these model classes and helpers directly from `motrix_robots`: + +| Defining module | Public configuration classes | +| --- | --- | +| `motrix_robots.unitree` | `UnitreeG129Dof`, `UnitreeGo1Robot`, `UnitreeGo2Robot` | +| `motrix_robots.anymal` | `AnymalC` | +| `motrix_robots.booster` | `BoosterK1` | +| `motrix_robots.dex_evt` | `DexEvt` | +| `motrix_robots.microduck` | `Microduck` | +| `motrix_robots.quadruped` | `QuadrupedLegCfg`, `QuadrupedLegsCfg`, `QuadrupedRobotCfg` | +| `motrix_robots.humanoid` | `HumanoidRobotCfg` | + +Bundled model descriptions, meshes, and model textures are under `src/motrix_robots/assets/`. +Task scenes, ground textures, and terrain assets belong to `motrix_envs`. Asset licenses and attribution +remain with their asset directories; see the root `THIRD_PARTY_NOTICES.md` for the +release inventory. diff --git a/motrix_robots/pyproject.toml b/motrix_robots/pyproject.toml new file mode 100644 index 00000000..75e76db4 --- /dev/null +++ b/motrix_robots/pyproject.toml @@ -0,0 +1,19 @@ +[build-system] +requires = ["uv_build>=0.11.23,<0.12"] +build-backend = "uv_build" + +[project] +name = "motrix-robots" +version = "0.4.0b0" +description = "Simulation robot configurations and model assets for MotrixLab." +authors = [{ name = "Motphys", email = "developers@motphys.com" }] +requires-python = "==3.10.*" +readme = "README.md" +license = "Apache-2.0" +dependencies = ["motrix-env-core"] + +[project.entry-points."motrix_env_core.robots"] +builtin = "motrix_robots.registration:register" + +[tool.uv.build-backend] +module-name = "motrix_robots" diff --git a/motrix_robots/src/motrix_robots/__init__.py b/motrix_robots/src/motrix_robots/__init__.py new file mode 100644 index 00000000..42eb5143 --- /dev/null +++ b/motrix_robots/src/motrix_robots/__init__.py @@ -0,0 +1,31 @@ +# Copyright Motphys Technology Co., Ltd. 2025, 2026 +# SPDX-License-Identifier: Apache-2.0 + +"""Public simulation robot configuration types and model-owned assets. + +Import model types from this public API or their defining leaf modules. +The core registry discovers builtin model IDs lazily through the installed +robot plugin entry point. Scene placement remains application-owned. +""" + +from motrix_robots.anymal import AnymalC +from motrix_robots.booster import BoosterK1 +from motrix_robots.dex_evt import DexEvt +from motrix_robots.humanoid import HumanoidRobotCfg +from motrix_robots.microduck import Microduck +from motrix_robots.quadruped import QuadrupedLegCfg, QuadrupedLegsCfg, QuadrupedRobotCfg +from motrix_robots.unitree import UnitreeG129Dof, UnitreeGo1Robot, UnitreeGo2Robot + +__all__ = [ + "AnymalC", + "BoosterK1", + "DexEvt", + "HumanoidRobotCfg", + "Microduck", + "QuadrupedLegCfg", + "QuadrupedLegsCfg", + "QuadrupedRobotCfg", + "UnitreeG129Dof", + "UnitreeGo1Robot", + "UnitreeGo2Robot", +] diff --git a/motrix_envs/src/motrix_envs/robot/anymal.py b/motrix_robots/src/motrix_robots/anymal.py similarity index 93% rename from motrix_envs/src/motrix_envs/robot/anymal.py rename to motrix_robots/src/motrix_robots/anymal.py index 62475880..b6534e0d 100644 --- a/motrix_envs/src/motrix_envs/robot/anymal.py +++ b/motrix_robots/src/motrix_robots/anymal.py @@ -5,7 +5,7 @@ from motrix_env_core.config import configclass from motrix_env_core.config.scene import KeyPoseCfg, MjcfFileCfg -from motrix_envs.robot.quadruped import QuadrupedLegCfg, QuadrupedLegsCfg, QuadrupedRobotCfg +from motrix_robots.quadruped import QuadrupedLegCfg, QuadrupedLegsCfg, QuadrupedRobotCfg ANYMAL_C_ASSET_DIR = Path(__file__).parent / "assets" / "anymal_c" _ANYMAL_C_MJCF = ANYMAL_C_ASSET_DIR / "anymal_c.xml" diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/anymal_c.xml b/motrix_robots/src/motrix_robots/assets/anymal_c/anymal_c.xml similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/anymal_c.xml rename to motrix_robots/src/motrix_robots/assets/anymal_c/anymal_c.xml diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/base.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/base.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_0.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_0.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_0.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_0.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_1.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_1.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_1.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_1.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_2.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_2.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_2.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_2.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_3.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_3.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_3.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_3.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_4.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_4.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_4.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_4.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_5.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_5.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/base_5.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/base_5.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/battery.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/battery.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/battery.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/battery.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/battery.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/battery.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/battery.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/battery.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/bottom_shell.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/bottom_shell.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/bottom_shell.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/bottom_shell.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/bottom_shell.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/bottom_shell.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/bottom_shell.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/bottom_shell.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/depth_camera.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/depth_camera.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/depth_camera.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/depth_camera.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/depth_camera.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/depth_camera.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/depth_camera.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/depth_camera.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/drive.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/drive.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/drive.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/drive.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/drive.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/drive.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/drive.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/drive.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/face.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/face.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/face.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/face.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/face.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/face.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/face.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/face.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/foot.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/foot.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/foot.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/foot.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/foot.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/foot.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/foot.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/foot.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/handle.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/handle.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/handle.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/handle.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/handle.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/handle.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/handle.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/handle.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hatch.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/hatch.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hatch.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/hatch.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hatch.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/hatch.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hatch.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/hatch.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hip_l.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/hip_l.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hip_l.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/hip_l.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hip_l.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/hip_l.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hip_l.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/hip_l.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hip_r.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/hip_r.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hip_r.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/hip_r.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hip_r.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/hip_r.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/hip_r.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/hip_r.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/lidar.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/lidar.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/lidar.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/lidar.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/lidar.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/lidar.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/lidar.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/lidar.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/lidar_cage.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/lidar_cage.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/lidar_cage.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/lidar_cage.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/lidar_cage.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/lidar_cage.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/lidar_cage.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/lidar_cage.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/remote.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/remote.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/remote.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/remote.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/remote.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/remote.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/remote.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/remote.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/shank_l.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/shank_l.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/shank_l.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/shank_l.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/shank_l.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/shank_l.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/shank_l.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/shank_l.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/shank_r.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/shank_r.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/shank_r.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/shank_r.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/shank_r.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/shank_r.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/shank_r.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/shank_r.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/thigh.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/thigh.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/thigh.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/thigh.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/thigh.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/thigh.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/thigh.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/thigh.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/top_shell.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/top_shell.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/top_shell.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/top_shell.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/top_shell.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/top_shell.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/top_shell.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/top_shell.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/wide_angle_camera.obj b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/wide_angle_camera.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/wide_angle_camera.obj rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/wide_angle_camera.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/wide_angle_camera.png b/motrix_robots/src/motrix_robots/assets/anymal_c/assets/wide_angle_camera.png similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/anymal_c/assets/wide_angle_camera.png rename to motrix_robots/src/motrix_robots/assets/anymal_c/assets/wide_angle_camera.png diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/dex_evt.urdf b/motrix_robots/src/motrix_robots/assets/dex_evt/dex_evt.urdf similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/dex_evt.urdf rename to motrix_robots/src/motrix_robots/assets/dex_evt/dex_evt.urdf diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/dex_evt.xml b/motrix_robots/src/motrix_robots/assets/dex_evt/dex_evt.xml similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/dex_evt.xml rename to motrix_robots/src/motrix_robots/assets/dex_evt/dex_evt.xml diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/ankle_pitch_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/ankle_pitch_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/ankle_pitch_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/ankle_pitch_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/ankle_pitch_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/ankle_pitch_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/ankle_pitch_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/ankle_pitch_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/ankle_roll_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/ankle_roll_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/ankle_roll_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/ankle_roll_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/ankle_roll_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/ankle_roll_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/ankle_roll_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/ankle_roll_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/camera_body_front_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/camera_body_front_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/camera_body_front_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/camera_body_front_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/camera_head_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/camera_head_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/camera_head_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/camera_head_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/elbow_pitch_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/elbow_pitch_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/elbow_pitch_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/elbow_pitch_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/elbow_pitch_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/elbow_pitch_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/elbow_pitch_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/elbow_pitch_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/elbow_yaw_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/elbow_yaw_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/elbow_yaw_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/elbow_yaw_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/elbow_yaw_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/elbow_yaw_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/elbow_yaw_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/elbow_yaw_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/head_pitch_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/head_pitch_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/head_pitch_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/head_pitch_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/head_yaw_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/head_yaw_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/head_yaw_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/head_yaw_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_pitch_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_pitch_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_pitch_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_pitch_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_pitch_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_pitch_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_pitch_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_pitch_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_roll_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_roll_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_roll_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_roll_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_roll_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_roll_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_roll_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_roll_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_yaw_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_yaw_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_yaw_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_yaw_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_yaw_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_yaw_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/hip_yaw_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/hip_yaw_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/imu_head_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/imu_head_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/imu_head_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/imu_head_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/imu_waist_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/imu_waist_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/imu_waist_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/imu_waist_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/knee_pitch_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/knee_pitch_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/knee_pitch_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/knee_pitch_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/knee_pitch_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/knee_pitch_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/knee_pitch_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/knee_pitch_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/left_tcp_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/left_tcp_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/left_tcp_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/left_tcp_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/pelvis.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/pelvis.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/pelvis.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/pelvis.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/radar_head_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/radar_head_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/radar_head_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/radar_head_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/right_tcp_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/right_tcp_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/right_tcp_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/right_tcp_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_pitch_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_pitch_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_pitch_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_pitch_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_pitch_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_pitch_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_pitch_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_pitch_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_roll_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_roll_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_roll_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_roll_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_roll_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_roll_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_roll_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_roll_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_yaw_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_yaw_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_yaw_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_yaw_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_yaw_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_yaw_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/shoulder_yaw_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/shoulder_yaw_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/waist_pitch_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/waist_pitch_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/waist_pitch_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/waist_pitch_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/waist_roll_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/waist_roll_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/waist_roll_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/waist_roll_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/waist_yaw_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/waist_yaw_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/waist_yaw_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/waist_yaw_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/wrist_pitch_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/wrist_pitch_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/wrist_pitch_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/wrist_pitch_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/wrist_pitch_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/wrist_pitch_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/wrist_pitch_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/wrist_pitch_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/wrist_roll_l_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/wrist_roll_l_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/wrist_roll_l_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/wrist_roll_l_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/wrist_roll_r_link.STL b/motrix_robots/src/motrix_robots/assets/dex_evt/meshes/wrist_roll_r_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/dex_evt/meshes/wrist_roll_r_link.STL rename to motrix_robots/src/motrix_robots/assets/dex_evt/meshes/wrist_roll_r_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/g1_29dof.xml b/motrix_robots/src/motrix_robots/assets/g1/g1_29dof.xml similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/g1_29dof.xml rename to motrix_robots/src/motrix_robots/assets/g1/g1_29dof.xml diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/half_sphere.obj b/motrix_robots/src/motrix_robots/assets/g1/meshes/half_sphere.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/half_sphere.obj rename to motrix_robots/src/motrix_robots/assets/g1/meshes/half_sphere.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/head_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/head_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/head_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/head_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_G1_EE_pad.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_G1_EE_pad.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_G1_EE_pad.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_G1_EE_pad.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_ankle_pitch_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_ankle_pitch_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_ankle_pitch_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_ankle_pitch_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_ankle_roll_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_ankle_roll_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_ankle_roll_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_ankle_roll_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_elbow_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_elbow_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_elbow_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_elbow_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_elbow_link_merge.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_elbow_link_merge.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_elbow_link_merge.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_elbow_link_merge.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_index_0_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_index_0_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_index_0_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_index_0_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_index_1_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_index_1_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_index_1_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_index_1_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_middle_0_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_middle_0_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_middle_0_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_middle_0_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_middle_1_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_middle_1_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_middle_1_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_middle_1_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_palm_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_palm_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_palm_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_palm_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_thumb_0_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_thumb_0_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_thumb_0_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_thumb_0_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_thumb_1_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_thumb_1_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_thumb_1_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_thumb_1_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_thumb_2_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_thumb_2_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hand_thumb_2_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_hand_thumb_2_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hip_pitch_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_hip_pitch_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hip_pitch_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_hip_pitch_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hip_roll_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_hip_roll_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hip_roll_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_hip_roll_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hip_yaw_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_hip_yaw_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_hip_yaw_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_hip_yaw_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_knee_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_knee_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_knee_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_knee_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_rubber_hand.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_rubber_hand.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_rubber_hand.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_rubber_hand.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_shoulder_pitch_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_shoulder_pitch_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_shoulder_pitch_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_shoulder_pitch_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_shoulder_roll_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_shoulder_roll_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_shoulder_roll_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_shoulder_roll_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_shoulder_yaw_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_shoulder_yaw_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_shoulder_yaw_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_shoulder_yaw_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_wrist_pitch_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_wrist_pitch_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_wrist_pitch_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_wrist_pitch_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_wrist_roll_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_wrist_roll_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_wrist_roll_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_wrist_roll_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_wrist_roll_rubber_hand.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_wrist_roll_rubber_hand.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_wrist_roll_rubber_hand.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_wrist_roll_rubber_hand.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_wrist_yaw_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/left_wrist_yaw_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/left_wrist_yaw_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/left_wrist_yaw_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/logo_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/logo_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/logo_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/logo_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/pelvis.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/pelvis.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/pelvis.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/pelvis.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/pelvis_contour_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/pelvis_contour_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/pelvis_contour_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/pelvis_contour_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_G1_EE_pad.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_G1_EE_pad.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_G1_EE_pad.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_G1_EE_pad.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_ankle_pitch_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_ankle_pitch_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_ankle_pitch_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_ankle_pitch_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_ankle_roll_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_ankle_roll_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_ankle_roll_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_ankle_roll_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_elbow_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_elbow_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_elbow_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_elbow_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_elbow_link_merge.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_elbow_link_merge.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_elbow_link_merge.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_elbow_link_merge.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_index_0_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_index_0_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_index_0_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_index_0_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_index_1_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_index_1_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_index_1_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_index_1_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_middle_0_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_middle_0_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_middle_0_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_middle_0_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_middle_1_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_middle_1_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_middle_1_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_middle_1_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_palm_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_palm_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_palm_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_palm_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_thumb_0_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_thumb_0_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_thumb_0_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_thumb_0_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_thumb_1_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_thumb_1_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_thumb_1_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_thumb_1_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_thumb_2_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_thumb_2_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hand_thumb_2_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_hand_thumb_2_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hip_pitch_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_hip_pitch_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hip_pitch_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_hip_pitch_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hip_roll_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_hip_roll_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hip_roll_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_hip_roll_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hip_yaw_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_hip_yaw_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_hip_yaw_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_hip_yaw_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_knee_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_knee_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_knee_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_knee_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_rubber_hand.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_rubber_hand.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_rubber_hand.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_rubber_hand.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_shoulder_pitch_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_shoulder_pitch_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_shoulder_pitch_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_shoulder_pitch_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_shoulder_roll_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_shoulder_roll_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_shoulder_roll_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_shoulder_roll_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_shoulder_yaw_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_shoulder_yaw_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_shoulder_yaw_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_shoulder_yaw_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_wrist_pitch_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_wrist_pitch_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_wrist_pitch_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_wrist_pitch_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_wrist_roll_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_wrist_roll_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_wrist_roll_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_wrist_roll_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_wrist_roll_rubber_hand.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_wrist_roll_rubber_hand.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_wrist_roll_rubber_hand.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_wrist_roll_rubber_hand.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_wrist_yaw_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/right_wrist_yaw_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/right_wrist_yaw_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/right_wrist_yaw_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_constraint_L_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/torso_constraint_L_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_constraint_L_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/torso_constraint_L_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_constraint_L_rod_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/torso_constraint_L_rod_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_constraint_L_rod_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/torso_constraint_L_rod_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_constraint_R_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/torso_constraint_R_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_constraint_R_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/torso_constraint_R_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_constraint_R_rod_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/torso_constraint_R_rod_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_constraint_R_rod_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/torso_constraint_R_rod_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/torso_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/torso_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_link_23dof_rev_1_0.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/torso_link_23dof_rev_1_0.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_link_23dof_rev_1_0.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/torso_link_23dof_rev_1_0.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_link_rev_1_0.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/torso_link_rev_1_0.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/torso_link_rev_1_0.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/torso_link_rev_1_0.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/tote_no_bar.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/tote_no_bar.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/tote_no_bar.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/tote_no_bar.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_constraint_L.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/waist_constraint_L.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_constraint_L.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/waist_constraint_L.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_constraint_R.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/waist_constraint_R.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_constraint_R.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/waist_constraint_R.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_roll_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/waist_roll_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_roll_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/waist_roll_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_roll_link_rev_1_0.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/waist_roll_link_rev_1_0.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_roll_link_rev_1_0.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/waist_roll_link_rev_1_0.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_support_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/waist_support_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_support_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/waist_support_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_yaw_link.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/waist_yaw_link.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_yaw_link.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/waist_yaw_link.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_yaw_link_rev_1_0.STL b/motrix_robots/src/motrix_robots/assets/g1/meshes/waist_yaw_link_rev_1_0.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/g1/meshes/waist_yaw_link_rev_1_0.STL rename to motrix_robots/src/motrix_robots/assets/g1/meshes/waist_yaw_link_rev_1_0.STL diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/assets/calf.stl b/motrix_robots/src/motrix_robots/assets/go1/assets/calf.stl similarity index 100% rename from motrix_envs/src/motrix_envs/locomotion/go1/xmls/assets/calf.stl rename to motrix_robots/src/motrix_robots/assets/go1/assets/calf.stl diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/assets/hip.stl b/motrix_robots/src/motrix_robots/assets/go1/assets/hip.stl similarity index 100% rename from motrix_envs/src/motrix_envs/locomotion/go1/xmls/assets/hip.stl rename to motrix_robots/src/motrix_robots/assets/go1/assets/hip.stl diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/assets/thigh.stl b/motrix_robots/src/motrix_robots/assets/go1/assets/thigh.stl similarity index 100% rename from motrix_envs/src/motrix_envs/locomotion/go1/xmls/assets/thigh.stl rename to motrix_robots/src/motrix_robots/assets/go1/assets/thigh.stl diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/assets/thigh_mirror.stl b/motrix_robots/src/motrix_robots/assets/go1/assets/thigh_mirror.stl similarity index 100% rename from motrix_envs/src/motrix_envs/locomotion/go1/xmls/assets/thigh_mirror.stl rename to motrix_robots/src/motrix_robots/assets/go1/assets/thigh_mirror.stl diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/assets/trunk.stl b/motrix_robots/src/motrix_robots/assets/go1/assets/trunk.stl similarity index 100% rename from motrix_envs/src/motrix_envs/locomotion/go1/xmls/assets/trunk.stl rename to motrix_robots/src/motrix_robots/assets/go1/assets/trunk.stl diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/go1.xml b/motrix_robots/src/motrix_robots/assets/go1/go1.xml similarity index 100% rename from motrix_envs/src/motrix_envs/locomotion/go1/xmls/go1.xml rename to motrix_robots/src/motrix_robots/assets/go1/go1.xml diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/go1_motor_actuator.xml b/motrix_robots/src/motrix_robots/assets/go1/go1_motor_actuator.xml similarity index 100% rename from motrix_envs/src/motrix_envs/locomotion/go1/xmls/go1_motor_actuator.xml rename to motrix_robots/src/motrix_robots/assets/go1/go1_motor_actuator.xml diff --git a/motrix_envs/src/motrix_envs/locomotion/go1/xmls/go1_position_actuator.xml b/motrix_robots/src/motrix_robots/assets/go1/go1_position_actuator.xml similarity index 100% rename from motrix_envs/src/motrix_envs/locomotion/go1/xmls/go1_position_actuator.xml rename to motrix_robots/src/motrix_robots/assets/go1/go1_position_actuator.xml diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/base_0.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/base_0.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/base_0.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/base_0.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/base_1.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/base_1.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/base_1.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/base_1.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/base_2.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/base_2.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/base_2.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/base_2.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/base_3.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/base_3.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/base_3.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/base_3.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/base_4.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/base_4.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/base_4.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/base_4.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/calf_0.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/calf_0.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/calf_0.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/calf_0.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/calf_1.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/calf_1.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/calf_1.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/calf_1.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/calf_mirror_0.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/calf_mirror_0.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/calf_mirror_0.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/calf_mirror_0.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/calf_mirror_1.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/calf_mirror_1.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/calf_mirror_1.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/calf_mirror_1.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/foot.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/foot.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/foot.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/foot.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/hip_0.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/hip_0.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/hip_0.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/hip_0.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/hip_1.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/hip_1.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/hip_1.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/hip_1.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/thigh_0.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/thigh_0.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/thigh_0.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/thigh_0.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/thigh_1.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/thigh_1.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/thigh_1.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/thigh_1.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/thigh_mirror_0.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/thigh_mirror_0.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/thigh_mirror_0.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/thigh_mirror_0.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/assets/thigh_mirror_1.obj b/motrix_robots/src/motrix_robots/assets/go2/assets/thigh_mirror_1.obj similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/assets/thigh_mirror_1.obj rename to motrix_robots/src/motrix_robots/assets/go2/assets/thigh_mirror_1.obj diff --git a/motrix_envs/src/motrix_envs/robot/assets/go2/go2_mjx.xml b/motrix_robots/src/motrix_robots/assets/go2/go2_mjx.xml similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/go2/go2_mjx.xml rename to motrix_robots/src/motrix_robots/assets/go2/go2_mjx.xml diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/k1_22dof.xml b/motrix_robots/src/motrix_robots/assets/k1/k1_22dof.xml similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/k1_22dof.xml rename to motrix_robots/src/motrix_robots/assets/k1/k1_22dof.xml diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Head_1.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Head_1.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Head_1.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Head_1.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Head_2.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Head_2.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Head_2.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Head_2.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/K1logo.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/K1logo.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/K1logo.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/K1logo.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Ankle_Cross.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Ankle_Cross.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Ankle_Cross.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Ankle_Cross.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Arm_1.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Arm_1.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Arm_1.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Arm_1.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Arm_2.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Arm_2.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Arm_2.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Arm_2.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Arm_3.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Arm_3.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Arm_3.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Arm_3.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Arm_4.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Arm_4.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Arm_4.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Arm_4.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Foot.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Foot.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Foot.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Foot.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Hip_Pitch.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Hip_Pitch.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Hip_Pitch.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Hip_Pitch.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Hip_Roll.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Hip_Roll.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Hip_Roll.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Hip_Roll.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Hip_Yaw.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Hip_Yaw.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Hip_Yaw.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Hip_Yaw.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Shank.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Shank.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Left_Shank.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Left_Shank.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Ankle_Cross.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Ankle_Cross.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Ankle_Cross.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Ankle_Cross.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Arm_1.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Arm_1.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Arm_1.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Arm_1.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Arm_2.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Arm_2.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Arm_2.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Arm_2.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Arm_3.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Arm_3.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Arm_3.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Arm_3.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Arm_4.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Arm_4.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Arm_4.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Arm_4.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Foot.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Foot.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Foot.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Foot.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Hip_Pitch.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Hip_Pitch.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Hip_Pitch.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Hip_Pitch.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Hip_Roll.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Hip_Roll.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Hip_Roll.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Hip_Roll.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Hip_Yaw.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Hip_Yaw.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Hip_Yaw.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Hip_Yaw.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Shank.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Shank.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Right_Shank.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Right_Shank.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Trunk.STL b/motrix_robots/src/motrix_robots/assets/k1/meshes/Trunk.STL similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/k1/meshes/Trunk.STL rename to motrix_robots/src/motrix_robots/assets/k1/meshes/Trunk.STL diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/README.md b/motrix_robots/src/motrix_robots/assets/microduck/README.md similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/README.md rename to motrix_robots/src/motrix_robots/assets/microduck/README.md diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/ankle_left.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/ankle_left.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/ankle_left.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/ankle_left.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/ankle_right.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/ankle_right.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/ankle_right.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/ankle_right.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/banana_pcb_locker.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/banana_pcb_locker.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/banana_pcb_locker.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/banana_pcb_locker.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/bearing_roll.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/bearing_roll.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/bearing_roll.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/bearing_roll.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/bottom_head_shell.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/bottom_head_shell.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/bottom_head_shell.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/bottom_head_shell.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/elec_rpi_robot_hat_pcb.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/elec_rpi_robot_hat_pcb.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/elec_rpi_robot_hat_pcb.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/elec_rpi_robot_hat_pcb.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/face_part.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/face_part.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/face_part.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/face_part.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/foot_left.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/foot_left.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/foot_left.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/foot_left.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/foot_right.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/foot_right.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/foot_right.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/foot_right.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/hip_l.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/hip_l.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/hip_l.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/hip_l.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/jaw.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/jaw.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/jaw.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/jaw.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/jaw_soft.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/jaw_soft.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/jaw_soft.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/jaw_soft.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/left_shell.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/left_shell.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/left_shell.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/left_shell.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/leg.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/leg.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/leg.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/leg.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/lens.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/lens.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/lens.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/lens.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/m12_lens_holder.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/m12_lens_holder.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/m12_lens_holder.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/m12_lens_holder.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/motor_support.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/motor_support.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/motor_support.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/motor_support.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/neck.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/neck.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/neck.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/neck.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/neck_pitch.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/neck_pitch.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/neck_pitch.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/neck_pitch.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/noenoeil.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/noenoeil.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/noenoeil.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/noenoeil.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/np_f970.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/np_f970.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/np_f970.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/np_f970.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/pcb__raspberry_pi_zero_2_w.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/pcb__raspberry_pi_zero_2_w.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/pcb__raspberry_pi_zero_2_w.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/pcb__raspberry_pi_zero_2_w.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/power_support.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/power_support.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/power_support.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/power_support.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/right_shell.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/right_shell.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/right_shell.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/right_shell.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/seeed_bearing__configuration__22x16x4.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/seeed_bearing__configuration__22x16x4.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/seeed_bearing__configuration__22x16x4.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/seeed_bearing__configuration__22x16x4.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/seeed_bearing__configuration_default.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/seeed_bearing__configuration_default.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/seeed_bearing__configuration_default.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/seeed_bearing__configuration_default.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/soft_mouth_top.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/soft_mouth_top.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/soft_mouth_top.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/soft_mouth_top.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/sole_left.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/sole_left.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/sole_left.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/sole_left.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/sole_left_collision.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/sole_left_collision.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/sole_left_collision.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/sole_left_collision.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/sole_right.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/sole_right.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/sole_right.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/sole_right.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/sole_right_collision.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/sole_right_collision.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/sole_right_collision.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/sole_right_collision.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/speaker.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/speaker.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/speaker.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/speaker.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/top_head_shell.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/top_head_shell.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/top_head_shell.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/top_head_shell.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/trunk_base.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/trunk_base.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/trunk_base.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/trunk_base.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/upper_leg_left.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/upper_leg_left.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/upper_leg_left.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/upper_leg_left.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/upper_leg_right.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/upper_leg_right.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/upper_leg_right.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/upper_leg_right.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/upper_leg_rigidity_plate.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/upper_leg_rigidity_plate.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/upper_leg_rigidity_plate.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/upper_leg_rigidity_plate.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/xl330.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/xl330.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/xl330.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/xl330.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/yaw2roll.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/yaw2roll.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/yaw2roll.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/yaw2roll.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/assets/yaw_roll_motion.stl b/motrix_robots/src/motrix_robots/assets/microduck/assets/yaw_roll_motion.stl similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/assets/yaw_roll_motion.stl rename to motrix_robots/src/motrix_robots/assets/microduck/assets/yaw_roll_motion.stl diff --git a/motrix_envs/src/motrix_envs/robot/assets/microduck/microduck.xml b/motrix_robots/src/motrix_robots/assets/microduck/microduck.xml similarity index 100% rename from motrix_envs/src/motrix_envs/robot/assets/microduck/microduck.xml rename to motrix_robots/src/motrix_robots/assets/microduck/microduck.xml diff --git a/motrix_envs/src/motrix_envs/robot/booster.py b/motrix_robots/src/motrix_robots/booster.py similarity index 97% rename from motrix_envs/src/motrix_envs/robot/booster.py rename to motrix_robots/src/motrix_robots/booster.py index 73a4bb46..44d3a5e5 100644 --- a/motrix_envs/src/motrix_envs/robot/booster.py +++ b/motrix_robots/src/motrix_robots/booster.py @@ -5,7 +5,7 @@ from motrix_env_core.config import configclass from motrix_env_core.config.scene import KeyPoseCfg, MjcfFileCfg -from motrix_envs.robot.humanoid import HumanoidRobotCfg +from motrix_robots.humanoid import HumanoidRobotCfg BOOSTER_K1_ASSET_DIR = Path(__file__).parent / "assets" / "k1" _K1_22DOF_MJCF = BOOSTER_K1_ASSET_DIR / "k1_22dof.xml" diff --git a/motrix_envs/src/motrix_envs/robot/dex_evt.py b/motrix_robots/src/motrix_robots/dex_evt.py similarity index 83% rename from motrix_envs/src/motrix_envs/robot/dex_evt.py rename to motrix_robots/src/motrix_robots/dex_evt.py index 8ef01b38..a43dd66b 100644 --- a/motrix_envs/src/motrix_envs/robot/dex_evt.py +++ b/motrix_robots/src/motrix_robots/dex_evt.py @@ -12,7 +12,7 @@ UrdfFileCfg, UrdfGeomCfg, ) -from motrix_envs.robot.humanoid import HumanoidRobotCfg +from motrix_robots.humanoid import HumanoidRobotCfg DEX_EVT_ASSET_DIR = Path(__file__).parent / "assets" / "dex_evt" _DEX_EVT_URDF = DEX_EVT_ASSET_DIR / "dex_evt.urdf" @@ -121,7 +121,31 @@ class DexEvt(HumanoidRobotCfg): right_foot_link_name: str = "ankle_roll_r_link" translation: tuple[float, float, float] | None = (0.0, 0.0, 0.95) key_pose: KeyPoseCfg = KeyPoseCfg( - joint_names=list(_DRIVE_PARAMS), + joint_names=[ + "hip_pitch_l_joint", + "hip_roll_l_joint", + "hip_yaw_l_joint", + "knee_pitch_l_joint", + "ankle_pitch_l_joint", + "ankle_roll_l_joint", + "hip_pitch_r_joint", + "hip_roll_r_joint", + "hip_yaw_r_joint", + "knee_pitch_r_joint", + "ankle_pitch_r_joint", + "ankle_roll_r_joint", + "waist_yaw_joint", + "waist_roll_joint", + "waist_pitch_joint", + "shoulder_pitch_l_joint", + "shoulder_roll_l_joint", + "shoulder_yaw_l_joint", + "elbow_pitch_l_joint", + "shoulder_pitch_r_joint", + "shoulder_roll_r_joint", + "shoulder_yaw_r_joint", + "elbow_pitch_r_joint", + ], poses={ "default": [ -0.25, diff --git a/motrix_envs/src/motrix_envs/robot/humanoid.py b/motrix_robots/src/motrix_robots/humanoid.py similarity index 95% rename from motrix_envs/src/motrix_envs/robot/humanoid.py rename to motrix_robots/src/motrix_robots/humanoid.py index 5b0e7069..662bfe38 100644 --- a/motrix_envs/src/motrix_envs/robot/humanoid.py +++ b/motrix_robots/src/motrix_robots/humanoid.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 from motrix_env_core.config import configclass -from motrix_env_core.config.scene import RobotCfg +from motrix_env_core.config.scene.base import RobotCfg @configclass(kw_only=True) diff --git a/motrix_envs/src/motrix_envs/robot/microduck.py b/motrix_robots/src/motrix_robots/microduck.py similarity index 91% rename from motrix_envs/src/motrix_envs/robot/microduck.py rename to motrix_robots/src/motrix_robots/microduck.py index 808d74ce..758430aa 100644 --- a/motrix_envs/src/motrix_envs/robot/microduck.py +++ b/motrix_robots/src/motrix_robots/microduck.py @@ -5,7 +5,7 @@ from motrix_env_core.config import configclass from motrix_env_core.config.scene import KeyPoseCfg, MjcfFileCfg -from motrix_envs.robot.humanoid import HumanoidRobotCfg +from motrix_robots.humanoid import HumanoidRobotCfg MICRODUCK_ASSET_DIR = Path(__file__).parent / "assets" / "microduck" _MICRODUCK_MJCF = MICRODUCK_ASSET_DIR / "microduck.xml" @@ -41,7 +41,7 @@ class Microduck(HumanoidRobotCfg): "right_ankle", ], poses={ - # Upstream keyframe "STAND" (trunk at z=0.12). + # Upstream keyframe "STAND". "default": [ 0.0, -0.08726646259971647, @@ -58,7 +58,7 @@ class Microduck(HumanoidRobotCfg): 0.004940, -0.452984, ], - # Upstream keyframe "SIT" (trunk at z=0.07). + # Upstream keyframe "SIT". "sit": [ 0.0, 0.0, @@ -75,7 +75,7 @@ class Microduck(HumanoidRobotCfg): -1.0472, 0.0, ], - # Upstream keyframe "FOLD" (trunk at z=0.07). + # Upstream keyframe "FOLD". "fold": [ 0.0, 0.0, diff --git a/motrix_envs/src/motrix_envs/robot/quadruped.py b/motrix_robots/src/motrix_robots/quadruped.py similarity index 97% rename from motrix_envs/src/motrix_envs/robot/quadruped.py rename to motrix_robots/src/motrix_robots/quadruped.py index dd57fa97..96d93ec5 100644 --- a/motrix_envs/src/motrix_envs/robot/quadruped.py +++ b/motrix_robots/src/motrix_robots/quadruped.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 from motrix_env_core.config import configclass -from motrix_env_core.config.scene import RobotCfg +from motrix_env_core.config.scene.base import RobotCfg @configclass(kw_only=True) diff --git a/motrix_robots/src/motrix_robots/registration.py b/motrix_robots/src/motrix_robots/registration.py new file mode 100644 index 00000000..06895d8a --- /dev/null +++ b/motrix_robots/src/motrix_robots/registration.py @@ -0,0 +1,30 @@ +# Copyright Motphys Technology Co., Ltd. 2025, 2026 +# SPDX-License-Identifier: Apache-2.0 + +"""Builtin model registration callback for ``motrix_env_core.robots`` discovery. + +Importing this module only loads model classes. The core registry invokes +:func:`register` lazily when an application first queries robots by ID. +""" + +from motrix_env_core import registry +from motrix_robots.anymal import AnymalC +from motrix_robots.booster import BoosterK1 +from motrix_robots.dex_evt import DexEvt +from motrix_robots.microduck import Microduck +from motrix_robots.unitree import ( + UnitreeG129Dof, + UnitreeGo1Robot, + UnitreeGo2Robot, +) + + +def register() -> None: + """Register the seven established builtin simulation robot IDs.""" + registry.register_robot_config("anymal_c", AnymalC) + registry.register_robot_config("dex-evt", DexEvt) + registry.register_robot_config("g1-29dof", UnitreeG129Dof) + registry.register_robot_config("go1", UnitreeGo1Robot) + registry.register_robot_config("go2", UnitreeGo2Robot) + registry.register_robot_config("k1", BoosterK1) + registry.register_robot_config("microduck", Microduck) diff --git a/motrix_envs/src/motrix_envs/robot/unitree.py b/motrix_robots/src/motrix_robots/unitree.py similarity index 95% rename from motrix_envs/src/motrix_envs/robot/unitree.py rename to motrix_robots/src/motrix_robots/unitree.py index bfe1a1fa..f095bf11 100644 --- a/motrix_envs/src/motrix_envs/robot/unitree.py +++ b/motrix_robots/src/motrix_robots/unitree.py @@ -5,11 +5,11 @@ from motrix_env_core.config import configclass from motrix_env_core.config.scene import KeyPoseCfg, MjcfFileCfg -from motrix_envs.robot.humanoid import HumanoidRobotCfg -from motrix_envs.robot.quadruped import QuadrupedLegCfg, QuadrupedLegsCfg, QuadrupedRobotCfg +from motrix_robots.humanoid import HumanoidRobotCfg +from motrix_robots.quadruped import QuadrupedLegCfg, QuadrupedLegsCfg, QuadrupedRobotCfg UNITREE_G1_ASSET_DIR = Path(__file__).parent / "assets" / "g1" -UNITREE_GO1_ASSET_DIR = Path(__file__).parents[1] / "locomotion" / "go1" / "xmls" +UNITREE_GO1_ASSET_DIR = Path(__file__).parent / "assets" / "go1" UNITREE_GO2_ASSET_DIR = Path(__file__).parent / "assets" / "go2" _G1_29DOF_MJCF = UNITREE_G1_ASSET_DIR / "g1_29dof.xml" _GO1_MJCF = UNITREE_GO1_ASSET_DIR / "go1_position_actuator.xml" diff --git a/motrix_robots/tests/test_assets.py b/motrix_robots/tests/test_assets.py new file mode 100644 index 00000000..418f9118 --- /dev/null +++ b/motrix_robots/tests/test_assets.py @@ -0,0 +1,46 @@ +# Copyright Motphys Technology Co., Ltd. 2025, 2026 +# SPDX-License-Identifier: Apache-2.0 + +"""Robot model references form a self-contained package asset closure.""" + +import xml.etree.ElementTree as ET +from pathlib import Path + +from motrix_robots.anymal import AnymalC +from motrix_robots.booster import BoosterK1 +from motrix_robots.dex_evt import DexEvt +from motrix_robots.microduck import Microduck +from motrix_robots.unitree import UnitreeG129Dof, UnitreeGo1Robot, UnitreeGo2Robot + + +def test_builtin_models_resolve_from_package_assets() -> None: + for robot_type in (AnymalC, BoosterK1, DexEvt, Microduck, UnitreeG129Dof, UnitreeGo1Robot, UnitreeGo2Robot): + robot = robot_type() + robot.validate("robot") + assert Path(robot.model.file).is_file() + assert len(robot.key_pose.poses[robot.init_key_pose]) == len(robot.key_pose.joint_names) + + +def test_bundled_mjcf_file_references_resolve() -> None: + asset_root = Path(UnitreeGo2Robot().model.file).parents[1] + for model in asset_root.rglob("*.xml"): + root = ET.parse(model).getroot() + if root.tag != "mujoco": + continue + compiler = root.find("compiler") + meshdir = compiler.get("meshdir", "") if compiler is not None else "" + texturedir = compiler.get("texturedir", "") if compiler is not None else "" + for element in root.iter(): + file = element.get("file") + if file is None: + continue + directory = meshdir if element.tag == "mesh" else texturedir if element.tag == "texture" else "" + assert (model.parent / directory / file).is_file(), (model, element.tag, file) + + +def test_bundled_urdf_mesh_references_resolve() -> None: + asset_root = Path(UnitreeGo2Robot().model.file).parents[1] + for model in asset_root.rglob("*.urdf"): + root = ET.parse(model).getroot() + for mesh in root.iter("mesh"): + assert (model.parent / mesh.attrib["filename"]).is_file(), (model, mesh.attrib["filename"]) diff --git a/motrix_robots/tests/test_robots_contracts.py b/motrix_robots/tests/test_robots_contracts.py new file mode 100644 index 00000000..07ea9192 --- /dev/null +++ b/motrix_robots/tests/test_robots_contracts.py @@ -0,0 +1,155 @@ +# Copyright Motphys Technology Co., Ltd. 2025, 2026 +# SPDX-License-Identifier: Apache-2.0 + +from copy import deepcopy +from importlib import import_module + +import pytest +from hydra.utils import instantiate +from motrix_robots.anymal import AnymalC +from motrix_robots.booster import BoosterK1 +from motrix_robots.dex_evt import DexEvt +from motrix_robots.microduck import Microduck +from motrix_robots.unitree import UnitreeG129Dof, UnitreeGo1Robot, UnitreeGo2Robot +from omegaconf import OmegaConf + +import motrix_robots +from motrix_env_core.config.scene import KeyPoseCfg +from motrix_env_core.config.scene.actuator import MotorActuatorCfg +from motrix_env_core.config.scene.base import RobotCfg + +MODEL_TYPES = [AnymalC, BoosterK1, DexEvt, Microduck, UnitreeG129Dof, UnitreeGo1Robot, UnitreeGo2Robot] + + +@pytest.mark.parametrize( + ("module_name", "type_name"), + [ + ("anymal", "AnymalC"), + ("booster", "BoosterK1"), + ("dex_evt", "DexEvt"), + ("humanoid", "HumanoidRobotCfg"), + ("microduck", "Microduck"), + ("quadruped", "QuadrupedLegCfg"), + ("quadruped", "QuadrupedLegsCfg"), + ("quadruped", "QuadrupedRobotCfg"), + ("unitree", "UnitreeG129Dof"), + ("unitree", "UnitreeGo1Robot"), + ("unitree", "UnitreeGo2Robot"), + ], +) +def test_public_types_are_their_defining_module_types(module_name, type_name) -> None: + defining_module = import_module(f"motrix_robots.{module_name}") + assert getattr(motrix_robots, type_name) is getattr(defining_module, type_name) + assert type_name in motrix_robots.__all__ + + +@pytest.mark.parametrize("model_type", MODEL_TYPES) +def test_public_model_constructors_return_fresh_configurations(model_type) -> None: + public_type = getattr(motrix_robots, model_type.__name__) + first = public_type() + second = public_type() + first.validate("robot") + second.validate("robot") + assert isinstance(first, model_type) + assert first is not second + assert first.model is not second.model + assert first.key_pose is not second.key_pose + + +@pytest.mark.parametrize("model_type", MODEL_TYPES) +@pytest.mark.parametrize("copy_kind", ["fresh", "deepcopy", "omegaconf"]) +def test_model_owned_key_poses_are_valid_and_isolated(model_type, copy_kind) -> None: + robot = model_type() + assert isinstance(robot, RobotCfg) + assert isinstance(robot.key_pose, KeyPoseCfg) + robot.validate("robot") + assert robot.key_pose.joint_names + assert robot.init_key_pose in robot.key_pose.poses + + cfg = OmegaConf.structured(robot) if copy_kind == "omegaconf" else None + if copy_kind == "fresh": + copied = model_type() + elif copy_kind == "deepcopy": + copied = deepcopy(robot) + else: + copied = OmegaConf.to_object(cfg) + assert isinstance(copied, model_type) + copied.validate("robot") + assert copied.key_pose == robot.key_pose + assert copied.key_pose is not robot.key_pose + assert copied.key_pose.joint_names is not robot.key_pose.joint_names + assert copied.key_pose.poses is not robot.key_pose.poses + for name, pose in copied.key_pose.poses.items(): + assert pose is not robot.key_pose.poses[name] + pose[0] += 1.0 + copied.key_pose.joint_names[0] = "custom_joint" + copied.key_pose.poses["custom"] = list(copied.key_pose.poses[copied.init_key_pose]) + assert robot.key_pose == model_type().key_pose + if cfg is not None: + assert OmegaConf.to_object(cfg).key_pose == robot.key_pose + + +def test_builtin_model_inherits_scene_placement_and_actuator_contract() -> None: + actuator = MotorActuatorCfg(joint_name="hinge", force_range=(-2.0, 2.0)) + robot = UnitreeGo2Robot( + prefix="robot_", + suffix="_1", + translation=(1.0, 2.0, 3.0), + actuators={"hinge_motor": actuator}, + ) + assert isinstance(robot, RobotCfg) + assert robot.resolved_base_link_name == robot.resolve_name(robot.base_link_name) + assert robot.resolve_name(actuator.joint_name) == "robot_hinge_1" + restored = OmegaConf.to_object(OmegaConf.structured(robot)) + restored.validate("robot") + assert tuple(restored.translation) == robot.translation + assert isinstance(restored.actuators["hinge_motor"], MotorActuatorCfg) + assert restored.actuators["hinge_motor"].joint_name == actuator.joint_name + assert tuple(restored.actuators["hinge_motor"].force_range) == actuator.force_range + restored.actuators["hinge_motor"].joint_name = "custom_hinge" + assert robot.actuators["hinge_motor"].joint_name == "hinge" + + +def test_scene_pose_override_and_hydra_composition() -> None: + override = KeyPoseCfg(joint_names=["hinge"], poses={"default": [0.2]}) + robot = UnitreeGo2Robot(key_pose=override) + assert robot.key_pose is override + robot.validate("robot") + assert OmegaConf.to_object(OmegaConf.structured(robot)).key_pose == override + composed = instantiate( + { + "_target_": "motrix_robots.unitree.UnitreeGo2Robot", + "key_pose": { + "_target_": "motrix_env_core.config.scene.KeyPoseCfg", + "joint_names": ["hinge"], + "poses": {"default": [0.3]}, + }, + } + ) + assert composed.key_pose == KeyPoseCfg(joint_names=["hinge"], poses={"default": [0.3]}) + composed.validate("robot") + + +def test_omegaconf_custom_key_pose_override() -> None: + original = UnitreeGo2Robot() + cfg = OmegaConf.structured(original) + cfg.key_pose = OmegaConf.structured(KeyPoseCfg(joint_names=["custom_hinge"], poses={"custom": [0.4]})) + cfg.init_key_pose = "custom" + restored = OmegaConf.to_object(cfg) + assert isinstance(restored, UnitreeGo2Robot) + assert restored.key_pose == KeyPoseCfg(joint_names=["custom_hinge"], poses={"custom": [0.4]}) + restored.validate("robot") + restored.key_pose.poses["custom"][0] += 1.0 + assert original.key_pose == UnitreeGo2Robot().key_pose + assert cfg.key_pose.poses.custom == [0.4] + + +def test_explicit_empty_key_pose_is_preserved() -> None: + empty = KeyPoseCfg() + robot = UnitreeGo2Robot(key_pose=empty) + assert robot.key_pose is empty + assert robot.key_pose == KeyPoseCfg() + robot.validate("robot") + restored = OmegaConf.to_object(OmegaConf.structured(robot)) + assert restored.key_pose == empty + restored.validate("robot") diff --git a/motrix_robots/tests/test_robots_package.py b/motrix_robots/tests/test_robots_package.py new file mode 100644 index 00000000..24948260 --- /dev/null +++ b/motrix_robots/tests/test_robots_package.py @@ -0,0 +1,100 @@ +# Copyright Motphys Technology Co., Ltd. 2025, 2026 +# SPDX-License-Identifier: Apache-2.0 + +"""Simulation model package boundaries and installed asset closure.""" + +import subprocess +import sys +import textwrap + + +def test_model_imports_do_not_read_or_scan_assets() -> None: + result = subprocess.run( + [ + sys.executable, + "-c", + textwrap.dedent( + """ + import sys + + def check_asset_access(event, args): + if event in ('open', 'os.scandir', 'os.listdir'): + path = str(args[0]).replace('\\\\', '/') + assert '/motrix_robots/assets' not in path, (event, path) + assert '/motrix_robots/common' not in path, (event, path) + + sys.addaudithook(check_asset_access) + from motrix_env_core import registry + import motrix_robots + from motrix_robots.unitree import UnitreeGo2Robot + import motrix_robots.registration + UnitreeGo2Robot() + assert not registry._robots + assert not registry._robots_discovered + """ + ), + ], + capture_output=True, + text=True, + ) + assert result.returncode == 0, result.stderr + + +def test_builtin_import_does_not_load_training_or_simulators() -> None: + result = subprocess.run( + [ + sys.executable, + "-c", + "from motrix_robots.unitree import UnitreeGo2Robot; " + "import sys; " + "assert not any(name in sys.modules for name in " + "('motrix_envs', 'motrixsim', 'mujoco', 'torch', 'motrix_deploy', 'unitree_sdk2py')); " + "UnitreeGo2Robot().validate('robot')", + ], + capture_output=True, + text=True, + ) + assert result.returncode == 0, result.stderr + + +def test_installed_plugin_discovers_builtin_models_without_explicit_imports() -> None: + result = subprocess.run( + [ + sys.executable, + "-c", + textwrap.dedent( + """ + import sys + + from motrix_env_core import registry + assert 'motrix_robots' not in sys.modules + expected_types = { + 'anymal_c': 'AnymalC', + 'dex-evt': 'DexEvt', + 'g1-29dof': 'UnitreeG129Dof', + 'go1': 'UnitreeGo1Robot', + 'go2': 'UnitreeGo2Robot', + 'k1': 'BoosterK1', + 'microduck': 'Microduck', + } + # A make lookup alone must discover the installed wheel entry point. + first = registry.make_robot_config('go2') + registered = registry.list_registered_robots() + assert expected_types.keys() <= registered.keys() + for name, expected_type in expected_types.items(): + robot = registry.make_robot_config(name) + assert type(robot).__name__ == expected_type + assert registered[name]['config_class'] == expected_type + assert registry.make_robot_config(name) is not robot + assert registry.make_robot_config('go2') is not first + assert not any(name in sys.modules for name in ( + 'motrix_envs', 'motrixsim', 'mujoco', 'torch', + 'motrix_deploy', 'unitree_sdk2py', + )) + """ + ), + ], + capture_output=True, + text=True, + ) + assert result.returncode == 0, result.stderr diff --git a/pyproject.toml b/pyproject.toml index 96b1192e..c6099c89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,6 +74,7 @@ test = [ [tool.uv.workspace] members = [ + "motrix_robots", "motrix_deploy", "motrix_deploy_mujoco", "motrix_deploy_unitree", @@ -116,6 +117,7 @@ name = "pypi" url = "https://pypi.org/simple" [tool.uv.sources] +motrix-robots = { workspace = true } motrix-env-core = { workspace = true } motrix-deploy = { workspace = true } motrix-deploy-mujoco = { workspace = true } diff --git a/scripts/motion/replay.py b/scripts/motion/replay.py index 66a408c1..7852472e 100644 --- a/scripts/motion/replay.py +++ b/scripts/motion/replay.py @@ -23,6 +23,9 @@ import motrixsim as mtx import numpy as np from absl import app, flags +from motrix_robots.booster import BoosterK1 +from motrix_robots.dex_evt import DexEvt +from motrix_robots.unitree import UnitreeG129Dof from motrixsim.render import RenderApp, RenderClosedError, RenderSettings from motrix_env_core.config.scene import ( @@ -32,7 +35,6 @@ from motrix_env_motrixsim.compiler import build_scene_model from motrix_envs.config.scene import StandardSceneCfg, StandardSceneObjsCfg from motrix_envs.motion import MotrixMotion -from motrix_envs.robot import BoosterK1, DexEvt, UnitreeG129Dof logger = logging.getLogger(__name__) diff --git a/scripts/private/g1_flip_converter.py b/scripts/private/g1_flip_converter.py index fa87b956..9dd2605f 100644 --- a/scripts/private/g1_flip_converter.py +++ b/scripts/private/g1_flip_converter.py @@ -28,6 +28,7 @@ import motrixsim as mtx import numpy as np +from motrix_robots.unitree import UnitreeG129Dof from motrix_env_core.config import configclass from motrix_env_core.config.scene import RobotCfg, SceneCfg, SceneObjsCfg @@ -40,7 +41,6 @@ _trim, ) from motrix_envs.motion.schema import SCHEMA_VERSION, XYZW_FROM_WXYZ -from motrix_envs.robot import UnitreeG129Dof # Assumed joint column order of the mjbatch flip.npz: the MuJoCo Menagerie # unitree_g1 29-DOF qpos order (verified indirectly by the FK cross-check). diff --git a/scripts/private/k1_mujoco_converter.py b/scripts/private/k1_mujoco_converter.py index ea227a3a..e82b16d9 100644 --- a/scripts/private/k1_mujoco_converter.py +++ b/scripts/private/k1_mujoco_converter.py @@ -20,6 +20,7 @@ import motrixsim as mtx import numpy as np +from motrix_robots.booster import BoosterK1 from motrix_env_core.config import configclass from motrix_env_core.config.scene import RobotCfg, SceneCfg, SceneObjsCfg @@ -31,7 +32,6 @@ _trim, ) from motrix_envs.motion.schema import SCHEMA_VERSION, XYZW_FROM_WXYZ -from motrix_envs.robot import BoosterK1 _K1_ROOT_BODY = "Trunk" _K1_REFERENCE_BODY = "Trunk" diff --git a/scripts/private/xmimic_converter.py b/scripts/private/xmimic_converter.py index fcf2fa4b..e37039f0 100644 --- a/scripts/private/xmimic_converter.py +++ b/scripts/private/xmimic_converter.py @@ -31,6 +31,7 @@ import motrixsim as mtx import numpy as np +from motrix_robots.dex_evt import DexEvt from motrix_env_core.config import configclass from motrix_env_core.config.scene import RobotCfg, SceneCfg, SceneObjsCfg @@ -42,7 +43,6 @@ _trim, ) from motrix_envs.motion.schema import SCHEMA_VERSION, XYZW_FROM_WXYZ -from motrix_envs.robot import DexEvt # 23-DOF joint order of the xMimic joint_pos columns. # diff --git a/tests/test_view_script.py b/tests/test_view_script.py index c7410133..842af537 100644 --- a/tests/test_view_script.py +++ b/tests/test_view_script.py @@ -8,9 +8,9 @@ from unittest.mock import Mock import pytest +from motrix_robots.unitree import UnitreeGo2Robot from motrix_env_core import registry -from motrix_envs.robot import UnitreeGo2Robot from motrix_rl.config import ViewConfig VIEW_SCRIPT = Path(__file__).resolve().parents[1] / "scripts" / "view.py" diff --git a/uv.lock b/uv.lock index 1f117acc..6246c943 100644 --- a/uv.lock +++ b/uv.lock @@ -31,6 +31,7 @@ members = [ "motrix-rl-builtin", "motrix-rl-rslrl", "motrix-rl-skrl", + "motrix-robots", ] [[package]] @@ -1074,6 +1075,7 @@ dependencies = [ { name = "gymnasium" }, { name = "motrix-env-core", extra = ["numba", "video"] }, { name = "motrix-env-motrixsim" }, + { name = "motrix-robots" }, { name = "numpy" }, { name = "omegaconf" }, ] @@ -1089,6 +1091,7 @@ requires-dist = [ { name = "motrix-deploy", marker = "extra == 'deploy'", editable = "motrix_deploy" }, { name = "motrix-env-core", extras = ["numba", "video"], editable = "motrix_env_core" }, { name = "motrix-env-motrixsim", editable = "motrix_env_motrixsim" }, + { name = "motrix-robots", editable = "motrix_robots" }, { name = "numpy", specifier = ">=1.26" }, { name = "omegaconf", specifier = ">=2.3,<2.4" }, ] @@ -1319,6 +1322,17 @@ requires-dist = [ ] provides-extras = ["jax"] +[[package]] +name = "motrix-robots" +version = "0.4.0b0" +source = { editable = "motrix_robots" } +dependencies = [ + { name = "motrix-env-core" }, +] + +[package.metadata] +requires-dist = [{ name = "motrix-env-core", editable = "motrix_env_core" }] + [[package]] name = "motrixsim" version = "0.10.1" diff --git a/wiki/design/user-docs-envs-part.md b/wiki/design/user-docs-envs-part.md index 27d91099..e1919dd9 100644 --- a/wiki/design/user-docs-envs-part.md +++ b/wiki/design/user-docs-envs-part.md @@ -375,7 +375,7 @@ Robot 页面继续作为独立参考。环境页面只链接其使用的 Robot - Env ID 和 EnvCfg:`motrix_env_core.registry` 及 `motrix_envs` 注册代码; - Env description:注册 class 或 factory 的 Python docstring,由 Env Registry 自动提取; - Training Algorithms:`configs/task//` 中实际存在的 Hydra Task 选项; -- Robot:Robot Registry 与 `motrix_envs.robot`; +- Robot:`motrix_env_core.registry` 的 Robot Registry 与 `motrix_robots` 公共配置 API; - 页面视频和封面:`docs/source/_static/`。 `envs/index.md` 的 overview 表格由生成器维护,不人工添加、删除或调整行。Env ID 和双语 description 直接来自 registry;description 的事实来源是注册 provider 的 Python docstring;Training Algorithms 直接来自 Hydra Task 发现结果。环境详情页中的长篇任务描述、任务语义和选型建议继续人工维护。