Extending
Tekkotsu to New
Platforms
Inverse Kinematics
At first, we
thought that inverse kinematics would simply "work" as soon as the
kinematics file was correct. This was partially correct. ROBOOP has a
suite of inverse kinematics solvers. inv_kin_pos is what was used by
default. It solves only for the position of the end effector and
ignores the orientation. This function worked, but it's useless for
real work. If the orientation of the gripper cannot be specified, how
can the robot do any meaningful work? If it tries to pick up an object,
it could come from the side, or from the top, or from some weird
diagonal angle. Since it is so unpredictable, it would not be able to
pick up anything except the most basic of shapes. Even though there was
also an inv_kin_orientation function, it was useless to us as well.
Solving for position and then for orientation would result in the
position being incorrect. We needed to solve for both parameters
simultaneously.
We then looked to ROBOOP's general inverse kinematics solver, which
would take a matrix containing both orientation and position, as a
solution. However, this was even less successful than inv_kin_position.
The theta_min and theta_max parameters are apparently ignored by
ROBOOP, and inv_kin assumes that each joint has a 360-degree range of
motion. Since every joint on the arm has a 180-degree range of motion,
this resulted in out-of-bounds joint values that the arm couldn't
possibly use. When we used these parameters, the arm would strain when
it reached its maximum positions, and then the servo at that joint
would deactivate.
We tried one final approach. ROBOOP had a special-purpose solver for a
type of arm called a Rhino, which is a 5-DOF robot arm. It seemed to us
that it would be possible to construct a special-purpose kinematics
file that would make the Lynxmotion arm appear, for all intents and
purposes, to be a Rhino. While we were able to accomplish that, even
more headaches cropped up. Forward kinematics stopped behaving as
expected; the parameter of link 1 seemed to be applied at link 0, while
link 1 had no d parameter. In
addition, the detection for the arm demands that only 5 links be
present, so the gripper had to be left out of the chain. This meant
that the gripper was not associated with a tekkotsu_output, and we
could not control it. As a result, inv_kin_rhino was just as big of a
bust as the other two approaches.
As a result, we have no meaningful inverse kinematics for the arm at
this point in time. We've identified a number of potential solutions
for the problem, none of which are particularly straightforward:
- Construct
a generalized inverse kinematics solver that obeys joint limits
specified by theta_min and theta_max. However, this requires a huge
number of changes to ROBOOP just to be able to access theta_min and
theta_max, much less the additional complexity in solving kinematics
equations given flexible joint boundaries.
- Find the
bug in the Rhino code that is breaking forward kinematics. Also, remove
the requirement that a tekkotsu_output be listed in the kinematics
file. This would let us use the Rhino codebase and still be able to use
the gripper. However, we had no luck at identifying that bug, much less
how changing out tekkotsu_outputs were constructed.
- Construct
an iterative inverse kinematics solver as Ethan has done for the Aibo.
This is by far the least attractive option. It is not generalized at
all, and the fucntion seems to grow exponentially in complexity with
each additional link. In addition, it's probably much slower than the
analytic solver (perhaps even to the point of rendering it useless).