Jacobians
moro provides tools for computing geometric Jacobians for the end-effector, arbitrary points on the manipulator, and link centers of mass.
The geometric Jacobian relates joint velocities to the linear and angular velocity of a point attached to the robot.
This section focuses on how to compute and inspect Jacobians in moro. For the mathematical derivation and interpretation of differential kinematics, see Theory → Differential Kinematics.
End-effector Jacobian
Once a Robot has been defined, the geometric Jacobian of the end-effector is available through the J property.
Consider a planar 2R manipulator:
from moro import Robot
from moro.abc import q1, q2, l1, l2
robot = Robot(
(l1, 0, 0, q1, "r"),
(l2, 0, 0, q2, "r"),
)
The end-effector Jacobian is:
J = robot.J
J
For a robot with \(n\) degrees of freedom, the geometric Jacobian has size:
It can be written as:
where:
\(J_v\) relates joint velocities to the linear velocity of the point;
\(J_\omega\) relates joint velocities to its angular velocity.
For robot.J, the point of interest is the origin of the final frame {n}, that is, the end-effector origin.
Linear and angular components
The linear and angular parts of a geometric Jacobian can be obtained directly by slicing the resulting SymPy matrix:
Jv = robot.J[:3, :]
Jw = robot.J[3:, :]
The upper part,
Jv
contains the linear-velocity contribution, while:
Jw
contains the angular-velocity contribution.
For a joint-velocity vector:
the corresponding end-effector velocities satisfy:
and:
Because the Jacobian is symbolic, these relationships can be inspected before assigning numerical values to the joint coordinates.
Jacobian of an arbitrary point
The Jacobian does not need to be restricted to the origin of the end-effector frame.
Use:
robot.J_point(point, i)
to compute the geometric Jacobian of a point attached to link i.
The coordinates in point must be expressed with respect to frame {i}.
For example:
Jp = robot.J_point([0.2, 0, 0], 2)
computes the Jacobian of a point located \(0.2\) units along the \(x_2\)-axis from the origin of frame {2}.
The point can be specified using a list, tuple, or a compatible SymPy vector.
For the origin of frame {i}, use:
Ji = robot.J_point([0, 0, 0], i)
The end-effector Jacobian itself is equivalent to:
robot.J_point([0, 0, 0], robot.dof)
This makes J_point() the most general Jacobian interface for points rigidly attached to the robot links.
Revolute and prismatic joint contributions
The columns of the geometric Jacobian depend on the corresponding joint type.
For a revolute joint \(j\), the contribution to a point located at \(p\) is:
and:
For a prismatic joint:
and:
moro builds these contributions automatically from the joint types stored in the Robot model.
For a point attached to link i, joints located after that link do not affect its motion. Their corresponding Jacobian columns are therefore zero.
For example, in a three-joint robot, the Jacobian of a point attached to link 2 has no contribution from joint 3.
The mathematical derivation of these expressions is covered in Theory → Differential Kinematics.
Center-of-mass Jacobians
moro also provides Jacobians for the centers of mass of individual links.
These are especially useful in dynamic modeling.
Before computing them, the center-of-mass position of each link must be defined:
robot.cm_positions = [
(...),
(...),
]
Each center-of-mass position is expressed with respect to the corresponding link frame.
For example, for a planar 2R robot:
from moro.abc import lc1, lc2
robot.cm_positions = [
(-lc1, 0, 0),
(-lc2, 0, 0),
]
Full center-of-mass Jacobian
The geometric Jacobian of the center of mass of link i is:
Jcm = robot.J_cm_i(i)
For example:
Jcm1 = robot.J_cm_i(1)
Jcm2 = robot.J_cm_i(2)
Each result has size:
Linear center-of-mass Jacobian
The linear part is available directly through:
Jv_cm = robot.Jv_cm_i(i)
For example:
Jv1 = robot.Jv_cm_i(1)
This is equivalent to the first three rows of the full center-of-mass Jacobian.
Angular center-of-mass Jacobian
The angular part is:
Jw_cm = robot.Jw_cm_i(i)
For example:
Jw1 = robot.Jw_cm_i(1)
This corresponds to the lower three rows of robot.J_cm_i(i).
These quantities are used internally when constructing dynamic terms such as the manipulator inertia matrix.
Evaluating a configuration
As with the forward-kinematics results, Jacobians returned by moro are symbolic SymPy matrices.
Consider the configuration:
Define:
from sympy import pi
values = {
l1: 1,
l2: 0.8,
q1: pi / 4,
q2: -pi / 6,
}
The end-effector Jacobian can then be evaluated with:
J_num = robot.J.subs(values)
and converted explicitly to floating-point values with:
J_num.evalf()
The same approach applies to arbitrary-point Jacobians:
Jp = robot.J_point([0.2, 0, 0], 2)
Jp_num = Jp.subs(values).evalf()
and to center-of-mass Jacobians:
Jcm2_num = robot.J_cm_i(2).subs(values).evalf()
provided all symbolic center-of-mass parameters are also included in the substitution dictionary.
Working with symbolic results
Because the Jacobians are SymPy matrices, they can be manipulated with standard symbolic operations.
For example:
from sympy import simplify
J = simplify(robot.J)
The linear and angular parts can be extracted:
Jv = J[:3, :]
Jw = J[3:, :]
Individual columns can also be inspected:
J1 = J[:, 0]
J2 = J[:, 1]
This is useful when studying how individual joints contribute to the velocity of the end-effector.
You can also inspect the rank of a numerically evaluated Jacobian:
J_num = robot.J.subs(values)
J_num.rank()
or compute symbolic expressions involving its entries.
For larger symbolic models, simplification may become computationally expensive, so it is often useful to simplify only the expressions that are relevant to the current analysis.
A worked example
Consider again a planar two-link robot:
from moro import Robot
from moro.abc import q1, q2, l1, l2
robot = Robot(
(l1, 0, 0, q1, "r"),
(l2, 0, 0, q2, "r"),
)
The end-effector Jacobian is:
J = robot.J
Its linear component is:
Jv = J[:3, :]
and its angular component is:
Jw = J[3:, :]
Now consider a point located halfway along the second link, assuming l2 represents its full length:
J_mid = robot.J_point(
[-l2 / 2, 0, 0],
2,
)
This point has a different linear Jacobian from the end-effector because its position relative to the joints is different.
Its angular Jacobian, however, is determined by the same revolute joints that affect link 2.
We can compare the linear parts:
Jv_end = robot.J[:3, :]
Jv_mid = J_mid[:3, :]
Now evaluate both at a specific configuration:
from sympy import pi
values = {
l1: 1,
l2: 0.8,
q1: pi / 4,
q2: -pi / 6,
}
Jv_end_num = Jv_end.subs(values).evalf()
Jv_mid_num = Jv_mid.subs(values).evalf()
This illustrates an important distinction:
same robot
+
same joint configuration
↓
different point on the robot
↓
different linear Jacobian
The J_point() interface makes it possible to compute these quantities without defining a separate robot model.
Notes and conventions
When working with Jacobians in moro, keep the following points in mind:
robot.Jis the geometric Jacobian of the end-effector origin;geometric Jacobians have size \(6\times n\);
the first three rows correspond to linear velocity;
the last three rows correspond to angular velocity;
robot.J_point(point, i)expects the point coordinates to be expressed in frame{i};the resulting Jacobian describes the point motion with respect to the base frame;
revolute and prismatic joints are handled automatically according to the robot model;
joints located after the link containing the point contribute zero columns;
center-of-mass Jacobians require
robot.cm_positionsto be defined;Jacobian results are symbolic SymPy matrices unless numerical values are substituted.
The Jacobians returned by moro are geometric Jacobians. Analytical Jacobians associated with specific minimal orientation parameterizations are outside the current scope of this interface.
See also
Forward Kinematics — compute the frame positions and axes used in geometric Jacobian construction.
Robot Modeling — define revolute and prismatic joints and their parameters.
Inverse Kinematics — use Jacobian-based numerical methods to solve position inverse kinematics problems.
Dynamics — use center-of-mass Jacobians when deriving the manipulator dynamic model.
Theory → Differential Kinematics — mathematical derivation and interpretation of the geometric Jacobian.
API Reference → Robot — complete signatures and descriptions for
J,J_point(),J_cm_i(),Jv_cm_i(), andJw_cm_i().