Computing the magnitude of a spatial velocity
When adding some concept of "pose naturalness" to an IK solver model I was building, I came across this mysterious char_len term. These notes elaborate on the math behind computing the magnitude of a spatial velocity!
TL;DR: Naturalness metrics (e.g. manipulability) derived upon the spatial Jacobian entail mixing the units of translational vs. angular velocity, and there provably exists no canonical mixing method in .
Spatial Jacobian
The spatial Jacobian maps joint velocities to both linear velocity and angular velocity :
What manipulability is actually asking
A manipulator with joint angles has end-effector velocity (a twist) given by: Yoshikawa's manipulability ellipsoid is the image of the unit ball of joint velocities (unit ball of joint velocities → ellipsoid of task-space velocities)and the scalar manipulability is (proportional to) its volume, with the singular values of . The condition number is , defined as:
Let's analyze the intuition behind these quantities!
- Volume of measures - "how much velocity-space does the ellipsoid fill?"
- The axis lengths measure - "how long is this twist?" (longer means that, on a relative scale, small changes in joint velocity map to larger changes in task-space velocity)
- Condition number measures - "how does the length of one twist compare to the length of another?"
Each of these ^ requires asking "how long is ?" and "what is the angle between and ?" To answer these questions, we need to take the inner product of on itself:
- 💡 Manipulability requires measuring distances within velocity space .
- 💡 ^ We can prove that SVD on requires computing : https://share.gemini.google/9bepvZCI4vNb
Measuring distances within is a finicky business
If we want to compute the magnitude of a spatial velocity, we may be tempted to use the standard Euclidean inner product: But this equation doesn't make physical sense! We can't meaningfully add to .
- ⚠️ Because the units are heterogenous, the space is non-Euclidean.
- ⚠️ Changing units will change the singular values of ! We can see this explicitly with an example.
- Let be the geometric Jacobian expressed in meters. We can partition it into its linear and angular components: The singular values of are the square roots of the eigenvalues of the matrix . Expanding this, we get: Now, let's change our linear units from meters to mm - the angular velocity component remains untouched, but the linear velocity component scales by a factor of . Mathematically, this unit swap is equivalent to multiplying by a diagonal scaling matrix : The new Jacobian in mm () becomes: Computing , we get: We can see without computation that has different eigenvalues from , so has different singular values from : the singular value spectrum distorts anisotropically.
- ⚠️ ^ By changing units from meters to mm, a robot configuration that looked perfectly well-conditioned can suddenly appear horribly ill-conditioned if our definition of "well vs. ill conditioned" relies on the singular values of .
Definition (Euclidean -space): A Euclidean -space is the coordinate space equipped with the dot product inner product. (Read more in: https://en.wikipedia.org/wiki/Inner_product_space)
Summary of the problem
The problem: Computing the magnitude of a raw spatial velocity vector yields a physically contradictory mix of units.
- 🔑 Can we find a mathematical operator that steps in before the dot product occurs - to neutralize the angular units and convert everything into a single, homogeneous unit metric?
- Standard SVD algorithms (e.g. PyTorch, C++ Eigen, ...) do not know what meters or radians are - so we need to feed them matrices where units have been "stripped out."
- Under the hood, standard SVD computes singular values using the standard Euclidean dot product
- As we proved earlier, if you feed the raw spatial Jacobian into a standard SVD solver, it implicitly computes , returning a physically meaningless answer.
- 💡 Solution^: Pre-warp the Jacobian matrix so that when we feed it into a standard SVD solver, the solver computes the correct physics.
Roadmap for the solution
Goal: Create a new, physically-meaningful variant of the Jacobian ("warped ") that strips out units so that it is safe to feed to an SVD solver.
- SVD() requires computing , which is physically meaningless in its vanilla form.
- Define a "legal" inner product that is "unitless"
- We want to create a warped Jacobian s.t. the standard SVD solver will auto resolve to computing instead of the problematic . How do we do this?
- The relation we need to preserve for this to work out is: , for some that we can define.
- ^ Working this out will show: needs to equal → we can define and voila!
(Read the following sections for more math.)
Constructing the metric tensor
Background knowledge
When a space is non-Euclidean (i.e. the standard dot product doesn't work), we can define a valid inner product by introducing a metric tensor, denoted . The metric tensor intercepts the two vectors being multiplied and maps them properly.
The new, legally valid inner product becomes:
- To convert a rotational displacement (radians) into a linear displacement (meters), we use the classical arc length formula: , where is a radius (length) and is the angle in radians.
Math for constructing
We need the equation to output a scalar where every term strictly has units of .
- Let be a symmetric block-diagonal matrix. To keep the linear velocity terms exactly as they are (since they are already in ), the top-left block of must simply be the identity matrix .
- To fix the angular velocity terms, we must multiply the terms by a squared length. Introduce a characteristic length measured in meters.
- The bottom-right block of becomes :
- Let's verify that this fixes the unit mismatch: Let's check units! (^ because radians are unit-less.)
Recap so far
By applying , has been successfully metricized into a Euclidean space! With , we can legally compute the squared magnitude of a spatial velocity vector.
- 🔑 Next, we need to apply this metric tensor directly to the Jacobian , so that when we compute the SVD of the Jacobian, it inherently respects this new unit-consistent space.
Decomposing to scale the Jacobian
Background knowledge
In linear algebra, if a matrix is symmetric and positive-definite, it can be decomposed into the product of a matrix and its transpose.
Positive-definite matrix: A symmetric matrix with real entries is positive-definite if the real number is positive for every nonzero real column vector .
- Our constructed earlier is positive-definite since , so we can write: Let's work through the proof that is positive-definite:
- We need to show that , .
- [FILL IN LATER] last message on https://share.gemini.google/AOUPEFskNeoF
- We'll substitute with inside our inner product equation, regroup the terms, and see what happens to the velocity vector .
Math to embed directly into to create a new, pre-scaled matrix
Let's find the weighting matrix such that . Because is block-diagonal, is simply the square root of the diagonal blocks: Now, substitute back into our legally valid inner product: The term is just a new 6D vector - let's call it . By multiplying by , we created a mapped velocity vector that naturally lives in a perfectly Euclidean space (i.e. - has a valid inner product!). Since we know that the raw velocity is generated by the raw Jacobian (), we can substitute that into our equation: The term is our scaled spatial Jacobian!
Recap so far
We've created a warped Jacobian such that so when we feed it to a standard SVD solver, the solver will be computing under the hood (the physically meaningful, unit-independent magnitude) instead of (the physically meaningless number we started with).
- 🔖 Next: How do we pick ?
Physical grounding of
What should be?
Intuition: can be interpreted as "how many meters of translation we treat as equivalent to 1 rad of rotation."
- 🔑 needs to convert "1 radian of rotation" into "← some matching number of meters"
- 💡 We can use the classical relation :
- ^ so the conversion factor we want for $L$ is "the radius at which the end-effector typically swings" - which is its typical moment arm (moment arm := lever arm := robot arm)! 1 radian of EE rotation drags the EE roughly $r$ meters, so setting $L = r$ makes 1 radian of rotation count the same as the $r$ meters of linear sweep it actually produces.
- 📍 But isn't a single number - it changes with configuration as the arm folds and extends!
- To freeze one into , we need a single representative radius - we can take the median EE reach, i.e.:

- To freeze one into , we need a single representative radius - we can take the median EE reach, i.e.:
- ⚠️ Notice that is a choice: we need to freeze it in downstream usages and use the same value everywhere for one robot!