Dynamics
Robot dynamics describes the relationship between joint motion and the generalized forces required to produce that motion.
For a serial manipulator with configuration
the corresponding velocity and acceleration vectors are
and
The conventions used in this section follow Mathematical notation and conventions, Forward kinematics, and Differential kinematics.
Scope of dynamics in Moro
Moro currently focuses on symbolic dynamic modeling of serial manipulators.
The main dynamic relation is
Here,
\(M(\vec q)\) is the inertia matrix,
\(C(\vec q,\dot{\vec q})\) is the Coriolis matrix,
\(G(\vec q)\) is the gravity generalized-force vector,
\(\vec\tau\) contains the generalized forces applied at the joints.
For joint \(i\),
represents a torque for a revolute joint and a linear force for a prismatic joint.
Moro currently provides two routes for obtaining the equations of motion:
the Euler–Lagrange formulation,
direct construction of the matrix form.
These routes represent the same physical model.
Important
id=”scope-dynamics” Moro currently derives symbolic equations of motion and supports inverse-dynamics modeling.
It does not yet integrate the equations of motion in time to obtain a numerical trajectory from applied forces and initial conditions.
Therefore, Moro currently supports the conceptual mapping
but not a complete simulation workflow of the form
Physical parameters of a link
For each link \(i\), the dynamic model uses the following physical quantities:
The complete robot model also requires the gravity acceleration vector
Here, \(C_i\) denotes the center of mass of link \(i\).
Link mass
The mass of link \(i\) is denoted by
Mass is a scalar quantity and does not depend on the choice of reference frame.
In Moro, individual masses are available through
robot.m(i)
and collectively through
robot.masses
.
Center of mass
Moro defines the center-of-mass position of link \(i\) relative to its own link frame \(\{i\}\).
Thus,
represents the vector from \(O_i\) to \(C_i\), expressed in frame \(\{i\}\).
Using the more explicit notation introduced previously,
The corresponding position expressed in the base frame is
Equivalently, using homogeneous coordinates,
In Moro, this quantity is obtained through
robot.r_cm(i)
.
The local vector
is a constant physical parameter of the link, while
depends on the current robot configuration.
Inertia tensor
The inertia tensor of link \(i\) is defined about its center of mass.
Moro assumes that the tensor supplied through inertia_tensors is expressed with respect to a frame:
located at \(C_i\),
aligned with the link frame \(\{i\}\).
We denote this tensor by
The superscript indicates the orientation of the axes used to express the tensor components.
Conceptually, the same inertia tensor expressed along axes parallel to the base frame is
In Moro,
robot.I_cm(i)
returns \(I_{C_i}^{\,i}\), while
robot.I_cm0(i)
returns the same tensor expressed in the base-frame orientation.
Gravity vector
Moro represents gravitational acceleration by
expressed in the base frame.
For example, if the \(z_0\) axis points vertically upward,
Moro does not assume a fixed gravity direction relative to the base frame. The user supplies the appropriate vector through
robot.gravity
.
Kinetic energy of a link
The kinetic energy of link \(i\) is the sum of translational and rotational contributions:
The translational term is
The rotational term is
Therefore,
This is the form used directly by Moro in link_kinetic_energy(i). The intermediate tensor \(I_{C_i}^{\,0}\) is useful conceptually, but Moro evaluates the rotated tensor directly as
Kinetic energy and Jacobians
From differential kinematics,
and
Substituting these expressions into the kinetic energy gives
The total kinetic energy is
In Moro, these quantities are available through
robot.link_kinetic_energy(i)
robot.kinetic_energy()
.
Potential energy
The gravitational potential energy of link \(i\) is
The total potential energy is therefore
This convention is used directly by Moro in
robot.link_potential_energy(i)
robot.potential_energy()
.
For example, if
then
Lagrangian
The Lagrangian of the manipulator is defined as
In general,
Moro provides this quantity through
robot.lagrangian()
.
Euler–Lagrange equations
For each generalized coordinate \(q_i\), the equation of motion is
Collectively, the \(n\) equations describe the inverse dynamic model of the robot.
Moro constructs these equations through
robot.dynamic_model()
.
The result is a list of symbolic equations, one for each joint.
Time-dependent joint variables
Dynamic analysis requires joint variables that depend on time:
Only then are
and
meaningful symbolic quantities.
Important
id=”dynamic-symbols” For dynamic analyses, joint variables should be defined as time-dependent symbolic functions.
Static SymPy symbols may be appropriate for purely kinematic calculations, but velocity- and acceleration-dependent expressions may become incomplete or incorrect when static symbols are used.
Moro emits warnings in velocity-dependent operations when static joint variables are detected. This applies, for example, to angular velocity, the Coriolis matrix, and the Euler–Lagrange dynamic model.
Geometric and physical parameters such as
may remain symbolic constants while
Matrix form of the dynamic model
The Euler–Lagrange equations can be reorganized as
This form separates the dynamic model into:
inertial effects,
Coriolis and centrifugal effects,
gravitational effects.
Moro can construct these quantities directly, without first expanding the complete Euler–Lagrange equations.
Inertia matrix
The kinetic energy can be written in quadratic form as
Using the link Jacobians, the inertia matrix is
This is the expression implemented by
robot.inertia_matrix()
.
The first term in each summand represents translational inertia, while the second represents rotational inertia.
For a physically valid rigid-body model, the inertia matrix has the theoretical properties
and, for nonzero \(\vec x\),
These properties characterize the usual symmetric positive-definite structure of the joint-space inertia matrix.
Christoffel symbols
Moro constructs the Coriolis matrix using Christoffel symbols of the first kind.
The convention used is
In the API,
robot.christoffel_symbols(i, j, k, M)
returns \(c_{ijk}\) for a supplied inertia matrix \(M\).
Coriolis matrix
The elements of the Coriolis matrix are defined by
Therefore,
The term that enters the equations of motion is
This vector contains the Coriolis and centrifugal effects associated with joint velocities.
Moro computes the matrix through
robot.coriolis_matrix()
.
Note
id=”coriolis-nonunique” The matrix representation \(C(\vec q,\dot{\vec q})\) is not unique in a completely abstract sense.
Moro uses the Christoffel-based convention defined above. When comparing formulations from different sources, the physically relevant quantity is the resulting velocity-dependent term in the equations of motion.
Gravity generalized-force vector
The gravity term is obtained from the gradient of the potential energy:
In component form,
Moro provides this vector through
robot.gravity_vector()
.
If
and
the dynamic equation reduces to
Thus, \(G(\vec q)\) represents the generalized forces required to balance gravity in static equilibrium.
Complete matrix formulation
After computing \(M\), \(C\), and \(G\), Moro assembles
through
robot.dynamic_model_matrix_form()
.
The vectors are
and
Energy and matrix formulations
Moro provides two routes for deriving the equations of motion.
Euler–Lagrange route
The energy-based route is
followed by
In Moro, the relevant methods are
robot.kinetic_energy()
robot.potential_energy()
robot.lagrangian()
robot.dynamic_model()
.
Matrix route
The direct matrix route constructs
and
independently, and then assembles
The relevant methods are
robot.inertia_matrix()
robot.coriolis_matrix()
robot.gravity_vector()
robot.dynamic_model_matrix_form()
.
These are not different physical models.
They are two algebraic routes to the same equations of motion.
Dynamic parameter assumptions
Not all dynamic parameters are treated identically by Moro.
Symbolic masses
If masses are initialized through the setter with None, Moro generates symbolic values
These are symbolic modeling parameters rather than identified physical properties.
Diagonal symbolic inertia tensors
If inertia tensors are initialized with None, Moro generates diagonal symbolic tensors of the form
This assumes zero products of inertia.
Important
id=”inertia-assumption” A diagonal inertia tensor is a modeling assumption, not a general property of every rigid body.
When products of inertia are relevant, the complete \(3\times3\) tensor should be supplied explicitly.
Center-of-mass positions
Center-of-mass positions are not generated automatically.
They must be supplied when required by the requested dynamic quantity.
Gravity
The gravity vector is also not generated automatically.
It must be defined when potential energy or gravity-dependent quantities are required.
Model state
Moro distinguishes between quantities that are:
explicitly defined,
generated under a documented assumption,
not set.
The current model state can be summarized through
robot.model_summary()
.
This distinction is useful because symbolic placeholders or default assumptions should not be interpreted as experimentally identified physical parameters.
Dynamic quantities in Moro
The main theory-to-API correspondence is:
Mathematical quantity |
Moro API |
|---|---|
\(m_i\) |
|
\(\vec r_{C_i}^{\,0}\) |
|
\(I_{C_i}^{\,i}\) |
|
\(I_{C_i}^{\,0}\) |
|
\(\vec v_{C_i}^{\,0}\) |
|
\(\vec\omega_i^{\,0}\) |
|
\(J_{v,C_i}\) |
|
\(J_{\omega,i}\) |
|
\(K_i\) |
|
\(P_i\) |
|
\(K\) |
|
\(P\) |
|
\(\mathcal L\) |
|
Euler–Lagrange equations |
|
\(M(\vec q)\) |
|
\(c_{ijk}\) |
|
\(C(\vec q,\dot q)\) |
|
\(G(\vec q)\) |
|
\(M\ddot q+C\dot q+G=\tau\) |
|
Example workflow
A typical symbolic dynamic-modeling workflow is:
import moro as mr
robot = mr.Robot(...)
robot.masses = [...]
robot.cm_positions = [...]
robot.inertia_tensors = [...]
robot.gravity = [...]
M = robot.inertia_matrix()
C = robot.coriolis_matrix()
G = robot.gravity_vector()
model = robot.dynamic_model_matrix_form()
Alternatively, the same model can be derived through the energy formulation:
K = robot.kinetic_energy()
P = robot.potential_energy()
L = robot.lagrangian()
equations = robot.dynamic_model()
The two workflows provide different symbolic routes to the same physical equations of motion.
Scope and limitations
The current dynamic-modeling capabilities of Moro include:
link masses,
center-of-mass locations,
full or diagonal inertia tensors,
arbitrary gravity direction expressed in the base frame,
translational and rotational kinetic energy,
gravitational potential energy,
Lagrangian formulation,
Euler–Lagrange equations,
joint-space inertia matrix,
Christoffel symbols,
Coriolis matrix,
gravity generalized-force vector,
inverse dynamic equations in matrix form.
The current implementation does not provide:
numerical forward-dynamics integration,
numerical simulation of \(\vec q(t)\) from applied forces,
contact dynamics,
collision forces,
friction models,
actuator dynamics,
external wrench handling in the dynamic equations.
Summary of conventions
Concept |
Moro convention |
|---|---|
Dynamic coordinates |
\(q_i=q_i(t)\) |
Generalized force |
\(\tau_i\) |
Revolute generalized force |
Torque |
Prismatic generalized force |
Linear force |
CoM local position |
\(\vec r_{C_i}^{\,i}\) |
CoM base position |
\(\vec r_{C_i}^{\,0}\) |
Local inertia tensor |
\(I_{C_i}^{\,i}\) |
Base-oriented inertia tensor |
\(R_i^0I_{C_i}^{\,i}(R_i^0)^T\) |
Gravity |
\(\vec g^{\,0}\) expressed in base frame |
Link kinetic energy |
Translational + rotational |
Potential energy |
\(-m_i(\vec g^{\,0})^T\vec r_{C_i}^{\,0}\) |
Lagrangian |
\(\mathcal L=K-P\) |
Gravity vector |
\(G=\nabla_qP\) |
Inertia matrix |
Jacobian-based link sum |
Coriolis convention |
Christoffel symbols of the first kind |
Dynamic model |
\(M\ddot q+C\dot q+G=\tau\) |
Current scope |
Symbolic modeling / inverse dynamics |
Forward time integration |
Not currently provided |
Dynamics completes the progression from geometry and motion to generalized forces. Forward kinematics determines where the robot is, differential kinematics relates joint rates to Cartesian velocities, and the dynamic model determines the forces required to produce a prescribed joint motion.