An N-Jointed Arm is a robotic arm that is made up of N number of joints and N number of lengths, with each joint followed by a length.
Inverse Kinematics is the process of finding the needed rotation of each joint in a robotic arm given the lengths of each arm segment and the desired position of the arm’s end effector.
This post describes the math behind finding an inverse kinematics solution for a robotic arm with any number of joints. The context of this post is in a two-dimensional space.
In this post, the joints and lengths of a robotic arm are stored in arrays J and L, respectively.
Joint J[0] represents the rotation of the joint nearest to the base of the arm, and J[N-1] represents the rotation of the joint nearest to the end of the arm. Lengths are referenced using similar notation.
In the image below, we have an arm with N = 4. The blue dot is the base of the arm and the red dot represents the endpoint.
Each joint is represented by a decimal number which indicates the rotation of that joint. Joint values are in local space, where they are relative to the rotation of the parent joint. A joint at 0 degrees points directly outwards, in line with the parent/previous joint. A joint at 90 degrees points 90 degrees in a counter-clockwise direction relative to its parent. The base joint J[0] has no parent and points in the positive X direction when at 0 degrees.
Forward Kinematics
Forward kinematics is the method of finding the end-point of a robotic arm given the joint rotations and lengths.
The general formula for finding the vector of an arm segment is:
Vector2d( cos(J[i]), sin(J[i]) ) * L[i]
The first joint is considered at the origin, X and Y coordinates (0.0, 0.0). The second joint is positioned at a vector of the first length, L[0], at the first angle, J[0].
If the first joint, J[0], is 45 degrees and has a length, L[0], of 2 units, according to the general formula the end of the first segment is located at the point (1.414, 1.414) with a rotation of 45 degrees.
From there, if the local angle of the second joint, J[1], is -90 degrees, relative to the parent, we can calculate the global angle of the second joint to be J[0] + J[1] = 45 + (-90) = -45 degrees.
According to the general formula, the second segment is the vector with a global angle of -45 degrees and length L[1] of 2 units (1.414, -1.414). Offsetting this with the first segment’s vector gives us the final end-point (2.828, 0.0).
Two-Joint Inverse Kinematics
The two-joint inverse kinematics solution is the basis for multiple-joint solutions.
Given two lengths, L[0] and L[1], and the desired end-point, a two-joint inverse kinematics solution will result in the angles J[0] and J[1] that position the arm’s end effector at the end-point.
This two-joint solution can be calculated from the intersection point of two circles. The first circle is centered at the point (0, 0) and has a radius L[0]. The second circle is centered at the desired end-point and has a length of L[1].
There are no intersections where the endpoint is out of the arm’s range. There is only one intersection where L[0] + L[1] is equal to the distance to the endpoint. If the sum of the lengths is greater than the distance to the endpoint, there are two points where the circles intersect. We arbitrarily choose one for this project.
With an intersection point, we can calculate the angle of each joint that results in the given endpoint.
Expanding To N-Joints
With more than two joints, there are infinite solutions to a 2D jointed arm inverse kinematics problem. “Infinite” means slight variations biased towards the base or the end-point.
To determine one solution, we have to provide N – 2 weights. Each weight is a decimal number between +0.0 and +1.0, inclusive, that biases the corresponding joint towards and away from the endpoint.
To find the angle of a joint (hereby referred to as J‘) when there are three or more uncalculated joints left, we calculate J’ as if it was the first segment of a two-jointed arm solution. The second segment of that solution is calculated from the remaining segments.
A collection of arm segments will have an upper and lower bound of range depending on the lengths involved. We use the given weight to calculate a value that lies between the upper and lower bounds. We will use this as a length, and as the second segment for that two-joint solution, along with the length of J’.
Calculating the angles from a two-joint solution using the length associated with J’ and the weighted second length, we get an angle for J’. By using a weighted length between the upper and lower bounds of the remaining arm segments, we ensure that there will still be a valid solution for the remaining joints that will reach the given endpoint.
From here, we would either run the same logic with the next joint if there are still three or more joints remaining, or if there are only two joints we would run a simple two-joint solution and calculate the final joint angles.
The following example uses three lengths of 1 unit, a weight of 0.7, and an endpoint of (2.09, 0.0).
Joint Limits
Physical joints typically have a limit to the range of motion they can achieve. Unlike real life, the implementation here gives each joint an unlimited, 360-degree range of motion.
This implementation may still be used without joint limiting in some situations where the user ensures that all possible theoretical solutions in a defined working area satisfy realistic joint limits.
The Software
I developed a python3 program as a proof of concept and testing, used to visualize the math throughout this post.