Implementation:Isaac sim IsaacGymEnvs Factory Control Algorithms
| Knowledge Sources | |
|---|---|
| Domains | Robotics, Control |
| Last Updated | 2026-02-15 00:00 GMT |
Overview
Stateless control functions that convert task-space targets from the RL policy into joint-space position targets or joint torques for the Franka robot.
Description
The factory_control module provides three core functions. compute_dof_pos_target() handles position-based controllers (joint_space_ik) by computing joint position targets via IK. compute_dof_torque() handles torque-based controllers (joint_space_id, task_space_impedance, operational_space_motion, open_loop_force, closed_loop_force, hybrid_force_motion) by computing joint torques. get_pose_error() is a shared utility that computes position and orientation errors between the current fingertip pose and the target pose.
All functions are stateless and operate on batched tensors, processing all environments in parallel on the GPU.
Usage
Use these functions in the pre_physics_step() method of any Factory or IndustReal task to convert RL policy outputs into robot commands. The controller type is selected via cfg_task.ctrl.controller_type.
Code Reference
Source Location
- Repository: IsaacGymEnvs
- File: isaacgymenvs/tasks/factory/factory_control.py, Lines 41-330
Signature
Position Target Computation
def compute_dof_pos_target(
cfg_ctrl,
arm_dof_pos,
fingertip_midpoint_pos,
fingertip_midpoint_quat,
jacobian,
ctrl_target_fingertip_midpoint_pos,
ctrl_target_fingertip_midpoint_quat,
ctrl_target_gripper_dof_pos,
device
):
"""Compute joint position targets using IK.
Supports controller_type: joint_space_ik
IK methods: 'dls' (damped least squares), 'trans' (pseudoinverse)
Returns:
dof_pos_target: Joint position targets [num_envs, num_dofs]
"""
Torque Computation
def compute_dof_torque(
cfg_ctrl,
dof_pos,
dof_vel,
fingertip_midpoint_pos,
fingertip_midpoint_quat,
fingertip_midpoint_linvel,
fingertip_midpoint_angvel,
left_finger_force,
right_finger_force,
jacobian,
arm_mass_matrix,
ctrl_target_gripper_dof_pos,
ctrl_target_fingertip_midpoint_pos,
ctrl_target_fingertip_midpoint_quat,
ctrl_target_fingertip_contact_wrench,
device
):
"""Compute joint torques for torque-based controllers.
Supports controller_type: joint_space_id, task_space_impedance,
operational_space_motion, open_loop_force, closed_loop_force,
hybrid_force_motion
Returns:
dof_torque: Joint torques [num_envs, num_dofs]
"""
Pose Error Utility
def get_pose_error(
fingertip_midpoint_pos,
fingertip_midpoint_quat,
ctrl_target_fingertip_midpoint_pos,
ctrl_target_fingertip_midpoint_quat,
jacobian_type,
rot_error_type
):
"""Compute position and orientation error between current and target poses.
Args:
jacobian_type: 'geometric' or 'analytic'
rot_error_type: 'axis_angle' or 'quat'
Returns:
pos_error: Position error [num_envs, 3]
rot_error: Orientation error [num_envs, 3]
"""
Import
from isaacgymenvs.tasks.factory import factory_control
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| cfg_ctrl | DictConfig | Yes | Controller configuration (controller_type, gains, jacobian_type) |
| arm_dof_pos | torch.Tensor | Yes | Current arm joint positions [num_envs, 7]
|
| dof_pos | torch.Tensor | Yes (torque) | Full DOF positions [num_envs, num_dofs]
|
| dof_vel | torch.Tensor | Yes (torque) | Full DOF velocities [num_envs, num_dofs]
|
| fingertip_midpoint_pos | torch.Tensor | Yes | Current fingertip position [num_envs, 3]
|
| fingertip_midpoint_quat | torch.Tensor | Yes | Current fingertip quaternion [num_envs, 4]
|
| jacobian | torch.Tensor | Yes | Franka Jacobian [num_envs, 6, num_dofs]
|
| arm_mass_matrix | torch.Tensor | Yes (torque) | Arm mass matrix [num_envs, 7, 7]
|
| ctrl_target_fingertip_midpoint_pos | torch.Tensor | Yes | Target fingertip position from RL [num_envs, 3]
|
| ctrl_target_fingertip_midpoint_quat | torch.Tensor | Yes | Target fingertip quaternion from RL [num_envs, 4]
|
| ctrl_target_gripper_dof_pos | torch.Tensor | Yes | Target gripper joint positions [num_envs, 2]
|
| ctrl_target_fingertip_contact_wrench | torch.Tensor | Conditional | Desired contact wrench for force controllers [num_envs, 6]
|
| device | str | Yes | Torch device string |
Outputs
| Name | Type | Description |
|---|---|---|
| dof_pos_target | torch.Tensor | Joint position targets for position controllers [num_envs, num_dofs]
|
| dof_torque | torch.Tensor | Joint torques for torque controllers [num_envs, num_dofs]
|
| pos_error | torch.Tensor | Position error [num_envs, 3]
|
| rot_error | torch.Tensor | Orientation error [num_envs, 3]
|
Controller Type Reference
| Controller Type | Function | Output | IK Method | Use Case |
|---|---|---|---|---|
joint_space_ik |
compute_dof_pos_target |
Joint positions | dls / trans | Default for position-controlled tasks |
joint_space_id |
compute_dof_torque |
Joint torques | N/A | Torque-controlled robots |
task_space_impedance |
compute_dof_torque |
Joint torques | N/A | Compliant contact tasks |
operational_space_motion |
compute_dof_torque |
Joint torques | N/A | Redundant manipulator control |
open_loop_force |
compute_dof_torque |
Joint torques | N/A | Force-controlled insertion |
closed_loop_force |
compute_dof_torque |
Joint torques | N/A | Precise force regulation |
hybrid_force_motion |
compute_dof_torque |
Joint torques | N/A | Assembly with directional force/motion split |
Usage Examples
Position Control with IK
from isaacgymenvs.tasks.factory import factory_control
# In pre_physics_step():
dof_pos_target = factory_control.compute_dof_pos_target(
cfg_ctrl=self.cfg_task.ctrl,
arm_dof_pos=self.arm_dof_pos,
fingertip_midpoint_pos=self.fingertip_midpoint_pos,
fingertip_midpoint_quat=self.fingertip_midpoint_quat,
jacobian=self.fingertip_midpoint_jacobian,
ctrl_target_fingertip_midpoint_pos=self.ctrl_target_fingertip_midpoint_pos,
ctrl_target_fingertip_midpoint_quat=self.ctrl_target_fingertip_midpoint_quat,
ctrl_target_gripper_dof_pos=self.ctrl_target_gripper_dof_pos,
device=self.device,
)
self.gym.set_dof_position_target_tensor(self.sim, gymtorch.unwrap_tensor(dof_pos_target))
Torque Control with Impedance
# With cfg_task.ctrl.controller_type = "task_space_impedance"
dof_torque = factory_control.compute_dof_torque(
cfg_ctrl=self.cfg_task.ctrl,
dof_pos=self.dof_pos,
dof_vel=self.dof_vel,
fingertip_midpoint_pos=self.fingertip_midpoint_pos,
fingertip_midpoint_quat=self.fingertip_midpoint_quat,
fingertip_midpoint_linvel=self.fingertip_midpoint_linvel,
fingertip_midpoint_angvel=self.fingertip_midpoint_angvel,
left_finger_force=self.left_finger_force,
right_finger_force=self.right_finger_force,
jacobian=self.fingertip_midpoint_jacobian,
arm_mass_matrix=self.arm_mass_matrix,
ctrl_target_gripper_dof_pos=self.ctrl_target_gripper_dof_pos,
ctrl_target_fingertip_midpoint_pos=self.ctrl_target_fingertip_midpoint_pos,
ctrl_target_fingertip_midpoint_quat=self.ctrl_target_fingertip_midpoint_quat,
ctrl_target_fingertip_contact_wrench=self.ctrl_target_fingertip_contact_wrench,
device=self.device,
)
self.gym.set_dof_actuation_force_tensor(self.sim, gymtorch.unwrap_tensor(dof_torque))