Implementation:Haosulab ManiSkill PDJointPosController
| Knowledge Sources | |
|---|---|
| Domains | Robotics, Simulation |
| Last Updated | 2026-02-15 08:00 GMT |
Overview
Concrete PD joint position controller that sets joint drive targets based on absolute or delta position actions, serving as the default and most fundamental controller in ManiSkill.
Description
PDJointPosController extends BaseController to implement proportional-derivative (PD) joint position control. On each set_action() call, it computes target joint positions from the action (either absolute positions or deltas from the current or virtual target position), then sets these as joint drive targets on the articulation. It supports configurable stiffness, damping, force limits, friction, and drive mode per joint. Optional linear interpolation smoothly distributes the position change across simulation sub-steps. The action space is derived from joint limits, optionally overridden by config bounds. PDJointPosMimicController extends this to handle mechanically coupled (mimic) joints where one control joint drives one or more mimic joints via the equation q_mimic = q_control * multiplier + offset, reducing the effective action dimensionality.
Usage
This is the default controller for all robots in ManiSkill. Use PDJointPosControllerConfig for direct joint position control. Use PDJointPosMimicControllerConfig for robots with mechanically coupled joints (e.g., parallel grippers where both fingers follow a single control input).
Code Reference
Source Location
- Repository: Haosulab_ManiSkill
- File: mani_skill/agents/controllers/pd_joint_pos.py
- Lines: 1-259
Signature
class PDJointPosController(BaseController):
config: "PDJointPosControllerConfig"
_start_qpos = None
_target_qpos = None
sets_target_qpos = True
sets_target_qvel = False
@dataclass
class PDJointPosControllerConfig(ControllerConfig):
lower: Union[None, float, Sequence[float]]
upper: Union[None, float, Sequence[float]]
stiffness: Union[float, Sequence[float]]
damping: Union[float, Sequence[float]]
force_limit: Union[float, Sequence[float]] = 1e10
friction: Union[float, Sequence[float]] = 0.0
use_delta: bool = False
use_target: bool = False
interpolate: bool = False
normalize_action: bool = True
drive_mode: Union[Sequence[DriveMode], DriveMode] = "force"
controller_cls = PDJointPosController
class PDJointPosMimicController(PDJointPosController):
config: "PDJointPosMimicControllerConfig"
@dataclass
class PDJointPosMimicControllerConfig(PDJointPosControllerConfig):
controller_cls = PDJointPosMimicController
mimic: dict[str, dict[str, float]] = field(default_factory=dict)
Import
from mani_skill.agents.controllers.pd_joint_pos import (
PDJointPosController,
PDJointPosControllerConfig,
PDJointPosMimicController,
PDJointPosMimicControllerConfig,
)
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| lower | None, float, or Sequence[float] | Yes | Lower joint position limit. If None, uses the articulation's built-in limits. |
| upper | None, float, or Sequence[float] | Yes | Upper joint position limit. If None, uses the articulation's built-in limits. |
| stiffness | float or Sequence[float] | Yes | PD proportional gain (stiffness) for joint drives. |
| damping | float or Sequence[float] | Yes | PD derivative gain (damping) for joint drives. |
| force_limit | float or Sequence[float] | No | Maximum force the drive can exert. Defaults to 1e10. |
| friction | float or Sequence[float] | No | Joint friction coefficient. Defaults to 0.0. |
| use_delta | bool | No | If True, actions are delta offsets from current (or target) position. Defaults to False. |
| use_target | bool | No | If True, delta actions accumulate on a virtual target. Defaults to False. |
| interpolate | bool | No | If True, linearly interpolates between start and target qpos over simulation steps. Defaults to False. |
| normalize_action | bool | No | If True, normalizes the action space to [-1, 1]. Defaults to True. |
| mimic | dict | No | (Mimic only) Maps mimic joint name to dict(joint=str, multiplier=float, offset=float).
|
Outputs
| Name | Type | Description |
|---|---|---|
| _target_qpos | torch.Tensor | The computed target joint positions set as drive targets. |
| get_state() | dict | Returns {"target_qpos": Tensor} when use_target=True, empty dict otherwise.
|
| action_space | spaces.Box | Box action space bounded by joint limits (or config overrides), optionally normalized. |
Usage Examples
Basic Usage
from mani_skill.agents.controllers.pd_joint_pos import PDJointPosControllerConfig
# Absolute position control with joint limits from the URDF
config_abs = PDJointPosControllerConfig(
joint_names=["joint1", "joint2", "joint3"],
lower=None,
upper=None,
stiffness=100,
damping=10,
normalize_action=False,
)
# Delta position control with normalized actions in [-1, 1]
config_delta = PDJointPosControllerConfig(
joint_names=["joint1", "joint2", "joint3"],
lower=-0.1,
upper=0.1,
stiffness=100,
damping=10,
use_delta=True,
normalize_action=True,
)