SRSSolver#
SRSSolver is a high-performance inverse kinematics (IK) solver specifically designed for 7-DOF manipulators with a Spherical-Rotational-Spherical (S-R-S) joint structure. This architecture is common in anthropomorphic and redundant industrial arms, providing high dexterity and redundancy for advanced manipulation tasks. SRSSolver supports batch computation, joint limits, GPU acceleration, and seamless integration with PyTorch workflows.
What is S-R-S Kinematics?#
The S-R-S (Spherical-Rotational-Spherical) structure refers to a 7-joint manipulator arrangement:
Spherical (S): A 3-DOF spherical joint (often realized by three intersecting revolute joints), enabling arbitrary orientation in 3D space.
Rotational (R): A single revolute joint, typically located at the “elbow, “ providing an extra degree of freedom for redundancy.
Spherical (S): Another 3-DOF spherical joint at the wrist, allowing full orientation control of the end-effector.
This structure enables:
Redundancy: The arm can reach the same pose with multiple joint configurations, useful for obstacle avoidance and singularity avoidance.
High Dexterity: Suitable for tasks requiring complex manipulation and orientation.
Wide Application: Common in humanoid robots and collaborative arms.
Key Features#
Optimized for S-R-S 7-DOF kinematic chains
Supports position and orientation constraints, joint limits
Batch sampling and multi-solution output for robust IK
GPU acceleration for large-scale or real-time applications
Flexible configuration for DH parameters, joint limits, link lengths, and more
Configuration#
SRSSolver is configured via the SRSSolverCfg class, allowing detailed control over kinematic parameters and solver behavior.
from embodichain.data import get_data_path
from embodichain.lab.sim.robots.dexforce_w1.types import (
DexforceW1ArmSide,
DexforceW1ArmKind,
DexforceW1Version,
)
from embodichain.lab.sim.robots.dexforce_w1.params import (
W1ArmKineParams,
)
from embodichain.lab.sim.solvers.srs_solver import SRSSolver, SRSSolverCfg
arm_params = W1ArmKineParams(
arm_side=DexforceW1ArmSide.RIGHT,
arm_kind=DexforceW1ArmKind.ANTHROPOMORPHIC,
version=DexforceW1Version.V021,
)
cfg = SRSSolverCfg(
urdf_path=get_data_path("DexforceW1V021/DexforceW1_v02_1.urdf"),
joint_names=[f"{'RIGHT'}_J{i+1}" for i in range(7)],
end_link_name="left_ee",
root_link_name="left_arm_base",
dh_params=arm_params.dh_params,
qpos_limits=arm_params.qpos_limits,
T_e_oe=arm_params.T_e_oe,
T_b_ob=arm_params.T_b_ob,
link_lengths=arm_params.link_lengths,
rotation_directions=arm_params.rotation_directions,
)
solver = SRSSolver(cfg, num_envs=1, device="cuda")
Main Methods#
get_fk(self, qpos: torch.Tensor) -> torch.Tensor
Computes the end-effector pose (homogeneous transformation matrix) for the given joint positions.Parameters:
qpos(torch.Tensororlist[float]): Joint positions, shape(num_envs, num_joints)or(num_joints,).
Returns:
torch.Tensor: End-effector pose(s), shape(num_envs, 4, 4).
Example:
fk = solver.get_fk(qpos=[0.0, 0.0, 0.0, 1.5708, 0.0, 0.0, 0.0])
print(fk)
# Output:
# tensor([[[ 0.0, -1.0, 0.0, 0.0],
# [ 0.0, 0.0, -1.0, -0.33],
# [ 1.0, 0.0, 0.0, 0.3625],
# [ 0.0, 0.0, 0.0, 1.0]]])
get_ik(self, target_xpos: torch.Tensor, qpos_seed: torch.Tensor = None, return_all_solutions: bool = False, jacobian: torch.Tensor = None) -> Tuple[torch.Tensor, torch.Tensor]
Computes joint positions (inverse kinematics) for the given target end-effector pose.Parameters:
target_xpos(torch.Tensor): Target end-effector pose(s), shape(num_envs, 4, 4).qpos_seed(torch.Tensor, optional): Initial guess for joint positions, shape(num_envs, num_joints). IfNone, a default is used.return_all_solutions(bool, optional): IfTrue, returns all possible solutions. Default isFalse.jacobian(torch.Tensor, optional): Custom Jacobian. Usually not required.
Returns:
Tuple[torch.Tensor, torch.Tensor]:First element: Joint positions, shape
(num_envs, num_joints).Second element: Convergence info or error for each environment.
Example:
import torch
xpos = torch.tensor([[[ 0.0, -1.0, 0.0, -0.0],
[ 0.0, 0.0, -1.0, -0.33],
[ 1.0, 0.0, 0.0, 0.3625],
[ 0.0, 0.0, 0.0, 1.0]]])
qpos_seed = torch.zeros((1, 7))
qpos_sol, info = solver.get_ik(target_xpos=xpos)
print("IK solution:", qpos_sol)
print("Convergence info:", info)
# IK solution: tensor([True], device='cuda:0')
# Convergence info: tensor([[[-0.022269, 0.045214, -0.022273, -1.570796, 0.045204, -0.001007, 0.044519]]], device='cuda:0')
References#
The following key references provide the theoretical foundation and algorithmic background for this implementation:
Analytical Inverse Kinematic Computation for 7-DOF Redundant Manipulators With Joint Limits and Its Application to Redundancy Resolution
Masayuki Shimizu, Hiromu Kakuya, Woo-Keun Yoon, Kosei Kitagaki, Kazuhiro Kosuge
IEEE Transactions on Robotics, 2008
DOI: 10.1109/TRO.2008.2003266
This paper presents an analytical approach for solving the inverse kinematics of 7-DOF redundant manipulators, including joint limit handling and redundancy resolution strategies.Position-based kinematics for 7-DoF serial manipulators with global configuration control, joint limit, and singularity avoidance
Carlos Faria, Flora Ferreira, Wolfram Erlhagen, Sérgio Monteiro, Estela Bicho
Mechanism and Machine Theory, 2018
DOI: 10.1016/j.mechmachtheory.2017.10.025
This work introduces position-based kinematic algorithms for 7-DOF manipulators, focusing on global configuration control, joint limit enforcement, and singularity avoidance.
These publications provide the mathematical models and solution strategies that underpin the SRSSolver’s design and functionality.