Implementation:ARISE Initiative Robosuite IKController
| Knowledge Sources | |
|---|---|
| Domains | Robotics, Control |
| Last Updated | 2026-02-15 07:00 GMT |
Overview
Concrete tool for controlling a robot arm end effector via inverse kinematics provided by robosuite.
Description
The InverseKinematicsController class provides position and orientation control of a robot arm's end effector using differential inverse kinematics with posture control in the null space. It extends the JointPositionController base class, converting desired Cartesian-space (position + orientation) commands into joint-space position targets which are then tracked by the underlying joint position impedance controller.
The controller uses a damped least-squares (pseudoinverse) approach to solve for joint velocity updates from a 6-DOF twist error (3 translational + 3 rotational). The null space of the Jacobian is used for posture control, biasing the solution toward the robot's initial (rest) joint configuration. This prevents drift in the joint space while achieving the desired end-effector pose. The implementation references the mjctrl library by Kevin Zakka for the differential IK formulation.
IK control is only supported for a limited set of robots: Baxter, Sawyer, Panda, and GR1FixedLowerBody. The controller also supports multi-site IK for robots with multiple end effectors, using the IKSolver utility for the multi-site case. Control input actions are assumed to be relative to the current end effector pose, formatted as (x_dpos, y_dpos, z_dpos, x_rot, y_rot, z_rot) where positions are in the MuJoCo world frame and rotations are in the end effector frame.
Usage
Use the InverseKinematicsController when you need intuitive task-space control of a robot arm's end effector position and orientation in robosuite environments. It is most appropriate for teleoperation scenarios, scripted manipulation policies, or any case where the desired control input is naturally expressed as Cartesian displacements and rotations rather than joint-level commands. It is instantiated through the controller factory with the name "IK_POSE".
Code Reference
Source Location
- Repository: ARISE_Initiative_Robosuite
- File: robosuite/controllers/parts/arm/ik.py
- Lines: 1-584
Signature
class InverseKinematicsController(JointPositionController):
def __init__(
self,
sim,
ref_name: Union[List[str], str],
joint_indexes,
robot_name,
actuator_range,
eef_rot_offset=None,
bullet_server_id=0,
policy_freq=20,
load_urdf=True,
ik_pos_limit=None,
ik_ori_limit=None,
interpolator_pos=None,
interpolator_ori=None,
converge_steps=5,
kp: int = 100,
kv: int = 10,
control_delta: bool = True,
**kwargs,
): ...
def get_control(self, dpos=None, rotation=None, update_targets=False) -> np.array: ...
@staticmethod
def compute_joint_positions(
sim, initial_joint, joint_indices, ref_name, control_freq,
velocity_limits=None, use_delta=True, dpos=None, drot=None,
Kn=None, damping_pseudo_inv=0.05, Kpos=0.95, Kori=0.95,
jac=None, joint_names=None, nullspace_joint_weights=None,
integration_dt=0.1, damping=5e-1, max_dq=4,
) -> np.ndarray: ...
def set_goal(self, delta, set_ik=None): ...
def run_controller(self) -> np.array: ...
def update_initial_joints(self, initial_joints): ...
def reset_goal(self): ...
@property
def control_limits(self) -> tuple: ...
@property
def name(self) -> str: ... # Returns "IK_POSE"
Import
from robosuite.controllers.parts.arm.ik import InverseKinematicsController
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| sim | MjSim | Yes | MuJoCo simulator instance the controller reads robot state from |
| ref_name | Union[List[str], str] | Yes | Name(s) of controlled robot arm end effector site(s) from the robot XML |
| joint_indexes | dict | Yes | Dictionary with keys 'joints', 'qpos', 'qvel' mapping to lists of simulation indexes
|
| robot_name | str | Yes | Name of the robot being controlled. Must be one of {"Baxter", "Sawyer", "Panda", "GR1FixedLowerBody"}
|
| actuator_range | 2-tuple of array | Yes | (low, high) arrays representing joint actuator torque limits |
| eef_rot_offset | array (4,) | No | Quaternion (x,y,z,w) rotational offset between final link and end effector frames |
| policy_freq | int | No | Frequency at which policy actions are provided (default: 20) |
| ik_pos_limit | float | No | Maximum positional displacement magnitude in meters per step |
| ik_ori_limit | float | No | Maximum orientation displacement magnitude in radians per step |
| interpolator_pos | Interpolator | No | Interpolator for smoothing position commands between action steps |
| interpolator_ori | Interpolator | No | Interpolator for smoothing orientation commands between action steps |
| converge_steps | int | No | Number of IK solver iterations for convergence (default: 5) |
| kp | int | No | Proportional gain for the underlying joint position controller (default: 100) |
| kv | int | No | Derivative gain for the underlying joint position controller (default: 10) |
| control_delta | bool | No | If True, actions are treated as deltas relative to current pose (default: True) |
Outputs
| Name | Type | Description |
|---|---|---|
| torques | np.array | Joint torques computed by the underlying position controller to track the IK-derived joint positions |
| name | str | Controller identifier string: "IK_POSE"
|
| control_limits | tuple(np.array, np.array) | (min, max) action limits based on ik_pos_limit and ik_ori_limit
|
Usage Examples
# Typical usage via the controller factory (recommended approach)
from robosuite.controllers.parts.controller_factory import arm_controller_factory
controller_params = {
"sim": sim,
"ref_name": "gripper0_grip_site",
"joint_indexes": {
"joints": [0, 1, 2, 3, 4, 5, 6],
"qpos": [0, 1, 2, 3, 4, 5, 6],
"qvel": [0, 1, 2, 3, 4, 5, 6],
},
"robot_name": "Panda",
"actuator_range": (np.array([-87]*7), np.array([87]*7)),
"policy_freq": 20,
"ik_pos_limit": 0.05,
"ik_ori_limit": 0.05,
"ndim": 7,
"interpolation": None,
"ramp_ratio": 0.2,
}
controller = arm_controller_factory("IK_POSE", controller_params)
# Set a delta goal: move +0.01 in x, no rotation
action = np.array([0.01, 0.0, 0.0, 0.0, 0.0, 0.0])
controller.set_goal(action)
# Compute torques for the current timestep
torques = controller.run_controller()
Related Pages
- Principle:ARISE_Initiative_Robosuite_Inverse_Kinematics_Control
- Environment:ARISE_Initiative_Robosuite_MuJoCo_Python
- Implementation:ARISE_Initiative_Robosuite_JointPositionController
- Implementation:ARISE_Initiative_Robosuite_Controller_Base
- Implementation:ARISE_Initiative_Robosuite_Controller_Factory