On 5/21/2011 10:25 AM, Viesturs Lācis wrote:
> 2011/5/21 Kent A. Reed<[email protected]>:
>> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/emc-users