Implementation:Haosulab ManiSkill BaseAgent
| Knowledge Sources | |
|---|---|
| Domains | Robotics, Simulation |
| Last Updated | 2026-02-15 08:00 GMT |
Overview
Concrete base class for defining and managing robot agents within the ManiSkill simulation framework.
Description
BaseAgent is the foundational class that all robot/agent implementations in ManiSkill inherit from. It wraps a SAPIEN Articulation and manages the full robot lifecycle: loading from URDF or MJCF definitions (with automatic asset download support), configuring controllers via the _controller_configs property (defaulting to PD joint position control), managing control modes, handling action spaces, and providing state get/set for reproducibility. Controllers are lazily instantiated on first use. Gravity is disabled on robot links as a workaround for passive force balancing in PhysX. The class also exposes get_proprioception(), reset(), and optional is_grasping()/is_static() interfaces. A companion Keyframe dataclass stores predefined robot poses (pose, qpos, qvel) for convenient reset targets.
Usage
Subclass BaseAgent when implementing a new robot. Set the class attributes uid, urdf_path (or mjcf_path), and override _controller_configs to define available control modes. The environment's _load_agent method instantiates the agent, and the environment delegates set_action, before_simulation_step, get_proprioception, and reset calls to it each step.
Code Reference
Source Location
- Repository: Haosulab_ManiSkill
- File: mani_skill/agents/base_agent.py
- Lines: 1-437
Signature
class BaseAgent:
uid: str
urdf_path: Union[str, None] = None
mjcf_path: Union[str, None] = None
fix_root_link: bool = True
keyframes: dict[str, Keyframe] = dict()
def __init__(
self,
scene: ManiSkillScene,
control_freq: int,
control_mode: Optional[str] = None,
agent_idx: Optional[str] = None,
initial_pose: Optional[Union[sapien.Pose, Pose]] = None,
build_separate: bool = False,
):
Import
from mani_skill.agents.base_agent import BaseAgent
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| scene | ManiSkillScene | Yes | The simulation scene instance the agent is placed in. |
| control_freq | int | Yes | Control frequency in Hz determining how often the controller is called. |
| control_mode | str or None | No | UID of the controller to activate. Defaults to first in _controller_configs.
|
| agent_idx | str or None | No | Index identifier for multi-agent setups. None for single-agent tasks. |
| initial_pose | sapien.Pose or Pose or None | No | Initial pose of the robot. Important for GPU simulation to avoid collisions during initialization. |
| build_separate | bool | No | If True, builds a separate articulation per sub-scene and merges them. Defaults to False. |
Outputs
| Name | Type | Description |
|---|---|---|
| robot | Articulation | The loaded robot articulation, accessible as self.robot.
|
| controllers | dict[str, BaseController] | Dictionary of instantiated controllers keyed by control mode UID. |
| action_space | spaces.Space | The Gymnasium action space of the currently active controller. |
| get_proprioception() | dict | Returns {"qpos": Tensor, "qvel": Tensor} plus optional controller state.
|
| get_state() | dict | Full agent state including root pose, velocities, qpos, qvel, and controller state. |
Usage Examples
Basic Usage
from mani_skill.agents.base_agent import BaseAgent, Keyframe
from mani_skill.agents.controllers.pd_joint_pos import PDJointPosControllerConfig
import sapien
class MyRobot(BaseAgent):
uid = "my_robot"
urdf_path = "path/to/robot.urdf"
fix_root_link = True
keyframes = dict(
rest=Keyframe(pose=sapien.Pose(), qpos=[0.0] * 7)
)
@property
def _controller_configs(self):
return dict(
pd_joint_pos=PDJointPosControllerConfig(
joint_names=[j.name for j in self.robot.active_joints],
lower=None,
upper=None,
stiffness=100,
damping=10,
normalize_action=False,
),
)