Dynamics

Linear state-space systems (time-varying / parameter-dependent and LTI).

class minilink.dynamics.abstraction.state_space.StateSpaceSystem(*, n, m, p=None, feedthrough=False, name='State Space System', declare_ports=True, expose_state=True)[source]

Linear state-space system, possibly time-varying or parameter-dependent:

dx = A(t, params) @ x + B(t, params) @ u
y  = C(t, params) @ x + D(t, params) @ u

The matrices are built by the methods A(), B(), C(), and D(), mirroring MechanicalSystem.H() (q, params). Subclasses override A() and B() (and optionally C() / D()) to assemble the matrices from params. For a constant system, use the LTISystem convenience subclass.

A(t=0.0, params=None)[source]

State matrix A as a function of time and parameters.

B(t=0.0, params=None)[source]

Input matrix B as a function of time and parameters.

C(t=0.0, params=None)[source]

Output matrix C; defaults to full-state output (identity).

D(t=0.0, params=None)[source]

Feedthrough matrix D; defaults to zero.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

class minilink.dynamics.abstraction.state_space.LTISystem(A, B, C=None, D=None, *, name='LTI System', declare_ports=True, expose_state=True, xbar=None, ubar=None, ybar=None)[source]

Linear time-invariant system with constant matrices:

dx = A @ x + B @ u
y  = C @ x + D @ u

The matrices are stored exactly as passed so NumPy arrays, JAX arrays, or other matrix objects can drive the same equation code. Access them through the zero-argument method calls, e.g. sys.A() (useful for introspection such as numpy.linalg.eigvals(sys.A())). declare_ports=False leaves the ports u, y and x undeclared, for a subclass that declares its own layout (a compensator TransferFunction); expose_state=False declares u and y only (a filter is not a plant).

A model obtained by linearize() describes deviations about an operating point, which it carries as xbar, ubar and ybar (the state, the inputs of its B columns, and the outputs of its C rows), so a design made on it knows where it applies. A model built from arrays sits at the origin.

A(t=0.0, params=None)[source]

State matrix A as a function of time and parameters.

B(t=0.0, params=None)[source]

Input matrix B as a function of time and parameters.

C(t=0.0, params=None)[source]

Output matrix C; defaults to full-state output (identity).

D(t=0.0, params=None)[source]

Feedthrough matrix D; defaults to zero.

Second-order mechanical systems in generalized coordinates: H(q) v̇ + C(q, v) v + d + g(q) = τ.

class minilink.dynamics.abstraction.mechanical.MechanicalSystem(dof=1, actuators=None)[source]

Mechanical system with equation of motion

H(q) a + C(q, v) v + d(q, v, u, t) + g(q)

= generalized_force(q, v, u, t)

State is stacked as x = [q; v] with n = 2 * dof and default output y = x. For ordinary generalized coordinates, v = qdot.

Subclasses override H, C, B, g, d, and/or generalized_force. The default hooks follow Minilink’s native-array rule; a concrete subclass is JAX-traceable only if its overridden hooks do the same.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, v, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

B(q, params=None)[source]

Actuator matrix, shape (dof, m).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, v, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

generalized_force(q, v, u, t=0.0, params=None)[source]

Right-side generalized force vector.

The default is the textbook actuator map B(q) @ u. Override this method when inputs mix force commands, geometry commands, environment variables, or other non-actuator semantics.

x2q(x)[source]

Split state x into q and v.

q2x(q, v)[source]

Stack q and v into state x.

inverse_dynamics(q, v, acceleration, u=None, t=0.0, params=None)[source]

Generalized RHS force required by a trajectory.

forward_dynamics(q, v, u, t=0.0, params=None)[source]

Forward dynamics: generalized acceleration given u.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

class minilink.dynamics.abstraction.mechanical.JaxMechanicalSystem(dof=1, actuators=None)[source]

JAX-traceable counterpart of MechanicalSystem.

Inherits port labels, bounds, __init__, x2q / h, and the inverse_dynamics formula from MechanicalSystem. Overrides only the matrix builders (H(), C(), B(), g(), d()), the state-stacking helper q2x(), and methods that need JAX array creation or jax.numpy.linalg.solve.

JAX is loaded lazily inside each method via require_jax_numpy(), so importing this module stays free without JAX.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, v, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

B(q, params=None)[source]

Actuator matrix, shape (dof, m).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, v, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

q2x(q, v)[source]

Stack q and v into state x.

forward_dynamics(q, v, u, t=0.0, params=None)[source]

Forward dynamics: generalized acceleration given u.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

Mechanical systems with generalized velocities: M(q) v̇ + C(q, v) v + d + g(q) = τ, q̇ = N(q) v.

class minilink.dynamics.abstraction.generalized_mechanical.GeneralizedMechanicalSystem(dof=1, pos=None, actuators=None)[source]

Mechanical system whose velocities need not equal qdot.

The state is stacked as x = [q; v]. In the course-note notation, v corresponds to a generalized or body-frame velocity, often written nu. Dynamics use the structure:

