添加物理后端#
实现以下后端接口,即可添加物理引擎。工厂分发和共享接口见 后端架构。
先决条件#
开始前,先明确引擎的生命周期、原生数据归属,以及可支持的资产和传感器。后端必须提供 PhysicsManager 实现,并遵循 FactoryBase 要求的模块布局。
创建后端包#
创建扩展包,在包路径中使用后端名称。例如,名为 mybackend 的后端使用以下布局:
source/isaaclab_mybackend/
└── isaaclab_mybackend/
├── __init__.py
├── physics/
│ ├── __init__.py # lazy_export()
│ ├── __init__.pyi # public exports
│ ├── mybackend_manager.py
│ └── mybackend_manager_cfg.py
├── assets/
│ ├── articulation/
│ │ ├── __init__.py
│ │ ├── __init__.pyi
│ │ ├── articulation.py
│ │ └── articulation_data.py
│ ├── rigid_object/
│ │ └── ...
│ ├── deformable_object/
│ │ └── ...
│ └── rigid_object_collection/
│ └── ...
├── sensors/
│ ├── contact_sensor/
│ └── ...
├── renderers/
│ └── ...
└── cloner/
└── ...
实现物理管理器#
管理器必须提供 SceneDataBackend ,使 SceneDataProvider 能以渲染器和可视化器使用的 Warp 原生格式,读取后端的刚体变换。
# isaaclab_mybackend/physics/mybackend_manager.py
from isaaclab.physics import PhysicsEvent, PhysicsManager
from isaaclab.scene_data import SceneDataBackend, SceneDataFormat
class MyBackendSceneDataBackend(SceneDataBackend):
def __init__(self):
self._scene_data = SceneDataFormat.Transform()
@property
def transforms(self) -> SceneDataFormat.Transform:
# Return current world-space body transforms as a Warp transformf array.
self._scene_data.transforms = ... # backend-native tensor view
return self._scene_data
@property
def transform_count(self) -> int:
...
@property
def transform_paths(self) -> list[str]:
# One prim path per transform; used by SceneDataProvider.create_mapping.
...
class MyBackendManager(PhysicsManager):
backend_name = "mybackend"
def __init__(self):
super().__init__()
self._scene_data_backend: MyBackendSceneDataBackend | None = None
def initialize(self, sim_context):
super().initialize(sim_context)
self._scene_data_backend = MyBackendSceneDataBackend()
# Initialize the physics engine.
def get_scene_data_backend(self) -> SceneDataBackend:
return self._scene_data_backend
def step(self):
# Advance simulation by one timestep.
...
def forward(self):
# Update kinematics without stepping.
...
def reset(self, soft=False):
if not soft:
self.dispatch_event(PhysicsEvent.PHYSICS_READY)
# Reset simulation state.
def close(self):
super().close()
# Clean up resources.
定义物理配置#
定义 PhysicsCfg 子类,指定管理器类并保存后端特有设置:
# isaaclab_mybackend/physics/mybackend_manager_cfg.py
from isaaclab.physics import PhysicsCfg
from isaaclab.utils import configclass
@configclass
class MyBackendCfg(PhysicsCfg):
class_type = "{DIR}.mybackend_manager:MyBackendManager"
# Backend-specific settings here.
注册后端键#
FactoryBase._get_backend() 返回当前 SimulationContext.backend_manager 实例的 backend_name 类属性。上述管理器设置 backend_name = "mybackend",因此工厂无需修改 isaaclab.utils.backend_utils 就能解析对应的资产与传感器。
现有的 _get_package_name() 约定将 mybackend 键映射到上面使用的 isaaclab_mybackend 包。若集成使用其他包名,还需在 _get_package_name() 中添加显式分支。FactoryBase.register() 只会在键和包映射已选中并导入后端模块后缓存具体类;单独调用它并不能注册新的后端键。
实现资产和传感器#
每个受支持的资产或传感器都继承 isaaclab 中对应的基类。实现类名必须与工厂期望的名称一致。在包的 __init__.py 中使用 lazy_export() 。核心后端键映射配置好后,工厂会按包名和模块路径约定导入模块,并缓存实现类。
# isaaclab_mybackend/assets/articulation/articulation.py
from isaaclab.assets.articulation import BaseArticulation
class Articulation(BaseArticulation):
def __init__(self, cfg):
super().__init__(cfg)
# Set up backend-specific simulation structures.
验证后端发现机制#
从当前物理管理器选择已注册的 mybackend 键后, FactoryBase 会将 isaaclab.assets.articulation 映射到 isaaclab_mybackend.assets.articulation 。请按以下步骤验证配置的发现路径:
构造后端配置。
使用该配置初始化最小仿真。
实例化一个后端支持的资产。
推进一个仿真步。
正常关闭仿真。