urdf_state_space¶
URDF → linear state-space plant. See the guide for concepts and the YAML schema.
state_space — linearization core¶
Linearize rigid-body robot dynamics from a URDF into a state-space model.
The manipulator equation
M(q) q_ddot + C(q, q_dot) q_dot + g(q) = S^T u
is linearized about an equilibrium (q_eq, q_dot = 0, u_eq = gravity compensation), giving the LTI system
x_dot = A x + B u_delta, y = C x + D u_delta
with state x = [q - q_eq, q_dot] (tangent space) and input u_delta = u - u_eq. The partial derivatives of the forward dynamics are computed analytically by Pinocchio (computeABADerivatives), not by finite differences.
- class urdf_state_space.state_space.StateSpaceModel(A: ~numpy.ndarray, B: ~numpy.ndarray, C: ~numpy.ndarray, D: ~numpy.ndarray, q_eq: ~numpy.ndarray, u_eq: ~numpy.ndarray, joint_names: ~typing.List[str], actuated_joint_names: ~typing.List[str], output_names: ~typing.List[str] = <factory>)[source]¶
Bases:
objectLTI model of a robot linearized about an equilibrium point.
State x = [q - q_eq (tangent), q_dot], input u = tau_actuated - u_eq.
- c2d(dt: float) StateSpaceModel[source]¶
Discretize with zero-order hold (exact, via matrix exponential).
- classmethod load_npz(path: str) StateSpaceModel[source]¶
- urdf_state_space.state_space.build_state_space(urdf: str, q_eq: Sequence[float] | Mapping[str, float] | None = None, actuated_joints: Sequence[str] | None = None, output_joints: Sequence[str] | None = None, velocity_outputs: bool = False, joint_damping: Sequence[float] | Mapping[str, float] | None = None, floating_base: bool = False, gravity_tol: float = 1e-06) StateSpaceModel[source]¶
Linearize the robot in
urdfabout (q_eq, q_dot = 0).- Parameters:
urdf – Path to a URDF file, or the URDF XML itself.
q_eq – Equilibrium configuration: either a full pinocchio q vector, or a {joint_name: position} mapping (unnamed joints stay neutral). Defaults to the neutral configuration.
actuated_joints – Names of actuated joints (columns of B). Default: all movable joints.
output_joints – Joints whose positions appear in y. Default: the actuated joints.
velocity_outputs – Also include the velocities of
output_jointsin y.joint_damping – Viscous damping added to the model (URDF <damping> values are NOT read by pinocchio): either a per-DoF sequence of length nv, or a {joint_name: damping} mapping (unnamed joints get 0). N*m*s/rad.
floating_base – Model the base as a free-flyer joint instead of fixed to the world.
gravity_tol – Warn if unactuated joints need more torque than this to hold q_eq (the point is then not a true equilibrium for the given actuation).
config — YAML config loader¶
YAML-driven model setup: describe the linearization per joint, by name.
Example config¶
model:
urdf: package://my_robot_description/urdf/my_robot.urdf
floating_base: false
joints: # every movable joint may have an entry
shoulder_joint: {actuated: true, damping: 0.1}
elbow_joint: {actuated: true, damping: 0.1, q_eq: 0.3}
wrist_joint: {damping: 0.005}
outputs:
velocities: true # y includes velocities as well
# joints: [elbow_joint] # optional; default: the actuated joints
export:
npz: model.npz
mat: model.mat
# dt: 0.001 # also produce/export the ZOH-discretized model
If any joint sets actuated, only joints with actuated: true are
actuated; if none does, all movable joints are. Joints without a damping
or q_eq entry default to 0 / neutral. Relative paths (URDF and export
files) are resolved against the YAML file’s directory.
- class urdf_state_space.config.ExportSpec(npz: str | None = None, mat: str | None = None, dt: float | None = None)[source]¶
Bases:
object
- urdf_state_space.config.resolve_resource(ref: str, base_dir: str = '.') str[source]¶
Resolve a package:// URI or a (possibly relative) filesystem path.
- urdf_state_space.config.build_from_yaml(config_path: str) Tuple[StateSpaceModel, ExportSpec][source]¶
Build a StateSpaceModel from a YAML config; also return export spec.
cli — the urdf2ss entry point¶
Command-line tool: linearize a URDF into state-space matrices.
Preferred: describe everything in a YAML config (joint-name keyed, no positional pitfalls) and run
urdf2ss model.yaml
Quick one-offs can still pass a URDF and flags directly:
urdf2ss robot.urdf urdf2ss robot.urdf –q-eq 0 0.5 0 –actuated shoulder_joint elbow_joint urdf2ss robot.xacro -o model.npz –mat model.mat