M(q) a + C(q, v) v + d(q, v, u, t) + g(q)
    = generalized_force(q, v, u, t)
qdot = N(q) v

The default generalized force is B(q) @ u. Subclasses with mixed force and geometry inputs should override generalized_force() rather than introducing a separate position-input inheritance branch.

M(q, params=None)[source]

Inertia matrix, shape (dof, dof).

C(q, v, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

N(q, params=None)[source]

Kinematic map from generalized velocities to configuration rates.

B(q, params=None)[source]

Actuator matrix used by the default generalized_force() hook.

g(q, params=None)[source]

Conservative generalized forces, shape (dof,).

d(q, v, u=None, t=0.0, params=None)[source]

Left-side generalized load/dissipation vector, shape (dof,).

generalized_force(q, v, u, t=0.0, params=None)[source]

Right-side generalized force vector.

The default is B(q) @ u. Override this method for systems where inputs include steering angles, control-surface positions, tire laws, aerodynamic forces, propulsor maps, or other mixed input semantics.

x2qv(x)[source]

Split state x into configuration q and velocity v.

qv2x(q, v)[source]

Stack configuration q and velocity v into state x.

qdot(q, v, params=None)[source]

Configuration derivative qdot = N(q) @ v.

inverse_dynamics(q, v, acceleration, u=None, t=0.0, params=None)[source]

Generalized RHS force required by a trajectory.

forward_dynamics(q, v, u, t=0.0, params=None)[source]

Velocity derivative from forward dynamics.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

Serial manipulators: the mechanical dynamics plus the task-space kinematics p = f(q), ṗ = J(q) q̇.

class minilink.dynamics.abstraction.manipulator.Manipulator(dof=1, actuators=None, task_dim=2)[source]

Serial manipulator with task-space kinematic outputs.

Dynamics follow MechanicalSystem. Subclasses override forward_kinematics() and J().

Output ports

p, pdot :

Task position p = f(q) and velocity ṗ = J(q) q̇.

y, x :

Full state [q; q̇].

Input port u carries joint torques τ. An optional world-frame tool-force port f (added by a subclass) is drawn as a crimson arrow at the tool when get_dynamic_geometry() runs.

forward_kinematics(q, params=None)[source]

Task-space position p = f(q), shape (task_dim,).

J(q, params=None)[source]

Manipulator Jacobian ∂p/∂q, shape (task_dim, dof).

get_dynamic_geometry(x, u, t=0, params=None)[source]

Crimson tool-force arrow when input port f is present and nonzero.

inverse_kinematics(p_d, q_guess=None, *, params=None, tol=1e-09, bounds=None, method='auto')[source]

Return q with forward_kinematics(q) ≈ p_d.

Uses scipy.optimize.fsolve when task_dim == dof and no joint bounds apply; otherwise scipy.optimize.least_squares. Returns one solution near q_guess (default: the nominal state’s q).

Catalog

Integrator chains: the simple, double and triple integrators.

class minilink.dynamics.catalog.equations.integrators.SimpleIntegrator[source]

Single integrator dx = u.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.equations.integrators.DoubleIntegrator[source]

Double integrator d(position)/dt = speed, d(speed)/dt = u.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.equations.integrators.TripleIntegrator[source]

Triple integrator with force as the third state.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

Canonical nonlinear oscillators: Van der Pol and Lorenz.

class minilink.dynamics.catalog.equations.oscillators.VanderPol(mu=0.5)[source]

Van der Pol oscillator.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

class minilink.dynamics.catalog.equations.oscillators.Lorenz(sigma=10.0, rho=28.0, beta=2.6666666666666665)[source]

Lorenz chaotic attractor.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

Linear mass-spring-damper chains of one, two and three masses, grounded or floating.

class minilink.dynamics.catalog.mass_spring_damper.linear.SingleMass(mass=1.0, k=2.0, b=0.0)[source]

Single linear mass-spring-damper model.

A(t=0.0, params=None)[source]

State matrix A as a function of time and parameters.

B(t=0.0, params=None)[source]

Input matrix B as a function of time and parameters.

C(t=0.0, params=None)[source]

Output matrix C; defaults to full-state output (identity).

D(t=0.0, params=None)[source]

Feedthrough matrix D; defaults to zero.

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.mass_spring_damper.linear.TwoMass(m=1.0, k=2.0, b=0.2, output_mass=2)[source]

Two-mass linear spring-damper chain with force on the second mass.

The springs couple neighbours: k1 ties the first mass to the wall and k2 ties the two masses together. Each damper acts on its own mass’s absolute velocity (b1 on the first mass, b2 on the second), not on the relative velocity across a spring.

A(t=0.0, params=None)[source]

State matrix A as a function of time and parameters.

B(t=0.0, params=None)[source]

Input matrix B as a function of time and parameters.

C(t=0.0, params=None)[source]

Output matrix C; defaults to full-state output (identity).

D(t=0.0, params=None)[source]

Feedthrough matrix D; defaults to zero.

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.mass_spring_damper.linear.ThreeMass(m=1.0, k=2.0, b=0.2, output_mass=2)[source]

Three-mass linear spring-damper chain with force on the third mass.

The springs couple neighbours: k1 ties the first mass to the wall, k2 and k3 tie each mass to the next. Each damper acts on its own mass’s absolute velocity (b1, b2, b3 on the first, second and third mass), not on the relative velocity across a spring.

A(t=0.0, params=None)[source]

State matrix A as a function of time and parameters.

B(t=0.0, params=None)[source]

Input matrix B as a function of time and parameters.

C(t=0.0, params=None)[source]

Output matrix C; defaults to full-state output (identity).

D(t=0.0, params=None)[source]

Feedthrough matrix D; defaults to zero.

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.mass_spring_damper.linear.FloatingSingleMass(m=1.0, b=0.0)[source]

Single mass with no ground spring.

class minilink.dynamics.catalog.mass_spring_damper.linear.FloatingTwoMass(m=1.0, k=1.0, b=0.0, output_mass=2)[source]

Two masses with no ground spring on the first mass.

class minilink.dynamics.catalog.mass_spring_damper.linear.FloatingThreeMass(m=1.0, k=1.0, b=0.0, output_mass=3)[source]

Three masses with no ground spring on the first mass.

Single pendulums: actuated, with noise ports, inverted, and two uncoupled ones.

class minilink.dynamics.catalog.pendulum.pendulum.Pendulum(length=1.0, mass=1.0)[source]

Single actuated pendulum.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.pendulum.pendulum.PendulumWithNoisePort[source]

Single actuated pendulum with process and measurement noise ports.

d injects disturbance torque into the dynamics; n corrupts the measured angular velocity in y.

B(q, params=None)[source]

Actuator matrix, shape (dof, m).

generalized_force(q, v, u, t=0.0, params=None)[source]

Right-side generalized force vector.

The default is the textbook actuator map B(q) @ u. Override this method when inputs mix force commands, geometry commands, environment variables, or other non-actuator semantics.

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

class minilink.dynamics.catalog.pendulum.pendulum.InvertedPendulum[source]

Single actuated pendulum with upward zero-angle equilibrium.

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

class minilink.dynamics.catalog.pendulum.pendulum.TwoIndependentPendulums[source]

Two uncoupled single pendulums sharing the same parameters.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

Cart-poles: the linear cart-pole and the rotating cart-pole, with a noise-port variant (pyro port).

class minilink.dynamics.catalog.pendulum.cartpole.CartPole[source]

Linear cart with one unactuated pendulum pole.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

B(q, params=None)[source]

Actuator matrix, shape (dof, m).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.pendulum.cartpole.CartPoleWithNoisePort[source]

Linear cart-pole with process and measurement noise ports.

d injects a disturbance force into the cart; n corrupts the measured state in y.

generalized_force(q, v, u, t=0.0, params=None)[source]

Right-side generalized force vector.

The default is the textbook actuator map B(q) @ u. Override this method when inputs mix force commands, geometry commands, environment variables, or other non-actuator semantics.

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

class minilink.dynamics.catalog.pendulum.cartpole.RotatingCartPole[source]

Rotating cart-pole with both joints actuated.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

class minilink.dynamics.catalog.pendulum.cartpole.UnderactuatedRotatingCartPole[source]

Rotating cart-pole actuated only at the base.

B(q, params=None)[source]

Actuator matrix, shape (dof, m).

Double pendulum: two links, two actuators, the second angle relative to the first link (pyro port).

class minilink.dynamics.catalog.pendulum.double_pendulum.DoublePendulum[source]

Two-link actuated pendulum in Pyro’s manipulator-equation convention.

Notes

The kinematic canvas uses a Pyro-style mapping from joint angles to rod orientations: world rod heading uses (pi/2 - theta) so the default Rod (local -Y) matches Pyro’s forward_kinematic_lines convention.

trig(q)[source]

Shorthands c1, s1, c2, s2, c12, s12 of the joint angles and their sum.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

B(q, params=None)[source]

Actuator matrix, shape (dof, m).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.pendulum.double_pendulum.Acrobot[source]

Double pendulum actuated only at the elbow.

B(q, params=None)[source]

Actuator matrix, shape (dof, m).

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

Planar and spatial serial arms: one, two, three and five links, and a velocity-controlled base.

class minilink.dynamics.catalog.manipulators.arms.OneLinkManipulator[source]

One-link planar manipulator.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

forward_kinematics(q, params=None)[source]

Task-space position p = f(q), shape (task_dim,).

J(q, params=None)[source]

Manipulator Jacobian ∂p/∂q, shape (task_dim, dof).

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Crimson tool-force arrow when input port f is present and nonzero.

class minilink.dynamics.catalog.manipulators.arms.TwoLinkManipulator[source]

Two-link planar manipulator.

trig(q)[source]

Shorthands c1, s1, c2, s2, c12, s12 of the joint angles and their sum.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

forward_kinematics(q, params=None)[source]

Task-space position p = f(q), shape (task_dim,).

J(q, params=None)[source]

Manipulator Jacobian ∂p/∂q, shape (task_dim, dof).

lengths(params=None)[source]

The link lengths [l1, l2].

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Crimson tool-force arrow when input port f is present and nonzero.

class minilink.dynamics.catalog.manipulators.arms.ThreeLinkManipulator3D[source]

Three-link spatial manipulator from the Pyro catalog.

trig(q)[source]

Shorthands c1, s1, c2, s2, c3, s3, c23, s23 of the joint angles.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

forward_kinematics(q, params=None)[source]

Task-space position p = f(q), shape (task_dim,).

J(q, params=None)[source]

Manipulator Jacobian ∂p/∂q, shape (task_dim, dof).

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

class minilink.dynamics.catalog.manipulators.arms.FiveLinkPlanarManipulator[source]

Five-link planar manipulator with Pyro’s default unit joint dynamics.

Kinematics and Jacobian are fully specified; dynamics use the MechanicalSystem placeholder H = I (no gravity/Coriolis). Prefer one- to three-link arms for computed-torque demos.

absolute_trig(q)[source]

Cosine and sine of each link’s absolute angle (the joint angles summed).

forward_kinematics(q, params=None)[source]

Task-space position p = f(q), shape (task_dim,).

J(q, params=None)[source]

Manipulator Jacobian ∂p/∂q, shape (task_dim, dof).

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Crimson tool-force arrow when input port f is present and nonzero.

class minilink.dynamics.catalog.manipulators.arms.SpeedControlledManipulator(dof, effector_dim)[source]

Joint-space integrator for velocity-controlled manipulators.

Dynamics: dq = u. State and default output y are joint angles q. Use from_manipulator() to inherit forward_kinematics and J from a torque-controlled Manipulator.

classmethod from_manipulator(arm)[source]

Build a velocity-controlled plant with kinematics from arm.

Parameters:

arm (Manipulator)

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

The drawn link lengths: the arm’s, read from params when they are given.

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

UR5 six-axis manipulator: spatial ABA forward dynamics and RNEA inverse dynamics.

class minilink.dynamics.catalog.manipulators.ur5.UR5Manipulator[source]

Six-degree-of-freedom UR5 arm with a schematic 3-D skin.

Kinematics use the standard Denavit-Hartenberg convention. Dimensions, masses and centers of mass follow the public ros-industrial/universal_robot description; they are paired with simple cylinder inertias, so the model is suitable for controller examples but is not a factory-calibrated representation.

Equation paths (H/C/g/d, FK, J, tf) are NumPy/JAX native-array. Forward dynamics and f use the spatial ABA; inverse_dynamics uses spatial RNEA; H/C/g remain RNEA-based for analysis and matrix-form checks.

forward_dynamics(q, v, u, t=0.0, params=None)[source]

Forward dynamics via articulated-body algorithm (default simulation path).

forward_dynamics_rnea_h(q, v, u, t=0.0, params=None)[source]

Forward dynamics via RNEA bias + explicit H (teaching / verification).

forward_dynamics_aba(q, v, u, t=0.0, params=None)[source]

Alias of forward_dynamics() (explicit ABA name for comparisons).

inverse_dynamics(q, v, acceleration, u=None, t=0.0, params=None)[source]

Inverse dynamics via spatial RNEA (default path).

inverse_dynamics_matrix(q, v, acceleration, u=None, t=0.0, params=None)[source]

Inverse dynamics via explicit H, C, g (teaching / verification).

inverse_dynamics_rnea(q, v, acceleration, u=None, t=0.0, params=None)[source]

Alias of inverse_dynamics() (explicit RNEA name for comparisons).

H(q, params=None)[source]

Joint-space inertia matrix.

C(q, dq, params=None)[source]

Coriolis matrix chosen so C(q, dq) @ dq is the RNEA bias force.

g(q, params=None)[source]

Gravity generalized force.

d(q, dq, u=None, t=0.0, params=None)[source]

Linear viscous joint damping.

forward_kinematics(q, params=None)[source]

Tool-center position in the world frame.

J(q, params=None)[source]

Translational tool Jacobian.

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

kinematic_chain(q, params=None)[source]

Each joint’s frame, origin and axis, and each link’s frame, in the base frame.

rnea(q, dq, acceleration, params=None, *, gravity=True)[source]

Recursive Newton-Euler inverse dynamics in link coordinates.

aba(q, dq, tau, params=None, *, gravity=True)[source]

Articulated-body forward dynamics — O(n) generalized accelerations.

Kinematic steering models: the bicycle, the full-size car and the holonomic point robot.

class minilink.dynamics.catalog.vehicles.steering.KinematicBicycle[source]

Kinematic bicycle model with speed and steering-angle inputs.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.vehicles.steering.KinematicCar[source]

Kinematic bicycle parameterized as a full-size car with a four-wheel skin.

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

class minilink.dynamics.catalog.vehicles.steering.HolonomicMobileRobot[source]

Holonomic 2D point robot.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

Dynamic bicycle: a planar rigid body on linear tires, and its wheel-rate / steer-rate rung.

class minilink.dynamics.catalog.vehicles.dynamic_bicycle.DynamicBicycle(named_ports=True)[source]

Dynamic bicycle with rear wheel speed and steer inputs.

State x = [x, y, theta, vx, vy, yaw_rate]: the world pose and the body-frame velocities. The two inputs come as two named ports, or as one stacked u port with named_ports=False. The research rungs live in examples/projects/car_trajopt/vehicles/ladder.py.

Inputs

w_rear : rear wheel angular rate [rad/s] delta : front steer angle [rad]

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

rear_wheel_ground_torque(v_body, w_rear, delta, params=None)[source]

Tire reaction plus viscous torque on the rear wheel [Nm].

Satisfies Jw * w_rear_dot = tau_motor - tau_ground for the rate, torque, servo, and engine variants built on this model.

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

2-D centerline look: one velocity and one force arrow per axle.

class minilink.dynamics.catalog.vehicles.dynamic_bicycle.DynamicBicycleCar3D[source]

Same dynamics as DynamicBicycle; overrides only kinematic graphics.

Body box, four wheel Rod primitives, and duplicated velocity/force arrows at each side (bicycle model vectors on L/R).

get_dynamic_geometry(x, u, t=0, params=None)[source]

3-D look: velocity and force arrows duplicated at all four wheels.

Dynamic geometry is not a skin concern, so the four-wheel arrow set is a manual override here rather than something driven by car_skin_3d. The arrows share the body frame (T_wb); each bakes its wheel corner as its base and lifts to the hub height via local_transform.

class minilink.dynamics.catalog.vehicles.dynamic_bicycle.BicycleDynRate(named_ports=False)[source]

Dynamic bicycle with rear-wheel and steer rate inputs (the MPC plant).

State x = [x, y, theta, vx, vy, yaw_rate, w_rear, delta]: the wheel rate and the steer angle are states driven by the inputs [w_rear_dot, delta_dot] — one stacked u port, or named_ports=True for a w_rear_dot and a delta_dot port. Jw_rear / bw_rear feed inverse_propulsion_dynamics().

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

inverse_propulsion_dynamics(x, u, t=0.0, params=None)[source]

Rear motor torque [Nm] that produces the commanded w_rear_dot.

Inverts Jw_rear * w_rear_dot = tau_rear - rear_wheel_ground_torque(...).

minilink.dynamics.catalog.vehicles.dynamic_bicycle.linear_tire_forces(vx, vy, w, R, Fz, Ca, Ck, mu, v_min_epsilon)[source]

Linear-slip tire forces with friction-circle saturation (pyro LinearTire).

Fx = Ck kappa and Fy = Ca alpha, scaled back onto |F| <= mu Fz.

minilink.dynamics.catalog.vehicles.dynamic_bicycle.tire_slip(vx, vy, w, R, v_min_epsilon)[source]

Slip angle alpha [rad] and slip ratio kappa [-] at one contact.

1/10-scale racecar: power-limited rear drive, brush tires, servo steering.

class minilink.dynamics.catalog.vehicles.racecar.UdeSRacecar[source]

Kinematic bicycle at the 1/10 racecar scale.

Same equations as KinematicBicycle, with a = b from PUBLIC_RACECAR_PARAMS. tf publishes the link frames, so the 3-D look attaches with car.skin = racecar_skin_3d. There is no rolling angle in the state: the wheels steer, they do not spin.

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

class minilink.dynamics.catalog.vehicles.racecar.UdeSRacecarDyn(named_ports=True)[source]

1/10-scale racecar: power-limited rear drive, brush tires, servo steering.

State x = [x, y, theta, vx, vy, yaw_rate, w_rear, delta, P]: world pose, body velocities, rear wheel rate [rad/s], steer angle [rad] and the power on its way to the ground [W]. The equation paths use the xp idiom and trace under JAX.

Inputs

P_cmd : requested drive power [W], clipped to +- P_max (negative brakes). delta_cmd : requested steer angle [rad], clipped to +- delta_max.

named_ports=False stacks the two commands into one u port instead — the planning and trajectory-optimization convention of the minilink vehicle ladder.

Propulsion

The drive is described by what it can deliver:

P_dot = (clip(P_cmd, +-P_max) - P) / engine_tau
tau   = clip(P / sqrt(w_rear^2 + w_min_epsilon^2), +-tau_sat)
Jw_rear w_rear_dot = tau - tau_ground(v, w_rear, delta) - tau_brake(w_rear)

with tau_brake = bw_drive w_rear + tau_fric tanh(w_rear / w_c). The smooth denominator keeps the torque’s sign tied to the power’s and stays finite at rest, where tau_sat is what limits the launch. Asking for power the rear tire cannot put down spins the rear wheel instead of accelerating the car.

Steering

The servo is a first-order lag with a smooth rate limit and end stops:

delta_dot = steer_rate_max tanh((delta_ref - delta) / (steering_tau steer_rate_max))

Outputs

y (the full state), speed [m/s], slip (kappa_r, alpha_f, alpha_r), grip (used fraction of each friction ellipse), imu (specific force at the centre of gravity and yaw rate) and power (the lagged power and the power actually reaching the wheel).

refresh()[source]

Recompute the solver hint: an estimate of the plant’s fastest mode.

The tire modes are stiffest at rest, where the slip denominators sit on their floor v_min_epsilon. Three of them are estimated — the wheel against the longitudinal stiffness, the yaw and the sideslip against the cornering stiffnesses — and the smallest is halved, because each is written for one degree of freedom while the real modes couple them (the longitudinal pair alone is some 16 % faster than an uncoupled wheel would be).

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

compute_tire_physics(v_body, u_inputs, params=None)[source]

Brush-tire axle forces, replacing the linear-slip pair of the base class.

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

class minilink.dynamics.catalog.vehicles.racecar.UdeSRacecarDyn3D[source]

Same car with the two wheel rolling angles as states, for the 3-D skin.

State x = [..., P, phi_rear, phi_front] (n = 11). An animation frame is a pure function of (x, u, t), so a wheel that turns needs its angle in the state; the two extra states are plain integrators and change nothing else.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

2-D centerline look: one velocity and one force arrow per axle.

minilink.dynamics.catalog.vehicles.racecar.stiff_tires(params)[source]

The same car with rigid tires: the no-slip limit, for tests and comparisons.

Multiplies every slip stiffness and the friction coefficient so that the axles hold their contact conditions, which turns the dynamic bicycle into a kinematic one.

Longitudinal front-wheel-drive car with wheel slip or wheel torque as the input.

class minilink.dynamics.catalog.vehicles.propulsion.LongitudinalFrontWheelDriveCarWithWheelSlipInput[source]

Longitudinal front-wheel-drive car with wheel slip as input.

slip2force(slip, params=None)[source]

The friction ratio μ = F_x / F_z at the wheel slip slip, not a force.

get_dynamic_geometry() draws it as the normalized traction arrow.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.vehicles.propulsion.LongitudinalFrontWheelDriveCarWithTorqueInput[source]

Longitudinal front-wheel-drive car with wheel torque input.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

Fiala brush tires: the axle slips, their saturated forces and the friction ellipse.

minilink.dynamics.catalog.vehicles.tires.axle_slips(vx, vy, yaw_rate, w_rear, delta, params)[source]

Slip ratio of the driven rear axle and slip angle of each axle.

Parameters:
  • vx (float) – Body-frame velocity of the centre of gravity [m/s].

  • vy (float) – Body-frame velocity of the centre of gravity [m/s].

  • yaw_rate (float) – Body yaw rate [rad/s].

  • w_rear (float) – Rear wheel angular rate [rad/s], positive when rolling forward.

  • delta (float) – Front steer angle [rad].

  • params (dict) – Needs a, b [m], r_r [m] and v_min_epsilon [m/s].

Returns:

  • kappa_r (float) – Rear slip ratio [-]: positive when the tire drives the car forward.

  • alpha_f, alpha_r (float) – Slip angles [rad]: positive when the tire pushes the car to the left.

Notes

Every denominator is floored by v_min_epsilon, so the slips stay bounded and differentiable at standstill instead of blowing up as 1 / vx.

minilink.dynamics.catalog.vehicles.tires.brush_tire_forces(kappa_r, alpha_f, alpha_r, vx, params)[source]

Axle forces (Fx_f, Fy_f, Fx_r, Fy_r) [N], each in its own wheel frame.

Static axle loads carry the weight. The free-rolling front axle makes a cornering force and pays rolling resistance; the driven rear axle shares one friction ellipse between its traction force and its cornering force, so asking for both at once costs grip in the other direction.

C_rr is charged to the front axle only: what the rear wheels lose to rolling is carried by the drivetrain terms of the plant (bw_drive, tau_fric), which resist the wheel rate itself rather than the contact patch.

Parameters:
  • kappa_r (float) – Slips from axle_slips().

  • alpha_f (float) – Slips from axle_slips().

  • alpha_r (float) – Slips from axle_slips().

  • vx (float) – Body-frame forward speed [m/s], for the direction of the rolling resistance.

  • params (dict) – Needs mass, gravity, a, b, mu, c_alpha_f, c_alpha_r, c_kappa, C_rr, v_c and z_floor.

Returns:

Fx_f, Fy_f, Fx_r, Fy_r – Longitudinal and lateral force of the front and of the rear axle [N].

Return type:

float

Notes

Axle stiffnesses are given per unit load (c_alpha in 1/rad, c_kappa in [-]), the usual way to write a tire whose stiffness scales with what it carries. The understeer gradient of the car is then 1/c_alpha_f - 1/c_alpha_r rad per g, independent of the mass split.

References

Pacejka, Tyre and Vehicle Dynamics, 3rd ed., ch. 3; Fiala, VDI Zeitschrift 96 (1954).

minilink.dynamics.catalog.vehicles.tires.friction_use(Fx_f, Fy_f, Fx_r, Fy_r, params)[source]

Used fraction (phi_f, phi_r) of each axle’s friction ellipse [-].

1 means the axle is sliding: it has no force left for anything else.

minilink.dynamics.catalog.vehicles.tires.smooth_sign(v, v_c)[source]

Sign of v softened over the creep speed v_c, for a resistance at rest.

minilink.dynamics.catalog.vehicles.tires.brush_saturation(z)[source]

Saturation factor g(z) = phi(z) / z applied to the linear tire force.

The brush model integrates the bristle deflection over the contact patch. While part of the patch still grips, the force is phi(z) = 1 - (1 - z/3)^3 of the friction limit; past z = 3 the whole patch slides and the force stays at the limit, so the factor decays as 1 / z.

Parameters:

z (float or array) – Slip demand [-]: the linear-slip force divided by the friction limit mu Fz.

Returns:

g – Factor in (0, 1]. g(0) = 1 (linear tire) and z g(z) <= 1 always, so the force never exceeds mu Fz. The two branches match in value and slope at z = 3 (both give 1/3 and -1/9).

Return type:

float or array

Quarter-car suspension riding over a prescribed rough terrain.

class minilink.dynamics.catalog.vehicles.suspension.QuarterCarOnRoughTerrain[source]

Quarter-car suspension moving over prescribed rough terrain.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

Mountain car: a one-coordinate mechanical system on a cosine hill.

class minilink.dynamics.catalog.vehicles.mountain_car.MountainCar[source]

Mountain car as a one-coordinate constrained mechanical system.

Dynamics match SherbyRobotics/pyro MountainCar in pyro/dynamic/mountaincar.py: a bead of mass mass slides along the fixed relief curve z(x) = a * cos(w * x) under gravity.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

B(q, params=None)[source]

Actuator matrix, shape (dof, m).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

forward_kinematic_effector(q, params=None)[source]

The bead’s position (x, z(x)) on the hill.

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

Planar drones: two vertical thrusters, a lateral thruster, velocity inputs, the tunnel helicopter.

class minilink.dynamics.catalog.aerial.drone.Drone2D[source]

Planar drone with two vertical body-frame thrusters.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

B(q, params=None)[source]

Actuator matrix, shape (dof, m).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.aerial.drone.Drone2DWithSideThruster[source]

Planar drone with an added lateral body-frame thruster.

B(q, params=None)[source]

Actuator matrix, shape (dof, m).

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.aerial.drone.SpeedControlledDrone2D[source]

Planar drone abstraction with velocity inputs.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.aerial.drone.ConstantSpeedHelicopterTunnel[source]

Constant-speed tunnel helicopter with vertical force input.

f(x, u, t=0.0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0.0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

Aircraft: the planar plane with an elevator, and the six-DoF plane with elevator, aileron and rudder.

class minilink.dynamics.catalog.aerial.plane.Plane2D[source]

Planar aircraft with thrust and elevator inputs.

velocity_vector(q, dq)[source]

Airspeed V, flight-path angle γ and angle of attack α = θ − γ.

Cl(alpha, params=None)[source]

Lift coefficient: sin 2α, plus Cl_alpha α below stall.

Cd(alpha, params=None)[source]

Drag coefficient: the parasitic drag, plus the induced drag below stall.

Cm(alpha, params=None)[source]

Pitch moment coefficient: the constant Cm0, at every angle of attack.

aerodynamic_forces(speed, alpha, delta, params=None)[source]

Lift, drag and moment of the wing, and of the tail deflected by delta.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

generalized_force(q, dq, u, t=0.0, params=None)[source]

Right-side generalized force vector.

The default is the textbook actuator map B(q) @ u. Override this method when inputs mix force commands, geometry commands, environment variables, or other non-actuator semantics.

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.aerial.plane.Plane3D[source]

Six-DoF aircraft with thrust, elevator, aileron, and rudder.

Configuration q = [x, y, z, phi, theta, psi] is world position (z up) plus ZYX Euler angles. Generalized velocity v = [u, v, w, p, q, r] is the body-frame linear and angular rate (aircraft body: +x forward, +y right, +z down).

The body-to-world rotation is R_wb = Rz(psi) @ Ry(theta) @ Rx(phi) @ Rx(pi) so that zero angles place the aircraft level with belly toward world -z. With this map, a horizontal flight path at angle of attack alpha uses pitch theta ≈ -alpha. Aerodynamics reuse the planar Cl / Cd / Cm laws on the wing and horizontal tail, plus a vertical fin (rudder) and a pure aileron roll moment.

Cl(alpha, params=None)[source]

Lift coefficient: sin 2α, plus Cl_alpha α below stall.

Cd(alpha, params=None)[source]

Drag coefficient: the parasitic drag, plus the induced drag below stall.

Cm(alpha, params=None)[source]

Pitch moment coefficient: the constant Cm0, at every angle of attack.

R_wb(q)[source]

Body-to-world rotation for configuration q.

velocity_angles(v)[source]

Airspeed, angle of attack, and sideslip from body velocity.

aerodynamic_forces(speed, alpha, beta, delta_e, delta_a, delta_r, params=None)[source]

Body-frame force and moment from the simple multi-surface aero model.

M(q, params=None)[source]

Inertia matrix, shape (dof, dof).

C(q, v, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

N(q, params=None)[source]

Kinematic map from generalized velocities to configuration rates.

g(q, params=None)[source]

Conservative generalized forces, shape (dof,).

d(q, v, u=None, t=0.0, params=None)[source]

Left-side generalized load/dissipation vector, shape (dof,).

generalized_force(q, v, u, t=0.0, params=None)[source]

Right-side generalized force vector.

The default is B(q) @ u. Override this method for systems where inputs include steering angles, control-surface positions, tire laws, aerodynamic forces, propulsor maps, or other mixed input semantics.

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

Planar rocket with thrust magnitude and gimbal angle inputs.

class minilink.dynamics.catalog.aerial.rocket.Rocket[source]

Planar rocket with thrust magnitude and gimbal angle inputs.

H(q, params=None)[source]

Inertia matrix, shape (dof, dof). Kinetic energy = 0.5 * dq^T H(q) dq.

C(q, dq, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

g(q, params=None)[source]

Gravitational / conservative forces, shape (dof,).

d(q, dq, u=None, t=0.0, params=None)[source]

Left-side load/dissipation vector, shape (dof,).

generalized_force(q, dq, u, t=0.0, params=None)[source]

Right-side generalized force vector.

The default is the textbook actuator map B(q) @ u. Override this method when inputs mix force commands, geometry commands, environment variables, or other non-actuator semantics.

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

Planar boat: surge, sway and yaw with surge/sway force inputs, with or without a current.

class minilink.dynamics.catalog.marine.boat.Boat2D[source]

Three-DoF planar boat with surge/sway force inputs.

Low-speed manoeuvring model with linear plus quadratic hydrodynamic damping, following Fossen, Handbook of Marine Craft Hydrodynamics and Motion Control (2nd ed.), section 6.7.

M(q, params=None)[source]

Inertia matrix, shape (dof, dof).

C(q, v, params=None)[source]

Coriolis and centrifugal matrix, shape (dof, dof).

N(q, params=None)[source]

Kinematic map from generalized velocities to configuration rates.

B(q, params=None)[source]

Actuator matrix used by the default generalized_force() hook.

d(q, v, u=None, t=0.0, params=None)[source]

Left-side generalized load/dissipation vector, shape (dof,).

damping(relative_velocity, params=None)[source]

Hydrodynamic damping of a water-relative body velocity [u_r, v_r, r].

current_coefficients(alpha, params=None)[source]

The current coefficients (Cx, Cy, Cm) at the attack angle alpha.

body_shape()[source]

Top-view hull silhouette with the c.g. at the local origin.

The hull spans body_length along local +X with a pointed bow and is centred so the body-frame origin (c.g.) sits at mid-hull.

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

class minilink.dynamics.catalog.marine.boat.Boat2DWithCurrent[source]

Planar boat with constant current velocity in world frame.

d(q, v, u=None, t=0.0, params=None)[source]

Left-side generalized load/dissipation vector, shape (dof,).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".

get_dynamic_geometry(x, u, t=0, params=None)[source]

Per-frame geometry as dict[str, list[primitive]] (rebuilt each frame).

The three-body problem: three point masses under mutual Newtonian gravitation.

class minilink.dynamics.catalog.astro.three_body.ThreeBodyProblem(preset='figure_eight', masses=None, G=1.0, softening=0.0)[source]

Mutual Newtonian gravitation for three point masses in 3-D.

State layout (18):

x = [r1, v1, r2, v2, r3, v3]

with r_i, v_i in R^3. Each mass follows:

v_i_dot = sum_{j != i} G m_j (r_j - r_i) / |r_j - r_i|^3

with optional softening eps added inside the distance norm.

f(x, u, t=0, params=None)[source]

State derivative dx = f(x, u, t; p).

Subclasses should treat this as a function of (x, u, t, params) only; the library does not verify purity.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional) – None means “use self.params”.

Returns:

dx

Return type:

array of shape (n,)

h(x, u, t=0, params=None)[source]

Output y = h(x, u, t; p).

Default: the full state, y = x, when the y port has the state dimension (p == n); zeros otherwise. Override for any other measurement.

Parameters:
  • x (array of shape (n,))

  • u (array of shape (m,))

  • t (float)

  • params (dict, optional)

Returns:

y

Return type:

array of shape (p,)

get_kinematic_geometry()[source]

Static skin as dict[str, list[primitive]] (delegates to skin).

tf(x, u, t=0, params=None)[source]

World transforms as dict[str, 4x4] (the forward-kinematics hook).

Return only named articulation frames (body, link0, …). Do not emit "world": I — the animator injects an implicit identity root for geometry keyed to "world".