URDF Processor API Referenceο
This page documents ManipulaPy.urdf_processor, the module for URDF (Unified Robot Description Format) processing and conversion to ManipulaPy objects.
Tip
For conceptual explanations, see URDF Processor User Guide.
URDFToSerialManipulator Classο
- class ManipulaPy.urdf_processor.URDFToSerialManipulator(urdf_name, use_pybullet_limits=False, backend='builtin', load_meshes=False, validate=False)[source]ο
Bases:
objectA class to convert URDF files to SerialManipulator objects and simulate them using PyBullet.
- Supports multiple URDF parser backends:
βbuiltinβ: Native ManipulaPy parser (NumPy 2.0 compatible, default)
βurchinβ: Legacy urchin parser (requires urchin, not NumPy 2.0 compatible)
βpybulletβ: PyBullet-based parser (requires pybullet)
- Features:
Direct conversion to SerialManipulator and ManipulatorDynamics
Forward kinematics (single and batch)
URDF validation
Optional PyBullet joint limit extraction
Visualization and animation
Example
>>> processor = URDFToSerialManipulator("robot.urdf") >>> manipulator = processor.serial_manipulator >>> T_ee = manipulator.forward_kinematics([0, 0, 0, 0, 0, 0])
>>> # Batch FK for trajectory >>> configs = np.random.uniform(-np.pi, np.pi, (100, 6)) >>> transforms = processor.batch_forward_kinematics(configs)
Converts URDF files to SerialManipulator and ManipulatorDynamics objects with PyBullet integration.
Constructor
- Parameters:
- __init__(urdf_name, use_pybullet_limits=False, backend='builtin', load_meshes=False, validate=False)[source]ο
Initializes the object with the given urdf_name.
- Parameters:
urdf_name (str | Path) β Path to the URDF file.
use_pybullet_limits (bool) β Whether to override URDF limits with PyBulletβs. Default False (use URDF limits directly).
backend (str) β Parser backend - βbuiltinβ (default), βurchinβ, or βpybulletβ
load_meshes (bool) β Whether to load mesh geometry. Default False.
validate (bool) β Whether to validate URDF structure. Default False.
Parameters:
urdf_name (str) β Path to the URDF file
use_pybullet_limits (bool) β Override URDF joint limits with PyBullet values (default: True)
Process:
Load URDF using urchin library
Extract kinematic and dynamic parameters
Optionally retrieve joint limits from PyBullet
Create SerialManipulator and ManipulatorDynamics objects
Attributes Created:
urdf_name (str) β Path to URDF file
robot (urchin.URDF) β Loaded URDF object
robot_data (dict) β Extracted robot parameters
serial_manipulator (SerialManipulator) β Kinematics object
dynamics (ManipulatorDynamics) β Dynamics object
URDF Processing
- load_urdf(urdf_name)[source]ο
Load the URDF file and extract the necessary info for the robot model.
DEPRECATED: Use _extract_robot_data() instead. This method is kept for backward compatibility but now delegates to the native parser.
- Parameters:
urdf_name (str) β Path to URDF file (ignored, uses self.robot)
- Returns:
Robot kinematic/dynamic parameters
- Return type:
Parameters:
urdf_name (str) β Path to the URDF file
Returns:
robot_data (dict) β Dictionary containing:
M (numpy.ndarray) β Home configuration matrix (4Γ4)
Slist (numpy.ndarray) β Space frame screw axes (6Γn)
Blist (numpy.ndarray) β Body frame screw axes (6Γn)
Glist (list) β Spatial inertia matrices (6Γ6 each)
actuated_joints_num (int) β Number of actuated joints
Process:
Extract joint positions and rotation axes
Build spatial inertia matrices from link properties
Compute screw axes using Product of Exponentials
Generate body frame screw axes via adjoint transformation
- _get_joint_limits_from_pybullet()[source]ο
Connect to PyBullet (in DIRECT mode, so no GUI), load the URDF, and retrieve per-joint limits for all revolute joints.
- Returns:
List of (lower, upper) tuples in the order they appear as revolute in the URDF.
- Raises:
RuntimeError β If PyBullet is not available.
- Return type:
Returns:
joint_limits (list) β List of (lower, upper) tuples for each revolute joint
Process:
Connect to PyBullet in DIRECT mode (no GUI)
Load URDF into PyBullet simulation
Extract joint limits for all revolute joints
Handle continuous joints with (-Ο, Ο) defaults
Disconnect from PyBullet
Note: Only processes revolute joints, ignoring fixed and other joint types.
Object Initialization
- initialize_serial_manipulator()[source]ο
Initializes a SerialManipulator object using the extracted URDF data. Overwrites the example joint limits with PyBullet-based ones if available.
Returns:
manipulator (SerialManipulator) β Configured kinematics object
Configuration:
Uses extracted URDF parameters (M, S_list, B_list)
Applies joint limits from PyBullet or defaults
Computes omega_list from screw axes
- Return type:
- initialize_manipulator_dynamics()[source]ο
Initializes the ManipulatorDynamics object using the extracted URDF data.
Returns:
dynamics (ManipulatorDynamics) β Configured dynamics object
Configuration:
Inherits from SerialManipulator for kinematics
Uses spatial inertia matrices (Glist) from URDF
Extracts r_list from space frame screw axes
Visualization
- visualize_robot(cfg=None)[source]ο
Visualizes the URDF model.
- Parameters:
cfg β Optional joint configuration (array or dict)
Purpose: Display static robot model using matplotlib visualization from urchin library.
Usage: Interactive 3D visualization with rotation and zoom capabilities.
- visualize_trajectory(cfg_trajectory=None, loop_time=3.0, use_collision=False)[source]ο
Animate robot along a trajectory.
- Parameters:
cfg_trajectory β Joint trajectories as (N, DOF) array or dict {joint_name: array}
loop_time β Animation duration in seconds
use_collision β Use collision geometry instead of visual
Parameters:
cfg_trajectory (numpy.ndarray or dict, optional) β Joint configurations over time
loop_time (float) β Animation duration in seconds (default: 3.0)
use_collision (bool) β Enable collision visualization (default: False)
Trajectory Formats:
NumPy array: Shape (n_timesteps, n_joints) with joint angles
Dictionary: {joint_name: [anglesβ¦]} mapping joint names to angle sequences
None: Uses default motion from 0 to Ο/2 for all joints
Features:
Smooth animation between waypoints
Collision geometry visualization
Configurable playback speed
Utilities
- print_joint_info()[source]ο
Returns the joint names instead of printing them to console.
- Returns:
Contains βnum_jointsβ and βjoint_namesβ
- Return type:
Returns:
joint_info (dict) β Dictionary containing:
num_joints (int) β Total number of joints
joint_names (list) β Names of all joints in order
Purpose: Inspect joint structure without console output.
Static Utility Methods
- static transform_to_xyz(T)[source]ο
Extracts the XYZ position from a 4x4 transformation matrix. Returns a 3-element NumPy array (x, y, z).
- static get_link(robot, link_name)[source]ο
Given a robot URDF and a link name, returns the link associated with that name. Returns None if not found.
- Parameters:
robot (URDF) β
link_name (str) β
- static w_p_to_slist(w, p, robot_dof)[source]ο
Convert angular velocity (w) and position (p) vectors into screw axes (Slist). Slist has shape (6, robot_dof).
- load_urdf(urdf_name)[source]ο
Load the URDF file and extract the necessary info for the robot model.
DEPRECATED: Use _extract_robot_data() instead. This method is kept for backward compatibility but now delegates to the native parser.
- initialize_serial_manipulator()[source]ο
Initializes a SerialManipulator object using the extracted URDF data. Overwrites the example joint limits with PyBullet-based ones if available.
- Return type:
- initialize_manipulator_dynamics()[source]ο
Initializes the ManipulatorDynamics object using the extracted URDF data.
- visualize_robot(cfg=None)[source]ο
Visualizes the URDF model.
- Parameters:
cfg β Optional joint configuration (array or dict)
- visualize_trajectory(cfg_trajectory=None, loop_time=3.0, use_collision=False)[source]ο
Animate robot along a trajectory.
- Parameters:
cfg_trajectory β Joint trajectories as (N, DOF) array or dict {joint_name: array}
loop_time β Animation duration in seconds
use_collision β Use collision geometry instead of visual
- print_joint_info()[source]ο
Returns the joint names instead of printing them to console.
- Returns:
Contains βnum_jointsβ and βjoint_namesβ
- Return type:
- get_serial_manipulator()[source]ο
Get SerialManipulator directly from native URDF parser.
This is a convenience method that uses the native parserβs to_serial_manipulator() method directly.
- Returns:
SerialManipulator instance
- Return type:
- get_manipulator_dynamics()[source]ο
Get ManipulatorDynamics directly from native URDF parser.
This is a convenience method that uses the native parserβs to_manipulator_dynamics() method directly.
- Returns:
ManipulatorDynamics instance
- Return type:
- forward_kinematics(cfg, frame='space')[source]ο
Compute forward kinematics using SerialManipulator.
- link_fk(cfg=None, use_names=True)[source]ο
Compute forward kinematics for all links using native URDF parser.
This is faster for getting transforms of all links, not just end-effector.
- batch_forward_kinematics(cfgs, link_name=None)[source]ο
Compute forward kinematics for multiple configurations (vectorized).
This is 50x+ faster than calling forward_kinematics in a loop.
- Parameters:
- Returns:
(N, 4, 4) array of transforms If link_name is None: Dict mapping link names to (N, 4, 4) arrays
- Return type:
If link_name is provided
Example
>>> configs = np.random.uniform(-np.pi, np.pi, (100, 6)) >>> ee_transforms = processor.batch_forward_kinematics(configs, "ee_link") >>> all_transforms = processor.batch_forward_kinematics(configs)
- get_end_effector_transforms(cfgs)[source]ο
Get end-effector transforms for multiple configurations.
Convenience method for batch FK of end-effector only.
- inverse_kinematics(T_desired, initial_guess=None, method='robust', **kwargs)[source]ο
Compute inverse kinematics to reach desired pose.
- Parameters:
- Returns:
Tuple of (theta, success, iterations)
- Return type:
- property joint_limits_array: ndarrayο
Joint limits as (N, 2) array.
- Returns:
, 0] is lower and [:, 1] is upper
- Return type:
Array with shape (num_dofs, 2) where [
- create_modifier()[source]ο
Create a URDFModifier for calibration and payload simulation.
The modifier creates a deep copy of the URDF, so modifications donβt affect the original robot.
- Returns:
URDFModifier instance
- Return type:
URDFModifier
Example
>>> modifier = processor.create_modifier() >>> modifier.offset_joint_zero("joint1", 0.01) >>> modifier.add_payload("ee_link", mass=1.0, com=[0, 0, 0.1]) >>> calibrated_robot = modifier.urdf
Usage Examplesο
Basic URDF Loading:
from ManipulaPy.urdf_processor import URDFToSerialManipulator
# Load robot from URDF
processor = URDFToSerialManipulator("robot.urdf")
# Access created objects
robot = processor.serial_manipulator
dynamics = processor.dynamics
print(f"Robot has {len(robot.joint_limits)} joints")
Using Built-in Robot Models:
from ManipulaPy.ManipulaPy_data.xarm import urdf_file as xarm_urdf
# Load xArm robot
processor = URDFToSerialManipulator(xarm_urdf)
# Perform forward kinematics
joint_angles = [0.1, 0.2, 0.3, 0, 0, 0]
T = processor.serial_manipulator.forward_kinematics(joint_angles)
Joint Limits Configuration:
# Use PyBullet joint limits (default)
processor_pb = URDFToSerialManipulator("robot.urdf", use_pybullet_limits=True)
# Use default limits (-Ο, Ο)
processor_default = URDFToSerialManipulator("robot.urdf", use_pybullet_limits=False)
# Compare joint limits
print("PyBullet limits:", processor_pb.serial_manipulator.joint_limits)
print("Default limits:", processor_default.serial_manipulator.joint_limits)
Robot Visualization:
# Static robot visualization
processor.visualize_robot()
# Trajectory animation with numpy array
import numpy as np
# Create trajectory: 100 timesteps, smooth motion
n_steps = 100
n_joints = len(processor.serial_manipulator.joint_limits)
trajectory = np.zeros((n_steps, n_joints))
for i in range(n_joints):
trajectory[:, i] = np.linspace(0, np.pi/3, n_steps)
processor.visualize_trajectory(
cfg_trajectory=trajectory,
loop_time=5.0,
use_collision=True
)
Trajectory Animation with Dictionary:
# Get joint names
joint_info = processor.print_joint_info()
joint_names = joint_info["joint_names"]
# Create trajectory dictionary
trajectory_dict = {}
for joint_name in joint_names:
if "joint" in joint_name.lower(): # Filter actuated joints
trajectory_dict[joint_name] = [0, np.pi/4, np.pi/2, np.pi/4, 0]
processor.visualize_trajectory(trajectory_dict, loop_time=4.0)
Extracting Robot Parameters:
# Access raw URDF data
robot_data = processor.robot_data
print(f"Home configuration:\n{robot_data['M']}")
print(f"Number of DOF: {robot_data['actuated_joints_num']}")
print(f"Screw axes shape: {robot_data['Slist'].shape}")
# Access inertia matrices
for i, G in enumerate(robot_data['Glist']):
print(f"Link {i} inertia:\n{G}")
Integration with Kinematics and Dynamics:
# Complete workflow example
processor = URDFToSerialManipulator("robot.urdf")
# Kinematics
joint_angles = [0.5, -0.3, 0.8, 0.1, -0.2, 0.4]
T = processor.serial_manipulator.forward_kinematics(joint_angles)
J = processor.serial_manipulator.jacobian(joint_angles)
# Dynamics
joint_velocities = [0.1, 0.2, 0.0, 0.0, 0.0, 0.0]
joint_accelerations = [1.0, 0.5, 0.0, 0.0, 0.0, 0.0]
torques = processor.dynamics.inverse_dynamics(
joint_angles, joint_velocities, joint_accelerations,
g=[0, 0, -9.81], Ftip=[0, 0, 0, 0, 0, 0]
)
print(f"Required torques: {torques}")
Custom URDF Processing:
# Access raw urchin URDF object
urdf_obj = processor.robot
# Inspect URDF structure
print(f"Robot name: {urdf_obj.name}")
print(f"Links: {[link.name for link in urdf_obj.links]}")
print(f"Joints: {[joint.name for joint in urdf_obj.joints]}")
# Get link-wise forward kinematics
link_transforms = urdf_obj.link_fk()
for link_name, transform in link_transforms.items():
print(f"{link_name}: {transform[:3, 3]}") # Position only
Error Handling:
try:
processor = URDFToSerialManipulator("nonexistent.urdf")
except FileNotFoundError:
print("URDF file not found")
except Exception as e:
print(f"URDF processing error: {e}")
# Validate extracted parameters
if processor.robot_data["actuated_joints_num"] == 0:
print("Warning: No actuated joints found")
if len(processor.dynamics.Glist) != processor.robot_data["actuated_joints_num"]:
print("Warning: Inertia matrix count mismatch")
Key Featuresο
Automatic parameter extraction from URDF files using urchin library
PyBullet integration for accurate joint limit retrieval
Dual object creation (SerialManipulator + ManipulatorDynamics)
Flexible visualization with static and animated display options
Robust trajectory handling supporting both array and dictionary formats
Complete inertia processing from URDF link properties
Screw theory conversion from joint parameters to screw axes
Error handling for malformed or missing URDF files
Dependenciesο
urchin β URDF loading and visualization
PyBullet β Joint limit extraction and simulation
NumPy β Numerical computations and array operations
ManipulaPy.kinematics β SerialManipulator class
ManipulaPy.dynamics β ManipulatorDynamics class
ManipulaPy.utils β Utility functions for transformations
See Alsoο
Kinematics API Reference β SerialManipulator class created by this processor
Dynamics API Reference β ManipulatorDynamics class created by this processor
Simulation API Reference β Simulation module using URDF models
URDF Processor User Guide β Conceptual overview and URDF format details