⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _posemath.c

📁 Source code for an Numeric Cmputer
💻 C
📖 第 1 页 / 共 3 页
字号:
/********************************************************************* Description: _posemath.c*    C definitions for pose math library data types and manipulation*    functions.**   Derived from a work by Fred Proctor & Will Shackleford** Author:* License: LGPL Version 2* System: Linux*    * Copyright (c) 2004 All rights reserved.** Last change: * $Revision: 1.10 $* $Author: jmkasunich $* $Date: 2005/08/06 17:56:56 $********************************************************************/#if defined(PM_PRINT_ERROR) && defined(rtai)#undef PM_PRINT_ERROR#endif#if defined(PM_DEBUG) && defined(rtai)#undef PM_DEBUG#endif#ifdef PM_PRINT_ERROR#define PM_DEBUG		/* have to have debug with printing */#include <stdio.h>#include <stdarg.h>#endif#include "posemath.h"#include "sincos.h"/* global error number */int pmErrno = 0;#ifdef PM_PRINT_ERRORvoid pmPrintError(const char *fmt, ...){    va_list args;    va_start(args, fmt);    vfprintf(stderr, fmt, args);    va_end(args);}/* error printing function */void pmPerror(const char *s){    char *pmErrnoString;    switch (pmErrno) {    case 0:	/* no error */	return;    case PM_ERR:	pmErrnoString = "unspecified error";	break;    case PM_IMPL_ERR:	pmErrnoString = "not implemented";	break;    case PM_NORM_ERR:	pmErrnoString = "expected normalized value";	break;    case PM_DIV_ERR:	pmErrnoString = "divide by zero";	break;    default:	pmErrnoString = "unassigned error";	break;    }    if (s != 0 && s[0] != 0) {	fprintf(stderr, "%s: %s\n", s, pmErrnoString);    } else {	fprintf(stderr, "%s\n", pmErrnoString);    }}#endif /* PM_PRINT_ERROR *//* fuzz checker */#define IS_FUZZ(a,fuzz) (fabs(a) < (fuzz) ? 1 : 0)/* Pose Math Basis Functions *//* Scalar functions */double pmSqrt(double x){    if (x > 0.0) {	return sqrt(x);    }    if (x > SQRT_FUZZ) {	return 0.0;    }#ifdef PM_PRINT_ERROR    pmPrintError("sqrt of large negative number\n");#endif    return 0.0;}/* Translation rep conversion functions */int pmCartSphConvert(PmCartesian v, PmSpherical * s){    double _r;    s->theta = atan2(v.y, v.x);    s->r = pmSqrt(pmSq(v.x) + pmSq(v.y) + pmSq(v.z));    _r = pmSqrt(pmSq(v.x) + pmSq(v.y));    s->phi = atan2(_r, v.z);    return pmErrno = 0;}int pmCartCylConvert(PmCartesian v, PmCylindrical * c){    c->theta = atan2(v.y, v.x);    c->r = pmSqrt(pmSq(v.x) + pmSq(v.y));    c->z = v.z;    return pmErrno = 0;}int pmSphCartConvert(PmSpherical s, PmCartesian * v){    double _r;    _r = s.r * sin(s.phi);    v->z = s.r * cos(s.phi);    v->x = _r * cos(s.theta);    v->y = _r * sin(s.theta);    return pmErrno = 0;}int pmSphCylConvert(PmSpherical s, PmCylindrical * c){    c->theta = s.theta;    c->r = s.r * cos(s.phi);    c->z = s.r * sin(s.phi);    return pmErrno = 0;}int pmCylCartConvert(PmCylindrical c, PmCartesian * v){    v->x = c.r * cos(c.theta);    v->y = c.r * sin(c.theta);    v->z = c.z;    return pmErrno = 0;}int pmCylSphConvert(PmCylindrical c, PmSpherical * s){    s->theta = c.theta;    s->r = pmSqrt(pmSq(c.r) + pmSq(c.z));    s->phi = atan2(c.z, c.r);    return pmErrno = 0;}/* Rotation rep conversion functions */int pmAxisAngleQuatConvert(PmAxis axis, double a, PmQuaternion * q){    double sh;    a *= 0.5;    sincos(a, &sh, &(q->s));    switch (axis) {    case PM_X:	q->x = sh;	q->y = 0.0;	q->z = 0.0;	break;    case PM_Y:	q->x = 0.0;	q->y = sh;	q->z = 0.0;	break;    case PM_Z:	q->x = 0.0;	q->y = 0.0;	q->z = sh;	break;    default:#ifdef PM_PRINT_ERROR	pmPrintError("error: bad axis in pmAxisAngleQuatConvert\n");#endif	return -1;	break;    }    if (q->s < 0.0) {	q->s *= -1.0;	q->x *= -1.0;	q->y *= -1.0;	q->z *= -1.0;    }    return 0;}int pmRotQuatConvert(PmRotationVector r, PmQuaternion * q){    double sh;#ifdef PM_DEBUG    /* make sure r is normalized */    if (0 != pmRotNorm(r, &r)) {#ifdef PM_PRINT_ERROR	pmPrintError	    ("error: pmRotQuatConvert rotation vector not normalized\n");#endif	return pmErrno = PM_NORM_ERR;    }#endif    if (pmClose(r.s, 0.0, QS_FUZZ)) {	q->s = 1.0;	q->x = q->y = q->z = 0.0;	return pmErrno = 0;    }    sincos(r.s / 2.0, &sh, &(q->s));    if (q->s >= 0.0) {	q->x = r.x * sh;	q->y = r.y * sh;	q->z = r.z * sh;    } else {	q->s *= -1;	q->x = -r.x * sh;	q->y = -r.y * sh;	q->z = -r.z * sh;    }    return pmErrno = 0;}int pmRotMatConvert(PmRotationVector r, PmRotationMatrix * m){    double s, c, omc;#ifdef PM_DEBUG    if (!pmRotIsNorm(r)) {#ifdef PM_PRINT_ERROR	pmPrintError("Bad vector in pmRotMatConvert\n");#endif	return pmErrno = PM_NORM_ERR;    }#endif    sincos(r.s, &s, &c);    /* from space book */    m->x.x = c + pmSq(r.x) * (omc = 1 - c);	/* omc = One Minus Cos */    m->y.x = -r.z * s + r.x * r.y * omc;    m->z.x = r.y * s + r.x * r.z * omc;    m->x.y = r.z * s + r.y * r.x * omc;    m->y.y = c + pmSq(r.y) * omc;    m->z.y = -r.x * s + r.y * r.z * omc;    m->x.z = -r.y * s + r.z * r.x * omc;    m->y.z = r.x * s + r.z * r.y * omc;    m->z.z = c + pmSq(r.z) * omc;    return pmErrno = 0;}int pmRotZyzConvert(PmRotationVector r, PmEulerZyz * zyz){#ifdef PM_DEBUG#ifdef PM_PRINT_ERROR    pmPrintError("error: pmRotZyzConvert not implemented\n");#endif    return pmErrno = PM_IMPL_ERR;#else    return PM_IMPL_ERR;#endif}int pmRotZyxConvert(PmRotationVector r, PmEulerZyx * zyx){    PmRotationMatrix m;    int r1, r2;    r1 = pmRotMatConvert(r, &m);    r2 = pmMatZyxConvert(m, zyx);    return pmErrno = r1 || r2 ? PM_NORM_ERR : 0;}int pmRotRpyConvert(PmRotationVector r, PmRpy * rpy){    PmQuaternion q;    int r1, r2;    r1 = 0;    r2 = 0;    q.s = q.x = q.y = q.z = 0.0;    r1 = pmRotQuatConvert(r, &q);    r2 = pmQuatRpyConvert(q, rpy);    return r1 || r2 ? pmErrno : 0;}int pmQuatRotConvert(PmQuaternion q, PmRotationVector * r){    double sh;#ifdef PM_DEBUG    if (!pmQuatIsNorm(q)) {#ifdef PM_PRINT_ERROR	pmPrintError("Bad quaternion in pmQuatRotConvert\n");#endif	return pmErrno = PM_NORM_ERR;    }#endif    if (r == 0) {	return (pmErrno = PM_ERR);    }    sh = pmSqrt(pmSq(q.x) + pmSq(q.y) + pmSq(q.z));    if (sh > QSIN_FUZZ) {	r->s = 2.0 * atan2(sh, q.s);	r->x = q.x / sh;	r->y = q.y / sh;	r->z = q.z / sh;    } else {	r->s = 0.0;	r->x = 0.0;	r->y = 0.0;	r->z = 0.0;    }    return pmErrno = 0;}int pmQuatMatConvert(PmQuaternion q, PmRotationMatrix * m){#ifdef PM_DEBUG    if (!pmQuatIsNorm(q)) {#ifdef PM_PRINT_ERROR	pmPrintError("Bad quaternion in pmQuatMatConvert\n");#endif	return pmErrno = PM_NORM_ERR;    }#endif    /* from space book where e1=q.x e2=q.y e3=q.z e4=q.s */    m->x.x = 1 - 2 * (pmSq(q.y) + pmSq(q.z));    m->y.x = 2 * (q.x * q.y - q.z * q.s);    m->z.x = 2 * (q.z * q.x + q.y * q.s);    m->x.y = 2 * (q.x * q.y + q.z * q.s);    m->y.y = 1 - 2 * (pmSq(q.z) + pmSq(q.x));    m->z.y = 2 * (q.y * q.z - q.x * q.s);    m->x.z = 2 * (q.z * q.x - q.y * q.s);    m->y.z = 2 * (q.y * q.z + q.x * q.s);    m->z.z = 1 - 2 * (pmSq(q.x) + pmSq(q.y));    return pmErrno = 0;}int pmQuatZyzConvert(PmQuaternion q, PmEulerZyz * zyz){    PmRotationMatrix m;    int r1, r2;    /*! \todo FIXME-- need direct equations */    r1 = pmQuatMatConvert(q, &m);    r2 = pmMatZyzConvert(m, zyz);    return pmErrno = r1 || r2 ? PM_NORM_ERR : 0;}int pmQuatZyxConvert(PmQuaternion q, PmEulerZyx * zyx){    PmRotationMatrix m;    int r1, r2;    /*! \todo FIXME-- need direct equations */    r1 = pmQuatMatConvert(q, &m);    r2 = pmMatZyxConvert(m, zyx);    return pmErrno = r1 || r2 ? PM_NORM_ERR : 0;}int pmQuatRpyConvert(PmQuaternion q, PmRpy * rpy){    PmRotationMatrix m;    int r1, r2;    /*! \todo FIXME-- need direct equations */    r1 = pmQuatMatConvert(q, &m);    r2 = pmMatRpyConvert(m, rpy);    return pmErrno = r1 || r2 ? PM_NORM_ERR : 0;}int pmMatRotConvert(PmRotationMatrix m, PmRotationVector * r){    PmQuaternion q;    int r1, r2;    /*! \todo FIXME-- need direct equations */    r1 = pmMatQuatConvert(m, &q);    r2 = pmQuatRotConvert(q, r);    return pmErrno = r1 || r2 ? PM_NORM_ERR : 0;}int pmMatQuatConvert(PmRotationMatrix m, PmQuaternion * q){    /*        from Stephe's "space" book e1 = (c32 - c23) / 4*e4 e2 = (c13 - c31) /       4*e4 e3 = (c21 - c12) / 4*e4 e4 = sqrt(1 + c11 + c22 + c33) / 2       if e4 == 0 e1 = sqrt(1 + c11 - c33 - c22) / 2 e2 = sqrt(1 + c22 - c33       - c11) / 2 e3 = sqrt(1 + c33 - c11 - c22) / 2 to determine whether to       take the positive or negative sqrt value since e4 == 0 indicates a       180* rotation then (0 x y z) = (0 -x -y -z). Thus some generallities       can be used: 1) find which of e1, e2, or e3 has the largest magnitude       and leave it pos. 2) if e1 is largest then if c21 < 0 then take the       negative for e2 if c31 < 0 then take the negative for e3 3) else if e2        is largest then if c21 < 0 then take the negative for e1 if c32 < 0       then take the negative for e3 4) else if e3 is larget then if c31 < 0       then take the negative for e1 if c32 < 0 then take the negative for e2       Note: c21 in the space book is m.x.y in this C code */    double a;#ifdef PM_DEBUG    if (!pmMatIsNorm(m)) {#ifdef PM_PRINT_ERROR	pmPrintError("Bad matrix in pmMatQuatConvert\n");#endif	return pmErrno = PM_NORM_ERR;    }#endif    q->s = 0.5 * pmSqrt(1.0 + m.x.x + m.y.y + m.z.z);    if (fabs(q->s) > QS_FUZZ) {	q->x = (m.y.z - m.z.y) / (a = 4 * q->s);	q->y = (m.z.x - m.x.z) / a;	q->z = (m.x.y - m.y.x) / a;    } else {	q->s = 0;	q->x = pmSqrt(1.0 + m.x.x - m.y.y - m.z.z) / 2.0;	q->y = pmSqrt(1.0 + m.y.y - m.x.x - m.z.z) / 2.0;	q->z = pmSqrt(1.0 + m.z.z - m.y.y - m.x.x) / 2.0;	if (q->x > q->y && q->x > q->z) {	    if (m.x.y < 0.0) {		q->y *= -1;	    }	    if (m.x.z < 0.0) {		q->z *= -1;	    }	} else if (q->y > q->z) {	    if (m.x.y < 0.0) {		q->x *= -1;	    }	    if (m.y.z < 0.0) {		q->z *= -1;	    }	} else {	    if (m.x.z < 0.0) {		q->x *= -1;	    }	    if (m.y.z < 0.0) {		q->y *= -1;	    }	}    }    return pmQuatNorm(*q, q);}int pmMatZyzConvert(PmRotationMatrix m, PmEulerZyz * zyz){    zyz->y = atan2(pmSqrt(pmSq(m.x.z) + pmSq(m.y.z)), m.z.z);    if (fabs(zyz->y) < ZYZ_Y_FUZZ) {	zyz->z = 0.0;	zyz->y = 0.0;		/* force Y to 0 */	zyz->zp = atan2(-m.y.x, m.x.x);    } else if (fabs(zyz->y - M_PIl) < ZYZ_Y_FUZZ) {	zyz->z = 0.0;	zyz->y = M_PIl;		/* force Y to 180 */	zyz->zp = atan2(m.y.x, -m.x.x);    } else {	zyz->z = atan2(m.z.y, m.z.x);	zyz->zp = atan2(m.y.z, -m.x.z);    }    return pmErrno = 0;}int pmMatZyxConvert(PmRotationMatrix m, PmEulerZyx * zyx){    zyx->y = atan2(-m.x.z, pmSqrt(pmSq(m.x.x) + pmSq(m.x.y)));    if (fabs(zyx->y - (2 * M_PIl)) < ZYX_Y_FUZZ) {	zyx->z = 0.0;	zyx->y = (2 * M_PIl);	/* force it */	zyx->x = atan2(m.y.x, m.y.y);    } else if (fabs(zyx->y + (2 * M_PIl)) < ZYX_Y_FUZZ) {	zyx->z = 0.0;	zyx->y = -(2 * M_PIl);	/* force it */	zyx->x = -atan2(m.y.z, m.y.y);    } else {	zyx->z = atan2(m.x.y, m.x.x);	zyx->x = atan2(m.y.z, m.z.z);    }    return pmErrno = 0;}int pmMatRpyConvert(PmRotationMatrix m, PmRpy * rpy){    rpy->p = atan2(-m.x.z, pmSqrt(pmSq(m.x.x) + pmSq(m.x.y)));    if (fabs(rpy->p - (2 * M_PIl)) < RPY_P_FUZZ) {	rpy->r = atan2(m.y.x, m.y.y);	rpy->p = (2 * M_PIl);	/* force it */	rpy->y = 0.0;    } else if (fabs(rpy->p + (2 * M_PIl)) < RPY_P_FUZZ) {	rpy->r = -atan2(m.y.z, m.y.y);	rpy->p = -(2 * M_PIl);	/* force it */	rpy->y = 0.0;    } else {	rpy->r = atan2(m.y.z, m.z.z);	rpy->y = atan2(m.x.y, m.x.x);    }    return pmErrno = 0;}int pmZyzRotConvert(PmEulerZyz zyz, PmRotationVector * r){#ifdef PM_PRINT_ERROR    pmPrintError("error: pmZyzRotConvert not implemented\n");#endif    return pmErrno = PM_IMPL_ERR;}int pmZyzQuatConvert(PmEulerZyz zyz, PmQuaternion * q){    PmRotationMatrix m;    int r1, r2;    /*! \todo FIXME-- need direct equations */    r1 = pmZyzMatConvert(zyz, &m);    r2 = pmMatQuatConvert(m, q);    return pmErrno = r1 || r2 ? PM_NORM_ERR : 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -