Implementation:Haosulab ManiSkill BaseController
| Knowledge Sources | |
|---|---|
| Domains | Robotics, Simulation |
| Last Updated | 2026-02-15 08:00 GMT |
Overview
Concrete base class and composite controller hierarchy for defining robot joint control interfaces in ManiSkill.
Description
This file defines the controller hierarchy used by all ManiSkill agents. BaseController is the abstract base class that initializes joints from a ControllerConfig, builds action spaces (with optional normalization via clip-and-scale), computes simulation steps per control step, and defines the interface methods: set_action, set_drive_property, before_simulation_step, get_state/set_state. ControllerConfig is a dataclass holding joint_names and a controller_cls reference. DictController manages multiple sub-controllers with a spaces.Dict action space. CombinedController extends DictController by flattening all sub-controller action spaces into a single Box space with an action mapping for slicing actions back to sub-controllers.
Usage
Subclass BaseController to implement a specific control strategy (e.g., PD joint position, PD joint velocity). Define a corresponding ControllerConfig dataclass with the controller_cls class variable pointing to your controller. The CombinedController is automatically used by BaseAgent when _controller_configs returns a dict of configs for heterogeneous joint groups (e.g., arm + gripper).
Code Reference
Source Location
- Repository: Haosulab_ManiSkill
- File: mani_skill/agents/controllers/base_controller.py
- Lines: 1-347
Signature
class BaseController:
def __init__(
self,
config: "ControllerConfig",
articulation: Articulation,
control_freq: int,
sim_freq: Optional[int] = None,
scene: ManiSkillScene = None,
):
@dataclass
class ControllerConfig:
joint_names: list[str]
controller_cls = BaseController
class DictController(BaseController):
def __init__(
self,
configs: dict[str, ControllerConfig],
articulation: Articulation,
control_freq: int,
sim_freq: int = None,
scene: ManiSkillScene = None,
):
class CombinedController(DictController):
...
Import
from mani_skill.agents.controllers.base_controller import (
BaseController,
ControllerConfig,
DictController,
CombinedController,
)
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| config | ControllerConfig | Yes | Configuration dataclass specifying joint names and controller parameters. |
| articulation | Articulation | Yes | The robot articulation this controller acts on. |
| control_freq | int | Yes | Control frequency in Hz. |
| sim_freq | int or None | No | Simulation frequency in Hz. If None, inferred from the articulation's physics timestep. |
| scene | ManiSkillScene | No | The simulation scene, used to determine batch size and GPU state. |
Outputs
| Name | Type | Description |
|---|---|---|
| action_space | spaces.Space | The (optionally batched and normalized) Gymnasium action space for this controller. |
| single_action_space | spaces.Space | The unbatched action space for a single environment. |
| joints | list[ArticulationJoint] | List of active joints controlled by this controller. |
| active_joint_indices | torch.Tensor | Tensor of active joint indices in the articulation. |
| get_state() | dict | Controller internal state (e.g., target positions for stateful controllers). |
Usage Examples
Basic Usage
from mani_skill.agents.controllers.base_controller import ControllerConfig, CombinedController
from mani_skill.agents.controllers.pd_joint_pos import PDJointPosControllerConfig
from mani_skill.agents.controllers.passive_controller import PassiveControllerConfig
# Define a combined controller config for a robot arm + gripper
controller_configs = dict(
arm=PDJointPosControllerConfig(
joint_names=["joint1", "joint2", "joint3", "joint4", "joint5", "joint6", "joint7"],
lower=-3.14, upper=3.14,
stiffness=100, damping=10,
normalize_action=True, use_delta=True,
),
gripper=PassiveControllerConfig(
joint_names=["finger_joint1", "finger_joint2"],
damping=10,
),
)
# CombinedController is created automatically by BaseAgent when given a dict config
# The resulting flat action space covers arm joints only (gripper is passive)