I'm working on a project with a friend of mine, Matthew Ebisu. He's really into robots and is most interested in applying the art of animation to robots. Below is a 3D-printed robot arm which is being controlled from Maya.
I designed the Maya rig to have FK and two versions of IK chains (arc and spring), and they can all blend between each other.
The IK arc chain is controlled by an expression that I wrote based on some simple geometry.
$pitch = 0.0;
if (IK_ctrl.translateX >= 0){
$pitch = IK_aim.rotateZ;
}
else {
$pitch = IK_aim.rotateZ - 180.0;
}
$lenRatio = `min 1 (shortDistShape.distance / armDistShape.distance)`;
shoulder_IKarc_jnt.rotateY = acosd (1.5 * $lenRatio - 0.5) + $pitch;
elbow_IKarc_jnt.rotateY = (-1.0) * acosd (1.5 * $lenRatio - 0.5);
wrist_IKarc_jnt.rotateY = (-1.0) * acosd (1.5 * $lenRatio - 0.5);$pitch is used to tilt the base joint to meet the IK control.
IK_aim is a Locator on the base aim constrained to another Locator in the same location as the IK control.
$lenRatio is the ratio of the compressed arm length to the uncompressed arm length. I used Maya's Distance Tool for this.
If the ratio exceeds 1 (IK control pulled beyond limit), use 1 for later calculations.
...And the rest is geometry. Yay math!
For IK spring mode, the user controls the first joint, and the last two are determined by an IK rotate plane solver.
I also wrote an expression for calibrating the servos. When I first got to work on the project, I noticed the digital and physical rigs were off by about 90 degrees. I first hard coded the values, then later added keyable controls. This is because servos have a hard time maintaining calibration. If they moved too quickly, calibration would be thrown off by as much as 25 degrees.
$sFlip = ((-2) * options_ctrl.shoulderFlip) + 1; servoWrite2.input = ($sFlip)*(calibrateNode2.valueY + options_ctrl.shoulderOffset); $eFlip = ((-2) * options_ctrl.elbowFlip) + 1; servoWrite3.input = ($eFlip)*(calibrateNode3.valueY + options_ctrl.elbowOffset); $wFlip = ((-2) * options_ctrl.wristFlip) + 1; servoWrite4.input = ($wFlip)*(calibrateNode4.valueY + options_ctrl.wristOffset);
The Flip controls determine the spin direction given the sign of the degree change. They are booleans, hence the need to convert from a 0 or 1 to 1 or -1, respectively.
The Offset controls are floats between -180 and 180 and currently stay at around -90 or 90 depending on the servo.
Lastly, I didn't play with the spinning servo much because the one installed now is very jittery, making it impossible to calibrate. We'll use heavier duty servos in later stages.
More to come later.


































