On 5/21/2011 10:25 AM, Viesturs Lācis wrote:
> 2011/5/21 Kent A. Reed<knbr...@erols.com>:
>> True, true. But I note that the functions like pmQuatZyzConvert are
>> marked "FIXME - - need direct equations"". In mathematics, the two
>> approaches (one conversion or two concatenated conversions) are
>> equivalent. In computer math, not so much. It may make no practical
>> difference for Viesturs' application but I like the direct approach.
> Yohoooo!!!
> I have made some progress in genserkins with linear joints:
> The travel distance on linear joint matches in both joint and teleop mode!
>
> Now the only remaining problem is to allign XYZ of the arm with XYZ of
> the base. Now only Z matches.
> It _should_ be easy with alpha and theta angles of DH parameters, but
> it is not... At least for me. But I hope that I will fix it and then
> those zyz<-->rpy conversions will not be necessary.
>
> Viesturs
Viesturs:

If linear joints work for you, then so much the better.

Just in case you end up needing or just want to try the zyz<-->rpy 
conversions, you can take the two-step approach that Andrew suggested.

In your forward and inverse routines, you will need to define a scratch 
rotation matrix to hold an intermediate result and replace the single 
calls to posemath routines with two, back-to-back calls. I took the 
liberty of replacing the constants (180/PM_PI) and (PM_PI/180) with 
their equivalent definitions in posemath.

---snip---

int kinematicsForward(const double * joint,
                       EmcPose * world,
                       const KINEMATICS_FORWARD_FLAGS * fflags,
                       KINEMATICS_INVERSE_FLAGS * iflags)
{
     double a3, a4, a5;

     PmEulerZyz zyz;
     PmRpy rpy;
     PmRotationMatrix rotMat;

     /* convert joint angles to radians for sin() and cos() */

     a3 = joint[3] * TO_RAD;
     a4 = joint[4] * TO_RAD;
     a5 = joint[5] * TO_RAD;

     /* assign joint values to Zyz angles */
     zyz.z = a3;
     zyz.y = a4;
     zyz.zp = a5;

     /* use Euler's Zyz to Rpy conversion*/
#    pmZyzRpyConvert(zyz,&rpy);
     pmZyzMatConvert(zyz,&rotMat);
     pmMatRpyConvert(rotMat,&rpy);

     world->tran.x = joint[0];
     world->tran.y = joint[1];
     world->tran.z = joint[2];
     world->a = rpy.r * TO_DEG;
     world->b = rpy.p * TO_DEG;
     world->c = rpy.y * TO_DEG;

     return (0);
}

int kinematicsInverse(const EmcPose * world,
                       double * joint,
                       const KINEMATICS_INVERSE_FLAGS * iflags,
                       KINEMATICS_FORWARD_FLAGS * fflags)
{
     PmEulerZyz zyz;
     PmRpy rpy;
     PmRotationMatrix rotMat;

     rpy.r = world->a * TO_RAD;
     rpy.p = world->b * TO_RAD;
     rpy.y = world->c * TO_RAD;

     /* convert Rpy angles to Euler's Zyz */
#    pmRpyZyzConvert(rpy,&zyz);
     pmRpyMatConvert(rpy,&rotMat);
     pmMatZyzConvert(rotMat,&zyz);

     joint[0] = world->tran.x;
     joint[1] = world->tran.y;
     joint[2] = world->tran.z;
     joint[3] = zyz.z * TO_DEG;
     joint[4] = zyz.y * TO_DEG;
     joint[5] = zyz.zp * TO_DEG;

     return (0);
}

---snip---


I did this quickly and didn't attempt to compile and link, so check my 
work carefully, especially any use of pointers---they are always my 
nemesis using C!

This solution has several appealing characteristics.

1) you can implement it right now, without any changes to posemath.
2) I can focus on the direct functions without concern that I'm standing 
in the way.

Good luck with whichever approach you take...

Regards,
Kent


------------------------------------------------------------------------------
What Every C/C++ and Fortran developer Should Know!
Read this article and learn how Intel has extended the reach of its 
next-generation tools to help Windows* and Linux* C/C++ and Fortran 
developers boost performance applications - including clusters. 
http://p.sf.net/sfu/intel-dev2devmay
_______________________________________________
Emc-users mailing list
Emc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/emc-users

Reply via email to